aboutsummaryrefslogtreecommitdiff
path: root/.repos
diff options
context:
space:
mode:
Diffstat (limited to '.repos')
-rw-r--r--.repos/dmenu/LICENSE30
-rw-r--r--.repos/dmenu/Makefile64
-rw-r--r--.repos/dmenu/README24
-rw-r--r--.repos/dmenu/arg.h49
-rw-r--r--.repos/dmenu/config.def.h23
-rw-r--r--.repos/dmenu/config.h23
-rw-r--r--.repos/dmenu/config.mk31
-rwxr-xr-x.repos/dmenu/dmenubin43416 -> 0 bytes
-rw-r--r--.repos/dmenu/dmenu.1194
-rw-r--r--.repos/dmenu/dmenu.c782
-rw-r--r--.repos/dmenu/dmenu.obin32736 -> 0 bytes
-rwxr-xr-x.repos/dmenu/dmenu_path13
-rwxr-xr-x.repos/dmenu/dmenu_run2
-rw-r--r--.repos/dmenu/drw.c436
-rw-r--r--.repos/dmenu/drw.h57
-rw-r--r--.repos/dmenu/drw.obin10584 -> 0 bytes
-rwxr-xr-x.repos/dmenu/stestbin17080 -> 0 bytes
-rw-r--r--.repos/dmenu/stest.190
-rw-r--r--.repos/dmenu/stest.c109
-rw-r--r--.repos/dmenu/stest.obin5296 -> 0 bytes
-rw-r--r--.repos/dmenu/util.c35
-rw-r--r--.repos/dmenu/util.h8
-rw-r--r--.repos/dmenu/util.obin2256 -> 0 bytes
-rw-r--r--.repos/dwm/LICENSE37
-rw-r--r--.repos/dwm/Makefile51
-rw-r--r--.repos/dwm/README48
-rw-r--r--.repos/dwm/aah137
-rw-r--r--.repos/dwm/config.def.h136
-rw-r--r--.repos/dwm/config.def.h.orig116
-rw-r--r--.repos/dwm/config.h134
-rw-r--r--.repos/dwm/config.mk38
-rw-r--r--.repos/dwm/drw.c436
-rw-r--r--.repos/dwm/drw.h57
-rw-r--r--.repos/dwm/drw.obin10240 -> 0 bytes
-rwxr-xr-x.repos/dwm/dwmbin70312 -> 0 bytes
-rw-r--r--.repos/dwm/dwm.1176
-rw-r--r--.repos/dwm/dwm.c2263
-rw-r--r--.repos/dwm/dwm.c.orig2187
-rw-r--r--.repos/dwm/dwm.obin57960 -> 0 bytes
-rw-r--r--.repos/dwm/dwm.pngbin373 -> 0 bytes
-rw-r--r--.repos/dwm/patches/dwm-pertag-20200914-61bb8b2.diff177
-rw-r--r--.repos/dwm/patches/dwm-scratchpads-20200414-728d397b.diff199
-rw-r--r--.repos/dwm/shiftview.c68
-rw-r--r--.repos/dwm/transient.c42
-rw-r--r--.repos/dwm/util.c35
-rw-r--r--.repos/dwm/util.h8
-rw-r--r--.repos/dwm/util.obin2080 -> 0 bytes
-rw-r--r--.repos/dwm/vanitygaps.c542
-rwxr-xr-x.repos/farbfeld/2ff38
-rw-r--r--.repos/farbfeld/2ff.145
-rw-r--r--.repos/farbfeld/FORMAT14
-rw-r--r--.repos/farbfeld/LICENSE24
-rw-r--r--.repos/farbfeld/Makefile67
-rw-r--r--.repos/farbfeld/README74
-rw-r--r--.repos/farbfeld/arg.h50
-rw-r--r--.repos/farbfeld/config.mk18
-rw-r--r--.repos/farbfeld/farbfeld.5177
-rw-r--r--.repos/farbfeld/ff2jpg.154
-rw-r--r--.repos/farbfeld/ff2jpg.c114
-rw-r--r--.repos/farbfeld/ff2pam.138
-rw-r--r--.repos/farbfeld/ff2pam.c55
-rw-r--r--.repos/farbfeld/ff2png.138
-rw-r--r--.repos/farbfeld/ff2png.c77
-rw-r--r--.repos/farbfeld/ff2ppm.146
-rw-r--r--.repos/farbfeld/ff2ppm.c72
-rw-r--r--.repos/farbfeld/jpg2ff.138
-rw-r--r--.repos/farbfeld/jpg2ff.c90
-rw-r--r--.repos/farbfeld/png2ff.138
-rw-r--r--.repos/farbfeld/png2ff.c97
-rw-r--r--.repos/farbfeld/util.c242
-rw-r--r--.repos/farbfeld/util.h28
-rw-r--r--.repos/sent/LICENSE29
-rw-r--r--.repos/sent/Makefile60
-rw-r--r--.repos/sent/README.md59
-rw-r--r--.repos/sent/arg.h49
-rw-r--r--.repos/sent/config.h63
-rw-r--r--.repos/sent/config.mk30
-rw-r--r--.repos/sent/drw.c421
-rw-r--r--.repos/sent/drw.h57
-rw-r--r--.repos/sent/example.sent69
-rw-r--r--.repos/sent/sent.171
-rw-r--r--.repos/sent/sent.c732
-rw-r--r--.repos/sent/util.c35
-rw-r--r--.repos/sent/util.h8
-rw-r--r--.repos/slock/LICENSE24
-rw-r--r--.repos/slock/Makefile61
-rw-r--r--.repos/slock/README24
-rw-r--r--.repos/slock/arg.h65
-rw-r--r--.repos/slock/config.def.h12
-rw-r--r--.repos/slock/config.h12
-rw-r--r--.repos/slock/config.mk32
-rw-r--r--.repos/slock/explicit_bzero.c19
-rw-r--r--.repos/slock/slock.139
-rw-r--r--.repos/slock/slock.c395
-rw-r--r--.repos/slock/util.h2
-rw-r--r--.repos/st/FAQ250
-rw-r--r--.repos/st/FUNDING.yml5
-rw-r--r--.repos/st/LEGACY17
-rw-r--r--.repos/st/LICENSE34
-rw-r--r--.repos/st/Makefile57
-rw-r--r--.repos/st/PKGBUILD45
-rw-r--r--.repos/st/README34
-rw-r--r--.repos/st/README.md82
-rw-r--r--.repos/st/TODO28
-rw-r--r--.repos/st/arg.h50
-rw-r--r--.repos/st/boxdraw.c194
-rw-r--r--.repos/st/boxdraw_data.h214
-rw-r--r--.repos/st/config.def.h472
-rw-r--r--.repos/st/config.h472
-rw-r--r--.repos/st/config.mk35
-rw-r--r--.repos/st/patches/st-scrollback-20210507-4536f46.diff351
-rw-r--r--.repos/st/patches/st-scrollback-mouse-20191024-a2c479c.diff13
-rwxr-xr-x.repos/st/stbin101944 -> 0 bytes
-rwxr-xr-x.repos/st/st-copyout13
-rwxr-xr-x.repos/st/st-urlhandler15
-rw-r--r--.repos/st/st.1177
-rw-r--r--.repos/st/st.c2679
-rw-r--r--.repos/st/st.c.orig2608
-rw-r--r--.repos/st/st.h127
-rw-r--r--.repos/st/st.info239
-rw-r--r--.repos/st/st.obin76032 -> 0 bytes
-rw-r--r--.repos/st/win.h40
-rw-r--r--.repos/st/x.c2067
-rw-r--r--.repos/st/x.obin73056 -> 0 bytes
-rw-r--r--.repos/tabbed/LICENSE23
-rw-r--r--.repos/tabbed/Makefile65
-rw-r--r--.repos/tabbed/README22
-rw-r--r--.repos/tabbed/TODO4
-rw-r--r--.repos/tabbed/arg.h48
-rw-r--r--.repos/tabbed/config.h66
-rw-r--r--.repos/tabbed/config.mk33
-rw-r--r--.repos/tabbed/tabbed.1171
-rw-r--r--.repos/tabbed/tabbed.c1366
-rw-r--r--.repos/tabbed/xembed.135
-rw-r--r--.repos/tabbed/xembed.c45
135 files changed, 0 insertions, 24955 deletions
diff --git a/.repos/dmenu/LICENSE b/.repos/dmenu/LICENSE
deleted file mode 100644
index 3afd28e..0000000
--- a/.repos/dmenu/LICENSE
+++ /dev/null
@@ -1,30 +0,0 @@
-MIT/X Consortium License
-
-© 2006-2019 Anselm R Garbe <anselm@garbe.ca>
-© 2006-2008 Sander van Dijk <a.h.vandijk@gmail.com>
-© 2006-2007 Michał Janeczek <janeczek@gmail.com>
-© 2007 Kris Maglione <jg@suckless.org>
-© 2009 Gottox <gottox@s01.de>
-© 2009 Markus Schnalke <meillo@marmaro.de>
-© 2009 Evan Gates <evan.gates@gmail.com>
-© 2010-2012 Connor Lane Smith <cls@lubutu.com>
-© 2014-2020 Hiltjo Posthuma <hiltjo@codemadness.org>
-© 2015-2019 Quentin Rameau <quinq@fifth.space>
-
-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/.repos/dmenu/Makefile b/.repos/dmenu/Makefile
deleted file mode 100644
index a03a95c..0000000
--- a/.repos/dmenu/Makefile
+++ /dev/null
@@ -1,64 +0,0 @@
-# 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: options dmenu stest
-
-options:
- @echo dmenu build options:
- @echo "CFLAGS = $(CFLAGS)"
- @echo "LDFLAGS = $(LDFLAGS)"
- @echo "CC = $(CC)"
-
-.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 options clean dist install uninstall
diff --git a/.repos/dmenu/README b/.repos/dmenu/README
deleted file mode 100644
index a8fcdfe..0000000
--- a/.repos/dmenu/README
+++ /dev/null
@@ -1,24 +0,0 @@
-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/.repos/dmenu/arg.h b/.repos/dmenu/arg.h
deleted file mode 100644
index e94e02b..0000000
--- a/.repos/dmenu/arg.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * 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/.repos/dmenu/config.def.h b/.repos/dmenu/config.def.h
deleted file mode 100644
index 1edb647..0000000
--- a/.repos/dmenu/config.def.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/* 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/.repos/dmenu/config.h b/.repos/dmenu/config.h
deleted file mode 100644
index 1edb647..0000000
--- a/.repos/dmenu/config.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/* 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/.repos/dmenu/config.mk b/.repos/dmenu/config.mk
deleted file mode 100644
index 05d5a3e..0000000
--- a/.repos/dmenu/config.mk
+++ /dev/null
@@ -1,31 +0,0 @@
-# dmenu version
-VERSION = 5.0
-
-# 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
-
-# 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/.repos/dmenu/dmenu b/.repos/dmenu/dmenu
deleted file mode 100755
index 3025fc2..0000000
--- a/.repos/dmenu/dmenu
+++ /dev/null
Binary files differ
diff --git a/.repos/dmenu/dmenu.1 b/.repos/dmenu/dmenu.1
deleted file mode 100644
index 323f93c..0000000
--- a/.repos/dmenu/dmenu.1
+++ /dev/null
@@ -1,194 +0,0 @@
-.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/.repos/dmenu/dmenu.c b/.repos/dmenu/dmenu.c
deleted file mode 100644
index 98507d9..0000000
--- a/.repos/dmenu/dmenu.c
+++ /dev/null
@@ -1,782 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-#include <ctype.h>
-#include <locale.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <strings.h>
-#include <time.h>
-#include <unistd.h>
-
-#include <X11/Xlib.h>
-#include <X11/Xatom.h>
-#include <X11/Xutil.h>
-#ifdef XINERAMA
-#include <X11/extensions/Xinerama.h>
-#endif
-#include <X11/Xft/Xft.h>
-
-#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 LENGTH(X) (sizeof X / sizeof X[0])
-#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 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 : MIN(TEXTW(next->text), n)) > n)
- break;
- for (i = 0, prev = curr; prev && prev->left; prev = prev->left)
- if ((i += (lines > 0) ? bh : MIN(TEXTW(prev->left->text), n)) > n)
- break;
-}
-
-static void
-cleanup(void)
-{
- size_t i;
-
- XUngrabKey(dpy, AnyKey, AnyModifier, root);
- for (i = 0; i < SchemeLast; i++)
- free(scheme[i]);
- drw_free(drw);
- XSync(dpy, False);
- XCloseDisplay(dpy);
-}
-
-static char *
-cistrstr(const char *s, const char *sub)
-{
- size_t len;
-
- for (len = strlen(sub); *s; s++)
- if (!strncasecmp(s, sub, len))
- return (char *)s;
- 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, MIN(TEXTW(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 %u 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[32];
- int len;
- KeySym ksym;
- Status status;
-
- len = XmbLookupString(xic, ev, buf, sizeof buf, &ksym, &status);
- switch (status) {
- default: /* XLookupNone, XBufferOverflow */
- return;
- case XLookupChars:
- goto insert;
- case XLookupKeySym:
- case XLookupBoth:
- 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(*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;
- strncpy(text, sel->text, sizeof text - 1);
- text[sizeof text - 1] = '\0';
- cursor = strlen(text);
- 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 buf[sizeof text], *p;
- size_t i, imax = 0, size = 0;
- unsigned int tmpmax = 0;
-
- /* read each line from stdin and add it to the item list */
- for (i = 0; fgets(buf, sizeof buf, stdin); i++) {
- if (i + 1 >= size / sizeof *items)
- if (!(items = realloc(items, (size += BUFSIZ))))
- die("cannot realloc %u bytes:", size);
- if ((p = strchr(buf, '\n')))
- *p = '\0';
- if (!(items[i].text = strdup(buf)))
- die("cannot strdup %u bytes:", strlen(buf) + 1);
- items[i].out = 0;
- drw_font_getexts(drw->fonts, buf, strlen(buf), &tmpmax, NULL);
- if (tmpmax > inputw) {
- inputw = tmpmax;
- imax = i;
- }
- }
- if (items)
- items[i].text = NULL;
- inputw = items ? TEXTW(items[imax].text) : 0;
- 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]))
- 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 = MIN(inputw, mw/3);
- match();
-
- /* create menu window */
- swa.override_redirect = True;
- swa.background_pixel = scheme[SchemeNorm][ColBg].pixel;
- swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask;
- win = XCreateWindow(dpy, parentwin, 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) {
- 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)
-{
- fputs("usage: dmenu [-bfiv] [-l lines] [-p prompt] [-fn font] [-m monitor]\n"
- " [-nb color] [-nf color] [-sb color] [-sf color] [-w windowid]\n", stderr);
- exit(1);
-}
-
-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/.repos/dmenu/dmenu.o b/.repos/dmenu/dmenu.o
deleted file mode 100644
index 01e1b7b..0000000
--- a/.repos/dmenu/dmenu.o
+++ /dev/null
Binary files differ
diff --git a/.repos/dmenu/dmenu_path b/.repos/dmenu/dmenu_path
deleted file mode 100755
index 3a7cda7..0000000
--- a/.repos/dmenu/dmenu_path
+++ /dev/null
@@ -1,13 +0,0 @@
-#!/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/.repos/dmenu/dmenu_run b/.repos/dmenu/dmenu_run
deleted file mode 100755
index 834ede5..0000000
--- a/.repos/dmenu/dmenu_run
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/sh
-dmenu_path | dmenu "$@" | ${SHELL:-"/bin/sh"} &
diff --git a/.repos/dmenu/drw.c b/.repos/dmenu/drw.c
deleted file mode 100644
index 4cdbcbe..0000000
--- a/.repos/dmenu/drw.c
+++ /dev/null
@@ -1,436 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <X11/Xlib.h>
-#include <X11/Xft/Xft.h>
-
-#include "drw.h"
-#include "util.h"
-
-#define UTF_INVALID 0xFFFD
-#define UTF_SIZ 4
-
-static const unsigned char utfbyte[UTF_SIZ + 1] = {0x80, 0, 0xC0, 0xE0, 0xF0};
-static const unsigned char utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8};
-static const long utfmin[UTF_SIZ + 1] = { 0, 0, 0x80, 0x800, 0x10000};
-static const long utfmax[UTF_SIZ + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF};
-
-static long
-utf8decodebyte(const char c, size_t *i)
-{
- for (*i = 0; *i < (UTF_SIZ + 1); ++(*i))
- if (((unsigned char)c & utfmask[*i]) == utfbyte[*i])
- return (unsigned char)c & ~utfmask[*i];
- return 0;
-}
-
-static size_t
-utf8validate(long *u, size_t i)
-{
- if (!BETWEEN(*u, utfmin[i], utfmax[i]) || BETWEEN(*u, 0xD800, 0xDFFF))
- *u = UTF_INVALID;
- for (i = 1; *u > utfmax[i]; ++i)
- ;
- return i;
-}
-
-static size_t
-utf8decode(const char *c, long *u, size_t clen)
-{
- size_t i, j, len, type;
- long udecoded;
-
- *u = UTF_INVALID;
- if (!clen)
- return 0;
- udecoded = utf8decodebyte(c[0], &len);
- if (!BETWEEN(len, 1, UTF_SIZ))
- return 1;
- for (i = 1, j = 1; i < clen && j < len; ++i, ++j) {
- udecoded = (udecoded << 6) | utf8decodebyte(c[i], &type);
- if (type)
- return j;
- }
- if (j < len)
- return 0;
- *u = udecoded;
- utf8validate(u, len);
-
- 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.");
- }
-
- /* Do not allow using color fonts. This is a workaround for a BadLength
- * error from Xft with color glyphs. Modelled on the Xterm workaround. See
- * https://bugzilla.redhat.com/show_bug.cgi?id=1498269
- * https://lists.suckless.org/dev/1701/30932.html
- * https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=916349
- * and lots more all over the internet.
- */
- FcBool iscol;
- if(FcPatternGetBool(xfont->pattern, FC_COLOR, 0, &iscol) == FcResultMatch && iscol) {
- XftFontClose(drw->dpy, xfont);
- return NULL;
- }
-
- 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)
-{
- char buf[1024];
- int ty;
- unsigned int ew;
- XftDraw *d = NULL;
- Fnt *usedfont, *curfont, *nextfont;
- size_t i, len;
- int utf8strlen, utf8charlen, render = x || y || w || h;
- long utf8codepoint = 0;
- const char *utf8str;
- FcCharSet *fccharset;
- FcPattern *fcpattern;
- FcPattern *match;
- XftResult result;
- int charexists = 0;
-
- if (!drw || (render && !drw->scheme) || !text || !drw->fonts)
- return 0;
-
- if (!render) {
- w = ~w;
- } else {
- XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].pixel);
- XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
- d = XftDrawCreate(drw->dpy, drw->drawable,
- DefaultVisual(drw->dpy, drw->screen),
- DefaultColormap(drw->dpy, drw->screen));
- x += lpad;
- w -= lpad;
- }
-
- usedfont = drw->fonts;
- while (1) {
- utf8strlen = 0;
- utf8str = text;
- nextfont = NULL;
- while (*text) {
- utf8charlen = utf8decode(text, &utf8codepoint, UTF_SIZ);
- for (curfont = drw->fonts; curfont; curfont = curfont->next) {
- charexists = charexists || XftCharExists(drw->dpy, curfont->xfont, utf8codepoint);
- if (charexists) {
- if (curfont == usedfont) {
- utf8strlen += utf8charlen;
- text += utf8charlen;
- } else {
- nextfont = curfont;
- }
- break;
- }
- }
-
- if (!charexists || nextfont)
- break;
- else
- charexists = 0;
- }
-
- if (utf8strlen) {
- drw_font_getexts(usedfont, utf8str, utf8strlen, &ew, NULL);
- /* shorten text if necessary */
- for (len = MIN(utf8strlen, sizeof(buf) - 1); len && ew > w; len--)
- drw_font_getexts(usedfont, utf8str, len, &ew, NULL);
-
- if (len) {
- memcpy(buf, utf8str, len);
- buf[len] = '\0';
- if (len < utf8strlen)
- for (i = len; i && i > len - 3; buf[--i] = '.')
- ; /* NOP */
-
- if (render) {
- ty = y + (h - usedfont->h) / 2 + usedfont->xfont->ascent;
- XftDrawStringUtf8(d, &drw->scheme[invert ? ColBg : ColFg],
- usedfont->xfont, x, ty, (XftChar8 *)buf, len);
- }
- x += ew;
- w -= ew;
- }
- }
-
- if (!*text) {
- 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;
-
- 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);
- FcPatternAddBool(fcpattern, FC_COLOR, FcFalse);
-
- 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);
- 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);
-}
-
-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/.repos/dmenu/drw.h b/.repos/dmenu/drw.h
deleted file mode 100644
index 4c67419..0000000
--- a/.repos/dmenu/drw.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/* 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);
-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/.repos/dmenu/drw.o b/.repos/dmenu/drw.o
deleted file mode 100644
index 57700fd..0000000
--- a/.repos/dmenu/drw.o
+++ /dev/null
Binary files differ
diff --git a/.repos/dmenu/stest b/.repos/dmenu/stest
deleted file mode 100755
index 63e0ea3..0000000
--- a/.repos/dmenu/stest
+++ /dev/null
Binary files differ
diff --git a/.repos/dmenu/stest.1 b/.repos/dmenu/stest.1
deleted file mode 100644
index 2667d8a..0000000
--- a/.repos/dmenu/stest.1
+++ /dev/null
@@ -1,90 +0,0 @@
-.TH STEST 1 dmenu\-VERSION
-.SH NAME
-stest \- filter a list of files by properties
-.SH SYNOPSIS
-.B stest
-.RB [ -abcdefghlpqrsuwx ]
-.RB [ -n
-.IR file ]
-.RB [ -o
-.IR file ]
-.RI [ file ...]
-.SH DESCRIPTION
-.B stest
-takes a list of files and filters by the files' properties, analogous to
-.IR test (1).
-Files which pass all tests are printed to stdout. If no files are given, stest
-reads files from stdin.
-.SH OPTIONS
-.TP
-.B \-a
-Test hidden files.
-.TP
-.B \-b
-Test that files are block specials.
-.TP
-.B \-c
-Test that files are character specials.
-.TP
-.B \-d
-Test that files are directories.
-.TP
-.B \-e
-Test that files exist.
-.TP
-.B \-f
-Test that files are regular files.
-.TP
-.B \-g
-Test that files have their set-group-ID flag set.
-.TP
-.B \-h
-Test that files are symbolic links.
-.TP
-.B \-l
-Test the contents of a directory given as an argument.
-.TP
-.BI \-n " file"
-Test that files are newer than
-.IR file .
-.TP
-.BI \-o " file"
-Test that files are older than
-.IR file .
-.TP
-.B \-p
-Test that files are named pipes.
-.TP
-.B \-q
-No files are printed, only the exit status is returned.
-.TP
-.B \-r
-Test that files are readable.
-.TP
-.B \-s
-Test that files are not empty.
-.TP
-.B \-u
-Test that files have their set-user-ID flag set.
-.TP
-.B \-v
-Invert the sense of tests, only failing files pass.
-.TP
-.B \-w
-Test that files are writable.
-.TP
-.B \-x
-Test that files are executable.
-.SH EXIT STATUS
-.TP
-.B 0
-At least one file passed all tests.
-.TP
-.B 1
-No files passed all tests.
-.TP
-.B 2
-An error occurred.
-.SH SEE ALSO
-.IR dmenu (1),
-.IR test (1)
diff --git a/.repos/dmenu/stest.c b/.repos/dmenu/stest.c
deleted file mode 100644
index e27d3a5..0000000
--- a/.repos/dmenu/stest.c
+++ /dev/null
@@ -1,109 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-#include <sys/stat.h>
-
-#include <dirent.h>
-#include <limits.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "arg.h"
-char *argv0;
-
-#define FLAG(x) (flag[(x)-'a'])
-
-static void test(const char *, const char *);
-static void usage(void);
-
-static int match = 0;
-static int flag[26];
-static struct stat old, new;
-
-static void
-test(const char *path, const char *name)
-{
- struct stat st, ln;
-
- if ((!stat(path, &st) && (FLAG('a') || name[0] != '.') /* hidden files */
- && (!FLAG('b') || S_ISBLK(st.st_mode)) /* block special */
- && (!FLAG('c') || S_ISCHR(st.st_mode)) /* character special */
- && (!FLAG('d') || S_ISDIR(st.st_mode)) /* directory */
- && (!FLAG('e') || access(path, F_OK) == 0) /* exists */
- && (!FLAG('f') || S_ISREG(st.st_mode)) /* regular file */
- && (!FLAG('g') || st.st_mode & S_ISGID) /* set-group-id flag */
- && (!FLAG('h') || (!lstat(path, &ln) && S_ISLNK(ln.st_mode))) /* symbolic link */
- && (!FLAG('n') || st.st_mtime > new.st_mtime) /* newer than file */
- && (!FLAG('o') || st.st_mtime < old.st_mtime) /* older than file */
- && (!FLAG('p') || S_ISFIFO(st.st_mode)) /* named pipe */
- && (!FLAG('r') || access(path, R_OK) == 0) /* readable */
- && (!FLAG('s') || st.st_size > 0) /* not empty */
- && (!FLAG('u') || st.st_mode & S_ISUID) /* set-user-id flag */
- && (!FLAG('w') || access(path, W_OK) == 0) /* writable */
- && (!FLAG('x') || access(path, X_OK) == 0)) != FLAG('v')) { /* executable */
- if (FLAG('q'))
- exit(0);
- match = 1;
- puts(name);
- }
-}
-
-static void
-usage(void)
-{
- fprintf(stderr, "usage: %s [-abcdefghlpqrsuvwx] "
- "[-n file] [-o file] [file...]\n", argv0);
- exit(2); /* like test(1) return > 1 on error */
-}
-
-int
-main(int argc, char *argv[])
-{
- struct dirent *d;
- char path[PATH_MAX], *line = NULL, *file;
- size_t linesiz = 0;
- ssize_t n;
- DIR *dir;
- int r;
-
- ARGBEGIN {
- case 'n': /* newer than file */
- case 'o': /* older than file */
- file = EARGF(usage());
- if (!(FLAG(ARGC()) = !stat(file, (ARGC() == 'n' ? &new : &old))))
- perror(file);
- break;
- default:
- /* miscellaneous operators */
- if (strchr("abcdefghlpqrsuvwx", ARGC()))
- FLAG(ARGC()) = 1;
- else
- usage(); /* unknown flag */
- } ARGEND;
-
- if (!argc) {
- /* read list from stdin */
- while ((n = getline(&line, &linesiz, stdin)) > 0) {
- if (line[n - 1] == '\n')
- line[n - 1] = '\0';
- test(line, line);
- }
- free(line);
- } else {
- for (; argc; argc--, argv++) {
- if (FLAG('l') && (dir = opendir(*argv))) {
- /* test directory contents */
- while ((d = readdir(dir))) {
- r = snprintf(path, sizeof path, "%s/%s",
- *argv, d->d_name);
- if (r >= 0 && (size_t)r < sizeof path)
- test(path, d->d_name);
- }
- closedir(dir);
- } else {
- test(*argv, *argv);
- }
- }
- }
- return match ? 0 : 1;
-}
diff --git a/.repos/dmenu/stest.o b/.repos/dmenu/stest.o
deleted file mode 100644
index 4ffa357..0000000
--- a/.repos/dmenu/stest.o
+++ /dev/null
Binary files differ
diff --git a/.repos/dmenu/util.c b/.repos/dmenu/util.c
deleted file mode 100644
index fe044fc..0000000
--- a/.repos/dmenu/util.c
+++ /dev/null
@@ -1,35 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "util.h"
-
-void *
-ecalloc(size_t nmemb, size_t size)
-{
- void *p;
-
- if (!(p = calloc(nmemb, size)))
- die("calloc:");
- return p;
-}
-
-void
-die(const char *fmt, ...) {
- va_list ap;
-
- va_start(ap, fmt);
- vfprintf(stderr, fmt, ap);
- va_end(ap);
-
- if (fmt[0] && fmt[strlen(fmt)-1] == ':') {
- fputc(' ', stderr);
- perror(NULL);
- } else {
- fputc('\n', stderr);
- }
-
- exit(1);
-}
diff --git a/.repos/dmenu/util.h b/.repos/dmenu/util.h
deleted file mode 100644
index f633b51..0000000
--- a/.repos/dmenu/util.h
+++ /dev/null
@@ -1,8 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-
-#define MAX(A, B) ((A) > (B) ? (A) : (B))
-#define MIN(A, B) ((A) < (B) ? (A) : (B))
-#define BETWEEN(X, A, B) ((A) <= (X) && (X) <= (B))
-
-void die(const char *fmt, ...);
-void *ecalloc(size_t nmemb, size_t size);
diff --git a/.repos/dmenu/util.o b/.repos/dmenu/util.o
deleted file mode 100644
index 3b48c2f..0000000
--- a/.repos/dmenu/util.o
+++ /dev/null
Binary files differ
diff --git a/.repos/dwm/LICENSE b/.repos/dwm/LICENSE
deleted file mode 100644
index d221f09..0000000
--- a/.repos/dwm/LICENSE
+++ /dev/null
@@ -1,37 +0,0 @@
-MIT/X Consortium License
-
-© 2006-2019 Anselm R Garbe <anselm@garbe.ca>
-© 2006-2009 Jukka Salmi <jukka at salmi dot ch>
-© 2006-2007 Sander van Dijk <a dot h dot vandijk at gmail dot com>
-© 2007-2011 Peter Hartlich <sgkkr at hartlich dot com>
-© 2007-2009 Szabolcs Nagy <nszabolcs at gmail dot com>
-© 2007-2009 Christof Musik <christof at sendfax dot de>
-© 2007-2009 Premysl Hruby <dfenze at gmail dot com>
-© 2007-2008 Enno Gottox Boland <gottox at s01 dot de>
-© 2008 Martin Hurton <martin dot hurton at gmail dot com>
-© 2008 Neale Pickett <neale dot woozle dot org>
-© 2009 Mate Nagy <mnagy at port70 dot net>
-© 2010-2016 Hiltjo Posthuma <hiltjo@codemadness.org>
-© 2010-2012 Connor Lane Smith <cls@lubutu.com>
-© 2011 Christoph Lohmann <20h@r-36.net>
-© 2015-2016 Quentin Rameau <quinq@fifth.space>
-© 2015-2016 Eric Pruitt <eric.pruitt@gmail.com>
-© 2016-2017 Markus Teich <markus.teich@stusta.mhn.de>
-
-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/.repos/dwm/Makefile b/.repos/dwm/Makefile
deleted file mode 100644
index 77bcbc0..0000000
--- a/.repos/dwm/Makefile
+++ /dev/null
@@ -1,51 +0,0 @@
-# dwm - dynamic window manager
-# See LICENSE file for copyright and license details.
-
-include config.mk
-
-SRC = drw.c dwm.c util.c
-OBJ = ${SRC:.c=.o}
-
-all: options dwm
-
-options:
- @echo dwm build options:
- @echo "CFLAGS = ${CFLAGS}"
- @echo "LDFLAGS = ${LDFLAGS}"
- @echo "CC = ${CC}"
-
-.c.o:
- ${CC} -c ${CFLAGS} $<
-
-${OBJ}: config.h config.mk
-
-config.h:
- cp config.def.h $@
-
-dwm: ${OBJ}
- ${CC} -o $@ ${OBJ} ${LDFLAGS}
-
-clean:
- rm -f dwm ${OBJ} dwm-${VERSION}.tar.gz
-
-dist: clean
- mkdir -p dwm-${VERSION}
- cp -R LICENSE Makefile README config.def.h config.mk\
- dwm.1 drw.h util.h ${SRC} dwm.png transient.c dwm-${VERSION}
- tar -cf dwm-${VERSION}.tar dwm-${VERSION}
- gzip dwm-${VERSION}.tar
- rm -rf dwm-${VERSION}
-
-install: all
- mkdir -p ${DESTDIR}${PREFIX}/bin
- cp -f dwm ${DESTDIR}${PREFIX}/bin
- chmod 755 ${DESTDIR}${PREFIX}/bin/dwm
- mkdir -p ${DESTDIR}${MANPREFIX}/man1
- sed "s/VERSION/${VERSION}/g" < dwm.1 > ${DESTDIR}${MANPREFIX}/man1/dwm.1
- chmod 644 ${DESTDIR}${MANPREFIX}/man1/dwm.1
-
-uninstall:
- rm -f ${DESTDIR}${PREFIX}/bin/dwm\
- ${DESTDIR}${MANPREFIX}/man1/dwm.1
-
-.PHONY: all options clean dist install uninstall
diff --git a/.repos/dwm/README b/.repos/dwm/README
deleted file mode 100644
index 95d4fd0..0000000
--- a/.repos/dwm/README
+++ /dev/null
@@ -1,48 +0,0 @@
-dwm - dynamic window manager
-============================
-dwm is an extremely fast, small, and dynamic window manager for X.
-
-
-Requirements
-------------
-In order to build dwm you need the Xlib header files.
-
-
-Installation
-------------
-Edit config.mk to match your local setup (dwm is installed into
-the /usr/local namespace by default).
-
-Afterwards enter the following command to build and install dwm (if
-necessary as root):
-
- make clean install
-
-
-Running dwm
------------
-Add the following line to your .xinitrc to start dwm using startx:
-
- exec dwm
-
-In order to connect dwm to a specific display, make sure that
-the DISPLAY environment variable is set correctly, e.g.:
-
- DISPLAY=foo.bar:1 exec dwm
-
-(This will start dwm on display :1 of the host foo.bar.)
-
-In order to display status info in the bar, you can do something
-like this in your .xinitrc:
-
- while xsetroot -name "`date` `uptime | sed 's/.*,//'`"
- do
- sleep 1
- done &
- exec dwm
-
-
-Configuration
--------------
-The configuration of dwm is done by creating a custom config.h
-and (re)compiling the source code.
diff --git a/.repos/dwm/aah b/.repos/dwm/aah
deleted file mode 100644
index 21d4f7d..0000000
--- a/.repos/dwm/aah
+++ /dev/null
@@ -1,137 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-
-/* appearance */
-static const unsigned int borderpx = 1; /* border pixel of windows */
-static const unsigned int snap = 32; /* snap pixel */
-static const int showbar = 0; /* 0 means no bar */
-static const int topbar = 1; /* 0 means bottom bar */
-static const char *fonts[] = { "Iosevka Term:pixelsize=13:antialias=true:autohint=true" };
-static const char dmenufont[] = "Iosevka Term:pixelsize=13:antialias=true:autohint=true";
-static const char col_gray1[] = "#222222";
-static const char col_gray2[] = "#444444";
-static const char col_gray3[] = "#bbbbbb";
-static const char col_gray4[] = "#eeeeee";
-static const char col_cyan[] = "#005577";
-static const char *colors[][3] = {
- /* fg bg border */
- [SchemeNorm] = { col_gray3, col_gray1, col_gray2 },
- [SchemeSel] = { col_gray4, col_cyan, col_cyan },
-};
-
-typedef struct {
- const char *name;
- const void *cmd;
-} Sp;
-
-const char *spcmd1[] = {"st", "-n", "spterm", NULL };
-const char *spcmd2[] = {"st", "-n", "spcalc", "-e", "python3", "-q", NULL };
-const char *spcmd3[] = {"keepassxc", NULL };
-static Sp scratchpads[] = {
- /* name cmd */
- {"spterm", spcmd1},
- {"spcalc", spcmd2},
- {"keepassxc", spcmd3},
-};
-
-/* tagging */
-static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" };
-
-static const Rule rules[] = {
- /* xprop(1):
- * WM_CLASS(STRING) = instance, class
- * WM_NAME(STRING) = title
- */
- /* class instance title tags mask isfloating monitor */
- { "Gimp", NULL, NULL, 0, 1, -1 },
- { NULL, "spterm", NULL, SPTAG(0), 1, -1 },
- { NULL, "spcalc", NULL, SPTAG(1), 1, -1 },
- { NULL, "keepassxc", NULL, SPTAG(2), 1, -1 },
-};
-
-/* layout(s) */
-static const float mfact = 0.55; /* factor of master area size [0.05..0.95] */
-static const int nmaster = 1; /* number of clients in master area */
-static const int resizehints = 0; /* 1 means respect size hints in tiled resizals */
-
-static const Layout layouts[] = {
- /* symbol arrange function */
- { "[T]", tile }, /* first entry is default */
- { "[F]", NULL }, /* no layout function means floating behavior */
- { "[M]", monocle },
-};
-
-/* key definitions */
-#define MODKEY Mod4Mask
-#define TAGKEYS(KEY,TAG) \
- { MODKEY, KEY, view, {.ui = 1 << TAG} }, \
- { MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG} }, \
- { MODKEY|ShiftMask, KEY, tag, {.ui = 1 << TAG} }, \
- { MODKEY|ControlMask|ShiftMask, KEY, toggletag, {.ui = 1 << TAG} },
-
-/* helper for spawning shell commands in the pre dwm-5.0 fashion */
-#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }
-
-/* commands */
-static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */
-static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL };
-static const char *termcmd[] = { "st", NULL };
-
-static Key keys[] = {
- /* modifier key function argument */
- { MODKEY, XK_p, spawn, {.v = dmenucmd } },
- { MODKEY, XK_Return, spawn, {.v = termcmd } },
- { MODKEY, XK_b, togglebar, {0} },
- { MODKEY, XK_j, focusstack, {.i = +1 } },
- { MODKEY, XK_k, focusstack, {.i = -1 } },
- { MODKEY, XK_i, incnmaster, {.i = +1 } },
- { MODKEY, XK_d, incnmaster, {.i = -1 } },
- { MODKEY, XK_h, setmfact, {.f = -0.05} },
- { MODKEY, XK_l, setmfact, {.f = +0.05} },
- { MODKEY|ShiftMask, XK_j, zoom, {0} },
- { MODKEY, XK_Tab, view, {0} },
- { MODKEY, XK_q, killclient, {0} },
- { MODKEY, XK_t, setlayout, {.v = &layouts[0]} },
- { MODKEY, XK_f, setlayout, {.v = &layouts[1]} },
- { MODKEY, XK_m, setlayout, {.v = &layouts[2]} },
- { MODKEY, XK_space, setlayout, {0} },
- { MODKEY|ShiftMask, XK_space, togglefloating, {0} },
- { MODKEY, XK_0, view, {.ui = ~0 } },
- { MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } },
- { MODKEY, XK_comma, focusmon, {.i = -1 } },
- { MODKEY, XK_period, focusmon, {.i = +1 } },
- { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } },
- { MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } },
- TAGKEYS( XK_1, 0)
- TAGKEYS( XK_2, 1)
- TAGKEYS( XK_3, 2)
- TAGKEYS( XK_4, 3)
- TAGKEYS( XK_5, 4)
- TAGKEYS( XK_6, 5)
- TAGKEYS( XK_7, 6)
- TAGKEYS( XK_8, 7)
- TAGKEYS( XK_9, 8)
- { MODKEY|ShiftMask, XK_q, quit, {0} },
-
- /* Scratchpads */
- { MODKEY|ShiftMask, XK_Return, togglescratch, {.ui = 0} },
- { MODKEY, XK_apostrophe, togglescratch, {.ui = 1} },
- { MODKEY|ShiftMask, XK_l, togglescratch, {.ui = 2} },
-};
-
-/* button definitions */
-/* click can be ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */
-static Button buttons[] = {
- /* click event mask button function argument */
- { ClkLtSymbol, 0, Button1, setlayout, {0} },
- { ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} },
- { ClkWinTitle, 0, Button2, zoom, {0} },
- { ClkStatusText, 0, Button2, spawn, {.v = termcmd } },
- { ClkClientWin, MODKEY, Button1, movemouse, {0} },
- { ClkClientWin, MODKEY, Button2, togglefloating, {0} },
- { ClkClientWin, MODKEY, Button3, resizemouse, {0} },
- { ClkTagBar, 0, Button1, view, {0} },
- { ClkTagBar, 0, Button3, toggleview, {0} },
- { ClkTagBar, MODKEY, Button1, tag, {0} },
- { ClkTagBar, MODKEY, Button3, toggletag, {0} },
-};
-
diff --git a/.repos/dwm/config.def.h b/.repos/dwm/config.def.h
deleted file mode 100644
index 90b5036..0000000
--- a/.repos/dwm/config.def.h
+++ /dev/null
@@ -1,136 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-
-/* appearance */
-static const unsigned int borderpx = 1; /* border pixel of windows */
-static const unsigned int snap = 32; /* snap pixel */
-static const int showbar = 1; /* 0 means no bar */
-static const int topbar = 1; /* 0 means bottom bar */
-static const char *fonts[] = { "monospace:size=10" };
-static const char dmenufont[] = "monospace:size=10";
-static const char col_gray1[] = "#222222";
-static const char col_gray2[] = "#444444";
-static const char col_gray3[] = "#bbbbbb";
-static const char col_gray4[] = "#eeeeee";
-static const char col_cyan[] = "#005577";
-static const char *colors[][3] = {
- /* fg bg border */
- [SchemeNorm] = { col_gray3, col_gray1, col_gray2 },
- [SchemeSel] = { col_gray4, col_cyan, col_cyan },
-};
-
-typedef struct {
- const char *name;
- const void *cmd;
-} Sp;
-const char *spcmd1[] = {"st", "-n", "spterm", "-g", "120x34", NULL };
-const char *spcmd2[] = {"st", "-n", "spfm", "-g", "144x41", "-e", "ranger", NULL };
-const char *spcmd3[] = {"keepassxc", NULL };
-static Sp scratchpads[] = {
- /* name cmd */
- {"spterm", spcmd1},
- {"spranger", spcmd2},
- {"keepassxc", spcmd3},
-};
-
-/* tagging */
-static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" };
-static const Rule rules[] = {
- /* xprop(1):
- * WM_CLASS(STRING) = instance, class
- * WM_NAME(STRING) = title
- */
- /* class instance title tags mask isfloating monitor */
- { "Gimp", NULL, NULL, 0, 1, -1 },
- { "Firefox", NULL, NULL, 1 << 8, 0, -1 },
- { NULL, "spterm", NULL, SPTAG(0), 1, -1 },
- { NULL, "spfm", NULL, SPTAG(1), 1, -1 },
- { NULL, "keepassxc", NULL, SPTAG(2), 0, -1 },
-};
-
-/* layout(s) */
-static const float mfact = 0.55; /* factor of master area size [0.05..0.95] */
-static const int nmaster = 1; /* number of clients in master area */
-static const int resizehints = 1; /* 1 means respect size hints in tiled resizals */
-static const int lockfullscreen = 1; /* 1 will force focus on the fullscreen window */
-
-static const Layout layouts[] = {
- /* symbol arrange function */
- { "[]=", tile }, /* first entry is default */
- { "><>", NULL }, /* no layout function means floating behavior */
- { "[M]", monocle },
-};
-
-/* key definitions */
-#define MODKEY Mod1Mask
-#define TAGKEYS(KEY,TAG) \
- { MODKEY, KEY, view, {.ui = 1 << TAG} }, \
- { MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG} }, \
- { MODKEY|ShiftMask, KEY, tag, {.ui = 1 << TAG} }, \
- { MODKEY|ControlMask|ShiftMask, KEY, toggletag, {.ui = 1 << TAG} },
-
-/* helper for spawning shell commands in the pre dwm-5.0 fashion */
-#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }
-
-/* commands */
-static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */
-static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL };
-static const char *termcmd[] = { "st", NULL };
-
-
-static Key keys[] = {
- /* modifier key function argument */
- { MODKEY, XK_p, spawn, {.v = dmenucmd } },
- { MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } },
- { MODKEY, XK_b, togglebar, {0} },
- { MODKEY, XK_j, focusstack, {.i = +1 } },
- { MODKEY, XK_k, focusstack, {.i = -1 } },
- { MODKEY, XK_i, incnmaster, {.i = +1 } },
- { MODKEY, XK_d, incnmaster, {.i = -1 } },
- { MODKEY, XK_h, setmfact, {.f = -0.05} },
- { MODKEY, XK_l, setmfact, {.f = +0.05} },
- { MODKEY, XK_Return, zoom, {0} },
- { MODKEY, XK_Tab, view, {0} },
- { MODKEY|ShiftMask, XK_c, killclient, {0} },
- { MODKEY, XK_t, setlayout, {.v = &layouts[0]} },
- { MODKEY, XK_f, setlayout, {.v = &layouts[1]} },
- { MODKEY, XK_m, setlayout, {.v = &layouts[2]} },
- { MODKEY, XK_space, setlayout, {0} },
- { MODKEY|ShiftMask, XK_space, togglefloating, {0} },
- { MODKEY, XK_0, view, {.ui = ~0 } },
- { MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } },
- { MODKEY, XK_comma, focusmon, {.i = -1 } },
- { MODKEY, XK_period, focusmon, {.i = +1 } },
- { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } },
- { MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } },
- { MODKEY, XK_y, togglescratch, {.ui = 0 } },
- { MODKEY, XK_u, togglescratch, {.ui = 1 } },
- { MODKEY, XK_x, togglescratch, {.ui = 2 } },
- TAGKEYS( XK_1, 0)
- TAGKEYS( XK_2, 1)
- TAGKEYS( XK_3, 2)
- TAGKEYS( XK_4, 3)
- TAGKEYS( XK_5, 4)
- TAGKEYS( XK_6, 5)
- TAGKEYS( XK_7, 6)
- TAGKEYS( XK_8, 7)
- TAGKEYS( XK_9, 8)
- { MODKEY|ShiftMask, XK_q, quit, {0} },
-};
-
-/* button definitions */
-/* click can be ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */
-static Button buttons[] = {
- /* click event mask button function argument */
- { ClkLtSymbol, 0, Button1, setlayout, {0} },
- { ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} },
- { ClkWinTitle, 0, Button2, zoom, {0} },
- { ClkStatusText, 0, Button2, spawn, {.v = termcmd } },
- { ClkClientWin, MODKEY, Button1, movemouse, {0} },
- { ClkClientWin, MODKEY, Button2, togglefloating, {0} },
- { ClkClientWin, MODKEY, Button1, resizemouse, {0} },
- { ClkTagBar, 0, Button1, view, {0} },
- { ClkTagBar, 0, Button3, toggleview, {0} },
- { ClkTagBar, MODKEY, Button1, tag, {0} },
- { ClkTagBar, MODKEY, Button3, toggletag, {0} },
-};
-
diff --git a/.repos/dwm/config.def.h.orig b/.repos/dwm/config.def.h.orig
deleted file mode 100644
index a2ac963..0000000
--- a/.repos/dwm/config.def.h.orig
+++ /dev/null
@@ -1,116 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-
-/* appearance */
-static const unsigned int borderpx = 1; /* border pixel of windows */
-static const unsigned int snap = 32; /* snap pixel */
-static const int showbar = 1; /* 0 means no bar */
-static const int topbar = 1; /* 0 means bottom bar */
-static const char *fonts[] = { "monospace:size=10" };
-static const char dmenufont[] = "monospace:size=10";
-static const char col_gray1[] = "#222222";
-static const char col_gray2[] = "#444444";
-static const char col_gray3[] = "#bbbbbb";
-static const char col_gray4[] = "#eeeeee";
-static const char col_cyan[] = "#005577";
-static const char *colors[][3] = {
- /* fg bg border */
- [SchemeNorm] = { col_gray3, col_gray1, col_gray2 },
- [SchemeSel] = { col_gray4, col_cyan, col_cyan },
-};
-
-/* tagging */
-static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" };
-
-static const Rule rules[] = {
- /* xprop(1):
- * WM_CLASS(STRING) = instance, class
- * WM_NAME(STRING) = title
- */
- /* class instance title tags mask isfloating monitor */
- { "Gimp", NULL, NULL, 0, 1, -1 },
- { "Firefox", NULL, NULL, 1 << 8, 0, -1 },
-};
-
-/* layout(s) */
-static const float mfact = 0.55; /* factor of master area size [0.05..0.95] */
-static const int nmaster = 1; /* number of clients in master area */
-static const int resizehints = 1; /* 1 means respect size hints in tiled resizals */
-static const int lockfullscreen = 1; /* 1 will force focus on the fullscreen window */
-
-static const Layout layouts[] = {
- /* symbol arrange function */
- { "[]=", tile }, /* first entry is default */
- { "><>", NULL }, /* no layout function means floating behavior */
- { "[M]", monocle },
-};
-
-/* key definitions */
-#define MODKEY Mod1Mask
-#define TAGKEYS(KEY,TAG) \
- { MODKEY, KEY, view, {.ui = 1 << TAG} }, \
- { MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG} }, \
- { MODKEY|ShiftMask, KEY, tag, {.ui = 1 << TAG} }, \
- { MODKEY|ControlMask|ShiftMask, KEY, toggletag, {.ui = 1 << TAG} },
-
-/* helper for spawning shell commands in the pre dwm-5.0 fashion */
-#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }
-
-/* commands */
-static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */
-static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL };
-static const char *termcmd[] = { "st", NULL };
-
-static Key keys[] = {
- /* modifier key function argument */
- { MODKEY, XK_p, spawn, {.v = dmenucmd } },
- { MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } },
- { MODKEY, XK_b, togglebar, {0} },
- { MODKEY, XK_j, focusstack, {.i = +1 } },
- { MODKEY, XK_k, focusstack, {.i = -1 } },
- { MODKEY, XK_i, incnmaster, {.i = +1 } },
- { MODKEY, XK_d, incnmaster, {.i = -1 } },
- { MODKEY, XK_h, setmfact, {.f = -0.05} },
- { MODKEY, XK_l, setmfact, {.f = +0.05} },
- { MODKEY, XK_Return, zoom, {0} },
- { MODKEY, XK_Tab, view, {0} },
- { MODKEY|ShiftMask, XK_c, killclient, {0} },
- { MODKEY, XK_t, setlayout, {.v = &layouts[0]} },
- { MODKEY, XK_f, setlayout, {.v = &layouts[1]} },
- { MODKEY, XK_m, setlayout, {.v = &layouts[2]} },
- { MODKEY, XK_space, setlayout, {0} },
- { MODKEY|ShiftMask, XK_space, togglefloating, {0} },
- { MODKEY, XK_0, view, {.ui = ~0 } },
- { MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } },
- { MODKEY, XK_comma, focusmon, {.i = -1 } },
- { MODKEY, XK_period, focusmon, {.i = +1 } },
- { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } },
- { MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } },
- TAGKEYS( XK_1, 0)
- TAGKEYS( XK_2, 1)
- TAGKEYS( XK_3, 2)
- TAGKEYS( XK_4, 3)
- TAGKEYS( XK_5, 4)
- TAGKEYS( XK_6, 5)
- TAGKEYS( XK_7, 6)
- TAGKEYS( XK_8, 7)
- TAGKEYS( XK_9, 8)
- { MODKEY|ShiftMask, XK_q, quit, {0} },
-};
-
-/* button definitions */
-/* click can be ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */
-static Button buttons[] = {
- /* click event mask button function argument */
- { ClkLtSymbol, 0, Button1, setlayout, {0} },
- { ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} },
- { ClkWinTitle, 0, Button2, zoom, {0} },
- { ClkStatusText, 0, Button2, spawn, {.v = termcmd } },
- { ClkClientWin, MODKEY, Button1, movemouse, {0} },
- { ClkClientWin, MODKEY, Button2, togglefloating, {0} },
- { ClkClientWin, MODKEY, Button3, resizemouse, {0} },
- { ClkTagBar, 0, Button1, view, {0} },
- { ClkTagBar, 0, Button3, toggleview, {0} },
- { ClkTagBar, MODKEY, Button1, tag, {0} },
- { ClkTagBar, MODKEY, Button3, toggletag, {0} },
-};
-
diff --git a/.repos/dwm/config.h b/.repos/dwm/config.h
deleted file mode 100644
index 85682d4..0000000
--- a/.repos/dwm/config.h
+++ /dev/null
@@ -1,134 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-
-/* appearance */
-static const unsigned int borderpx = 1; /* border pixel of windows */
-static const unsigned int snap = 32; /* snap pixel */
-static const int showbar = 1; /* 0 means no bar */
-static const int topbar = 1; /* 0 means bottom bar */
-static const char *fonts[] = { "Iosevka Term:pixelsize=13:antialias=true:autohint=true" };
-static const char dmenufont[] = "Iosevka Term:pixelsize=13:antialias=true:autohint=true";
-static const char col_gray1[] = "#222222";
-static const char col_gray2[] = "#444444";
-static const char col_gray3[] = "#bbbbbb";
-static const char col_gray4[] = "#eeeeee";
-static const char col_cyan[] = "#005577";
-static const char *colors[][3] = {
- /* fg bg border */
- [SchemeNorm] = { col_gray3, col_gray1, col_gray2 },
- [SchemeSel] = { col_gray4, col_cyan, col_cyan },
-};
-
-typedef struct {
- const char *name;
- const void *cmd;
-} Sp;
-const char *spcmd1[] = {"st", "-n", "spterm", "-g", "120x34", NULL };
-const char *spcmd2[] = {"st", "-n", "spcalc", "-e", "python3", "-q", NULL };
-const char *spcmd3[] = {"keepassxc", NULL };
-static Sp scratchpads[] = {
- /* name cmd */
- {"spterm", spcmd1},
- {"spcalc", spcmd2},
- {"keepassxc", spcmd3},
-};
-
-/* tagging */
-static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" };
-static const Rule rules[] = {
- /* xprop(1):
- * WM_CLASS(STRING) = instance, class
- * WM_NAME(STRING) = title
- */
- /* class instance title tags mask isfloating monitor */
- { NULL, "spterm", NULL, SPTAG(0), 1, -1 },
- { NULL, "spcalc", NULL, SPTAG(1), 1, -1 },
- { NULL, "keepassxc",NULL, SPTAG(2), 1, -1 },
-};
-
-/* layout(s) */
-static const float mfact = 0.55; /* factor of master area size [0.05..0.95] */
-static const int nmaster = 1; /* number of clients in master area */
-static const int resizehints = 0; /* 1 means respect size hints in tiled resizals */
-static const int lockfullscreen = 1; /* 1 will force focus on the fullscreen window */
-
-static const Layout layouts[] = {
- /* symbol arrange function */
- { "[T]", tile }, /* first entry is default */
- { "[F]", NULL }, /* no layout function means floating behavior */
- { "[M]", monocle },
-};
-
-/* key definitions */
-#define MODKEY Mod4Mask
-#define TAGKEYS(KEY,TAG) \
- { MODKEY, KEY, view, {.ui = 1 << TAG} }, \
- { MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG} }, \
- { MODKEY|ShiftMask, KEY, tag, {.ui = 1 << TAG} }, \
- { MODKEY|ControlMask|ShiftMask, KEY, toggletag, {.ui = 1 << TAG} },
-
-/* helper for spawning shell commands in the pre dwm-5.0 fashion */
-#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }
-
-/* commands */
-static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */
-static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL };
-static const char *termcmd[] = { "st", NULL };
-
-
-static Key keys[] = {
- /* modifier key function argument */
- { MODKEY, XK_p, spawn, {.v = dmenucmd } },
- { MODKEY, XK_Return, spawn, {.v = termcmd } },
- { MODKEY, XK_b, togglebar, {0} },
- { MODKEY, XK_j, focusstack, {.i = +1 } },
- { MODKEY, XK_k, focusstack, {.i = -1 } },
- { MODKEY, XK_i, incnmaster, {.i = +1 } },
- { MODKEY, XK_d, incnmaster, {.i = -1 } },
- { MODKEY, XK_h, setmfact, {.f = -0.05} },
- { MODKEY, XK_l, setmfact, {.f = +0.05} },
- { MODKEY|ShiftMask, XK_j, zoom, {0} },
- { MODKEY, XK_Tab, view, {0} },
- { MODKEY, XK_q, killclient, {0} },
- { MODKEY, XK_t, setlayout, {.v = &layouts[0]} },
- { MODKEY, XK_f, setlayout, {.v = &layouts[1]} },
- { MODKEY, XK_m, setlayout, {.v = &layouts[2]} },
- { MODKEY, XK_space, setlayout, {0} },
- { MODKEY|ShiftMask, XK_space, togglefloating, {0} },
- { MODKEY, XK_0, view, {.ui = ~0 } },
- { MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } },
- { MODKEY, XK_comma, focusmon, {.i = -1 } },
- { MODKEY, XK_period, focusmon, {.i = +1 } },
- { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } },
- { MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } },
- { MODKEY|ShiftMask, XK_Return, togglescratch, {.ui = 0 } },
- { MODKEY, XK_apostrophe,togglescratch,{.ui = 1} },
- { MODKEY|ShiftMask, XK_l, togglescratch, {.ui = 2 } },
- TAGKEYS( XK_1, 0)
- TAGKEYS( XK_2, 1)
- TAGKEYS( XK_3, 2)
- TAGKEYS( XK_4, 3)
- TAGKEYS( XK_5, 4)
- TAGKEYS( XK_6, 5)
- TAGKEYS( XK_7, 6)
- TAGKEYS( XK_8, 7)
- TAGKEYS( XK_9, 8)
- { MODKEY|ShiftMask, XK_q, quit, {0} },
-};
-
-/* button definitions */
-/* click can be ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */
-static Button buttons[] = {
- /* click event mask button function argument */
- { ClkLtSymbol, 0, Button1, setlayout, {0} },
- { ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} },
- { ClkWinTitle, 0, Button2, zoom, {0} },
- { ClkStatusText, 0, Button2, spawn, {.v = termcmd } },
- { ClkClientWin, MODKEY, Button1, movemouse, {0} },
- { ClkClientWin, MODKEY, Button2, togglefloating, {0} },
- { ClkClientWin, MODKEY, Button3, resizemouse, {0} },
- { ClkTagBar, 0, Button1, view, {0} },
- { ClkTagBar, 0, Button3, toggleview, {0} },
- { ClkTagBar, MODKEY, Button1, tag, {0} },
- { ClkTagBar, MODKEY, Button3, toggletag, {0} },
-};
-
diff --git a/.repos/dwm/config.mk b/.repos/dwm/config.mk
deleted file mode 100644
index 7084c33..0000000
--- a/.repos/dwm/config.mk
+++ /dev/null
@@ -1,38 +0,0 @@
-# dwm version
-VERSION = 6.2
-
-# Customize below to fit your system
-
-# 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
-
-# includes and libs
-INCS = -I${X11INC} -I${FREETYPEINC}
-LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS}
-
-# flags
-CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=200809L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS}
-#CFLAGS = -g -std=c99 -pedantic -Wall -O0 ${INCS} ${CPPFLAGS}
-CFLAGS = -std=c99 -pedantic -Wall -Wno-deprecated-declarations -Os ${INCS} ${CPPFLAGS}
-LDFLAGS = ${LIBS}
-
-# Solaris
-#CFLAGS = -fast ${INCS} -DVERSION=\"${VERSION}\"
-#LDFLAGS = ${LIBS}
-
-# compiler and linker
-CC = cc
diff --git a/.repos/dwm/drw.c b/.repos/dwm/drw.c
deleted file mode 100644
index 4cdbcbe..0000000
--- a/.repos/dwm/drw.c
+++ /dev/null
@@ -1,436 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <X11/Xlib.h>
-#include <X11/Xft/Xft.h>
-
-#include "drw.h"
-#include "util.h"
-
-#define UTF_INVALID 0xFFFD
-#define UTF_SIZ 4
-
-static const unsigned char utfbyte[UTF_SIZ + 1] = {0x80, 0, 0xC0, 0xE0, 0xF0};
-static const unsigned char utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8};
-static const long utfmin[UTF_SIZ + 1] = { 0, 0, 0x80, 0x800, 0x10000};
-static const long utfmax[UTF_SIZ + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF};
-
-static long
-utf8decodebyte(const char c, size_t *i)
-{
- for (*i = 0; *i < (UTF_SIZ + 1); ++(*i))
- if (((unsigned char)c & utfmask[*i]) == utfbyte[*i])
- return (unsigned char)c & ~utfmask[*i];
- return 0;
-}
-
-static size_t
-utf8validate(long *u, size_t i)
-{
- if (!BETWEEN(*u, utfmin[i], utfmax[i]) || BETWEEN(*u, 0xD800, 0xDFFF))
- *u = UTF_INVALID;
- for (i = 1; *u > utfmax[i]; ++i)
- ;
- return i;
-}
-
-static size_t
-utf8decode(const char *c, long *u, size_t clen)
-{
- size_t i, j, len, type;
- long udecoded;
-
- *u = UTF_INVALID;
- if (!clen)
- return 0;
- udecoded = utf8decodebyte(c[0], &len);
- if (!BETWEEN(len, 1, UTF_SIZ))
- return 1;
- for (i = 1, j = 1; i < clen && j < len; ++i, ++j) {
- udecoded = (udecoded << 6) | utf8decodebyte(c[i], &type);
- if (type)
- return j;
- }
- if (j < len)
- return 0;
- *u = udecoded;
- utf8validate(u, len);
-
- 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.");
- }
-
- /* Do not allow using color fonts. This is a workaround for a BadLength
- * error from Xft with color glyphs. Modelled on the Xterm workaround. See
- * https://bugzilla.redhat.com/show_bug.cgi?id=1498269
- * https://lists.suckless.org/dev/1701/30932.html
- * https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=916349
- * and lots more all over the internet.
- */
- FcBool iscol;
- if(FcPatternGetBool(xfont->pattern, FC_COLOR, 0, &iscol) == FcResultMatch && iscol) {
- XftFontClose(drw->dpy, xfont);
- return NULL;
- }
-
- 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)
-{
- char buf[1024];
- int ty;
- unsigned int ew;
- XftDraw *d = NULL;
- Fnt *usedfont, *curfont, *nextfont;
- size_t i, len;
- int utf8strlen, utf8charlen, render = x || y || w || h;
- long utf8codepoint = 0;
- const char *utf8str;
- FcCharSet *fccharset;
- FcPattern *fcpattern;
- FcPattern *match;
- XftResult result;
- int charexists = 0;
-
- if (!drw || (render && !drw->scheme) || !text || !drw->fonts)
- return 0;
-
- if (!render) {
- w = ~w;
- } else {
- XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].pixel);
- XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
- d = XftDrawCreate(drw->dpy, drw->drawable,
- DefaultVisual(drw->dpy, drw->screen),
- DefaultColormap(drw->dpy, drw->screen));
- x += lpad;
- w -= lpad;
- }
-
- usedfont = drw->fonts;
- while (1) {
- utf8strlen = 0;
- utf8str = text;
- nextfont = NULL;
- while (*text) {
- utf8charlen = utf8decode(text, &utf8codepoint, UTF_SIZ);
- for (curfont = drw->fonts; curfont; curfont = curfont->next) {
- charexists = charexists || XftCharExists(drw->dpy, curfont->xfont, utf8codepoint);
- if (charexists) {
- if (curfont == usedfont) {
- utf8strlen += utf8charlen;
- text += utf8charlen;
- } else {
- nextfont = curfont;
- }
- break;
- }
- }
-
- if (!charexists || nextfont)
- break;
- else
- charexists = 0;
- }
-
- if (utf8strlen) {
- drw_font_getexts(usedfont, utf8str, utf8strlen, &ew, NULL);
- /* shorten text if necessary */
- for (len = MIN(utf8strlen, sizeof(buf) - 1); len && ew > w; len--)
- drw_font_getexts(usedfont, utf8str, len, &ew, NULL);
-
- if (len) {
- memcpy(buf, utf8str, len);
- buf[len] = '\0';
- if (len < utf8strlen)
- for (i = len; i && i > len - 3; buf[--i] = '.')
- ; /* NOP */
-
- if (render) {
- ty = y + (h - usedfont->h) / 2 + usedfont->xfont->ascent;
- XftDrawStringUtf8(d, &drw->scheme[invert ? ColBg : ColFg],
- usedfont->xfont, x, ty, (XftChar8 *)buf, len);
- }
- x += ew;
- w -= ew;
- }
- }
-
- if (!*text) {
- 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;
-
- 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);
- FcPatternAddBool(fcpattern, FC_COLOR, FcFalse);
-
- 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);
- 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);
-}
-
-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/.repos/dwm/drw.h b/.repos/dwm/drw.h
deleted file mode 100644
index 4bcd5ad..0000000
--- a/.repos/dwm/drw.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/* 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, ColBorder }; /* 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);
-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/.repos/dwm/drw.o b/.repos/dwm/drw.o
deleted file mode 100644
index b65f4ca..0000000
--- a/.repos/dwm/drw.o
+++ /dev/null
Binary files differ
diff --git a/.repos/dwm/dwm b/.repos/dwm/dwm
deleted file mode 100755
index 78c1cb2..0000000
--- a/.repos/dwm/dwm
+++ /dev/null
Binary files differ
diff --git a/.repos/dwm/dwm.1 b/.repos/dwm/dwm.1
deleted file mode 100644
index ddc8321..0000000
--- a/.repos/dwm/dwm.1
+++ /dev/null
@@ -1,176 +0,0 @@
-.TH DWM 1 dwm\-VERSION
-.SH NAME
-dwm \- dynamic window manager
-.SH SYNOPSIS
-.B dwm
-.RB [ \-v ]
-.SH DESCRIPTION
-dwm is a dynamic window manager for X. It manages windows in tiled, monocle
-and floating layouts. Either layout can be applied dynamically, optimising the
-environment for the application in use and the task performed.
-.P
-In tiled layouts windows are managed in a master and stacking area. The master
-area on the left contains one window by default, and the stacking area on the
-right contains all other windows. The number of master area windows can be
-adjusted from zero to an arbitrary number. In monocle layout all windows are
-maximised to the screen size. In floating layout windows can be resized and
-moved freely. Dialog windows are always managed floating, regardless of the
-layout applied.
-.P
-Windows are grouped by tags. Each window can be tagged with one or multiple
-tags. Selecting certain tags displays all windows with these tags.
-.P
-Each screen contains a small status bar which displays all available tags, the
-layout, the title of the focused window, and the text read from the root window
-name property, if the screen is focused. A floating window is indicated with an
-empty square and a maximised floating window is indicated with a filled square
-before the windows title. The selected tags are indicated with a different
-color. The tags of the focused window are indicated with a filled square in the
-top left corner. The tags which are applied to one or more windows are
-indicated with an empty square in the top left corner.
-.P
-dwm draws a small border around windows to indicate the focus state.
-.SH OPTIONS
-.TP
-.B \-v
-prints version information to stderr, then exits.
-.SH USAGE
-.SS Status bar
-.TP
-.B X root window name
-is read and displayed in the status text area. It can be set with the
-.BR xsetroot (1)
-command.
-.TP
-.B Button1
-click on a tag label to display all windows with that tag, click on the layout
-label toggles between tiled and floating layout.
-.TP
-.B Button3
-click on a tag label adds/removes all windows with that tag to/from the view.
-.TP
-.B Mod1\-Button1
-click on a tag label applies that tag to the focused window.
-.TP
-.B Mod1\-Button3
-click on a tag label adds/removes that tag to/from the focused window.
-.SS Keyboard commands
-.TP
-.B Mod1\-Shift\-Return
-Start
-.BR st(1).
-.TP
-.B Mod1\-p
-Spawn
-.BR dmenu(1)
-for launching other programs.
-.TP
-.B Mod1\-,
-Focus previous screen, if any.
-.TP
-.B Mod1\-.
-Focus next screen, if any.
-.TP
-.B Mod1\-Shift\-,
-Send focused window to previous screen, if any.
-.TP
-.B Mod1\-Shift\-.
-Send focused window to next screen, if any.
-.TP
-.B Mod1\-b
-Toggles bar on and off.
-.TP
-.B Mod1\-t
-Sets tiled layout.
-.TP
-.B Mod1\-f
-Sets floating layout.
-.TP
-.B Mod1\-m
-Sets monocle layout.
-.TP
-.B Mod1\-space
-Toggles between current and previous layout.
-.TP
-.B Mod1\-j
-Focus next window.
-.TP
-.B Mod1\-k
-Focus previous window.
-.TP
-.B Mod1\-i
-Increase number of windows in master area.
-.TP
-.B Mod1\-d
-Decrease number of windows in master area.
-.TP
-.B Mod1\-l
-Increase master area size.
-.TP
-.B Mod1\-h
-Decrease master area size.
-.TP
-.B Mod1\-Return
-Zooms/cycles focused window to/from master area (tiled layouts only).
-.TP
-.B Mod1\-Shift\-c
-Close focused window.
-.TP
-.B Mod1\-Shift\-space
-Toggle focused window between tiled and floating state.
-.TP
-.B Mod1\-Tab
-Toggles to the previously selected tags.
-.TP
-.B Mod1\-Shift\-[1..n]
-Apply nth tag to focused window.
-.TP
-.B Mod1\-Shift\-0
-Apply all tags to focused window.
-.TP
-.B Mod1\-Control\-Shift\-[1..n]
-Add/remove nth tag to/from focused window.
-.TP
-.B Mod1\-[1..n]
-View all windows with nth tag.
-.TP
-.B Mod1\-0
-View all windows with any tag.
-.TP
-.B Mod1\-Control\-[1..n]
-Add/remove all windows with nth tag to/from the view.
-.TP
-.B Mod1\-Shift\-q
-Quit dwm.
-.SS Mouse commands
-.TP
-.B Mod1\-Button1
-Move focused window while dragging. Tiled windows will be toggled to the floating state.
-.TP
-.B Mod1\-Button2
-Toggles focused window between floating and tiled state.
-.TP
-.B Mod1\-Button3
-Resize focused window while dragging. Tiled windows will be toggled to the floating state.
-.SH CUSTOMIZATION
-dwm is customized by creating a custom config.h and (re)compiling the source
-code. This keeps it fast, secure and simple.
-.SH SEE ALSO
-.BR dmenu (1),
-.BR st (1)
-.SH ISSUES
-Java applications which use the XToolkit/XAWT backend may draw grey windows
-only. The XToolkit/XAWT backend breaks ICCCM-compliance in recent JDK 1.5 and early
-JDK 1.6 versions, because it assumes a reparenting window manager. Possible workarounds
-are using JDK 1.4 (which doesn't contain the XToolkit/XAWT backend) or setting the
-environment variable
-.BR AWT_TOOLKIT=MToolkit
-(to use the older Motif backend instead) or running
-.B xprop -root -f _NET_WM_NAME 32a -set _NET_WM_NAME LG3D
-or
-.B wmname LG3D
-(to pretend that a non-reparenting window manager is running that the
-XToolkit/XAWT backend can recognize) or when using OpenJDK setting the environment variable
-.BR _JAVA_AWT_WM_NONREPARENTING=1 .
-.SH BUGS
-Send all bug reports with a patch to hackers@suckless.org.
diff --git a/.repos/dwm/dwm.c b/.repos/dwm/dwm.c
deleted file mode 100644
index 8e327ec..0000000
--- a/.repos/dwm/dwm.c
+++ /dev/null
@@ -1,2263 +0,0 @@
-/* See LICENSE file for copyright and license details.
- *
- * dynamic window manager is designed like any other X client as well. It is
- * driven through handling X events. In contrast to other X clients, a window
- * manager selects for SubstructureRedirectMask on the root window, to receive
- * events about window (dis-)appearance. Only one X connection at a time is
- * allowed to select for this event mask.
- *
- * The event handlers of dwm are organized in an array which is accessed
- * whenever a new event has been fetched. This allows event dispatching
- * in O(1) time.
- *
- * Each child of the root window is called a client, except windows which have
- * set the override_redirect flag. Clients are organized in a linked client
- * list on each monitor, the focus history is remembered through a stack list
- * on each monitor. Each client contains a bit array to indicate the tags of a
- * client.
- *
- * Keys and tagging rules are organized as arrays and defined in config.h.
- *
- * To understand everything else, start reading main().
- */
-#include <errno.h>
-#include <locale.h>
-#include <signal.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <X11/cursorfont.h>
-#include <X11/keysym.h>
-#include <X11/Xatom.h>
-#include <X11/Xlib.h>
-#include <X11/Xproto.h>
-#include <X11/Xutil.h>
-#ifdef XINERAMA
-#include <X11/extensions/Xinerama.h>
-#endif /* XINERAMA */
-#include <X11/Xft/Xft.h>
-
-#include "drw.h"
-#include "util.h"
-
-/* macros */
-#define BUTTONMASK (ButtonPressMask|ButtonReleaseMask)
-#define CLEANMASK(mask) (mask & ~(numlockmask|LockMask) & (ShiftMask|ControlMask|Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask))
-#define INTERSECT(x,y,w,h,m) (MAX(0, MIN((x)+(w),(m)->wx+(m)->ww) - MAX((x),(m)->wx)) \
- * MAX(0, MIN((y)+(h),(m)->wy+(m)->wh) - MAX((y),(m)->wy)))
-#define ISVISIBLE(C) ((C->tags & C->mon->tagset[C->mon->seltags]))
-#define LENGTH(X) (sizeof X / sizeof X[0])
-#define MOUSEMASK (BUTTONMASK|PointerMotionMask)
-#define WIDTH(X) ((X)->w + 2 * (X)->bw)
-#define HEIGHT(X) ((X)->h + 2 * (X)->bw)
-#define NUMTAGS (LENGTH(tags) + LENGTH(scratchpads))
-#define TAGMASK ((1 << NUMTAGS) - 1)
-#define SPTAG(i) ((1 << LENGTH(tags)) << (i))
-#define SPTAGMASK (((1 << LENGTH(scratchpads))-1) << LENGTH(tags))
-#define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad)
-
-/* enums */
-enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
-enum { SchemeNorm, SchemeSel }; /* color schemes */
-enum { NetSupported, NetWMName, NetWMState, NetWMCheck,
- NetWMFullscreen, NetActiveWindow, NetWMWindowType,
- NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */
-enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */
-enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle,
- ClkClientWin, ClkRootWin, ClkLast }; /* clicks */
-
-typedef union {
- int i;
- unsigned int ui;
- float f;
- const void *v;
-} Arg;
-
-typedef struct {
- unsigned int click;
- unsigned int mask;
- unsigned int button;
- void (*func)(const Arg *arg);
- const Arg arg;
-} Button;
-
-typedef struct Monitor Monitor;
-typedef struct Client Client;
-struct Client {
- char name[256];
- float mina, maxa;
- int x, y, w, h;
- int oldx, oldy, oldw, oldh;
- int basew, baseh, incw, inch, maxw, maxh, minw, minh;
- int bw, oldbw;
- unsigned int tags;
- int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen;
- Client *next;
- Client *snext;
- Monitor *mon;
- Window win;
-};
-
-typedef struct {
- unsigned int mod;
- KeySym keysym;
- void (*func)(const Arg *);
- const Arg arg;
-} Key;
-
-typedef struct {
- const char *symbol;
- void (*arrange)(Monitor *);
-} Layout;
-
-typedef struct Pertag Pertag;
-struct Monitor {
- char ltsymbol[16];
- float mfact;
- int nmaster;
- int num;
- int by; /* bar geometry */
- int mx, my, mw, mh; /* screen size */
- int wx, wy, ww, wh; /* window area */
- unsigned int seltags;
- unsigned int sellt;
- unsigned int tagset[2];
- int showbar;
- int topbar;
- Client *clients;
- Client *sel;
- Client *stack;
- Monitor *next;
- Window barwin;
- const Layout *lt[2];
- Pertag *pertag;
-};
-
-typedef struct {
- const char *class;
- const char *instance;
- const char *title;
- unsigned int tags;
- int isfloating;
- int monitor;
-} Rule;
-
-/* function declarations */
-static void applyrules(Client *c);
-static int applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact);
-static void arrange(Monitor *m);
-static void arrangemon(Monitor *m);
-static void attach(Client *c);
-static void attachstack(Client *c);
-static void buttonpress(XEvent *e);
-static void checkotherwm(void);
-static void cleanup(void);
-static void cleanupmon(Monitor *mon);
-static void clientmessage(XEvent *e);
-static void configure(Client *c);
-static void configurenotify(XEvent *e);
-static void configurerequest(XEvent *e);
-static Monitor *createmon(void);
-static void destroynotify(XEvent *e);
-static void detach(Client *c);
-static void detachstack(Client *c);
-static Monitor *dirtomon(int dir);
-static void drawbar(Monitor *m);
-static void drawbars(void);
-static void enternotify(XEvent *e);
-static void expose(XEvent *e);
-static void focus(Client *c);
-static void focusin(XEvent *e);
-static void focusmon(const Arg *arg);
-static void focusstack(const Arg *arg);
-static Atom getatomprop(Client *c, Atom prop);
-static int getrootptr(int *x, int *y);
-static long getstate(Window w);
-static int gettextprop(Window w, Atom atom, char *text, unsigned int size);
-static void grabbuttons(Client *c, int focused);
-static void grabkeys(void);
-static void incnmaster(const Arg *arg);
-static void keypress(XEvent *e);
-static void killclient(const Arg *arg);
-static void manage(Window w, XWindowAttributes *wa);
-static void mappingnotify(XEvent *e);
-static void maprequest(XEvent *e);
-static void monocle(Monitor *m);
-static void motionnotify(XEvent *e);
-static void movemouse(const Arg *arg);
-static Client *nexttiled(Client *c);
-static void pop(Client *);
-static void propertynotify(XEvent *e);
-static void quit(const Arg *arg);
-static Monitor *recttomon(int x, int y, int w, int h);
-static void resize(Client *c, int x, int y, int w, int h, int interact);
-static void resizeclient(Client *c, int x, int y, int w, int h);
-static void resizemouse(const Arg *arg);
-static void restack(Monitor *m);
-static void run(void);
-static void scan(void);
-static int sendevent(Client *c, Atom proto);
-static void sendmon(Client *c, Monitor *m);
-static void setclientstate(Client *c, long state);
-static void setfocus(Client *c);
-static void setfullscreen(Client *c, int fullscreen);
-static void setlayout(const Arg *arg);
-static void setmfact(const Arg *arg);
-static void setup(void);
-static void seturgent(Client *c, int urg);
-static void showhide(Client *c);
-static void sigchld(int unused);
-static void spawn(const Arg *arg);
-static void tag(const Arg *arg);
-static void tagmon(const Arg *arg);
-static void tile(Monitor *);
-static void togglebar(const Arg *arg);
-static void togglefloating(const Arg *arg);
-static void togglescratch(const Arg *arg);
-static void toggletag(const Arg *arg);
-static void toggleview(const Arg *arg);
-static void unfocus(Client *c, int setfocus);
-static void unmanage(Client *c, int destroyed);
-static void unmapnotify(XEvent *e);
-static void updatebarpos(Monitor *m);
-static void updatebars(void);
-static void updateclientlist(void);
-static int updategeom(void);
-static void updatenumlockmask(void);
-static void updatesizehints(Client *c);
-static void updatestatus(void);
-static void updatetitle(Client *c);
-static void updatewindowtype(Client *c);
-static void updatewmhints(Client *c);
-static void view(const Arg *arg);
-static Client *wintoclient(Window w);
-static Monitor *wintomon(Window w);
-static int xerror(Display *dpy, XErrorEvent *ee);
-static int xerrordummy(Display *dpy, XErrorEvent *ee);
-static int xerrorstart(Display *dpy, XErrorEvent *ee);
-static void zoom(const Arg *arg);
-
-/* variables */
-static const char broken[] = "broken";
-static char stext[256];
-static int screen;
-static int sw, sh; /* X display screen geometry width, height */
-static int bh, blw = 0; /* bar geometry */
-static int lrpad; /* sum of left and right padding for text */
-static int (*xerrorxlib)(Display *, XErrorEvent *);
-static unsigned int numlockmask = 0;
-static void (*handler[LASTEvent]) (XEvent *) = {
- [ButtonPress] = buttonpress,
- [ClientMessage] = clientmessage,
- [ConfigureRequest] = configurerequest,
- [ConfigureNotify] = configurenotify,
- [DestroyNotify] = destroynotify,
- [EnterNotify] = enternotify,
- [Expose] = expose,
- [FocusIn] = focusin,
- [KeyPress] = keypress,
- [MappingNotify] = mappingnotify,
- [MapRequest] = maprequest,
- [MotionNotify] = motionnotify,
- [PropertyNotify] = propertynotify,
- [UnmapNotify] = unmapnotify
-};
-static Atom wmatom[WMLast], netatom[NetLast];
-static int running = 1;
-static Cur *cursor[CurLast];
-static Clr **scheme;
-static Display *dpy;
-static Drw *drw;
-static Monitor *mons, *selmon;
-static Window root, wmcheckwin;
-
-/* configuration, allows nested code to access above variables */
-#include "config.h"
-
-struct Pertag {
- unsigned int curtag, prevtag; /* current and previous tag */
- int nmasters[LENGTH(tags) + 1]; /* number of windows in master area */
- float mfacts[LENGTH(tags) + 1]; /* mfacts per tag */
- unsigned int sellts[LENGTH(tags) + 1]; /* selected layouts */
- const Layout *ltidxs[LENGTH(tags) + 1][2]; /* matrix of tags and layouts indexes */
- int showbars[LENGTH(tags) + 1]; /* display bar for the current tag */
-};
-
-/* compile-time check if all tags fit into an unsigned int bit array. */
-struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; };
-
-/* function implementations */
-void
-applyrules(Client *c)
-{
- const char *class, *instance;
- unsigned int i;
- const Rule *r;
- Monitor *m;
- XClassHint ch = { NULL, NULL };
-
- /* rule matching */
- c->isfloating = 0;
- c->tags = 0;
- XGetClassHint(dpy, c->win, &ch);
- class = ch.res_class ? ch.res_class : broken;
- instance = ch.res_name ? ch.res_name : broken;
-
- for (i = 0; i < LENGTH(rules); i++) {
- r = &rules[i];
- if ((!r->title || strstr(c->name, r->title))
- && (!r->class || strstr(class, r->class))
- && (!r->instance || strstr(instance, r->instance)))
- {
- c->isfloating = r->isfloating;
- c->tags |= r->tags;
- if ((r->tags & SPTAGMASK) && r->isfloating) {
- c->x = c->mon->wx + (c->mon->ww / 2 - WIDTH(c) / 2);
- c->y = c->mon->wy + (c->mon->wh / 2 - HEIGHT(c) / 2);
- }
-
- for (m = mons; m && m->num != r->monitor; m = m->next);
- if (m)
- c->mon = m;
- }
- }
- if (ch.res_class)
- XFree(ch.res_class);
- if (ch.res_name)
- XFree(ch.res_name);
- c->tags = c->tags & TAGMASK ? c->tags & TAGMASK : (c->mon->tagset[c->mon->seltags] & ~SPTAGMASK);
-}
-
-int
-applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact)
-{
- int baseismin;
- Monitor *m = c->mon;
-
- /* set minimum possible */
- *w = MAX(1, *w);
- *h = MAX(1, *h);
- if (interact) {
- if (*x > sw)
- *x = sw - WIDTH(c);
- if (*y > sh)
- *y = sh - HEIGHT(c);
- if (*x + *w + 2 * c->bw < 0)
- *x = 0;
- if (*y + *h + 2 * c->bw < 0)
- *y = 0;
- } else {
- if (*x >= m->wx + m->ww)
- *x = m->wx + m->ww - WIDTH(c);
- if (*y >= m->wy + m->wh)
- *y = m->wy + m->wh - HEIGHT(c);
- if (*x + *w + 2 * c->bw <= m->wx)
- *x = m->wx;
- if (*y + *h + 2 * c->bw <= m->wy)
- *y = m->wy;
- }
- if (*h < bh)
- *h = bh;
- if (*w < bh)
- *w = bh;
- if (resizehints || c->isfloating || !c->mon->lt[c->mon->sellt]->arrange) {
- /* see last two sentences in ICCCM 4.1.2.3 */
- baseismin = c->basew == c->minw && c->baseh == c->minh;
- if (!baseismin) { /* temporarily remove base dimensions */
- *w -= c->basew;
- *h -= c->baseh;
- }
- /* adjust for aspect limits */
- if (c->mina > 0 && c->maxa > 0) {
- if (c->maxa < (float)*w / *h)
- *w = *h * c->maxa + 0.5;
- else if (c->mina < (float)*h / *w)
- *h = *w * c->mina + 0.5;
- }
- if (baseismin) { /* increment calculation requires this */
- *w -= c->basew;
- *h -= c->baseh;
- }
- /* adjust for increment value */
- if (c->incw)
- *w -= *w % c->incw;
- if (c->inch)
- *h -= *h % c->inch;
- /* restore base dimensions */
- *w = MAX(*w + c->basew, c->minw);
- *h = MAX(*h + c->baseh, c->minh);
- if (c->maxw)
- *w = MIN(*w, c->maxw);
- if (c->maxh)
- *h = MIN(*h, c->maxh);
- }
- return *x != c->x || *y != c->y || *w != c->w || *h != c->h;
-}
-
-void
-arrange(Monitor *m)
-{
- if (m)
- showhide(m->stack);
- else for (m = mons; m; m = m->next)
- showhide(m->stack);
- if (m) {
- arrangemon(m);
- restack(m);
- } else for (m = mons; m; m = m->next)
- arrangemon(m);
-}
-
-void
-arrangemon(Monitor *m)
-{
- strncpy(m->ltsymbol, m->lt[m->sellt]->symbol, sizeof m->ltsymbol);
- if (m->lt[m->sellt]->arrange)
- m->lt[m->sellt]->arrange(m);
-}
-
-void
-attach(Client *c)
-{
- c->next = c->mon->clients;
- c->mon->clients = c;
-}
-
-void
-attachstack(Client *c)
-{
- c->snext = c->mon->stack;
- c->mon->stack = c;
-}
-
-void
-buttonpress(XEvent *e)
-{
- unsigned int i, x, click;
- Arg arg = {0};
- Client *c;
- Monitor *m;
- XButtonPressedEvent *ev = &e->xbutton;
-
- click = ClkRootWin;
- /* focus monitor if necessary */
- if ((m = wintomon(ev->window)) && m != selmon) {
- unfocus(selmon->sel, 1);
- selmon = m;
- focus(NULL);
- }
- if (ev->window == selmon->barwin) {
- i = x = 0;
- do
- x += TEXTW(tags[i]);
- while (ev->x >= x && ++i < LENGTH(tags));
- if (i < LENGTH(tags)) {
- click = ClkTagBar;
- arg.ui = 1 << i;
- } else if (ev->x < x + blw)
- click = ClkLtSymbol;
- else if (ev->x > selmon->ww - (int)TEXTW(stext))
- click = ClkStatusText;
- else
- click = ClkWinTitle;
- } else if ((c = wintoclient(ev->window))) {
- focus(c);
- restack(selmon);
- XAllowEvents(dpy, ReplayPointer, CurrentTime);
- click = ClkClientWin;
- }
- for (i = 0; i < LENGTH(buttons); i++)
- if (click == buttons[i].click && buttons[i].func && buttons[i].button == ev->button
- && CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state))
- buttons[i].func(click == ClkTagBar && buttons[i].arg.i == 0 ? &arg : &buttons[i].arg);
-}
-
-void
-checkotherwm(void)
-{
- xerrorxlib = XSetErrorHandler(xerrorstart);
- /* this causes an error if some other window manager is running */
- XSelectInput(dpy, DefaultRootWindow(dpy), SubstructureRedirectMask);
- XSync(dpy, False);
- XSetErrorHandler(xerror);
- XSync(dpy, False);
-}
-
-void
-cleanup(void)
-{
- Arg a = {.ui = ~0};
- Layout foo = { "", NULL };
- Monitor *m;
- size_t i;
-
- view(&a);
- selmon->lt[selmon->sellt] = &foo;
- for (m = mons; m; m = m->next)
- while (m->stack)
- unmanage(m->stack, 0);
- XUngrabKey(dpy, AnyKey, AnyModifier, root);
- while (mons)
- cleanupmon(mons);
- for (i = 0; i < CurLast; i++)
- drw_cur_free(drw, cursor[i]);
- for (i = 0; i < LENGTH(colors); i++)
- free(scheme[i]);
- XDestroyWindow(dpy, wmcheckwin);
- drw_free(drw);
- XSync(dpy, False);
- XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime);
- XDeleteProperty(dpy, root, netatom[NetActiveWindow]);
-}
-
-void
-cleanupmon(Monitor *mon)
-{
- Monitor *m;
-
- if (mon == mons)
- mons = mons->next;
- else {
- for (m = mons; m && m->next != mon; m = m->next);
- m->next = mon->next;
- }
- XUnmapWindow(dpy, mon->barwin);
- XDestroyWindow(dpy, mon->barwin);
- free(mon);
-}
-
-void
-clientmessage(XEvent *e)
-{
- XClientMessageEvent *cme = &e->xclient;
- Client *c = wintoclient(cme->window);
-
- if (!c)
- return;
- if (cme->message_type == netatom[NetWMState]) {
- if (cme->data.l[1] == netatom[NetWMFullscreen]
- || cme->data.l[2] == netatom[NetWMFullscreen])
- setfullscreen(c, (cme->data.l[0] == 1 /* _NET_WM_STATE_ADD */
- || (cme->data.l[0] == 2 /* _NET_WM_STATE_TOGGLE */ && !c->isfullscreen)));
- } else if (cme->message_type == netatom[NetActiveWindow]) {
- if (c != selmon->sel && !c->isurgent)
- seturgent(c, 1);
- }
-}
-
-void
-configure(Client *c)
-{
- XConfigureEvent ce;
-
- ce.type = ConfigureNotify;
- ce.display = dpy;
- ce.event = c->win;
- ce.window = c->win;
- ce.x = c->x;
- ce.y = c->y;
- ce.width = c->w;
- ce.height = c->h;
- ce.border_width = c->bw;
- ce.above = None;
- ce.override_redirect = False;
- XSendEvent(dpy, c->win, False, StructureNotifyMask, (XEvent *)&ce);
-}
-
-void
-configurenotify(XEvent *e)
-{
- Monitor *m;
- Client *c;
- XConfigureEvent *ev = &e->xconfigure;
- int dirty;
-
- /* TODO: updategeom handling sucks, needs to be simplified */
- if (ev->window == root) {
- dirty = (sw != ev->width || sh != ev->height);
- sw = ev->width;
- sh = ev->height;
- if (updategeom() || dirty) {
- drw_resize(drw, sw, bh);
- updatebars();
- for (m = mons; m; m = m->next) {
- for (c = m->clients; c; c = c->next)
- if (c->isfullscreen)
- resizeclient(c, m->mx, m->my, m->mw, m->mh);
- XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, bh);
- }
- focus(NULL);
- arrange(NULL);
- }
- }
-}
-
-void
-configurerequest(XEvent *e)
-{
- Client *c;
- Monitor *m;
- XConfigureRequestEvent *ev = &e->xconfigurerequest;
- XWindowChanges wc;
-
- if ((c = wintoclient(ev->window))) {
- if (ev->value_mask & CWBorderWidth)
- c->bw = ev->border_width;
- else if (c->isfloating || !selmon->lt[selmon->sellt]->arrange) {
- m = c->mon;
- if (ev->value_mask & CWX) {
- c->oldx = c->x;
- c->x = m->mx + ev->x;
- }
- if (ev->value_mask & CWY) {
- c->oldy = c->y;
- c->y = m->my + ev->y;
- }
- if (ev->value_mask & CWWidth) {
- c->oldw = c->w;
- c->w = ev->width;
- }
- if (ev->value_mask & CWHeight) {
- c->oldh = c->h;
- c->h = ev->height;
- }
- if ((c->x + c->w) > m->mx + m->mw && c->isfloating)
- c->x = m->mx + (m->mw / 2 - WIDTH(c) / 2); /* center in x direction */
- if ((c->y + c->h) > m->my + m->mh && c->isfloating)
- c->y = m->my + (m->mh / 2 - HEIGHT(c) / 2); /* center in y direction */
- if ((ev->value_mask & (CWX|CWY)) && !(ev->value_mask & (CWWidth|CWHeight)))
- configure(c);
- if (ISVISIBLE(c))
- XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h);
- } else
- configure(c);
- } else {
- wc.x = ev->x;
- wc.y = ev->y;
- wc.width = ev->width;
- wc.height = ev->height;
- wc.border_width = ev->border_width;
- wc.sibling = ev->above;
- wc.stack_mode = ev->detail;
- XConfigureWindow(dpy, ev->window, ev->value_mask, &wc);
- }
- XSync(dpy, False);
-}
-
-Monitor *
-createmon(void)
-{
- Monitor *m;
- unsigned int i;
-
- m = ecalloc(1, sizeof(Monitor));
- m->tagset[0] = m->tagset[1] = 1;
- m->mfact = mfact;
- m->nmaster = nmaster;
- m->showbar = showbar;
- m->topbar = topbar;
- m->lt[0] = &layouts[0];
- m->lt[1] = &layouts[1 % LENGTH(layouts)];
- strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol);
- m->pertag = ecalloc(1, sizeof(Pertag));
- m->pertag->curtag = m->pertag->prevtag = 1;
-
- for (i = 0; i <= LENGTH(tags); i++) {
- m->pertag->nmasters[i] = m->nmaster;
- m->pertag->mfacts[i] = m->mfact;
-
- m->pertag->ltidxs[i][0] = m->lt[0];
- m->pertag->ltidxs[i][1] = m->lt[1];
- m->pertag->sellts[i] = m->sellt;
-
- m->pertag->showbars[i] = m->showbar;
- }
-
- return m;
-}
-
-void
-destroynotify(XEvent *e)
-{
- Client *c;
- XDestroyWindowEvent *ev = &e->xdestroywindow;
-
- if ((c = wintoclient(ev->window)))
- unmanage(c, 1);
-}
-
-void
-detach(Client *c)
-{
- Client **tc;
-
- for (tc = &c->mon->clients; *tc && *tc != c; tc = &(*tc)->next);
- *tc = c->next;
-}
-
-void
-detachstack(Client *c)
-{
- Client **tc, *t;
-
- for (tc = &c->mon->stack; *tc && *tc != c; tc = &(*tc)->snext);
- *tc = c->snext;
-
- if (c == c->mon->sel) {
- for (t = c->mon->stack; t && !ISVISIBLE(t); t = t->snext);
- c->mon->sel = t;
- }
-}
-
-Monitor *
-dirtomon(int dir)
-{
- Monitor *m = NULL;
-
- if (dir > 0) {
- if (!(m = selmon->next))
- m = mons;
- } else if (selmon == mons)
- for (m = mons; m->next; m = m->next);
- else
- for (m = mons; m->next != selmon; m = m->next);
- return m;
-}
-
-void
-drawbar(Monitor *m)
-{
- int x, w, tw = 0;
- int boxs = drw->fonts->h / 9;
- int boxw = drw->fonts->h / 6 + 2;
- unsigned int i, occ = 0, urg = 0;
- Client *c;
-
- /* draw status first so it can be overdrawn by tags later */
- if (m == selmon) { /* status is only drawn on selected monitor */
- drw_setscheme(drw, scheme[SchemeNorm]);
- tw = TEXTW(stext) - lrpad + 2; /* 2px right padding */
- drw_text(drw, m->ww - tw, 0, tw, bh, 0, stext, 0);
- }
-
- for (c = m->clients; c; c = c->next) {
- occ |= c->tags;
- if (c->isurgent)
- urg |= c->tags;
- }
- x = 0;
- for (i = 0; i < LENGTH(tags); i++) {
- w = TEXTW(tags[i]);
- drw_setscheme(drw, scheme[m->tagset[m->seltags] & 1 << i ? SchemeSel : SchemeNorm]);
- drw_text(drw, x, 0, w, bh, lrpad / 2, tags[i], urg & 1 << i);
- if (occ & 1 << i)
- drw_rect(drw, x + boxs, boxs, boxw, boxw,
- m == selmon && selmon->sel && selmon->sel->tags & 1 << i,
- urg & 1 << i);
- x += w;
- }
- w = blw = TEXTW(m->ltsymbol);
- drw_setscheme(drw, scheme[SchemeNorm]);
- x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0);
-
- if ((w = m->ww - tw - x) > bh) {
- if (m->sel) {
- drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]);
- drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0);
- if (m->sel->isfloating)
- drw_rect(drw, x + boxs, boxs, boxw, boxw, m->sel->isfixed, 0);
- } else {
- drw_setscheme(drw, scheme[SchemeNorm]);
- drw_rect(drw, x, 0, w, bh, 1, 1);
- }
- }
- drw_map(drw, m->barwin, 0, 0, m->ww, bh);
-}
-
-void
-drawbars(void)
-{
- Monitor *m;
-
- for (m = mons; m; m = m->next)
- drawbar(m);
-}
-
-void
-enternotify(XEvent *e)
-{
- Client *c;
- Monitor *m;
- XCrossingEvent *ev = &e->xcrossing;
-
- if ((ev->mode != NotifyNormal || ev->detail == NotifyInferior) && ev->window != root)
- return;
- c = wintoclient(ev->window);
- m = c ? c->mon : wintomon(ev->window);
- if (m != selmon) {
- unfocus(selmon->sel, 1);
- selmon = m;
- } else if (!c || c == selmon->sel)
- return;
- focus(c);
-}
-
-void
-expose(XEvent *e)
-{
- Monitor *m;
- XExposeEvent *ev = &e->xexpose;
-
- if (ev->count == 0 && (m = wintomon(ev->window)))
- drawbar(m);
-}
-
-void
-focus(Client *c)
-{
- if (!c || !ISVISIBLE(c))
- for (c = selmon->stack; c && !ISVISIBLE(c); c = c->snext);
- if (selmon->sel && selmon->sel != c)
- unfocus(selmon->sel, 0);
- if (c) {
- if (c->mon != selmon)
- selmon = c->mon;
- if (c->isurgent)
- seturgent(c, 0);
- detachstack(c);
- attachstack(c);
- grabbuttons(c, 1);
- XSetWindowBorder(dpy, c->win, scheme[SchemeSel][ColBorder].pixel);
- setfocus(c);
- } else {
- XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
- XDeleteProperty(dpy, root, netatom[NetActiveWindow]);
- }
- selmon->sel = c;
- drawbars();
-}
-
-/* there are some broken focus acquiring clients needing extra handling */
-void
-focusin(XEvent *e)
-{
- XFocusChangeEvent *ev = &e->xfocus;
-
- if (selmon->sel && ev->window != selmon->sel->win)
- setfocus(selmon->sel);
-}
-
-void
-focusmon(const Arg *arg)
-{
- Monitor *m;
-
- if (!mons->next)
- return;
- if ((m = dirtomon(arg->i)) == selmon)
- return;
- unfocus(selmon->sel, 0);
- selmon = m;
- focus(NULL);
-}
-
-void
-focusstack(const Arg *arg)
-{
- Client *c = NULL, *i;
-
- if (!selmon->sel || (selmon->sel->isfullscreen && lockfullscreen))
- return;
- if (arg->i > 0) {
- for (c = selmon->sel->next; c && !ISVISIBLE(c); c = c->next);
- if (!c)
- for (c = selmon->clients; c && !ISVISIBLE(c); c = c->next);
- } else {
- for (i = selmon->clients; i != selmon->sel; i = i->next)
- if (ISVISIBLE(i))
- c = i;
- if (!c)
- for (; i; i = i->next)
- if (ISVISIBLE(i))
- c = i;
- }
- if (c) {
- focus(c);
- restack(selmon);
- }
-}
-
-Atom
-getatomprop(Client *c, Atom prop)
-{
- int di;
- unsigned long dl;
- unsigned char *p = NULL;
- Atom da, atom = None;
-
- if (XGetWindowProperty(dpy, c->win, prop, 0L, sizeof atom, False, XA_ATOM,
- &da, &di, &dl, &dl, &p) == Success && p) {
- atom = *(Atom *)p;
- XFree(p);
- }
- return atom;
-}
-
-int
-getrootptr(int *x, int *y)
-{
- int di;
- unsigned int dui;
- Window dummy;
-
- return XQueryPointer(dpy, root, &dummy, &dummy, x, y, &di, &di, &dui);
-}
-
-long
-getstate(Window w)
-{
- int format;
- long result = -1;
- unsigned char *p = NULL;
- unsigned long n, extra;
- Atom real;
-
- if (XGetWindowProperty(dpy, w, wmatom[WMState], 0L, 2L, False, wmatom[WMState],
- &real, &format, &n, &extra, (unsigned char **)&p) != Success)
- return -1;
- if (n != 0)
- result = *p;
- XFree(p);
- return result;
-}
-
-int
-gettextprop(Window w, Atom atom, char *text, unsigned int size)
-{
- char **list = NULL;
- int n;
- XTextProperty name;
-
- if (!text || size == 0)
- return 0;
- text[0] = '\0';
- if (!XGetTextProperty(dpy, w, &name, atom) || !name.nitems)
- return 0;
- if (name.encoding == XA_STRING)
- strncpy(text, (char *)name.value, size - 1);
- else {
- if (XmbTextPropertyToTextList(dpy, &name, &list, &n) >= Success && n > 0 && *list) {
- strncpy(text, *list, size - 1);
- XFreeStringList(list);
- }
- }
- text[size - 1] = '\0';
- XFree(name.value);
- return 1;
-}
-
-void
-grabbuttons(Client *c, int focused)
-{
- updatenumlockmask();
- {
- unsigned int i, j;
- unsigned int modifiers[] = { 0, LockMask, numlockmask, numlockmask|LockMask };
- XUngrabButton(dpy, AnyButton, AnyModifier, c->win);
- if (!focused)
- XGrabButton(dpy, AnyButton, AnyModifier, c->win, False,
- BUTTONMASK, GrabModeSync, GrabModeSync, None, None);
- for (i = 0; i < LENGTH(buttons); i++)
- if (buttons[i].click == ClkClientWin)
- for (j = 0; j < LENGTH(modifiers); j++)
- XGrabButton(dpy, buttons[i].button,
- buttons[i].mask | modifiers[j],
- c->win, False, BUTTONMASK,
- GrabModeAsync, GrabModeSync, None, None);
- }
-}
-
-void
-grabkeys(void)
-{
- updatenumlockmask();
- {
- unsigned int i, j;
- unsigned int modifiers[] = { 0, LockMask, numlockmask, numlockmask|LockMask };
- KeyCode code;
-
- XUngrabKey(dpy, AnyKey, AnyModifier, root);
- for (i = 0; i < LENGTH(keys); i++)
- if ((code = XKeysymToKeycode(dpy, keys[i].keysym)))
- for (j = 0; j < LENGTH(modifiers); j++)
- XGrabKey(dpy, code, keys[i].mod | modifiers[j], root,
- True, GrabModeAsync, GrabModeAsync);
- }
-}
-
-void
-incnmaster(const Arg *arg)
-{
- selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag] = MAX(selmon->nmaster + arg->i, 0);
- arrange(selmon);
-}
-
-#ifdef XINERAMA
-static int
-isuniquegeom(XineramaScreenInfo *unique, size_t n, XineramaScreenInfo *info)
-{
- while (n--)
- if (unique[n].x_org == info->x_org && unique[n].y_org == info->y_org
- && unique[n].width == info->width && unique[n].height == info->height)
- return 0;
- return 1;
-}
-#endif /* XINERAMA */
-
-void
-keypress(XEvent *e)
-{
- unsigned int i;
- KeySym keysym;
- XKeyEvent *ev;
-
- ev = &e->xkey;
- keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0);
- for (i = 0; i < LENGTH(keys); i++)
- if (keysym == keys[i].keysym
- && CLEANMASK(keys[i].mod) == CLEANMASK(ev->state)
- && keys[i].func)
- keys[i].func(&(keys[i].arg));
-}
-
-void
-killclient(const Arg *arg)
-{
- if (!selmon->sel)
- return;
- if (!sendevent(selmon->sel, wmatom[WMDelete])) {
- XGrabServer(dpy);
- XSetErrorHandler(xerrordummy);
- XSetCloseDownMode(dpy, DestroyAll);
- XKillClient(dpy, selmon->sel->win);
- XSync(dpy, False);
- XSetErrorHandler(xerror);
- XUngrabServer(dpy);
- }
-}
-
-void
-manage(Window w, XWindowAttributes *wa)
-{
- Client *c, *t = NULL;
- Window trans = None;
- XWindowChanges wc;
-
- c = ecalloc(1, sizeof(Client));
- c->win = w;
- /* geometry */
- c->x = c->oldx = wa->x;
- c->y = c->oldy = wa->y;
- c->w = c->oldw = wa->width;
- c->h = c->oldh = wa->height;
- c->oldbw = wa->border_width;
-
- updatetitle(c);
- if (XGetTransientForHint(dpy, w, &trans) && (t = wintoclient(trans))) {
- c->mon = t->mon;
- c->tags = t->tags;
- } else {
- c->mon = selmon;
- applyrules(c);
- }
-
- if (c->x + WIDTH(c) > c->mon->mx + c->mon->mw)
- c->x = c->mon->mx + c->mon->mw - WIDTH(c);
- if (c->y + HEIGHT(c) > c->mon->my + c->mon->mh)
- c->y = c->mon->my + c->mon->mh - HEIGHT(c);
- c->x = MAX(c->x, c->mon->mx);
- /* only fix client y-offset, if the client center might cover the bar */
- c->y = MAX(c->y, ((c->mon->by == c->mon->my) && (c->x + (c->w / 2) >= c->mon->wx)
- && (c->x + (c->w / 2) < c->mon->wx + c->mon->ww)) ? bh : c->mon->my);
- c->bw = borderpx;
-
- wc.border_width = c->bw;
- XConfigureWindow(dpy, w, CWBorderWidth, &wc);
- XSetWindowBorder(dpy, w, scheme[SchemeNorm][ColBorder].pixel);
- configure(c); /* propagates border_width, if size doesn't change */
- updatewindowtype(c);
- updatesizehints(c);
- updatewmhints(c);
- XSelectInput(dpy, w, EnterWindowMask|FocusChangeMask|PropertyChangeMask|StructureNotifyMask);
- grabbuttons(c, 0);
- if (!c->isfloating)
- c->isfloating = c->oldstate = trans != None || c->isfixed;
- if (c->isfloating)
- XRaiseWindow(dpy, c->win);
- attach(c);
- attachstack(c);
- XChangeProperty(dpy, root, netatom[NetClientList], XA_WINDOW, 32, PropModeAppend,
- (unsigned char *) &(c->win), 1);
- XMoveResizeWindow(dpy, c->win, c->x + 2 * sw, c->y, c->w, c->h); /* some windows require this */
- setclientstate(c, NormalState);
- if (c->mon == selmon)
- unfocus(selmon->sel, 0);
- c->mon->sel = c;
- arrange(c->mon);
- XMapWindow(dpy, c->win);
- focus(NULL);
-}
-
-void
-mappingnotify(XEvent *e)
-{
- XMappingEvent *ev = &e->xmapping;
-
- XRefreshKeyboardMapping(ev);
- if (ev->request == MappingKeyboard)
- grabkeys();
-}
-
-void
-maprequest(XEvent *e)
-{
- static XWindowAttributes wa;
- XMapRequestEvent *ev = &e->xmaprequest;
-
- if (!XGetWindowAttributes(dpy, ev->window, &wa))
- return;
- if (wa.override_redirect)
- return;
- if (!wintoclient(ev->window))
- manage(ev->window, &wa);
-}
-
-void
-monocle(Monitor *m)
-{
- unsigned int n = 0;
- Client *c;
-
- for (c = m->clients; c; c = c->next)
- if (ISVISIBLE(c))
- n++;
- if (n > 0) /* override layout symbol */
- snprintf(m->ltsymbol, sizeof m->ltsymbol, "[%d]", n);
- for (c = nexttiled(m->clients); c; c = nexttiled(c->next))
- resize(c, m->wx, m->wy, m->ww - 2 * c->bw, m->wh - 2 * c->bw, 0);
-}
-
-void
-motionnotify(XEvent *e)
-{
- static Monitor *mon = NULL;
- Monitor *m;
- XMotionEvent *ev = &e->xmotion;
-
- if (ev->window != root)
- return;
- if ((m = recttomon(ev->x_root, ev->y_root, 1, 1)) != mon && mon) {
- unfocus(selmon->sel, 1);
- selmon = m;
- focus(NULL);
- }
- mon = m;
-}
-
-void
-movemouse(const Arg *arg)
-{
- int x, y, ocx, ocy, nx, ny;
- Client *c;
- Monitor *m;
- XEvent ev;
- Time lasttime = 0;
-
- if (!(c = selmon->sel))
- return;
- if (c->isfullscreen) /* no support moving fullscreen windows by mouse */
- return;
- restack(selmon);
- ocx = c->x;
- ocy = c->y;
- if (XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync,
- None, cursor[CurMove]->cursor, CurrentTime) != GrabSuccess)
- return;
- if (!getrootptr(&x, &y))
- return;
- do {
- XMaskEvent(dpy, MOUSEMASK|ExposureMask|SubstructureRedirectMask, &ev);
- switch(ev.type) {
- case ConfigureRequest:
- case Expose:
- case MapRequest:
- handler[ev.type](&ev);
- break;
- case MotionNotify:
- if ((ev.xmotion.time - lasttime) <= (1000 / 60))
- continue;
- lasttime = ev.xmotion.time;
-
- nx = ocx + (ev.xmotion.x - x);
- ny = ocy + (ev.xmotion.y - y);
- if (abs(selmon->wx - nx) < snap)
- nx = selmon->wx;
- else if (abs((selmon->wx + selmon->ww) - (nx + WIDTH(c))) < snap)
- nx = selmon->wx + selmon->ww - WIDTH(c);
- if (abs(selmon->wy - ny) < snap)
- ny = selmon->wy;
- else if (abs((selmon->wy + selmon->wh) - (ny + HEIGHT(c))) < snap)
- ny = selmon->wy + selmon->wh - HEIGHT(c);
- if (!c->isfloating && selmon->lt[selmon->sellt]->arrange
- && (abs(nx - c->x) > snap || abs(ny - c->y) > snap))
- togglefloating(NULL);
- if (!selmon->lt[selmon->sellt]->arrange || c->isfloating)
- resize(c, nx, ny, c->w, c->h, 1);
- break;
- }
- } while (ev.type != ButtonRelease);
- XUngrabPointer(dpy, CurrentTime);
- if ((m = recttomon(c->x, c->y, c->w, c->h)) != selmon) {
- sendmon(c, m);
- selmon = m;
- focus(NULL);
- }
-}
-
-Client *
-nexttiled(Client *c)
-{
- for (; c && (c->isfloating || !ISVISIBLE(c)); c = c->next);
- return c;
-}
-
-void
-pop(Client *c)
-{
- detach(c);
- attach(c);
- focus(c);
- arrange(c->mon);
-}
-
-void
-propertynotify(XEvent *e)
-{
- Client *c;
- Window trans;
- XPropertyEvent *ev = &e->xproperty;
-
- if ((ev->window == root) && (ev->atom == XA_WM_NAME))
- updatestatus();
- else if (ev->state == PropertyDelete)
- return; /* ignore */
- else if ((c = wintoclient(ev->window))) {
- switch(ev->atom) {
- default: break;
- case XA_WM_TRANSIENT_FOR:
- if (!c->isfloating && (XGetTransientForHint(dpy, c->win, &trans)) &&
- (c->isfloating = (wintoclient(trans)) != NULL))
- arrange(c->mon);
- break;
- case XA_WM_NORMAL_HINTS:
- updatesizehints(c);
- break;
- case XA_WM_HINTS:
- updatewmhints(c);
- drawbars();
- break;
- }
- if (ev->atom == XA_WM_NAME || ev->atom == netatom[NetWMName]) {
- updatetitle(c);
- if (c == c->mon->sel)
- drawbar(c->mon);
- }
- if (ev->atom == netatom[NetWMWindowType])
- updatewindowtype(c);
- }
-}
-
-void
-quit(const Arg *arg)
-{
- running = 0;
-}
-
-Monitor *
-recttomon(int x, int y, int w, int h)
-{
- Monitor *m, *r = selmon;
- int a, area = 0;
-
- for (m = mons; m; m = m->next)
- if ((a = INTERSECT(x, y, w, h, m)) > area) {
- area = a;
- r = m;
- }
- return r;
-}
-
-void
-resize(Client *c, int x, int y, int w, int h, int interact)
-{
- if (applysizehints(c, &x, &y, &w, &h, interact))
- resizeclient(c, x, y, w, h);
-}
-
-void
-resizeclient(Client *c, int x, int y, int w, int h)
-{
- XWindowChanges wc;
-
- c->oldx = c->x; c->x = wc.x = x;
- c->oldy = c->y; c->y = wc.y = y;
- c->oldw = c->w; c->w = wc.width = w;
- c->oldh = c->h; c->h = wc.height = h;
- wc.border_width = c->bw;
- XConfigureWindow(dpy, c->win, CWX|CWY|CWWidth|CWHeight|CWBorderWidth, &wc);
- configure(c);
- XSync(dpy, False);
-}
-
-void
-resizemouse(const Arg *arg)
-{
- int ocx, ocy, nw, nh;
- Client *c;
- Monitor *m;
- XEvent ev;
- Time lasttime = 0;
-
- if (!(c = selmon->sel))
- return;
- if (c->isfullscreen) /* no support resizing fullscreen windows by mouse */
- return;
- restack(selmon);
- ocx = c->x;
- ocy = c->y;
- if (XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync,
- None, cursor[CurResize]->cursor, CurrentTime) != GrabSuccess)
- return;
- XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->bw - 1, c->h + c->bw - 1);
- do {
- XMaskEvent(dpy, MOUSEMASK|ExposureMask|SubstructureRedirectMask, &ev);
- switch(ev.type) {
- case ConfigureRequest:
- case Expose:
- case MapRequest:
- handler[ev.type](&ev);
- break;
- case MotionNotify:
- if ((ev.xmotion.time - lasttime) <= (1000 / 60))
- continue;
- lasttime = ev.xmotion.time;
-
- nw = MAX(ev.xmotion.x - ocx - 2 * c->bw + 1, 1);
- nh = MAX(ev.xmotion.y - ocy - 2 * c->bw + 1, 1);
- if (c->mon->wx + nw >= selmon->wx && c->mon->wx + nw <= selmon->wx + selmon->ww
- && c->mon->wy + nh >= selmon->wy && c->mon->wy + nh <= selmon->wy + selmon->wh)
- {
- if (!c->isfloating && selmon->lt[selmon->sellt]->arrange
- && (abs(nw - c->w) > snap || abs(nh - c->h) > snap))
- togglefloating(NULL);
- }
- if (!selmon->lt[selmon->sellt]->arrange || c->isfloating)
- resize(c, c->x, c->y, nw, nh, 1);
- break;
- }
- } while (ev.type != ButtonRelease);
- XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->bw - 1, c->h + c->bw - 1);
- XUngrabPointer(dpy, CurrentTime);
- while (XCheckMaskEvent(dpy, EnterWindowMask, &ev));
- if ((m = recttomon(c->x, c->y, c->w, c->h)) != selmon) {
- sendmon(c, m);
- selmon = m;
- focus(NULL);
- }
-}
-
-void
-restack(Monitor *m)
-{
- Client *c;
- XEvent ev;
- XWindowChanges wc;
-
- drawbar(m);
- if (!m->sel)
- return;
- if (m->sel->isfloating || !m->lt[m->sellt]->arrange)
- XRaiseWindow(dpy, m->sel->win);
- if (m->lt[m->sellt]->arrange) {
- wc.stack_mode = Below;
- wc.sibling = m->barwin;
- for (c = m->stack; c; c = c->snext)
- if (!c->isfloating && ISVISIBLE(c)) {
- XConfigureWindow(dpy, c->win, CWSibling|CWStackMode, &wc);
- wc.sibling = c->win;
- }
- }
- XSync(dpy, False);
- while (XCheckMaskEvent(dpy, EnterWindowMask, &ev));
-}
-
-void
-run(void)
-{
- XEvent ev;
- /* main event loop */
- XSync(dpy, False);
- while (running && !XNextEvent(dpy, &ev))
- if (handler[ev.type])
- handler[ev.type](&ev); /* call handler */
-}
-
-void
-scan(void)
-{
- unsigned int i, num;
- Window d1, d2, *wins = NULL;
- XWindowAttributes wa;
-
- if (XQueryTree(dpy, root, &d1, &d2, &wins, &num)) {
- for (i = 0; i < num; i++) {
- if (!XGetWindowAttributes(dpy, wins[i], &wa)
- || wa.override_redirect || XGetTransientForHint(dpy, wins[i], &d1))
- continue;
- if (wa.map_state == IsViewable || getstate(wins[i]) == IconicState)
- manage(wins[i], &wa);
- }
- for (i = 0; i < num; i++) { /* now the transients */
- if (!XGetWindowAttributes(dpy, wins[i], &wa))
- continue;
- if (XGetTransientForHint(dpy, wins[i], &d1)
- && (wa.map_state == IsViewable || getstate(wins[i]) == IconicState))
- manage(wins[i], &wa);
- }
- if (wins)
- XFree(wins);
- }
-}
-
-void
-sendmon(Client *c, Monitor *m)
-{
- if (c->mon == m)
- return;
- unfocus(c, 1);
- detach(c);
- detachstack(c);
- c->mon = m;
- c->tags = m->tagset[m->seltags]; /* assign tags of target monitor */
- attach(c);
- attachstack(c);
- focus(NULL);
- arrange(NULL);
-}
-
-void
-setclientstate(Client *c, long state)
-{
- long data[] = { state, None };
-
- XChangeProperty(dpy, c->win, wmatom[WMState], wmatom[WMState], 32,
- PropModeReplace, (unsigned char *)data, 2);
-}
-
-int
-sendevent(Client *c, Atom proto)
-{
- int n;
- Atom *protocols;
- int exists = 0;
- XEvent ev;
-
- if (XGetWMProtocols(dpy, c->win, &protocols, &n)) {
- while (!exists && n--)
- exists = protocols[n] == proto;
- XFree(protocols);
- }
- if (exists) {
- ev.type = ClientMessage;
- ev.xclient.window = c->win;
- ev.xclient.message_type = wmatom[WMProtocols];
- ev.xclient.format = 32;
- ev.xclient.data.l[0] = proto;
- ev.xclient.data.l[1] = CurrentTime;
- XSendEvent(dpy, c->win, False, NoEventMask, &ev);
- }
- return exists;
-}
-
-void
-setfocus(Client *c)
-{
- if (!c->neverfocus) {
- XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime);
- XChangeProperty(dpy, root, netatom[NetActiveWindow],
- XA_WINDOW, 32, PropModeReplace,
- (unsigned char *) &(c->win), 1);
- }
- sendevent(c, wmatom[WMTakeFocus]);
-}
-
-void
-setfullscreen(Client *c, int fullscreen)
-{
- if (fullscreen && !c->isfullscreen) {
- XChangeProperty(dpy, c->win, netatom[NetWMState], XA_ATOM, 32,
- PropModeReplace, (unsigned char*)&netatom[NetWMFullscreen], 1);
- c->isfullscreen = 1;
- c->oldstate = c->isfloating;
- c->oldbw = c->bw;
- c->bw = 0;
- c->isfloating = 1;
- resizeclient(c, c->mon->mx, c->mon->my, c->mon->mw, c->mon->mh);
- XRaiseWindow(dpy, c->win);
- } else if (!fullscreen && c->isfullscreen){
- XChangeProperty(dpy, c->win, netatom[NetWMState], XA_ATOM, 32,
- PropModeReplace, (unsigned char*)0, 0);
- c->isfullscreen = 0;
- c->isfloating = c->oldstate;
- c->bw = c->oldbw;
- c->x = c->oldx;
- c->y = c->oldy;
- c->w = c->oldw;
- c->h = c->oldh;
- resizeclient(c, c->x, c->y, c->w, c->h);
- arrange(c->mon);
- }
-}
-
-void
-setlayout(const Arg *arg)
-{
- if (!arg || !arg->v || arg->v != selmon->lt[selmon->sellt])
- selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag] ^= 1;
- if (arg && arg->v)
- selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt] = (Layout *)arg->v;
- strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, sizeof selmon->ltsymbol);
- if (selmon->sel)
- arrange(selmon);
- else
- drawbar(selmon);
-}
-
-/* arg > 1.0 will set mfact absolutely */
-void
-setmfact(const Arg *arg)
-{
- float f;
-
- if (!arg || !selmon->lt[selmon->sellt]->arrange)
- return;
- f = arg->f < 1.0 ? arg->f + selmon->mfact : arg->f - 1.0;
- if (f < 0.05 || f > 0.95)
- return;
- selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag] = f;
- arrange(selmon);
-}
-
-void
-setup(void)
-{
- int i;
- XSetWindowAttributes wa;
- Atom utf8string;
-
- /* clean up any zombies immediately */
- sigchld(0);
-
- /* init screen */
- screen = DefaultScreen(dpy);
- sw = DisplayWidth(dpy, screen);
- sh = DisplayHeight(dpy, screen);
- root = RootWindow(dpy, screen);
- drw = drw_create(dpy, screen, root, sw, sh);
- if (!drw_fontset_create(drw, fonts, LENGTH(fonts)))
- die("no fonts could be loaded.");
- lrpad = drw->fonts->h;
- bh = drw->fonts->h + 2;
- updategeom();
- /* init atoms */
- utf8string = XInternAtom(dpy, "UTF8_STRING", False);
- wmatom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False);
- wmatom[WMDelete] = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
- wmatom[WMState] = XInternAtom(dpy, "WM_STATE", False);
- wmatom[WMTakeFocus] = XInternAtom(dpy, "WM_TAKE_FOCUS", False);
- netatom[NetActiveWindow] = XInternAtom(dpy, "_NET_ACTIVE_WINDOW", False);
- netatom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False);
- netatom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False);
- netatom[NetWMState] = XInternAtom(dpy, "_NET_WM_STATE", False);
- netatom[NetWMCheck] = XInternAtom(dpy, "_NET_SUPPORTING_WM_CHECK", False);
- netatom[NetWMFullscreen] = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False);
- netatom[NetWMWindowType] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False);
- netatom[NetWMWindowTypeDialog] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DIALOG", False);
- netatom[NetClientList] = XInternAtom(dpy, "_NET_CLIENT_LIST", False);
- /* init cursors */
- cursor[CurNormal] = drw_cur_create(drw, XC_left_ptr);
- cursor[CurResize] = drw_cur_create(drw, XC_sizing);
- cursor[CurMove] = drw_cur_create(drw, XC_fleur);
- /* init appearance */
- scheme = ecalloc(LENGTH(colors), sizeof(Clr *));
- for (i = 0; i < LENGTH(colors); i++)
- scheme[i] = drw_scm_create(drw, colors[i], 3);
- /* init bars */
- updatebars();
- updatestatus();
- /* supporting window for NetWMCheck */
- wmcheckwin = XCreateSimpleWindow(dpy, root, 0, 0, 1, 1, 0, 0, 0);
- XChangeProperty(dpy, wmcheckwin, netatom[NetWMCheck], XA_WINDOW, 32,
- PropModeReplace, (unsigned char *) &wmcheckwin, 1);
- XChangeProperty(dpy, wmcheckwin, netatom[NetWMName], utf8string, 8,
- PropModeReplace, (unsigned char *) "dwm", 3);
- XChangeProperty(dpy, root, netatom[NetWMCheck], XA_WINDOW, 32,
- PropModeReplace, (unsigned char *) &wmcheckwin, 1);
- /* EWMH support per view */
- XChangeProperty(dpy, root, netatom[NetSupported], XA_ATOM, 32,
- PropModeReplace, (unsigned char *) netatom, NetLast);
- XDeleteProperty(dpy, root, netatom[NetClientList]);
- /* select events */
- wa.cursor = cursor[CurNormal]->cursor;
- wa.event_mask = SubstructureRedirectMask|SubstructureNotifyMask
- |ButtonPressMask|PointerMotionMask|EnterWindowMask
- |LeaveWindowMask|StructureNotifyMask|PropertyChangeMask;
- XChangeWindowAttributes(dpy, root, CWEventMask|CWCursor, &wa);
- XSelectInput(dpy, root, wa.event_mask);
- grabkeys();
- focus(NULL);
-}
-
-
-void
-seturgent(Client *c, int urg)
-{
- XWMHints *wmh;
-
- c->isurgent = urg;
- if (!(wmh = XGetWMHints(dpy, c->win)))
- return;
- wmh->flags = urg ? (wmh->flags | XUrgencyHint) : (wmh->flags & ~XUrgencyHint);
- XSetWMHints(dpy, c->win, wmh);
- XFree(wmh);
-}
-
-void
-showhide(Client *c)
-{
- if (!c)
- return;
- if (ISVISIBLE(c)) {
- /* show clients top down */
- XMoveWindow(dpy, c->win, c->x, c->y);
- if ((!c->mon->lt[c->mon->sellt]->arrange || c->isfloating) && !c->isfullscreen)
- resize(c, c->x, c->y, c->w, c->h, 0);
- showhide(c->snext);
- } else {
- /* hide clients bottom up */
- showhide(c->snext);
- XMoveWindow(dpy, c->win, WIDTH(c) * -2, c->y);
- }
-}
-
-void
-sigchld(int unused)
-{
- if (signal(SIGCHLD, sigchld) == SIG_ERR)
- die("can't install SIGCHLD handler:");
- while (0 < waitpid(-1, NULL, WNOHANG));
-}
-
-void
-spawn(const Arg *arg)
-{
- if (arg->v == dmenucmd)
- dmenumon[0] = '0' + selmon->num;
- if (fork() == 0) {
- if (dpy)
- close(ConnectionNumber(dpy));
- setsid();
- execvp(((char **)arg->v)[0], (char **)arg->v);
- fprintf(stderr, "dwm: execvp %s", ((char **)arg->v)[0]);
- perror(" failed");
- exit(EXIT_SUCCESS);
- }
-}
-
-void
-tag(const Arg *arg)
-{
- if (selmon->sel && arg->ui & TAGMASK) {
- selmon->sel->tags = arg->ui & TAGMASK;
- focus(NULL);
- arrange(selmon);
- }
-}
-
-void
-tagmon(const Arg *arg)
-{
- if (!selmon->sel || !mons->next)
- return;
- sendmon(selmon->sel, dirtomon(arg->i));
-}
-
-void
-tile(Monitor *m)
-{
- unsigned int i, n, h, mw, my, ty;
- Client *c;
-
- for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
- if (n == 0)
- return;
-
- if (n > m->nmaster)
- mw = m->nmaster ? m->ww * m->mfact : 0;
- else
- mw = m->ww;
- for (i = my = ty = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
- if (i < m->nmaster) {
- h = (m->wh - my) / (MIN(n, m->nmaster) - i);
- resize(c, m->wx, m->wy + my, mw - (2*c->bw), h - (2*c->bw), 0);
- if (my + HEIGHT(c) < m->wh)
- my += HEIGHT(c);
- } else {
- h = (m->wh - ty) / (n - i);
- resize(c, m->wx + mw, m->wy + ty, m->ww - mw - (2*c->bw), h - (2*c->bw), 0);
- if (ty + HEIGHT(c) < m->wh)
- ty += HEIGHT(c);
- }
-}
-
-void
-togglebar(const Arg *arg)
-{
- selmon->showbar = selmon->pertag->showbars[selmon->pertag->curtag] = !selmon->showbar;
- updatebarpos(selmon);
- XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh);
- arrange(selmon);
-}
-
-void
-togglefloating(const Arg *arg)
-{
- if (!selmon->sel)
- return;
- if (selmon->sel->isfullscreen) /* no support for fullscreen windows */
- return;
- selmon->sel->isfloating = !selmon->sel->isfloating || selmon->sel->isfixed;
- if (selmon->sel->isfloating)
- resize(selmon->sel, selmon->sel->x, selmon->sel->y,
- selmon->sel->w, selmon->sel->h, 0);
- arrange(selmon);
-}
-
-void
-togglescratch(const Arg *arg)
-{
- Client *c;
- unsigned int found = 0;
- unsigned int scratchtag = SPTAG(arg->ui);
- Arg sparg = {.v = scratchpads[arg->ui].cmd};
-
- for (c = selmon->clients; c && !(found = c->tags & scratchtag); c = c->next);
- if (found) {
- unsigned int newtagset = selmon->tagset[selmon->seltags] ^ scratchtag;
- if (newtagset) {
- selmon->tagset[selmon->seltags] = newtagset;
- focus(NULL);
- arrange(selmon);
- }
- if (ISVISIBLE(c)) {
- focus(c);
- restack(selmon);
- }
- } else {
- selmon->tagset[selmon->seltags] |= scratchtag;
- spawn(&sparg);
- }
-}
-
-void
-toggletag(const Arg *arg)
-{
- unsigned int newtags;
-
- if (!selmon->sel)
- return;
- newtags = selmon->sel->tags ^ (arg->ui & TAGMASK);
- if (newtags) {
- selmon->sel->tags = newtags;
- focus(NULL);
- arrange(selmon);
- }
-}
-
-void
-toggleview(const Arg *arg)
-{
- unsigned int newtagset = selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK);
- int i;
-
- if (newtagset) {
- selmon->tagset[selmon->seltags] = newtagset;
-
- if (newtagset == ~0) {
- selmon->pertag->prevtag = selmon->pertag->curtag;
- selmon->pertag->curtag = 0;
- }
-
- /* test if the user did not select the same tag */
- if (!(newtagset & 1 << (selmon->pertag->curtag - 1))) {
- selmon->pertag->prevtag = selmon->pertag->curtag;
- for (i = 0; !(newtagset & 1 << i); i++) ;
- selmon->pertag->curtag = i + 1;
- }
-
- /* apply settings for this view */
- selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag];
- selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag];
- selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag];
- selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt];
- selmon->lt[selmon->sellt^1] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt^1];
-
- if (selmon->showbar != selmon->pertag->showbars[selmon->pertag->curtag])
- togglebar(NULL);
-
- focus(NULL);
- arrange(selmon);
- }
-}
-
-void
-unfocus(Client *c, int setfocus)
-{
- if (!c)
- return;
- grabbuttons(c, 0);
- XSetWindowBorder(dpy, c->win, scheme[SchemeNorm][ColBorder].pixel);
- if (setfocus) {
- XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
- XDeleteProperty(dpy, root, netatom[NetActiveWindow]);
- }
-}
-
-void
-unmanage(Client *c, int destroyed)
-{
- Monitor *m = c->mon;
- XWindowChanges wc;
-
- detach(c);
- detachstack(c);
- if (!destroyed) {
- wc.border_width = c->oldbw;
- XGrabServer(dpy); /* avoid race conditions */
- XSetErrorHandler(xerrordummy);
- XConfigureWindow(dpy, c->win, CWBorderWidth, &wc); /* restore border */
- XUngrabButton(dpy, AnyButton, AnyModifier, c->win);
- setclientstate(c, WithdrawnState);
- XSync(dpy, False);
- XSetErrorHandler(xerror);
- XUngrabServer(dpy);
- }
- free(c);
- focus(NULL);
- updateclientlist();
- arrange(m);
-}
-
-void
-unmapnotify(XEvent *e)
-{
- Client *c;
- XUnmapEvent *ev = &e->xunmap;
-
- if ((c = wintoclient(ev->window))) {
- if (ev->send_event)
- setclientstate(c, WithdrawnState);
- else
- unmanage(c, 0);
- }
-}
-
-void
-updatebars(void)
-{
- Monitor *m;
- XSetWindowAttributes wa = {
- .override_redirect = True,
- .background_pixmap = ParentRelative,
- .event_mask = ButtonPressMask|ExposureMask
- };
- XClassHint ch = {"dwm", "dwm"};
- for (m = mons; m; m = m->next) {
- if (m->barwin)
- continue;
- m->barwin = XCreateWindow(dpy, root, m->wx, m->by, m->ww, bh, 0, DefaultDepth(dpy, screen),
- CopyFromParent, DefaultVisual(dpy, screen),
- CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa);
- XDefineCursor(dpy, m->barwin, cursor[CurNormal]->cursor);
- XMapRaised(dpy, m->barwin);
- XSetClassHint(dpy, m->barwin, &ch);
- }
-}
-
-void
-updatebarpos(Monitor *m)
-{
- m->wy = m->my;
- m->wh = m->mh;
- if (m->showbar) {
- m->wh -= bh;
- m->by = m->topbar ? m->wy : m->wy + m->wh;
- m->wy = m->topbar ? m->wy + bh : m->wy;
- } else
- m->by = -bh;
-}
-
-void
-updateclientlist()
-{
- Client *c;
- Monitor *m;
-
- XDeleteProperty(dpy, root, netatom[NetClientList]);
- for (m = mons; m; m = m->next)
- for (c = m->clients; c; c = c->next)
- XChangeProperty(dpy, root, netatom[NetClientList],
- XA_WINDOW, 32, PropModeAppend,
- (unsigned char *) &(c->win), 1);
-}
-
-int
-updategeom(void)
-{
- int dirty = 0;
-
-#ifdef XINERAMA
- if (XineramaIsActive(dpy)) {
- int i, j, n, nn;
- Client *c;
- Monitor *m;
- XineramaScreenInfo *info = XineramaQueryScreens(dpy, &nn);
- XineramaScreenInfo *unique = NULL;
-
- for (n = 0, m = mons; m; m = m->next, n++);
- /* only consider unique geometries as separate screens */
- unique = ecalloc(nn, sizeof(XineramaScreenInfo));
- for (i = 0, j = 0; i < nn; i++)
- if (isuniquegeom(unique, j, &info[i]))
- memcpy(&unique[j++], &info[i], sizeof(XineramaScreenInfo));
- XFree(info);
- nn = j;
- if (n <= nn) { /* new monitors available */
- for (i = 0; i < (nn - n); i++) {
- for (m = mons; m && m->next; m = m->next);
- if (m)
- m->next = createmon();
- else
- mons = createmon();
- }
- for (i = 0, m = mons; i < nn && m; m = m->next, i++)
- if (i >= n
- || unique[i].x_org != m->mx || unique[i].y_org != m->my
- || unique[i].width != m->mw || unique[i].height != m->mh)
- {
- dirty = 1;
- m->num = i;
- m->mx = m->wx = unique[i].x_org;
- m->my = m->wy = unique[i].y_org;
- m->mw = m->ww = unique[i].width;
- m->mh = m->wh = unique[i].height;
- updatebarpos(m);
- }
- } else { /* less monitors available nn < n */
- for (i = nn; i < n; i++) {
- for (m = mons; m && m->next; m = m->next);
- while ((c = m->clients)) {
- dirty = 1;
- m->clients = c->next;
- detachstack(c);
- c->mon = mons;
- attach(c);
- attachstack(c);
- }
- if (m == selmon)
- selmon = mons;
- cleanupmon(m);
- }
- }
- free(unique);
- } else
-#endif /* XINERAMA */
- { /* default monitor setup */
- if (!mons)
- mons = createmon();
- if (mons->mw != sw || mons->mh != sh) {
- dirty = 1;
- mons->mw = mons->ww = sw;
- mons->mh = mons->wh = sh;
- updatebarpos(mons);
- }
- }
- if (dirty) {
- selmon = mons;
- selmon = wintomon(root);
- }
- return dirty;
-}
-
-void
-updatenumlockmask(void)
-{
- unsigned int i, j;
- XModifierKeymap *modmap;
-
- numlockmask = 0;
- modmap = XGetModifierMapping(dpy);
- for (i = 0; i < 8; i++)
- for (j = 0; j < modmap->max_keypermod; j++)
- if (modmap->modifiermap[i * modmap->max_keypermod + j]
- == XKeysymToKeycode(dpy, XK_Num_Lock))
- numlockmask = (1 << i);
- XFreeModifiermap(modmap);
-}
-
-void
-updatesizehints(Client *c)
-{
- long msize;
- XSizeHints size;
-
- if (!XGetWMNormalHints(dpy, c->win, &size, &msize))
- /* size is uninitialized, ensure that size.flags aren't used */
- size.flags = PSize;
- if (size.flags & PBaseSize) {
- c->basew = size.base_width;
- c->baseh = size.base_height;
- } else if (size.flags & PMinSize) {
- c->basew = size.min_width;
- c->baseh = size.min_height;
- } else
- c->basew = c->baseh = 0;
- if (size.flags & PResizeInc) {
- c->incw = size.width_inc;
- c->inch = size.height_inc;
- } else
- c->incw = c->inch = 0;
- if (size.flags & PMaxSize) {
- c->maxw = size.max_width;
- c->maxh = size.max_height;
- } else
- c->maxw = c->maxh = 0;
- if (size.flags & PMinSize) {
- c->minw = size.min_width;
- c->minh = size.min_height;
- } else if (size.flags & PBaseSize) {
- c->minw = size.base_width;
- c->minh = size.base_height;
- } else
- c->minw = c->minh = 0;
- if (size.flags & PAspect) {
- c->mina = (float)size.min_aspect.y / size.min_aspect.x;
- c->maxa = (float)size.max_aspect.x / size.max_aspect.y;
- } else
- c->maxa = c->mina = 0.0;
- c->isfixed = (c->maxw && c->maxh && c->maxw == c->minw && c->maxh == c->minh);
-}
-
-void
-updatestatus(void)
-{
- if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext)))
- strcpy(stext, "dwm-"VERSION);
- drawbar(selmon);
-}
-
-void
-updatetitle(Client *c)
-{
- if (!gettextprop(c->win, netatom[NetWMName], c->name, sizeof c->name))
- gettextprop(c->win, XA_WM_NAME, c->name, sizeof c->name);
- if (c->name[0] == '\0') /* hack to mark broken clients */
- strcpy(c->name, broken);
-}
-
-void
-updatewindowtype(Client *c)
-{
- Atom state = getatomprop(c, netatom[NetWMState]);
- Atom wtype = getatomprop(c, netatom[NetWMWindowType]);
-
- if (state == netatom[NetWMFullscreen])
- setfullscreen(c, 1);
- if (wtype == netatom[NetWMWindowTypeDialog])
- c->isfloating = 1;
-}
-
-void
-updatewmhints(Client *c)
-{
- XWMHints *wmh;
-
- if ((wmh = XGetWMHints(dpy, c->win))) {
- if (c == selmon->sel && wmh->flags & XUrgencyHint) {
- wmh->flags &= ~XUrgencyHint;
- XSetWMHints(dpy, c->win, wmh);
- } else
- c->isurgent = (wmh->flags & XUrgencyHint) ? 1 : 0;
- if (wmh->flags & InputHint)
- c->neverfocus = !wmh->input;
- else
- c->neverfocus = 0;
- XFree(wmh);
- }
-}
-
-void
-view(const Arg *arg)
-{
- int i;
- unsigned int tmptag;
-
- if ((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags])
- return;
- selmon->seltags ^= 1; /* toggle sel tagset */
- if (arg->ui & TAGMASK) {
- selmon->tagset[selmon->seltags] = arg->ui & TAGMASK;
- selmon->pertag->prevtag = selmon->pertag->curtag;
-
- if (arg->ui == ~0)
- selmon->pertag->curtag = 0;
- else {
- for (i = 0; !(arg->ui & 1 << i); i++) ;
- selmon->pertag->curtag = i + 1;
- }
- } else {
- tmptag = selmon->pertag->prevtag;
- selmon->pertag->prevtag = selmon->pertag->curtag;
- selmon->pertag->curtag = tmptag;
- }
-
- selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag];
- selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag];
- selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag];
- selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt];
- selmon->lt[selmon->sellt^1] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt^1];
-
- if (selmon->showbar != selmon->pertag->showbars[selmon->pertag->curtag])
- togglebar(NULL);
-
- focus(NULL);
- arrange(selmon);
-}
-
-Client *
-wintoclient(Window w)
-{
- Client *c;
- Monitor *m;
-
- for (m = mons; m; m = m->next)
- for (c = m->clients; c; c = c->next)
- if (c->win == w)
- return c;
- return NULL;
-}
-
-Monitor *
-wintomon(Window w)
-{
- int x, y;
- Client *c;
- Monitor *m;
-
- if (w == root && getrootptr(&x, &y))
- return recttomon(x, y, 1, 1);
- for (m = mons; m; m = m->next)
- if (w == m->barwin)
- return m;
- if ((c = wintoclient(w)))
- return c->mon;
- return selmon;
-}
-
-/* There's no way to check accesses to destroyed windows, thus those cases are
- * ignored (especially on UnmapNotify's). Other types of errors call Xlibs
- * default error handler, which may call exit. */
-int
-xerror(Display *dpy, XErrorEvent *ee)
-{
- if (ee->error_code == BadWindow
- || (ee->request_code == X_SetInputFocus && ee->error_code == BadMatch)
- || (ee->request_code == X_PolyText8 && ee->error_code == BadDrawable)
- || (ee->request_code == X_PolyFillRectangle && ee->error_code == BadDrawable)
- || (ee->request_code == X_PolySegment && ee->error_code == BadDrawable)
- || (ee->request_code == X_ConfigureWindow && ee->error_code == BadMatch)
- || (ee->request_code == X_GrabButton && ee->error_code == BadAccess)
- || (ee->request_code == X_GrabKey && ee->error_code == BadAccess)
- || (ee->request_code == X_CopyArea && ee->error_code == BadDrawable))
- return 0;
- fprintf(stderr, "dwm: fatal error: request code=%d, error code=%d\n",
- ee->request_code, ee->error_code);
- return xerrorxlib(dpy, ee); /* may call exit */
-}
-
-int
-xerrordummy(Display *dpy, XErrorEvent *ee)
-{
- return 0;
-}
-
-/* Startup Error handler to check if another window manager
- * is already running. */
-int
-xerrorstart(Display *dpy, XErrorEvent *ee)
-{
- die("dwm: another window manager is already running");
- return -1;
-}
-
-void
-zoom(const Arg *arg)
-{
- Client *c = selmon->sel;
-
- if (!selmon->lt[selmon->sellt]->arrange
- || (selmon->sel && selmon->sel->isfloating))
- return;
- if (c == nexttiled(selmon->clients))
- if (!c || !(c = nexttiled(c->next)))
- return;
- pop(c);
-}
-
-int
-main(int argc, char *argv[])
-{
- if (argc == 2 && !strcmp("-v", argv[1]))
- die("dwm-"VERSION);
- else if (argc != 1)
- die("usage: dwm [-v]");
- if (!setlocale(LC_CTYPE, "") || !XSupportsLocale())
- fputs("warning: no locale support\n", stderr);
- if (!(dpy = XOpenDisplay(NULL)))
- die("dwm: cannot open display");
- checkotherwm();
- setup();
-#ifdef __OpenBSD__
- if (pledge("stdio rpath proc exec", NULL) == -1)
- die("pledge");
-#endif /* __OpenBSD__ */
- scan();
- run();
- cleanup();
- XCloseDisplay(dpy);
- return EXIT_SUCCESS;
-}
diff --git a/.repos/dwm/dwm.c.orig b/.repos/dwm/dwm.c.orig
deleted file mode 100644
index 855f269..0000000
--- a/.repos/dwm/dwm.c.orig
+++ /dev/null
@@ -1,2187 +0,0 @@
-/* See LICENSE file for copyright and license details.
- *
- * dynamic window manager is designed like any other X client as well. It is
- * driven through handling X events. In contrast to other X clients, a window
- * manager selects for SubstructureRedirectMask on the root window, to receive
- * events about window (dis-)appearance. Only one X connection at a time is
- * allowed to select for this event mask.
- *
- * The event handlers of dwm are organized in an array which is accessed
- * whenever a new event has been fetched. This allows event dispatching
- * in O(1) time.
- *
- * Each child of the root window is called a client, except windows which have
- * set the override_redirect flag. Clients are organized in a linked client
- * list on each monitor, the focus history is remembered through a stack list
- * on each monitor. Each client contains a bit array to indicate the tags of a
- * client.
- *
- * Keys and tagging rules are organized as arrays and defined in config.h.
- *
- * To understand everything else, start reading main().
- */
-#include <errno.h>
-#include <locale.h>
-#include <signal.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <X11/cursorfont.h>
-#include <X11/keysym.h>
-#include <X11/Xatom.h>
-#include <X11/Xlib.h>
-#include <X11/Xproto.h>
-#include <X11/Xutil.h>
-#ifdef XINERAMA
-#include <X11/extensions/Xinerama.h>
-#endif /* XINERAMA */
-#include <X11/Xft/Xft.h>
-
-#include "drw.h"
-#include "util.h"
-
-/* macros */
-#define BUTTONMASK (ButtonPressMask|ButtonReleaseMask)
-#define CLEANMASK(mask) (mask & ~(numlockmask|LockMask) & (ShiftMask|ControlMask|Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask))
-#define INTERSECT(x,y,w,h,m) (MAX(0, MIN((x)+(w),(m)->wx+(m)->ww) - MAX((x),(m)->wx)) \
- * MAX(0, MIN((y)+(h),(m)->wy+(m)->wh) - MAX((y),(m)->wy)))
-#define ISVISIBLE(C) ((C->tags & C->mon->tagset[C->mon->seltags]))
-#define LENGTH(X) (sizeof X / sizeof X[0])
-#define MOUSEMASK (BUTTONMASK|PointerMotionMask)
-#define WIDTH(X) ((X)->w + 2 * (X)->bw)
-#define HEIGHT(X) ((X)->h + 2 * (X)->bw)
-#define NUMTAGS (LENGTH(tags) + LENGTH(scratchpads))
-#define TAGMASK ((1 << NUMTAGS) - 1)
-#define SPTAG(i) ((1 << LENGTH(tags)) << (i))
-#define SPTAGMASK (((1 << LENGTH(scratchpads))-1) << LENGTH(tags))
-#define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad)
-
-/* enums */
-enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
-enum { SchemeNorm, SchemeSel }; /* color schemes */
-enum { NetSupported, NetWMName, NetWMState, NetWMCheck,
- NetWMFullscreen, NetActiveWindow, NetWMWindowType,
- NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */
-enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */
-enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle,
- ClkClientWin, ClkRootWin, ClkLast }; /* clicks */
-
-typedef union {
- int i;
- unsigned int ui;
- float f;
- const void *v;
-} Arg;
-
-typedef struct {
- unsigned int click;
- unsigned int mask;
- unsigned int button;
- void (*func)(const Arg *arg);
- const Arg arg;
-} Button;
-
-typedef struct Monitor Monitor;
-typedef struct Client Client;
-struct Client {
- char name[256];
- float mina, maxa;
- int x, y, w, h;
- int oldx, oldy, oldw, oldh;
- int basew, baseh, incw, inch, maxw, maxh, minw, minh;
- int bw, oldbw;
- unsigned int tags;
- int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen;
- Client *next;
- Client *snext;
- Monitor *mon;
- Window win;
-};
-
-typedef struct {
- unsigned int mod;
- KeySym keysym;
- void (*func)(const Arg *);
- const Arg arg;
-} Key;
-
-typedef struct {
- const char *symbol;
- void (*arrange)(Monitor *);
-} Layout;
-
-struct Monitor {
- char ltsymbol[16];
- float mfact;
- int nmaster;
- int num;
- int by; /* bar geometry */
- int mx, my, mw, mh; /* screen size */
- int wx, wy, ww, wh; /* window area */
- unsigned int seltags;
- unsigned int sellt;
- unsigned int tagset[2];
- int showbar;
- int topbar;
- Client *clients;
- Client *sel;
- Client *stack;
- Monitor *next;
- Window barwin;
- const Layout *lt[2];
-};
-
-typedef struct {
- const char *class;
- const char *instance;
- const char *title;
- unsigned int tags;
- int isfloating;
- int monitor;
-} Rule;
-
-/* function declarations */
-static void applyrules(Client *c);
-static int applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact);
-static void arrange(Monitor *m);
-static void arrangemon(Monitor *m);
-static void attach(Client *c);
-static void attachstack(Client *c);
-static void buttonpress(XEvent *e);
-static void checkotherwm(void);
-static void cleanup(void);
-static void cleanupmon(Monitor *mon);
-static void clientmessage(XEvent *e);
-static void configure(Client *c);
-static void configurenotify(XEvent *e);
-static void configurerequest(XEvent *e);
-static Monitor *createmon(void);
-static void destroynotify(XEvent *e);
-static void detach(Client *c);
-static void detachstack(Client *c);
-static Monitor *dirtomon(int dir);
-static void drawbar(Monitor *m);
-static void drawbars(void);
-static void enternotify(XEvent *e);
-static void expose(XEvent *e);
-static void focus(Client *c);
-static void focusin(XEvent *e);
-static void focusmon(const Arg *arg);
-static void focusstack(const Arg *arg);
-static Atom getatomprop(Client *c, Atom prop);
-static int getrootptr(int *x, int *y);
-static long getstate(Window w);
-static int gettextprop(Window w, Atom atom, char *text, unsigned int size);
-static void grabbuttons(Client *c, int focused);
-static void grabkeys(void);
-static void incnmaster(const Arg *arg);
-static void keypress(XEvent *e);
-static void killclient(const Arg *arg);
-static void manage(Window w, XWindowAttributes *wa);
-static void mappingnotify(XEvent *e);
-static void maprequest(XEvent *e);
-static void monocle(Monitor *m);
-static void motionnotify(XEvent *e);
-static void movemouse(const Arg *arg);
-static Client *nexttiled(Client *c);
-static void pop(Client *);
-static void propertynotify(XEvent *e);
-static void quit(const Arg *arg);
-static Monitor *recttomon(int x, int y, int w, int h);
-static void resize(Client *c, int x, int y, int w, int h, int interact);
-static void resizeclient(Client *c, int x, int y, int w, int h);
-static void resizemouse(const Arg *arg);
-static void restack(Monitor *m);
-static void run(void);
-static void scan(void);
-static int sendevent(Client *c, Atom proto);
-static void sendmon(Client *c, Monitor *m);
-static void setclientstate(Client *c, long state);
-static void setfocus(Client *c);
-static void setfullscreen(Client *c, int fullscreen);
-static void setlayout(const Arg *arg);
-static void setmfact(const Arg *arg);
-static void setup(void);
-static void seturgent(Client *c, int urg);
-static void showhide(Client *c);
-static void sigchld(int unused);
-static void spawn(const Arg *arg);
-static void tag(const Arg *arg);
-static void tagmon(const Arg *arg);
-static void tile(Monitor *);
-static void togglebar(const Arg *arg);
-static void togglefloating(const Arg *arg);
-static void togglescratch(const Arg *arg);
-static void toggletag(const Arg *arg);
-static void toggleview(const Arg *arg);
-static void unfocus(Client *c, int setfocus);
-static void unmanage(Client *c, int destroyed);
-static void unmapnotify(XEvent *e);
-static void updatebarpos(Monitor *m);
-static void updatebars(void);
-static void updateclientlist(void);
-static int updategeom(void);
-static void updatenumlockmask(void);
-static void updatesizehints(Client *c);
-static void updatestatus(void);
-static void updatetitle(Client *c);
-static void updatewindowtype(Client *c);
-static void updatewmhints(Client *c);
-static void view(const Arg *arg);
-static Client *wintoclient(Window w);
-static Monitor *wintomon(Window w);
-static int xerror(Display *dpy, XErrorEvent *ee);
-static int xerrordummy(Display *dpy, XErrorEvent *ee);
-static int xerrorstart(Display *dpy, XErrorEvent *ee);
-static void zoom(const Arg *arg);
-
-/* variables */
-static const char broken[] = "broken";
-static char stext[256];
-static int screen;
-static int sw, sh; /* X display screen geometry width, height */
-static int bh, blw = 0; /* bar geometry */
-static int lrpad; /* sum of left and right padding for text */
-static int (*xerrorxlib)(Display *, XErrorEvent *);
-static unsigned int numlockmask = 0;
-static void (*handler[LASTEvent]) (XEvent *) = {
- [ButtonPress] = buttonpress,
- [ClientMessage] = clientmessage,
- [ConfigureRequest] = configurerequest,
- [ConfigureNotify] = configurenotify,
- [DestroyNotify] = destroynotify,
- [EnterNotify] = enternotify,
- [Expose] = expose,
- [FocusIn] = focusin,
- [KeyPress] = keypress,
- [MappingNotify] = mappingnotify,
- [MapRequest] = maprequest,
- [MotionNotify] = motionnotify,
- [PropertyNotify] = propertynotify,
- [UnmapNotify] = unmapnotify
-};
-static Atom wmatom[WMLast], netatom[NetLast];
-static int running = 1;
-static Cur *cursor[CurLast];
-static Clr **scheme;
-static Display *dpy;
-static Drw *drw;
-static Monitor *mons, *selmon;
-static Window root, wmcheckwin;
-
-/* configuration, allows nested code to access above variables */
-#include "config.h"
-
-/* compile-time check if all tags fit into an unsigned int bit array. */
-struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; };
-
-/* function implementations */
-void
-applyrules(Client *c)
-{
- const char *class, *instance;
- unsigned int i;
- const Rule *r;
- Monitor *m;
- XClassHint ch = { NULL, NULL };
-
- /* rule matching */
- c->isfloating = 0;
- c->tags = 0;
- XGetClassHint(dpy, c->win, &ch);
- class = ch.res_class ? ch.res_class : broken;
- instance = ch.res_name ? ch.res_name : broken;
-
- for (i = 0; i < LENGTH(rules); i++) {
- r = &rules[i];
- if ((!r->title || strstr(c->name, r->title))
- && (!r->class || strstr(class, r->class))
- && (!r->instance || strstr(instance, r->instance)))
- {
- c->isfloating = r->isfloating;
- c->tags |= r->tags;
- if ((r->tags & SPTAGMASK) && r->isfloating) {
- c->x = c->mon->wx + (c->mon->ww / 2 - WIDTH(c) / 2);
- c->y = c->mon->wy + (c->mon->wh / 2 - HEIGHT(c) / 2);
- }
-
- for (m = mons; m && m->num != r->monitor; m = m->next);
- if (m)
- c->mon = m;
- }
- }
- if (ch.res_class)
- XFree(ch.res_class);
- if (ch.res_name)
- XFree(ch.res_name);
- c->tags = c->tags & TAGMASK ? c->tags & TAGMASK : (c->mon->tagset[c->mon->seltags] & ~SPTAGMASK);
-}
-
-int
-applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact)
-{
- int baseismin;
- Monitor *m = c->mon;
-
- /* set minimum possible */
- *w = MAX(1, *w);
- *h = MAX(1, *h);
- if (interact) {
- if (*x > sw)
- *x = sw - WIDTH(c);
- if (*y > sh)
- *y = sh - HEIGHT(c);
- if (*x + *w + 2 * c->bw < 0)
- *x = 0;
- if (*y + *h + 2 * c->bw < 0)
- *y = 0;
- } else {
- if (*x >= m->wx + m->ww)
- *x = m->wx + m->ww - WIDTH(c);
- if (*y >= m->wy + m->wh)
- *y = m->wy + m->wh - HEIGHT(c);
- if (*x + *w + 2 * c->bw <= m->wx)
- *x = m->wx;
- if (*y + *h + 2 * c->bw <= m->wy)
- *y = m->wy;
- }
- if (*h < bh)
- *h = bh;
- if (*w < bh)
- *w = bh;
- if (resizehints || c->isfloating || !c->mon->lt[c->mon->sellt]->arrange) {
- /* see last two sentences in ICCCM 4.1.2.3 */
- baseismin = c->basew == c->minw && c->baseh == c->minh;
- if (!baseismin) { /* temporarily remove base dimensions */
- *w -= c->basew;
- *h -= c->baseh;
- }
- /* adjust for aspect limits */
- if (c->mina > 0 && c->maxa > 0) {
- if (c->maxa < (float)*w / *h)
- *w = *h * c->maxa + 0.5;
- else if (c->mina < (float)*h / *w)
- *h = *w * c->mina + 0.5;
- }
- if (baseismin) { /* increment calculation requires this */
- *w -= c->basew;
- *h -= c->baseh;
- }
- /* adjust for increment value */
- if (c->incw)
- *w -= *w % c->incw;
- if (c->inch)
- *h -= *h % c->inch;
- /* restore base dimensions */
- *w = MAX(*w + c->basew, c->minw);
- *h = MAX(*h + c->baseh, c->minh);
- if (c->maxw)
- *w = MIN(*w, c->maxw);
- if (c->maxh)
- *h = MIN(*h, c->maxh);
- }
- return *x != c->x || *y != c->y || *w != c->w || *h != c->h;
-}
-
-void
-arrange(Monitor *m)
-{
- if (m)
- showhide(m->stack);
- else for (m = mons; m; m = m->next)
- showhide(m->stack);
- if (m) {
- arrangemon(m);
- restack(m);
- } else for (m = mons; m; m = m->next)
- arrangemon(m);
-}
-
-void
-arrangemon(Monitor *m)
-{
- strncpy(m->ltsymbol, m->lt[m->sellt]->symbol, sizeof m->ltsymbol);
- if (m->lt[m->sellt]->arrange)
- m->lt[m->sellt]->arrange(m);
-}
-
-void
-attach(Client *c)
-{
- c->next = c->mon->clients;
- c->mon->clients = c;
-}
-
-void
-attachstack(Client *c)
-{
- c->snext = c->mon->stack;
- c->mon->stack = c;
-}
-
-void
-buttonpress(XEvent *e)
-{
- unsigned int i, x, click;
- Arg arg = {0};
- Client *c;
- Monitor *m;
- XButtonPressedEvent *ev = &e->xbutton;
-
- click = ClkRootWin;
- /* focus monitor if necessary */
- if ((m = wintomon(ev->window)) && m != selmon) {
- unfocus(selmon->sel, 1);
- selmon = m;
- focus(NULL);
- }
- if (ev->window == selmon->barwin) {
- i = x = 0;
- do
- x += TEXTW(tags[i]);
- while (ev->x >= x && ++i < LENGTH(tags));
- if (i < LENGTH(tags)) {
- click = ClkTagBar;
- arg.ui = 1 << i;
- } else if (ev->x < x + blw)
- click = ClkLtSymbol;
- else if (ev->x > selmon->ww - (int)TEXTW(stext))
- click = ClkStatusText;
- else
- click = ClkWinTitle;
- } else if ((c = wintoclient(ev->window))) {
- focus(c);
- restack(selmon);
- XAllowEvents(dpy, ReplayPointer, CurrentTime);
- click = ClkClientWin;
- }
- for (i = 0; i < LENGTH(buttons); i++)
- if (click == buttons[i].click && buttons[i].func && buttons[i].button == ev->button
- && CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state))
- buttons[i].func(click == ClkTagBar && buttons[i].arg.i == 0 ? &arg : &buttons[i].arg);
-}
-
-void
-checkotherwm(void)
-{
- xerrorxlib = XSetErrorHandler(xerrorstart);
- /* this causes an error if some other window manager is running */
- XSelectInput(dpy, DefaultRootWindow(dpy), SubstructureRedirectMask);
- XSync(dpy, False);
- XSetErrorHandler(xerror);
- XSync(dpy, False);
-}
-
-void
-cleanup(void)
-{
- Arg a = {.ui = ~0};
- Layout foo = { "", NULL };
- Monitor *m;
- size_t i;
-
- view(&a);
- selmon->lt[selmon->sellt] = &foo;
- for (m = mons; m; m = m->next)
- while (m->stack)
- unmanage(m->stack, 0);
- XUngrabKey(dpy, AnyKey, AnyModifier, root);
- while (mons)
- cleanupmon(mons);
- for (i = 0; i < CurLast; i++)
- drw_cur_free(drw, cursor[i]);
- for (i = 0; i < LENGTH(colors); i++)
- free(scheme[i]);
- XDestroyWindow(dpy, wmcheckwin);
- drw_free(drw);
- XSync(dpy, False);
- XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime);
- XDeleteProperty(dpy, root, netatom[NetActiveWindow]);
-}
-
-void
-cleanupmon(Monitor *mon)
-{
- Monitor *m;
-
- if (mon == mons)
- mons = mons->next;
- else {
- for (m = mons; m && m->next != mon; m = m->next);
- m->next = mon->next;
- }
- XUnmapWindow(dpy, mon->barwin);
- XDestroyWindow(dpy, mon->barwin);
- free(mon);
-}
-
-void
-clientmessage(XEvent *e)
-{
- XClientMessageEvent *cme = &e->xclient;
- Client *c = wintoclient(cme->window);
-
- if (!c)
- return;
- if (cme->message_type == netatom[NetWMState]) {
- if (cme->data.l[1] == netatom[NetWMFullscreen]
- || cme->data.l[2] == netatom[NetWMFullscreen])
- setfullscreen(c, (cme->data.l[0] == 1 /* _NET_WM_STATE_ADD */
- || (cme->data.l[0] == 2 /* _NET_WM_STATE_TOGGLE */ && !c->isfullscreen)));
- } else if (cme->message_type == netatom[NetActiveWindow]) {
- if (c != selmon->sel && !c->isurgent)
- seturgent(c, 1);
- }
-}
-
-void
-configure(Client *c)
-{
- XConfigureEvent ce;
-
- ce.type = ConfigureNotify;
- ce.display = dpy;
- ce.event = c->win;
- ce.window = c->win;
- ce.x = c->x;
- ce.y = c->y;
- ce.width = c->w;
- ce.height = c->h;
- ce.border_width = c->bw;
- ce.above = None;
- ce.override_redirect = False;
- XSendEvent(dpy, c->win, False, StructureNotifyMask, (XEvent *)&ce);
-}
-
-void
-configurenotify(XEvent *e)
-{
- Monitor *m;
- Client *c;
- XConfigureEvent *ev = &e->xconfigure;
- int dirty;
-
- /* TODO: updategeom handling sucks, needs to be simplified */
- if (ev->window == root) {
- dirty = (sw != ev->width || sh != ev->height);
- sw = ev->width;
- sh = ev->height;
- if (updategeom() || dirty) {
- drw_resize(drw, sw, bh);
- updatebars();
- for (m = mons; m; m = m->next) {
- for (c = m->clients; c; c = c->next)
- if (c->isfullscreen)
- resizeclient(c, m->mx, m->my, m->mw, m->mh);
- XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, bh);
- }
- focus(NULL);
- arrange(NULL);
- }
- }
-}
-
-void
-configurerequest(XEvent *e)
-{
- Client *c;
- Monitor *m;
- XConfigureRequestEvent *ev = &e->xconfigurerequest;
- XWindowChanges wc;
-
- if ((c = wintoclient(ev->window))) {
- if (ev->value_mask & CWBorderWidth)
- c->bw = ev->border_width;
- else if (c->isfloating || !selmon->lt[selmon->sellt]->arrange) {
- m = c->mon;
- if (ev->value_mask & CWX) {
- c->oldx = c->x;
- c->x = m->mx + ev->x;
- }
- if (ev->value_mask & CWY) {
- c->oldy = c->y;
- c->y = m->my + ev->y;
- }
- if (ev->value_mask & CWWidth) {
- c->oldw = c->w;
- c->w = ev->width;
- }
- if (ev->value_mask & CWHeight) {
- c->oldh = c->h;
- c->h = ev->height;
- }
- if ((c->x + c->w) > m->mx + m->mw && c->isfloating)
- c->x = m->mx + (m->mw / 2 - WIDTH(c) / 2); /* center in x direction */
- if ((c->y + c->h) > m->my + m->mh && c->isfloating)
- c->y = m->my + (m->mh / 2 - HEIGHT(c) / 2); /* center in y direction */
- if ((ev->value_mask & (CWX|CWY)) && !(ev->value_mask & (CWWidth|CWHeight)))
- configure(c);
- if (ISVISIBLE(c))
- XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h);
- } else
- configure(c);
- } else {
- wc.x = ev->x;
- wc.y = ev->y;
- wc.width = ev->width;
- wc.height = ev->height;
- wc.border_width = ev->border_width;
- wc.sibling = ev->above;
- wc.stack_mode = ev->detail;
- XConfigureWindow(dpy, ev->window, ev->value_mask, &wc);
- }
- XSync(dpy, False);
-}
-
-Monitor *
-createmon(void)
-{
- Monitor *m;
-
- m = ecalloc(1, sizeof(Monitor));
- m->tagset[0] = m->tagset[1] = 1;
- m->mfact = mfact;
- m->nmaster = nmaster;
- m->showbar = showbar;
- m->topbar = topbar;
- m->lt[0] = &layouts[0];
- m->lt[1] = &layouts[1 % LENGTH(layouts)];
- strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol);
- return m;
-}
-
-void
-destroynotify(XEvent *e)
-{
- Client *c;
- XDestroyWindowEvent *ev = &e->xdestroywindow;
-
- if ((c = wintoclient(ev->window)))
- unmanage(c, 1);
-}
-
-void
-detach(Client *c)
-{
- Client **tc;
-
- for (tc = &c->mon->clients; *tc && *tc != c; tc = &(*tc)->next);
- *tc = c->next;
-}
-
-void
-detachstack(Client *c)
-{
- Client **tc, *t;
-
- for (tc = &c->mon->stack; *tc && *tc != c; tc = &(*tc)->snext);
- *tc = c->snext;
-
- if (c == c->mon->sel) {
- for (t = c->mon->stack; t && !ISVISIBLE(t); t = t->snext);
- c->mon->sel = t;
- }
-}
-
-Monitor *
-dirtomon(int dir)
-{
- Monitor *m = NULL;
-
- if (dir > 0) {
- if (!(m = selmon->next))
- m = mons;
- } else if (selmon == mons)
- for (m = mons; m->next; m = m->next);
- else
- for (m = mons; m->next != selmon; m = m->next);
- return m;
-}
-
-void
-drawbar(Monitor *m)
-{
- int x, w, tw = 0;
- int boxs = drw->fonts->h / 9;
- int boxw = drw->fonts->h / 6 + 2;
- unsigned int i, occ = 0, urg = 0;
- Client *c;
-
- /* draw status first so it can be overdrawn by tags later */
- if (m == selmon) { /* status is only drawn on selected monitor */
- drw_setscheme(drw, scheme[SchemeNorm]);
- tw = TEXTW(stext) - lrpad + 2; /* 2px right padding */
- drw_text(drw, m->ww - tw, 0, tw, bh, 0, stext, 0);
- }
-
- for (c = m->clients; c; c = c->next) {
- occ |= c->tags;
- if (c->isurgent)
- urg |= c->tags;
- }
- x = 0;
- for (i = 0; i < LENGTH(tags); i++) {
- w = TEXTW(tags[i]);
- drw_setscheme(drw, scheme[m->tagset[m->seltags] & 1 << i ? SchemeSel : SchemeNorm]);
- drw_text(drw, x, 0, w, bh, lrpad / 2, tags[i], urg & 1 << i);
- if (occ & 1 << i)
- drw_rect(drw, x + boxs, boxs, boxw, boxw,
- m == selmon && selmon->sel && selmon->sel->tags & 1 << i,
- urg & 1 << i);
- x += w;
- }
- w = blw = TEXTW(m->ltsymbol);
- drw_setscheme(drw, scheme[SchemeNorm]);
- x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0);
-
- if ((w = m->ww - tw - x) > bh) {
- if (m->sel) {
- drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]);
- drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0);
- if (m->sel->isfloating)
- drw_rect(drw, x + boxs, boxs, boxw, boxw, m->sel->isfixed, 0);
- } else {
- drw_setscheme(drw, scheme[SchemeNorm]);
- drw_rect(drw, x, 0, w, bh, 1, 1);
- }
- }
- drw_map(drw, m->barwin, 0, 0, m->ww, bh);
-}
-
-void
-drawbars(void)
-{
- Monitor *m;
-
- for (m = mons; m; m = m->next)
- drawbar(m);
-}
-
-void
-enternotify(XEvent *e)
-{
- Client *c;
- Monitor *m;
- XCrossingEvent *ev = &e->xcrossing;
-
- if ((ev->mode != NotifyNormal || ev->detail == NotifyInferior) && ev->window != root)
- return;
- c = wintoclient(ev->window);
- m = c ? c->mon : wintomon(ev->window);
- if (m != selmon) {
- unfocus(selmon->sel, 1);
- selmon = m;
- } else if (!c || c == selmon->sel)
- return;
- focus(c);
-}
-
-void
-expose(XEvent *e)
-{
- Monitor *m;
- XExposeEvent *ev = &e->xexpose;
-
- if (ev->count == 0 && (m = wintomon(ev->window)))
- drawbar(m);
-}
-
-void
-focus(Client *c)
-{
- if (!c || !ISVISIBLE(c))
- for (c = selmon->stack; c && !ISVISIBLE(c); c = c->snext);
- if (selmon->sel && selmon->sel != c)
- unfocus(selmon->sel, 0);
- if (c) {
- if (c->mon != selmon)
- selmon = c->mon;
- if (c->isurgent)
- seturgent(c, 0);
- detachstack(c);
- attachstack(c);
- grabbuttons(c, 1);
- XSetWindowBorder(dpy, c->win, scheme[SchemeSel][ColBorder].pixel);
- setfocus(c);
- } else {
- XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
- XDeleteProperty(dpy, root, netatom[NetActiveWindow]);
- }
- selmon->sel = c;
- drawbars();
-}
-
-/* there are some broken focus acquiring clients needing extra handling */
-void
-focusin(XEvent *e)
-{
- XFocusChangeEvent *ev = &e->xfocus;
-
- if (selmon->sel && ev->window != selmon->sel->win)
- setfocus(selmon->sel);
-}
-
-void
-focusmon(const Arg *arg)
-{
- Monitor *m;
-
- if (!mons->next)
- return;
- if ((m = dirtomon(arg->i)) == selmon)
- return;
- unfocus(selmon->sel, 0);
- selmon = m;
- focus(NULL);
-}
-
-void
-focusstack(const Arg *arg)
-{
- Client *c = NULL, *i;
-
- if (!selmon->sel || (selmon->sel->isfullscreen && lockfullscreen))
- return;
- if (arg->i > 0) {
- for (c = selmon->sel->next; c && !ISVISIBLE(c); c = c->next);
- if (!c)
- for (c = selmon->clients; c && !ISVISIBLE(c); c = c->next);
- } else {
- for (i = selmon->clients; i != selmon->sel; i = i->next)
- if (ISVISIBLE(i))
- c = i;
- if (!c)
- for (; i; i = i->next)
- if (ISVISIBLE(i))
- c = i;
- }
- if (c) {
- focus(c);
- restack(selmon);
- }
-}
-
-Atom
-getatomprop(Client *c, Atom prop)
-{
- int di;
- unsigned long dl;
- unsigned char *p = NULL;
- Atom da, atom = None;
-
- if (XGetWindowProperty(dpy, c->win, prop, 0L, sizeof atom, False, XA_ATOM,
- &da, &di, &dl, &dl, &p) == Success && p) {
- atom = *(Atom *)p;
- XFree(p);
- }
- return atom;
-}
-
-int
-getrootptr(int *x, int *y)
-{
- int di;
- unsigned int dui;
- Window dummy;
-
- return XQueryPointer(dpy, root, &dummy, &dummy, x, y, &di, &di, &dui);
-}
-
-long
-getstate(Window w)
-{
- int format;
- long result = -1;
- unsigned char *p = NULL;
- unsigned long n, extra;
- Atom real;
-
- if (XGetWindowProperty(dpy, w, wmatom[WMState], 0L, 2L, False, wmatom[WMState],
- &real, &format, &n, &extra, (unsigned char **)&p) != Success)
- return -1;
- if (n != 0)
- result = *p;
- XFree(p);
- return result;
-}
-
-int
-gettextprop(Window w, Atom atom, char *text, unsigned int size)
-{
- char **list = NULL;
- int n;
- XTextProperty name;
-
- if (!text || size == 0)
- return 0;
- text[0] = '\0';
- if (!XGetTextProperty(dpy, w, &name, atom) || !name.nitems)
- return 0;
- if (name.encoding == XA_STRING)
- strncpy(text, (char *)name.value, size - 1);
- else {
- if (XmbTextPropertyToTextList(dpy, &name, &list, &n) >= Success && n > 0 && *list) {
- strncpy(text, *list, size - 1);
- XFreeStringList(list);
- }
- }
- text[size - 1] = '\0';
- XFree(name.value);
- return 1;
-}
-
-void
-grabbuttons(Client *c, int focused)
-{
- updatenumlockmask();
- {
- unsigned int i, j;
- unsigned int modifiers[] = { 0, LockMask, numlockmask, numlockmask|LockMask };
- XUngrabButton(dpy, AnyButton, AnyModifier, c->win);
- if (!focused)
- XGrabButton(dpy, AnyButton, AnyModifier, c->win, False,
- BUTTONMASK, GrabModeSync, GrabModeSync, None, None);
- for (i = 0; i < LENGTH(buttons); i++)
- if (buttons[i].click == ClkClientWin)
- for (j = 0; j < LENGTH(modifiers); j++)
- XGrabButton(dpy, buttons[i].button,
- buttons[i].mask | modifiers[j],
- c->win, False, BUTTONMASK,
- GrabModeAsync, GrabModeSync, None, None);
- }
-}
-
-void
-grabkeys(void)
-{
- updatenumlockmask();
- {
- unsigned int i, j;
- unsigned int modifiers[] = { 0, LockMask, numlockmask, numlockmask|LockMask };
- KeyCode code;
-
- XUngrabKey(dpy, AnyKey, AnyModifier, root);
- for (i = 0; i < LENGTH(keys); i++)
- if ((code = XKeysymToKeycode(dpy, keys[i].keysym)))
- for (j = 0; j < LENGTH(modifiers); j++)
- XGrabKey(dpy, code, keys[i].mod | modifiers[j], root,
- True, GrabModeAsync, GrabModeAsync);
- }
-}
-
-void
-incnmaster(const Arg *arg)
-{
- selmon->nmaster = MAX(selmon->nmaster + arg->i, 0);
- arrange(selmon);
-}
-
-#ifdef XINERAMA
-static int
-isuniquegeom(XineramaScreenInfo *unique, size_t n, XineramaScreenInfo *info)
-{
- while (n--)
- if (unique[n].x_org == info->x_org && unique[n].y_org == info->y_org
- && unique[n].width == info->width && unique[n].height == info->height)
- return 0;
- return 1;
-}
-#endif /* XINERAMA */
-
-void
-keypress(XEvent *e)
-{
- unsigned int i;
- KeySym keysym;
- XKeyEvent *ev;
-
- ev = &e->xkey;
- keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0);
- for (i = 0; i < LENGTH(keys); i++)
- if (keysym == keys[i].keysym
- && CLEANMASK(keys[i].mod) == CLEANMASK(ev->state)
- && keys[i].func)
- keys[i].func(&(keys[i].arg));
-}
-
-void
-killclient(const Arg *arg)
-{
- if (!selmon->sel)
- return;
- if (!sendevent(selmon->sel, wmatom[WMDelete])) {
- XGrabServer(dpy);
- XSetErrorHandler(xerrordummy);
- XSetCloseDownMode(dpy, DestroyAll);
- XKillClient(dpy, selmon->sel->win);
- XSync(dpy, False);
- XSetErrorHandler(xerror);
- XUngrabServer(dpy);
- }
-}
-
-void
-manage(Window w, XWindowAttributes *wa)
-{
- Client *c, *t = NULL;
- Window trans = None;
- XWindowChanges wc;
-
- c = ecalloc(1, sizeof(Client));
- c->win = w;
- /* geometry */
- c->x = c->oldx = wa->x;
- c->y = c->oldy = wa->y;
- c->w = c->oldw = wa->width;
- c->h = c->oldh = wa->height;
- c->oldbw = wa->border_width;
-
- updatetitle(c);
- if (XGetTransientForHint(dpy, w, &trans) && (t = wintoclient(trans))) {
- c->mon = t->mon;
- c->tags = t->tags;
- } else {
- c->mon = selmon;
- applyrules(c);
- }
-
- if (c->x + WIDTH(c) > c->mon->mx + c->mon->mw)
- c->x = c->mon->mx + c->mon->mw - WIDTH(c);
- if (c->y + HEIGHT(c) > c->mon->my + c->mon->mh)
- c->y = c->mon->my + c->mon->mh - HEIGHT(c);
- c->x = MAX(c->x, c->mon->mx);
- /* only fix client y-offset, if the client center might cover the bar */
- c->y = MAX(c->y, ((c->mon->by == c->mon->my) && (c->x + (c->w / 2) >= c->mon->wx)
- && (c->x + (c->w / 2) < c->mon->wx + c->mon->ww)) ? bh : c->mon->my);
- c->bw = borderpx;
-
- wc.border_width = c->bw;
- XConfigureWindow(dpy, w, CWBorderWidth, &wc);
- XSetWindowBorder(dpy, w, scheme[SchemeNorm][ColBorder].pixel);
- configure(c); /* propagates border_width, if size doesn't change */
- updatewindowtype(c);
- updatesizehints(c);
- updatewmhints(c);
- XSelectInput(dpy, w, EnterWindowMask|FocusChangeMask|PropertyChangeMask|StructureNotifyMask);
- grabbuttons(c, 0);
- if (!c->isfloating)
- c->isfloating = c->oldstate = trans != None || c->isfixed;
- if (c->isfloating)
- XRaiseWindow(dpy, c->win);
- attach(c);
- attachstack(c);
- XChangeProperty(dpy, root, netatom[NetClientList], XA_WINDOW, 32, PropModeAppend,
- (unsigned char *) &(c->win), 1);
- XMoveResizeWindow(dpy, c->win, c->x + 2 * sw, c->y, c->w, c->h); /* some windows require this */
- setclientstate(c, NormalState);
- if (c->mon == selmon)
- unfocus(selmon->sel, 0);
- c->mon->sel = c;
- arrange(c->mon);
- XMapWindow(dpy, c->win);
- focus(NULL);
-}
-
-void
-mappingnotify(XEvent *e)
-{
- XMappingEvent *ev = &e->xmapping;
-
- XRefreshKeyboardMapping(ev);
- if (ev->request == MappingKeyboard)
- grabkeys();
-}
-
-void
-maprequest(XEvent *e)
-{
- static XWindowAttributes wa;
- XMapRequestEvent *ev = &e->xmaprequest;
-
- if (!XGetWindowAttributes(dpy, ev->window, &wa))
- return;
- if (wa.override_redirect)
- return;
- if (!wintoclient(ev->window))
- manage(ev->window, &wa);
-}
-
-void
-monocle(Monitor *m)
-{
- unsigned int n = 0;
- Client *c;
-
- for (c = m->clients; c; c = c->next)
- if (ISVISIBLE(c))
- n++;
- if (n > 0) /* override layout symbol */
- snprintf(m->ltsymbol, sizeof m->ltsymbol, "[%d]", n);
- for (c = nexttiled(m->clients); c; c = nexttiled(c->next))
- resize(c, m->wx, m->wy, m->ww - 2 * c->bw, m->wh - 2 * c->bw, 0);
-}
-
-void
-motionnotify(XEvent *e)
-{
- static Monitor *mon = NULL;
- Monitor *m;
- XMotionEvent *ev = &e->xmotion;
-
- if (ev->window != root)
- return;
- if ((m = recttomon(ev->x_root, ev->y_root, 1, 1)) != mon && mon) {
- unfocus(selmon->sel, 1);
- selmon = m;
- focus(NULL);
- }
- mon = m;
-}
-
-void
-movemouse(const Arg *arg)
-{
- int x, y, ocx, ocy, nx, ny;
- Client *c;
- Monitor *m;
- XEvent ev;
- Time lasttime = 0;
-
- if (!(c = selmon->sel))
- return;
- if (c->isfullscreen) /* no support moving fullscreen windows by mouse */
- return;
- restack(selmon);
- ocx = c->x;
- ocy = c->y;
- if (XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync,
- None, cursor[CurMove]->cursor, CurrentTime) != GrabSuccess)
- return;
- if (!getrootptr(&x, &y))
- return;
- do {
- XMaskEvent(dpy, MOUSEMASK|ExposureMask|SubstructureRedirectMask, &ev);
- switch(ev.type) {
- case ConfigureRequest:
- case Expose:
- case MapRequest:
- handler[ev.type](&ev);
- break;
- case MotionNotify:
- if ((ev.xmotion.time - lasttime) <= (1000 / 60))
- continue;
- lasttime = ev.xmotion.time;
-
- nx = ocx + (ev.xmotion.x - x);
- ny = ocy + (ev.xmotion.y - y);
- if (abs(selmon->wx - nx) < snap)
- nx = selmon->wx;
- else if (abs((selmon->wx + selmon->ww) - (nx + WIDTH(c))) < snap)
- nx = selmon->wx + selmon->ww - WIDTH(c);
- if (abs(selmon->wy - ny) < snap)
- ny = selmon->wy;
- else if (abs((selmon->wy + selmon->wh) - (ny + HEIGHT(c))) < snap)
- ny = selmon->wy + selmon->wh - HEIGHT(c);
- if (!c->isfloating && selmon->lt[selmon->sellt]->arrange
- && (abs(nx - c->x) > snap || abs(ny - c->y) > snap))
- togglefloating(NULL);
- if (!selmon->lt[selmon->sellt]->arrange || c->isfloating)
- resize(c, nx, ny, c->w, c->h, 1);
- break;
- }
- } while (ev.type != ButtonRelease);
- XUngrabPointer(dpy, CurrentTime);
- if ((m = recttomon(c->x, c->y, c->w, c->h)) != selmon) {
- sendmon(c, m);
- selmon = m;
- focus(NULL);
- }
-}
-
-Client *
-nexttiled(Client *c)
-{
- for (; c && (c->isfloating || !ISVISIBLE(c)); c = c->next);
- return c;
-}
-
-void
-pop(Client *c)
-{
- detach(c);
- attach(c);
- focus(c);
- arrange(c->mon);
-}
-
-void
-propertynotify(XEvent *e)
-{
- Client *c;
- Window trans;
- XPropertyEvent *ev = &e->xproperty;
-
- if ((ev->window == root) && (ev->atom == XA_WM_NAME))
- updatestatus();
- else if (ev->state == PropertyDelete)
- return; /* ignore */
- else if ((c = wintoclient(ev->window))) {
- switch(ev->atom) {
- default: break;
- case XA_WM_TRANSIENT_FOR:
- if (!c->isfloating && (XGetTransientForHint(dpy, c->win, &trans)) &&
- (c->isfloating = (wintoclient(trans)) != NULL))
- arrange(c->mon);
- break;
- case XA_WM_NORMAL_HINTS:
- updatesizehints(c);
- break;
- case XA_WM_HINTS:
- updatewmhints(c);
- drawbars();
- break;
- }
- if (ev->atom == XA_WM_NAME || ev->atom == netatom[NetWMName]) {
- updatetitle(c);
- if (c == c->mon->sel)
- drawbar(c->mon);
- }
- if (ev->atom == netatom[NetWMWindowType])
- updatewindowtype(c);
- }
-}
-
-void
-quit(const Arg *arg)
-{
- running = 0;
-}
-
-Monitor *
-recttomon(int x, int y, int w, int h)
-{
- Monitor *m, *r = selmon;
- int a, area = 0;
-
- for (m = mons; m; m = m->next)
- if ((a = INTERSECT(x, y, w, h, m)) > area) {
- area = a;
- r = m;
- }
- return r;
-}
-
-void
-resize(Client *c, int x, int y, int w, int h, int interact)
-{
- if (applysizehints(c, &x, &y, &w, &h, interact))
- resizeclient(c, x, y, w, h);
-}
-
-void
-resizeclient(Client *c, int x, int y, int w, int h)
-{
- XWindowChanges wc;
-
- c->oldx = c->x; c->x = wc.x = x;
- c->oldy = c->y; c->y = wc.y = y;
- c->oldw = c->w; c->w = wc.width = w;
- c->oldh = c->h; c->h = wc.height = h;
- wc.border_width = c->bw;
- XConfigureWindow(dpy, c->win, CWX|CWY|CWWidth|CWHeight|CWBorderWidth, &wc);
- configure(c);
- XSync(dpy, False);
-}
-
-void
-resizemouse(const Arg *arg)
-{
- int ocx, ocy, nw, nh;
- Client *c;
- Monitor *m;
- XEvent ev;
- Time lasttime = 0;
-
- if (!(c = selmon->sel))
- return;
- if (c->isfullscreen) /* no support resizing fullscreen windows by mouse */
- return;
- restack(selmon);
- ocx = c->x;
- ocy = c->y;
- if (XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync,
- None, cursor[CurResize]->cursor, CurrentTime) != GrabSuccess)
- return;
- XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->bw - 1, c->h + c->bw - 1);
- do {
- XMaskEvent(dpy, MOUSEMASK|ExposureMask|SubstructureRedirectMask, &ev);
- switch(ev.type) {
- case ConfigureRequest:
- case Expose:
- case MapRequest:
- handler[ev.type](&ev);
- break;
- case MotionNotify:
- if ((ev.xmotion.time - lasttime) <= (1000 / 60))
- continue;
- lasttime = ev.xmotion.time;
-
- nw = MAX(ev.xmotion.x - ocx - 2 * c->bw + 1, 1);
- nh = MAX(ev.xmotion.y - ocy - 2 * c->bw + 1, 1);
- if (c->mon->wx + nw >= selmon->wx && c->mon->wx + nw <= selmon->wx + selmon->ww
- && c->mon->wy + nh >= selmon->wy && c->mon->wy + nh <= selmon->wy + selmon->wh)
- {
- if (!c->isfloating && selmon->lt[selmon->sellt]->arrange
- && (abs(nw - c->w) > snap || abs(nh - c->h) > snap))
- togglefloating(NULL);
- }
- if (!selmon->lt[selmon->sellt]->arrange || c->isfloating)
- resize(c, c->x, c->y, nw, nh, 1);
- break;
- }
- } while (ev.type != ButtonRelease);
- XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->bw - 1, c->h + c->bw - 1);
- XUngrabPointer(dpy, CurrentTime);
- while (XCheckMaskEvent(dpy, EnterWindowMask, &ev));
- if ((m = recttomon(c->x, c->y, c->w, c->h)) != selmon) {
- sendmon(c, m);
- selmon = m;
- focus(NULL);
- }
-}
-
-void
-restack(Monitor *m)
-{
- Client *c;
- XEvent ev;
- XWindowChanges wc;
-
- drawbar(m);
- if (!m->sel)
- return;
- if (m->sel->isfloating || !m->lt[m->sellt]->arrange)
- XRaiseWindow(dpy, m->sel->win);
- if (m->lt[m->sellt]->arrange) {
- wc.stack_mode = Below;
- wc.sibling = m->barwin;
- for (c = m->stack; c; c = c->snext)
- if (!c->isfloating && ISVISIBLE(c)) {
- XConfigureWindow(dpy, c->win, CWSibling|CWStackMode, &wc);
- wc.sibling = c->win;
- }
- }
- XSync(dpy, False);
- while (XCheckMaskEvent(dpy, EnterWindowMask, &ev));
-}
-
-void
-run(void)
-{
- XEvent ev;
- /* main event loop */
- XSync(dpy, False);
- while (running && !XNextEvent(dpy, &ev))
- if (handler[ev.type])
- handler[ev.type](&ev); /* call handler */
-}
-
-void
-scan(void)
-{
- unsigned int i, num;
- Window d1, d2, *wins = NULL;
- XWindowAttributes wa;
-
- if (XQueryTree(dpy, root, &d1, &d2, &wins, &num)) {
- for (i = 0; i < num; i++) {
- if (!XGetWindowAttributes(dpy, wins[i], &wa)
- || wa.override_redirect || XGetTransientForHint(dpy, wins[i], &d1))
- continue;
- if (wa.map_state == IsViewable || getstate(wins[i]) == IconicState)
- manage(wins[i], &wa);
- }
- for (i = 0; i < num; i++) { /* now the transients */
- if (!XGetWindowAttributes(dpy, wins[i], &wa))
- continue;
- if (XGetTransientForHint(dpy, wins[i], &d1)
- && (wa.map_state == IsViewable || getstate(wins[i]) == IconicState))
- manage(wins[i], &wa);
- }
- if (wins)
- XFree(wins);
- }
-}
-
-void
-sendmon(Client *c, Monitor *m)
-{
- if (c->mon == m)
- return;
- unfocus(c, 1);
- detach(c);
- detachstack(c);
- c->mon = m;
- c->tags = m->tagset[m->seltags]; /* assign tags of target monitor */
- attach(c);
- attachstack(c);
- focus(NULL);
- arrange(NULL);
-}
-
-void
-setclientstate(Client *c, long state)
-{
- long data[] = { state, None };
-
- XChangeProperty(dpy, c->win, wmatom[WMState], wmatom[WMState], 32,
- PropModeReplace, (unsigned char *)data, 2);
-}
-
-int
-sendevent(Client *c, Atom proto)
-{
- int n;
- Atom *protocols;
- int exists = 0;
- XEvent ev;
-
- if (XGetWMProtocols(dpy, c->win, &protocols, &n)) {
- while (!exists && n--)
- exists = protocols[n] == proto;
- XFree(protocols);
- }
- if (exists) {
- ev.type = ClientMessage;
- ev.xclient.window = c->win;
- ev.xclient.message_type = wmatom[WMProtocols];
- ev.xclient.format = 32;
- ev.xclient.data.l[0] = proto;
- ev.xclient.data.l[1] = CurrentTime;
- XSendEvent(dpy, c->win, False, NoEventMask, &ev);
- }
- return exists;
-}
-
-void
-setfocus(Client *c)
-{
- if (!c->neverfocus) {
- XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime);
- XChangeProperty(dpy, root, netatom[NetActiveWindow],
- XA_WINDOW, 32, PropModeReplace,
- (unsigned char *) &(c->win), 1);
- }
- sendevent(c, wmatom[WMTakeFocus]);
-}
-
-void
-setfullscreen(Client *c, int fullscreen)
-{
- if (fullscreen && !c->isfullscreen) {
- XChangeProperty(dpy, c->win, netatom[NetWMState], XA_ATOM, 32,
- PropModeReplace, (unsigned char*)&netatom[NetWMFullscreen], 1);
- c->isfullscreen = 1;
- c->oldstate = c->isfloating;
- c->oldbw = c->bw;
- c->bw = 0;
- c->isfloating = 1;
- resizeclient(c, c->mon->mx, c->mon->my, c->mon->mw, c->mon->mh);
- XRaiseWindow(dpy, c->win);
- } else if (!fullscreen && c->isfullscreen){
- XChangeProperty(dpy, c->win, netatom[NetWMState], XA_ATOM, 32,
- PropModeReplace, (unsigned char*)0, 0);
- c->isfullscreen = 0;
- c->isfloating = c->oldstate;
- c->bw = c->oldbw;
- c->x = c->oldx;
- c->y = c->oldy;
- c->w = c->oldw;
- c->h = c->oldh;
- resizeclient(c, c->x, c->y, c->w, c->h);
- arrange(c->mon);
- }
-}
-
-void
-setlayout(const Arg *arg)
-{
- if (!arg || !arg->v || arg->v != selmon->lt[selmon->sellt])
- selmon->sellt ^= 1;
- if (arg && arg->v)
- selmon->lt[selmon->sellt] = (Layout *)arg->v;
- strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, sizeof selmon->ltsymbol);
- if (selmon->sel)
- arrange(selmon);
- else
- drawbar(selmon);
-}
-
-/* arg > 1.0 will set mfact absolutely */
-void
-setmfact(const Arg *arg)
-{
- float f;
-
- if (!arg || !selmon->lt[selmon->sellt]->arrange)
- return;
- f = arg->f < 1.0 ? arg->f + selmon->mfact : arg->f - 1.0;
- if (f < 0.05 || f > 0.95)
- return;
- selmon->mfact = f;
- arrange(selmon);
-}
-
-void
-setup(void)
-{
- int i;
- XSetWindowAttributes wa;
- Atom utf8string;
-
- /* clean up any zombies immediately */
- sigchld(0);
-
- /* init screen */
- screen = DefaultScreen(dpy);
- sw = DisplayWidth(dpy, screen);
- sh = DisplayHeight(dpy, screen);
- root = RootWindow(dpy, screen);
- drw = drw_create(dpy, screen, root, sw, sh);
- if (!drw_fontset_create(drw, fonts, LENGTH(fonts)))
- die("no fonts could be loaded.");
- lrpad = drw->fonts->h;
- bh = drw->fonts->h + 2;
- updategeom();
- /* init atoms */
- utf8string = XInternAtom(dpy, "UTF8_STRING", False);
- wmatom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False);
- wmatom[WMDelete] = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
- wmatom[WMState] = XInternAtom(dpy, "WM_STATE", False);
- wmatom[WMTakeFocus] = XInternAtom(dpy, "WM_TAKE_FOCUS", False);
- netatom[NetActiveWindow] = XInternAtom(dpy, "_NET_ACTIVE_WINDOW", False);
- netatom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False);
- netatom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False);
- netatom[NetWMState] = XInternAtom(dpy, "_NET_WM_STATE", False);
- netatom[NetWMCheck] = XInternAtom(dpy, "_NET_SUPPORTING_WM_CHECK", False);
- netatom[NetWMFullscreen] = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False);
- netatom[NetWMWindowType] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False);
- netatom[NetWMWindowTypeDialog] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DIALOG", False);
- netatom[NetClientList] = XInternAtom(dpy, "_NET_CLIENT_LIST", False);
- /* init cursors */
- cursor[CurNormal] = drw_cur_create(drw, XC_left_ptr);
- cursor[CurResize] = drw_cur_create(drw, XC_sizing);
- cursor[CurMove] = drw_cur_create(drw, XC_fleur);
- /* init appearance */
- scheme = ecalloc(LENGTH(colors), sizeof(Clr *));
- for (i = 0; i < LENGTH(colors); i++)
- scheme[i] = drw_scm_create(drw, colors[i], 3);
- /* init bars */
- updatebars();
- updatestatus();
- /* supporting window for NetWMCheck */
- wmcheckwin = XCreateSimpleWindow(dpy, root, 0, 0, 1, 1, 0, 0, 0);
- XChangeProperty(dpy, wmcheckwin, netatom[NetWMCheck], XA_WINDOW, 32,
- PropModeReplace, (unsigned char *) &wmcheckwin, 1);
- XChangeProperty(dpy, wmcheckwin, netatom[NetWMName], utf8string, 8,
- PropModeReplace, (unsigned char *) "dwm", 3);
- XChangeProperty(dpy, root, netatom[NetWMCheck], XA_WINDOW, 32,
- PropModeReplace, (unsigned char *) &wmcheckwin, 1);
- /* EWMH support per view */
- XChangeProperty(dpy, root, netatom[NetSupported], XA_ATOM, 32,
- PropModeReplace, (unsigned char *) netatom, NetLast);
- XDeleteProperty(dpy, root, netatom[NetClientList]);
- /* select events */
- wa.cursor = cursor[CurNormal]->cursor;
- wa.event_mask = SubstructureRedirectMask|SubstructureNotifyMask
- |ButtonPressMask|PointerMotionMask|EnterWindowMask
- |LeaveWindowMask|StructureNotifyMask|PropertyChangeMask;
- XChangeWindowAttributes(dpy, root, CWEventMask|CWCursor, &wa);
- XSelectInput(dpy, root, wa.event_mask);
- grabkeys();
- focus(NULL);
-}
-
-
-void
-seturgent(Client *c, int urg)
-{
- XWMHints *wmh;
-
- c->isurgent = urg;
- if (!(wmh = XGetWMHints(dpy, c->win)))
- return;
- wmh->flags = urg ? (wmh->flags | XUrgencyHint) : (wmh->flags & ~XUrgencyHint);
- XSetWMHints(dpy, c->win, wmh);
- XFree(wmh);
-}
-
-void
-showhide(Client *c)
-{
- if (!c)
- return;
- if (ISVISIBLE(c)) {
- /* show clients top down */
- XMoveWindow(dpy, c->win, c->x, c->y);
- if ((!c->mon->lt[c->mon->sellt]->arrange || c->isfloating) && !c->isfullscreen)
- resize(c, c->x, c->y, c->w, c->h, 0);
- showhide(c->snext);
- } else {
- /* hide clients bottom up */
- showhide(c->snext);
- XMoveWindow(dpy, c->win, WIDTH(c) * -2, c->y);
- }
-}
-
-void
-sigchld(int unused)
-{
- if (signal(SIGCHLD, sigchld) == SIG_ERR)
- die("can't install SIGCHLD handler:");
- while (0 < waitpid(-1, NULL, WNOHANG));
-}
-
-void
-spawn(const Arg *arg)
-{
- if (arg->v == dmenucmd)
- dmenumon[0] = '0' + selmon->num;
- if (fork() == 0) {
- if (dpy)
- close(ConnectionNumber(dpy));
- setsid();
- execvp(((char **)arg->v)[0], (char **)arg->v);
- fprintf(stderr, "dwm: execvp %s", ((char **)arg->v)[0]);
- perror(" failed");
- exit(EXIT_SUCCESS);
- }
-}
-
-void
-tag(const Arg *arg)
-{
- if (selmon->sel && arg->ui & TAGMASK) {
- selmon->sel->tags = arg->ui & TAGMASK;
- focus(NULL);
- arrange(selmon);
- }
-}
-
-void
-tagmon(const Arg *arg)
-{
- if (!selmon->sel || !mons->next)
- return;
- sendmon(selmon->sel, dirtomon(arg->i));
-}
-
-void
-tile(Monitor *m)
-{
- unsigned int i, n, h, mw, my, ty;
- Client *c;
-
- for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
- if (n == 0)
- return;
-
- if (n > m->nmaster)
- mw = m->nmaster ? m->ww * m->mfact : 0;
- else
- mw = m->ww;
- for (i = my = ty = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
- if (i < m->nmaster) {
- h = (m->wh - my) / (MIN(n, m->nmaster) - i);
- resize(c, m->wx, m->wy + my, mw - (2*c->bw), h - (2*c->bw), 0);
- if (my + HEIGHT(c) < m->wh)
- my += HEIGHT(c);
- } else {
- h = (m->wh - ty) / (n - i);
- resize(c, m->wx + mw, m->wy + ty, m->ww - mw - (2*c->bw), h - (2*c->bw), 0);
- if (ty + HEIGHT(c) < m->wh)
- ty += HEIGHT(c);
- }
-}
-
-void
-togglebar(const Arg *arg)
-{
- selmon->showbar = !selmon->showbar;
- updatebarpos(selmon);
- XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh);
- arrange(selmon);
-}
-
-void
-togglefloating(const Arg *arg)
-{
- if (!selmon->sel)
- return;
- if (selmon->sel->isfullscreen) /* no support for fullscreen windows */
- return;
- selmon->sel->isfloating = !selmon->sel->isfloating || selmon->sel->isfixed;
- if (selmon->sel->isfloating)
- resize(selmon->sel, selmon->sel->x, selmon->sel->y,
- selmon->sel->w, selmon->sel->h, 0);
- arrange(selmon);
-}
-
-void
-togglescratch(const Arg *arg)
-{
- Client *c;
- unsigned int found = 0;
- unsigned int scratchtag = SPTAG(arg->ui);
- Arg sparg = {.v = scratchpads[arg->ui].cmd};
-
- for (c = selmon->clients; c && !(found = c->tags & scratchtag); c = c->next);
- if (found) {
- unsigned int newtagset = selmon->tagset[selmon->seltags] ^ scratchtag;
- if (newtagset) {
- selmon->tagset[selmon->seltags] = newtagset;
- focus(NULL);
- arrange(selmon);
- }
- if (ISVISIBLE(c)) {
- focus(c);
- restack(selmon);
- }
- } else {
- selmon->tagset[selmon->seltags] |= scratchtag;
- spawn(&sparg);
- }
-}
-
-void
-toggletag(const Arg *arg)
-{
- unsigned int newtags;
-
- if (!selmon->sel)
- return;
- newtags = selmon->sel->tags ^ (arg->ui & TAGMASK);
- if (newtags) {
- selmon->sel->tags = newtags;
- focus(NULL);
- arrange(selmon);
- }
-}
-
-void
-toggleview(const Arg *arg)
-{
- unsigned int newtagset = selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK);
-
- if (newtagset) {
- selmon->tagset[selmon->seltags] = newtagset;
- focus(NULL);
- arrange(selmon);
- }
-}
-
-void
-unfocus(Client *c, int setfocus)
-{
- if (!c)
- return;
- grabbuttons(c, 0);
- XSetWindowBorder(dpy, c->win, scheme[SchemeNorm][ColBorder].pixel);
- if (setfocus) {
- XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
- XDeleteProperty(dpy, root, netatom[NetActiveWindow]);
- }
-}
-
-void
-unmanage(Client *c, int destroyed)
-{
- Monitor *m = c->mon;
- XWindowChanges wc;
-
- detach(c);
- detachstack(c);
- if (!destroyed) {
- wc.border_width = c->oldbw;
- XGrabServer(dpy); /* avoid race conditions */
- XSetErrorHandler(xerrordummy);
- XConfigureWindow(dpy, c->win, CWBorderWidth, &wc); /* restore border */
- XUngrabButton(dpy, AnyButton, AnyModifier, c->win);
- setclientstate(c, WithdrawnState);
- XSync(dpy, False);
- XSetErrorHandler(xerror);
- XUngrabServer(dpy);
- }
- free(c);
- focus(NULL);
- updateclientlist();
- arrange(m);
-}
-
-void
-unmapnotify(XEvent *e)
-{
- Client *c;
- XUnmapEvent *ev = &e->xunmap;
-
- if ((c = wintoclient(ev->window))) {
- if (ev->send_event)
- setclientstate(c, WithdrawnState);
- else
- unmanage(c, 0);
- }
-}
-
-void
-updatebars(void)
-{
- Monitor *m;
- XSetWindowAttributes wa = {
- .override_redirect = True,
- .background_pixmap = ParentRelative,
- .event_mask = ButtonPressMask|ExposureMask
- };
- XClassHint ch = {"dwm", "dwm"};
- for (m = mons; m; m = m->next) {
- if (m->barwin)
- continue;
- m->barwin = XCreateWindow(dpy, root, m->wx, m->by, m->ww, bh, 0, DefaultDepth(dpy, screen),
- CopyFromParent, DefaultVisual(dpy, screen),
- CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa);
- XDefineCursor(dpy, m->barwin, cursor[CurNormal]->cursor);
- XMapRaised(dpy, m->barwin);
- XSetClassHint(dpy, m->barwin, &ch);
- }
-}
-
-void
-updatebarpos(Monitor *m)
-{
- m->wy = m->my;
- m->wh = m->mh;
- if (m->showbar) {
- m->wh -= bh;
- m->by = m->topbar ? m->wy : m->wy + m->wh;
- m->wy = m->topbar ? m->wy + bh : m->wy;
- } else
- m->by = -bh;
-}
-
-void
-updateclientlist()
-{
- Client *c;
- Monitor *m;
-
- XDeleteProperty(dpy, root, netatom[NetClientList]);
- for (m = mons; m; m = m->next)
- for (c = m->clients; c; c = c->next)
- XChangeProperty(dpy, root, netatom[NetClientList],
- XA_WINDOW, 32, PropModeAppend,
- (unsigned char *) &(c->win), 1);
-}
-
-int
-updategeom(void)
-{
- int dirty = 0;
-
-#ifdef XINERAMA
- if (XineramaIsActive(dpy)) {
- int i, j, n, nn;
- Client *c;
- Monitor *m;
- XineramaScreenInfo *info = XineramaQueryScreens(dpy, &nn);
- XineramaScreenInfo *unique = NULL;
-
- for (n = 0, m = mons; m; m = m->next, n++);
- /* only consider unique geometries as separate screens */
- unique = ecalloc(nn, sizeof(XineramaScreenInfo));
- for (i = 0, j = 0; i < nn; i++)
- if (isuniquegeom(unique, j, &info[i]))
- memcpy(&unique[j++], &info[i], sizeof(XineramaScreenInfo));
- XFree(info);
- nn = j;
- if (n <= nn) { /* new monitors available */
- for (i = 0; i < (nn - n); i++) {
- for (m = mons; m && m->next; m = m->next);
- if (m)
- m->next = createmon();
- else
- mons = createmon();
- }
- for (i = 0, m = mons; i < nn && m; m = m->next, i++)
- if (i >= n
- || unique[i].x_org != m->mx || unique[i].y_org != m->my
- || unique[i].width != m->mw || unique[i].height != m->mh)
- {
- dirty = 1;
- m->num = i;
- m->mx = m->wx = unique[i].x_org;
- m->my = m->wy = unique[i].y_org;
- m->mw = m->ww = unique[i].width;
- m->mh = m->wh = unique[i].height;
- updatebarpos(m);
- }
- } else { /* less monitors available nn < n */
- for (i = nn; i < n; i++) {
- for (m = mons; m && m->next; m = m->next);
- while ((c = m->clients)) {
- dirty = 1;
- m->clients = c->next;
- detachstack(c);
- c->mon = mons;
- attach(c);
- attachstack(c);
- }
- if (m == selmon)
- selmon = mons;
- cleanupmon(m);
- }
- }
- free(unique);
- } else
-#endif /* XINERAMA */
- { /* default monitor setup */
- if (!mons)
- mons = createmon();
- if (mons->mw != sw || mons->mh != sh) {
- dirty = 1;
- mons->mw = mons->ww = sw;
- mons->mh = mons->wh = sh;
- updatebarpos(mons);
- }
- }
- if (dirty) {
- selmon = mons;
- selmon = wintomon(root);
- }
- return dirty;
-}
-
-void
-updatenumlockmask(void)
-{
- unsigned int i, j;
- XModifierKeymap *modmap;
-
- numlockmask = 0;
- modmap = XGetModifierMapping(dpy);
- for (i = 0; i < 8; i++)
- for (j = 0; j < modmap->max_keypermod; j++)
- if (modmap->modifiermap[i * modmap->max_keypermod + j]
- == XKeysymToKeycode(dpy, XK_Num_Lock))
- numlockmask = (1 << i);
- XFreeModifiermap(modmap);
-}
-
-void
-updatesizehints(Client *c)
-{
- long msize;
- XSizeHints size;
-
- if (!XGetWMNormalHints(dpy, c->win, &size, &msize))
- /* size is uninitialized, ensure that size.flags aren't used */
- size.flags = PSize;
- if (size.flags & PBaseSize) {
- c->basew = size.base_width;
- c->baseh = size.base_height;
- } else if (size.flags & PMinSize) {
- c->basew = size.min_width;
- c->baseh = size.min_height;
- } else
- c->basew = c->baseh = 0;
- if (size.flags & PResizeInc) {
- c->incw = size.width_inc;
- c->inch = size.height_inc;
- } else
- c->incw = c->inch = 0;
- if (size.flags & PMaxSize) {
- c->maxw = size.max_width;
- c->maxh = size.max_height;
- } else
- c->maxw = c->maxh = 0;
- if (size.flags & PMinSize) {
- c->minw = size.min_width;
- c->minh = size.min_height;
- } else if (size.flags & PBaseSize) {
- c->minw = size.base_width;
- c->minh = size.base_height;
- } else
- c->minw = c->minh = 0;
- if (size.flags & PAspect) {
- c->mina = (float)size.min_aspect.y / size.min_aspect.x;
- c->maxa = (float)size.max_aspect.x / size.max_aspect.y;
- } else
- c->maxa = c->mina = 0.0;
- c->isfixed = (c->maxw && c->maxh && c->maxw == c->minw && c->maxh == c->minh);
-}
-
-void
-updatestatus(void)
-{
- if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext)))
- strcpy(stext, "dwm-"VERSION);
- drawbar(selmon);
-}
-
-void
-updatetitle(Client *c)
-{
- if (!gettextprop(c->win, netatom[NetWMName], c->name, sizeof c->name))
- gettextprop(c->win, XA_WM_NAME, c->name, sizeof c->name);
- if (c->name[0] == '\0') /* hack to mark broken clients */
- strcpy(c->name, broken);
-}
-
-void
-updatewindowtype(Client *c)
-{
- Atom state = getatomprop(c, netatom[NetWMState]);
- Atom wtype = getatomprop(c, netatom[NetWMWindowType]);
-
- if (state == netatom[NetWMFullscreen])
- setfullscreen(c, 1);
- if (wtype == netatom[NetWMWindowTypeDialog])
- c->isfloating = 1;
-}
-
-void
-updatewmhints(Client *c)
-{
- XWMHints *wmh;
-
- if ((wmh = XGetWMHints(dpy, c->win))) {
- if (c == selmon->sel && wmh->flags & XUrgencyHint) {
- wmh->flags &= ~XUrgencyHint;
- XSetWMHints(dpy, c->win, wmh);
- } else
- c->isurgent = (wmh->flags & XUrgencyHint) ? 1 : 0;
- if (wmh->flags & InputHint)
- c->neverfocus = !wmh->input;
- else
- c->neverfocus = 0;
- XFree(wmh);
- }
-}
-
-void
-view(const Arg *arg)
-{
- if ((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags])
- return;
- selmon->seltags ^= 1; /* toggle sel tagset */
- if (arg->ui & TAGMASK)
- selmon->tagset[selmon->seltags] = arg->ui & TAGMASK;
- focus(NULL);
- arrange(selmon);
-}
-
-Client *
-wintoclient(Window w)
-{
- Client *c;
- Monitor *m;
-
- for (m = mons; m; m = m->next)
- for (c = m->clients; c; c = c->next)
- if (c->win == w)
- return c;
- return NULL;
-}
-
-Monitor *
-wintomon(Window w)
-{
- int x, y;
- Client *c;
- Monitor *m;
-
- if (w == root && getrootptr(&x, &y))
- return recttomon(x, y, 1, 1);
- for (m = mons; m; m = m->next)
- if (w == m->barwin)
- return m;
- if ((c = wintoclient(w)))
- return c->mon;
- return selmon;
-}
-
-/* There's no way to check accesses to destroyed windows, thus those cases are
- * ignored (especially on UnmapNotify's). Other types of errors call Xlibs
- * default error handler, which may call exit. */
-int
-xerror(Display *dpy, XErrorEvent *ee)
-{
- if (ee->error_code == BadWindow
- || (ee->request_code == X_SetInputFocus && ee->error_code == BadMatch)
- || (ee->request_code == X_PolyText8 && ee->error_code == BadDrawable)
- || (ee->request_code == X_PolyFillRectangle && ee->error_code == BadDrawable)
- || (ee->request_code == X_PolySegment && ee->error_code == BadDrawable)
- || (ee->request_code == X_ConfigureWindow && ee->error_code == BadMatch)
- || (ee->request_code == X_GrabButton && ee->error_code == BadAccess)
- || (ee->request_code == X_GrabKey && ee->error_code == BadAccess)
- || (ee->request_code == X_CopyArea && ee->error_code == BadDrawable))
- return 0;
- fprintf(stderr, "dwm: fatal error: request code=%d, error code=%d\n",
- ee->request_code, ee->error_code);
- return xerrorxlib(dpy, ee); /* may call exit */
-}
-
-int
-xerrordummy(Display *dpy, XErrorEvent *ee)
-{
- return 0;
-}
-
-/* Startup Error handler to check if another window manager
- * is already running. */
-int
-xerrorstart(Display *dpy, XErrorEvent *ee)
-{
- die("dwm: another window manager is already running");
- return -1;
-}
-
-void
-zoom(const Arg *arg)
-{
- Client *c = selmon->sel;
-
- if (!selmon->lt[selmon->sellt]->arrange
- || (selmon->sel && selmon->sel->isfloating))
- return;
- if (c == nexttiled(selmon->clients))
- if (!c || !(c = nexttiled(c->next)))
- return;
- pop(c);
-}
-
-int
-main(int argc, char *argv[])
-{
- if (argc == 2 && !strcmp("-v", argv[1]))
- die("dwm-"VERSION);
- else if (argc != 1)
- die("usage: dwm [-v]");
- if (!setlocale(LC_CTYPE, "") || !XSupportsLocale())
- fputs("warning: no locale support\n", stderr);
- if (!(dpy = XOpenDisplay(NULL)))
- die("dwm: cannot open display");
- checkotherwm();
- setup();
-#ifdef __OpenBSD__
- if (pledge("stdio rpath proc exec", NULL) == -1)
- die("pledge");
-#endif /* __OpenBSD__ */
- scan();
- run();
- cleanup();
- XCloseDisplay(dpy);
- return EXIT_SUCCESS;
-}
diff --git a/.repos/dwm/dwm.o b/.repos/dwm/dwm.o
deleted file mode 100644
index 898bc89..0000000
--- a/.repos/dwm/dwm.o
+++ /dev/null
Binary files differ
diff --git a/.repos/dwm/dwm.png b/.repos/dwm/dwm.png
deleted file mode 100644
index b1f9ba7..0000000
--- a/.repos/dwm/dwm.png
+++ /dev/null
Binary files differ
diff --git a/.repos/dwm/patches/dwm-pertag-20200914-61bb8b2.diff b/.repos/dwm/patches/dwm-pertag-20200914-61bb8b2.diff
deleted file mode 100644
index c8d7fbc..0000000
--- a/.repos/dwm/patches/dwm-pertag-20200914-61bb8b2.diff
+++ /dev/null
@@ -1,177 +0,0 @@
-diff --git a/dwm.c b/dwm.c
-index 664c527..ac8e4ec 100644
---- a/dwm.c
-+++ b/dwm.c
-@@ -111,6 +111,7 @@ typedef struct {
- void (*arrange)(Monitor *);
- } Layout;
-
-+typedef struct Pertag Pertag;
- struct Monitor {
- char ltsymbol[16];
- float mfact;
-@@ -130,6 +131,7 @@ struct Monitor {
- Monitor *next;
- Window barwin;
- const Layout *lt[2];
-+ Pertag *pertag;
- };
-
- typedef struct {
-@@ -272,6 +274,15 @@ static Window root, wmcheckwin;
- /* configuration, allows nested code to access above variables */
- #include "config.h"
-
-+struct Pertag {
-+ unsigned int curtag, prevtag; /* current and previous tag */
-+ int nmasters[LENGTH(tags) + 1]; /* number of windows in master area */
-+ float mfacts[LENGTH(tags) + 1]; /* mfacts per tag */
-+ unsigned int sellts[LENGTH(tags) + 1]; /* selected layouts */
-+ const Layout *ltidxs[LENGTH(tags) + 1][2]; /* matrix of tags and layouts indexes */
-+ int showbars[LENGTH(tags) + 1]; /* display bar for the current tag */
-+};
-+
- /* compile-time check if all tags fit into an unsigned int bit array. */
- struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; };
-
-@@ -632,6 +643,7 @@ Monitor *
- createmon(void)
- {
- Monitor *m;
-+ unsigned int i;
-
- m = ecalloc(1, sizeof(Monitor));
- m->tagset[0] = m->tagset[1] = 1;
-@@ -642,6 +654,20 @@ createmon(void)
- m->lt[0] = &layouts[0];
- m->lt[1] = &layouts[1 % LENGTH(layouts)];
- strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol);
-+ m->pertag = ecalloc(1, sizeof(Pertag));
-+ m->pertag->curtag = m->pertag->prevtag = 1;
-+
-+ for (i = 0; i <= LENGTH(tags); i++) {
-+ m->pertag->nmasters[i] = m->nmaster;
-+ m->pertag->mfacts[i] = m->mfact;
-+
-+ m->pertag->ltidxs[i][0] = m->lt[0];
-+ m->pertag->ltidxs[i][1] = m->lt[1];
-+ m->pertag->sellts[i] = m->sellt;
-+
-+ m->pertag->showbars[i] = m->showbar;
-+ }
-+
- return m;
- }
-
-@@ -967,7 +993,7 @@ grabkeys(void)
- void
- incnmaster(const Arg *arg)
- {
-- selmon->nmaster = MAX(selmon->nmaster + arg->i, 0);
-+ selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag] = MAX(selmon->nmaster + arg->i, 0);
- arrange(selmon);
- }
-
-@@ -1502,9 +1528,9 @@ void
- setlayout(const Arg *arg)
- {
- if (!arg || !arg->v || arg->v != selmon->lt[selmon->sellt])
-- selmon->sellt ^= 1;
-+ selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag] ^= 1;
- if (arg && arg->v)
-- selmon->lt[selmon->sellt] = (Layout *)arg->v;
-+ selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt] = (Layout *)arg->v;
- strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, sizeof selmon->ltsymbol);
- if (selmon->sel)
- arrange(selmon);
-@@ -1523,7 +1549,7 @@ setmfact(const Arg *arg)
- f = arg->f < 1.0 ? arg->f + selmon->mfact : arg->f - 1.0;
- if (f < 0.05 || f > 0.95)
- return;
-- selmon->mfact = f;
-+ selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag] = f;
- arrange(selmon);
- }
-
-@@ -1702,7 +1728,7 @@ tile(Monitor *m)
- void
- togglebar(const Arg *arg)
- {
-- selmon->showbar = !selmon->showbar;
-+ selmon->showbar = selmon->pertag->showbars[selmon->pertag->curtag] = !selmon->showbar;
- updatebarpos(selmon);
- XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh);
- arrange(selmon);
-@@ -1741,9 +1767,33 @@ void
- toggleview(const Arg *arg)
- {
- unsigned int newtagset = selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK);
-+ int i;
-
- if (newtagset) {
- selmon->tagset[selmon->seltags] = newtagset;
-+
-+ if (newtagset == ~0) {
-+ selmon->pertag->prevtag = selmon->pertag->curtag;
-+ selmon->pertag->curtag = 0;
-+ }
-+
-+ /* test if the user did not select the same tag */
-+ if (!(newtagset & 1 << (selmon->pertag->curtag - 1))) {
-+ selmon->pertag->prevtag = selmon->pertag->curtag;
-+ for (i = 0; !(newtagset & 1 << i); i++) ;
-+ selmon->pertag->curtag = i + 1;
-+ }
-+
-+ /* apply settings for this view */
-+ selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag];
-+ selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag];
-+ selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag];
-+ selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt];
-+ selmon->lt[selmon->sellt^1] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt^1];
-+
-+ if (selmon->showbar != selmon->pertag->showbars[selmon->pertag->curtag])
-+ togglebar(NULL);
-+
- focus(NULL);
- arrange(selmon);
- }
-@@ -2038,11 +2088,37 @@ updatewmhints(Client *c)
- void
- view(const Arg *arg)
- {
-+ int i;
-+ unsigned int tmptag;
-+
- if ((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags])
- return;
- selmon->seltags ^= 1; /* toggle sel tagset */
-- if (arg->ui & TAGMASK)
-+ if (arg->ui & TAGMASK) {
- selmon->tagset[selmon->seltags] = arg->ui & TAGMASK;
-+ selmon->pertag->prevtag = selmon->pertag->curtag;
-+
-+ if (arg->ui == ~0)
-+ selmon->pertag->curtag = 0;
-+ else {
-+ for (i = 0; !(arg->ui & 1 << i); i++) ;
-+ selmon->pertag->curtag = i + 1;
-+ }
-+ } else {
-+ tmptag = selmon->pertag->prevtag;
-+ selmon->pertag->prevtag = selmon->pertag->curtag;
-+ selmon->pertag->curtag = tmptag;
-+ }
-+
-+ selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag];
-+ selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag];
-+ selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag];
-+ selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt];
-+ selmon->lt[selmon->sellt^1] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt^1];
-+
-+ if (selmon->showbar != selmon->pertag->showbars[selmon->pertag->curtag])
-+ togglebar(NULL);
-+
- focus(NULL);
- arrange(selmon);
- }
diff --git a/.repos/dwm/patches/dwm-scratchpads-20200414-728d397b.diff b/.repos/dwm/patches/dwm-scratchpads-20200414-728d397b.diff
deleted file mode 100644
index d3e90c0..0000000
--- a/.repos/dwm/patches/dwm-scratchpads-20200414-728d397b.diff
+++ /dev/null
@@ -1,199 +0,0 @@
-From 728d397b21982af88737277fd9d6939a7b558786 Mon Sep 17 00:00:00 2001
-From: Christian Tenllado <ctenllado@gmail.com>
-Date: Tue, 14 Apr 2020 23:31:15 +0200
-Subject: [PATCH] Multiple scratchpads
-
-This patch enables multiple scratchpads, each with one asigned window.
-This enables the same scratchpad workflow that you have in i3.
-
-Scratchpads are implemented as special tags, whose mask does not
-apply to new spawned windows. To assign a window to a scratchpad you
-have to set up a rule, as you do with regular tags.
-
-Windows tagged with scratchpad tags can be set floating or not in the
-rules array. Most users would probably want them floating (i3 style),
-but having them tiled does also perfectly work and might fit better the
-DWM approach. In case they are set floating, the patch moves them to the
-center of the screen whenever they are shown. The patch can easily be
-modified to make this last feature configurable in the rules array (see
-the center patch).
-
-The togglescratch function, borrowed from the previous scratchpad patch
-and slightly modified, can be used to spawn a registered scratchpad
-process or toggle its view. This function looks for a window tagged with
-the selected scratchpad tag. If it is found its view is toggled. If it is
-not found the corresponding registered command is spawned. The
-config.def.h shows three examples of its use to spawn a terminal in the
-first scratchpad tag, a second terminal running ranger on the second
-scratchpad tag and the keepassxc application to manage passwords on a
-third scratchpad tag.
-
-If you prefer to spawn your scratchpad applications from the startup
-script, you might opt for binding keys to toggleview instead, as
-scratchpads are just special tags (you may even extend the TAGKEYS macro
-to generalize the key bindings).
----
- config.def.h | 28 ++++++++++++++++++++++++----
- dwm.c | 43 +++++++++++++++++++++++++++++++++++++++++--
- 2 files changed, 65 insertions(+), 6 deletions(-)
-
-diff --git a/config.def.h b/config.def.h
-index 1c0b587..06265e1 100644
---- a/config.def.h
-+++ b/config.def.h
-@@ -18,17 +18,33 @@ static const char *colors[][3] = {
- [SchemeSel] = { col_gray4, col_cyan, col_cyan },
- };
-
-+typedef struct {
-+ const char *name;
-+ const void *cmd;
-+} Sp;
-+const char *spcmd1[] = {"st", "-n", "spterm", "-g", "120x34", NULL };
-+const char *spcmd2[] = {"st", "-n", "spfm", "-g", "144x41", "-e", "ranger", NULL };
-+const char *spcmd3[] = {"keepassxc", NULL };
-+static Sp scratchpads[] = {
-+ /* name cmd */
-+ {"spterm", spcmd1},
-+ {"spranger", spcmd2},
-+ {"keepassxc", spcmd3},
-+};
-+
- /* tagging */
- static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" };
--
- static const Rule rules[] = {
- /* xprop(1):
- * WM_CLASS(STRING) = instance, class
- * WM_NAME(STRING) = title
- */
- /* class instance title tags mask isfloating monitor */
-- { "Gimp", NULL, NULL, 0, 1, -1 },
-- { "Firefox", NULL, NULL, 1 << 8, 0, -1 },
-+ { "Gimp", NULL, NULL, 0, 1, -1 },
-+ { "Firefox", NULL, NULL, 1 << 8, 0, -1 },
-+ { NULL, "spterm", NULL, SPTAG(0), 1, -1 },
-+ { NULL, "spfm", NULL, SPTAG(1), 1, -1 },
-+ { NULL, "keepassxc", NULL, SPTAG(2), 0, -1 },
- };
-
- /* layout(s) */
-@@ -59,6 +75,7 @@ static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn()
- static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL };
- static const char *termcmd[] = { "st", NULL };
-
-+
- static Key keys[] = {
- /* modifier key function argument */
- { MODKEY, XK_p, spawn, {.v = dmenucmd } },
-@@ -84,6 +101,9 @@ static Key keys[] = {
- { MODKEY, XK_period, focusmon, {.i = +1 } },
- { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } },
- { MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } },
-+ { MODKEY, XK_y, togglescratch, {.ui = 0 } },
-+ { MODKEY, XK_u, togglescratch, {.ui = 1 } },
-+ { MODKEY, XK_x, togglescratch, {.ui = 2 } },
- TAGKEYS( XK_1, 0)
- TAGKEYS( XK_2, 1)
- TAGKEYS( XK_3, 2)
-@@ -106,7 +126,7 @@ static Button buttons[] = {
- { ClkStatusText, 0, Button2, spawn, {.v = termcmd } },
- { ClkClientWin, MODKEY, Button1, movemouse, {0} },
- { ClkClientWin, MODKEY, Button2, togglefloating, {0} },
-- { ClkClientWin, MODKEY, Button3, resizemouse, {0} },
-+ { ClkClientWin, MODKEY, Button1, resizemouse, {0} },
- { ClkTagBar, 0, Button1, view, {0} },
- { ClkTagBar, 0, Button3, toggleview, {0} },
- { ClkTagBar, MODKEY, Button1, tag, {0} },
-diff --git a/dwm.c b/dwm.c
-index 4465af1..646aa1a 100644
---- a/dwm.c
-+++ b/dwm.c
-@@ -54,7 +54,10 @@
- #define MOUSEMASK (BUTTONMASK|PointerMotionMask)
- #define WIDTH(X) ((X)->w + 2 * (X)->bw)
- #define HEIGHT(X) ((X)->h + 2 * (X)->bw)
--#define TAGMASK ((1 << LENGTH(tags)) - 1)
-+#define NUMTAGS (LENGTH(tags) + LENGTH(scratchpads))
-+#define TAGMASK ((1 << NUMTAGS) - 1)
-+#define SPTAG(i) ((1 << LENGTH(tags)) << (i))
-+#define SPTAGMASK (((1 << LENGTH(scratchpads))-1) << LENGTH(tags))
- #define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad)
-
- /* enums */
-@@ -211,6 +214,7 @@ static void tagmon(const Arg *arg);
- static void tile(Monitor *);
- static void togglebar(const Arg *arg);
- static void togglefloating(const Arg *arg);
-+static void togglescratch(const Arg *arg);
- static void toggletag(const Arg *arg);
- static void toggleview(const Arg *arg);
- static void unfocus(Client *c, int setfocus);
-@@ -299,6 +303,11 @@ applyrules(Client *c)
- {
- c->isfloating = r->isfloating;
- c->tags |= r->tags;
-+ if ((r->tags & SPTAGMASK) && r->isfloating) {
-+ c->x = c->mon->wx + (c->mon->ww / 2 - WIDTH(c) / 2);
-+ c->y = c->mon->wy + (c->mon->wh / 2 - HEIGHT(c) / 2);
-+ }
-+
- for (m = mons; m && m->num != r->monitor; m = m->next);
- if (m)
- c->mon = m;
-@@ -308,7 +317,7 @@ applyrules(Client *c)
- XFree(ch.res_class);
- if (ch.res_name)
- XFree(ch.res_name);
-- c->tags = c->tags & TAGMASK ? c->tags & TAGMASK : c->mon->tagset[c->mon->seltags];
-+ c->tags = c->tags & TAGMASK ? c->tags & TAGMASK : (c->mon->tagset[c->mon->seltags] & ~SPTAGMASK);
- }
-
- int
-@@ -1616,6 +1625,10 @@ showhide(Client *c)
- if (!c)
- return;
- if (ISVISIBLE(c)) {
-+ if ((c->tags & SPTAGMASK) && c->isfloating) {
-+ c->x = c->mon->wx + (c->mon->ww / 2 - WIDTH(c) / 2);
-+ c->y = c->mon->wy + (c->mon->wh / 2 - HEIGHT(c) / 2);
-+ }
- /* show clients top down */
- XMoveWindow(dpy, c->win, c->x, c->y);
- if ((!c->mon->lt[c->mon->sellt]->arrange || c->isfloating) && !c->isfullscreen)
-@@ -1719,6 +1732,32 @@ togglefloating(const Arg *arg)
- arrange(selmon);
- }
-
-+void
-+togglescratch(const Arg *arg)
-+{
-+ Client *c;
-+ unsigned int found = 0;
-+ unsigned int scratchtag = SPTAG(arg->ui);
-+ Arg sparg = {.v = scratchpads[arg->ui].cmd};
-+
-+ for (c = selmon->clients; c && !(found = c->tags & scratchtag); c = c->next);
-+ if (found) {
-+ unsigned int newtagset = selmon->tagset[selmon->seltags] ^ scratchtag;
-+ if (newtagset) {
-+ selmon->tagset[selmon->seltags] = newtagset;
-+ focus(NULL);
-+ arrange(selmon);
-+ }
-+ if (ISVISIBLE(c)) {
-+ focus(c);
-+ restack(selmon);
-+ }
-+ } else {
-+ selmon->tagset[selmon->seltags] |= scratchtag;
-+ spawn(&sparg);
-+ }
-+}
-+
- void
- toggletag(const Arg *arg)
- {
---
-2.20.1
-
diff --git a/.repos/dwm/shiftview.c b/.repos/dwm/shiftview.c
deleted file mode 100644
index a52ccd7..0000000
--- a/.repos/dwm/shiftview.c
+++ /dev/null
@@ -1,68 +0,0 @@
-/** Function to shift the current view to the left/right
- *
- * @param: "arg->i" stores the number of tags to shift right (positive value)
- * or left (negative value)
- */
-void
-shiftview(const Arg *arg)
-{
- Arg a;
- Client *c;
- unsigned visible = 0;
- int i = arg->i;
- int count = 0;
- int nextseltags, curseltags = selmon->tagset[selmon->seltags];
-
- do {
- if(i > 0) // left circular shift
- nextseltags = (curseltags << i) | (curseltags >> (LENGTH(tags) - i));
-
- else // right circular shift
- nextseltags = curseltags >> (- i) | (curseltags << (LENGTH(tags) + i));
-
- // Check if tag is visible
- for (c = selmon->clients; c && !visible; c = c->next)
- if (nextseltags & c->tags) {
- visible = 1;
- break;
- }
- i += arg->i;
- } while (!visible && ++count < 10);
-
- if (count < 10) {
- a.i = nextseltags;
- view(&a);
- }
-}
-
-void
-shifttag(const Arg *arg)
-{
- Arg a;
- Client *c;
- unsigned visible = 0;
- int i = arg->i;
- int count = 0;
- int nextseltags, curseltags = selmon->tagset[selmon->seltags];
-
- do {
- if(i > 0) // left circular shift
- nextseltags = (curseltags << i) | (curseltags >> (LENGTH(tags) - i));
-
- else // right circular shift
- nextseltags = curseltags >> (- i) | (curseltags << (LENGTH(tags) + i));
-
- // Check if tag is visible
- for (c = selmon->clients; c && !visible; c = c->next)
- if (nextseltags & c->tags) {
- visible = 1;
- break;
- }
- i += arg->i;
- } while (!visible && ++count < 10);
-
- if (count < 10) {
- a.i = nextseltags;
- tag(&a);
- }
-}
diff --git a/.repos/dwm/transient.c b/.repos/dwm/transient.c
deleted file mode 100644
index 040adb5..0000000
--- a/.repos/dwm/transient.c
+++ /dev/null
@@ -1,42 +0,0 @@
-/* cc transient.c -o transient -lX11 */
-
-#include <stdlib.h>
-#include <unistd.h>
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-
-int main(void) {
- Display *d;
- Window r, f, t = None;
- XSizeHints h;
- XEvent e;
-
- d = XOpenDisplay(NULL);
- if (!d)
- exit(1);
- r = DefaultRootWindow(d);
-
- f = XCreateSimpleWindow(d, r, 100, 100, 400, 400, 0, 0, 0);
- h.min_width = h.max_width = h.min_height = h.max_height = 400;
- h.flags = PMinSize | PMaxSize;
- XSetWMNormalHints(d, f, &h);
- XStoreName(d, f, "floating");
- XMapWindow(d, f);
-
- XSelectInput(d, f, ExposureMask);
- while (1) {
- XNextEvent(d, &e);
-
- if (t == None) {
- sleep(5);
- t = XCreateSimpleWindow(d, r, 50, 50, 100, 100, 0, 0, 0);
- XSetTransientForHint(d, t, f);
- XStoreName(d, t, "transient");
- XMapWindow(d, t);
- XSelectInput(d, t, ExposureMask);
- }
- }
-
- XCloseDisplay(d);
- exit(0);
-}
diff --git a/.repos/dwm/util.c b/.repos/dwm/util.c
deleted file mode 100644
index fe044fc..0000000
--- a/.repos/dwm/util.c
+++ /dev/null
@@ -1,35 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "util.h"
-
-void *
-ecalloc(size_t nmemb, size_t size)
-{
- void *p;
-
- if (!(p = calloc(nmemb, size)))
- die("calloc:");
- return p;
-}
-
-void
-die(const char *fmt, ...) {
- va_list ap;
-
- va_start(ap, fmt);
- vfprintf(stderr, fmt, ap);
- va_end(ap);
-
- if (fmt[0] && fmt[strlen(fmt)-1] == ':') {
- fputc(' ', stderr);
- perror(NULL);
- } else {
- fputc('\n', stderr);
- }
-
- exit(1);
-}
diff --git a/.repos/dwm/util.h b/.repos/dwm/util.h
deleted file mode 100644
index f633b51..0000000
--- a/.repos/dwm/util.h
+++ /dev/null
@@ -1,8 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-
-#define MAX(A, B) ((A) > (B) ? (A) : (B))
-#define MIN(A, B) ((A) < (B) ? (A) : (B))
-#define BETWEEN(X, A, B) ((A) <= (X) && (X) <= (B))
-
-void die(const char *fmt, ...);
-void *ecalloc(size_t nmemb, size_t size);
diff --git a/.repos/dwm/util.o b/.repos/dwm/util.o
deleted file mode 100644
index c08aa49..0000000
--- a/.repos/dwm/util.o
+++ /dev/null
Binary files differ
diff --git a/.repos/dwm/vanitygaps.c b/.repos/dwm/vanitygaps.c
deleted file mode 100644
index 7245e74..0000000
--- a/.repos/dwm/vanitygaps.c
+++ /dev/null
@@ -1,542 +0,0 @@
-/* Key binding functions */
-static void defaultgaps(const Arg *arg);
-static void incrgaps(const Arg *arg);
-/* static void incrigaps(const Arg *arg); */
-/* static void incrogaps(const Arg *arg); */
-/* static void incrohgaps(const Arg *arg); */
-/* static void incrovgaps(const Arg *arg); */
-/* static void incrihgaps(const Arg *arg); */
-/* static void incrivgaps(const Arg *arg); */
-static void togglegaps(const Arg *arg);
-
-/* Layouts */
-static void bstack(Monitor *m);
-static void centeredmaster(Monitor *m);
-static void centeredfloatingmaster(Monitor *m);
-static void deck(Monitor *m);
-static void dwindle(Monitor *m);
-static void fibonacci(Monitor *m, int s);
-static void spiral(Monitor *m);
-static void tile(Monitor *);
-
-/* Internals */
-static void getgaps(Monitor *m, int *oh, int *ov, int *ih, int *iv, unsigned int *nc);
-static void setgaps(int oh, int ov, int ih, int iv);
-
-/* Settings */
-static int enablegaps = 1;
-
-static void
-setgaps(int oh, int ov, int ih, int iv)
-{
- if (oh < 0) oh = 0;
- if (ov < 0) ov = 0;
- if (ih < 0) ih = 0;
- if (iv < 0) iv = 0;
-
- selmon->gappoh = oh;
- selmon->gappov = ov;
- selmon->gappih = ih;
- selmon->gappiv = iv;
- arrange(selmon);
-}
-
-static void
-togglegaps(const Arg *arg)
-{
- enablegaps = !enablegaps;
- arrange(NULL);
-}
-
-static void
-defaultgaps(const Arg *arg)
-{
- setgaps(gappoh, gappov, gappih, gappiv);
-}
-
-static void
-incrgaps(const Arg *arg)
-{
- setgaps(
- selmon->gappoh + arg->i,
- selmon->gappov + arg->i,
- selmon->gappih + arg->i,
- selmon->gappiv + arg->i
- );
-}
-
-/* static void */
-/* incrigaps(const Arg *arg) */
-/* { */
-/* setgaps( */
-/* selmon->gappoh, */
-/* selmon->gappov, */
-/* selmon->gappih + arg->i, */
-/* selmon->gappiv + arg->i */
-/* ); */
-/* } */
-
-/* static void */
-/* incrogaps(const Arg *arg) */
-/* { */
-/* setgaps( */
-/* selmon->gappoh + arg->i, */
-/* selmon->gappov + arg->i, */
-/* selmon->gappih, */
-/* selmon->gappiv */
-/* ); */
-/* } */
-
-/* static void */
-/* incrohgaps(const Arg *arg) */
-/* { */
-/* setgaps( */
-/* selmon->gappoh + arg->i, */
-/* selmon->gappov, */
-/* selmon->gappih, */
-/* selmon->gappiv */
-/* ); */
-/* } */
-
-/* static void */
-/* incrovgaps(const Arg *arg) */
-/* { */
-/* setgaps( */
-/* selmon->gappoh, */
-/* selmon->gappov + arg->i, */
-/* selmon->gappih, */
-/* selmon->gappiv */
-/* ); */
-/* } */
-
-/* static void */
-/* incrihgaps(const Arg *arg) */
-/* { */
-/* setgaps( */
-/* selmon->gappoh, */
-/* selmon->gappov, */
-/* selmon->gappih + arg->i, */
-/* selmon->gappiv */
-/* ); */
-/* } */
-
-/* static void */
-/* incrivgaps(const Arg *arg) */
-/* { */
-/* setgaps( */
-/* selmon->gappoh, */
-/* selmon->gappov, */
-/* selmon->gappih, */
-/* selmon->gappiv + arg->i */
-/* ); */
-/* } */
-
-static void
-getgaps(Monitor *m, int *oh, int *ov, int *ih, int *iv, unsigned int *nc)
-{
- unsigned int n, oe, ie;
- oe = ie = enablegaps;
- Client *c;
-
- for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
- if (smartgaps && n == 1) {
- oe = 0; // outer gaps disabled when only one client
- }
-
- *oh = m->gappoh*oe; // outer horizontal gap
- *ov = m->gappov*oe; // outer vertical gap
- *ih = m->gappih*ie; // inner horizontal gap
- *iv = m->gappiv*ie; // inner vertical gap
- *nc = n; // number of clients
-}
-
-void
-getfacts(Monitor *m, int msize, int ssize, float *mf, float *sf, int *mr, int *sr)
-{
- unsigned int n;
- float mfacts, sfacts;
- int mtotal = 0, stotal = 0;
- Client *c;
-
- for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
- mfacts = MIN(n, m->nmaster);
- sfacts = n - m->nmaster;
-
- for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++)
- if (n < m->nmaster)
- mtotal += msize / mfacts;
- else
- stotal += ssize / sfacts;
-
- *mf = mfacts; // total factor of master area
- *sf = sfacts; // total factor of stack area
- *mr = msize - mtotal; // the remainder (rest) of pixels after an even master split
- *sr = ssize - stotal; // the remainder (rest) of pixels after an even stack split
-}
-
-/***
- * Layouts
- */
-
-/*
- * Bottomstack layout + gaps
- * https://dwm.suckless.org/patches/bottomstack/
- */
-
-static void
-bstack(Monitor *m)
-{
- unsigned int i, n;
- int mx = 0, my = 0, mh = 0, mw = 0;
- int sx = 0, sy = 0, sh = 0, sw = 0;
- float mfacts, sfacts;
- int mrest, srest;
- Client *c;
-
- int oh, ov, ih, iv;
- getgaps(m, &oh, &ov, &ih, &iv, &n);
-
- if (n == 0)
- return;
-
- sx = mx = m->wx + ov;
- sy = my = m->wy + oh;
- sh = mh = m->wh - 2*oh;
- mw = m->ww - 2*ov - iv * (MIN(n, m->nmaster) - 1);
- sw = m->ww - 2*ov - iv * (n - m->nmaster - 1);
-
- if (m->nmaster && n > m->nmaster) {
- sh = (mh - ih) * (1 - m->mfact);
- mh = (mh - ih) * m->mfact;
- sx = mx;
- sy = my + mh + ih;
- }
-
- getfacts(m, mw, sw, &mfacts, &sfacts, &mrest, &srest);
-
- for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) {
- if (i < m->nmaster) {
- resize(c, mx, my, (mw / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), mh - (2*c->bw), 0);
- mx += WIDTH(c) + iv;
- } else {
- resize(c, sx, sy, (sw / sfacts) + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), sh - (2*c->bw), 0);
- sx += WIDTH(c) + iv;
- }
- }
-}
-
-/*
- * Centred master layout + gaps
- * https://dwm.suckless.org/patches/centeredmaster/
- */
-
-void
-centeredmaster(Monitor *m)
-{
- unsigned int i, n;
- int mx = 0, my = 0, mh = 0, mw = 0;
- int lx = 0, ly = 0, lw = 0, lh = 0;
- int rx = 0, ry = 0, rw = 0, rh = 0;
- float mfacts = 0, lfacts = 0, rfacts = 0;
- int mtotal = 0, ltotal = 0, rtotal = 0;
- int mrest = 0, lrest = 0, rrest = 0;
- Client *c;
-
- int oh, ov, ih, iv;
- getgaps(m, &oh, &ov, &ih, &iv, &n);
-
- if (n == 0)
- return;
-
- /* initialize areas */
- mx = m->wx + ov;
- my = m->wy + oh;
- mh = m->wh - 2*oh - ih * ((!m->nmaster ? n : MIN(n, m->nmaster)) - 1);
- mw = m->ww - 2*ov;
- lh = m->wh - 2*oh - ih * (((n - m->nmaster) / 2) - 1);
- rh = m->wh - 2*oh - ih * (((n - m->nmaster) / 2) - ((n - m->nmaster) % 2 ? 0 : 1));
-
- if (m->nmaster && n > m->nmaster) {
- /* go mfact box in the center if more than nmaster clients */
- if (n - m->nmaster > 1) {
- /* ||<-S->|<---M--->|<-S->|| */
- mw = (m->ww - 2*ov - 2*iv) * m->mfact;
- lw = (m->ww - mw - 2*ov - 2*iv) / 2;
- mx += lw + iv;
- } else {
- /* ||<---M--->|<-S->|| */
- mw = (mw - iv) * m->mfact;
- lw = m->ww - mw - iv - 2*ov;
- }
- rw = lw;
- lx = m->wx + ov;
- ly = m->wy + oh;
- rx = mx + mw + iv;
- ry = m->wy + oh;
- }
-
- /* calculate facts */
- for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++) {
- if (!m->nmaster || n < m->nmaster)
- mfacts += 1;
- else if ((n - m->nmaster) % 2)
- lfacts += 1; // total factor of left hand stack area
- else
- rfacts += 1; // total factor of right hand stack area
- }
-
- for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++)
- if (!m->nmaster || n < m->nmaster)
- mtotal += mh / mfacts;
- else if ((n - m->nmaster) % 2)
- ltotal += lh / lfacts;
- else
- rtotal += rh / rfacts;
-
- mrest = mh - mtotal;
- lrest = lh - ltotal;
- rrest = rh - rtotal;
-
- for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) {
- if (!m->nmaster || i < m->nmaster) {
- /* nmaster clients are stacked vertically, in the center of the screen */
- resize(c, mx, my, mw - (2*c->bw), (mh / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), 0);
- my += HEIGHT(c) + ih;
- } else {
- /* stack clients are stacked vertically */
- if ((i - m->nmaster) % 2 ) {
- resize(c, lx, ly, lw - (2*c->bw), (lh / lfacts) + ((i - 2*m->nmaster) < 2*lrest ? 1 : 0) - (2*c->bw), 0);
- ly += HEIGHT(c) + ih;
- } else {
- resize(c, rx, ry, rw - (2*c->bw), (rh / rfacts) + ((i - 2*m->nmaster) < 2*rrest ? 1 : 0) - (2*c->bw), 0);
- ry += HEIGHT(c) + ih;
- }
- }
- }
-}
-
-void
-centeredfloatingmaster(Monitor *m)
-{
- unsigned int i, n;
- float mfacts, sfacts;
- int mrest, srest;
- int mx = 0, my = 0, mh = 0, mw = 0;
- int sx = 0, sy = 0, sh = 0, sw = 0;
- Client *c;
-
- float mivf = 1.0; // master inner vertical gap factor
- int oh, ov, ih, iv;
- getgaps(m, &oh, &ov, &ih, &iv, &n);
-
- if (n == 0)
- return;
-
- sx = mx = m->wx + ov;
- sy = my = m->wy + oh;
- sh = mh = m->wh - 2*oh;
- mw = m->ww - 2*ov - iv*(n - 1);
- sw = m->ww - 2*ov - iv*(n - m->nmaster - 1);
-
- if (m->nmaster && n > m->nmaster) {
- mivf = 0.8;
- /* go mfact box in the center if more than nmaster clients */
- if (m->ww > m->wh) {
- mw = m->ww * m->mfact - iv*mivf*(MIN(n, m->nmaster) - 1);
- mh = m->wh * 0.9 - 2*oh;
- } else {
- mw = m->ww * 0.9 - iv*mivf*(MIN(n, m->nmaster) - 1);
- mh = m->wh * m->mfact;
- }
- mx = m->wx + (m->ww - mw) / 2;
- my = m->wy + (m->wh - mh) / 2;
-
- sx = m->wx + ov;
- sy = m->wy + oh;
- sh = m->wh - 2*oh;
- }
-
- getfacts(m, mw, sw, &mfacts, &sfacts, &mrest, &srest);
-
- for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
- if (i < m->nmaster) {
- /* nmaster clients are stacked horizontally, in the center of the screen */
- resize(c, mx, my, (mw / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), mh - (2*c->bw), 0);
- mx += WIDTH(c) + iv*mivf;
- } else {
- /* stack clients are stacked horizontally */
- resize(c, sx, sy, (sw / sfacts) + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), sh - (2*c->bw), 0);
- sx += WIDTH(c) + iv;
- }
-}
-
-/*
- * Deck layout + gaps
- * https://dwm.suckless.org/patches/deck/
- */
-
-static void
-deck(Monitor *m)
-{
- unsigned int i, n;
- int mx = 0, my = 0, mh = 0, mw = 0;
- int sx = 0, sy = 0, sh = 0, sw = 0;
- float mfacts, sfacts;
- int mrest, srest;
- Client *c;
-
- int oh, ov, ih, iv;
- getgaps(m, &oh, &ov, &ih, &iv, &n);
-
- if (n == 0)
- return;
-
- sx = mx = m->wx + ov;
- sy = my = m->wy + oh;
- sh = mh = m->wh - 2*oh - ih * (MIN(n, m->nmaster) - 1);
- sw = mw = m->ww - 2*ov;
-
- if (m->nmaster && n > m->nmaster) {
- sw = (mw - iv) * (1 - m->mfact);
- mw = (mw - iv) * m->mfact;
- sx = mx + mw + iv;
- sh = m->wh - 2*oh;
- }
-
- getfacts(m, mh, sh, &mfacts, &sfacts, &mrest, &srest);
-
- if (n - m->nmaster > 0) /* override layout symbol */
- snprintf(m->ltsymbol, sizeof m->ltsymbol, "D %d", n - m->nmaster);
-
- for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
- if (i < m->nmaster) {
- resize(c, mx, my, mw - (2*c->bw), (mh / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), 0);
- my += HEIGHT(c) + ih;
- } else {
- resize(c, sx, sy, sw - (2*c->bw), sh - (2*c->bw), 0);
- }
-}
-
-/*
- * Fibonacci layout + gaps
- * https://dwm.suckless.org/patches/fibonacci/
- */
-
-static void
-fibonacci(Monitor *m, int s)
-{
- unsigned int i, n;
- int nx, ny, nw, nh;
- int oh, ov, ih, iv;
- Client *c;
-
- getgaps(m, &oh, &ov, &ih, &iv, &n);
-
- if (n == 0)
- return;
-
- nx = m->wx + ov;
- ny = oh;
- nw = m->ww - 2*ov;
- nh = m->wh - 2*oh;
-
- for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next)) {
- if ((i % 2 && nh / 2 > 2*c->bw)
- || (!(i % 2) && nw / 2 > 2*c->bw)) {
- if (i < n - 1) {
- if (i % 2)
- nh = (nh - ih) / 2;
- else
- nw = (nw - iv) / 2;
-
- if ((i % 4) == 2 && !s)
- nx += nw + iv;
- else if ((i % 4) == 3 && !s)
- ny += nh + ih;
- }
- if ((i % 4) == 0) {
- if (s)
- ny += nh + ih;
- else
- ny -= nh + ih;
- }
- else if ((i % 4) == 1)
- nx += nw + iv;
- else if ((i % 4) == 2)
- ny += nh + ih;
- else if ((i % 4) == 3) {
- if (s)
- nx += nw + iv;
- else
- nx -= nw + iv;
- }
- if (i == 0) {
- if (n != 1)
- nw = (m->ww - 2*ov - iv) * m->mfact;
- ny = m->wy + oh;
- }
- else if (i == 1)
- nw = m->ww - nw - iv - 2*ov;
- i++;
- }
-
- resize(c, nx, ny, nw - (2*c->bw), nh - (2*c->bw), False);
- }
-}
-
-static void
-dwindle(Monitor *m)
-{
- fibonacci(m, 1);
-}
-
-static void
-spiral(Monitor *m)
-{
- fibonacci(m, 0);
-}
-
-/*
- * Default tile layout + gaps
- */
-
-static void
-tile(Monitor *m)
-{
- unsigned int i, n;
- int mx = 0, my = 0, mh = 0, mw = 0;
- int sx = 0, sy = 0, sh = 0, sw = 0;
- float mfacts, sfacts;
- int mrest, srest;
- Client *c;
-
-
- int oh, ov, ih, iv;
- getgaps(m, &oh, &ov, &ih, &iv, &n);
-
- if (n == 0)
- return;
-
- sx = mx = m->wx + ov;
- sy = my = m->wy + oh;
- mh = m->wh - 2*oh - ih * (MIN(n, m->nmaster) - 1);
- sh = m->wh - 2*oh - ih * (n - m->nmaster - 1);
- sw = mw = m->ww - 2*ov;
-
- if (m->nmaster && n > m->nmaster) {
- sw = (mw - iv) * (1 - m->mfact);
- mw = (mw - iv) * m->mfact;
- sx = mx + mw + iv;
- }
-
- getfacts(m, mh, sh, &mfacts, &sfacts, &mrest, &srest);
-
- for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
- if (i < m->nmaster) {
- resize(c, mx, my, mw - (2*c->bw), (mh / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), 0);
- my += HEIGHT(c) + ih;
- } else {
- resize(c, sx, sy, sw - (2*c->bw), (sh / sfacts) + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), 0);
- sy += HEIGHT(c) + ih;
- }
-}
diff --git a/.repos/farbfeld/2ff b/.repos/farbfeld/2ff
deleted file mode 100755
index 6ce91b9..0000000
--- a/.repos/farbfeld/2ff
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/bin/sh
-
-# arguments
-if [ "$#" -ne 0 ]; then
- echo "usage: $0" >&2
- exit 1
-fi
-
-# write input into temporary file
-TMP=$(mktemp)
-trap 'rm "$TMP"' EXIT
-cat > "$TMP"
-
-# determine the mime-type
-if [ "$(dd if="$TMP" bs=1 count=8 2>/dev/null | tr -d '\0')" = "farbfeld" ]; then
- cat "$TMP"
-else
- MIME=$(file -ib "$TMP" | cut -d ";" -f 1)
-
- case "$MIME" in
- image/png)
- png2ff < "$TMP"
- ;;
- image/jpeg)
- jpg2ff < "$TMP"
- ;;
- *)
- convert "$TMP" png:- | png2ff
- ;;
- esac
-fi
-
-# errors
-if [ $? -ne 0 ]; then
- exit 1
-else
- exit 0
-fi
diff --git a/.repos/farbfeld/2ff.1 b/.repos/farbfeld/2ff.1
deleted file mode 100644
index 426e3fd..0000000
--- a/.repos/farbfeld/2ff.1
+++ /dev/null
@@ -1,45 +0,0 @@
-.Dd 2018-04-11
-.Dt 2FF 1
-.Os suckless.org
-.Sh NAME
-.Nm 2ff
-.Nd convert image to farbfeld
-.Sh SYNOPSIS
-.Nm
-.Sh DESCRIPTION
-.Nm
-reads an image from stdin, converts it to
-.Xr farbfeld 5
-and writes the result to stdout.
-.Pp
-.Nm
-is a wrapper script around the farbfeld conversion tools
-with a fallback to obtaining a PNG using
-.Xr ImageMagick 1
-and passing it through
-.Xr png2ff 1 .
-.Pp
-In case of an error
-.Nm
-writes a diagnostic message to stderr.
-.Sh EXIT STATUS
-.Bl -tag -width Ds
-.It 0
-Image processed successfully.
-.It 1
-An error occurred.
-.El
-.Sh EXAMPLES
-$
-.Nm
-< image.* > image.ff
-.Pp
-$
-.Nm
-< image.* | bzip2 > image.ff.bz2
-.Sh SEE ALSO
-.Xr bzip2 1 ,
-.Xr ImageMagick 1 ,
-.Xr farbfeld 5
-.Sh AUTHORS
-.An Laslo Hunhold Aq Mt dev@frign.de
diff --git a/.repos/farbfeld/FORMAT b/.repos/farbfeld/FORMAT
deleted file mode 100644
index 0c082ea..0000000
--- a/.repos/farbfeld/FORMAT
+++ /dev/null
@@ -1,14 +0,0 @@
-
- FARBFELD IMAGE FORMAT SPECIFICATION
-
- ╔════════╤═════════════════════════════════════════════════════════╗
- ║ Bytes │ Description ║
- ╠════════╪═════════════════════════════════════════════════════════╣
- ║ 8 │ "farbfeld" magic value ║
- ╟────────┼─────────────────────────────────────────────────────────╢
- ║ 4 │ 32-Bit BE unsigned integer (width) ║
- ╟────────┼─────────────────────────────────────────────────────────╢
- ║ 4 │ 32-Bit BE unsigned integer (height) ║
- ╟────────┼─────────────────────────────────────────────────────────╢
- ║ [2222] │ 4⋅16-Bit BE unsigned integers [RGBA] / pixel, row-major ║
- ╚════════╧═════════════════════════════════════════════════════════╝
diff --git a/.repos/farbfeld/LICENSE b/.repos/farbfeld/LICENSE
deleted file mode 100644
index 05640a5..0000000
--- a/.repos/farbfeld/LICENSE
+++ /dev/null
@@ -1,24 +0,0 @@
-ISC-License
-
-Copyright 2014-2018 Laslo Hunhold <dev@frign.de>
-
-Copyright 2004 Ted Unangst <tedu@openbsd.org>
-Copyright 2004 Todd C. Miller <Todd.Miller@courtesan.com>
-Copyright 2008 Otto Moerbeek <otto@drijf.net>
-Copyright 2014-2015 Dimitris Papastamos <sin@2f30.org>
-Copyright 2014-2016 Hiltjo Posthuma <hiltjo@codemadness.org>
-Copyright 2015 Willy Goiffon <willy@mailoo.org>
-Copyright 2016 Alexander Krotov <ilabdsf@yandex.ru>
-Copyright 2017 Mattias Andrée <maandree@kth.se>
-
-Permission to use, copy, modify, and/or distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
diff --git a/.repos/farbfeld/Makefile b/.repos/farbfeld/Makefile
deleted file mode 100644
index 120ce25..0000000
--- a/.repos/farbfeld/Makefile
+++ /dev/null
@@ -1,67 +0,0 @@
-# See LICENSE file for copyright and license details
-# farbfeld - suckless image format with conversion tools
-.POSIX:
-
-include config.mk
-
-REQ = util
-HDR = arg.h
-BIN = png2ff ff2png jpg2ff ff2jpg ff2pam ff2ppm
-SCR = 2ff
-MAN1 = 2ff.1 $(BIN:=.1)
-MAN5 = farbfeld.5
-
-all: $(BIN)
-
-png2ff-LDLIBS = $(PNG-LDLIBS)
-ff2png-LDLIBS = $(PNG-LDLIBS)
-jpg2ff-LDLIBS = $(JPG-LDLIBS)
-ff2jpg-LDLIBS = $(JPG-LDLIBS)
-
-png2ff: png2ff.o $(REQ:=.o)
-ff2png: ff2png.o $(REQ:=.o)
-jpg2ff: jpg2ff.o $(REQ:=.o)
-ff2jpg: ff2jpg.o $(REQ:=.o)
-ff2pam: ff2pam.o $(REQ:=.o)
-ff2ppm: ff2ppm.o $(REQ:=.o)
-
-png2ff.o: png2ff.c config.mk $(HDR) $(REQ:=.h)
-ff2png.o: ff2png.c config.mk $(HDR) $(REQ:=.h)
-jpg2ff.o: jpg2ff.c config.mk $(HDR) $(REQ:=.h)
-ff2jpg.o: ff2jpg.c config.mk $(HDR) $(REQ:=.h)
-ff2pam.o: ff2pam.c config.mk $(HDR) $(REQ:=.h)
-ff2ppm.o: ff2ppm.c config.mk $(HDR) $(REQ:=.h)
-
-.o:
- $(CC) -o $@ $(LDFLAGS) $< $(REQ:=.o) $($*-LDLIBS)
-
-.c.o:
- $(CC) -c $(CPPFLAGS) $(CFLAGS) $<
-
-clean:
- rm -f $(BIN) $(BIN:=.o) $(REQ:=.o)
-
-dist:
- rm -rf "farbfeld-$(VERSION)"
- mkdir -p "farbfeld-$(VERSION)"
- cp -R FORMAT LICENSE Makefile README config.mk $(SCR) \
- $(HDR) $(BIN:=.c) $(REQ:=.c) $(REQ:=.h) \
- $(MAN1) $(MAN5) "farbfeld-$(VERSION)"
- tar -cf - "farbfeld-$(VERSION)" | gzip -c > "farbfeld-$(VERSION).tar.gz"
- rm -rf "farbfeld-$(VERSION)"
-
-install: all
- mkdir -p "$(DESTDIR)$(PREFIX)/bin"
- cp -f $(SCR) $(BIN) "$(DESTDIR)$(PREFIX)/bin"
- for f in $(BIN) $(SCR); do chmod 755 "$(DESTDIR)$(PREFIX)/bin/$$f"; done
- mkdir -p "$(DESTDIR)$(MANPREFIX)/man1"
- cp -f $(MAN1) "$(DESTDIR)$(MANPREFIX)/man1"
- for m in $(MAN1); do chmod 644 "$(DESTDIR)$(MANPREFIX)/man1/$$m"; done
- mkdir -p "$(DESTDIR)$(MANPREFIX)/man5"
- cp -f $(MAN5) "$(DESTDIR)$(MANPREFIX)/man5"
- for m in $(MAN5); do chmod 644 "$(DESTDIR)$(MANPREFIX)/man5/$$m"; done
-
-uninstall:
- for f in $(BIN) $(SCR); do rm -f "$(DESTDIR)$(PREFIX)/bin/$$f"; done
- for m in $(MAN1); do rm -f "$(DESTDIR)$(MANPREFIX)/man1/$$m"; done
- for m in $(MAN5); do rm -f "$(DESTDIR)$(MANPREFIX)/man5/$$m"; done
diff --git a/.repos/farbfeld/README b/.repos/farbfeld/README
deleted file mode 100644
index 1fe1125..0000000
--- a/.repos/farbfeld/README
+++ /dev/null
@@ -1,74 +0,0 @@
-
- ███ ███ ██ ██ ███ ███ █ ██
- █ █ █ █ █ █ █ █ █ █ █ █
- ██ ███ ██ ███ ██ ██ █ █ █
- █ █ █ █ █ █ █ █ █ █ █ █
- █ █ █ █ █ ██ █ ███ ███ ██
-
-
-WHAT IS FARBFELD?
- Farbfeld is a lossless image-format designed to be
- parsed and piped easily. It is probably the simplest
- image-format you can find (see FORMAT).
- It does not have integrated compression, but allows
- compression algorithms to work with it easily by adding
- little entropy to the image data itself. This beats PNG
- in many cases.
- Given the free choice of compression algorithms, it
- is trivial to switch to better and faster ones as they
- show up in the future.
-
-HOW DO I USE THE TOOLS?
- encoding:
- png2ff < example.png > example.ff
- png2ff < example.png | bzip2 > example.ff.bz2
-
- decoding:
- ff2png < example.ff > example.png
- bzcat example.ff.bz2 | ff2png > example.png
-
- bzip2 is used in this example and a recommended
- compression algorithm. Of course you are free
- to use something else.
-
-WHY FARBFELD?
- Current image-formats have integrated compression,
- making it complicated to read the image data.
- One is forced to use complex libraries like libpng,
- libjpeg, libjpeg-turbo, giflib and others, read the
- documentation and write a lot of boilerplate in order
- to get started.
- Farbfeld leaves this behind and is designed to be as
- simple as possible, leaving the task of compression
- to outside tools.
- The simple design, which was the primary objective,
- implicitly lead to the very good compression
- characteristics, as it often happens when you go with
- the UNIX philosophy.
- Reading farbfeld images doesn't require any special
- libraries. The tools in this folder are just a toolbox
- to make it easy to convert between common image formats
- and farbfeld.
-
-HOW DOES IT WORK?
- In farbfeld, pattern resolution is not done while
- converting, but while compressing the image.
- For example, farbfeld always stores the alpha-channel,
- even if the image doesn't have alpha-variation.
- This may sound like a big waste at first, but as
- soon as you compress an image of this kind, the
- compression-algorithm (e.g. bzip2) recognizes the
- pattern that every 48 bits the 16 bits store the
- same information.
- And the compression-algorithms get better and better
- at this.
- Same applies to the idea of having 16 bits per channel.
- It sounds excessive, but if you for instance only have
- a greyscale image, the R, G and B channels will store
- the same value, which is recognized by the compression
- algorithm easily.
- This effectively leads to filesizes you'd normally only
- reach with paletted images, and in some cases bzip2 even
- beats png's compression, for instance when you're dealing
- with grayscale data, line drawings, decals and even
- photographs.
diff --git a/.repos/farbfeld/arg.h b/.repos/farbfeld/arg.h
deleted file mode 100644
index 35cc7cc..0000000
--- a/.repos/farbfeld/arg.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * ISC-License
- *
- * Copyright 2004-2017 Christoph Lohmann <20h@r-36.net>
- * Copyright 2017-2018 Laslo Hunhold <dev@frign.de>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-#ifndef ARG_H
-#define ARG_H
-
-extern char *argv0;
-
-/* int main(int argc, char *argv[]) */
-#define ARGBEGIN for (argv0 = *argv, *argv ? (argc--, argv++) : ((void *)0); \
- *argv && (*argv)[0] == '-' && (*argv)[1]; argc--, argv++) { \
- int i_, argused_; \
- if ((*argv)[1] == '-' && !(*argv)[2]) { \
- argc--, argv++; \
- break; \
- } \
- for (i_ = 1, argused_ = 0; (*argv)[i_]; i_++) { \
- switch((*argv)[i_])
-#define ARGEND if (argused_) { \
- if ((*argv)[i_ + 1]) { \
- break; \
- } else { \
- argc--, argv++; \
- break; \
- } \
- } \
- } \
- }
-#define ARGC() ((*argv)[i_])
-#define ARGF_(x) (((*argv)[i_ + 1]) ? (argused_ = 1, &((*argv)[i_ + 1])) : \
- (*(argv + 1)) ? (argused_ = 1, *(argv + 1)) : (x))
-#define EARGF(x) ARGF_(((x), exit(1), (char *)0))
-#define ARGF() ARGF_((char *)0)
-
-#endif
diff --git a/.repos/farbfeld/config.mk b/.repos/farbfeld/config.mk
deleted file mode 100644
index e13ced3..0000000
--- a/.repos/farbfeld/config.mk
+++ /dev/null
@@ -1,18 +0,0 @@
-# farbfeld version
-VERSION = 4
-
-# Customize below to fit your system
-
-# paths
-PREFIX = /usr/local
-MANPREFIX = $(PREFIX)/share/man
-
-# flags
-CPPFLAGS = -D_DEFAULT_SOURCE
-CFLAGS = -std=c99 -pedantic -Wall -Wextra -Os
-LDFLAGS = -s
-PNG-LDLIBS = -lpng
-JPG-LDLIBS = -ljpeg
-
-# compiler and linker
-CC = cc
diff --git a/.repos/farbfeld/farbfeld.5 b/.repos/farbfeld/farbfeld.5
deleted file mode 100644
index 55dc47c..0000000
--- a/.repos/farbfeld/farbfeld.5
+++ /dev/null
@@ -1,177 +0,0 @@
-.Dd 2018-04-11
-.Dt FARBFELD 5
-.Os suckless.org
-.Sh NAME
-.Nm farbfeld
-.Nd suckless image format
-.Sh DESCRIPTION
-.Nm
-is a
-.Em lossless
-image format which is easy to parse, pipe and compress.
-It has the following format:
-.Bd -literal -offset left
-BYTES DESCRIPTION
-8 "farbfeld" magic value
-4 32-Bit BE unsigned integer (width)
-4 32-Bit BE unsigned integer (height)
-[2222] 4*16-Bit BE unsigned integers [RGBA] / pixel, row-major
-.Ed
-.Pp
-The RGB-data should be sRGB for best interoperability and not
-alpha-premultiplied.
-.Sh USAGE
-.Nm
-provides the tools
-.Xr 2ff 1 ,
-.Xr jpg2ff 1 ,
-.Xr png2ff 1
-and
-.Xr ff2jpg 1 ,
-.Xr ff2pam 1 ,
-.Xr ff2png 1 ,
-.Xr ff2ppm 1
-to
-.Em convert
-to and from farbfeld images respectively.
-.Pp
-.Xr bzip2 1
-is recommended for
-.Em compression ,
-giving results comparable with PNG for photographs and much better results
-for other image types.
-.sp
-The
-.Em file extension
-is ".ff" and compression extensions shall be
-appended (e.g. ".ff.bz2").
-.Sh MOTIVATION
-.Nm
-was created because the author was not satisfied with the boilerplate
-and inherent complexity involved in handling common image formats
-(PNG, JPEG, GIF,...), having to rely on bloated libraries while not being
-able to focus on the task at hand for a given image processing problem.
-.Sh EXAMPLES
-The following code listing
-.Em invert.c
-is a ready-to-use color inverter with all necessary error handling and
-reporting. This program can be integrated into a farbfeld pipeline as
-follows:
-.Pp
-$ png2ff < image.png | invert | ff2png > image-inverted.png
-.Pp
-It shall be noted here that due to the simplicity of the format no
-external libraries are needed to handle the farbfeld image data. The
-0BSD-License gives you the freedom to throw away the license block and
-just use the code as you wish. Happy hacking!
-.Bd -literal -offset left
-/*
- * 0BSD-License
- *
- * (c) 2017 Laslo Hunhold <dev@frign.de>
- *
- * Permission to use, copy, modify, and/or distribute this software for
- * any purpose with or without fee is hereby granted.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
- * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
- * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
- * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-#include <arpa/inet.h>
-
-#include <errno.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <string.h>
-
-#define LEN(x) (sizeof (x) / sizeof *(x))
-
-static void
-invert(uint16_t rgba[4])
-{
- rgba[0] = UINT16_MAX - rgba[0];
- rgba[1] = UINT16_MAX - rgba[1];
- rgba[2] = UINT16_MAX - rgba[2];
-}
-
-int
-main(int argc, char *argv[])
-{
- uint32_t hdr[4], width, height, i, j, k;
- uint16_t rgba[4];
-
- /* arguments */
- if (argc != 1) {
- fprintf(stderr, "usage: %s\\n", argv[0]);
- return 1;
- }
-
- /* read header */
- if (fread(hdr, sizeof(*hdr), LEN(hdr), stdin) != LEN(hdr)) {
- goto readerr;
- }
- if (memcmp("farbfeld", hdr, sizeof("farbfeld") - 1)) {
- fprintf(stderr, "%s: invalid magic value\\n", argv[0]);
- return 1;
- }
- width = ntohl(hdr[2]);
- height = ntohl(hdr[3]);
-
- /* write data */
- if (fwrite(hdr, sizeof(*hdr), LEN(hdr), stdout) != 4) {
- goto writerr;
- }
-
- for (i = 0; i < height; i++) {
- for (j = 0; j < width; j++) {
- if (fread(rgba, sizeof(*rgba), LEN(rgba),
- stdin) != LEN(rgba)) {
- goto readerr;
- }
- for (k = 0; k < 4; k++) {
- rgba[k] = ntohs(rgba[k]);
- }
-
- invert(rgba);
-
- for (k = 0; k < 4; k++) {
- rgba[k] = htons(rgba[k]);
- }
- if (fwrite(rgba, sizeof(*rgba), LEN(rgba),
- stdout) != LEN(rgba)) {
- goto writerr;
- }
- }
- }
-
- /* clean up */
- if (fclose(stdout)) {
- fprintf(stderr, "%s: fclose: %s\\n", argv[0],
- strerror(errno));
- return 1;
- }
-
- return 0;
-readerr:
- fprintf(stderr, "%s: fread: Unexpected EOF\\n", argv[0]);
- return 1;
-writerr:
- fprintf(stderr, "%s: fwrite: %s\\n", argv[0], strerror(errno));
- return 1;
-}
-.Ed
-.Sh SEE ALSO
-.Xr 2ff 1 ,
-.Xr ff2jpg 1 ,
-.Xr ff2pam 1 ,
-.Xr ff2png 1 ,
-.Xr ff2ppm 1 ,
-.Xr jpg2ff 1 ,
-.Xr png2ff 1
-.Sh AUTHORS
-.An Laslo Hunhold Aq Mt dev@frign.de
diff --git a/.repos/farbfeld/ff2jpg.1 b/.repos/farbfeld/ff2jpg.1
deleted file mode 100644
index 745ae6e..0000000
--- a/.repos/farbfeld/ff2jpg.1
+++ /dev/null
@@ -1,54 +0,0 @@
-.Dd 2018-04-11
-.Dt FF2JPG 1
-.Os suckless.org
-.Sh NAME
-.Nm ff2jpg
-.Nd convert farbfeld to JPG
-.Sh SYNOPSIS
-.Nm
-.Op Fl b Ar colour
-.Op Fl o
-.Op Fl q Ar quality
-.Sh DESCRIPTION
-.Nm
-reads a
-.Xr farbfeld 5
-image from stdin, converts it to JPG (8-bit RGB) and writes the result to
-stdout.
-.Pp
-In case of an error
-.Nm
-writes a diagnostic message to stderr.
-.Sh OPTIONS
-.Bl -tag -width Ds
-.It Fl b Ar colour
-Blend the transparent colours with
-.Ar colour
-specified as rgb, rrggbb or rrrrggggbbbb. The default is fff.
-.It Fl o
-Optimize the Huffman table, which reduces the file size but takes longer.
-.It Fl q Ar quality
-Set the output
-.Ar quality
-ranging from 0 to 100. The default is 85.
-.El
-.Sh EXIT STATUS
-.Bl -tag -width Ds
-.It 0
-Image processed successfully.
-.It 1
-An error occurred.
-.El
-.Sh EXAMPLES
-$
-.Nm
-< image.ff > image.jpg
-.Pp
-$ bunzip2 < image.ff.bz2 |
-.Nm
--b 0f0 -q 90 > image.jpg
-.Sh SEE ALSO
-.Xr bzip2 1 ,
-.Xr farbfeld 5
-.Sh AUTHORS
-.An Hiltjo Posthuma Aq Mt hiltjo@codemadness.org
diff --git a/.repos/farbfeld/ff2jpg.c b/.repos/farbfeld/ff2jpg.c
deleted file mode 100644
index f4514b8..0000000
--- a/.repos/farbfeld/ff2jpg.c
+++ /dev/null
@@ -1,114 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-#include <arpa/inet.h>
-
-#include <errno.h>
-#include <inttypes.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <jpeglib.h>
-
-#include "arg.h"
-#include "util.h"
-
-static void
-jpeg_error(j_common_ptr js)
-{
- fprintf(stderr, "%s: libjpeg: ", argv0);
- (*js->err->output_message)(js);
- exit(1);
-}
-
-static void
-jpeg_setup_writer(struct jpeg_compress_struct *s, struct jpeg_error_mgr *e,
- uint32_t w, uint32_t h, int quality, int opt)
-{
- jpeg_create_compress(s);
- e->error_exit = jpeg_error;
- s->err = jpeg_std_error(e);
-
- jpeg_stdio_dest(s, stdout);
- s->image_width = w;
- s->image_height = h;
- s->input_components = 3; /* color components per pixel */
- s->in_color_space = JCS_RGB; /* output color space */
- jpeg_set_defaults(s);
-
- if (opt) {
- s->optimize_coding = 1;
- }
- jpeg_set_quality(s, quality, 1);
-
- jpeg_start_compress(s, 1);
-}
-
-static void
-usage(void)
-{
- die("usage: %s [-b colour] [-o] [-q quality]", argv0);
-}
-
-int
-main(int argc, char *argv[])
-{
- struct jpeg_compress_struct jcomp;
- struct jpeg_error_mgr jerr;
- size_t rowlen;
- uint64_t a;
- uint32_t width, height, i, j, k, l;
- uint16_t *row, mask[3] = { 0xffff, 0xffff, 0xffff };
- uint8_t *rowout;
- int optimize = 0, quality = 85;
-
- /* arguments */
- ARGBEGIN {
- case 'b':
- if (parse_mask(EARGF(usage()), mask)) {
- usage();
- }
- break;
- case 'o':
- optimize = 1;
- break;
- case 'q':
- quality = estrtonum(EARGF(usage()), 0, 100);
- break;
- default:
- usage();
- } ARGEND
-
- if (argc) {
- usage();
- }
-
- /* prepare */
- ff_read_header(&width, &height);
- jpeg_setup_writer(&jcomp, &jerr, width, height, quality, optimize);
- row = ereallocarray(NULL, width, (sizeof("RGBA") - 1) * sizeof(uint16_t));
- rowlen = width * (sizeof("RGBA") - 1);
- rowout = ereallocarray(NULL, width, (sizeof("RGB") - 1) * sizeof(uint8_t));
-
- /* write data */
- for (i = 0; i < height; ++i) {
- efread(row, sizeof(uint16_t), rowlen, stdin);
- for (j = 0, k = 0; j < rowlen; j += 4, k += 3) {
- a = ntohs(row[j + 3]);
- for (l = 0; l < 3; l++) {
- /* alpha blending and 8-bit-reduction */
- rowout[k + l] = (a * ntohs(row[j + l]) +
- (UINT16_MAX - a) * mask[l]) /
- (UINT16_MAX *
- (UINT16_MAX / UINT8_MAX));
- }
- }
- jpeg_write_scanlines(&jcomp, &rowout, 1);
- }
-
- /* clean up */
- jpeg_finish_compress(&jcomp);
- jpeg_destroy_compress(&jcomp);
-
- return fshut(stdout, "<stdout>");
-}
diff --git a/.repos/farbfeld/ff2pam.1 b/.repos/farbfeld/ff2pam.1
deleted file mode 100644
index 3f4acfe..0000000
--- a/.repos/farbfeld/ff2pam.1
+++ /dev/null
@@ -1,38 +0,0 @@
-.Dd 2018-04-11
-.Dt FF2PAM 1
-.Os suckless.org
-.Sh NAME
-.Nm ff2pam
-.Nd convert farbfeld to PAM
-.Sh SYNOPSIS
-.Nm
-.Sh DESCRIPTION
-.Nm
-reads a
-.Xr farbfeld 5
-image from stdin, converts it to PAM (16-bit RGBA) and writes the result
-to stdout.
-.Pp
-In case of an error
-.Nm
-writes a diagnostic message to stderr.
-.Sh EXIT STATUS
-.Bl -tag -width Ds
-.It 0
-Image processed successfully.
-.It 1
-An error occurred.
-.El
-.Sh EXAMPLES
-$
-.Nm
-< image.ff > image.pam
-.Pp
-$ bunzip2 < image.ff.bz2 |
-.Nm
-> image.pam
-.Sh SEE ALSO
-.Xr bzip2 1 ,
-.Xr farbfeld 5
-.Sh AUTHORS
-.An Mattias Andrée Aq Mt maandree@kth.se
diff --git a/.repos/farbfeld/ff2pam.c b/.repos/farbfeld/ff2pam.c
deleted file mode 100644
index fca5c6f..0000000
--- a/.repos/farbfeld/ff2pam.c
+++ /dev/null
@@ -1,55 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-#include <arpa/inet.h>
-
-#include <errno.h>
-#include <inttypes.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "util.h"
-
-static void
-usage(void)
-{
- die("usage: %s", argv0);
-}
-
-int
-main(int argc, char *argv[])
-{
- size_t rowlen;
- uint32_t width, height, i;
- uint16_t *row;
-
- /* arguments */
- argv0 = argv[0], argc--, argv++;
-
- if (argc) {
- usage();
- }
-
- /* prepare */
- ff_read_header(&width, &height);
- row = ereallocarray(NULL, width, (sizeof("RGBA") - 1) * sizeof(uint16_t));
- rowlen = width * (sizeof("RGBA") - 1);
-
- /* write data */
- printf("P7\n"
- "WIDTH %" PRIu32 "\n"
- "HEIGHT %" PRIu32 "\n"
- "DEPTH 4\n" /* number of channels */
- "MAXVAL 65535\n"
- "TUPLTYPE RGB_ALPHA\n"
- "ENDHDR\n",
- width, height);
-
- for (i = 0; i < height; i++) {
- efread(row, sizeof(uint16_t), rowlen, stdin);
- efwrite(row, sizeof(uint16_t), rowlen, stdout);
- }
-
- return fshut(stdout, "<stdout>");
-}
diff --git a/.repos/farbfeld/ff2png.1 b/.repos/farbfeld/ff2png.1
deleted file mode 100644
index d8e1fab..0000000
--- a/.repos/farbfeld/ff2png.1
+++ /dev/null
@@ -1,38 +0,0 @@
-.Dd 2018-04-11
-.Dt FF2PNG 1
-.Os suckless.org
-.Sh NAME
-.Nm ff2png
-.Nd convert farbfeld to PNG
-.Sh SYNOPSIS
-.Nm
-.Sh DESCRIPTION
-.Nm
-reads a
-.Xr farbfeld 5
-image from stdin, converts it to PNG (16-bit RGBA) and writes the result
-to stdout.
-.Pp
-In case of an error
-.Nm
-writes a diagnostic message to stderr.
-.Sh EXIT STATUS
-.Bl -tag -width Ds
-.It 0
-Image processed successfully.
-.It 1
-An error occurred.
-.El
-.Sh EXAMPLES
-$
-.Nm
-< image.ff > image.png
-.Pp
-$ bunzip2 < image.ff.bz2 |
-.Nm
-> image.png
-.Sh SEE ALSO
-.Xr bzip2 1 ,
-.Xr farbfeld 5
-.Sh AUTHORS
-.An Laslo Hunhold Aq Mt dev@frign.de
diff --git a/.repos/farbfeld/ff2png.c b/.repos/farbfeld/ff2png.c
deleted file mode 100644
index 193b375..0000000
--- a/.repos/farbfeld/ff2png.c
+++ /dev/null
@@ -1,77 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-#include <arpa/inet.h>
-
-#include <errno.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <png.h>
-
-#include "util.h"
-
-static void
-png_err(png_struct *pngs, const char *msg)
-{
- (void)pngs;
- die("libpng: %s", msg);
-}
-
-static void
-png_setup_writer(png_struct **s, png_info **i, uint32_t w, uint32_t h)
-{
- *s = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, png_err, NULL);
- *i = png_create_info_struct(*s);
-
- if (!*s || !*i) {
- die("Failed to initialize libpng");
- }
-
- png_init_io(*s, stdout);
- png_set_IHDR(*s, *i, w, h, 16, PNG_COLOR_TYPE_RGB_ALPHA,
- PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE,
- PNG_FILTER_TYPE_BASE);
- png_write_info(*s, *i);
-}
-
-static void
-usage(void)
-{
- die("usage: %s", argv0);
-}
-
-int
-main(int argc, char *argv[])
-{
- png_struct *pngs;
- png_info *pngi;
- size_t rowlen;
- uint32_t width, height, i;
- uint16_t *row;
-
- /* arguments */
- argv0 = argv[0], argc--, argv++;
-
- if (argc) {
- usage();
- }
-
- /* prepare */
- ff_read_header(&width, &height);
- png_setup_writer(&pngs, &pngi, width, height);
- row = ereallocarray(NULL, width, (sizeof("RGBA") - 1) * sizeof(uint16_t));
- rowlen = width * (sizeof("RGBA") - 1);
-
- /* write data */
- for (i = 0; i < height; ++i) {
- efread(row, sizeof(uint16_t), rowlen, stdin);
- png_write_row(pngs, (uint8_t *)row);
- }
-
- /* clean up */
- png_write_end(pngs, NULL);
- png_destroy_write_struct(&pngs, NULL);
-
- return fshut(stdout, "<stdout>");
-}
diff --git a/.repos/farbfeld/ff2ppm.1 b/.repos/farbfeld/ff2ppm.1
deleted file mode 100644
index 1687346..0000000
--- a/.repos/farbfeld/ff2ppm.1
+++ /dev/null
@@ -1,46 +0,0 @@
-.Dd 2018-04-11
-.Dt FF2PPM 1
-.Os suckless.org
-.Sh NAME
-.Nm ff2ppm
-.Nd convert farbfeld to PPM
-.Sh SYNOPSIS
-.Nm
-.Op Fl b Ar colour
-.Sh DESCRIPTION
-.Nm
-reads a
-.Xr farbfeld 5
-image from stdin, converts it to PPM (16-Bit RGB P6 binary format) and
-writes the result to stdout.
-.Pp
-In case of an error
-.Nm
-writes a diagnostic message to stderr.
-.Sh OPTIONS
-.Bl -tag -width Ds
-.It Fl b Ar colour
-Blend the transparent colours with
-.Ar colour
-specified as rgb, rrggbb or rrrrggggbbbb. The default is fff.
-.El
-.Sh EXIT STATUS
-.Bl -tag -width Ds
-.It 0
-Image processed successfully.
-.It 1
-An error occurred.
-.El
-.Sh EXAMPLES
-$
-.Nm
-< image.ff > image.ppm
-.Pp
-$ bunzip2 < image.ff.bz2 |
-.Nm
--b 0f0 > image.ppm
-.Sh SEE ALSO
-.Xr bzip2 1 ,
-.Xr farbfeld 5
-.Sh AUTHORS
-.An Hiltjo Posthuma Aq Mt hiltjo@codemadness.org
diff --git a/.repos/farbfeld/ff2ppm.c b/.repos/farbfeld/ff2ppm.c
deleted file mode 100644
index 9b82d9c..0000000
--- a/.repos/farbfeld/ff2ppm.c
+++ /dev/null
@@ -1,72 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-#include <arpa/inet.h>
-
-#include <errno.h>
-#include <inttypes.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "arg.h"
-#include "util.h"
-
-static void
-usage(void)
-{
- die("usage: %s [-b colour]", argv0);
-}
-
-int
-main(int argc, char *argv[])
-{
- size_t rowlen, rowoutlen;
- uint64_t a;
- uint32_t width, height, i, j, k, l;
- uint16_t *row, mask[3] = { 0xffff, 0xffff, 0xffff };
- uint8_t *rowout;
-
- /* arguments */
- ARGBEGIN {
- case 'b':
- if (parse_mask(EARGF(usage()), mask)) {
- usage();
- }
- break;
- default:
- usage();
- } ARGEND
-
- if (argc) {
- usage();
- }
-
- /* prepare */
- ff_read_header(&width, &height);
- row = ereallocarray(NULL, width, (sizeof("RGBA") - 1) * sizeof(uint16_t));
- rowout = ereallocarray(NULL, width, (sizeof("RGB") - 1) * sizeof(uint8_t));
- rowlen = width * (sizeof("RGBA") - 1);
- rowoutlen = width * (sizeof("RGB") - 1);
-
- /* write data */
- printf("P6\n%" PRIu32 " %" PRIu32 "\n255\n", width, height);
-
- for (i = 0; i < height; ++i) {
- efread(row, sizeof(uint16_t), rowlen, stdin);
-
- for (j = 0, k = 0; j < rowlen; j += 4, k += 3) {
- a = ntohs(row[j + 3]);
- for (l = 0; l < 3; l++) {
- /* alpha blending and 8-bit-reduction */
- rowout[k + l] = (a * ntohs(row[j + l]) +
- (UINT16_MAX - a) * mask[l]) /
- (UINT16_MAX *
- (UINT16_MAX / UINT8_MAX));
- }
- }
-
- efwrite(rowout, sizeof(uint8_t), rowoutlen, stdout);
- }
-
- return fshut(stdout, "<stdout>");
-}
diff --git a/.repos/farbfeld/jpg2ff.1 b/.repos/farbfeld/jpg2ff.1
deleted file mode 100644
index 6ae67e2..0000000
--- a/.repos/farbfeld/jpg2ff.1
+++ /dev/null
@@ -1,38 +0,0 @@
-.Dd 2018-04-11
-.Dt JPG2FF 1
-.Os suckless.org
-.Sh NAME
-.Nm jpg2ff
-.Nd convert JPG to farbfeld
-.Sh SYNOPSIS
-.Nm
-.Sh DESCRIPTION
-.Nm
-reads a JPG image from stdin, converts it to
-.Xr farbfeld 5
-and writes the result to stdout.
-.Pp
-In case of an error
-.Nm
-writes a diagnostic message to stderr.
-.Sh EXIT STATUS
-.Bl -tag -width Ds
-.It 0
-Image processed successfully.
-.It 1
-An error occurred.
-.El
-.Sh EXAMPLES
-$
-.Nm
-< image.jpg > image.ff
-.Pp
-$
-.Nm
-< image.jpg | bzip2 > image.ff.bz2
-.Sh SEE ALSO
-.Xr 2ff 1 ,
-.Xr bzip2 1 ,
-.Xr farbfeld 5
-.Sh AUTHORS
-.An Laslo Hunhold Aq Mt dev@frign.de
diff --git a/.repos/farbfeld/jpg2ff.c b/.repos/farbfeld/jpg2ff.c
deleted file mode 100644
index 360ace4..0000000
--- a/.repos/farbfeld/jpg2ff.c
+++ /dev/null
@@ -1,90 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-#include <arpa/inet.h>
-
-#include <errno.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <jpeglib.h>
-
-#include "util.h"
-
-static void
-jpeg_error(j_common_ptr js)
-{
- fprintf(stderr, "%s: libjpeg: ", argv0);
- (*js->err->output_message)(js);
- exit(1);
-}
-
-static void
-jpeg_setup_reader(struct jpeg_decompress_struct *s, struct jpeg_error_mgr *e,
- uint32_t *w, uint32_t *h)
-{
- jpeg_create_decompress(s);
- e->error_exit = jpeg_error;
- s->err = jpeg_std_error(e);
-
- jpeg_stdio_src(s, stdin);
- jpeg_read_header(s, 1);
- *w = s->image_width;
- *h = s->image_height;
- s->output_components = 3; /* color components per pixel */
- s->out_color_space = JCS_RGB; /* input color space */
-
- jpeg_start_decompress(s);
-}
-
-static void
-usage(void)
-{
- die("usage: %s", argv0);
-}
-
-int
-main(int argc, char *argv[])
-{
- struct jpeg_decompress_struct js;
- struct jpeg_error_mgr jerr;
- uint32_t width, height;
- uint16_t *row;
- uint8_t *rowin;
- size_t rowlen, i;
-
- /* arguments */
- argv0 = argv[0], argc--, argv++;
-
- if (argc) {
- usage();
- }
-
- /* prepare */
- jpeg_setup_reader(&js, &jerr, &width, &height);
- row = ereallocarray(NULL, width, (sizeof("RGBA") - 1) * sizeof(uint16_t));
- rowlen = width * (sizeof("RGBA") - 1);
- rowin = ereallocarray(NULL, width, (sizeof("RGB") - 1) * sizeof(uint8_t));
-
- /* write data */
- ff_write_header(width, height);
-
- while (js.output_scanline < js.output_height) {
- jpeg_read_scanlines(&js, &rowin, 1);
-
- for (i = 0; i < width; ++i) {
- row[4 * i + 0] = htons(rowin[3 * i + 0] * 257);
- row[4 * i + 1] = htons(rowin[3 * i + 1] * 257);
- row[4 * i + 2] = htons(rowin[3 * i + 2] * 257);
- row[4 * i + 3] = htons(65535);
- }
-
- efwrite(row, sizeof(uint16_t), rowlen, stdout);
- }
-
- /* clean up */
- jpeg_finish_decompress(&js);
- jpeg_destroy_decompress(&js);
-
- return fshut(stdout, "<stdout>");
-}
diff --git a/.repos/farbfeld/png2ff.1 b/.repos/farbfeld/png2ff.1
deleted file mode 100644
index 5ede5c9..0000000
--- a/.repos/farbfeld/png2ff.1
+++ /dev/null
@@ -1,38 +0,0 @@
-.Dd 2018-04-11
-.Dt PNG2FF 1
-.Os suckless.org
-.Sh NAME
-.Nm png2ff
-.Nd convert PNG to farbfeld
-.Sh SYNOPSIS
-.Nm
-.Sh DESCRIPTION
-.Nm
-reads a PNG image from stdin, converts it to
-.Xr farbfeld 5
-and writes the result to stdout.
-.Pp
-In case of an error
-.Nm
-writes a diagnostic message to stderr.
-.Sh EXIT STATUS
-.Bl -tag -width Ds
-.It 0
-Image processed successfully.
-.It 1
-An error occurred.
-.El
-.Sh EXAMPLES
-$
-.Nm
-< image.png > image.ff
-.Pp
-$
-.Nm
-< image.png | bzip2 > image.ff.bz2
-.Sh SEE ALSO
-.Xr 2ff 1 ,
-.Xr bzip2 1 ,
-.Xr farbfeld 5
-.Sh AUTHORS
-.An Laslo Hunhold Aq Mt dev@frign.de
diff --git a/.repos/farbfeld/png2ff.c b/.repos/farbfeld/png2ff.c
deleted file mode 100644
index 74109d8..0000000
--- a/.repos/farbfeld/png2ff.c
+++ /dev/null
@@ -1,97 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-#include <arpa/inet.h>
-
-#include <errno.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <png.h>
-
-#include "util.h"
-
-static void
-png_err(png_struct *pngs, const char *msg)
-{
- (void)pngs;
- die("libpng: %s", msg);
-}
-
-static void
-png_setup_reader(png_struct **s, png_info **i, uint32_t *w, uint32_t *h)
-{
- *s = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, png_err, NULL);
- *i = png_create_info_struct(*s);
-
- if (!*s || !*i) {
- die("Failed to initialize libpng");
- }
-
- png_init_io(*s, stdin);
- if (png_get_valid(*s, *i, PNG_INFO_tRNS)) {
- png_set_tRNS_to_alpha(*s);
- }
- png_set_add_alpha(*s, 255*257, PNG_FILLER_AFTER);
- png_set_expand_gray_1_2_4_to_8(*s);
- png_set_gray_to_rgb(*s);
- png_set_packing(*s);
- png_read_png(*s, *i, PNG_TRANSFORM_PACKING | PNG_TRANSFORM_EXPAND, NULL);
- *w = png_get_image_width(*s, *i);
- *h = png_get_image_height(*s, *i);
-}
-
-static void
-usage(void)
-{
- die("usage: %s", argv0);
-}
-
-int
-main(int argc, char *argv[])
-{
- png_struct *pngs;
- png_info *pngi;
- uint32_t width, height, rowlen, r, i;
- uint16_t *row;
- uint8_t **pngrows;
-
- /* arguments */
- argv0 = argv[0], argc--, argv++;
-
- if (argc) {
- usage();
- }
-
- /* prepare */
- png_setup_reader(&pngs, &pngi, &width, &height);
- row = ereallocarray(NULL, width, (sizeof("RGBA") - 1) * sizeof(uint16_t));
- rowlen = width * (sizeof("RGBA") - 1);
- pngrows = png_get_rows(pngs, pngi);
-
- /* write data */
- ff_write_header(width, height);
-
- switch(png_get_bit_depth(pngs, pngi)) {
- case 8:
- for (r = 0; r < height; ++r) {
- for (i = 0; i < rowlen; i++) {
- row[i] = htons(257 * pngrows[r][i]);
- }
- efwrite(row, sizeof(uint16_t), rowlen, stdout);
- }
- break;
- case 16:
- for (r = 0; r < height; ++r) {
- efwrite(pngrows[r], sizeof(uint16_t), rowlen, stdout);
- }
- break;
- default:
- die("Invalid bit-depth");
- }
-
- /* clean up */
- png_destroy_read_struct(&pngs, &pngi, NULL);
-
- return fshut(stdout, "<stdout>");
-}
diff --git a/.repos/farbfeld/util.c b/.repos/farbfeld/util.c
deleted file mode 100644
index 6418bc9..0000000
--- a/.repos/farbfeld/util.c
+++ /dev/null
@@ -1,242 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-#include <arpa/inet.h>
-
-#include <errno.h>
-#include <limits.h>
-#include <stdarg.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-
-#include "util.h"
-
-char *argv0;
-
-static void
-verr(const char *fmt, va_list ap)
-{
- if (argv0 && strncmp(fmt, "usage", sizeof("usage") - 1)) {
- fprintf(stderr, "%s: ", argv0);
- }
-
- vfprintf(stderr, fmt, ap);
-
- if (fmt[0] && fmt[strlen(fmt) - 1] == ':') {
- fputc(' ', stderr);
- perror(NULL);
- } else {
- fputc('\n', stderr);
- }
-}
-
-void
-warn(const char *fmt, ...)
-{
- va_list ap;
-
- va_start(ap, fmt);
- verr(fmt, ap);
- va_end(ap);
-}
-
-void
-die(const char *fmt, ...)
-{
- va_list ap;
-
- va_start(ap, fmt);
- verr(fmt, ap);
- va_end(ap);
-
- exit(1);
-}
-
-void
-ff_read_header(uint32_t *width, uint32_t *height)
-{
- uint32_t hdr[4];
-
- efread(hdr, sizeof(*hdr), LEN(hdr), stdin);
-
- if (memcmp("farbfeld", hdr, sizeof("farbfeld") - 1)) {
- die("Invalid magic value");
- }
-
- *width = ntohl(hdr[2]);
- *height = ntohl(hdr[3]);
-}
-
-void
-ff_write_header(uint32_t width, uint32_t height)
-{
- uint32_t tmp;
-
- fputs("farbfeld", stdout);
-
- tmp = htonl(width);
- efwrite(&tmp, sizeof(tmp), 1, stdout);
-
- tmp = htonl(height);
- efwrite(&tmp, sizeof(tmp), 1, stdout);
-}
-
-int
-parse_mask(const char *s, uint16_t mask[3])
-{
- size_t slen, i;
- unsigned int col[3], colfac;
- char fmt[] = "%#x%#x%#x";
-
- slen = strlen(s);
- if (slen != 3 && slen != 6 && slen != 12) {
- return 1;
- }
-
- fmt[1] = fmt[4] = fmt[7] = ((slen / 3) + '0');
- if (sscanf(s, fmt, col, col + 1, col + 2) != 3) {
- return 1;
- }
-
- colfac = (slen == 3) ? UINT16_MAX / 0xf :
- (slen == 6) ? UINT16_MAX / 0xff :
- UINT16_MAX / 0xffff;
-
- for (i = 0; i < 3; i++) {
- mask[i] = col[i] * colfac;
- }
-
- return 0;
-}
-
-int
-fshut(FILE *fp, const char *fname)
-{
- int ret = 0;
-
- /* fflush() is undefined for input streams by ISO C,
- * but not POSIX 2008 if you ignore ISO C overrides.
- * Leave it unchecked and rely on the following
- * functions to detect errors.
- */
- fflush(fp);
-
- if (ferror(fp) && !ret) {
- warn("ferror '%s':", fname);
- ret = 1;
- }
-
- if (fclose(fp) && !ret) {
- warn("fclose '%s':", fname);
- ret = 1;
- }
-
- return ret;
-}
-
-void
-efread(void *p, size_t s, size_t n, FILE *f)
-{
- if (fread(p, s, n, f) != n) {
- if (ferror(f)) {
- die("fread:");
- } else {
- die("fread: Unexpected end of file");
- }
- }
-}
-
-void
-efwrite(const void *p, size_t s, size_t n, FILE *f)
-{
- if (fwrite(p, s, n, f) != n) {
- die("fwrite:");
- }
-}
-
-void *
-ereallocarray(void *optr, size_t nmemb, size_t size)
-{
- void *p;
-
- if (!(p = reallocarray(optr, nmemb, size))) {
- die("reallocarray: Out of memory");
- }
-
- return p;
-}
-
-long long
-estrtonum(const char *numstr, long long minval, long long maxval)
-{
- const char *errstr;
- long long ll;
-
- ll = strtonum(numstr, minval, maxval, &errstr);
- if (errstr) {
- die("strtonum '%s': %s", numstr, errstr);
- }
-
- return ll;
-}
-
-/*
- * This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX
- * if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW
- */
-#define MUL_NO_OVERFLOW (1UL << (sizeof(size_t) * 4))
-
-void *
-reallocarray(void *optr, size_t nmemb, size_t size)
-{
- if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
- nmemb > 0 && SIZE_MAX / nmemb < size) {
- errno = ENOMEM;
- return NULL;
- }
- return realloc(optr, size * nmemb);
-}
-
-#define INVALID 1
-#define TOOSMALL 2
-#define TOOLARGE 3
-
-long long
-strtonum(const char *numstr, long long minval, long long maxval,
- const char **errstrp)
-{
- long long ll = 0;
- int error = 0;
- char *ep;
- struct errval {
- const char *errstr;
- int err;
- } ev[4] = {
- { NULL, 0 },
- { "invalid", EINVAL },
- { "too small", ERANGE },
- { "too large", ERANGE },
- };
-
- ev[0].err = errno;
- errno = 0;
- if (minval > maxval) {
- error = INVALID;
- } else {
- ll = strtoll(numstr, &ep, 10);
- if (numstr == ep || *ep != '\0')
- error = INVALID;
- else if ((ll == LLONG_MIN && errno == ERANGE) || ll < minval)
- error = TOOSMALL;
- else if ((ll == LLONG_MAX && errno == ERANGE) || ll > maxval)
- error = TOOLARGE;
- }
- if (errstrp != NULL)
- *errstrp = ev[error].errstr;
- errno = ev[error].err;
- if (error)
- ll = 0;
-
- return (ll);
-}
diff --git a/.repos/farbfeld/util.h b/.repos/farbfeld/util.h
deleted file mode 100644
index f6e32c6..0000000
--- a/.repos/farbfeld/util.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-#include <stdint.h>
-#include <stdio.h>
-
-#define LEN(x) (sizeof (x) / sizeof *(x))
-
-extern char *argv0;
-
-void warn(const char *, ...);
-void die(const char *, ...);
-
-void ff_read_header(uint32_t *width, uint32_t *height);
-void ff_write_header(uint32_t width, uint32_t height);
-
-int parse_mask(const char *, uint16_t mask[3]);
-
-int fshut(FILE *, const char *);
-
-void efread(void *, size_t, size_t, FILE *);
-void efwrite(const void *, size_t, size_t, FILE *);
-
-#undef reallocarray
-void *reallocarray(void *, size_t, size_t);
-void *ereallocarray(void *optr, size_t nmemb, size_t size);
-
-#undef strtonum
-long long strtonum(const char *, long long, long long, const char **);
-long long estrtonum(const char *, long long, long long);
diff --git a/.repos/sent/LICENSE b/.repos/sent/LICENSE
deleted file mode 100644
index e0be8ce..0000000
--- a/.repos/sent/LICENSE
+++ /dev/null
@@ -1,29 +0,0 @@
-ISC-License
-
-(c) 2014-2017 Markus Teich <markus.teich@stusta.mhn.de>
-
-Permission to use, copy, modify, and/or distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-(c) 2016,2017 Laslo Hunhold <dev@frign.de>
-(c) 2016 ssd <ssd@mailless.org>
-(c) 2016 Hiltjo Posthuma <hiltjo@codemadness.org>
-(c) 2015 David Phillips <dbphillipsnz@gmail.com>
-(c) 2015 Grant Mathews <grant.m.mathews@gmail.com>
-(c) 2015 Dimitris Papastamos <sin@2f30.org>
-(c) 2015 Alexis <surryhill@gmail.com>
-(c) 2015 Quentin Rameau <quinq@fifth.space>
-(c) 2015 Ivan Tham <pickfire@riseup.net>
-(c) 2015 Jan Christoph Ebersbach <jceb@e-jc.de>
-(c) 2015 Tony Lainson <t.lainson@gmail.com>
-(c) 2015 Szabolcs Nagy <nsz@port70.net>
-(c) 2015 Jonas Jelten <jj@sft.mx>
diff --git a/.repos/sent/Makefile b/.repos/sent/Makefile
deleted file mode 100644
index 56e6367..0000000
--- a/.repos/sent/Makefile
+++ /dev/null
@@ -1,60 +0,0 @@
-# sent - plain text presentation tool
-# See LICENSE file for copyright and license details.
-
-include config.mk
-
-SRC = sent.c drw.c util.c
-OBJ = ${SRC:.c=.o}
-
-all: options sent
-
-options:
- @echo sent build options:
- @echo "CFLAGS = ${CFLAGS}"
- @echo "LDFLAGS = ${LDFLAGS}"
- @echo "CC = ${CC}"
-
-config.h:
- cp config.def.h config.h
-
-.c.o:
- @echo CC $<
- @${CC} -c ${CFLAGS} $<
-
-${OBJ}: config.h config.mk
-
-sent: ${OBJ}
- @echo CC -o $@
- @${CC} -o $@ ${OBJ} ${LDFLAGS}
-
-cscope: ${SRC} config.h
- @echo cScope
- @cscope -R -b || echo cScope not installed
-
-clean:
- @echo cleaning
- @rm -f sent ${OBJ} sent-${VERSION}.tar.gz
-
-dist: clean
- @echo creating dist tarball
- @mkdir -p sent-${VERSION}
- @cp -R LICENSE Makefile config.mk config.def.h ${SRC} sent-${VERSION}
- @tar -cf sent-${VERSION}.tar sent-${VERSION}
- @gzip sent-${VERSION}.tar
- @rm -rf sent-${VERSION}
-
-install: all
- @echo installing executable file to ${DESTDIR}${PREFIX}/bin
- @mkdir -p ${DESTDIR}${PREFIX}/bin
- @cp -f sent ${DESTDIR}${PREFIX}/bin
- @chmod 755 ${DESTDIR}${PREFIX}/bin/sent
- @echo installing manual page to ${DESTDIR}${MANPREFIX}/man1
- @mkdir -p ${DESTDIR}${MANPREFIX}/man1
- @cp sent.1 ${DESTDIR}${MANPREFIX}/man1/sent.1
- @chmod 644 ${DESTDIR}${MANPREFIX}/man1/sent.1
-
-uninstall:
- @echo removing executable file from ${DESTDIR}${PREFIX}/bin
- @rm -f ${DESTDIR}${PREFIX}/bin/sent
-
-.PHONY: all options clean dist install uninstall cscope
diff --git a/.repos/sent/README.md b/.repos/sent/README.md
deleted file mode 100644
index c1e9385..0000000
--- a/.repos/sent/README.md
+++ /dev/null
@@ -1,59 +0,0 @@
-sent is a simple plaintext presentation tool.
-
-sent does not need latex, libreoffice or any other fancy file format, it uses
-plaintext files to describe the slides and can include images via farbfeld.
-Every paragraph represents a slide in the presentation.
-
-The presentation is displayed in a simple X11 window. The content of each slide
-is automatically scaled to fit the window and centered so you also don't have to
-worry about alignment. Instead you can really concentrate on the content.
-
-
-Dependencies
-
-You need Xlib and Xft to build sent and the farbfeld[0] tools installed to use
-images in your presentations.
-
-Demo
-
-To get a little demo, just type
-
- make && ./sent example
-
-You can navigate with the arrow keys and quit with `q`.
-
-
-Usage
-
- sent [FILE]
-
-If FILE is omitted or equals `-`, stdin will be read. Produce image slides by
-prepending a `@` in front of the filename as a single paragraph. Lines starting
-with `#` will be ignored. A `\` at the beginning of the line escapes `@` and
-`#`. A presentation file could look like this:
-
- sent
-
- @nyan.png
-
- depends on
- - Xlib
- - Xft
- - farbfeld
-
- sent FILENAME
- one slide per paragraph
- # This is a comment and will not be part of the presentation
- \# This and the next line start with backslashes
-
- \@FILE.png
-
- thanks / questions?
-
-
-Development
-
-sent is developed at http://tools.suckless.org/sent
-
-
-0: http://tools.suckless.org/farbfeld/
diff --git a/.repos/sent/arg.h b/.repos/sent/arg.h
deleted file mode 100644
index 7f503ec..0000000
--- a/.repos/sent/arg.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * ISC-License
- *
- * Copyright 2017 Laslo Hunhold <dev@frign.de>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-#ifndef ARG_H
-#define ARG_H
-
-extern char *argv0;
-
-/* int main(int argc, char *argv[]) */
-#define ARGBEGIN for (argv0 = *argv, *argv ? (argc--, argv++) : ((void *)0); \
- *argv && (*argv)[0] == '-' && (*argv)[1]; argc--, argv++) { \
- int i_, argused_; \
- if ((*argv)[1] == '-' && !(*argv)[2]) { \
- argc--, argv++; \
- break; \
- } \
- for (i_ = 1, argused_ = 0; (*argv)[i_]; i_++) { \
- switch((*argv)[i_])
-#define ARGEND if (argused_) { \
- if ((*argv)[i_ + 1]) { \
- break; \
- } else { \
- argc--, argv++; \
- break; \
- } \
- } \
- } \
- }
-#define ARGC() ((*argv)[i_])
-#define ARGF_(x) (((*argv)[i_ + 1]) ? (argused_ = 1, &((*argv)[i_ + 1])) : \
- (*(argv + 1)) ? (argused_ = 1, *(argv + 1)) : (x))
-#define EARGF(x) ARGF_(((x), exit(1), (char *)0))
-#define ARGF() ARGF_((char *)0)
-
-#endif
diff --git a/.repos/sent/config.h b/.repos/sent/config.h
deleted file mode 100644
index 407b1df..0000000
--- a/.repos/sent/config.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-
-static char *fontfallbacks[] = {
- "Latin Modern Math",
- "dejavu sans",
- "roboto",
- "ubuntu",
-};
-#define NUMFONTSCALES 42
-#define FONTSZ(x) ((int)(10.0 * powf(1.1288, (x)))) /* x in [0, NUMFONTSCALES-1] */
-
-static const char *colors[] = {
- "#282c34", /* foreground color */
- "#abb2bf", /* background color */
-};
-
-static const char *dark_colors[] = {
- "#abb2bf", /* foreground color */
- "#282c34", /* background color */
-};
-
-static const float linespacing = 1.4;
-
-/* how much screen estate is to be used at max for the content */
-static const float usablewidth = 0.75;
-static const float usableheight = 0.75;
-
-static Mousekey mshortcuts[] = {
- /* button function argument */
- { Button1, advance, {.i = +1} },
- { Button3, advance, {.i = -1} },
- { Button4, advance, {.i = -1} },
- { Button5, advance, {.i = +1} },
-};
-
-static Shortcut shortcuts[] = {
- /* keysym function argument */
- { XK_Escape, quit, {0} },
- { XK_q, quit, {0} },
- { XK_Right, advance, {.i = +1} },
- { XK_Left, advance, {.i = -1} },
- { XK_Return, advance, {.i = +1} },
- { XK_space, advance, {.i = +1} },
- { XK_BackSpace, advance, {.i = -1} },
- { XK_l, advance, {.i = +1} },
- { XK_h, advance, {.i = -1} },
- { XK_j, advance, {.i = +1} },
- { XK_k, advance, {.i = -1} },
- { XK_Down, advance, {.i = +1} },
- { XK_Up, advance, {.i = -1} },
- { XK_Next, advance, {.i = +1} },
- { XK_Prior, advance, {.i = -1} },
- { XK_n, advance, {.i = +1} },
- { XK_p, advance, {.i = -1} },
- { XK_i, toggle_theme, {0} },
- { XK_r, reload, {0} },
-};
-
-static Filter filters[] = {
- { "\\.ff$", "cat" },
- { "\\.ff.bz2$", "bunzip2" },
- { "\\.[a-z0-9]+$", "2ff" },
-};
diff --git a/.repos/sent/config.mk b/.repos/sent/config.mk
deleted file mode 100644
index d61c554..0000000
--- a/.repos/sent/config.mk
+++ /dev/null
@@ -1,30 +0,0 @@
-# sent version
-VERSION = 1
-
-# Customize below to fit your system
-
-# paths
-PREFIX = /usr/local
-MANPREFIX = ${PREFIX}/share/man
-
-X11INC = /usr/X11R6/include
-X11LIB = /usr/X11R6/lib
-
-# includes and libs
-INCS = -I. -I/usr/include -I/usr/include/freetype2 -I${X11INC}
-LIBS = -L/usr/lib -lc -lm -L${X11LIB} -lXft -lfontconfig -lX11
-# OpenBSD (uncomment)
-#INCS = -I. -I${X11INC} -I${X11INC}/freetype2
-# FreeBSD (uncomment)
-#INCS = -I. -I/usr/local/include -I/usr/local/include/freetype2 -I${X11INC}
-#LIBS = -L/usr/local/lib -lc -lm -L${X11LIB} -lXft -lfontconfig -lX11
-
-# flags
-CPPFLAGS = -DVERSION=\"${VERSION}\" -D_XOPEN_SOURCE=600
-CFLAGS += -g -std=c99 -pedantic -Wall ${INCS} ${CPPFLAGS}
-LDFLAGS += -g ${LIBS}
-#CFLAGS += -std=c99 -pedantic -Wall -Os ${INCS} ${CPPFLAGS}
-#LDFLAGS += ${LIBS}
-
-# compiler and linker
-CC ?= cc
diff --git a/.repos/sent/drw.c b/.repos/sent/drw.c
deleted file mode 100644
index c1582e7..0000000
--- a/.repos/sent/drw.c
+++ /dev/null
@@ -1,421 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <X11/Xlib.h>
-#include <X11/Xft/Xft.h>
-
-#include "drw.h"
-#include "util.h"
-
-#define UTF_INVALID 0xFFFD
-#define UTF_SIZ 4
-
-static const unsigned char utfbyte[UTF_SIZ + 1] = {0x80, 0, 0xC0, 0xE0, 0xF0};
-static const unsigned char utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8};
-static const long utfmin[UTF_SIZ + 1] = { 0, 0, 0x80, 0x800, 0x10000};
-static const long utfmax[UTF_SIZ + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF};
-
-static long
-utf8decodebyte(const char c, size_t *i)
-{
- for (*i = 0; *i < (UTF_SIZ + 1); ++(*i))
- if (((unsigned char)c & utfmask[*i]) == utfbyte[*i])
- return (unsigned char)c & ~utfmask[*i];
- return 0;
-}
-
-static size_t
-utf8validate(long *u, size_t i)
-{
- if (!BETWEEN(*u, utfmin[i], utfmax[i]) || BETWEEN(*u, 0xD800, 0xDFFF))
- *u = UTF_INVALID;
- for (i = 1; *u > utfmax[i]; ++i)
- ;
- return i;
-}
-
-static size_t
-utf8decode(const char *c, long *u, size_t clen)
-{
- size_t i, j, len, type;
- long udecoded;
-
- *u = UTF_INVALID;
- if (!clen)
- return 0;
- udecoded = utf8decodebyte(c[0], &len);
- if (!BETWEEN(len, 1, UTF_SIZ))
- return 1;
- for (i = 1, j = 1; i < clen && j < len; ++i, ++j) {
- udecoded = (udecoded << 6) | utf8decodebyte(c[i], &type);
- if (type)
- return j;
- }
- if (j < len)
- return 0;
- *u = udecoded;
- utf8validate(u, len);
-
- 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);
- 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)
-{
- char buf[1024];
- int ty;
- unsigned int ew;
- XftDraw *d = NULL;
- Fnt *usedfont, *curfont, *nextfont;
- size_t i, len;
- int utf8strlen, utf8charlen, render = x || y || w || h;
- long utf8codepoint = 0;
- const char *utf8str;
- FcCharSet *fccharset;
- FcPattern *fcpattern;
- FcPattern *match;
- XftResult result;
- int charexists = 0;
-
- if (!drw || (render && !drw->scheme) || !text || !drw->fonts)
- return 0;
-
- if (!render) {
- w = ~w;
- } else {
- XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].pixel);
- XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
- d = XftDrawCreate(drw->dpy, drw->drawable,
- DefaultVisual(drw->dpy, drw->screen),
- DefaultColormap(drw->dpy, drw->screen));
- x += lpad;
- w -= lpad;
- }
-
- usedfont = drw->fonts;
- while (1) {
- utf8strlen = 0;
- utf8str = text;
- nextfont = NULL;
- while (*text) {
- utf8charlen = utf8decode(text, &utf8codepoint, UTF_SIZ);
- for (curfont = drw->fonts; curfont; curfont = curfont->next) {
- charexists = charexists || XftCharExists(drw->dpy, curfont->xfont, utf8codepoint);
- if (charexists) {
- if (curfont == usedfont) {
- utf8strlen += utf8charlen;
- text += utf8charlen;
- } else {
- nextfont = curfont;
- }
- break;
- }
- }
-
- if (!charexists || nextfont)
- break;
- else
- charexists = 0;
- }
-
- if (utf8strlen) {
- drw_font_getexts(usedfont, utf8str, utf8strlen, &ew, NULL);
- /* shorten text if necessary */
- for (len = MIN(utf8strlen, sizeof(buf) - 1); len && ew > w; len--)
- drw_font_getexts(usedfont, utf8str, len, &ew, NULL);
-
- if (len) {
- memcpy(buf, utf8str, len);
- buf[len] = '\0';
- if (len < utf8strlen)
- for (i = len; i && i > len - 3; buf[--i] = '.')
- ; /* NOP */
-
- if (render) {
- ty = y + (h - usedfont->h) / 2 + usedfont->xfont->ascent;
- XftDrawStringUtf8(d, &drw->scheme[invert ? ColBg : ColFg],
- usedfont->xfont, x, ty, (XftChar8 *)buf, len);
- }
- x += ew;
- w -= ew;
- }
- }
-
- if (!*text) {
- 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;
-
- 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);
- 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);
-}
-
-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/.repos/sent/drw.h b/.repos/sent/drw.h
deleted file mode 100644
index 4c67419..0000000
--- a/.repos/sent/drw.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/* 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);
-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/.repos/sent/example.sent b/.repos/sent/example.sent
deleted file mode 100644
index 300577a..0000000
--- a/.repos/sent/example.sent
+++ /dev/null
@@ -1,69 +0,0 @@
-sent
-
-Origin:
- Takahashi
-
-Why?
-• PPTX sucks
-• LATEX sucks
-• PDF sucks
-
-also:
-terminal presentations
-don't support images…
-
-@nyan.png
-this text will not be displayed, since the @ at the start of the first line
-makes this paragraph an image slide.
-
-easy to use
-
-depends on
-♽ Xlib
-☢ Xft
-☃ farbfeld
-
-~1000 lines of code
-
-usage:
-$ sent FILE1 [FILE2 …]
-
-▸ one slide per paragraph
-▸ lines starting with # are ignored
-▸ image slide: paragraph containing @FILENAME
-▸ empty slide: just use a \ as a paragraph
-
-# This is a comment and will not be part of the presentation
-
-# multiple empty lines between paragraphs are also ignored
-
-
-# The following lines should produce
-# one empty slide
-
-
-
-\
-\
-
-\@this_line_actually_started_with_a_\.png
-\#This line as well
-⇒ Prepend a backslash to kill behaviour of special characters
-
-Images are handled in the
-http://tools.suckless.org/farbfeld/
-format internally.
-
-sent also supports transparent images.
-Try changing the background in config.h
-and rebuild.
-
-@transparent_test.ff
-
-😀😁😂😃😄😅😆😇😈😉😊😋😌😍😎😏
-😐😑😒😓😔😕😖😗😘😙😚😛😜😝😞😟
-😠😡😢😣😥😦😧😨😩😪😫😭😮😯😰😱
-😲😳😴😵😶😷😸😹😺😻😼😽😾😿🙀☠
-
-thanks.
-questions?
diff --git a/.repos/sent/sent.1 b/.repos/sent/sent.1
deleted file mode 100644
index e2bec40..0000000
--- a/.repos/sent/sent.1
+++ /dev/null
@@ -1,71 +0,0 @@
-.Dd 2016-08-12
-.Dt SENT 1
-.Sh NAME
-.Nm sent
-.Nd simple plaintext presentation tool
-.Sh SYNOPSIS
-.Nm
-.Op Fl v
-.Op Fl d
-.Op Ar file
-.Sh DESCRIPTION
-.Nm
-is a simple plain text presentation tool for X. sent does not need LaTeX,
-LibreOffice or any other fancy file format. Instead, sent reads plain text
-describing the slides. sent can also draw images.
-.Pp
-Every paragraph represents a slide in the presentation. Especially for
-presentations using the Takahashi method this is very nice and allows
-you to write the presentation for a quick lightning talk within a
-few minutes.
-.Sh OPTIONS
-.Bl -tag -width Ds
-.It Fl v
-Print version information to stdout and exit.
-.It Fl d
-Use the colors from the dark colors array.
-.El
-.Sh USAGE
-.Bl -tag -width Ds
-.It Em Mouse commands
-.Bl -tag -width Ds
-.It Sy Button1 | Button5
-Go to next slide, if existent.
-.It Sy Button3 | Button4
-Go to previous slide, if existent.
-.El
-.It Em Keyboard commands
-.Bl -tag -width Ds
-.It Sy Escape | q
-Quit.
-.It Sy r
-Reload the slides. Only works on file input.
-.It Sy Right | Return | Space | l | j | Down | Next | n
-Go to next slide, if existent.
-.It Sy Left | Backspace | h | k | Up | Prior | p
-Go to previous slide, if existent.
-.El
-.El
-.Sh FORMAT
-The presentation file is made up of at least one paragraph, with an
-empty line separating two slides.
-Each input line is interpreted literally, except from control characters
-at the beginning of lines described as follows:
-.Bl -tag -width Ds
-.It Sy @
-Create individual slide containing the image pointed to by the filename
-following the
-.Sy @ .
-.It Sy #
-Ignore this input line.
-.It Sy \e
-Create input line using the characters following the
-.Sy \e
-without interpreting them.
-.El
-.Sh CUSTOMIZATION
-.Nm
-can be customized by creating a custom config.h and (re)compiling the
-source code. This keeps it fast, secure and simple.
-.Sh SEE ALSO
-.Xr 2ff 1
diff --git a/.repos/sent/sent.c b/.repos/sent/sent.c
deleted file mode 100644
index eb7b503..0000000
--- a/.repos/sent/sent.c
+++ /dev/null
@@ -1,732 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-#include <sys/types.h>
-#include <arpa/inet.h>
-
-#include <errno.h>
-#include <fcntl.h>
-#include <math.h>
-#include <regex.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <X11/keysym.h>
-#include <X11/XKBlib.h>
-#include <X11/Xatom.h>
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-#include <X11/Xft/Xft.h>
-
-#include "arg.h"
-#include "util.h"
-#include "drw.h"
-
-char *argv0;
-
-int use_dark_scheme = 0;
-
-/* macros */
-#define LEN(a) (sizeof(a) / sizeof(a)[0])
-#define LIMIT(x, a, b) (x) = (x) < (a) ? (a) : (x) > (b) ? (b) : (x)
-#define MAXFONTSTRLEN 128
-
-typedef enum {
- NONE = 0,
- SCALED = 1,
-} imgstate;
-
-typedef struct {
- unsigned char *buf;
- unsigned int bufwidth, bufheight;
- imgstate state;
- XImage *ximg;
- int numpasses;
-} Image;
-
-typedef struct {
- char *regex;
- char *bin;
-} Filter;
-
-typedef struct {
- unsigned int linecount;
- char **lines;
- Image *img;
- char *embed;
-} Slide;
-
-/* Purely graphic info */
-typedef struct {
- Display *dpy;
- Window win;
- Atom wmdeletewin, netwmname;
- Visual *vis;
- XSetWindowAttributes attrs;
- int scr;
- int w, h;
- int uw, uh; /* usable dimensions for drawing text and images */
-} XWindow;
-
-typedef union {
- int i;
- unsigned int ui;
- float f;
- const void *v;
-} Arg;
-
-typedef struct {
- unsigned int b;
- void (*func)(const Arg *);
- const Arg arg;
-} Mousekey;
-
-typedef struct {
- KeySym keysym;
- void (*func)(const Arg *);
- const Arg arg;
-} Shortcut;
-
-static void fffree(Image *img);
-static void ffload(Slide *s);
-static void ffprepare(Image *img);
-static void ffscale(Image *img);
-static void ffdraw(Image *img);
-
-static void getfontsize(Slide *s, unsigned int *width, unsigned int *height);
-static void cleanup(int slidesonly);
-static void reload(const Arg *arg);
-static void load(FILE *fp);
-static void advance(const Arg *arg);
-static void toggle_theme(const Arg *arg);
-static void quit(const Arg *arg);
-static void resize(int width, int height);
-static void run();
-static void usage();
-static void xdraw();
-static void xhints();
-static void xinit();
-static void xloadfonts();
-
-static void bpress(XEvent *);
-static void cmessage(XEvent *);
-static void expose(XEvent *);
-static void kpress(XEvent *);
-static void configure(XEvent *);
-
-/* config.h for applying patches and the configuration. */
-#include "config.h"
-
-/* Globals */
-static const char *fname = NULL;
-static Slide *slides = NULL;
-static int idx = 0;
-static int slidecount = 0;
-static XWindow xw;
-static Drw *d = NULL;
-static Clr *sc;
-static Fnt *fonts[NUMFONTSCALES];
-static int running = 1;
-
-static void (*handler[LASTEvent])(XEvent *) = {
- [ButtonPress] = bpress,
- [ClientMessage] = cmessage,
- [ConfigureNotify] = configure,
- [Expose] = expose,
- [KeyPress] = kpress,
-};
-
-int
-filter(int fd, const char *cmd)
-{
- int fds[2];
-
- if (pipe(fds) < 0)
- die("sent: Unable to create pipe:");
-
- switch (fork()) {
- case -1:
- die("sent: Unable to fork:");
- case 0:
- dup2(fd, 0);
- dup2(fds[1], 1);
- close(fds[0]);
- close(fds[1]);
- execlp("sh", "sh", "-c", cmd, (char *)0);
- fprintf(stderr, "sent: execlp sh -c '%s': %s\n", cmd, strerror(errno));
- _exit(1);
- }
- close(fds[1]);
- return fds[0];
-}
-
-void
-fffree(Image *img)
-{
- free(img->buf);
- if (img->ximg)
- XDestroyImage(img->ximg);
- free(img);
-}
-
-void
-ffload(Slide *s)
-{
- uint32_t y, x;
- uint16_t *row;
- uint8_t opac, fg_r, fg_g, fg_b, bg_r, bg_g, bg_b;
- size_t rowlen, off, nbytes, i;
- ssize_t count;
- unsigned char hdr[16];
- char *bin = NULL;
- char *filename;
- regex_t regex;
- int fdin, fdout;
-
- if (s->img || !(filename = s->embed) || !s->embed[0])
- return; /* already done */
-
- for (i = 0; i < LEN(filters); i++) {
- if (regcomp(&regex, filters[i].regex,
- REG_NOSUB | REG_EXTENDED | REG_ICASE)) {
- fprintf(stderr, "sent: Invalid regex '%s'\n", filters[i].regex);
- continue;
- }
- if (!regexec(&regex, filename, 0, NULL, 0)) {
- bin = filters[i].bin;
- regfree(&regex);
- break;
- }
- regfree(&regex);
- }
- if (!bin)
- die("sent: Unable to find matching filter for '%s'", filename);
-
- if ((fdin = open(filename, O_RDONLY)) < 0)
- die("sent: Unable to open '%s':", filename);
-
- if ((fdout = filter(fdin, bin)) < 0)
- die("sent: Unable to filter '%s':", filename);
- close(fdin);
-
- if (read(fdout, hdr, 16) != 16)
- die("sent: Unable to read filtered file '%s':", filename);
- if (memcmp("farbfeld", hdr, 8))
- die("sent: Filtered file '%s' has no valid farbfeld header", filename);
-
- s->img = ecalloc(1, sizeof(Image));
- s->img->bufwidth = ntohl(*(uint32_t *)&hdr[8]);
- s->img->bufheight = ntohl(*(uint32_t *)&hdr[12]);
-
- if (s->img->buf)
- free(s->img->buf);
- /* internally the image is stored in 888 format */
- s->img->buf = ecalloc(s->img->bufwidth * s->img->bufheight, strlen("888"));
-
- /* scratch buffer to read row by row */
- rowlen = s->img->bufwidth * 2 * strlen("RGBA");
- row = ecalloc(1, rowlen);
-
- /* extract window background color channels for transparency */
- bg_r = (sc[ColBg].pixel >> 16) % 256;
- bg_g = (sc[ColBg].pixel >> 8) % 256;
- bg_b = (sc[ColBg].pixel >> 0) % 256;
-
- for (off = 0, y = 0; y < s->img->bufheight; y++) {
- nbytes = 0;
- while (nbytes < rowlen) {
- count = read(fdout, (char *)row + nbytes, rowlen - nbytes);
- if (count < 0)
- die("sent: Unable to read from pipe:");
- nbytes += count;
- }
- for (x = 0; x < rowlen / 2; x += 4) {
- fg_r = ntohs(row[x + 0]) / 257;
- fg_g = ntohs(row[x + 1]) / 257;
- fg_b = ntohs(row[x + 2]) / 257;
- opac = ntohs(row[x + 3]) / 257;
- /* blend opaque part of image data with window background color to
- * emulate transparency */
- s->img->buf[off++] = (fg_r * opac + bg_r * (255 - opac)) / 255;
- s->img->buf[off++] = (fg_g * opac + bg_g * (255 - opac)) / 255;
- s->img->buf[off++] = (fg_b * opac + bg_b * (255 - opac)) / 255;
- }
- }
-
- free(row);
- close(fdout);
-}
-
-void
-ffprepare(Image *img)
-{
- int depth = DefaultDepth(xw.dpy, xw.scr);
- int width = xw.uw;
- int height = xw.uh;
-
- if (xw.uw * img->bufheight > xw.uh * img->bufwidth)
- width = img->bufwidth * xw.uh / img->bufheight;
- else
- height = img->bufheight * xw.uw / img->bufwidth;
-
- if (depth < 24)
- die("sent: Display color depths < 24 not supported");
-
- if (!(img->ximg = XCreateImage(xw.dpy, CopyFromParent, depth, ZPixmap, 0,
- NULL, width, height, 32, 0)))
- die("sent: Unable to create XImage");
-
- img->ximg->data = ecalloc(height, img->ximg->bytes_per_line);
- if (!XInitImage(img->ximg))
- die("sent: Unable to initiate XImage");
-
- ffscale(img);
- img->state |= SCALED;
-}
-
-void
-ffscale(Image *img)
-{
- unsigned int x, y;
- unsigned int width = img->ximg->width;
- unsigned int height = img->ximg->height;
- char* newBuf = img->ximg->data;
- unsigned char* ibuf;
- unsigned int jdy = img->ximg->bytes_per_line / 4 - width;
- unsigned int dx = (img->bufwidth << 10) / width;
-
- for (y = 0; y < height; y++) {
- unsigned int bufx = img->bufwidth / width;
- ibuf = &img->buf[y * img->bufheight / height * img->bufwidth * 3];
-
- for (x = 0; x < width; x++) {
- *newBuf++ = (ibuf[(bufx >> 10)*3+2]);
- *newBuf++ = (ibuf[(bufx >> 10)*3+1]);
- *newBuf++ = (ibuf[(bufx >> 10)*3+0]);
- newBuf++;
- bufx += dx;
- }
- newBuf += jdy;
- }
-}
-
-void
-ffdraw(Image *img)
-{
- int xoffset = (xw.w - img->ximg->width) / 2;
- int yoffset = (xw.h - img->ximg->height) / 2;
- XPutImage(xw.dpy, xw.win, d->gc, img->ximg, 0, 0,
- xoffset, yoffset, img->ximg->width, img->ximg->height);
- XFlush(xw.dpy);
-}
-
-void
-getfontsize(Slide *s, unsigned int *width, unsigned int *height)
-{
- int i, j;
- unsigned int curw, newmax;
- float lfac = linespacing * (s->linecount - 1) + 1;
-
- /* fit height */
- for (j = NUMFONTSCALES - 1; j >= 0; j--)
- if (fonts[j]->h * lfac <= xw.uh)
- break;
- LIMIT(j, 0, NUMFONTSCALES - 1);
- drw_setfontset(d, fonts[j]);
-
- /* fit width */
- *width = 0;
- for (i = 0; i < s->linecount; i++) {
- curw = drw_fontset_getwidth(d, s->lines[i]);
- newmax = (curw >= *width);
- while (j > 0 && curw > xw.uw) {
- drw_setfontset(d, fonts[--j]);
- curw = drw_fontset_getwidth(d, s->lines[i]);
- }
- if (newmax)
- *width = curw;
- }
- *height = fonts[j]->h * lfac;
-}
-
-void
-cleanup(int slidesonly)
-{
- unsigned int i, j;
-
- if (!slidesonly) {
- for (i = 0; i < NUMFONTSCALES; i++)
- drw_fontset_free(fonts[i]);
- free(sc);
- drw_free(d);
-
- XDestroyWindow(xw.dpy, xw.win);
- XSync(xw.dpy, False);
- XCloseDisplay(xw.dpy);
- }
-
- if (slides) {
- for (i = 0; i < slidecount; i++) {
- for (j = 0; j < slides[i].linecount; j++)
- free(slides[i].lines[j]);
- free(slides[i].lines);
- if (slides[i].img)
- fffree(slides[i].img);
- }
- if (!slidesonly) {
- free(slides);
- slides = NULL;
- }
- }
-}
-
-void
-reload(const Arg *arg)
-{
- FILE *fp = NULL;
- unsigned int i;
-
- if (!fname) {
- fprintf(stderr, "sent: Cannot reload from stdin. Use a file!\n");
- return;
- }
-
- cleanup(1);
- slidecount = 0;
-
- if (!(fp = fopen(fname, "r")))
- die("sent: Unable to open '%s' for reading:", fname);
- load(fp);
- fclose(fp);
-
- LIMIT(idx, 0, slidecount-1);
- for (i = 0; i < slidecount; i++)
- ffload(&slides[i]);
- xdraw();
-}
-
-void
-load(FILE *fp)
-{
- static size_t size = 0;
- size_t blen, maxlines;
- char buf[BUFSIZ], *p;
- Slide *s;
-
- /* read each line from fp and add it to the item list */
- while (1) {
- /* eat consecutive empty lines */
- while ((p = fgets(buf, sizeof(buf), fp)))
- if (strcmp(buf, "\n") != 0 && buf[0] != '#')
- break;
- if (!p)
- break;
-
- if ((slidecount+1) * sizeof(*slides) >= size)
- if (!(slides = realloc(slides, (size += BUFSIZ))))
- die("sent: Unable to reallocate %u bytes:", size);
-
- /* read one slide */
- maxlines = 0;
- memset((s = &slides[slidecount]), 0, sizeof(Slide));
- do {
- /* if there's a leading null, we can't do blen-1 */
- if (buf[0] == '\0')
- continue;
-
- if (buf[0] == '#')
- continue;
-
- /* grow lines array */
- if (s->linecount >= maxlines) {
- maxlines = 2 * s->linecount + 1;
- if (!(s->lines = realloc(s->lines, maxlines * sizeof(s->lines[0]))))
- die("sent: Unable to reallocate %u bytes:", maxlines * sizeof(s->lines[0]));
- }
-
- blen = strlen(buf);
- if (!(s->lines[s->linecount] = strdup(buf)))
- die("sent: Unable to strdup:");
- if (s->lines[s->linecount][blen-1] == '\n')
- s->lines[s->linecount][blen-1] = '\0';
-
- /* mark as image slide if first line of a slide starts with @ */
- if (s->linecount == 0 && s->lines[0][0] == '@')
- s->embed = &s->lines[0][1];
-
- if (s->lines[s->linecount][0] == '\\')
- memmove(s->lines[s->linecount], &s->lines[s->linecount][1], blen);
- s->linecount++;
- } while ((p = fgets(buf, sizeof(buf), fp)) && strcmp(buf, "\n") != 0);
-
- slidecount++;
- if (!p)
- break;
- }
-
- if (!slidecount)
- die("sent: No slides in file");
-}
-
-void
-advance(const Arg *arg)
-{
- int new_idx = idx + arg->i;
- LIMIT(new_idx, 0, slidecount-1);
- if (new_idx != idx) {
- if (slides[idx].img)
- slides[idx].img->state &= ~SCALED;
- idx = new_idx;
- xdraw();
- }
-}
-
-void
-toggle_theme(const Arg *arg)
-{
- use_dark_scheme ^= 1;
- if (use_dark_scheme)
- sc = drw_scm_create(d, dark_colors, 2);
- else
- sc = drw_scm_create(d, colors, 2);
- drw_setscheme(d, sc);
- reload(NULL);
-}
-
-void
-quit(const Arg *arg)
-{
- running = 0;
-}
-
-void
-resize(int width, int height)
-{
- xw.w = width;
- xw.h = height;
- xw.uw = usablewidth * width;
- xw.uh = usableheight * height;
- drw_resize(d, width, height);
-}
-
-void
-run()
-{
- XEvent ev;
-
- /* Waiting for window mapping */
- while (1) {
- XNextEvent(xw.dpy, &ev);
- if (ev.type == ConfigureNotify) {
- resize(ev.xconfigure.width, ev.xconfigure.height);
- } else if (ev.type == MapNotify) {
- break;
- }
- }
-
- while (running) {
- XNextEvent(xw.dpy, &ev);
- if (handler[ev.type])
- (handler[ev.type])(&ev);
- }
-}
-
-void
-xdraw()
-{
- unsigned int height, width, i;
- Image *im = slides[idx].img;
-
- getfontsize(&slides[idx], &width, &height);
- XClearWindow(xw.dpy, xw.win);
-
- if (!im) {
- drw_rect(d, 0, 0, xw.w, xw.h, 1, 1);
- for (i = 0; i < slides[idx].linecount; i++)
- drw_text(d,
- (xw.w - width) / 2,
- (xw.h - height) / 2 + i * linespacing * d->fonts->h,
- width,
- d->fonts->h,
- 0,
- slides[idx].lines[i],
- 0);
- drw_map(d, xw.win, 0, 0, xw.w, xw.h);
- } else {
- if (!(im->state & SCALED))
- ffprepare(im);
- ffdraw(im);
- }
-}
-
-void
-xhints()
-{
- XClassHint class = {.res_name = "sent", .res_class = "presenter"};
- XWMHints wm = {.flags = InputHint, .input = True};
- XSizeHints *sizeh = NULL;
-
- if (!(sizeh = XAllocSizeHints()))
- die("sent: Unable to allocate size hints");
-
- sizeh->flags = PSize;
- sizeh->height = xw.h;
- sizeh->width = xw.w;
-
- XSetWMProperties(xw.dpy, xw.win, NULL, NULL, NULL, 0, sizeh, &wm, &class);
- XFree(sizeh);
-}
-
-void
-xinit()
-{
- XTextProperty prop;
- unsigned int i;
-
- if (!(xw.dpy = XOpenDisplay(NULL)))
- die("sent: Unable to open display");
- xw.scr = XDefaultScreen(xw.dpy);
- xw.vis = XDefaultVisual(xw.dpy, xw.scr);
- resize(DisplayWidth(xw.dpy, xw.scr), DisplayHeight(xw.dpy, xw.scr));
-
- xw.attrs.bit_gravity = CenterGravity;
- xw.attrs.event_mask = KeyPressMask | ExposureMask | StructureNotifyMask |
- ButtonMotionMask | ButtonPressMask;
-
- xw.win = XCreateWindow(xw.dpy, XRootWindow(xw.dpy, xw.scr), 0, 0,
- xw.w, xw.h, 0, XDefaultDepth(xw.dpy, xw.scr),
- InputOutput, xw.vis, CWBitGravity | CWEventMask,
- &xw.attrs);
-
- xw.wmdeletewin = XInternAtom(xw.dpy, "WM_DELETE_WINDOW", False);
- xw.netwmname = XInternAtom(xw.dpy, "_NET_WM_NAME", False);
- XSetWMProtocols(xw.dpy, xw.win, &xw.wmdeletewin, 1);
-
- if (!(d = drw_create(xw.dpy, xw.scr, xw.win, xw.w, xw.h)))
- die("sent: Unable to create drawing context");
-
- if (use_dark_scheme)
- sc = drw_scm_create(d, dark_colors, 2);
- else
- sc = drw_scm_create(d, colors, 2);
- drw_setscheme(d, sc);
- XSetWindowBackground(xw.dpy, xw.win, sc[ColBg].pixel);
-
- xloadfonts();
- for (i = 0; i < slidecount; i++)
- ffload(&slides[i]);
-
- XStringListToTextProperty(&argv0, 1, &prop);
- XSetWMName(xw.dpy, xw.win, &prop);
- XSetTextProperty(xw.dpy, xw.win, &prop, xw.netwmname);
- XFree(prop.value);
- XMapWindow(xw.dpy, xw.win);
- xhints();
- XSync(xw.dpy, False);
-}
-
-void
-xloadfonts()
-{
- int i, j;
- char *fstrs[LEN(fontfallbacks)];
-
- for (j = 0; j < LEN(fontfallbacks); j++) {
- fstrs[j] = ecalloc(1, MAXFONTSTRLEN);
- }
-
- for (i = 0; i < NUMFONTSCALES; i++) {
- for (j = 0; j < LEN(fontfallbacks); j++) {
- if (MAXFONTSTRLEN < snprintf(fstrs[j], MAXFONTSTRLEN, "%s:size=%d", fontfallbacks[j], FONTSZ(i)))
- die("sent: Font string too long");
- }
- if (!(fonts[i] = drw_fontset_create(d, (const char**)fstrs, LEN(fstrs))))
- die("sent: Unable to load any font for size %d", FONTSZ(i));
- }
-
- for (j = 0; j < LEN(fontfallbacks); j++)
- if (fstrs[j])
- free(fstrs[j]);
-}
-
-void
-bpress(XEvent *e)
-{
- unsigned int i;
-
- for (i = 0; i < LEN(mshortcuts); i++)
- if (e->xbutton.button == mshortcuts[i].b && mshortcuts[i].func)
- mshortcuts[i].func(&(mshortcuts[i].arg));
-}
-
-void
-cmessage(XEvent *e)
-{
- if (e->xclient.data.l[0] == xw.wmdeletewin)
- running = 0;
-}
-
-void
-expose(XEvent *e)
-{
- if (0 == e->xexpose.count)
- xdraw();
-}
-
-void
-kpress(XEvent *e)
-{
- unsigned int i;
- KeySym sym;
-
- sym = XkbKeycodeToKeysym(xw.dpy, (KeyCode)e->xkey.keycode, 0, 0);
- for (i = 0; i < LEN(shortcuts); i++)
- if (sym == shortcuts[i].keysym && shortcuts[i].func)
- shortcuts[i].func(&(shortcuts[i].arg));
-}
-
-void
-configure(XEvent *e)
-{
- resize(e->xconfigure.width, e->xconfigure.height);
- if (slides[idx].img)
- slides[idx].img->state &= ~SCALED;
- xdraw();
-}
-
-void
-usage()
-{
- die("usage: %s [file]", argv0);
-}
-
-int
-main(int argc, char *argv[])
-{
- FILE *fp = NULL;
-
- ARGBEGIN {
- case 'v':
- fprintf(stderr, "sent-"VERSION"\n");
- return 0;
- case 'd':
- use_dark_scheme = 1;
- break;
- default:
- usage();
- } ARGEND
-
- if (!argv[0] || !strcmp(argv[0], "-"))
- fp = stdin;
- else if (!(fp = fopen(fname = argv[0], "r")))
- die("sent: Unable to open '%s' for reading:", fname);
- load(fp);
- fclose(fp);
-
- xinit();
- run();
-
- cleanup(0);
- return 0;
-}
diff --git a/.repos/sent/util.c b/.repos/sent/util.c
deleted file mode 100644
index fe044fc..0000000
--- a/.repos/sent/util.c
+++ /dev/null
@@ -1,35 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "util.h"
-
-void *
-ecalloc(size_t nmemb, size_t size)
-{
- void *p;
-
- if (!(p = calloc(nmemb, size)))
- die("calloc:");
- return p;
-}
-
-void
-die(const char *fmt, ...) {
- va_list ap;
-
- va_start(ap, fmt);
- vfprintf(stderr, fmt, ap);
- va_end(ap);
-
- if (fmt[0] && fmt[strlen(fmt)-1] == ':') {
- fputc(' ', stderr);
- perror(NULL);
- } else {
- fputc('\n', stderr);
- }
-
- exit(1);
-}
diff --git a/.repos/sent/util.h b/.repos/sent/util.h
deleted file mode 100644
index f633b51..0000000
--- a/.repos/sent/util.h
+++ /dev/null
@@ -1,8 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-
-#define MAX(A, B) ((A) > (B) ? (A) : (B))
-#define MIN(A, B) ((A) < (B) ? (A) : (B))
-#define BETWEEN(X, A, B) ((A) <= (X) && (X) <= (B))
-
-void die(const char *fmt, ...);
-void *ecalloc(size_t nmemb, size_t size);
diff --git a/.repos/slock/LICENSE b/.repos/slock/LICENSE
deleted file mode 100644
index 2e4419b..0000000
--- a/.repos/slock/LICENSE
+++ /dev/null
@@ -1,24 +0,0 @@
-MIT/X Consortium License
-
-© 2015-2016 Markus Teich <markus.teich@stusta.mhn.de>
-© 2014 Dimitris Papastamos <sin@2f30.org>
-© 2006-2014 Anselm R Garbe <anselm@garbe.us>
-© 2014-2016 Laslo Hunhold <dev@frign.de>
-
-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/.repos/slock/Makefile b/.repos/slock/Makefile
deleted file mode 100644
index f4ffbb7..0000000
--- a/.repos/slock/Makefile
+++ /dev/null
@@ -1,61 +0,0 @@
-# slock - simple screen locker
-# See LICENSE file for copyright and license details.
-
-include config.mk
-
-SRC = slock.c ${COMPATSRC}
-OBJ = ${SRC:.c=.o}
-
-all: options slock
-
-options:
- @echo slock build options:
- @echo "CFLAGS = ${CFLAGS}"
- @echo "LDFLAGS = ${LDFLAGS}"
- @echo "CC = ${CC}"
-
-.c.o:
- @echo CC $<
- @${CC} -c ${CFLAGS} $<
-
-${OBJ}: config.h config.mk arg.h util.h
-
-config.h:
- @echo creating $@ from config.def.h
- @cp config.def.h $@
-
-slock: ${OBJ}
- @echo CC -o $@
- @${CC} -o $@ ${OBJ} ${LDFLAGS}
-
-clean:
- @echo cleaning
- @rm -f slock ${OBJ} slock-${VERSION}.tar.gz
-
-dist: clean
- @echo creating dist tarball
- @mkdir -p slock-${VERSION}
- @cp -R LICENSE Makefile README slock.1 config.mk \
- ${SRC} explicit_bzero.c config.def.h arg.h util.h slock-${VERSION}
- @tar -cf slock-${VERSION}.tar slock-${VERSION}
- @gzip slock-${VERSION}.tar
- @rm -rf slock-${VERSION}
-
-install: all
- @echo installing executable file to ${DESTDIR}${PREFIX}/bin
- @mkdir -p ${DESTDIR}${PREFIX}/bin
- @cp -f slock ${DESTDIR}${PREFIX}/bin
- @chmod 755 ${DESTDIR}${PREFIX}/bin/slock
- @chmod u+s ${DESTDIR}${PREFIX}/bin/slock
- @echo installing manual page to ${DESTDIR}${MANPREFIX}/man1
- @mkdir -p ${DESTDIR}${MANPREFIX}/man1
- @sed "s/VERSION/${VERSION}/g" <slock.1 >${DESTDIR}${MANPREFIX}/man1/slock.1
- @chmod 644 ${DESTDIR}${MANPREFIX}/man1/slock.1
-
-uninstall:
- @echo removing executable file from ${DESTDIR}${PREFIX}/bin
- @rm -f ${DESTDIR}${PREFIX}/bin/slock
- @echo removing manual page from ${DESTDIR}${MANPREFIX}/man1
- @rm -f ${DESTDIR}${MANPREFIX}/man1/slock.1
-
-.PHONY: all options clean dist install uninstall
diff --git a/.repos/slock/README b/.repos/slock/README
deleted file mode 100644
index dcacd01..0000000
--- a/.repos/slock/README
+++ /dev/null
@@ -1,24 +0,0 @@
-slock - simple screen locker
-============================
-simple screen locker utility for X.
-
-
-Requirements
-------------
-In order to build slock you need the Xlib header files.
-
-
-Installation
-------------
-Edit config.mk to match your local setup (slock is installed into
-the /usr/local namespace by default).
-
-Afterwards enter the following command to build and install slock
-(if necessary as root):
-
- make clean install
-
-
-Running slock
--------------
-Simply invoke the 'slock' command. To get out of it, enter your password.
diff --git a/.repos/slock/arg.h b/.repos/slock/arg.h
deleted file mode 100644
index 0b23c53..0000000
--- a/.repos/slock/arg.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * 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_)
-
-/* Handles obsolete -NUM syntax */
-#define ARGNUM case '0':\
- case '1':\
- case '2':\
- case '3':\
- case '4':\
- case '5':\
- case '6':\
- case '7':\
- case '8':\
- case '9'
-
-#define ARGEND }\
- }
-
-#define ARGC() argc_
-
-#define ARGNUMF() (brk_ = 1, estrtonum(argv[0], 0, INT_MAX))
-
-#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])))
-
-#define LNGARG() &argv[0][0]
-
-#endif
diff --git a/.repos/slock/config.def.h b/.repos/slock/config.def.h
deleted file mode 100644
index 9855e21..0000000
--- a/.repos/slock/config.def.h
+++ /dev/null
@@ -1,12 +0,0 @@
-/* user and group to drop privileges to */
-static const char *user = "nobody";
-static const char *group = "nogroup";
-
-static const char *colorname[NUMCOLS] = {
- [INIT] = "black", /* after initialization */
- [INPUT] = "#005577", /* during input */
- [FAILED] = "#CC3333", /* wrong password */
-};
-
-/* treat a cleared input like a wrong password (color) */
-static const int failonclear = 1;
diff --git a/.repos/slock/config.h b/.repos/slock/config.h
deleted file mode 100644
index 9855e21..0000000
--- a/.repos/slock/config.h
+++ /dev/null
@@ -1,12 +0,0 @@
-/* user and group to drop privileges to */
-static const char *user = "nobody";
-static const char *group = "nogroup";
-
-static const char *colorname[NUMCOLS] = {
- [INIT] = "black", /* after initialization */
- [INPUT] = "#005577", /* during input */
- [FAILED] = "#CC3333", /* wrong password */
-};
-
-/* treat a cleared input like a wrong password (color) */
-static const int failonclear = 1;
diff --git a/.repos/slock/config.mk b/.repos/slock/config.mk
deleted file mode 100644
index 74429ae..0000000
--- a/.repos/slock/config.mk
+++ /dev/null
@@ -1,32 +0,0 @@
-# slock version
-VERSION = 1.4
-
-# Customize below to fit your system
-
-# paths
-PREFIX = /usr/local
-MANPREFIX = ${PREFIX}/share/man
-
-X11INC = /usr/X11R6/include
-X11LIB = /usr/X11R6/lib
-
-# includes and libs
-INCS = -I. -I/usr/include -I${X11INC}
-LIBS = -L/usr/lib -lc -lcrypt -L${X11LIB} -lX11 -lXext -lXrandr
-
-# flags
-CPPFLAGS = -DVERSION=\"${VERSION}\" -D_DEFAULT_SOURCE -DHAVE_SHADOW_H
-CFLAGS = -std=c99 -pedantic -Wall -Os ${INCS} ${CPPFLAGS}
-LDFLAGS = -s ${LIBS}
-COMPATSRC = explicit_bzero.c
-
-# On OpenBSD and Darwin remove -lcrypt from LIBS
-#LIBS = -L/usr/lib -lc -L${X11LIB} -lX11 -lXext -lXrandr
-# On *BSD remove -DHAVE_SHADOW_H from CPPFLAGS
-# On NetBSD add -D_NETBSD_SOURCE to CPPFLAGS
-#CPPFLAGS = -DVERSION=\"${VERSION}\" -D_BSD_SOURCE -D_NETBSD_SOURCE
-# On OpenBSD set COMPATSRC to empty
-#COMPATSRC =
-
-# compiler and linker
-CC = cc
diff --git a/.repos/slock/explicit_bzero.c b/.repos/slock/explicit_bzero.c
deleted file mode 100644
index 3e33ca8..0000000
--- a/.repos/slock/explicit_bzero.c
+++ /dev/null
@@ -1,19 +0,0 @@
-/* $OpenBSD: explicit_bzero.c,v 1.3 2014/06/21 02:34:26 matthew Exp $ */
-/*
- * Public domain.
- * Written by Matthew Dempsky.
- */
-
-#include <string.h>
-
-__attribute__((weak)) void
-__explicit_bzero_hook(void *buf, size_t len)
-{
-}
-
-void
-explicit_bzero(void *buf, size_t len)
-{
- memset(buf, 0, len);
- __explicit_bzero_hook(buf, len);
-}
diff --git a/.repos/slock/slock.1 b/.repos/slock/slock.1
deleted file mode 100644
index 82cdcd6..0000000
--- a/.repos/slock/slock.1
+++ /dev/null
@@ -1,39 +0,0 @@
-.Dd 2016-08-23
-.Dt SLOCK 1
-.Sh NAME
-.Nm slock
-.Nd simple X screen locker
-.Sh SYNOPSIS
-.Nm
-.Op Fl v
-.Op Ar cmd Op Ar arg ...
-.Sh DESCRIPTION
-.Nm
-is a simple X screen locker. If provided,
-.Ar cmd Op Ar arg ...
-is executed after the screen has been locked.
-.Sh OPTIONS
-.Bl -tag -width Ds
-.It Fl v
-Print version information to stdout and exit.
-.El
-.Sh SECURITY CONSIDERATIONS
-To make sure a locked screen can not be bypassed by switching VTs
-or killing the X server with Ctrl+Alt+Backspace, it is recommended
-to disable both in
-.Xr xorg.conf 5
-for maximum security:
-.Bd -literal -offset left
-Section "ServerFlags"
- Option "DontVTSwitch" "True"
- Option "DontZap" "True"
-EndSection
-.Ed
-.Sh EXAMPLES
-$
-.Nm
-/usr/sbin/s2ram
-.Sh CUSTOMIZATION
-.Nm
-can be customized by creating a custom config.h from config.def.h and
-(re)compiling the source code. This keeps it fast, secure and simple.
diff --git a/.repos/slock/slock.c b/.repos/slock/slock.c
deleted file mode 100644
index 5ae738c..0000000
--- a/.repos/slock/slock.c
+++ /dev/null
@@ -1,395 +0,0 @@
-/* See LICENSE file for license details. */
-#define _XOPEN_SOURCE 500
-#if HAVE_SHADOW_H
-#include <shadow.h>
-#endif
-
-#include <ctype.h>
-#include <errno.h>
-#include <grp.h>
-#include <pwd.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <X11/extensions/Xrandr.h>
-#include <X11/keysym.h>
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-
-#include "arg.h"
-#include "util.h"
-
-char *argv0;
-
-enum {
- INIT,
- INPUT,
- FAILED,
- NUMCOLS
-};
-
-struct lock {
- int screen;
- Window root, win;
- Pixmap pmap;
- unsigned long colors[NUMCOLS];
-};
-
-struct xrandr {
- int active;
- int evbase;
- int errbase;
-};
-
-#include "config.h"
-
-static void
-die(const char *errstr, ...)
-{
- va_list ap;
-
- va_start(ap, errstr);
- vfprintf(stderr, errstr, ap);
- va_end(ap);
- exit(1);
-}
-
-#ifdef __linux__
-#include <fcntl.h>
-#include <linux/oom.h>
-
-static void
-dontkillme(void)
-{
- FILE *f;
- const char oomfile[] = "/proc/self/oom_score_adj";
-
- if (!(f = fopen(oomfile, "w"))) {
- if (errno == ENOENT)
- return;
- die("slock: fopen %s: %s\n", oomfile, strerror(errno));
- }
- fprintf(f, "%d", OOM_SCORE_ADJ_MIN);
- if (fclose(f)) {
- if (errno == EACCES)
- die("slock: unable to disable OOM killer. "
- "Make sure to suid or sgid slock.\n");
- else
- die("slock: fclose %s: %s\n", oomfile, strerror(errno));
- }
-}
-#endif
-
-static const char *
-gethash(void)
-{
- const char *hash;
- struct passwd *pw;
-
- /* Check if the current user has a password entry */
- errno = 0;
- if (!(pw = getpwuid(getuid()))) {
- if (errno)
- die("slock: getpwuid: %s\n", strerror(errno));
- else
- die("slock: cannot retrieve password entry\n");
- }
- hash = pw->pw_passwd;
-
-#if HAVE_SHADOW_H
- if (!strcmp(hash, "x")) {
- struct spwd *sp;
- if (!(sp = getspnam(pw->pw_name)))
- die("slock: getspnam: cannot retrieve shadow entry. "
- "Make sure to suid or sgid slock.\n");
- hash = sp->sp_pwdp;
- }
-#else
- if (!strcmp(hash, "*")) {
-#ifdef __OpenBSD__
- if (!(pw = getpwuid_shadow(getuid())))
- die("slock: getpwnam_shadow: cannot retrieve shadow entry. "
- "Make sure to suid or sgid slock.\n");
- hash = pw->pw_passwd;
-#else
- die("slock: getpwuid: cannot retrieve shadow entry. "
- "Make sure to suid or sgid slock.\n");
-#endif /* __OpenBSD__ */
- }
-#endif /* HAVE_SHADOW_H */
-
- return hash;
-}
-
-static void
-readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens,
- const char *hash)
-{
- XRRScreenChangeNotifyEvent *rre;
- char buf[32], passwd[256], *inputhash;
- int num, screen, running, failure, oldc;
- unsigned int len, color;
- KeySym ksym;
- XEvent ev;
-
- len = 0;
- running = 1;
- failure = 0;
- oldc = INIT;
-
- while (running && !XNextEvent(dpy, &ev)) {
- if (ev.type == KeyPress) {
- explicit_bzero(&buf, sizeof(buf));
- num = XLookupString(&ev.xkey, buf, sizeof(buf), &ksym, 0);
- if (IsKeypadKey(ksym)) {
- if (ksym == XK_KP_Enter)
- ksym = XK_Return;
- else if (ksym >= XK_KP_0 && ksym <= XK_KP_9)
- ksym = (ksym - XK_KP_0) + XK_0;
- }
- if (IsFunctionKey(ksym) ||
- IsKeypadKey(ksym) ||
- IsMiscFunctionKey(ksym) ||
- IsPFKey(ksym) ||
- IsPrivateKeypadKey(ksym))
- continue;
- switch (ksym) {
- case XK_Return:
- passwd[len] = '\0';
- errno = 0;
- if (!(inputhash = crypt(passwd, hash)))
- fprintf(stderr, "slock: crypt: %s\n", strerror(errno));
- else
- running = !!strcmp(inputhash, hash);
- if (running) {
- XBell(dpy, 100);
- failure = 1;
- }
- explicit_bzero(&passwd, sizeof(passwd));
- len = 0;
- break;
- case XK_Escape:
- explicit_bzero(&passwd, sizeof(passwd));
- len = 0;
- break;
- case XK_BackSpace:
- if (len)
- passwd[--len] = '\0';
- break;
- default:
- if (num && !iscntrl((int)buf[0]) &&
- (len + num < sizeof(passwd))) {
- memcpy(passwd + len, buf, num);
- len += num;
- }
- break;
- }
- color = len ? INPUT : ((failure || failonclear) ? FAILED : INIT);
- if (running && oldc != color) {
- for (screen = 0; screen < nscreens; screen++) {
- XSetWindowBackground(dpy,
- locks[screen]->win,
- locks[screen]->colors[color]);
- XClearWindow(dpy, locks[screen]->win);
- }
- oldc = color;
- }
- } else if (rr->active && ev.type == rr->evbase + RRScreenChangeNotify) {
- rre = (XRRScreenChangeNotifyEvent*)&ev;
- for (screen = 0; screen < nscreens; screen++) {
- if (locks[screen]->win == rre->window) {
- if (rre->rotation == RR_Rotate_90 ||
- rre->rotation == RR_Rotate_270)
- XResizeWindow(dpy, locks[screen]->win,
- rre->height, rre->width);
- else
- XResizeWindow(dpy, locks[screen]->win,
- rre->width, rre->height);
- XClearWindow(dpy, locks[screen]->win);
- break;
- }
- }
- } else {
- for (screen = 0; screen < nscreens; screen++)
- XRaiseWindow(dpy, locks[screen]->win);
- }
- }
-}
-
-static struct lock *
-lockscreen(Display *dpy, struct xrandr *rr, int screen)
-{
- char curs[] = {0, 0, 0, 0, 0, 0, 0, 0};
- int i, ptgrab, kbgrab;
- struct lock *lock;
- XColor color, dummy;
- XSetWindowAttributes wa;
- Cursor invisible;
-
- if (dpy == NULL || screen < 0 || !(lock = malloc(sizeof(struct lock))))
- return NULL;
-
- lock->screen = screen;
- lock->root = RootWindow(dpy, lock->screen);
-
- for (i = 0; i < NUMCOLS; i++) {
- XAllocNamedColor(dpy, DefaultColormap(dpy, lock->screen),
- colorname[i], &color, &dummy);
- lock->colors[i] = color.pixel;
- }
-
- /* init */
- wa.override_redirect = 1;
- wa.background_pixel = lock->colors[INIT];
- lock->win = XCreateWindow(dpy, lock->root, 0, 0,
- DisplayWidth(dpy, lock->screen),
- DisplayHeight(dpy, lock->screen),
- 0, DefaultDepth(dpy, lock->screen),
- CopyFromParent,
- DefaultVisual(dpy, lock->screen),
- CWOverrideRedirect | CWBackPixel, &wa);
- lock->pmap = XCreateBitmapFromData(dpy, lock->win, curs, 8, 8);
- invisible = XCreatePixmapCursor(dpy, lock->pmap, lock->pmap,
- &color, &color, 0, 0);
- XDefineCursor(dpy, lock->win, invisible);
-
- /* Try to grab mouse pointer *and* keyboard for 600ms, else fail the lock */
- for (i = 0, ptgrab = kbgrab = -1; i < 6; i++) {
- if (ptgrab != GrabSuccess) {
- ptgrab = XGrabPointer(dpy, lock->root, False,
- ButtonPressMask | ButtonReleaseMask |
- PointerMotionMask, GrabModeAsync,
- GrabModeAsync, None, invisible, CurrentTime);
- }
- if (kbgrab != GrabSuccess) {
- kbgrab = XGrabKeyboard(dpy, lock->root, True,
- GrabModeAsync, GrabModeAsync, CurrentTime);
- }
-
- /* input is grabbed: we can lock the screen */
- if (ptgrab == GrabSuccess && kbgrab == GrabSuccess) {
- XMapRaised(dpy, lock->win);
- if (rr->active)
- XRRSelectInput(dpy, lock->win, RRScreenChangeNotifyMask);
-
- XSelectInput(dpy, lock->root, SubstructureNotifyMask);
- return lock;
- }
-
- /* retry on AlreadyGrabbed but fail on other errors */
- if ((ptgrab != AlreadyGrabbed && ptgrab != GrabSuccess) ||
- (kbgrab != AlreadyGrabbed && kbgrab != GrabSuccess))
- break;
-
- usleep(100000);
- }
-
- /* we couldn't grab all input: fail out */
- if (ptgrab != GrabSuccess)
- fprintf(stderr, "slock: unable to grab mouse pointer for screen %d\n",
- screen);
- if (kbgrab != GrabSuccess)
- fprintf(stderr, "slock: unable to grab keyboard for screen %d\n",
- screen);
- return NULL;
-}
-
-static void
-usage(void)
-{
- die("usage: slock [-v] [cmd [arg ...]]\n");
-}
-
-int
-main(int argc, char **argv) {
- struct xrandr rr;
- struct lock **locks;
- struct passwd *pwd;
- struct group *grp;
- uid_t duid;
- gid_t dgid;
- const char *hash;
- Display *dpy;
- int s, nlocks, nscreens;
-
- ARGBEGIN {
- case 'v':
- fprintf(stderr, "slock-"VERSION"\n");
- return 0;
- default:
- usage();
- } ARGEND
-
- /* validate drop-user and -group */
- errno = 0;
- if (!(pwd = getpwnam(user)))
- die("slock: getpwnam %s: %s\n", user,
- errno ? strerror(errno) : "user entry not found");
- duid = pwd->pw_uid;
- errno = 0;
- if (!(grp = getgrnam(group)))
- die("slock: getgrnam %s: %s\n", group,
- errno ? strerror(errno) : "group entry not found");
- dgid = grp->gr_gid;
-
-#ifdef __linux__
- dontkillme();
-#endif
-
- hash = gethash();
- errno = 0;
- if (!crypt("", hash))
- die("slock: crypt: %s\n", strerror(errno));
-
- if (!(dpy = XOpenDisplay(NULL)))
- die("slock: cannot open display\n");
-
- /* drop privileges */
- if (setgroups(0, NULL) < 0)
- die("slock: setgroups: %s\n", strerror(errno));
- if (setgid(dgid) < 0)
- die("slock: setgid: %s\n", strerror(errno));
- if (setuid(duid) < 0)
- die("slock: setuid: %s\n", strerror(errno));
-
- /* check for Xrandr support */
- rr.active = XRRQueryExtension(dpy, &rr.evbase, &rr.errbase);
-
- /* get number of screens in display "dpy" and blank them */
- nscreens = ScreenCount(dpy);
- if (!(locks = calloc(nscreens, sizeof(struct lock *))))
- die("slock: out of memory\n");
- for (nlocks = 0, s = 0; s < nscreens; s++) {
- if ((locks[s] = lockscreen(dpy, &rr, s)) != NULL)
- nlocks++;
- else
- break;
- }
- XSync(dpy, 0);
-
- /* did we manage to lock everything? */
- if (nlocks != nscreens)
- return 1;
-
- /* run post-lock command */
- if (argc > 0) {
- switch (fork()) {
- case -1:
- die("slock: fork failed: %s\n", strerror(errno));
- case 0:
- if (close(ConnectionNumber(dpy)) < 0)
- die("slock: close: %s\n", strerror(errno));
- execvp(argv[0], argv);
- fprintf(stderr, "slock: execvp %s: %s\n", argv[0], strerror(errno));
- _exit(1);
- }
- }
-
- /* everything is now blank. Wait for the correct password */
- readpw(dpy, &rr, locks, nscreens, hash);
-
- return 0;
-}
diff --git a/.repos/slock/util.h b/.repos/slock/util.h
deleted file mode 100644
index 6f748b8..0000000
--- a/.repos/slock/util.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#undef explicit_bzero
-void explicit_bzero(void *, size_t);
diff --git a/.repos/st/FAQ b/.repos/st/FAQ
deleted file mode 100644
index 0f9609d..0000000
--- a/.repos/st/FAQ
+++ /dev/null
@@ -1,250 +0,0 @@
-## Why does st not handle utmp entries?
-
-Use the excellent tool of [utmp](https://git.suckless.org/utmp/) for this task.
-
-
-## Some _random program_ complains that st is unknown/not recognised/unsupported/whatever!
-
-It means that st doesn’t have any terminfo entry on your system. Chances are
-you did not `make install`. If you just want to test it without installing it,
-you can manually run `tic -sx st.info`.
-
-
-## Nothing works, and nothing is said about an unknown terminal!
-
-* Some programs just assume they’re running in xterm i.e. they don’t rely on
- terminfo. What you see is the current state of the “xterm compliance”.
-* Some programs don’t complain about the lacking st description and default to
- another terminal. In that case see the question about terminfo.
-
-
-## How do I scroll back up?
-
-* Using a terminal multiplexer.
- * `st -e tmux` using C-b [
- * `st -e screen` using C-a ESC
-* Using the excellent tool of [scroll](https://git.suckless.org/scroll/).
-* Using the scrollback [patch](https://st.suckless.org/patches/scrollback/).
-
-
-## I would like to have utmp and/or scroll functionality by default
-
-You can add the absolute patch of both programs in your config.h
-file. You only have to modify the value of utmp and scroll variables.
-
-
-## Why doesn't the Del key work in some programs?
-
-Taken from the terminfo manpage:
-
- If the terminal has a keypad that transmits codes when the keys
- are pressed, this information can be given. Note that it is not
- possible to handle terminals where the keypad only works in
- local (this applies, for example, to the unshifted HP 2621 keys).
- If the keypad can be set to transmit or not transmit, give these
- codes as smkx and rmkx. Otherwise the keypad is assumed to
- always transmit.
-
-In the st case smkx=E[?1hE= and rmkx=E[?1lE>, so it is mandatory that
-applications which want to test against keypad keys send these
-sequences.
-
-But buggy applications (like bash and irssi, for example) don't do this. A fast
-solution for them is to use the following command:
-
- $ printf '\033[?1h\033=' >/dev/tty
-
-or
- $ tput smkx
-
-In the case of bash, readline is used. Readline has a different note in its
-manpage about this issue:
-
- enable-keypad (Off)
- When set to On, readline will try to enable the
- application keypad when it is called. Some systems
- need this to enable arrow keys.
-
-Adding this option to your .inputrc will fix the keypad problem for all
-applications using readline.
-
-If you are using zsh, then read the zsh FAQ
-<http://zsh.sourceforge.net/FAQ/zshfaq03.html#l25>:
-
- It should be noted that the O / [ confusion can occur with other keys
- such as Home and End. Some systems let you query the key sequences
- sent by these keys from the system's terminal database, terminfo.
- Unfortunately, the key sequences given there typically apply to the
- mode that is not the one zsh uses by default (it's the "application"
- mode rather than the "raw" mode). Explaining the use of terminfo is
- outside of the scope of this FAQ, but if you wish to use the key
- sequences given there you can tell the line editor to turn on
- "application" mode when it starts and turn it off when it stops:
-
- function zle-line-init () { echoti smkx }
- function zle-line-finish () { echoti rmkx }
- zle -N zle-line-init
- zle -N zle-line-finish
-
-Putting these lines into your .zshrc will fix the problems.
-
-
-## How can I use meta in 8bit mode?
-
-St supports meta in 8bit mode, but the default terminfo entry doesn't
-use this capability. If you want it, you have to use the 'st-meta' value
-in TERM.
-
-
-## I cannot compile st in OpenBSD
-
-OpenBSD lacks librt, despite it being mandatory in POSIX
-<http://pubs.opengroup.org/onlinepubs/9699919799/utilities/c99.html#tag_20_11_13>.
-If you want to compile st for OpenBSD you have to remove -lrt from config.mk, and
-st will compile without any loss of functionality, because all the functions are
-included in libc on this platform.
-
-
-## The Backspace Case
-
-St is emulating the Linux way of handling backspace being delete and delete being
-backspace.
-
-This is an issue that was discussed in suckless mailing list
-<https://lists.suckless.org/dev/1404/20697.html>. Here is why some old grumpy
-terminal users wants its backspace to be how he feels it:
-
- Well, I am going to comment why I want to change the behaviour
- of this key. When ASCII was defined in 1968, communication
- with computers was done using punched cards, or hardcopy
- terminals (basically a typewriter machine connected with the
- computer using a serial port). ASCII defines DELETE as 7F,
- because, in punched-card terms, it means all the holes of the
- card punched; it is thus a kind of 'physical delete'. In the
- same way, the BACKSPACE key was a non-destructive backspace,
- as on a typewriter. So, if you wanted to delete a character,
- you had to BACKSPACE and then DELETE. Another use of BACKSPACE
- was to type accented characters, for example 'a BACKSPACE `'.
- The VT100 had no BACKSPACE key; it was generated using the
- CONTROL key as another control character (CONTROL key sets to
- 0 b7 b6 b5, so it converts H (code 0x48) into BACKSPACE (code
- 0x08)), but it had a DELETE key in a similar position where
- the BACKSPACE key is located today on common PC keyboards.
- All the terminal emulators emulated the difference between
- these keys correctly: the backspace key generated a BACKSPACE
- (^H) and delete key generated a DELETE (^?).
-
- But a problem arose when Linus Torvalds wrote Linux. Unlike
- earlier terminals, the Linux virtual terminal (the terminal
- emulator integrated in the kernel) returned a DELETE when
- backspace was pressed, due to the VT100 having a DELETE key in
- the same position. This created a lot of problems (see [1]
- and [2]). Since Linux has become the king, a lot of terminal
- emulators today generate a DELETE when the backspace key is
- pressed in order to avoid problems with Linux. The result is
- that the only way of generating a BACKSPACE on these systems
- is by using CONTROL + H. (I also think that emacs had an
- important point here because the CONTROL + H prefix is used
- in emacs in some commands (help commands).)
-
- From point of view of the kernel, you can change the key
- for deleting a previous character with stty erase. When you
- connect a real terminal into a machine you describe the type
- of terminal, so getty configures the correct value of stty
- erase for this terminal. In the case of terminal emulators,
- however, you don't have any getty that can set the correct
- value of stty erase, so you always get the default value.
- For this reason, it is necessary to add 'stty erase ^H' to your
- profile if you have changed the value of the backspace key.
- Of course, another solution is for st itself to modify the
- value of stty erase. I usually have the inverse problem:
- when I connect to non-Unix machines, I have to press CONTROL +
- h to get a BACKSPACE. The inverse problem occurs when a user
- connects to my Unix machines from a different system with a
- correct backspace key.
-
- [1] http://www.ibb.net/~anne/keyboard.html
- [2] http://www.tldp.org/HOWTO/Keyboard-and-Console-HOWTO-5.html
-
-
-## But I really want the old grumpy behaviour of my terminal
-
-Apply [1].
-
-[1] https://st.suckless.org/patches/delkey
-
-
-## Why do images not work in st using the w3m image hack?
-
-w3mimg uses a hack that draws an image on top of the terminal emulator Drawable
-window. The hack relies on the terminal to use a single buffer to draw its
-contents directly.
-
-st uses double-buffered drawing so the image is quickly replaced and may show a
-short flicker effect.
-
-Below is a patch example to change st double-buffering to a single Drawable
-buffer.
-
-diff --git a/x.c b/x.c
---- a/x.c
-+++ b/x.c
-@@ -732,10 +732,6 @@ xresize(int col, int row)
- win.tw = col * win.cw;
- win.th = row * win.ch;
-
-- XFreePixmap(xw.dpy, xw.buf);
-- xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h,
-- DefaultDepth(xw.dpy, xw.scr));
-- XftDrawChange(xw.draw, xw.buf);
- xclear(0, 0, win.w, win.h);
-
- /* resize to new width */
-@@ -1148,8 +1144,7 @@ xinit(int cols, int rows)
- gcvalues.graphics_exposures = False;
- dc.gc = XCreateGC(xw.dpy, parent, GCGraphicsExposures,
- &gcvalues);
-- xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h,
-- DefaultDepth(xw.dpy, xw.scr));
-+ xw.buf = xw.win;
- XSetForeground(xw.dpy, dc.gc, dc.col[defaultbg].pixel);
- XFillRectangle(xw.dpy, xw.buf, dc.gc, 0, 0, win.w, win.h);
-
-@@ -1632,8 +1627,6 @@ xdrawline(Line line, int x1, int y1, int x2)
- void
- xfinishdraw(void)
- {
-- XCopyArea(xw.dpy, xw.buf, xw.win, dc.gc, 0, 0, win.w,
-- win.h, 0, 0);
- XSetForeground(xw.dpy, dc.gc,
- dc.col[IS_SET(MODE_REVERSE)?
- defaultfg : defaultbg].pixel);
-
-
-## BadLength X error in Xft when trying to render emoji
-
-Xft makes st crash when rendering color emojis with the following error:
-
-"X Error of failed request: BadLength (poly request too large or internal Xlib length error)"
- Major opcode of failed request: 139 (RENDER)
- Minor opcode of failed request: 20 (RenderAddGlyphs)
- Serial number of failed request: 1595
- Current serial number in output stream: 1818"
-
-This is a known bug in Xft (not st) which happens on some platforms and
-combination of particular fonts and fontconfig settings.
-
-See also:
-https://gitlab.freedesktop.org/xorg/lib/libxft/issues/6
-https://bugs.freedesktop.org/show_bug.cgi?id=107534
-https://bugzilla.redhat.com/show_bug.cgi?id=1498269
-
-The solution is to remove color emoji fonts or disable this in the fontconfig
-XML configuration. As an ugly workaround (which may work only on newer
-fontconfig versions (FC_COLOR)), the following code can be used to mask color
-fonts:
-
- FcPatternAddBool(fcpattern, FC_COLOR, FcFalse);
-
-Please don't bother reporting this bug to st, but notify the upstream Xft
-developers about fixing this bug.
diff --git a/.repos/st/FUNDING.yml b/.repos/st/FUNDING.yml
deleted file mode 100644
index 5b856dc..0000000
--- a/.repos/st/FUNDING.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-github: lukesmithxyz
-custom: "https://lukesmith.xyz/donate"
-custom: "https://paypal.me/lukemsmith"
-patreon: lukesmith
-custom: "https://lukesmith.xyz/crypto"
diff --git a/.repos/st/LEGACY b/.repos/st/LEGACY
deleted file mode 100644
index bf28b1e..0000000
--- a/.repos/st/LEGACY
+++ /dev/null
@@ -1,17 +0,0 @@
-A STATEMENT ON LEGACY SUPPORT
-
-In the terminal world there is much cruft that comes from old and unsup‐
-ported terminals that inherit incompatible modes and escape sequences
-which noone is able to know, except when he/she comes from that time and
-developed a graphical vt100 emulator at that time.
-
-One goal of st is to only support what is really needed. When you en‐
-counter a sequence which you really need, implement it. But while you
-are at it, do not add the other cruft you might encounter while sneek‐
-ing at other terminal emulators. History has bloated them and there is
-no real evidence that most of the sequences are used today.
-
-
-Christoph Lohmann <20h@r-36.net>
-2012-09-13T07:00:36.081271045+02:00
-
diff --git a/.repos/st/LICENSE b/.repos/st/LICENSE
deleted file mode 100644
index d80eb47..0000000
--- a/.repos/st/LICENSE
+++ /dev/null
@@ -1,34 +0,0 @@
-MIT/X Consortium License
-
-© 2014-2020 Hiltjo Posthuma <hiltjo at codemadness dot org>
-© 2018 Devin J. Pohly <djpohly at gmail dot com>
-© 2014-2017 Quentin Rameau <quinq at fifth dot space>
-© 2009-2012 Aurélien APTEL <aurelien dot aptel at gmail dot com>
-© 2008-2017 Anselm R Garbe <garbeam at gmail dot com>
-© 2012-2017 Roberto E. Vargas Caballero <k0ga at shike2 dot com>
-© 2012-2016 Christoph Lohmann <20h at r-36 dot net>
-© 2013 Eon S. Jeon <esjeon at hyunmu dot am>
-© 2013 Alexander Sedov <alex0player at gmail dot com>
-© 2013 Mark Edgar <medgar123 at gmail dot com>
-© 2013-2014 Eric Pruitt <eric.pruitt at gmail dot com>
-© 2013 Michael Forney <mforney at mforney dot org>
-© 2013-2014 Markus Teich <markus dot teich at stusta dot mhn dot de>
-© 2014-2015 Laslo Hunhold <dev at frign dot de>
-
-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/.repos/st/Makefile b/.repos/st/Makefile
deleted file mode 100644
index 470ac86..0000000
--- a/.repos/st/Makefile
+++ /dev/null
@@ -1,57 +0,0 @@
-# st - simple terminal
-# See LICENSE file for copyright and license details.
-.POSIX:
-
-include config.mk
-
-SRC = st.c x.c
-OBJ = $(SRC:.c=.o)
-
-all: options st
-
-options:
- @echo st build options:
- @echo "CFLAGS = $(STCFLAGS)"
- @echo "LDFLAGS = $(STLDFLAGS)"
- @echo "CC = $(CC)"
-
-config.h:
- cp config.def.h config.h
-
-.c.o:
- $(CC) $(STCFLAGS) -c $<
-
-st.o: config.h st.h win.h
-x.o: arg.h config.h st.h win.h
-
-$(OBJ): config.h config.mk
-
-st: $(OBJ)
- $(CC) -o $@ $(OBJ) $(STLDFLAGS)
-
-clean:
- rm -f st $(OBJ) st-$(VERSION).tar.gz
-
-dist: clean
- mkdir -p st-$(VERSION)
- cp -R FAQ LEGACY TODO LICENSE Makefile README config.mk\
- config.def.h st.info st.1 arg.h st.h win.h $(SRC)\
- st-$(VERSION)
- tar -cf - st-$(VERSION) | gzip > st-$(VERSION).tar.gz
- rm -rf st-$(VERSION)
-
-install: st
- mkdir -p $(DESTDIR)$(PREFIX)/bin
- cp -f st $(DESTDIR)$(PREFIX)/bin
- chmod 755 $(DESTDIR)$(PREFIX)/bin/st
- mkdir -p $(DESTDIR)$(MANPREFIX)/man1
- sed "s/VERSION/$(VERSION)/g" < st.1 > $(DESTDIR)$(MANPREFIX)/man1/st.1
- chmod 644 $(DESTDIR)$(MANPREFIX)/man1/st.1
- tic -sx st.info
- @echo Please see the README file regarding the terminfo entry of st.
-
-uninstall:
- rm -f $(DESTDIR)$(PREFIX)/bin/st
- rm -f $(DESTDIR)$(MANPREFIX)/man1/st.1
-
-.PHONY: all options clean dist install uninstall
diff --git a/.repos/st/PKGBUILD b/.repos/st/PKGBUILD
deleted file mode 100644
index 98a057d..0000000
--- a/.repos/st/PKGBUILD
+++ /dev/null
@@ -1,45 +0,0 @@
-# Maintainer:
-
-pkgname=st-luke-git
-_pkgname=st
-pkgver=0.8.2.r1062.2087ab9
-pkgrel=1
-epoch=1
-pkgdesc="Luke's simple (suckless) terminal with vim-bindings, transparency, xresources, etc. "
-url='https://github.com/LukeSmithxyz/st'
-arch=('i686' 'x86_64')
-license=('MIT')
-options=('zipman')
-depends=('libxft')
-makedepends=('ncurses' 'libxext' 'git')
-optdepends=('dmenu: feed urls to dmenu')
-source=('git://github.com/LukeSmithxyz/st')
-sha1sums=('SKIP')
-
-provides=("${_pkgname}")
-conflicts=("${_pkgname}")
-
-pkgver() {
- cd "${_pkgname}"
- printf "%s.r%s.%s" "$(awk '/^VERSION =/ {print $3}' config.mk)" \
- "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)"
-}
-
-prepare() {
- cd $srcdir/${_pkgname}
- # skip terminfo which conflicts with ncurses
- sed -i '/tic /d' Makefile
-}
-
-build() {
- cd "${_pkgname}"
- make X11INC=/usr/include/X11 X11LIB=/usr/lib/X11
-}
-
-package() {
- cd "${_pkgname}"
- make PREFIX=/usr DESTDIR="${pkgdir}" install
- install -Dm644 LICENSE "${pkgdir}/usr/share/licenses/${pkgname}/LICENSE"
- install -Dm644 README.md "${pkgdir}/usr/share/doc/${pkgname}/README.md"
- install -Dm644 .Xdefaults "${pkgdir}/usr/share/doc/${pkgname}/Xdefaults.example"
-}
diff --git a/.repos/st/README b/.repos/st/README
deleted file mode 100644
index 6a846ed..0000000
--- a/.repos/st/README
+++ /dev/null
@@ -1,34 +0,0 @@
-st - simple terminal
---------------------
-st is a simple terminal emulator for X which sucks less.
-
-
-Requirements
-------------
-In order to build st you need the Xlib header files.
-
-
-Installation
-------------
-Edit config.mk to match your local setup (st is installed into
-the /usr/local namespace by default).
-
-Afterwards enter the following command to build and install st (if
-necessary as root):
-
- make clean install
-
-
-Running st
-----------
-If you did not install st with make clean install, you must compile
-the st terminfo entry with the following command:
-
- tic -sx st.info
-
-See the man page for additional details.
-
-Credits
--------
-Based on Aurélien APTEL <aurelien dot aptel at gmail dot com> bt source code.
-
diff --git a/.repos/st/README.md b/.repos/st/README.md
deleted file mode 100644
index 811f446..0000000
--- a/.repos/st/README.md
+++ /dev/null
@@ -1,82 +0,0 @@
-# Luke's build of st - the simple (suckless) terminal
-
-The [suckless terminal (st)](https://st.suckless.org/) with some additional features that make it literally the best terminal emulator ever:
-
-## Unique features (using dmenu)
-
-+ **follow urls** by pressing `alt-l`
-+ **copy urls** in the same way with `alt-y`
-+ **copy the output of commands** with `alt-o`
-
-## Bindings for
-
-+ **scrollback** with `alt-↑/↓` or `alt-pageup/down` or `shift` while scrolling the mouse
-+ OR **vim-bindings**: scroll up/down in history with `alt-k` and `alt-j`. Faster with `alt-u`/`alt-d`.
-+ **zoom/change font size**: same bindings as above, but holding down shift as well. `alt-home` returns to default
-+ **copy text** with `alt-c`, **paste** is `alt-v` or `shift-insert`
-
-## Pretty stuff
-
-+ Compatibility with `Xresources` and `pywal` for dynamic colors.
-+ Default [gruvbox](https://github.com/morhetz/gruvbox) colors otherwise.
-+ Transparency/alpha, which is also adjustable from your `Xresources`.
-+ Default font is system "mono" at 14pt, meaning the font will match your system font.
-
-## Other st patches
-
-+ Vertcenter
-+ Scrollback
-+ font2
-+ updated to latest version 0.8.2
-
-## Installation for newbs
-
-```
-git clone https://github.com/LukeSmithxyz/st
-cd st
-sudo make install
-```
-
-Users of Arch-based distros can also install it from the AUR as [st-luke-git](https://aur.archlinux.org/packages/st-luke-git/).
-
-Obviously, `make` is required to build. `fontconfig` is required for the default build, since it asks `fontconfig` for your system monospace font. It might be obvious, but `libX11` and `libXft` are required as well. Chances are, you have all of this installed already.
-
-On OpenBSD, be sure to edit `config.mk` first and remove `-lrt` from the `$LIBS` before compiling.
-
-Be sure to have a composite manager (`xcompmgr`, `picom`, etc.) running if you want transparency.
-
-## How to configure dynamically with Xresources
-
-For many key variables, this build of `st` will look for X settings set in either `~/.Xdefaults` or `~/.Xresources`. You must run `xrdb` on one of these files to load the settings.
-
-For example, you can define your desired fonts, transparency or colors:
-
-```
-*.font: Liberation Mono:pixelsize=12:antialias=true:autohint=true;
-*.alpha: 0.9
-*.color0: #111
-...
-```
-
-The `alpha` value (for transparency) goes from `0` (transparent) to `1` (opaque).
-
-### Colors
-
-To be clear about the color settings:
-
-- This build will use gruvbox colors by default and as a fallback.
-- If there are Xresources colors defined, those will take priority.
-- But if `wal` has run in your session, its colors will take priority.
-
-Note that when you run `wal`, it will negate the transparency of existing windows, but new windows will continue with the previously defined transparency.
-
-## Notes on Emojis and Special Characters
-
-If st crashes when viewing emojis, install [libxft-bgra](https://aur.archlinux.org/packages/libxft-bgra/) from the AUR.
-
-Note that some special characters may appear truncated if too wide. You might want to manually set your prefered emoji/special character font to a lower size in the `config.h` file to avoid this. By default, JoyPixels is used at a smaller size than the usual text.
-
-## Contact
-
-- Luke Smith <luke@lukesmith.xyz>
-- [https://lukesmith.xyz](https://lukesmith.xyz)
diff --git a/.repos/st/TODO b/.repos/st/TODO
deleted file mode 100644
index 5f74cd5..0000000
--- a/.repos/st/TODO
+++ /dev/null
@@ -1,28 +0,0 @@
-vt emulation
-------------
-
-* double-height support
-
-code & interface
-----------------
-
-* add a simple way to do multiplexing
-
-drawing
--------
-* add diacritics support to xdraws()
- * switch to a suckless font drawing library
-* make the font cache simpler
-* add better support for brightening of the upper colors
-
-bugs
-----
-
-* fix shift up/down (shift selection in emacs)
-* remove DEC test sequence when appropriate
-
-misc
-----
-
- $ grep -nE 'XXX|TODO' st.c
-
diff --git a/.repos/st/arg.h b/.repos/st/arg.h
deleted file mode 100644
index a22e019..0000000
--- a/.repos/st/arg.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * 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;\
- }\
- int i_;\
- for (i_ = 1, brk_ = 0, argv_ = argv;\
- argv[0][i_] && !brk_;\
- i_++) {\
- if (argv_ != argv)\
- break;\
- argc_ = argv[0][i_];\
- switch (argc_)
-
-#define ARGEND }\
- }
-
-#define ARGC() argc_
-
-#define EARGF(x) ((argv[0][i_+1] == '\0' && argv[1] == NULL)?\
- ((x), abort(), (char *)0) :\
- (brk_ = 1, (argv[0][i_+1] != '\0')?\
- (&argv[0][i_+1]) :\
- (argc--, argv++, argv[0])))
-
-#define ARGF() ((argv[0][i_+1] == '\0' && argv[1] == NULL)?\
- (char *)0 :\
- (brk_ = 1, (argv[0][i_+1] != '\0')?\
- (&argv[0][i_+1]) :\
- (argc--, argv++, argv[0])))
-
-#endif
diff --git a/.repos/st/boxdraw.c b/.repos/st/boxdraw.c
deleted file mode 100644
index 28a92d0..0000000
--- a/.repos/st/boxdraw.c
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * Copyright 2018 Avi Halachmi (:avih) avihpit@yahoo.com https://github.com/avih
- * MIT/X Consortium License
- */
-
-#include <X11/Xft/Xft.h>
-#include "st.h"
-#include "boxdraw_data.h"
-
-/* Rounded non-negative integers division of n / d */
-#define DIV(n, d) (((n) + (d) / 2) / (d))
-
-static Display *xdpy;
-static Colormap xcmap;
-static XftDraw *xd;
-static Visual *xvis;
-
-static void drawbox(int, int, int, int, XftColor *, XftColor *, ushort);
-static void drawboxlines(int, int, int, int, XftColor *, ushort);
-
-/* public API */
-
-void
-boxdraw_xinit(Display *dpy, Colormap cmap, XftDraw *draw, Visual *vis)
-{
- xdpy = dpy; xcmap = cmap; xd = draw, xvis = vis;
-}
-
-int
-isboxdraw(Rune u)
-{
- Rune block = u & ~0xff;
- return (boxdraw && block == 0x2500 && boxdata[(uint8_t)u]) ||
- (boxdraw_braille && block == 0x2800);
-}
-
-/* the "index" is actually the entire shape data encoded as ushort */
-ushort
-boxdrawindex(const Glyph *g)
-{
- if (boxdraw_braille && (g->u & ~0xff) == 0x2800)
- return BRL | (uint8_t)g->u;
- if (boxdraw_bold && (g->mode & ATTR_BOLD))
- return BDB | boxdata[(uint8_t)g->u];
- return boxdata[(uint8_t)g->u];
-}
-
-void
-drawboxes(int x, int y, int cw, int ch, XftColor *fg, XftColor *bg,
- const XftGlyphFontSpec *specs, int len)
-{
- for ( ; len-- > 0; x += cw, specs++)
- drawbox(x, y, cw, ch, fg, bg, (ushort)specs->glyph);
-}
-
-/* implementation */
-
-void
-drawbox(int x, int y, int w, int h, XftColor *fg, XftColor *bg, ushort bd)
-{
- ushort cat = bd & ~(BDB | 0xff); /* mask out bold and data */
- if (bd & (BDL | BDA)) {
- /* lines (light/double/heavy/arcs) */
- drawboxlines(x, y, w, h, fg, bd);
-
- } else if (cat == BBD) {
- /* lower (8-X)/8 block */
- int d = DIV((uint8_t)bd * h, 8);
- XftDrawRect(xd, fg, x, y + d, w, h - d);
-
- } else if (cat == BBU) {
- /* upper X/8 block */
- XftDrawRect(xd, fg, x, y, w, DIV((uint8_t)bd * h, 8));
-
- } else if (cat == BBL) {
- /* left X/8 block */
- XftDrawRect(xd, fg, x, y, DIV((uint8_t)bd * w, 8), h);
-
- } else if (cat == BBR) {
- /* right (8-X)/8 block */
- int d = DIV((uint8_t)bd * w, 8);
- XftDrawRect(xd, fg, x + d, y, w - d, h);
-
- } else if (cat == BBQ) {
- /* Quadrants */
- int w2 = DIV(w, 2), h2 = DIV(h, 2);
- if (bd & TL)
- XftDrawRect(xd, fg, x, y, w2, h2);
- if (bd & TR)
- XftDrawRect(xd, fg, x + w2, y, w - w2, h2);
- if (bd & BL)
- XftDrawRect(xd, fg, x, y + h2, w2, h - h2);
- if (bd & BR)
- XftDrawRect(xd, fg, x + w2, y + h2, w - w2, h - h2);
-
- } else if (bd & BBS) {
- /* Shades - data is 1/2/3 for 25%/50%/75% alpha, respectively */
- int d = (uint8_t)bd;
- XftColor xfc;
- XRenderColor xrc = { .alpha = 0xffff };
-
- xrc.red = DIV(fg->color.red * d + bg->color.red * (4 - d), 4);
- xrc.green = DIV(fg->color.green * d + bg->color.green * (4 - d), 4);
- xrc.blue = DIV(fg->color.blue * d + bg->color.blue * (4 - d), 4);
-
- XftColorAllocValue(xdpy, xvis, xcmap, &xrc, &xfc);
- XftDrawRect(xd, &xfc, x, y, w, h);
- XftColorFree(xdpy, xvis, xcmap, &xfc);
-
- } else if (cat == BRL) {
- /* braille, each data bit corresponds to one dot at 2x4 grid */
- int w1 = DIV(w, 2);
- int h1 = DIV(h, 4), h2 = DIV(h, 2), h3 = DIV(3 * h, 4);
-
- if (bd & 1) XftDrawRect(xd, fg, x, y, w1, h1);
- if (bd & 2) XftDrawRect(xd, fg, x, y + h1, w1, h2 - h1);
- if (bd & 4) XftDrawRect(xd, fg, x, y + h2, w1, h3 - h2);
- if (bd & 8) XftDrawRect(xd, fg, x + w1, y, w - w1, h1);
- if (bd & 16) XftDrawRect(xd, fg, x + w1, y + h1, w - w1, h2 - h1);
- if (bd & 32) XftDrawRect(xd, fg, x + w1, y + h2, w - w1, h3 - h2);
- if (bd & 64) XftDrawRect(xd, fg, x, y + h3, w1, h - h3);
- if (bd & 128) XftDrawRect(xd, fg, x + w1, y + h3, w - w1, h - h3);
-
- }
-}
-
-void
-drawboxlines(int x, int y, int w, int h, XftColor *fg, ushort bd)
-{
- /* s: stem thickness. width/8 roughly matches underscore thickness. */
- /* We draw bold as 1.5 * normal-stem and at least 1px thicker. */
- /* doubles draw at least 3px, even when w or h < 3. bold needs 6px. */
- int mwh = MIN(w, h);
- int base_s = MAX(1, DIV(mwh, 8));
- int bold = (bd & BDB) && mwh >= 6; /* possibly ignore boldness */
- int s = bold ? MAX(base_s + 1, DIV(3 * base_s, 2)) : base_s;
- int w2 = DIV(w - s, 2), h2 = DIV(h - s, 2);
- /* the s-by-s square (x + w2, y + h2, s, s) is the center texel. */
- /* The base length (per direction till edge) includes this square. */
-
- int light = bd & (LL | LU | LR | LD);
- int double_ = bd & (DL | DU | DR | DD);
-
- if (light) {
- /* d: additional (negative) length to not-draw the center */
- /* texel - at arcs and avoid drawing inside (some) doubles */
- int arc = bd & BDA;
- int multi_light = light & (light - 1);
- int multi_double = double_ & (double_ - 1);
- /* light crosses double only at DH+LV, DV+LH (ref. shapes) */
- int d = arc || (multi_double && !multi_light) ? -s : 0;
-
- if (bd & LL)
- XftDrawRect(xd, fg, x, y + h2, w2 + s + d, s);
- if (bd & LU)
- XftDrawRect(xd, fg, x + w2, y, s, h2 + s + d);
- if (bd & LR)
- XftDrawRect(xd, fg, x + w2 - d, y + h2, w - w2 + d, s);
- if (bd & LD)
- XftDrawRect(xd, fg, x + w2, y + h2 - d, s, h - h2 + d);
- }
-
- /* double lines - also align with light to form heavy when combined */
- if (double_) {
- /*
- * going clockwise, for each double-ray: p is additional length
- * to the single-ray nearer to the previous direction, and n to
- * the next. p and n adjust from the base length to lengths
- * which consider other doubles - shorter to avoid intersections
- * (p, n), or longer to draw the far-corner texel (n).
- */
- int dl = bd & DL, du = bd & DU, dr = bd & DR, dd = bd & DD;
- if (dl) {
- int p = dd ? -s : 0, n = du ? -s : dd ? s : 0;
- XftDrawRect(xd, fg, x, y + h2 + s, w2 + s + p, s);
- XftDrawRect(xd, fg, x, y + h2 - s, w2 + s + n, s);
- }
- if (du) {
- int p = dl ? -s : 0, n = dr ? -s : dl ? s : 0;
- XftDrawRect(xd, fg, x + w2 - s, y, s, h2 + s + p);
- XftDrawRect(xd, fg, x + w2 + s, y, s, h2 + s + n);
- }
- if (dr) {
- int p = du ? -s : 0, n = dd ? -s : du ? s : 0;
- XftDrawRect(xd, fg, x + w2 - p, y + h2 - s, w - w2 + p, s);
- XftDrawRect(xd, fg, x + w2 - n, y + h2 + s, w - w2 + n, s);
- }
- if (dd) {
- int p = dr ? -s : 0, n = dl ? -s : dr ? s : 0;
- XftDrawRect(xd, fg, x + w2 + s, y + h2 - p, s, h - h2 + p);
- XftDrawRect(xd, fg, x + w2 - s, y + h2 - n, s, h - h2 + n);
- }
- }
-}
diff --git a/.repos/st/boxdraw_data.h b/.repos/st/boxdraw_data.h
deleted file mode 100644
index 7890500..0000000
--- a/.repos/st/boxdraw_data.h
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * Copyright 2018 Avi Halachmi (:avih) avihpit@yahoo.com https://github.com/avih
- * MIT/X Consortium License
- */
-
-/*
- * U+25XX codepoints data
- *
- * References:
- * http://www.unicode.org/charts/PDF/U2500.pdf
- * http://www.unicode.org/charts/PDF/U2580.pdf
- *
- * Test page:
- * https://github.com/GNOME/vte/blob/master/doc/boxes.txt
- */
-
-/* Each shape is encoded as 16-bits. Higher bits are category, lower are data */
-/* Categories (mutually exclusive except BDB): */
-/* For convenience, BDL/BDA/BBS/BDB are 1 bit each, the rest are enums */
-#define BDL (1<<8) /* Box Draw Lines (light/double/heavy) */
-#define BDA (1<<9) /* Box Draw Arc (light) */
-
-#define BBD (1<<10) /* Box Block Down (lower) X/8 */
-#define BBL (2<<10) /* Box Block Left X/8 */
-#define BBU (3<<10) /* Box Block Upper X/8 */
-#define BBR (4<<10) /* Box Block Right X/8 */
-#define BBQ (5<<10) /* Box Block Quadrants */
-#define BRL (6<<10) /* Box Braille (data is lower byte of U28XX) */
-
-#define BBS (1<<14) /* Box Block Shades */
-#define BDB (1<<15) /* Box Draw is Bold */
-
-/* (BDL/BDA) Light/Double/Heavy x Left/Up/Right/Down/Horizontal/Vertical */
-/* Heavy is light+double (literally drawing light+double align to form heavy) */
-#define LL (1<<0)
-#define LU (1<<1)
-#define LR (1<<2)
-#define LD (1<<3)
-#define LH (LL+LR)
-#define LV (LU+LD)
-
-#define DL (1<<4)
-#define DU (1<<5)
-#define DR (1<<6)
-#define DD (1<<7)
-#define DH (DL+DR)
-#define DV (DU+DD)
-
-#define HL (LL+DL)
-#define HU (LU+DU)
-#define HR (LR+DR)
-#define HD (LD+DD)
-#define HH (HL+HR)
-#define HV (HU+HD)
-
-/* (BBQ) Quadrants Top/Bottom x Left/Right */
-#define TL (1<<0)
-#define TR (1<<1)
-#define BL (1<<2)
-#define BR (1<<3)
-
-/* Data for U+2500 - U+259F except dashes/diagonals */
-static const unsigned short boxdata[256] = {
- /* light lines */
- [0x00] = BDL + LH, /* light horizontal */
- [0x02] = BDL + LV, /* light vertical */
- [0x0c] = BDL + LD + LR, /* light down and right */
- [0x10] = BDL + LD + LL, /* light down and left */
- [0x14] = BDL + LU + LR, /* light up and right */
- [0x18] = BDL + LU + LL, /* light up and left */
- [0x1c] = BDL + LV + LR, /* light vertical and right */
- [0x24] = BDL + LV + LL, /* light vertical and left */
- [0x2c] = BDL + LH + LD, /* light horizontal and down */
- [0x34] = BDL + LH + LU, /* light horizontal and up */
- [0x3c] = BDL + LV + LH, /* light vertical and horizontal */
- [0x74] = BDL + LL, /* light left */
- [0x75] = BDL + LU, /* light up */
- [0x76] = BDL + LR, /* light right */
- [0x77] = BDL + LD, /* light down */
-
- /* heavy [+light] lines */
- [0x01] = BDL + HH,
- [0x03] = BDL + HV,
- [0x0d] = BDL + HR + LD,
- [0x0e] = BDL + HD + LR,
- [0x0f] = BDL + HD + HR,
- [0x11] = BDL + HL + LD,
- [0x12] = BDL + HD + LL,
- [0x13] = BDL + HD + HL,
- [0x15] = BDL + HR + LU,
- [0x16] = BDL + HU + LR,
- [0x17] = BDL + HU + HR,
- [0x19] = BDL + HL + LU,
- [0x1a] = BDL + HU + LL,
- [0x1b] = BDL + HU + HL,
- [0x1d] = BDL + HR + LV,
- [0x1e] = BDL + HU + LD + LR,
- [0x1f] = BDL + HD + LR + LU,
- [0x20] = BDL + HV + LR,
- [0x21] = BDL + HU + HR + LD,
- [0x22] = BDL + HD + HR + LU,
- [0x23] = BDL + HV + HR,
- [0x25] = BDL + HL + LV,
- [0x26] = BDL + HU + LD + LL,
- [0x27] = BDL + HD + LU + LL,
- [0x28] = BDL + HV + LL,
- [0x29] = BDL + HU + HL + LD,
- [0x2a] = BDL + HD + HL + LU,
- [0x2b] = BDL + HV + HL,
- [0x2d] = BDL + HL + LD + LR,
- [0x2e] = BDL + HR + LL + LD,
- [0x2f] = BDL + HH + LD,
- [0x30] = BDL + HD + LH,
- [0x31] = BDL + HD + HL + LR,
- [0x32] = BDL + HR + HD + LL,
- [0x33] = BDL + HH + HD,
- [0x35] = BDL + HL + LU + LR,
- [0x36] = BDL + HR + LU + LL,
- [0x37] = BDL + HH + LU,
- [0x38] = BDL + HU + LH,
- [0x39] = BDL + HU + HL + LR,
- [0x3a] = BDL + HU + HR + LL,
- [0x3b] = BDL + HH + HU,
- [0x3d] = BDL + HL + LV + LR,
- [0x3e] = BDL + HR + LV + LL,
- [0x3f] = BDL + HH + LV,
- [0x40] = BDL + HU + LH + LD,
- [0x41] = BDL + HD + LH + LU,
- [0x42] = BDL + HV + LH,
- [0x43] = BDL + HU + HL + LD + LR,
- [0x44] = BDL + HU + HR + LD + LL,
- [0x45] = BDL + HD + HL + LU + LR,
- [0x46] = BDL + HD + HR + LU + LL,
- [0x47] = BDL + HH + HU + LD,
- [0x48] = BDL + HH + HD + LU,
- [0x49] = BDL + HV + HL + LR,
- [0x4a] = BDL + HV + HR + LL,
- [0x4b] = BDL + HV + HH,
- [0x78] = BDL + HL,
- [0x79] = BDL + HU,
- [0x7a] = BDL + HR,
- [0x7b] = BDL + HD,
- [0x7c] = BDL + HR + LL,
- [0x7d] = BDL + HD + LU,
- [0x7e] = BDL + HL + LR,
- [0x7f] = BDL + HU + LD,
-
- /* double [+light] lines */
- [0x50] = BDL + DH,
- [0x51] = BDL + DV,
- [0x52] = BDL + DR + LD,
- [0x53] = BDL + DD + LR,
- [0x54] = BDL + DR + DD,
- [0x55] = BDL + DL + LD,
- [0x56] = BDL + DD + LL,
- [0x57] = BDL + DL + DD,
- [0x58] = BDL + DR + LU,
- [0x59] = BDL + DU + LR,
- [0x5a] = BDL + DU + DR,
- [0x5b] = BDL + DL + LU,
- [0x5c] = BDL + DU + LL,
- [0x5d] = BDL + DL + DU,
- [0x5e] = BDL + DR + LV,
- [0x5f] = BDL + DV + LR,
- [0x60] = BDL + DV + DR,
- [0x61] = BDL + DL + LV,
- [0x62] = BDL + DV + LL,
- [0x63] = BDL + DV + DL,
- [0x64] = BDL + DH + LD,
- [0x65] = BDL + DD + LH,
- [0x66] = BDL + DD + DH,
- [0x67] = BDL + DH + LU,
- [0x68] = BDL + DU + LH,
- [0x69] = BDL + DH + DU,
- [0x6a] = BDL + DH + LV,
- [0x6b] = BDL + DV + LH,
- [0x6c] = BDL + DH + DV,
-
- /* (light) arcs */
- [0x6d] = BDA + LD + LR,
- [0x6e] = BDA + LD + LL,
- [0x6f] = BDA + LU + LL,
- [0x70] = BDA + LU + LR,
-
- /* Lower (Down) X/8 block (data is 8 - X) */
- [0x81] = BBD + 7, [0x82] = BBD + 6, [0x83] = BBD + 5, [0x84] = BBD + 4,
- [0x85] = BBD + 3, [0x86] = BBD + 2, [0x87] = BBD + 1, [0x88] = BBD + 0,
-
- /* Left X/8 block (data is X) */
- [0x89] = BBL + 7, [0x8a] = BBL + 6, [0x8b] = BBL + 5, [0x8c] = BBL + 4,
- [0x8d] = BBL + 3, [0x8e] = BBL + 2, [0x8f] = BBL + 1,
-
- /* upper 1/2 (4/8), 1/8 block (X), right 1/2, 1/8 block (8-X) */
- [0x80] = BBU + 4, [0x94] = BBU + 1,
- [0x90] = BBR + 4, [0x95] = BBR + 7,
-
- /* Quadrants */
- [0x96] = BBQ + BL,
- [0x97] = BBQ + BR,
- [0x98] = BBQ + TL,
- [0x99] = BBQ + TL + BL + BR,
- [0x9a] = BBQ + TL + BR,
- [0x9b] = BBQ + TL + TR + BL,
- [0x9c] = BBQ + TL + TR + BR,
- [0x9d] = BBQ + TR,
- [0x9e] = BBQ + BL + TR,
- [0x9f] = BBQ + BL + TR + BR,
-
- /* Shades, data is an alpha value in 25% units (1/4, 1/2, 3/4) */
- [0x91] = BBS + 1, [0x92] = BBS + 2, [0x93] = BBS + 3,
-
- /* U+2504 - U+250B, U+254C - U+254F: unsupported (dashes) */
- /* U+2571 - U+2573: unsupported (diagonals) */
-};
diff --git a/.repos/st/config.def.h b/.repos/st/config.def.h
deleted file mode 100644
index 6f05dce..0000000
--- a/.repos/st/config.def.h
+++ /dev/null
@@ -1,472 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-
-/*
- * appearance
- *
- * font: see http://freedesktop.org/software/fontconfig/fontconfig-user.html
- */
-static char *font = "Liberation Mono:pixelsize=12:antialias=true:autohint=true";
-static int borderpx = 2;
-
-/*
- * What program is execed by st depends of these precedence rules:
- * 1: program passed with -e
- * 2: scroll and/or utmp
- * 3: SHELL environment variable
- * 4: value of shell in /etc/passwd
- * 5: value of shell in config.h
- */
-static char *shell = "/bin/sh";
-char *utmp = NULL;
-/* scroll program: to enable use a string like "scroll" */
-char *scroll = NULL;
-char *stty_args = "stty raw pass8 nl -echo -iexten -cstopb 38400";
-
-/* identification sequence returned in DA and DECID */
-char *vtiden = "\033[?6c";
-
-/* Kerning / character bounding-box multipliers */
-static float cwscale = 1.0;
-static float chscale = 1.0;
-
-/*
- * word delimiter string
- *
- * More advanced example: L" `'\"()[]{}"
- */
-wchar_t *worddelimiters = L" ";
-
-/* selection timeouts (in milliseconds) */
-static unsigned int doubleclicktimeout = 300;
-static unsigned int tripleclicktimeout = 600;
-
-/* alt screens */
-int allowaltscreen = 1;
-
-/* allow certain non-interactive (insecure) window operations such as:
- setting the clipboard text */
-int allowwindowops = 0;
-
-/*
- * draw latency range in ms - from new content/keypress/etc until drawing.
- * within this range, st draws when content stops arriving (idle). mostly it's
- * near minlatency, but it waits longer for slow updates to avoid partial draw.
- * low minlatency will tear/flicker more, as it can "detect" idle too early.
- */
-static double minlatency = 8;
-static double maxlatency = 33;
-
-/*
- * blinking timeout (set to 0 to disable blinking) for the terminal blinking
- * attribute.
- */
-static unsigned int blinktimeout = 800;
-
-/*
- * thickness of underline and bar cursors
- */
-static unsigned int cursorthickness = 2;
-
-/*
- * bell volume. It must be a value between -100 and 100. Use 0 for disabling
- * it
- */
-static int bellvolume = 0;
-
-/* default TERM value */
-char *termname = "st-256color";
-
-/*
- * spaces per tab
- *
- * When you are changing this value, don't forget to adapt the »it« value in
- * the st.info and appropriately install the st.info in the environment where
- * you use this st version.
- *
- * it#$tabspaces,
- *
- * Secondly make sure your kernel is not expanding tabs. When running `stty
- * -a` »tab0« should appear. You can tell the terminal to not expand tabs by
- * running following command:
- *
- * stty tabs
- */
-unsigned int tabspaces = 8;
-
-/* Terminal colors (16 first used in escape sequence) */
-static const char *colorname[] = {
- /* 8 normal colors */
- "black",
- "red3",
- "green3",
- "yellow3",
- "blue2",
- "magenta3",
- "cyan3",
- "gray90",
-
- /* 8 bright colors */
- "gray50",
- "red",
- "green",
- "yellow",
- "#5c5cff",
- "magenta",
- "cyan",
- "white",
-
- [255] = 0,
-
- /* more colors can be added after 255 to use with DefaultXX */
- "#cccccc",
- "#555555",
-};
-
-
-/*
- * Default colors (colorname index)
- * foreground, background, cursor, reverse cursor
- */
-unsigned int defaultfg = 7;
-unsigned int defaultbg = 0;
-static unsigned int defaultcs = 256;
-static unsigned int defaultrcs = 257;
-
-/*
- * Default shape of cursor
- * 2: Block ("█")
- * 4: Underline ("_")
- * 6: Bar ("|")
- * 7: Snowman ("☃")
- */
-static unsigned int cursorshape = 2;
-
-/*
- * Default columns and rows numbers
- */
-
-static unsigned int cols = 80;
-static unsigned int rows = 24;
-
-/*
- * Default colour and shape of the mouse cursor
- */
-static unsigned int mouseshape = XC_xterm;
-static unsigned int mousefg = 7;
-static unsigned int mousebg = 0;
-
-/*
- * Color used to display font attributes when fontconfig selected a font which
- * doesn't match the ones requested.
- */
-static unsigned int defaultattr = 11;
-
-/*
- * Force mouse select/shortcuts while mask is active (when MODE_MOUSE is set).
- * Note that if you want to use ShiftMask with selmasks, set this to an other
- * modifier, set to 0 to not use it.
- */
-static uint forcemousemod = ShiftMask;
-
-/*
- * Internal mouse shortcuts.
- * Beware that overloading Button1 will disable the selection.
- */
-static MouseShortcut mshortcuts[] = {
- /* mask button function argument release */
- { XK_ANY_MOD, Button2, selpaste, {.i = 0}, 1 },
- { ShiftMask, Button4, ttysend, {.s = "\033[5;2~"} },
- { XK_ANY_MOD, Button4, ttysend, {.s = "\031"} },
- { ShiftMask, Button5, ttysend, {.s = "\033[6;2~"} },
- { XK_ANY_MOD, Button5, ttysend, {.s = "\005"} },
-};
-
-/* Internal keyboard shortcuts. */
-#define MODKEY Mod1Mask
-#define TERMMOD (ControlMask|ShiftMask)
-
-static Shortcut shortcuts[] = {
- /* mask keysym function argument */
- { XK_ANY_MOD, XK_Break, sendbreak, {.i = 0} },
- { ControlMask, XK_Print, toggleprinter, {.i = 0} },
- { ShiftMask, XK_Print, printscreen, {.i = 0} },
- { XK_ANY_MOD, XK_Print, printsel, {.i = 0} },
- { TERMMOD, XK_Prior, zoom, {.f = +1} },
- { TERMMOD, XK_Next, zoom, {.f = -1} },
- { TERMMOD, XK_Home, zoomreset, {.f = 0} },
- { TERMMOD, XK_C, clipcopy, {.i = 0} },
- { TERMMOD, XK_V, clippaste, {.i = 0} },
- { TERMMOD, XK_Y, selpaste, {.i = 0} },
- { ShiftMask, XK_Insert, selpaste, {.i = 0} },
- { TERMMOD, XK_Num_Lock, numlock, {.i = 0} },
-};
-
-/*
- * Special keys (change & recompile st.info accordingly)
- *
- * Mask value:
- * * Use XK_ANY_MOD to match the key no matter modifiers state
- * * Use XK_NO_MOD to match the key alone (no modifiers)
- * appkey value:
- * * 0: no value
- * * > 0: keypad application mode enabled
- * * = 2: term.numlock = 1
- * * < 0: keypad application mode disabled
- * appcursor value:
- * * 0: no value
- * * > 0: cursor application mode enabled
- * * < 0: cursor application mode disabled
- *
- * Be careful with the order of the definitions because st searches in
- * this table sequentially, so any XK_ANY_MOD must be in the last
- * position for a key.
- */
-
-/*
- * If you want keys other than the X11 function keys (0xFD00 - 0xFFFF)
- * to be mapped below, add them to this array.
- */
-static KeySym mappedkeys[] = { -1 };
-
-/*
- * State bits to ignore when matching key or button events. By default,
- * numlock (Mod2Mask) and keyboard layout (XK_SWITCH_MOD) are ignored.
- */
-static uint ignoremod = Mod2Mask|XK_SWITCH_MOD;
-
-/*
- * This is the huge key array which defines all compatibility to the Linux
- * world. Please decide about changes wisely.
- */
-static Key key[] = {
- /* keysym mask string appkey appcursor */
- { XK_KP_Home, ShiftMask, "\033[2J", 0, -1},
- { XK_KP_Home, ShiftMask, "\033[1;2H", 0, +1},
- { XK_KP_Home, XK_ANY_MOD, "\033[H", 0, -1},
- { XK_KP_Home, XK_ANY_MOD, "\033[1~", 0, +1},
- { XK_KP_Up, XK_ANY_MOD, "\033Ox", +1, 0},
- { XK_KP_Up, XK_ANY_MOD, "\033[A", 0, -1},
- { XK_KP_Up, XK_ANY_MOD, "\033OA", 0, +1},
- { XK_KP_Down, XK_ANY_MOD, "\033Or", +1, 0},
- { XK_KP_Down, XK_ANY_MOD, "\033[B", 0, -1},
- { XK_KP_Down, XK_ANY_MOD, "\033OB", 0, +1},
- { XK_KP_Left, XK_ANY_MOD, "\033Ot", +1, 0},
- { XK_KP_Left, XK_ANY_MOD, "\033[D", 0, -1},
- { XK_KP_Left, XK_ANY_MOD, "\033OD", 0, +1},
- { XK_KP_Right, XK_ANY_MOD, "\033Ov", +1, 0},
- { XK_KP_Right, XK_ANY_MOD, "\033[C", 0, -1},
- { XK_KP_Right, XK_ANY_MOD, "\033OC", 0, +1},
- { XK_KP_Prior, ShiftMask, "\033[5;2~", 0, 0},
- { XK_KP_Prior, XK_ANY_MOD, "\033[5~", 0, 0},
- { XK_KP_Begin, XK_ANY_MOD, "\033[E", 0, 0},
- { XK_KP_End, ControlMask, "\033[J", -1, 0},
- { XK_KP_End, ControlMask, "\033[1;5F", +1, 0},
- { XK_KP_End, ShiftMask, "\033[K", -1, 0},
- { XK_KP_End, ShiftMask, "\033[1;2F", +1, 0},
- { XK_KP_End, XK_ANY_MOD, "\033[4~", 0, 0},
- { XK_KP_Next, ShiftMask, "\033[6;2~", 0, 0},
- { XK_KP_Next, XK_ANY_MOD, "\033[6~", 0, 0},
- { XK_KP_Insert, ShiftMask, "\033[2;2~", +1, 0},
- { XK_KP_Insert, ShiftMask, "\033[4l", -1, 0},
- { XK_KP_Insert, ControlMask, "\033[L", -1, 0},
- { XK_KP_Insert, ControlMask, "\033[2;5~", +1, 0},
- { XK_KP_Insert, XK_ANY_MOD, "\033[4h", -1, 0},
- { XK_KP_Insert, XK_ANY_MOD, "\033[2~", +1, 0},
- { XK_KP_Delete, ControlMask, "\033[M", -1, 0},
- { XK_KP_Delete, ControlMask, "\033[3;5~", +1, 0},
- { XK_KP_Delete, ShiftMask, "\033[2K", -1, 0},
- { XK_KP_Delete, ShiftMask, "\033[3;2~", +1, 0},
- { XK_KP_Delete, XK_ANY_MOD, "\033[P", -1, 0},
- { XK_KP_Delete, XK_ANY_MOD, "\033[3~", +1, 0},
- { XK_KP_Multiply, XK_ANY_MOD, "\033Oj", +2, 0},
- { XK_KP_Add, XK_ANY_MOD, "\033Ok", +2, 0},
- { XK_KP_Enter, XK_ANY_MOD, "\033OM", +2, 0},
- { XK_KP_Enter, XK_ANY_MOD, "\r", -1, 0},
- { XK_KP_Subtract, XK_ANY_MOD, "\033Om", +2, 0},
- { XK_KP_Decimal, XK_ANY_MOD, "\033On", +2, 0},
- { XK_KP_Divide, XK_ANY_MOD, "\033Oo", +2, 0},
- { XK_KP_0, XK_ANY_MOD, "\033Op", +2, 0},
- { XK_KP_1, XK_ANY_MOD, "\033Oq", +2, 0},
- { XK_KP_2, XK_ANY_MOD, "\033Or", +2, 0},
- { XK_KP_3, XK_ANY_MOD, "\033Os", +2, 0},
- { XK_KP_4, XK_ANY_MOD, "\033Ot", +2, 0},
- { XK_KP_5, XK_ANY_MOD, "\033Ou", +2, 0},
- { XK_KP_6, XK_ANY_MOD, "\033Ov", +2, 0},
- { XK_KP_7, XK_ANY_MOD, "\033Ow", +2, 0},
- { XK_KP_8, XK_ANY_MOD, "\033Ox", +2, 0},
- { XK_KP_9, XK_ANY_MOD, "\033Oy", +2, 0},
- { XK_Up, ShiftMask, "\033[1;2A", 0, 0},
- { XK_Up, Mod1Mask, "\033[1;3A", 0, 0},
- { XK_Up, ShiftMask|Mod1Mask,"\033[1;4A", 0, 0},
- { XK_Up, ControlMask, "\033[1;5A", 0, 0},
- { XK_Up, ShiftMask|ControlMask,"\033[1;6A", 0, 0},
- { XK_Up, ControlMask|Mod1Mask,"\033[1;7A", 0, 0},
- { XK_Up,ShiftMask|ControlMask|Mod1Mask,"\033[1;8A", 0, 0},
- { XK_Up, XK_ANY_MOD, "\033[A", 0, -1},
- { XK_Up, XK_ANY_MOD, "\033OA", 0, +1},
- { XK_Down, ShiftMask, "\033[1;2B", 0, 0},
- { XK_Down, Mod1Mask, "\033[1;3B", 0, 0},
- { XK_Down, ShiftMask|Mod1Mask,"\033[1;4B", 0, 0},
- { XK_Down, ControlMask, "\033[1;5B", 0, 0},
- { XK_Down, ShiftMask|ControlMask,"\033[1;6B", 0, 0},
- { XK_Down, ControlMask|Mod1Mask,"\033[1;7B", 0, 0},
- { XK_Down,ShiftMask|ControlMask|Mod1Mask,"\033[1;8B",0, 0},
- { XK_Down, XK_ANY_MOD, "\033[B", 0, -1},
- { XK_Down, XK_ANY_MOD, "\033OB", 0, +1},
- { XK_Left, ShiftMask, "\033[1;2D", 0, 0},
- { XK_Left, Mod1Mask, "\033[1;3D", 0, 0},
- { XK_Left, ShiftMask|Mod1Mask,"\033[1;4D", 0, 0},
- { XK_Left, ControlMask, "\033[1;5D", 0, 0},
- { XK_Left, ShiftMask|ControlMask,"\033[1;6D", 0, 0},
- { XK_Left, ControlMask|Mod1Mask,"\033[1;7D", 0, 0},
- { XK_Left,ShiftMask|ControlMask|Mod1Mask,"\033[1;8D",0, 0},
- { XK_Left, XK_ANY_MOD, "\033[D", 0, -1},
- { XK_Left, XK_ANY_MOD, "\033OD", 0, +1},
- { XK_Right, ShiftMask, "\033[1;2C", 0, 0},
- { XK_Right, Mod1Mask, "\033[1;3C", 0, 0},
- { XK_Right, ShiftMask|Mod1Mask,"\033[1;4C", 0, 0},
- { XK_Right, ControlMask, "\033[1;5C", 0, 0},
- { XK_Right, ShiftMask|ControlMask,"\033[1;6C", 0, 0},
- { XK_Right, ControlMask|Mod1Mask,"\033[1;7C", 0, 0},
- { XK_Right,ShiftMask|ControlMask|Mod1Mask,"\033[1;8C",0, 0},
- { XK_Right, XK_ANY_MOD, "\033[C", 0, -1},
- { XK_Right, XK_ANY_MOD, "\033OC", 0, +1},
- { XK_ISO_Left_Tab, ShiftMask, "\033[Z", 0, 0},
- { XK_Return, Mod1Mask, "\033\r", 0, 0},
- { XK_Return, XK_ANY_MOD, "\r", 0, 0},
- { XK_Insert, ShiftMask, "\033[4l", -1, 0},
- { XK_Insert, ShiftMask, "\033[2;2~", +1, 0},
- { XK_Insert, ControlMask, "\033[L", -1, 0},
- { XK_Insert, ControlMask, "\033[2;5~", +1, 0},
- { XK_Insert, XK_ANY_MOD, "\033[4h", -1, 0},
- { XK_Insert, XK_ANY_MOD, "\033[2~", +1, 0},
- { XK_Delete, ControlMask, "\033[M", -1, 0},
- { XK_Delete, ControlMask, "\033[3;5~", +1, 0},
- { XK_Delete, ShiftMask, "\033[2K", -1, 0},
- { XK_Delete, ShiftMask, "\033[3;2~", +1, 0},
- { XK_Delete, XK_ANY_MOD, "\033[P", -1, 0},
- { XK_Delete, XK_ANY_MOD, "\033[3~", +1, 0},
- { XK_BackSpace, XK_NO_MOD, "\177", 0, 0},
- { XK_BackSpace, Mod1Mask, "\033\177", 0, 0},
- { XK_Home, ShiftMask, "\033[2J", 0, -1},
- { XK_Home, ShiftMask, "\033[1;2H", 0, +1},
- { XK_Home, XK_ANY_MOD, "\033[H", 0, -1},
- { XK_Home, XK_ANY_MOD, "\033[1~", 0, +1},
- { XK_End, ControlMask, "\033[J", -1, 0},
- { XK_End, ControlMask, "\033[1;5F", +1, 0},
- { XK_End, ShiftMask, "\033[K", -1, 0},
- { XK_End, ShiftMask, "\033[1;2F", +1, 0},
- { XK_End, XK_ANY_MOD, "\033[4~", 0, 0},
- { XK_Prior, ControlMask, "\033[5;5~", 0, 0},
- { XK_Prior, ShiftMask, "\033[5;2~", 0, 0},
- { XK_Prior, XK_ANY_MOD, "\033[5~", 0, 0},
- { XK_Next, ControlMask, "\033[6;5~", 0, 0},
- { XK_Next, ShiftMask, "\033[6;2~", 0, 0},
- { XK_Next, XK_ANY_MOD, "\033[6~", 0, 0},
- { XK_F1, XK_NO_MOD, "\033OP" , 0, 0},
- { XK_F1, /* F13 */ ShiftMask, "\033[1;2P", 0, 0},
- { XK_F1, /* F25 */ ControlMask, "\033[1;5P", 0, 0},
- { XK_F1, /* F37 */ Mod4Mask, "\033[1;6P", 0, 0},
- { XK_F1, /* F49 */ Mod1Mask, "\033[1;3P", 0, 0},
- { XK_F1, /* F61 */ Mod3Mask, "\033[1;4P", 0, 0},
- { XK_F2, XK_NO_MOD, "\033OQ" , 0, 0},
- { XK_F2, /* F14 */ ShiftMask, "\033[1;2Q", 0, 0},
- { XK_F2, /* F26 */ ControlMask, "\033[1;5Q", 0, 0},
- { XK_F2, /* F38 */ Mod4Mask, "\033[1;6Q", 0, 0},
- { XK_F2, /* F50 */ Mod1Mask, "\033[1;3Q", 0, 0},
- { XK_F2, /* F62 */ Mod3Mask, "\033[1;4Q", 0, 0},
- { XK_F3, XK_NO_MOD, "\033OR" , 0, 0},
- { XK_F3, /* F15 */ ShiftMask, "\033[1;2R", 0, 0},
- { XK_F3, /* F27 */ ControlMask, "\033[1;5R", 0, 0},
- { XK_F3, /* F39 */ Mod4Mask, "\033[1;6R", 0, 0},
- { XK_F3, /* F51 */ Mod1Mask, "\033[1;3R", 0, 0},
- { XK_F3, /* F63 */ Mod3Mask, "\033[1;4R", 0, 0},
- { XK_F4, XK_NO_MOD, "\033OS" , 0, 0},
- { XK_F4, /* F16 */ ShiftMask, "\033[1;2S", 0, 0},
- { XK_F4, /* F28 */ ControlMask, "\033[1;5S", 0, 0},
- { XK_F4, /* F40 */ Mod4Mask, "\033[1;6S", 0, 0},
- { XK_F4, /* F52 */ Mod1Mask, "\033[1;3S", 0, 0},
- { XK_F5, XK_NO_MOD, "\033[15~", 0, 0},
- { XK_F5, /* F17 */ ShiftMask, "\033[15;2~", 0, 0},
- { XK_F5, /* F29 */ ControlMask, "\033[15;5~", 0, 0},
- { XK_F5, /* F41 */ Mod4Mask, "\033[15;6~", 0, 0},
- { XK_F5, /* F53 */ Mod1Mask, "\033[15;3~", 0, 0},
- { XK_F6, XK_NO_MOD, "\033[17~", 0, 0},
- { XK_F6, /* F18 */ ShiftMask, "\033[17;2~", 0, 0},
- { XK_F6, /* F30 */ ControlMask, "\033[17;5~", 0, 0},
- { XK_F6, /* F42 */ Mod4Mask, "\033[17;6~", 0, 0},
- { XK_F6, /* F54 */ Mod1Mask, "\033[17;3~", 0, 0},
- { XK_F7, XK_NO_MOD, "\033[18~", 0, 0},
- { XK_F7, /* F19 */ ShiftMask, "\033[18;2~", 0, 0},
- { XK_F7, /* F31 */ ControlMask, "\033[18;5~", 0, 0},
- { XK_F7, /* F43 */ Mod4Mask, "\033[18;6~", 0, 0},
- { XK_F7, /* F55 */ Mod1Mask, "\033[18;3~", 0, 0},
- { XK_F8, XK_NO_MOD, "\033[19~", 0, 0},
- { XK_F8, /* F20 */ ShiftMask, "\033[19;2~", 0, 0},
- { XK_F8, /* F32 */ ControlMask, "\033[19;5~", 0, 0},
- { XK_F8, /* F44 */ Mod4Mask, "\033[19;6~", 0, 0},
- { XK_F8, /* F56 */ Mod1Mask, "\033[19;3~", 0, 0},
- { XK_F9, XK_NO_MOD, "\033[20~", 0, 0},
- { XK_F9, /* F21 */ ShiftMask, "\033[20;2~", 0, 0},
- { XK_F9, /* F33 */ ControlMask, "\033[20;5~", 0, 0},
- { XK_F9, /* F45 */ Mod4Mask, "\033[20;6~", 0, 0},
- { XK_F9, /* F57 */ Mod1Mask, "\033[20;3~", 0, 0},
- { XK_F10, XK_NO_MOD, "\033[21~", 0, 0},
- { XK_F10, /* F22 */ ShiftMask, "\033[21;2~", 0, 0},
- { XK_F10, /* F34 */ ControlMask, "\033[21;5~", 0, 0},
- { XK_F10, /* F46 */ Mod4Mask, "\033[21;6~", 0, 0},
- { XK_F10, /* F58 */ Mod1Mask, "\033[21;3~", 0, 0},
- { XK_F11, XK_NO_MOD, "\033[23~", 0, 0},
- { XK_F11, /* F23 */ ShiftMask, "\033[23;2~", 0, 0},
- { XK_F11, /* F35 */ ControlMask, "\033[23;5~", 0, 0},
- { XK_F11, /* F47 */ Mod4Mask, "\033[23;6~", 0, 0},
- { XK_F11, /* F59 */ Mod1Mask, "\033[23;3~", 0, 0},
- { XK_F12, XK_NO_MOD, "\033[24~", 0, 0},
- { XK_F12, /* F24 */ ShiftMask, "\033[24;2~", 0, 0},
- { XK_F12, /* F36 */ ControlMask, "\033[24;5~", 0, 0},
- { XK_F12, /* F48 */ Mod4Mask, "\033[24;6~", 0, 0},
- { XK_F12, /* F60 */ Mod1Mask, "\033[24;3~", 0, 0},
- { XK_F13, XK_NO_MOD, "\033[1;2P", 0, 0},
- { XK_F14, XK_NO_MOD, "\033[1;2Q", 0, 0},
- { XK_F15, XK_NO_MOD, "\033[1;2R", 0, 0},
- { XK_F16, XK_NO_MOD, "\033[1;2S", 0, 0},
- { XK_F17, XK_NO_MOD, "\033[15;2~", 0, 0},
- { XK_F18, XK_NO_MOD, "\033[17;2~", 0, 0},
- { XK_F19, XK_NO_MOD, "\033[18;2~", 0, 0},
- { XK_F20, XK_NO_MOD, "\033[19;2~", 0, 0},
- { XK_F21, XK_NO_MOD, "\033[20;2~", 0, 0},
- { XK_F22, XK_NO_MOD, "\033[21;2~", 0, 0},
- { XK_F23, XK_NO_MOD, "\033[23;2~", 0, 0},
- { XK_F24, XK_NO_MOD, "\033[24;2~", 0, 0},
- { XK_F25, XK_NO_MOD, "\033[1;5P", 0, 0},
- { XK_F26, XK_NO_MOD, "\033[1;5Q", 0, 0},
- { XK_F27, XK_NO_MOD, "\033[1;5R", 0, 0},
- { XK_F28, XK_NO_MOD, "\033[1;5S", 0, 0},
- { XK_F29, XK_NO_MOD, "\033[15;5~", 0, 0},
- { XK_F30, XK_NO_MOD, "\033[17;5~", 0, 0},
- { XK_F31, XK_NO_MOD, "\033[18;5~", 0, 0},
- { XK_F32, XK_NO_MOD, "\033[19;5~", 0, 0},
- { XK_F33, XK_NO_MOD, "\033[20;5~", 0, 0},
- { XK_F34, XK_NO_MOD, "\033[21;5~", 0, 0},
- { XK_F35, XK_NO_MOD, "\033[23;5~", 0, 0},
-};
-
-/*
- * Selection types' masks.
- * Use the same masks as usual.
- * Button1Mask is always unset, to make masks match between ButtonPress.
- * ButtonRelease and MotionNotify.
- * If no match is found, regular selection is used.
- */
-static uint selmasks[] = {
- [SEL_RECTANGULAR] = Mod1Mask,
-};
-
-/*
- * Printable characters in ASCII, used to estimate the advance width
- * of single wide characters.
- */
-static char ascii_printable[] =
- " !\"#$%&'()*+,-./0123456789:;<=>?"
- "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_"
- "`abcdefghijklmnopqrstuvwxyz{|}~";
diff --git a/.repos/st/config.h b/.repos/st/config.h
deleted file mode 100644
index c25b213..0000000
--- a/.repos/st/config.h
+++ /dev/null
@@ -1,472 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-
-/*
- * appearance
- *
- * font: see http://freedesktop.org/software/fontconfig/fontconfig-user.html
- */
-static char *font = "Iosevka Term:pixelsize=18:antialias=true:autohint=true";
-static int borderpx = 2;
-
-/*
- * What program is execed by st depends of these precedence rules:
- * 1: program passed with -e
- * 2: scroll and/or utmp
- * 3: SHELL environment variable
- * 4: value of shell in /etc/passwd
- * 5: value of shell in config.h
- */
-static char *shell = "/bin/sh";
-char *utmp = NULL;
-/* scroll program: to enable use a string like "scroll" */
-char *scroll = NULL;
-char *stty_args = "stty raw pass8 nl -echo -iexten -cstopb 38400";
-
-/* identification sequence returned in DA and DECID */
-char *vtiden = "\033[?6c";
-
-/* Kerning / character bounding-box multipliers */
-static float cwscale = 1.0;
-static float chscale = 1.0;
-
-/*
- * word delimiter string
- *
- * More advanced example: L" `'\"()[]{}"
- */
-wchar_t *worddelimiters = L" ";
-
-/* selection timeouts (in milliseconds) */
-static unsigned int doubleclicktimeout = 300;
-static unsigned int tripleclicktimeout = 600;
-
-/* alt screens */
-int allowaltscreen = 1;
-
-/* allow certain non-interactive (insecure) window operations such as:
- setting the clipboard text */
-int allowwindowops = 0;
-
-/*
- * draw latency range in ms - from new content/keypress/etc until drawing.
- * within this range, st draws when content stops arriving (idle). mostly it's
- * near minlatency, but it waits longer for slow updates to avoid partial draw.
- * low minlatency will tear/flicker more, as it can "detect" idle too early.
- */
-static double minlatency = 8;
-static double maxlatency = 33;
-
-/*
- * blinking timeout (set to 0 to disable blinking) for the terminal blinking
- * attribute.
- */
-static unsigned int blinktimeout = 800;
-
-/*
- * thickness of underline and bar cursors
- */
-static unsigned int cursorthickness = 2;
-
-/*
- * bell volume. It must be a value between -100 and 100. Use 0 for disabling
- * it
- */
-static int bellvolume = 0;
-
-/* default TERM value */
-char *termname = "st-256color";
-
-/*
- * spaces per tab
- *
- * When you are changing this value, don't forget to adapt the »it« value in
- * the st.info and appropriately install the st.info in the environment where
- * you use this st version.
- *
- * it#$tabspaces,
- *
- * Secondly make sure your kernel is not expanding tabs. When running `stty
- * -a` »tab0« should appear. You can tell the terminal to not expand tabs by
- * running following command:
- *
- * stty tabs
- */
-unsigned int tabspaces = 8;
-
-/* Terminal colors (16 first used in escape sequence) */
-static const char *colorname[] = {
- /* 8 normal colors */
- "black",
- "red3",
- "green3",
- "yellow3",
- "blue2",
- "magenta3",
- "cyan3",
- "gray90",
-
- /* 8 bright colors */
- "gray50",
- "red",
- "green",
- "yellow",
- "#5c5cff",
- "magenta",
- "cyan",
- "white",
-
- [255] = 0,
-
- /* more colors can be added after 255 to use with DefaultXX */
- "#cccccc",
- "#555555",
-};
-
-/*
- * Default colors (colorname index)
- * foreground, background, cursor, reverse cursor
- */
-unsigned int defaultfg = 7;
-unsigned int defaultbg = 0;
-static unsigned int defaultcs = 256;
-static unsigned int defaultrcs = 257;
-
-/*
- * Default shape of cursor
- * 2: Block ("█")
- * 4: Underline ("_")
- * 6: Bar ("|")
- * 7: Snowman ("☃")
- */
-static unsigned int cursorshape = 2;
-
-/*
- * Default columns and rows numbers
- */
-
-static unsigned int cols = 80;
-static unsigned int rows = 24;
-
-/*
- * Default colour and shape of the mouse cursor
- */
-static unsigned int mouseshape = XC_xterm;
-static unsigned int mousefg = 7;
-static unsigned int mousebg = 0;
-
-/*
- * Color used to display font attributes when fontconfig selected a font which
- * doesn't match the ones requested.
- */
-static unsigned int defaultattr = 11;
-
-/*
- * Force mouse select/shortcuts while mask is active (when MODE_MOUSE is set).
- * Note that if you want to use ShiftMask with selmasks, set this to an other
- * modifier, set to 0 to not use it.
- */
-static uint forcemousemod = ShiftMask;
-
-/* Internal keyboard shortcuts. */
-#define MODKEY Mod1Mask
-#define TERMMOD (MODKEY | ShiftMask)
-
-/*
- * Internal mouse shortcuts.
- * Beware that overloading Button1 will disable the selection.
- */
-static MouseShortcut mshortcuts[] = {
- /* mask button function argument release */
- { ShiftMask, Button4, kscrollup, { .i = 1 } },
- { ShiftMask, Button5, kscrolldown, { .i = 1 } },
- { XK_ANY_MOD, Button2, selpaste, { .i = 0 }, 1 },
- { ShiftMask, Button4, ttysend, { .s = "\033[5;2~" } },
- { XK_ANY_MOD, Button4, ttysend, { .s = "\031" } },
- { ShiftMask, Button5, ttysend, { .s = "\033[6;2~" } },
- { XK_ANY_MOD, Button5, ttysend, { .s = "\005" } },
-};
-
-static Shortcut shortcuts[] = {
- /* mask keysym function argument */
- { XK_ANY_MOD, XK_Break, sendbreak, { .i = 0 } },
- { ControlMask, XK_Print, toggleprinter, { .i = 0 } },
- { ShiftMask, XK_Print, printscreen, { .i = 0 } },
- { XK_ANY_MOD, XK_Print, printsel, { .i = 0 } },
- { TERMMOD, XK_K, zoom, { .f = +1 } },
- { TERMMOD, XK_J, zoom, { .f = -1 } },
- { TERMMOD, XK_Home, zoomreset, { .f = 0 } },
- { TERMMOD, XK_C, clipcopy, { .i = 0 } },
- { TERMMOD, XK_V, clippaste, { .i = 0 } },
- { TERMMOD, XK_Y, selpaste, { .i = 0 } },
- { ShiftMask, XK_Insert, selpaste, { .i = 0 } },
- { TERMMOD, XK_Num_Lock, numlock, { .i = 0 } },
-};
-
-/*
- * Special keys (change & recompile st.info accordingly)
- *
- * Mask value:
- * * Use XK_ANY_MOD to match the key no matter modifiers state
- * * Use XK_NO_MOD to match the key alone (no modifiers)
- * appkey value:
- * * 0: no value
- * * > 0: keypad application mode enabled
- * * = 2: term.numlock = 1
- * * < 0: keypad application mode disabled
- * appcursor value:
- * * 0: no value
- * * > 0: cursor application mode enabled
- * * < 0: cursor application mode disabled
- *
- * Be careful with the order of the definitions because st searches in
- * this table sequentially, so any XK_ANY_MOD must be in the last
- * position for a key.
- */
-
-/*
- * If you want keys other than the X11 function keys (0xFD00 - 0xFFFF)
- * to be mapped below, add them to this array.
- */
-static KeySym mappedkeys[] = { -1 };
-
-/*
- * State bits to ignore when matching key or button events. By default,
- * numlock (Mod2Mask) and keyboard layout (XK_SWITCH_MOD) are ignored.
- */
-static uint ignoremod = Mod2Mask | XK_SWITCH_MOD;
-
-/*
- * This is the huge key array which defines all compatibility to the Linux
- * world. Please decide about changes wisely.
- */
-static Key key[] = {
- /* keysym mask string appkey appcursor */
- { XK_KP_Home, ShiftMask, "\033[2J", 0, -1 },
- { XK_KP_Home, ShiftMask, "\033[1;2H", 0, +1 },
- { XK_KP_Home, XK_ANY_MOD, "\033[H", 0, -1 },
- { XK_KP_Home, XK_ANY_MOD, "\033[1~", 0, +1 },
- { XK_KP_Up, XK_ANY_MOD, "\033Ox", +1, 0 },
- { XK_KP_Up, XK_ANY_MOD, "\033[A", 0, -1 },
- { XK_KP_Up, XK_ANY_MOD, "\033OA", 0, +1 },
- { XK_KP_Down, XK_ANY_MOD, "\033Or", +1, 0 },
- { XK_KP_Down, XK_ANY_MOD, "\033[B", 0, -1 },
- { XK_KP_Down, XK_ANY_MOD, "\033OB", 0, +1 },
- { XK_KP_Left, XK_ANY_MOD, "\033Ot", +1, 0 },
- { XK_KP_Left, XK_ANY_MOD, "\033[D", 0, -1 },
- { XK_KP_Left, XK_ANY_MOD, "\033OD", 0, +1 },
- { XK_KP_Right, XK_ANY_MOD, "\033Ov", +1, 0 },
- { XK_KP_Right, XK_ANY_MOD, "\033[C", 0, -1 },
- { XK_KP_Right, XK_ANY_MOD, "\033OC", 0, +1 },
- { XK_KP_Prior, ShiftMask, "\033[5;2~", 0, 0 },
- { XK_KP_Prior, XK_ANY_MOD, "\033[5~", 0, 0 },
- { XK_KP_Begin, XK_ANY_MOD, "\033[E", 0, 0 },
- { XK_KP_End, ControlMask, "\033[J", -1, 0 },
- { XK_KP_End, ControlMask, "\033[1;5F", +1, 0 },
- { XK_KP_End, ShiftMask, "\033[K", -1, 0 },
- { XK_KP_End, ShiftMask, "\033[1;2F", +1, 0 },
- { XK_KP_End, XK_ANY_MOD, "\033[4~", 0, 0 },
- { XK_KP_Next, ShiftMask, "\033[6;2~", 0, 0 },
- { XK_KP_Next, XK_ANY_MOD, "\033[6~", 0, 0 },
- { XK_KP_Insert, ShiftMask, "\033[2;2~", +1, 0 },
- { XK_KP_Insert, ShiftMask, "\033[4l", -1, 0 },
- { XK_KP_Insert, ControlMask, "\033[L", -1, 0 },
- { XK_KP_Insert, ControlMask, "\033[2;5~", +1, 0 },
- { XK_KP_Insert, XK_ANY_MOD, "\033[4h", -1, 0 },
- { XK_KP_Insert, XK_ANY_MOD, "\033[2~", +1, 0 },
- { XK_KP_Delete, ControlMask, "\033[M", -1, 0 },
- { XK_KP_Delete, ControlMask, "\033[3;5~", +1, 0 },
- { XK_KP_Delete, ShiftMask, "\033[2K", -1, 0 },
- { XK_KP_Delete, ShiftMask, "\033[3;2~", +1, 0 },
- { XK_KP_Delete, XK_ANY_MOD, "\033[P", -1, 0 },
- { XK_KP_Delete, XK_ANY_MOD, "\033[3~", +1, 0 },
- { XK_KP_Multiply, XK_ANY_MOD, "\033Oj", +2, 0 },
- { XK_KP_Add, XK_ANY_MOD, "\033Ok", +2, 0 },
- { XK_KP_Enter, XK_ANY_MOD, "\033OM", +2, 0 },
- { XK_KP_Enter, XK_ANY_MOD, "\r", -1, 0 },
- { XK_KP_Subtract, XK_ANY_MOD, "\033Om", +2, 0 },
- { XK_KP_Decimal, XK_ANY_MOD, "\033On", +2, 0 },
- { XK_KP_Divide, XK_ANY_MOD, "\033Oo", +2, 0 },
- { XK_KP_0, XK_ANY_MOD, "\033Op", +2, 0 },
- { XK_KP_1, XK_ANY_MOD, "\033Oq", +2, 0 },
- { XK_KP_2, XK_ANY_MOD, "\033Or", +2, 0 },
- { XK_KP_3, XK_ANY_MOD, "\033Os", +2, 0 },
- { XK_KP_4, XK_ANY_MOD, "\033Ot", +2, 0 },
- { XK_KP_5, XK_ANY_MOD, "\033Ou", +2, 0 },
- { XK_KP_6, XK_ANY_MOD, "\033Ov", +2, 0 },
- { XK_KP_7, XK_ANY_MOD, "\033Ow", +2, 0 },
- { XK_KP_8, XK_ANY_MOD, "\033Ox", +2, 0 },
- { XK_KP_9, XK_ANY_MOD, "\033Oy", +2, 0 },
- { XK_Up, ShiftMask, "\033[1;2A", 0, 0 },
- { XK_Up, Mod1Mask, "\033[1;3A", 0, 0 },
- { XK_Up, ShiftMask | Mod1Mask, "\033[1;4A", 0, 0 },
- { XK_Up, ControlMask, "\033[1;5A", 0, 0 },
- { XK_Up, ShiftMask | ControlMask, "\033[1;6A", 0, 0 },
- { XK_Up, ControlMask | Mod1Mask, "\033[1;7A", 0, 0 },
- { XK_Up, ShiftMask | ControlMask | Mod1Mask, "\033[1;8A", 0, 0 },
- { XK_Up, XK_ANY_MOD, "\033[A", 0, -1 },
- { XK_Up, XK_ANY_MOD, "\033OA", 0, +1 },
- { XK_Down, ShiftMask, "\033[1;2B", 0, 0 },
- { XK_Down, Mod1Mask, "\033[1;3B", 0, 0 },
- { XK_Down, ShiftMask | Mod1Mask, "\033[1;4B", 0, 0 },
- { XK_Down, ControlMask, "\033[1;5B", 0, 0 },
- { XK_Down, ShiftMask | ControlMask, "\033[1;6B", 0, 0 },
- { XK_Down, ControlMask | Mod1Mask, "\033[1;7B", 0, 0 },
- { XK_Down, ShiftMask | ControlMask | Mod1Mask, "\033[1;8B", 0, 0 },
- { XK_Down, XK_ANY_MOD, "\033[B", 0, -1 },
- { XK_Down, XK_ANY_MOD, "\033OB", 0, +1 },
- { XK_Left, ShiftMask, "\033[1;2D", 0, 0 },
- { XK_Left, Mod1Mask, "\033[1;3D", 0, 0 },
- { XK_Left, ShiftMask | Mod1Mask, "\033[1;4D", 0, 0 },
- { XK_Left, ControlMask, "\033[1;5D", 0, 0 },
- { XK_Left, ShiftMask | ControlMask, "\033[1;6D", 0, 0 },
- { XK_Left, ControlMask | Mod1Mask, "\033[1;7D", 0, 0 },
- { XK_Left, ShiftMask | ControlMask | Mod1Mask, "\033[1;8D", 0, 0 },
- { XK_Left, XK_ANY_MOD, "\033[D", 0, -1 },
- { XK_Left, XK_ANY_MOD, "\033OD", 0, +1 },
- { XK_Right, ShiftMask, "\033[1;2C", 0, 0 },
- { XK_Right, Mod1Mask, "\033[1;3C", 0, 0 },
- { XK_Right, ShiftMask | Mod1Mask, "\033[1;4C", 0, 0 },
- { XK_Right, ControlMask, "\033[1;5C", 0, 0 },
- { XK_Right, ShiftMask | ControlMask, "\033[1;6C", 0, 0 },
- { XK_Right, ControlMask | Mod1Mask, "\033[1;7C", 0, 0 },
- { XK_Right, ShiftMask | ControlMask | Mod1Mask, "\033[1;8C", 0, 0 },
- { XK_Right, XK_ANY_MOD, "\033[C", 0, -1 },
- { XK_Right, XK_ANY_MOD, "\033OC", 0, +1 },
- { XK_ISO_Left_Tab, ShiftMask, "\033[Z", 0, 0 },
- { XK_Return, Mod1Mask, "\033\r", 0, 0 },
- { XK_Return, XK_ANY_MOD, "\r", 0, 0 },
- { XK_Insert, ShiftMask, "\033[4l", -1, 0 },
- { XK_Insert, ShiftMask, "\033[2;2~", +1, 0 },
- { XK_Insert, ControlMask, "\033[L", -1, 0 },
- { XK_Insert, ControlMask, "\033[2;5~", +1, 0 },
- { XK_Insert, XK_ANY_MOD, "\033[4h", -1, 0 },
- { XK_Insert, XK_ANY_MOD, "\033[2~", +1, 0 },
- { XK_Delete, ControlMask, "\033[M", -1, 0 },
- { XK_Delete, ControlMask, "\033[3;5~", +1, 0 },
- { XK_Delete, ShiftMask, "\033[2K", -1, 0 },
- { XK_Delete, ShiftMask, "\033[3;2~", +1, 0 },
- { XK_Delete, XK_ANY_MOD, "\033[P", -1, 0 },
- { XK_Delete, XK_ANY_MOD, "\033[3~", +1, 0 },
- { XK_BackSpace, XK_NO_MOD, "\177", 0, 0 },
- { XK_BackSpace, Mod1Mask, "\033\177", 0, 0 },
- { XK_Home, ShiftMask, "\033[2J", 0, -1 },
- { XK_Home, ShiftMask, "\033[1;2H", 0, +1 },
- { XK_Home, XK_ANY_MOD, "\033[H", 0, -1 },
- { XK_Home, XK_ANY_MOD, "\033[1~", 0, +1 },
- { XK_End, ControlMask, "\033[J", -1, 0 },
- { XK_End, ControlMask, "\033[1;5F", +1, 0 },
- { XK_End, ShiftMask, "\033[K", -1, 0 },
- { XK_End, ShiftMask, "\033[1;2F", +1, 0 },
- { XK_End, XK_ANY_MOD, "\033[4~", 0, 0 },
- { XK_Prior, ControlMask, "\033[5;5~", 0, 0 },
- { XK_Prior, ShiftMask, "\033[5;2~", 0, 0 },
- { XK_Prior, XK_ANY_MOD, "\033[5~", 0, 0 },
- { XK_Next, ControlMask, "\033[6;5~", 0, 0 },
- { XK_Next, ShiftMask, "\033[6;2~", 0, 0 },
- { XK_Next, XK_ANY_MOD, "\033[6~", 0, 0 },
- { XK_F1, XK_NO_MOD, "\033OP", 0, 0 },
- { XK_F1, /* F13 */ ShiftMask, "\033[1;2P", 0, 0 },
- { XK_F1, /* F25 */ ControlMask, "\033[1;5P", 0, 0 },
- { XK_F1, /* F37 */ Mod4Mask, "\033[1;6P", 0, 0 },
- { XK_F1, /* F49 */ Mod1Mask, "\033[1;3P", 0, 0 },
- { XK_F1, /* F61 */ Mod3Mask, "\033[1;4P", 0, 0 },
- { XK_F2, XK_NO_MOD, "\033OQ", 0, 0 },
- { XK_F2, /* F14 */ ShiftMask, "\033[1;2Q", 0, 0 },
- { XK_F2, /* F26 */ ControlMask, "\033[1;5Q", 0, 0 },
- { XK_F2, /* F38 */ Mod4Mask, "\033[1;6Q", 0, 0 },
- { XK_F2, /* F50 */ Mod1Mask, "\033[1;3Q", 0, 0 },
- { XK_F2, /* F62 */ Mod3Mask, "\033[1;4Q", 0, 0 },
- { XK_F3, XK_NO_MOD, "\033OR", 0, 0 },
- { XK_F3, /* F15 */ ShiftMask, "\033[1;2R", 0, 0 },
- { XK_F3, /* F27 */ ControlMask, "\033[1;5R", 0, 0 },
- { XK_F3, /* F39 */ Mod4Mask, "\033[1;6R", 0, 0 },
- { XK_F3, /* F51 */ Mod1Mask, "\033[1;3R", 0, 0 },
- { XK_F3, /* F63 */ Mod3Mask, "\033[1;4R", 0, 0 },
- { XK_F4, XK_NO_MOD, "\033OS", 0, 0 },
- { XK_F4, /* F16 */ ShiftMask, "\033[1;2S", 0, 0 },
- { XK_F4, /* F28 */ ControlMask, "\033[1;5S", 0, 0 },
- { XK_F4, /* F40 */ Mod4Mask, "\033[1;6S", 0, 0 },
- { XK_F4, /* F52 */ Mod1Mask, "\033[1;3S", 0, 0 },
- { XK_F5, XK_NO_MOD, "\033[15~", 0, 0 },
- { XK_F5, /* F17 */ ShiftMask, "\033[15;2~", 0, 0 },
- { XK_F5, /* F29 */ ControlMask, "\033[15;5~", 0, 0 },
- { XK_F5, /* F41 */ Mod4Mask, "\033[15;6~", 0, 0 },
- { XK_F5, /* F53 */ Mod1Mask, "\033[15;3~", 0, 0 },
- { XK_F6, XK_NO_MOD, "\033[17~", 0, 0 },
- { XK_F6, /* F18 */ ShiftMask, "\033[17;2~", 0, 0 },
- { XK_F6, /* F30 */ ControlMask, "\033[17;5~", 0, 0 },
- { XK_F6, /* F42 */ Mod4Mask, "\033[17;6~", 0, 0 },
- { XK_F6, /* F54 */ Mod1Mask, "\033[17;3~", 0, 0 },
- { XK_F7, XK_NO_MOD, "\033[18~", 0, 0 },
- { XK_F7, /* F19 */ ShiftMask, "\033[18;2~", 0, 0 },
- { XK_F7, /* F31 */ ControlMask, "\033[18;5~", 0, 0 },
- { XK_F7, /* F43 */ Mod4Mask, "\033[18;6~", 0, 0 },
- { XK_F7, /* F55 */ Mod1Mask, "\033[18;3~", 0, 0 },
- { XK_F8, XK_NO_MOD, "\033[19~", 0, 0 },
- { XK_F8, /* F20 */ ShiftMask, "\033[19;2~", 0, 0 },
- { XK_F8, /* F32 */ ControlMask, "\033[19;5~", 0, 0 },
- { XK_F8, /* F44 */ Mod4Mask, "\033[19;6~", 0, 0 },
- { XK_F8, /* F56 */ Mod1Mask, "\033[19;3~", 0, 0 },
- { XK_F9, XK_NO_MOD, "\033[20~", 0, 0 },
- { XK_F9, /* F21 */ ShiftMask, "\033[20;2~", 0, 0 },
- { XK_F9, /* F33 */ ControlMask, "\033[20;5~", 0, 0 },
- { XK_F9, /* F45 */ Mod4Mask, "\033[20;6~", 0, 0 },
- { XK_F9, /* F57 */ Mod1Mask, "\033[20;3~", 0, 0 },
- { XK_F10, XK_NO_MOD, "\033[21~", 0, 0 },
- { XK_F10, /* F22 */ ShiftMask, "\033[21;2~", 0, 0 },
- { XK_F10, /* F34 */ ControlMask, "\033[21;5~", 0, 0 },
- { XK_F10, /* F46 */ Mod4Mask, "\033[21;6~", 0, 0 },
- { XK_F10, /* F58 */ Mod1Mask, "\033[21;3~", 0, 0 },
- { XK_F11, XK_NO_MOD, "\033[23~", 0, 0 },
- { XK_F11, /* F23 */ ShiftMask, "\033[23;2~", 0, 0 },
- { XK_F11, /* F35 */ ControlMask, "\033[23;5~", 0, 0 },
- { XK_F11, /* F47 */ Mod4Mask, "\033[23;6~", 0, 0 },
- { XK_F11, /* F59 */ Mod1Mask, "\033[23;3~", 0, 0 },
- { XK_F12, XK_NO_MOD, "\033[24~", 0, 0 },
- { XK_F12, /* F24 */ ShiftMask, "\033[24;2~", 0, 0 },
- { XK_F12, /* F36 */ ControlMask, "\033[24;5~", 0, 0 },
- { XK_F12, /* F48 */ Mod4Mask, "\033[24;6~", 0, 0 },
- { XK_F12, /* F60 */ Mod1Mask, "\033[24;3~", 0, 0 },
- { XK_F13, XK_NO_MOD, "\033[1;2P", 0, 0 },
- { XK_F14, XK_NO_MOD, "\033[1;2Q", 0, 0 },
- { XK_F15, XK_NO_MOD, "\033[1;2R", 0, 0 },
- { XK_F16, XK_NO_MOD, "\033[1;2S", 0, 0 },
- { XK_F17, XK_NO_MOD, "\033[15;2~", 0, 0 },
- { XK_F18, XK_NO_MOD, "\033[17;2~", 0, 0 },
- { XK_F19, XK_NO_MOD, "\033[18;2~", 0, 0 },
- { XK_F20, XK_NO_MOD, "\033[19;2~", 0, 0 },
- { XK_F21, XK_NO_MOD, "\033[20;2~", 0, 0 },
- { XK_F22, XK_NO_MOD, "\033[21;2~", 0, 0 },
- { XK_F23, XK_NO_MOD, "\033[23;2~", 0, 0 },
- { XK_F24, XK_NO_MOD, "\033[24;2~", 0, 0 },
- { XK_F25, XK_NO_MOD, "\033[1;5P", 0, 0 },
- { XK_F26, XK_NO_MOD, "\033[1;5Q", 0, 0 },
- { XK_F27, XK_NO_MOD, "\033[1;5R", 0, 0 },
- { XK_F28, XK_NO_MOD, "\033[1;5S", 0, 0 },
- { XK_F29, XK_NO_MOD, "\033[15;5~", 0, 0 },
- { XK_F30, XK_NO_MOD, "\033[17;5~", 0, 0 },
- { XK_F31, XK_NO_MOD, "\033[18;5~", 0, 0 },
- { XK_F32, XK_NO_MOD, "\033[19;5~", 0, 0 },
- { XK_F33, XK_NO_MOD, "\033[20;5~", 0, 0 },
- { XK_F34, XK_NO_MOD, "\033[21;5~", 0, 0 },
- { XK_F35, XK_NO_MOD, "\033[23;5~", 0, 0 },
-};
-
-/*
- * Selection types' masks.
- * Use the same masks as usual.
- * Button1Mask is always unset, to make masks match between ButtonPress.
- * ButtonRelease and MotionNotify.
- * If no match is found, regular selection is used.
- */
-static uint selmasks[] = {
- [SEL_RECTANGULAR] = Mod1Mask,
-};
-
-/*
- * Printable characters in ASCII, used to estimate the advance width
- * of single wide characters.
- */
-static char ascii_printable[] = " !\"#$%&'()*+,-./0123456789:;<=>?"
- "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_"
- "`abcdefghijklmnopqrstuvwxyz{|}~";
diff --git a/.repos/st/config.mk b/.repos/st/config.mk
deleted file mode 100644
index c070a4a..0000000
--- a/.repos/st/config.mk
+++ /dev/null
@@ -1,35 +0,0 @@
-# st version
-VERSION = 0.8.4
-
-# Customize below to fit your system
-
-# paths
-PREFIX = /usr/local
-MANPREFIX = $(PREFIX)/share/man
-
-X11INC = /usr/X11R6/include
-X11LIB = /usr/X11R6/lib
-
-PKG_CONFIG = pkg-config
-
-# includes and libs
-INCS = -I$(X11INC) \
- `$(PKG_CONFIG) --cflags fontconfig` \
- `$(PKG_CONFIG) --cflags freetype2`
-LIBS = -L$(X11LIB) -lm -lrt -lX11 -lutil -lXft \
- `$(PKG_CONFIG) --libs fontconfig` \
- `$(PKG_CONFIG) --libs freetype2`
-
-# flags
-STCPPFLAGS = -DVERSION=\"$(VERSION)\" -D_XOPEN_SOURCE=600
-STCFLAGS = $(INCS) $(STCPPFLAGS) $(CPPFLAGS) $(CFLAGS)
-STLDFLAGS = $(LIBS) $(LDFLAGS)
-
-# OpenBSD:
-#CPPFLAGS = -DVERSION=\"$(VERSION)\" -D_XOPEN_SOURCE=600 -D_BSD_SOURCE
-#LIBS = -L$(X11LIB) -lm -lX11 -lutil -lXft \
-# `$(PKG_CONFIG) --libs fontconfig` \
-# `$(PKG_CONFIG) --libs freetype2`
-
-# compiler and linker
-# CC = c99
diff --git a/.repos/st/patches/st-scrollback-20210507-4536f46.diff b/.repos/st/patches/st-scrollback-20210507-4536f46.diff
deleted file mode 100644
index f960f6b..0000000
--- a/.repos/st/patches/st-scrollback-20210507-4536f46.diff
+++ /dev/null
@@ -1,351 +0,0 @@
-diff --git a/config.def.h b/config.def.h
-index 6f05dce..93cbcc0 100644
---- a/config.def.h
-+++ b/config.def.h
-@@ -199,6 +199,8 @@ static Shortcut shortcuts[] = {
- { TERMMOD, XK_Y, selpaste, {.i = 0} },
- { ShiftMask, XK_Insert, selpaste, {.i = 0} },
- { TERMMOD, XK_Num_Lock, numlock, {.i = 0} },
-+ { ShiftMask, XK_Page_Up, kscrollup, {.i = -1} },
-+ { ShiftMask, XK_Page_Down, kscrolldown, {.i = -1} },
- };
-
- /*
-diff --git a/st.c b/st.c
-index ebdf360..817cc47 100644
---- a/st.c
-+++ b/st.c
-@@ -35,6 +35,7 @@
- #define ESC_ARG_SIZ 16
- #define STR_BUF_SIZ ESC_BUF_SIZ
- #define STR_ARG_SIZ ESC_ARG_SIZ
-+#define HISTSIZE 2000
-
- /* macros */
- #define IS_SET(flag) ((term.mode & (flag)) != 0)
-@@ -42,6 +43,9 @@
- #define ISCONTROLC1(c) (BETWEEN(c, 0x80, 0x9f))
- #define ISCONTROL(c) (ISCONTROLC0(c) || ISCONTROLC1(c))
- #define ISDELIM(u) (u && wcschr(worddelimiters, u))
-+#define TLINE(y) ((y) < term.scr ? term.hist[((y) + term.histi - \
-+ term.scr + HISTSIZE + 1) % HISTSIZE] : \
-+ term.line[(y) - term.scr])
-
- enum term_mode {
- MODE_WRAP = 1 << 0,
-@@ -115,6 +119,9 @@ typedef struct {
- int col; /* nb col */
- Line *line; /* screen */
- Line *alt; /* alternate screen */
-+ Line hist[HISTSIZE]; /* history buffer */
-+ int histi; /* history index */
-+ int scr; /* scroll back */
- int *dirty; /* dirtyness of lines */
- TCursor c; /* cursor */
- int ocx; /* old cursor col */
-@@ -184,8 +191,8 @@ static void tnewline(int);
- static void tputtab(int);
- static void tputc(Rune);
- static void treset(void);
--static void tscrollup(int, int);
--static void tscrolldown(int, int);
-+static void tscrollup(int, int, int);
-+static void tscrolldown(int, int, int);
- static void tsetattr(const int *, int);
- static void tsetchar(Rune, const Glyph *, int, int);
- static void tsetdirt(int, int);
-@@ -416,10 +423,10 @@ tlinelen(int y)
- {
- int i = term.col;
-
-- if (term.line[y][i - 1].mode & ATTR_WRAP)
-+ if (TLINE(y)[i - 1].mode & ATTR_WRAP)
- return i;
-
-- while (i > 0 && term.line[y][i - 1].u == ' ')
-+ while (i > 0 && TLINE(y)[i - 1].u == ' ')
- --i;
-
- return i;
-@@ -528,7 +535,7 @@ selsnap(int *x, int *y, int direction)
- * Snap around if the word wraps around at the end or
- * beginning of a line.
- */
-- prevgp = &term.line[*y][*x];
-+ prevgp = &TLINE(*y)[*x];
- prevdelim = ISDELIM(prevgp->u);
- for (;;) {
- newx = *x + direction;
-@@ -543,14 +550,14 @@ selsnap(int *x, int *y, int direction)
- yt = *y, xt = *x;
- else
- yt = newy, xt = newx;
-- if (!(term.line[yt][xt].mode & ATTR_WRAP))
-+ if (!(TLINE(yt)[xt].mode & ATTR_WRAP))
- break;
- }
-
- if (newx >= tlinelen(newy))
- break;
-
-- gp = &term.line[newy][newx];
-+ gp = &TLINE(newy)[newx];
- delim = ISDELIM(gp->u);
- if (!(gp->mode & ATTR_WDUMMY) && (delim != prevdelim
- || (delim && gp->u != prevgp->u)))
-@@ -571,14 +578,14 @@ selsnap(int *x, int *y, int direction)
- *x = (direction < 0) ? 0 : term.col - 1;
- if (direction < 0) {
- for (; *y > 0; *y += direction) {
-- if (!(term.line[*y-1][term.col-1].mode
-+ if (!(TLINE(*y-1)[term.col-1].mode
- & ATTR_WRAP)) {
- break;
- }
- }
- } else if (direction > 0) {
- for (; *y < term.row-1; *y += direction) {
-- if (!(term.line[*y][term.col-1].mode
-+ if (!(TLINE(*y)[term.col-1].mode
- & ATTR_WRAP)) {
- break;
- }
-@@ -609,13 +616,13 @@ getsel(void)
- }
-
- if (sel.type == SEL_RECTANGULAR) {
-- gp = &term.line[y][sel.nb.x];
-+ gp = &TLINE(y)[sel.nb.x];
- lastx = sel.ne.x;
- } else {
-- gp = &term.line[y][sel.nb.y == y ? sel.nb.x : 0];
-+ gp = &TLINE(y)[sel.nb.y == y ? sel.nb.x : 0];
- lastx = (sel.ne.y == y) ? sel.ne.x : term.col-1;
- }
-- last = &term.line[y][MIN(lastx, linelen-1)];
-+ last = &TLINE(y)[MIN(lastx, linelen-1)];
- while (last >= gp && last->u == ' ')
- --last;
-
-@@ -850,6 +857,9 @@ void
- ttywrite(const char *s, size_t n, int may_echo)
- {
- const char *next;
-+ Arg arg = (Arg) { .i = term.scr };
-+
-+ kscrolldown(&arg);
-
- if (may_echo && IS_SET(MODE_ECHO))
- twrite(s, n, 1);
-@@ -1061,13 +1071,53 @@ tswapscreen(void)
- }
-
- void
--tscrolldown(int orig, int n)
-+kscrolldown(const Arg* a)
-+{
-+ int n = a->i;
-+
-+ if (n < 0)
-+ n = term.row + n;
-+
-+ if (n > term.scr)
-+ n = term.scr;
-+
-+ if (term.scr > 0) {
-+ term.scr -= n;
-+ selscroll(0, -n);
-+ tfulldirt();
-+ }
-+}
-+
-+void
-+kscrollup(const Arg* a)
-+{
-+ int n = a->i;
-+
-+ if (n < 0)
-+ n = term.row + n;
-+
-+ if (term.scr <= HISTSIZE-n) {
-+ term.scr += n;
-+ selscroll(0, n);
-+ tfulldirt();
-+ }
-+}
-+
-+void
-+tscrolldown(int orig, int n, int copyhist)
- {
- int i;
- Line temp;
-
- LIMIT(n, 0, term.bot-orig+1);
-
-+ if (copyhist) {
-+ term.histi = (term.histi - 1 + HISTSIZE) % HISTSIZE;
-+ temp = term.hist[term.histi];
-+ term.hist[term.histi] = term.line[term.bot];
-+ term.line[term.bot] = temp;
-+ }
-+
- tsetdirt(orig, term.bot-n);
- tclearregion(0, term.bot-n+1, term.col-1, term.bot);
-
-@@ -1077,17 +1127,28 @@ tscrolldown(int orig, int n)
- term.line[i-n] = temp;
- }
-
-- selscroll(orig, n);
-+ if (term.scr == 0)
-+ selscroll(orig, n);
- }
-
- void
--tscrollup(int orig, int n)
-+tscrollup(int orig, int n, int copyhist)
- {
- int i;
- Line temp;
-
- LIMIT(n, 0, term.bot-orig+1);
-
-+ if (copyhist) {
-+ term.histi = (term.histi + 1) % HISTSIZE;
-+ temp = term.hist[term.histi];
-+ term.hist[term.histi] = term.line[orig];
-+ term.line[orig] = temp;
-+ }
-+
-+ if (term.scr > 0 && term.scr < HISTSIZE)
-+ term.scr = MIN(term.scr + n, HISTSIZE-1);
-+
- tclearregion(0, orig, term.col-1, orig+n-1);
- tsetdirt(orig+n, term.bot);
-
-@@ -1097,7 +1158,8 @@ tscrollup(int orig, int n)
- term.line[i+n] = temp;
- }
-
-- selscroll(orig, -n);
-+ if (term.scr == 0)
-+ selscroll(orig, -n);
- }
-
- void
-@@ -1126,7 +1188,7 @@ tnewline(int first_col)
- int y = term.c.y;
-
- if (y == term.bot) {
-- tscrollup(term.top, 1);
-+ tscrollup(term.top, 1, 1);
- } else {
- y++;
- }
-@@ -1291,14 +1353,14 @@ void
- tinsertblankline(int n)
- {
- if (BETWEEN(term.c.y, term.top, term.bot))
-- tscrolldown(term.c.y, n);
-+ tscrolldown(term.c.y, n, 0);
- }
-
- void
- tdeleteline(int n)
- {
- if (BETWEEN(term.c.y, term.top, term.bot))
-- tscrollup(term.c.y, n);
-+ tscrollup(term.c.y, n, 0);
- }
-
- int32_t
-@@ -1735,11 +1797,11 @@ csihandle(void)
- break;
- case 'S': /* SU -- Scroll <n> line up */
- DEFAULT(csiescseq.arg[0], 1);
-- tscrollup(term.top, csiescseq.arg[0]);
-+ tscrollup(term.top, csiescseq.arg[0], 0);
- break;
- case 'T': /* SD -- Scroll <n> line down */
- DEFAULT(csiescseq.arg[0], 1);
-- tscrolldown(term.top, csiescseq.arg[0]);
-+ tscrolldown(term.top, csiescseq.arg[0], 0);
- break;
- case 'L': /* IL -- Insert <n> blank lines */
- DEFAULT(csiescseq.arg[0], 1);
-@@ -2251,7 +2313,7 @@ eschandle(uchar ascii)
- return 0;
- case 'D': /* IND -- Linefeed */
- if (term.c.y == term.bot) {
-- tscrollup(term.top, 1);
-+ tscrollup(term.top, 1, 1);
- } else {
- tmoveto(term.c.x, term.c.y+1);
- }
-@@ -2264,7 +2326,7 @@ eschandle(uchar ascii)
- break;
- case 'M': /* RI -- Reverse index */
- if (term.c.y == term.top) {
-- tscrolldown(term.top, 1);
-+ tscrolldown(term.top, 1, 1);
- } else {
- tmoveto(term.c.x, term.c.y-1);
- }
-@@ -2474,7 +2536,7 @@ twrite(const char *buf, int buflen, int show_ctrl)
- void
- tresize(int col, int row)
- {
-- int i;
-+ int i, j;
- int minrow = MIN(row, term.row);
- int mincol = MIN(col, term.col);
- int *bp;
-@@ -2511,6 +2573,14 @@ tresize(int col, int row)
- term.dirty = xrealloc(term.dirty, row * sizeof(*term.dirty));
- term.tabs = xrealloc(term.tabs, col * sizeof(*term.tabs));
-
-+ for (i = 0; i < HISTSIZE; i++) {
-+ term.hist[i] = xrealloc(term.hist[i], col * sizeof(Glyph));
-+ for (j = mincol; j < col; j++) {
-+ term.hist[i][j] = term.c.attr;
-+ term.hist[i][j].u = ' ';
-+ }
-+ }
-+
- /* resize each row to new width, zero-pad if needed */
- for (i = 0; i < minrow; i++) {
- term.line[i] = xrealloc(term.line[i], col * sizeof(Glyph));
-@@ -2569,7 +2639,7 @@ drawregion(int x1, int y1, int x2, int y2)
- continue;
-
- term.dirty[y] = 0;
-- xdrawline(term.line[y], x1, y, x2);
-+ xdrawline(TLINE(y), x1, y, x2);
- }
- }
-
-@@ -2590,8 +2660,9 @@ draw(void)
- cx--;
-
- drawregion(0, 0, term.col, term.row);
-- xdrawcursor(cx, term.c.y, term.line[term.c.y][cx],
-- term.ocx, term.ocy, term.line[term.ocy][term.ocx]);
-+ if (term.scr == 0)
-+ xdrawcursor(cx, term.c.y, term.line[term.c.y][cx],
-+ term.ocx, term.ocy, term.line[term.ocy][term.ocx]);
- term.ocx = cx;
- term.ocy = term.c.y;
- xfinishdraw();
-diff --git a/st.h b/st.h
-index fa2eddf..adda2db 100644
---- a/st.h
-+++ b/st.h
-@@ -81,6 +81,8 @@ void die(const char *, ...);
- void redraw(void);
- void draw(void);
-
-+void kscrolldown(const Arg *);
-+void kscrollup(const Arg *);
- void printscreen(const Arg *);
- void printsel(const Arg *);
- void sendbreak(const Arg *);
diff --git a/.repos/st/patches/st-scrollback-mouse-20191024-a2c479c.diff b/.repos/st/patches/st-scrollback-mouse-20191024-a2c479c.diff
deleted file mode 100644
index 49eba8e..0000000
--- a/.repos/st/patches/st-scrollback-mouse-20191024-a2c479c.diff
+++ /dev/null
@@ -1,13 +0,0 @@
-diff --git a/config.def.h b/config.def.h
-index ec1b576..4b3bf15 100644
---- a/config.def.h
-+++ b/config.def.h
-@@ -163,6 +163,8 @@ static uint forcemousemod = ShiftMask;
- */
- static MouseShortcut mshortcuts[] = {
- /* mask button function argument release */
-+ { ShiftMask, Button4, kscrollup, {.i = 1} },
-+ { ShiftMask, Button5, kscrolldown, {.i = 1} },
- { XK_ANY_MOD, Button2, selpaste, {.i = 0}, 1 },
- { XK_ANY_MOD, Button4, ttysend, {.s = "\031"} },
- { XK_ANY_MOD, Button5, ttysend, {.s = "\005"} },
diff --git a/.repos/st/st b/.repos/st/st
deleted file mode 100755
index 811dae4..0000000
--- a/.repos/st/st
+++ /dev/null
Binary files differ
diff --git a/.repos/st/st-copyout b/.repos/st/st-copyout
deleted file mode 100755
index 0d19e5a..0000000
--- a/.repos/st/st-copyout
+++ /dev/null
@@ -1,13 +0,0 @@
-#!/bin/sh
-# Using external pipe with st, give a dmenu prompt of recent commands,
-# allowing the user to copy the output of one.
-# xclip required for this script.
-# By Jaywalker and Luke
-tmpfile=$(mktemp /tmp/st-cmd-output.XXXXXX)
-trap 'rm "$tmpfile"' 0 1 15
-sed -n "w $tmpfile"
-sed -i 's/\x0//g' "$tmpfile"
-ps1="$(grep "\S" "$tmpfile" | tail -n 1 | sed 's/^\s*//' | cut -d' ' -f1)"
-chosen="$(grep -F "$ps1" "$tmpfile" | sed '$ d' | tac | dmenu -p "Copy which command's output?" -i -l 10 | sed 's/[^^]/[&]/g; s/\^/\\^/g')"
-eps1="$(echo "$ps1" | sed 's/[^^]/[&]/g; s/\^/\\^/g')"
-awk "/^$chosen$/{p=1;print;next} p&&/$eps1/{p=0};p" "$tmpfile" | xclip -selection clipboard
diff --git a/.repos/st/st-urlhandler b/.repos/st/st-urlhandler
deleted file mode 100755
index d44bb99..0000000
--- a/.repos/st/st-urlhandler
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/bin/sh
-
-urlregex="(((http|https)://|www\\.)[a-zA-Z0-9.]*[:]?[a-zA-Z0-9./@$&%?$#=_-]*)|((magnet:\\?xt=urn:btih:)[a-zA-Z0-9]*)"
-
-# First remove linebreaks and mutt sidebars:
-urls="$(sed 's/.*│//g' | tr -d '\n' |
- grep -aEo "$urlregex" | # grep only urls as defined above.
- uniq | # Ignore neighboring duplicates.
- sed 's/^www./http:\/\/www\./g')"
-
-[ -z "$urls" ] && exit
-
-chosen="$(echo "$urls" | dmenu -i -p 'Follow which url?' -l 10)"
-
-setsid xdg-open "$chosen" >/dev/null 2>&1 &
diff --git a/.repos/st/st.1 b/.repos/st/st.1
deleted file mode 100644
index 39120b4..0000000
--- a/.repos/st/st.1
+++ /dev/null
@@ -1,177 +0,0 @@
-.TH ST 1 st\-VERSION
-.SH NAME
-st \- simple terminal
-.SH SYNOPSIS
-.B st
-.RB [ \-aiv ]
-.RB [ \-c
-.IR class ]
-.RB [ \-f
-.IR font ]
-.RB [ \-g
-.IR geometry ]
-.RB [ \-n
-.IR name ]
-.RB [ \-o
-.IR iofile ]
-.RB [ \-T
-.IR title ]
-.RB [ \-t
-.IR title ]
-.RB [ \-l
-.IR line ]
-.RB [ \-w
-.IR windowid ]
-.RB [[ \-e ]
-.IR command
-.RI [ arguments ...]]
-.PP
-.B st
-.RB [ \-aiv ]
-.RB [ \-c
-.IR class ]
-.RB [ \-f
-.IR font ]
-.RB [ \-g
-.IR geometry ]
-.RB [ \-n
-.IR name ]
-.RB [ \-o
-.IR iofile ]
-.RB [ \-T
-.IR title ]
-.RB [ \-t
-.IR title ]
-.RB [ \-w
-.IR windowid ]
-.RB \-l
-.IR line
-.RI [ stty_args ...]
-.SH DESCRIPTION
-.B st
-is a simple terminal emulator.
-.SH OPTIONS
-.TP
-.B \-a
-disable alternate screens in terminal
-.TP
-.BI \-c " class"
-defines the window class (default $TERM).
-.TP
-.BI \-f " font"
-defines the
-.I font
-to use when st is run.
-.TP
-.BI \-g " geometry"
-defines the X11 geometry string.
-The form is [=][<cols>{xX}<rows>][{+-}<xoffset>{+-}<yoffset>]. See
-.BR XParseGeometry (3)
-for further details.
-.TP
-.B \-i
-will fixate the position given with the -g option.
-.TP
-.BI \-n " name"
-defines the window instance name (default $TERM).
-.TP
-.BI \-o " iofile"
-writes all the I/O to
-.I iofile.
-This feature is useful when recording st sessions. A value of "-" means
-standard output.
-.TP
-.BI \-T " title"
-defines the window title (default 'st').
-.TP
-.BI \-t " title"
-defines the window title (default 'st').
-.TP
-.BI \-w " windowid"
-embeds st within the window identified by
-.I windowid
-.TP
-.BI \-l " line"
-use a tty
-.I line
-instead of a pseudo terminal.
-.I line
-should be a (pseudo-)serial device (e.g. /dev/ttyS0 on Linux for serial port
-0).
-When this flag is given
-remaining arguments are used as flags for
-.BR stty(1).
-By default st initializes the serial line to 8 bits, no parity, 1 stop bit
-and a 38400 baud rate. The speed is set by appending it as last argument
-(e.g. 'st -l /dev/ttyS0 115200'). Arguments before the last one are
-.BR stty(1)
-flags. If you want to set odd parity on 115200 baud use for example 'st -l
-/dev/ttyS0 parenb parodd 115200'. Set the number of bits by using for
-example 'st -l /dev/ttyS0 cs7 115200'. See
-.BR stty(1)
-for more arguments and cases.
-.TP
-.B \-v
-prints version information to stderr, then exits.
-.TP
-.BI \-e " command " [ " arguments " "... ]"
-st executes
-.I command
-instead of the shell. If this is used it
-.B must be the last option
-on the command line, as in xterm / rxvt.
-This option is only intended for compatibility,
-and all the remaining arguments are used as a command
-even without it.
-.SH SHORTCUTS
-.TP
-.B Break
-Send a break in the serial line.
-Break key is obtained in PC keyboards
-pressing at the same time control and pause.
-.TP
-.B Ctrl-Print Screen
-Toggle if st should print to the
-.I iofile.
-.TP
-.B Shift-Print Screen
-Print the full screen to the
-.I iofile.
-.TP
-.B Print Screen
-Print the selection to the
-.I iofile.
-.TP
-.B Ctrl-Shift-Page Up
-Increase font size.
-.TP
-.B Ctrl-Shift-Page Down
-Decrease font size.
-.TP
-.B Ctrl-Shift-Home
-Reset to default font size.
-.TP
-.B Ctrl-Shift-y
-Paste from primary selection (middle mouse button).
-.TP
-.B Ctrl-Shift-c
-Copy the selected text to the clipboard selection.
-.TP
-.B Ctrl-Shift-v
-Paste from the clipboard selection.
-.SH CUSTOMIZATION
-.B st
-can be customized by creating a custom config.h and (re)compiling the source
-code. This keeps it fast, secure and simple.
-.SH AUTHORS
-See the LICENSE file for the authors.
-.SH LICENSE
-See the LICENSE file for the terms of redistribution.
-.SH SEE ALSO
-.BR tabbed (1),
-.BR utmp (1),
-.BR stty (1),
-.BR scroll (1)
-.SH BUGS
-See the TODO file in the distribution.
-
diff --git a/.repos/st/st.c b/.repos/st/st.c
deleted file mode 100644
index 1934bcf..0000000
--- a/.repos/st/st.c
+++ /dev/null
@@ -1,2679 +0,0 @@
-/* See LICENSE for license details. */
-#include <ctype.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <pwd.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <signal.h>
-#include <sys/ioctl.h>
-#include <sys/select.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <termios.h>
-#include <unistd.h>
-#include <wchar.h>
-
-#include "st.h"
-#include "win.h"
-
-#if defined(__linux)
- #include <pty.h>
-#elif defined(__OpenBSD__) || defined(__NetBSD__) || defined(__APPLE__)
- #include <util.h>
-#elif defined(__FreeBSD__) || defined(__DragonFly__)
- #include <libutil.h>
-#endif
-
-/* Arbitrary sizes */
-#define UTF_INVALID 0xFFFD
-#define UTF_SIZ 4
-#define ESC_BUF_SIZ (128*UTF_SIZ)
-#define ESC_ARG_SIZ 16
-#define STR_BUF_SIZ ESC_BUF_SIZ
-#define STR_ARG_SIZ ESC_ARG_SIZ
-#define HISTSIZE 2000
-
-/* macros */
-#define IS_SET(flag) ((term.mode & (flag)) != 0)
-#define ISCONTROLC0(c) (BETWEEN(c, 0, 0x1f) || (c) == 0x7f)
-#define ISCONTROLC1(c) (BETWEEN(c, 0x80, 0x9f))
-#define ISCONTROL(c) (ISCONTROLC0(c) || ISCONTROLC1(c))
-#define ISDELIM(u) (u && wcschr(worddelimiters, u))
-#define TLINE(y) ((y) < term.scr ? term.hist[((y) + term.histi - \
- term.scr + HISTSIZE + 1) % HISTSIZE] : \
- term.line[(y) - term.scr])
-
-enum term_mode {
- MODE_WRAP = 1 << 0,
- MODE_INSERT = 1 << 1,
- MODE_ALTSCREEN = 1 << 2,
- MODE_CRLF = 1 << 3,
- MODE_ECHO = 1 << 4,
- MODE_PRINT = 1 << 5,
- MODE_UTF8 = 1 << 6,
-};
-
-enum cursor_movement {
- CURSOR_SAVE,
- CURSOR_LOAD
-};
-
-enum cursor_state {
- CURSOR_DEFAULT = 0,
- CURSOR_WRAPNEXT = 1,
- CURSOR_ORIGIN = 2
-};
-
-enum charset {
- CS_GRAPHIC0,
- CS_GRAPHIC1,
- CS_UK,
- CS_USA,
- CS_MULTI,
- CS_GER,
- CS_FIN
-};
-
-enum escape_state {
- ESC_START = 1,
- ESC_CSI = 2,
- ESC_STR = 4, /* DCS, OSC, PM, APC */
- ESC_ALTCHARSET = 8,
- ESC_STR_END = 16, /* a final string was encountered */
- ESC_TEST = 32, /* Enter in test mode */
- ESC_UTF8 = 64,
-};
-
-typedef struct {
- Glyph attr; /* current char attributes */
- int x;
- int y;
- char state;
-} TCursor;
-
-typedef struct {
- int mode;
- int type;
- int snap;
- /*
- * Selection variables:
- * nb – normalized coordinates of the beginning of the selection
- * ne – normalized coordinates of the end of the selection
- * ob – original coordinates of the beginning of the selection
- * oe – original coordinates of the end of the selection
- */
- struct {
- int x, y;
- } nb, ne, ob, oe;
-
- int alt;
-} Selection;
-
-/* Internal representation of the screen */
-typedef struct {
- int row; /* nb row */
- int col; /* nb col */
- Line *line; /* screen */
- Line *alt; /* alternate screen */
- Line hist[HISTSIZE]; /* history buffer */
- int histi; /* history index */
- int scr; /* scroll back */
- int *dirty; /* dirtyness of lines */
- TCursor c; /* cursor */
- int ocx; /* old cursor col */
- int ocy; /* old cursor row */
- int top; /* top scroll limit */
- int bot; /* bottom scroll limit */
- int mode; /* terminal mode flags */
- int esc; /* escape state flags */
- char trantbl[4]; /* charset table translation */
- int charset; /* current charset */
- int icharset; /* selected charset for sequence */
- int *tabs;
- Rune lastc; /* last printed char outside of sequence, 0 if control */
-} Term;
-
-/* CSI Escape sequence structs */
-/* ESC '[' [[ [<priv>] <arg> [;]] <mode> [<mode>]] */
-typedef struct {
- char buf[ESC_BUF_SIZ]; /* raw string */
- size_t len; /* raw string length */
- char priv;
- int arg[ESC_ARG_SIZ];
- int narg; /* nb of args */
- char mode[2];
-} CSIEscape;
-
-/* STR Escape sequence structs */
-/* ESC type [[ [<priv>] <arg> [;]] <mode>] ESC '\' */
-typedef struct {
- char type; /* ESC type ... */
- char *buf; /* allocated raw string */
- size_t siz; /* allocation size */
- size_t len; /* raw string length */
- char *args[STR_ARG_SIZ];
- int narg; /* nb of args */
-} STREscape;
-
-static void execsh(char *, char **);
-static void stty(char **);
-static void sigchld(int);
-static void ttywriteraw(const char *, size_t);
-
-static void csidump(void);
-static void csihandle(void);
-static void csiparse(void);
-static void csireset(void);
-static int eschandle(uchar);
-static void strdump(void);
-static void strhandle(void);
-static void strparse(void);
-static void strreset(void);
-
-static void tprinter(char *, size_t);
-static void tdumpsel(void);
-static void tdumpline(int);
-static void tdump(void);
-static void tclearregion(int, int, int, int);
-static void tcursor(int);
-static void tdeletechar(int);
-static void tdeleteline(int);
-static void tinsertblank(int);
-static void tinsertblankline(int);
-static int tlinelen(int);
-static void tmoveto(int, int);
-static void tmoveato(int, int);
-static void tnewline(int);
-static void tputtab(int);
-static void tputc(Rune);
-static void treset(void);
-static void tscrollup(int, int, int);
-static void tscrolldown(int, int, int);
-static void tsetattr(const int *, int);
-static void tsetchar(Rune, const Glyph *, int, int);
-static void tsetdirt(int, int);
-static void tsetscroll(int, int);
-static void tswapscreen(void);
-static void tsetmode(int, int, const int *, int);
-static int twrite(const char *, int, int);
-static void tfulldirt(void);
-static void tcontrolcode(uchar );
-static void tdectest(char );
-static void tdefutf8(char);
-static int32_t tdefcolor(const int *, int *, int);
-static void tdeftran(char);
-static void tstrsequence(uchar);
-
-static void drawregion(int, int, int, int);
-
-static void selnormalize(void);
-static void selscroll(int, int);
-static void selsnap(int *, int *, int);
-
-static size_t utf8decode(const char *, Rune *, size_t);
-static Rune utf8decodebyte(char, size_t *);
-static char utf8encodebyte(Rune, size_t);
-static size_t utf8validate(Rune *, size_t);
-
-static char *base64dec(const char *);
-static char base64dec_getc(const char **);
-
-static ssize_t xwrite(int, const char *, size_t);
-
-/* Globals */
-static Term term;
-static Selection sel;
-static CSIEscape csiescseq;
-static STREscape strescseq;
-static int iofd = 1;
-static int cmdfd;
-static pid_t pid;
-
-static const uchar utfbyte[UTF_SIZ + 1] = {0x80, 0, 0xC0, 0xE0, 0xF0};
-static const uchar utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8};
-static const Rune utfmin[UTF_SIZ + 1] = { 0, 0, 0x80, 0x800, 0x10000};
-static const Rune utfmax[UTF_SIZ + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF};
-
-ssize_t
-xwrite(int fd, const char *s, size_t len)
-{
- size_t aux = len;
- ssize_t r;
-
- while (len > 0) {
- r = write(fd, s, len);
- if (r < 0)
- return r;
- len -= r;
- s += r;
- }
-
- return aux;
-}
-
-void *
-xmalloc(size_t len)
-{
- void *p;
-
- if (!(p = malloc(len)))
- die("malloc: %s\n", strerror(errno));
-
- return p;
-}
-
-void *
-xrealloc(void *p, size_t len)
-{
- if ((p = realloc(p, len)) == NULL)
- die("realloc: %s\n", strerror(errno));
-
- return p;
-}
-
-char *
-xstrdup(const char *s)
-{
- char *p;
-
- if ((p = strdup(s)) == NULL)
- die("strdup: %s\n", strerror(errno));
-
- return p;
-}
-
-size_t
-utf8decode(const char *c, Rune *u, size_t clen)
-{
- size_t i, j, len, type;
- Rune udecoded;
-
- *u = UTF_INVALID;
- if (!clen)
- return 0;
- udecoded = utf8decodebyte(c[0], &len);
- if (!BETWEEN(len, 1, UTF_SIZ))
- return 1;
- for (i = 1, j = 1; i < clen && j < len; ++i, ++j) {
- udecoded = (udecoded << 6) | utf8decodebyte(c[i], &type);
- if (type != 0)
- return j;
- }
- if (j < len)
- return 0;
- *u = udecoded;
- utf8validate(u, len);
-
- return len;
-}
-
-Rune
-utf8decodebyte(char c, size_t *i)
-{
- for (*i = 0; *i < LEN(utfmask); ++(*i))
- if (((uchar)c & utfmask[*i]) == utfbyte[*i])
- return (uchar)c & ~utfmask[*i];
-
- return 0;
-}
-
-size_t
-utf8encode(Rune u, char *c)
-{
- size_t len, i;
-
- len = utf8validate(&u, 0);
- if (len > UTF_SIZ)
- return 0;
-
- for (i = len - 1; i != 0; --i) {
- c[i] = utf8encodebyte(u, 0);
- u >>= 6;
- }
- c[0] = utf8encodebyte(u, len);
-
- return len;
-}
-
-char
-utf8encodebyte(Rune u, size_t i)
-{
- return utfbyte[i] | (u & ~utfmask[i]);
-}
-
-size_t
-utf8validate(Rune *u, size_t i)
-{
- if (!BETWEEN(*u, utfmin[i], utfmax[i]) || BETWEEN(*u, 0xD800, 0xDFFF))
- *u = UTF_INVALID;
- for (i = 1; *u > utfmax[i]; ++i)
- ;
-
- return i;
-}
-
-static const char base64_digits[] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0,
- 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0, 0, 0, -1, 0, 0, 0, 0, 1,
- 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
- 22, 23, 24, 25, 0, 0, 0, 0, 0, 0, 26, 27, 28, 29, 30, 31, 32, 33, 34,
- 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-};
-
-char
-base64dec_getc(const char **src)
-{
- while (**src && !isprint(**src))
- (*src)++;
- return **src ? *((*src)++) : '='; /* emulate padding if string ends */
-}
-
-char *
-base64dec(const char *src)
-{
- size_t in_len = strlen(src);
- char *result, *dst;
-
- if (in_len % 4)
- in_len += 4 - (in_len % 4);
- result = dst = xmalloc(in_len / 4 * 3 + 1);
- while (*src) {
- int a = base64_digits[(unsigned char) base64dec_getc(&src)];
- int b = base64_digits[(unsigned char) base64dec_getc(&src)];
- int c = base64_digits[(unsigned char) base64dec_getc(&src)];
- int d = base64_digits[(unsigned char) base64dec_getc(&src)];
-
- /* invalid input. 'a' can be -1, e.g. if src is "\n" (c-str) */
- if (a == -1 || b == -1)
- break;
-
- *dst++ = (a << 2) | ((b & 0x30) >> 4);
- if (c == -1)
- break;
- *dst++ = ((b & 0x0f) << 4) | ((c & 0x3c) >> 2);
- if (d == -1)
- break;
- *dst++ = ((c & 0x03) << 6) | d;
- }
- *dst = '\0';
- return result;
-}
-
-void
-selinit(void)
-{
- sel.mode = SEL_IDLE;
- sel.snap = 0;
- sel.ob.x = -1;
-}
-
-int
-tlinelen(int y)
-{
- int i = term.col;
-
- if (TLINE(y)[i - 1].mode & ATTR_WRAP)
- return i;
-
- while (i > 0 && TLINE(y)[i - 1].u == ' ')
- --i;
-
- return i;
-}
-
-void
-selstart(int col, int row, int snap)
-{
- selclear();
- sel.mode = SEL_EMPTY;
- sel.type = SEL_REGULAR;
- sel.alt = IS_SET(MODE_ALTSCREEN);
- sel.snap = snap;
- sel.oe.x = sel.ob.x = col;
- sel.oe.y = sel.ob.y = row;
- selnormalize();
-
- if (sel.snap != 0)
- sel.mode = SEL_READY;
- tsetdirt(sel.nb.y, sel.ne.y);
-}
-
-void
-selextend(int col, int row, int type, int done)
-{
- int oldey, oldex, oldsby, oldsey, oldtype;
-
- if (sel.mode == SEL_IDLE)
- return;
- if (done && sel.mode == SEL_EMPTY) {
- selclear();
- return;
- }
-
- oldey = sel.oe.y;
- oldex = sel.oe.x;
- oldsby = sel.nb.y;
- oldsey = sel.ne.y;
- oldtype = sel.type;
-
- sel.oe.x = col;
- sel.oe.y = row;
- selnormalize();
- sel.type = type;
-
- if (oldey != sel.oe.y || oldex != sel.oe.x || oldtype != sel.type || sel.mode == SEL_EMPTY)
- tsetdirt(MIN(sel.nb.y, oldsby), MAX(sel.ne.y, oldsey));
-
- sel.mode = done ? SEL_IDLE : SEL_READY;
-}
-
-void
-selnormalize(void)
-{
- int i;
-
- if (sel.type == SEL_REGULAR && sel.ob.y != sel.oe.y) {
- sel.nb.x = sel.ob.y < sel.oe.y ? sel.ob.x : sel.oe.x;
- sel.ne.x = sel.ob.y < sel.oe.y ? sel.oe.x : sel.ob.x;
- } else {
- sel.nb.x = MIN(sel.ob.x, sel.oe.x);
- sel.ne.x = MAX(sel.ob.x, sel.oe.x);
- }
- sel.nb.y = MIN(sel.ob.y, sel.oe.y);
- sel.ne.y = MAX(sel.ob.y, sel.oe.y);
-
- selsnap(&sel.nb.x, &sel.nb.y, -1);
- selsnap(&sel.ne.x, &sel.ne.y, +1);
-
- /* expand selection over line breaks */
- if (sel.type == SEL_RECTANGULAR)
- return;
- i = tlinelen(sel.nb.y);
- if (i < sel.nb.x)
- sel.nb.x = i;
- if (tlinelen(sel.ne.y) <= sel.ne.x)
- sel.ne.x = term.col - 1;
-}
-
-int
-selected(int x, int y)
-{
- if (sel.mode == SEL_EMPTY || sel.ob.x == -1 ||
- sel.alt != IS_SET(MODE_ALTSCREEN))
- return 0;
-
- if (sel.type == SEL_RECTANGULAR)
- return BETWEEN(y, sel.nb.y, sel.ne.y)
- && BETWEEN(x, sel.nb.x, sel.ne.x);
-
- return BETWEEN(y, sel.nb.y, sel.ne.y)
- && (y != sel.nb.y || x >= sel.nb.x)
- && (y != sel.ne.y || x <= sel.ne.x);
-}
-
-void
-selsnap(int *x, int *y, int direction)
-{
- int newx, newy, xt, yt;
- int delim, prevdelim;
- const Glyph *gp, *prevgp;
-
- switch (sel.snap) {
- case SNAP_WORD:
- /*
- * Snap around if the word wraps around at the end or
- * beginning of a line.
- */
- prevgp = &TLINE(*y)[*x];
- prevdelim = ISDELIM(prevgp->u);
- for (;;) {
- newx = *x + direction;
- newy = *y;
- if (!BETWEEN(newx, 0, term.col - 1)) {
- newy += direction;
- newx = (newx + term.col) % term.col;
- if (!BETWEEN(newy, 0, term.row - 1))
- break;
-
- if (direction > 0)
- yt = *y, xt = *x;
- else
- yt = newy, xt = newx;
- if (!(TLINE(yt)[xt].mode & ATTR_WRAP))
- break;
- }
-
- if (newx >= tlinelen(newy))
- break;
-
- gp = &TLINE(newy)[newx];
- delim = ISDELIM(gp->u);
- if (!(gp->mode & ATTR_WDUMMY) && (delim != prevdelim
- || (delim && gp->u != prevgp->u)))
- break;
-
- *x = newx;
- *y = newy;
- prevgp = gp;
- prevdelim = delim;
- }
- break;
- case SNAP_LINE:
- /*
- * Snap around if the the previous line or the current one
- * has set ATTR_WRAP at its end. Then the whole next or
- * previous line will be selected.
- */
- *x = (direction < 0) ? 0 : term.col - 1;
- if (direction < 0) {
- for (; *y > 0; *y += direction) {
- if (!(TLINE(*y-1)[term.col-1].mode
- & ATTR_WRAP)) {
- break;
- }
- }
- } else if (direction > 0) {
- for (; *y < term.row-1; *y += direction) {
- if (!(TLINE(*y)[term.col-1].mode
- & ATTR_WRAP)) {
- break;
- }
- }
- }
- break;
- }
-}
-
-char *
-getsel(void)
-{
- char *str, *ptr;
- int y, bufsize, lastx, linelen;
- const Glyph *gp, *last;
-
- if (sel.ob.x == -1)
- return NULL;
-
- bufsize = (term.col+1) * (sel.ne.y-sel.nb.y+1) * UTF_SIZ;
- ptr = str = xmalloc(bufsize);
-
- /* append every set & selected glyph to the selection */
- for (y = sel.nb.y; y <= sel.ne.y; y++) {
- if ((linelen = tlinelen(y)) == 0) {
- *ptr++ = '\n';
- continue;
- }
-
- if (sel.type == SEL_RECTANGULAR) {
- gp = &TLINE(y)[sel.nb.x];
- lastx = sel.ne.x;
- } else {
- gp = &TLINE(y)[sel.nb.y == y ? sel.nb.x : 0];
- lastx = (sel.ne.y == y) ? sel.ne.x : term.col-1;
- }
- last = &TLINE(y)[MIN(lastx, linelen-1)];
- while (last >= gp && last->u == ' ')
- --last;
-
- for ( ; gp <= last; ++gp) {
- if (gp->mode & ATTR_WDUMMY)
- continue;
-
- ptr += utf8encode(gp->u, ptr);
- }
-
- /*
- * Copy and pasting of line endings is inconsistent
- * in the inconsistent terminal and GUI world.
- * The best solution seems like to produce '\n' when
- * something is copied from st and convert '\n' to
- * '\r', when something to be pasted is received by
- * st.
- * FIXME: Fix the computer world.
- */
- if ((y < sel.ne.y || lastx >= linelen) &&
- (!(last->mode & ATTR_WRAP) || sel.type == SEL_RECTANGULAR))
- *ptr++ = '\n';
- }
- *ptr = 0;
- return str;
-}
-
-void
-selclear(void)
-{
- if (sel.ob.x == -1)
- return;
- sel.mode = SEL_IDLE;
- sel.ob.x = -1;
- tsetdirt(sel.nb.y, sel.ne.y);
-}
-
-void
-die(const char *errstr, ...)
-{
- va_list ap;
-
- va_start(ap, errstr);
- vfprintf(stderr, errstr, ap);
- va_end(ap);
- exit(1);
-}
-
-void
-execsh(char *cmd, char **args)
-{
- char *sh, *prog, *arg;
- const struct passwd *pw;
-
- errno = 0;
- if ((pw = getpwuid(getuid())) == NULL) {
- if (errno)
- die("getpwuid: %s\n", strerror(errno));
- else
- die("who are you?\n");
- }
-
- if ((sh = getenv("SHELL")) == NULL)
- sh = (pw->pw_shell[0]) ? pw->pw_shell : cmd;
-
- if (args) {
- prog = args[0];
- arg = NULL;
- } else if (scroll) {
- prog = scroll;
- arg = utmp ? utmp : sh;
- } else if (utmp) {
- prog = utmp;
- arg = NULL;
- } else {
- prog = sh;
- arg = NULL;
- }
- DEFAULT(args, ((char *[]) {prog, arg, NULL}));
-
- unsetenv("COLUMNS");
- unsetenv("LINES");
- unsetenv("TERMCAP");
- setenv("LOGNAME", pw->pw_name, 1);
- setenv("USER", pw->pw_name, 1);
- setenv("SHELL", sh, 1);
- setenv("HOME", pw->pw_dir, 1);
- setenv("TERM", termname, 1);
-
- signal(SIGCHLD, SIG_DFL);
- signal(SIGHUP, SIG_DFL);
- signal(SIGINT, SIG_DFL);
- signal(SIGQUIT, SIG_DFL);
- signal(SIGTERM, SIG_DFL);
- signal(SIGALRM, SIG_DFL);
-
- execvp(prog, args);
- _exit(1);
-}
-
-void
-sigchld(int a)
-{
- int stat;
- pid_t p;
-
- if ((p = waitpid(pid, &stat, WNOHANG)) < 0)
- die("waiting for pid %hd failed: %s\n", pid, strerror(errno));
-
- if (pid != p)
- return;
-
- if (WIFEXITED(stat) && WEXITSTATUS(stat))
- die("child exited with status %d\n", WEXITSTATUS(stat));
- else if (WIFSIGNALED(stat))
- die("child terminated due to signal %d\n", WTERMSIG(stat));
- _exit(0);
-}
-
-void
-stty(char **args)
-{
- char cmd[_POSIX_ARG_MAX], **p, *q, *s;
- size_t n, siz;
-
- if ((n = strlen(stty_args)) > sizeof(cmd)-1)
- die("incorrect stty parameters\n");
- memcpy(cmd, stty_args, n);
- q = cmd + n;
- siz = sizeof(cmd) - n;
- for (p = args; p && (s = *p); ++p) {
- if ((n = strlen(s)) > siz-1)
- die("stty parameter length too long\n");
- *q++ = ' ';
- memcpy(q, s, n);
- q += n;
- siz -= n + 1;
- }
- *q = '\0';
- if (system(cmd) != 0)
- perror("Couldn't call stty");
-}
-
-int
-ttynew(const char *line, char *cmd, const char *out, char **args)
-{
- int m, s;
-
- if (out) {
- term.mode |= MODE_PRINT;
- iofd = (!strcmp(out, "-")) ?
- 1 : open(out, O_WRONLY | O_CREAT, 0666);
- if (iofd < 0) {
- fprintf(stderr, "Error opening %s:%s\n",
- out, strerror(errno));
- }
- }
-
- if (line) {
- if ((cmdfd = open(line, O_RDWR)) < 0)
- die("open line '%s' failed: %s\n",
- line, strerror(errno));
- dup2(cmdfd, 0);
- stty(args);
- return cmdfd;
- }
-
- /* seems to work fine on linux, openbsd and freebsd */
- if (openpty(&m, &s, NULL, NULL, NULL) < 0)
- die("openpty failed: %s\n", strerror(errno));
-
- switch (pid = fork()) {
- case -1:
- die("fork failed: %s\n", strerror(errno));
- break;
- case 0:
- close(iofd);
- close(m);
- setsid(); /* create a new process group */
- dup2(s, 0);
- dup2(s, 1);
- dup2(s, 2);
- if (ioctl(s, TIOCSCTTY, NULL) < 0)
- die("ioctl TIOCSCTTY failed: %s\n", strerror(errno));
- if (s > 2)
- close(s);
-#ifdef __OpenBSD__
- if (pledge("stdio getpw proc exec", NULL) == -1)
- die("pledge\n");
-#endif
- execsh(cmd, args);
- break;
- default:
-#ifdef __OpenBSD__
- if (pledge("stdio rpath tty proc", NULL) == -1)
- die("pledge\n");
-#endif
- close(s);
- cmdfd = m;
- signal(SIGCHLD, sigchld);
- break;
- }
- return cmdfd;
-}
-
-size_t
-ttyread(void)
-{
- static char buf[BUFSIZ];
- static int buflen = 0;
- int ret, written;
-
- /* append read bytes to unprocessed bytes */
- ret = read(cmdfd, buf+buflen, LEN(buf)-buflen);
-
- switch (ret) {
- case 0:
- exit(0);
- case -1:
- die("couldn't read from shell: %s\n", strerror(errno));
- default:
- buflen += ret;
- written = twrite(buf, buflen, 0);
- buflen -= written;
- /* keep any incomplete UTF-8 byte sequence for the next call */
- if (buflen > 0)
- memmove(buf, buf + written, buflen);
- return ret;
- }
-}
-
-void
-ttywrite(const char *s, size_t n, int may_echo)
-{
- const char *next;
- Arg arg = (Arg) { .i = term.scr };
-
- kscrolldown(&arg);
-
- if (may_echo && IS_SET(MODE_ECHO))
- twrite(s, n, 1);
-
- if (!IS_SET(MODE_CRLF)) {
- ttywriteraw(s, n);
- return;
- }
-
- /* This is similar to how the kernel handles ONLCR for ttys */
- while (n > 0) {
- if (*s == '\r') {
- next = s + 1;
- ttywriteraw("\r\n", 2);
- } else {
- next = memchr(s, '\r', n);
- DEFAULT(next, s + n);
- ttywriteraw(s, next - s);
- }
- n -= next - s;
- s = next;
- }
-}
-
-void
-ttywriteraw(const char *s, size_t n)
-{
- fd_set wfd, rfd;
- ssize_t r;
- size_t lim = 256;
-
- /*
- * Remember that we are using a pty, which might be a modem line.
- * Writing too much will clog the line. That's why we are doing this
- * dance.
- * FIXME: Migrate the world to Plan 9.
- */
- while (n > 0) {
- FD_ZERO(&wfd);
- FD_ZERO(&rfd);
- FD_SET(cmdfd, &wfd);
- FD_SET(cmdfd, &rfd);
-
- /* Check if we can write. */
- if (pselect(cmdfd+1, &rfd, &wfd, NULL, NULL, NULL) < 0) {
- if (errno == EINTR)
- continue;
- die("select failed: %s\n", strerror(errno));
- }
- if (FD_ISSET(cmdfd, &wfd)) {
- /*
- * Only write the bytes written by ttywrite() or the
- * default of 256. This seems to be a reasonable value
- * for a serial line. Bigger values might clog the I/O.
- */
- if ((r = write(cmdfd, s, (n < lim)? n : lim)) < 0)
- goto write_error;
- if (r < n) {
- /*
- * We weren't able to write out everything.
- * This means the buffer is getting full
- * again. Empty it.
- */
- if (n < lim)
- lim = ttyread();
- n -= r;
- s += r;
- } else {
- /* All bytes have been written. */
- break;
- }
- }
- if (FD_ISSET(cmdfd, &rfd))
- lim = ttyread();
- }
- return;
-
-write_error:
- die("write error on tty: %s\n", strerror(errno));
-}
-
-void
-ttyresize(int tw, int th)
-{
- struct winsize w;
-
- w.ws_row = term.row;
- w.ws_col = term.col;
- w.ws_xpixel = tw;
- w.ws_ypixel = th;
- if (ioctl(cmdfd, TIOCSWINSZ, &w) < 0)
- fprintf(stderr, "Couldn't set window size: %s\n", strerror(errno));
-}
-
-void
-ttyhangup()
-{
- /* Send SIGHUP to shell */
- kill(pid, SIGHUP);
-}
-
-int
-tattrset(int attr)
-{
- int i, j;
-
- for (i = 0; i < term.row-1; i++) {
- for (j = 0; j < term.col-1; j++) {
- if (term.line[i][j].mode & attr)
- return 1;
- }
- }
-
- return 0;
-}
-
-void
-tsetdirt(int top, int bot)
-{
- int i;
-
- LIMIT(top, 0, term.row-1);
- LIMIT(bot, 0, term.row-1);
-
- for (i = top; i <= bot; i++)
- term.dirty[i] = 1;
-}
-
-void
-tsetdirtattr(int attr)
-{
- int i, j;
-
- for (i = 0; i < term.row-1; i++) {
- for (j = 0; j < term.col-1; j++) {
- if (term.line[i][j].mode & attr) {
- tsetdirt(i, i);
- break;
- }
- }
- }
-}
-
-void
-tfulldirt(void)
-{
- tsetdirt(0, term.row-1);
-}
-
-void
-tcursor(int mode)
-{
- static TCursor c[2];
- int alt = IS_SET(MODE_ALTSCREEN);
-
- if (mode == CURSOR_SAVE) {
- c[alt] = term.c;
- } else if (mode == CURSOR_LOAD) {
- term.c = c[alt];
- tmoveto(c[alt].x, c[alt].y);
- }
-}
-
-void
-treset(void)
-{
- uint i;
-
- term.c = (TCursor){{
- .mode = ATTR_NULL,
- .fg = defaultfg,
- .bg = defaultbg
- }, .x = 0, .y = 0, .state = CURSOR_DEFAULT};
-
- memset(term.tabs, 0, term.col * sizeof(*term.tabs));
- for (i = tabspaces; i < term.col; i += tabspaces)
- term.tabs[i] = 1;
- term.top = 0;
- term.bot = term.row - 1;
- term.mode = MODE_WRAP|MODE_UTF8;
- memset(term.trantbl, CS_USA, sizeof(term.trantbl));
- term.charset = 0;
-
- for (i = 0; i < 2; i++) {
- tmoveto(0, 0);
- tcursor(CURSOR_SAVE);
- tclearregion(0, 0, term.col-1, term.row-1);
- tswapscreen();
- }
-}
-
-void
-tnew(int col, int row)
-{
- term = (Term){ .c = { .attr = { .fg = defaultfg, .bg = defaultbg } } };
- tresize(col, row);
- treset();
-}
-
-void
-tswapscreen(void)
-{
- Line *tmp = term.line;
-
- term.line = term.alt;
- term.alt = tmp;
- term.mode ^= MODE_ALTSCREEN;
- tfulldirt();
-}
-
-void
-kscrolldown(const Arg* a)
-{
- int n = a->i;
-
- if (n < 0)
- n = term.row + n;
-
- if (n > term.scr)
- n = term.scr;
-
- if (term.scr > 0) {
- term.scr -= n;
- selscroll(0, -n);
- tfulldirt();
- }
-}
-
-void
-kscrollup(const Arg* a)
-{
- int n = a->i;
-
- if (n < 0)
- n = term.row + n;
-
- if (term.scr <= HISTSIZE-n) {
- term.scr += n;
- selscroll(0, n);
- tfulldirt();
- }
-}
-
-void
-tscrolldown(int orig, int n, int copyhist)
-{
- int i;
- Line temp;
-
- LIMIT(n, 0, term.bot-orig+1);
-
- if (copyhist) {
- term.histi = (term.histi - 1 + HISTSIZE) % HISTSIZE;
- temp = term.hist[term.histi];
- term.hist[term.histi] = term.line[term.bot];
- term.line[term.bot] = temp;
- }
-
- tsetdirt(orig, term.bot-n);
- tclearregion(0, term.bot-n+1, term.col-1, term.bot);
-
- for (i = term.bot; i >= orig+n; i--) {
- temp = term.line[i];
- term.line[i] = term.line[i-n];
- term.line[i-n] = temp;
- }
-
- if (term.scr == 0)
- selscroll(orig, n);
-}
-
-void
-tscrollup(int orig, int n, int copyhist)
-{
- int i;
- Line temp;
-
- LIMIT(n, 0, term.bot-orig+1);
-
- if (copyhist) {
- term.histi = (term.histi + 1) % HISTSIZE;
- temp = term.hist[term.histi];
- term.hist[term.histi] = term.line[orig];
- term.line[orig] = temp;
- }
-
- if (term.scr > 0 && term.scr < HISTSIZE)
- term.scr = MIN(term.scr + n, HISTSIZE-1);
-
- tclearregion(0, orig, term.col-1, orig+n-1);
- tsetdirt(orig+n, term.bot);
-
- for (i = orig; i <= term.bot-n; i++) {
- temp = term.line[i];
- term.line[i] = term.line[i+n];
- term.line[i+n] = temp;
- }
-
- if (term.scr == 0)
- selscroll(orig, -n);
-}
-
-void
-selscroll(int orig, int n)
-{
- if (sel.ob.x == -1)
- return;
-
- if (BETWEEN(sel.nb.y, orig, term.bot) != BETWEEN(sel.ne.y, orig, term.bot)) {
- selclear();
- } else if (BETWEEN(sel.nb.y, orig, term.bot)) {
- sel.ob.y += n;
- sel.oe.y += n;
- if (sel.ob.y < term.top || sel.ob.y > term.bot ||
- sel.oe.y < term.top || sel.oe.y > term.bot) {
- selclear();
- } else {
- selnormalize();
- }
- }
-}
-
-void
-tnewline(int first_col)
-{
- int y = term.c.y;
-
- if (y == term.bot) {
- tscrollup(term.top, 1, 1);
- } else {
- y++;
- }
- tmoveto(first_col ? 0 : term.c.x, y);
-}
-
-void
-csiparse(void)
-{
- char *p = csiescseq.buf, *np;
- long int v;
-
- csiescseq.narg = 0;
- if (*p == '?') {
- csiescseq.priv = 1;
- p++;
- }
-
- csiescseq.buf[csiescseq.len] = '\0';
- while (p < csiescseq.buf+csiescseq.len) {
- np = NULL;
- v = strtol(p, &np, 10);
- if (np == p)
- v = 0;
- if (v == LONG_MAX || v == LONG_MIN)
- v = -1;
- csiescseq.arg[csiescseq.narg++] = v;
- p = np;
- if (*p != ';' || csiescseq.narg == ESC_ARG_SIZ)
- break;
- p++;
- }
- csiescseq.mode[0] = *p++;
- csiescseq.mode[1] = (p < csiescseq.buf+csiescseq.len) ? *p : '\0';
-}
-
-/* for absolute user moves, when decom is set */
-void
-tmoveato(int x, int y)
-{
- tmoveto(x, y + ((term.c.state & CURSOR_ORIGIN) ? term.top: 0));
-}
-
-void
-tmoveto(int x, int y)
-{
- int miny, maxy;
-
- if (term.c.state & CURSOR_ORIGIN) {
- miny = term.top;
- maxy = term.bot;
- } else {
- miny = 0;
- maxy = term.row - 1;
- }
- term.c.state &= ~CURSOR_WRAPNEXT;
- term.c.x = LIMIT(x, 0, term.col-1);
- term.c.y = LIMIT(y, miny, maxy);
-}
-
-void
-tsetchar(Rune u, const Glyph *attr, int x, int y)
-{
- static const char *vt100_0[62] = { /* 0x41 - 0x7e */
- "↑", "↓", "→", "←", "█", "▚", "☃", /* A - G */
- 0, 0, 0, 0, 0, 0, 0, 0, /* H - O */
- 0, 0, 0, 0, 0, 0, 0, 0, /* P - W */
- 0, 0, 0, 0, 0, 0, 0, " ", /* X - _ */
- "◆", "▒", "␉", "␌", "␍", "␊", "°", "±", /* ` - g */
- "␤", "␋", "┘", "┐", "┌", "└", "┼", "⎺", /* h - o */
- "⎻", "─", "⎼", "⎽", "├", "┤", "┴", "┬", /* p - w */
- "│", "≤", "≥", "π", "≠", "£", "·", /* x - ~ */
- };
-
- /*
- * The table is proudly stolen from rxvt.
- */
- if (term.trantbl[term.charset] == CS_GRAPHIC0 &&
- BETWEEN(u, 0x41, 0x7e) && vt100_0[u - 0x41])
- utf8decode(vt100_0[u - 0x41], &u, UTF_SIZ);
-
- if (term.line[y][x].mode & ATTR_WIDE) {
- if (x+1 < term.col) {
- term.line[y][x+1].u = ' ';
- term.line[y][x+1].mode &= ~ATTR_WDUMMY;
- }
- } else if (term.line[y][x].mode & ATTR_WDUMMY) {
- term.line[y][x-1].u = ' ';
- term.line[y][x-1].mode &= ~ATTR_WIDE;
- }
-
- term.dirty[y] = 1;
- term.line[y][x] = *attr;
- term.line[y][x].u = u;
-}
-
-void
-tclearregion(int x1, int y1, int x2, int y2)
-{
- int x, y, temp;
- Glyph *gp;
-
- if (x1 > x2)
- temp = x1, x1 = x2, x2 = temp;
- if (y1 > y2)
- temp = y1, y1 = y2, y2 = temp;
-
- LIMIT(x1, 0, term.col-1);
- LIMIT(x2, 0, term.col-1);
- LIMIT(y1, 0, term.row-1);
- LIMIT(y2, 0, term.row-1);
-
- for (y = y1; y <= y2; y++) {
- term.dirty[y] = 1;
- for (x = x1; x <= x2; x++) {
- gp = &term.line[y][x];
- if (selected(x, y))
- selclear();
- gp->fg = term.c.attr.fg;
- gp->bg = term.c.attr.bg;
- gp->mode = 0;
- gp->u = ' ';
- }
- }
-}
-
-void
-tdeletechar(int n)
-{
- int dst, src, size;
- Glyph *line;
-
- LIMIT(n, 0, term.col - term.c.x);
-
- dst = term.c.x;
- src = term.c.x + n;
- size = term.col - src;
- line = term.line[term.c.y];
-
- memmove(&line[dst], &line[src], size * sizeof(Glyph));
- tclearregion(term.col-n, term.c.y, term.col-1, term.c.y);
-}
-
-void
-tinsertblank(int n)
-{
- int dst, src, size;
- Glyph *line;
-
- LIMIT(n, 0, term.col - term.c.x);
-
- dst = term.c.x + n;
- src = term.c.x;
- size = term.col - dst;
- line = term.line[term.c.y];
-
- memmove(&line[dst], &line[src], size * sizeof(Glyph));
- tclearregion(src, term.c.y, dst - 1, term.c.y);
-}
-
-void
-tinsertblankline(int n)
-{
- if (BETWEEN(term.c.y, term.top, term.bot))
- tscrolldown(term.c.y, n, 0);
-}
-
-void
-tdeleteline(int n)
-{
- if (BETWEEN(term.c.y, term.top, term.bot))
- tscrollup(term.c.y, n, 0);
-}
-
-int32_t
-tdefcolor(const int *attr, int *npar, int l)
-{
- int32_t idx = -1;
- uint r, g, b;
-
- switch (attr[*npar + 1]) {
- case 2: /* direct color in RGB space */
- if (*npar + 4 >= l) {
- fprintf(stderr,
- "erresc(38): Incorrect number of parameters (%d)\n",
- *npar);
- break;
- }
- r = attr[*npar + 2];
- g = attr[*npar + 3];
- b = attr[*npar + 4];
- *npar += 4;
- if (!BETWEEN(r, 0, 255) || !BETWEEN(g, 0, 255) || !BETWEEN(b, 0, 255))
- fprintf(stderr, "erresc: bad rgb color (%u,%u,%u)\n",
- r, g, b);
- else
- idx = TRUECOLOR(r, g, b);
- break;
- case 5: /* indexed color */
- if (*npar + 2 >= l) {
- fprintf(stderr,
- "erresc(38): Incorrect number of parameters (%d)\n",
- *npar);
- break;
- }
- *npar += 2;
- if (!BETWEEN(attr[*npar], 0, 255))
- fprintf(stderr, "erresc: bad fgcolor %d\n", attr[*npar]);
- else
- idx = attr[*npar];
- break;
- case 0: /* implemented defined (only foreground) */
- case 1: /* transparent */
- case 3: /* direct color in CMY space */
- case 4: /* direct color in CMYK space */
- default:
- fprintf(stderr,
- "erresc(38): gfx attr %d unknown\n", attr[*npar]);
- break;
- }
-
- return idx;
-}
-
-void
-tsetattr(const int *attr, int l)
-{
- int i;
- int32_t idx;
-
- for (i = 0; i < l; i++) {
- switch (attr[i]) {
- case 0:
- term.c.attr.mode &= ~(
- ATTR_BOLD |
- ATTR_FAINT |
- ATTR_ITALIC |
- ATTR_UNDERLINE |
- ATTR_BLINK |
- ATTR_REVERSE |
- ATTR_INVISIBLE |
- ATTR_STRUCK );
- term.c.attr.fg = defaultfg;
- term.c.attr.bg = defaultbg;
- break;
- case 1:
- term.c.attr.mode |= ATTR_BOLD;
- break;
- case 2:
- term.c.attr.mode |= ATTR_FAINT;
- break;
- case 3:
- term.c.attr.mode |= ATTR_ITALIC;
- break;
- case 4:
- term.c.attr.mode |= ATTR_UNDERLINE;
- break;
- case 5: /* slow blink */
- /* FALLTHROUGH */
- case 6: /* rapid blink */
- term.c.attr.mode |= ATTR_BLINK;
- break;
- case 7:
- term.c.attr.mode |= ATTR_REVERSE;
- break;
- case 8:
- term.c.attr.mode |= ATTR_INVISIBLE;
- break;
- case 9:
- term.c.attr.mode |= ATTR_STRUCK;
- break;
- case 22:
- term.c.attr.mode &= ~(ATTR_BOLD | ATTR_FAINT);
- break;
- case 23:
- term.c.attr.mode &= ~ATTR_ITALIC;
- break;
- case 24:
- term.c.attr.mode &= ~ATTR_UNDERLINE;
- break;
- case 25:
- term.c.attr.mode &= ~ATTR_BLINK;
- break;
- case 27:
- term.c.attr.mode &= ~ATTR_REVERSE;
- break;
- case 28:
- term.c.attr.mode &= ~ATTR_INVISIBLE;
- break;
- case 29:
- term.c.attr.mode &= ~ATTR_STRUCK;
- break;
- case 38:
- if ((idx = tdefcolor(attr, &i, l)) >= 0)
- term.c.attr.fg = idx;
- break;
- case 39:
- term.c.attr.fg = defaultfg;
- break;
- case 48:
- if ((idx = tdefcolor(attr, &i, l)) >= 0)
- term.c.attr.bg = idx;
- break;
- case 49:
- term.c.attr.bg = defaultbg;
- break;
- default:
- if (BETWEEN(attr[i], 30, 37)) {
- term.c.attr.fg = attr[i] - 30;
- } else if (BETWEEN(attr[i], 40, 47)) {
- term.c.attr.bg = attr[i] - 40;
- } else if (BETWEEN(attr[i], 90, 97)) {
- term.c.attr.fg = attr[i] - 90 + 8;
- } else if (BETWEEN(attr[i], 100, 107)) {
- term.c.attr.bg = attr[i] - 100 + 8;
- } else {
- fprintf(stderr,
- "erresc(default): gfx attr %d unknown\n",
- attr[i]);
- csidump();
- }
- break;
- }
- }
-}
-
-void
-tsetscroll(int t, int b)
-{
- int temp;
-
- LIMIT(t, 0, term.row-1);
- LIMIT(b, 0, term.row-1);
- if (t > b) {
- temp = t;
- t = b;
- b = temp;
- }
- term.top = t;
- term.bot = b;
-}
-
-void
-tsetmode(int priv, int set, const int *args, int narg)
-{
- int alt; const int *lim;
-
- for (lim = args + narg; args < lim; ++args) {
- if (priv) {
- switch (*args) {
- case 1: /* DECCKM -- Cursor key */
- xsetmode(set, MODE_APPCURSOR);
- break;
- case 5: /* DECSCNM -- Reverse video */
- xsetmode(set, MODE_REVERSE);
- break;
- case 6: /* DECOM -- Origin */
- MODBIT(term.c.state, set, CURSOR_ORIGIN);
- tmoveato(0, 0);
- break;
- case 7: /* DECAWM -- Auto wrap */
- MODBIT(term.mode, set, MODE_WRAP);
- break;
- case 0: /* Error (IGNORED) */
- case 2: /* DECANM -- ANSI/VT52 (IGNORED) */
- case 3: /* DECCOLM -- Column (IGNORED) */
- case 4: /* DECSCLM -- Scroll (IGNORED) */
- case 8: /* DECARM -- Auto repeat (IGNORED) */
- case 18: /* DECPFF -- Printer feed (IGNORED) */
- case 19: /* DECPEX -- Printer extent (IGNORED) */
- case 42: /* DECNRCM -- National characters (IGNORED) */
- case 12: /* att610 -- Start blinking cursor (IGNORED) */
- break;
- case 25: /* DECTCEM -- Text Cursor Enable Mode */
- xsetmode(!set, MODE_HIDE);
- break;
- case 9: /* X10 mouse compatibility mode */
- xsetpointermotion(0);
- xsetmode(0, MODE_MOUSE);
- xsetmode(set, MODE_MOUSEX10);
- break;
- case 1000: /* 1000: report button press */
- xsetpointermotion(0);
- xsetmode(0, MODE_MOUSE);
- xsetmode(set, MODE_MOUSEBTN);
- break;
- case 1002: /* 1002: report motion on button press */
- xsetpointermotion(0);
- xsetmode(0, MODE_MOUSE);
- xsetmode(set, MODE_MOUSEMOTION);
- break;
- case 1003: /* 1003: enable all mouse motions */
- xsetpointermotion(set);
- xsetmode(0, MODE_MOUSE);
- xsetmode(set, MODE_MOUSEMANY);
- break;
- case 1004: /* 1004: send focus events to tty */
- xsetmode(set, MODE_FOCUS);
- break;
- case 1006: /* 1006: extended reporting mode */
- xsetmode(set, MODE_MOUSESGR);
- break;
- case 1034:
- xsetmode(set, MODE_8BIT);
- break;
- case 1049: /* swap screen & set/restore cursor as xterm */
- if (!allowaltscreen)
- break;
- tcursor((set) ? CURSOR_SAVE : CURSOR_LOAD);
- /* FALLTHROUGH */
- case 47: /* swap screen */
- case 1047:
- if (!allowaltscreen)
- break;
- alt = IS_SET(MODE_ALTSCREEN);
- if (alt) {
- tclearregion(0, 0, term.col-1,
- term.row-1);
- }
- if (set ^ alt) /* set is always 1 or 0 */
- tswapscreen();
- if (*args != 1049)
- break;
- /* FALLTHROUGH */
- case 1048:
- tcursor((set) ? CURSOR_SAVE : CURSOR_LOAD);
- break;
- case 2004: /* 2004: bracketed paste mode */
- xsetmode(set, MODE_BRCKTPASTE);
- break;
- /* Not implemented mouse modes. See comments there. */
- case 1001: /* mouse highlight mode; can hang the
- terminal by design when implemented. */
- case 1005: /* UTF-8 mouse mode; will confuse
- applications not supporting UTF-8
- and luit. */
- case 1015: /* urxvt mangled mouse mode; incompatible
- and can be mistaken for other control
- codes. */
- break;
- default:
- fprintf(stderr,
- "erresc: unknown private set/reset mode %d\n",
- *args);
- break;
- }
- } else {
- switch (*args) {
- case 0: /* Error (IGNORED) */
- break;
- case 2:
- xsetmode(set, MODE_KBDLOCK);
- break;
- case 4: /* IRM -- Insertion-replacement */
- MODBIT(term.mode, set, MODE_INSERT);
- break;
- case 12: /* SRM -- Send/Receive */
- MODBIT(term.mode, !set, MODE_ECHO);
- break;
- case 20: /* LNM -- Linefeed/new line */
- MODBIT(term.mode, set, MODE_CRLF);
- break;
- default:
- fprintf(stderr,
- "erresc: unknown set/reset mode %d\n",
- *args);
- break;
- }
- }
- }
-}
-
-void
-csihandle(void)
-{
- char buf[40];
- int len;
-
- switch (csiescseq.mode[0]) {
- default:
- unknown:
- fprintf(stderr, "erresc: unknown csi ");
- csidump();
- /* die(""); */
- break;
- case '@': /* ICH -- Insert <n> blank char */
- DEFAULT(csiescseq.arg[0], 1);
- tinsertblank(csiescseq.arg[0]);
- break;
- case 'A': /* CUU -- Cursor <n> Up */
- DEFAULT(csiescseq.arg[0], 1);
- tmoveto(term.c.x, term.c.y-csiescseq.arg[0]);
- break;
- case 'B': /* CUD -- Cursor <n> Down */
- case 'e': /* VPR --Cursor <n> Down */
- DEFAULT(csiescseq.arg[0], 1);
- tmoveto(term.c.x, term.c.y+csiescseq.arg[0]);
- break;
- case 'i': /* MC -- Media Copy */
- switch (csiescseq.arg[0]) {
- case 0:
- tdump();
- break;
- case 1:
- tdumpline(term.c.y);
- break;
- case 2:
- tdumpsel();
- break;
- case 4:
- term.mode &= ~MODE_PRINT;
- break;
- case 5:
- term.mode |= MODE_PRINT;
- break;
- }
- break;
- case 'c': /* DA -- Device Attributes */
- if (csiescseq.arg[0] == 0)
- ttywrite(vtiden, strlen(vtiden), 0);
- break;
- case 'b': /* REP -- if last char is printable print it <n> more times */
- DEFAULT(csiescseq.arg[0], 1);
- if (term.lastc)
- while (csiescseq.arg[0]-- > 0)
- tputc(term.lastc);
- break;
- case 'C': /* CUF -- Cursor <n> Forward */
- case 'a': /* HPR -- Cursor <n> Forward */
- DEFAULT(csiescseq.arg[0], 1);
- tmoveto(term.c.x+csiescseq.arg[0], term.c.y);
- break;
- case 'D': /* CUB -- Cursor <n> Backward */
- DEFAULT(csiescseq.arg[0], 1);
- tmoveto(term.c.x-csiescseq.arg[0], term.c.y);
- break;
- case 'E': /* CNL -- Cursor <n> Down and first col */
- DEFAULT(csiescseq.arg[0], 1);
- tmoveto(0, term.c.y+csiescseq.arg[0]);
- break;
- case 'F': /* CPL -- Cursor <n> Up and first col */
- DEFAULT(csiescseq.arg[0], 1);
- tmoveto(0, term.c.y-csiescseq.arg[0]);
- break;
- case 'g': /* TBC -- Tabulation clear */
- switch (csiescseq.arg[0]) {
- case 0: /* clear current tab stop */
- term.tabs[term.c.x] = 0;
- break;
- case 3: /* clear all the tabs */
- memset(term.tabs, 0, term.col * sizeof(*term.tabs));
- break;
- default:
- goto unknown;
- }
- break;
- case 'G': /* CHA -- Move to <col> */
- case '`': /* HPA */
- DEFAULT(csiescseq.arg[0], 1);
- tmoveto(csiescseq.arg[0]-1, term.c.y);
- break;
- case 'H': /* CUP -- Move to <row> <col> */
- case 'f': /* HVP */
- DEFAULT(csiescseq.arg[0], 1);
- DEFAULT(csiescseq.arg[1], 1);
- tmoveato(csiescseq.arg[1]-1, csiescseq.arg[0]-1);
- break;
- case 'I': /* CHT -- Cursor Forward Tabulation <n> tab stops */
- DEFAULT(csiescseq.arg[0], 1);
- tputtab(csiescseq.arg[0]);
- break;
- case 'J': /* ED -- Clear screen */
- switch (csiescseq.arg[0]) {
- case 0: /* below */
- tclearregion(term.c.x, term.c.y, term.col-1, term.c.y);
- if (term.c.y < term.row-1) {
- tclearregion(0, term.c.y+1, term.col-1,
- term.row-1);
- }
- break;
- case 1: /* above */
- if (term.c.y > 1)
- tclearregion(0, 0, term.col-1, term.c.y-1);
- tclearregion(0, term.c.y, term.c.x, term.c.y);
- break;
- case 2: /* all */
- tclearregion(0, 0, term.col-1, term.row-1);
- break;
- default:
- goto unknown;
- }
- break;
- case 'K': /* EL -- Clear line */
- switch (csiescseq.arg[0]) {
- case 0: /* right */
- tclearregion(term.c.x, term.c.y, term.col-1,
- term.c.y);
- break;
- case 1: /* left */
- tclearregion(0, term.c.y, term.c.x, term.c.y);
- break;
- case 2: /* all */
- tclearregion(0, term.c.y, term.col-1, term.c.y);
- break;
- }
- break;
- case 'S': /* SU -- Scroll <n> line up */
- DEFAULT(csiescseq.arg[0], 1);
- tscrollup(term.top, csiescseq.arg[0], 0);
- break;
- case 'T': /* SD -- Scroll <n> line down */
- DEFAULT(csiescseq.arg[0], 1);
- tscrolldown(term.top, csiescseq.arg[0], 0);
- break;
- case 'L': /* IL -- Insert <n> blank lines */
- DEFAULT(csiescseq.arg[0], 1);
- tinsertblankline(csiescseq.arg[0]);
- break;
- case 'l': /* RM -- Reset Mode */
- tsetmode(csiescseq.priv, 0, csiescseq.arg, csiescseq.narg);
- break;
- case 'M': /* DL -- Delete <n> lines */
- DEFAULT(csiescseq.arg[0], 1);
- tdeleteline(csiescseq.arg[0]);
- break;
- case 'X': /* ECH -- Erase <n> char */
- DEFAULT(csiescseq.arg[0], 1);
- tclearregion(term.c.x, term.c.y,
- term.c.x + csiescseq.arg[0] - 1, term.c.y);
- break;
- case 'P': /* DCH -- Delete <n> char */
- DEFAULT(csiescseq.arg[0], 1);
- tdeletechar(csiescseq.arg[0]);
- break;
- case 'Z': /* CBT -- Cursor Backward Tabulation <n> tab stops */
- DEFAULT(csiescseq.arg[0], 1);
- tputtab(-csiescseq.arg[0]);
- break;
- case 'd': /* VPA -- Move to <row> */
- DEFAULT(csiescseq.arg[0], 1);
- tmoveato(term.c.x, csiescseq.arg[0]-1);
- break;
- case 'h': /* SM -- Set terminal mode */
- tsetmode(csiescseq.priv, 1, csiescseq.arg, csiescseq.narg);
- break;
- case 'm': /* SGR -- Terminal attribute (color) */
- tsetattr(csiescseq.arg, csiescseq.narg);
- break;
- case 'n': /* DSR – Device Status Report (cursor position) */
- if (csiescseq.arg[0] == 6) {
- len = snprintf(buf, sizeof(buf), "\033[%i;%iR",
- term.c.y+1, term.c.x+1);
- ttywrite(buf, len, 0);
- }
- break;
- case 'r': /* DECSTBM -- Set Scrolling Region */
- if (csiescseq.priv) {
- goto unknown;
- } else {
- DEFAULT(csiescseq.arg[0], 1);
- DEFAULT(csiescseq.arg[1], term.row);
- tsetscroll(csiescseq.arg[0]-1, csiescseq.arg[1]-1);
- tmoveato(0, 0);
- }
- break;
- case 's': /* DECSC -- Save cursor position (ANSI.SYS) */
- tcursor(CURSOR_SAVE);
- break;
- case 'u': /* DECRC -- Restore cursor position (ANSI.SYS) */
- tcursor(CURSOR_LOAD);
- break;
- case ' ':
- switch (csiescseq.mode[1]) {
- case 'q': /* DECSCUSR -- Set Cursor Style */
- if (xsetcursor(csiescseq.arg[0]))
- goto unknown;
- break;
- default:
- goto unknown;
- }
- break;
- }
-}
-
-void
-csidump(void)
-{
- size_t i;
- uint c;
-
- fprintf(stderr, "ESC[");
- for (i = 0; i < csiescseq.len; i++) {
- c = csiescseq.buf[i] & 0xff;
- if (isprint(c)) {
- putc(c, stderr);
- } else if (c == '\n') {
- fprintf(stderr, "(\\n)");
- } else if (c == '\r') {
- fprintf(stderr, "(\\r)");
- } else if (c == 0x1b) {
- fprintf(stderr, "(\\e)");
- } else {
- fprintf(stderr, "(%02x)", c);
- }
- }
- putc('\n', stderr);
-}
-
-void
-csireset(void)
-{
- memset(&csiescseq, 0, sizeof(csiescseq));
-}
-
-void
-strhandle(void)
-{
- char *p = NULL, *dec;
- int j, narg, par;
-
- term.esc &= ~(ESC_STR_END|ESC_STR);
- strparse();
- par = (narg = strescseq.narg) ? atoi(strescseq.args[0]) : 0;
-
- switch (strescseq.type) {
- case ']': /* OSC -- Operating System Command */
- switch (par) {
- case 0:
- if (narg > 1) {
- xsettitle(strescseq.args[1]);
- xseticontitle(strescseq.args[1]);
- }
- return;
- case 1:
- if (narg > 1)
- xseticontitle(strescseq.args[1]);
- return;
- case 2:
- if (narg > 1)
- xsettitle(strescseq.args[1]);
- return;
- case 52:
- if (narg > 2 && allowwindowops) {
- dec = base64dec(strescseq.args[2]);
- if (dec) {
- xsetsel(dec);
- xclipcopy();
- } else {
- fprintf(stderr, "erresc: invalid base64\n");
- }
- }
- return;
- case 4: /* color set */
- if (narg < 3)
- break;
- p = strescseq.args[2];
- /* FALLTHROUGH */
- case 104: /* color reset, here p = NULL */
- j = (narg > 1) ? atoi(strescseq.args[1]) : -1;
- if (xsetcolorname(j, p)) {
- if (par == 104 && narg <= 1)
- return; /* color reset without parameter */
- fprintf(stderr, "erresc: invalid color j=%d, p=%s\n",
- j, p ? p : "(null)");
- } else {
- /*
- * TODO if defaultbg color is changed, borders
- * are dirty
- */
- redraw();
- }
- return;
- }
- break;
- case 'k': /* old title set compatibility */
- xsettitle(strescseq.args[0]);
- return;
- case 'P': /* DCS -- Device Control String */
- case '_': /* APC -- Application Program Command */
- case '^': /* PM -- Privacy Message */
- return;
- }
-
- fprintf(stderr, "erresc: unknown str ");
- strdump();
-}
-
-void
-strparse(void)
-{
- int c;
- char *p = strescseq.buf;
-
- strescseq.narg = 0;
- strescseq.buf[strescseq.len] = '\0';
-
- if (*p == '\0')
- return;
-
- while (strescseq.narg < STR_ARG_SIZ) {
- strescseq.args[strescseq.narg++] = p;
- while ((c = *p) != ';' && c != '\0')
- ++p;
- if (c == '\0')
- return;
- *p++ = '\0';
- }
-}
-
-void
-strdump(void)
-{
- size_t i;
- uint c;
-
- fprintf(stderr, "ESC%c", strescseq.type);
- for (i = 0; i < strescseq.len; i++) {
- c = strescseq.buf[i] & 0xff;
- if (c == '\0') {
- putc('\n', stderr);
- return;
- } else if (isprint(c)) {
- putc(c, stderr);
- } else if (c == '\n') {
- fprintf(stderr, "(\\n)");
- } else if (c == '\r') {
- fprintf(stderr, "(\\r)");
- } else if (c == 0x1b) {
- fprintf(stderr, "(\\e)");
- } else {
- fprintf(stderr, "(%02x)", c);
- }
- }
- fprintf(stderr, "ESC\\\n");
-}
-
-void
-strreset(void)
-{
- strescseq = (STREscape){
- .buf = xrealloc(strescseq.buf, STR_BUF_SIZ),
- .siz = STR_BUF_SIZ,
- };
-}
-
-void
-sendbreak(const Arg *arg)
-{
- if (tcsendbreak(cmdfd, 0))
- perror("Error sending break");
-}
-
-void
-tprinter(char *s, size_t len)
-{
- if (iofd != -1 && xwrite(iofd, s, len) < 0) {
- perror("Error writing to output file");
- close(iofd);
- iofd = -1;
- }
-}
-
-void
-toggleprinter(const Arg *arg)
-{
- term.mode ^= MODE_PRINT;
-}
-
-void
-printscreen(const Arg *arg)
-{
- tdump();
-}
-
-void
-printsel(const Arg *arg)
-{
- tdumpsel();
-}
-
-void
-tdumpsel(void)
-{
- char *ptr;
-
- if ((ptr = getsel())) {
- tprinter(ptr, strlen(ptr));
- free(ptr);
- }
-}
-
-void
-tdumpline(int n)
-{
- char buf[UTF_SIZ];
- const Glyph *bp, *end;
-
- bp = &term.line[n][0];
- end = &bp[MIN(tlinelen(n), term.col) - 1];
- if (bp != end || bp->u != ' ') {
- for ( ; bp <= end; ++bp)
- tprinter(buf, utf8encode(bp->u, buf));
- }
- tprinter("\n", 1);
-}
-
-void
-tdump(void)
-{
- int i;
-
- for (i = 0; i < term.row; ++i)
- tdumpline(i);
-}
-
-void
-tputtab(int n)
-{
- uint x = term.c.x;
-
- if (n > 0) {
- while (x < term.col && n--)
- for (++x; x < term.col && !term.tabs[x]; ++x)
- /* nothing */ ;
- } else if (n < 0) {
- while (x > 0 && n++)
- for (--x; x > 0 && !term.tabs[x]; --x)
- /* nothing */ ;
- }
- term.c.x = LIMIT(x, 0, term.col-1);
-}
-
-void
-tdefutf8(char ascii)
-{
- if (ascii == 'G')
- term.mode |= MODE_UTF8;
- else if (ascii == '@')
- term.mode &= ~MODE_UTF8;
-}
-
-void
-tdeftran(char ascii)
-{
- static char cs[] = "0B";
- static int vcs[] = {CS_GRAPHIC0, CS_USA};
- char *p;
-
- if ((p = strchr(cs, ascii)) == NULL) {
- fprintf(stderr, "esc unhandled charset: ESC ( %c\n", ascii);
- } else {
- term.trantbl[term.icharset] = vcs[p - cs];
- }
-}
-
-void
-tdectest(char c)
-{
- int x, y;
-
- if (c == '8') { /* DEC screen alignment test. */
- for (x = 0; x < term.col; ++x) {
- for (y = 0; y < term.row; ++y)
- tsetchar('E', &term.c.attr, x, y);
- }
- }
-}
-
-void
-tstrsequence(uchar c)
-{
- switch (c) {
- case 0x90: /* DCS -- Device Control String */
- c = 'P';
- break;
- case 0x9f: /* APC -- Application Program Command */
- c = '_';
- break;
- case 0x9e: /* PM -- Privacy Message */
- c = '^';
- break;
- case 0x9d: /* OSC -- Operating System Command */
- c = ']';
- break;
- }
- strreset();
- strescseq.type = c;
- term.esc |= ESC_STR;
-}
-
-void
-tcontrolcode(uchar ascii)
-{
- switch (ascii) {
- case '\t': /* HT */
- tputtab(1);
- return;
- case '\b': /* BS */
- tmoveto(term.c.x-1, term.c.y);
- return;
- case '\r': /* CR */
- tmoveto(0, term.c.y);
- return;
- case '\f': /* LF */
- case '\v': /* VT */
- case '\n': /* LF */
- /* go to first col if the mode is set */
- tnewline(IS_SET(MODE_CRLF));
- return;
- case '\a': /* BEL */
- if (term.esc & ESC_STR_END) {
- /* backwards compatibility to xterm */
- strhandle();
- } else {
- xbell();
- }
- break;
- case '\033': /* ESC */
- csireset();
- term.esc &= ~(ESC_CSI|ESC_ALTCHARSET|ESC_TEST);
- term.esc |= ESC_START;
- return;
- case '\016': /* SO (LS1 -- Locking shift 1) */
- case '\017': /* SI (LS0 -- Locking shift 0) */
- term.charset = 1 - (ascii - '\016');
- return;
- case '\032': /* SUB */
- tsetchar('?', &term.c.attr, term.c.x, term.c.y);
- /* FALLTHROUGH */
- case '\030': /* CAN */
- csireset();
- break;
- case '\005': /* ENQ (IGNORED) */
- case '\000': /* NUL (IGNORED) */
- case '\021': /* XON (IGNORED) */
- case '\023': /* XOFF (IGNORED) */
- case 0177: /* DEL (IGNORED) */
- return;
- case 0x80: /* TODO: PAD */
- case 0x81: /* TODO: HOP */
- case 0x82: /* TODO: BPH */
- case 0x83: /* TODO: NBH */
- case 0x84: /* TODO: IND */
- break;
- case 0x85: /* NEL -- Next line */
- tnewline(1); /* always go to first col */
- break;
- case 0x86: /* TODO: SSA */
- case 0x87: /* TODO: ESA */
- break;
- case 0x88: /* HTS -- Horizontal tab stop */
- term.tabs[term.c.x] = 1;
- break;
- case 0x89: /* TODO: HTJ */
- case 0x8a: /* TODO: VTS */
- case 0x8b: /* TODO: PLD */
- case 0x8c: /* TODO: PLU */
- case 0x8d: /* TODO: RI */
- case 0x8e: /* TODO: SS2 */
- case 0x8f: /* TODO: SS3 */
- case 0x91: /* TODO: PU1 */
- case 0x92: /* TODO: PU2 */
- case 0x93: /* TODO: STS */
- case 0x94: /* TODO: CCH */
- case 0x95: /* TODO: MW */
- case 0x96: /* TODO: SPA */
- case 0x97: /* TODO: EPA */
- case 0x98: /* TODO: SOS */
- case 0x99: /* TODO: SGCI */
- break;
- case 0x9a: /* DECID -- Identify Terminal */
- ttywrite(vtiden, strlen(vtiden), 0);
- break;
- case 0x9b: /* TODO: CSI */
- case 0x9c: /* TODO: ST */
- break;
- case 0x90: /* DCS -- Device Control String */
- case 0x9d: /* OSC -- Operating System Command */
- case 0x9e: /* PM -- Privacy Message */
- case 0x9f: /* APC -- Application Program Command */
- tstrsequence(ascii);
- return;
- }
- /* only CAN, SUB, \a and C1 chars interrupt a sequence */
- term.esc &= ~(ESC_STR_END|ESC_STR);
-}
-
-/*
- * returns 1 when the sequence is finished and it hasn't to read
- * more characters for this sequence, otherwise 0
- */
-int
-eschandle(uchar ascii)
-{
- switch (ascii) {
- case '[':
- term.esc |= ESC_CSI;
- return 0;
- case '#':
- term.esc |= ESC_TEST;
- return 0;
- case '%':
- term.esc |= ESC_UTF8;
- return 0;
- case 'P': /* DCS -- Device Control String */
- case '_': /* APC -- Application Program Command */
- case '^': /* PM -- Privacy Message */
- case ']': /* OSC -- Operating System Command */
- case 'k': /* old title set compatibility */
- tstrsequence(ascii);
- return 0;
- case 'n': /* LS2 -- Locking shift 2 */
- case 'o': /* LS3 -- Locking shift 3 */
- term.charset = 2 + (ascii - 'n');
- break;
- case '(': /* GZD4 -- set primary charset G0 */
- case ')': /* G1D4 -- set secondary charset G1 */
- case '*': /* G2D4 -- set tertiary charset G2 */
- case '+': /* G3D4 -- set quaternary charset G3 */
- term.icharset = ascii - '(';
- term.esc |= ESC_ALTCHARSET;
- return 0;
- case 'D': /* IND -- Linefeed */
- if (term.c.y == term.bot) {
- tscrollup(term.top, 1, 1);
- } else {
- tmoveto(term.c.x, term.c.y+1);
- }
- break;
- case 'E': /* NEL -- Next line */
- tnewline(1); /* always go to first col */
- break;
- case 'H': /* HTS -- Horizontal tab stop */
- term.tabs[term.c.x] = 1;
- break;
- case 'M': /* RI -- Reverse index */
- if (term.c.y == term.top) {
- tscrolldown(term.top, 1, 1);
- } else {
- tmoveto(term.c.x, term.c.y-1);
- }
- break;
- case 'Z': /* DECID -- Identify Terminal */
- ttywrite(vtiden, strlen(vtiden), 0);
- break;
- case 'c': /* RIS -- Reset to initial state */
- treset();
- resettitle();
- xloadcols();
- break;
- case '=': /* DECPAM -- Application keypad */
- xsetmode(1, MODE_APPKEYPAD);
- break;
- case '>': /* DECPNM -- Normal keypad */
- xsetmode(0, MODE_APPKEYPAD);
- break;
- case '7': /* DECSC -- Save Cursor */
- tcursor(CURSOR_SAVE);
- break;
- case '8': /* DECRC -- Restore Cursor */
- tcursor(CURSOR_LOAD);
- break;
- case '\\': /* ST -- String Terminator */
- if (term.esc & ESC_STR_END)
- strhandle();
- break;
- default:
- fprintf(stderr, "erresc: unknown sequence ESC 0x%02X '%c'\n",
- (uchar) ascii, isprint(ascii)? ascii:'.');
- break;
- }
- return 1;
-}
-
-void
-tputc(Rune u)
-{
- char c[UTF_SIZ];
- int control;
- int width, len;
- Glyph *gp;
-
- control = ISCONTROL(u);
- if (u < 127 || !IS_SET(MODE_UTF8)) {
- c[0] = u;
- width = len = 1;
- } else {
- len = utf8encode(u, c);
- if (!control && (width = wcwidth(u)) == -1)
- width = 1;
- }
-
- if (IS_SET(MODE_PRINT))
- tprinter(c, len);
-
- /*
- * STR sequence must be checked before anything else
- * because it uses all following characters until it
- * receives a ESC, a SUB, a ST or any other C1 control
- * character.
- */
- if (term.esc & ESC_STR) {
- if (u == '\a' || u == 030 || u == 032 || u == 033 ||
- ISCONTROLC1(u)) {
- term.esc &= ~(ESC_START|ESC_STR);
- term.esc |= ESC_STR_END;
- goto check_control_code;
- }
-
- if (strescseq.len+len >= strescseq.siz) {
- /*
- * Here is a bug in terminals. If the user never sends
- * some code to stop the str or esc command, then st
- * will stop responding. But this is better than
- * silently failing with unknown characters. At least
- * then users will report back.
- *
- * In the case users ever get fixed, here is the code:
- */
- /*
- * term.esc = 0;
- * strhandle();
- */
- if (strescseq.siz > (SIZE_MAX - UTF_SIZ) / 2)
- return;
- strescseq.siz *= 2;
- strescseq.buf = xrealloc(strescseq.buf, strescseq.siz);
- }
-
- memmove(&strescseq.buf[strescseq.len], c, len);
- strescseq.len += len;
- return;
- }
-
-check_control_code:
- /*
- * Actions of control codes must be performed as soon they arrive
- * because they can be embedded inside a control sequence, and
- * they must not cause conflicts with sequences.
- */
- if (control) {
- tcontrolcode(u);
- /*
- * control codes are not shown ever
- */
- if (!term.esc)
- term.lastc = 0;
- return;
- } else if (term.esc & ESC_START) {
- if (term.esc & ESC_CSI) {
- csiescseq.buf[csiescseq.len++] = u;
- if (BETWEEN(u, 0x40, 0x7E)
- || csiescseq.len >= \
- sizeof(csiescseq.buf)-1) {
- term.esc = 0;
- csiparse();
- csihandle();
- }
- return;
- } else if (term.esc & ESC_UTF8) {
- tdefutf8(u);
- } else if (term.esc & ESC_ALTCHARSET) {
- tdeftran(u);
- } else if (term.esc & ESC_TEST) {
- tdectest(u);
- } else {
- if (!eschandle(u))
- return;
- /* sequence already finished */
- }
- term.esc = 0;
- /*
- * All characters which form part of a sequence are not
- * printed
- */
- return;
- }
- if (selected(term.c.x, term.c.y))
- selclear();
-
- gp = &term.line[term.c.y][term.c.x];
- if (IS_SET(MODE_WRAP) && (term.c.state & CURSOR_WRAPNEXT)) {
- gp->mode |= ATTR_WRAP;
- tnewline(1);
- gp = &term.line[term.c.y][term.c.x];
- }
-
- if (IS_SET(MODE_INSERT) && term.c.x+width < term.col)
- memmove(gp+width, gp, (term.col - term.c.x - width) * sizeof(Glyph));
-
- if (term.c.x+width > term.col) {
- tnewline(1);
- gp = &term.line[term.c.y][term.c.x];
- }
-
- tsetchar(u, &term.c.attr, term.c.x, term.c.y);
- term.lastc = u;
-
- if (width == 2) {
- gp->mode |= ATTR_WIDE;
- if (term.c.x+1 < term.col) {
- gp[1].u = '\0';
- gp[1].mode = ATTR_WDUMMY;
- }
- }
- if (term.c.x+width < term.col) {
- tmoveto(term.c.x+width, term.c.y);
- } else {
- term.c.state |= CURSOR_WRAPNEXT;
- }
-}
-
-int
-twrite(const char *buf, int buflen, int show_ctrl)
-{
- int charsize;
- Rune u;
- int n;
-
- for (n = 0; n < buflen; n += charsize) {
- if (IS_SET(MODE_UTF8)) {
- /* process a complete utf8 char */
- charsize = utf8decode(buf + n, &u, buflen - n);
- if (charsize == 0)
- break;
- } else {
- u = buf[n] & 0xFF;
- charsize = 1;
- }
- if (show_ctrl && ISCONTROL(u)) {
- if (u & 0x80) {
- u &= 0x7f;
- tputc('^');
- tputc('[');
- } else if (u != '\n' && u != '\r' && u != '\t') {
- u ^= 0x40;
- tputc('^');
- }
- }
- tputc(u);
- }
- return n;
-}
-
-void
-tresize(int col, int row)
-{
- int i, j;
- int minrow = MIN(row, term.row);
- int mincol = MIN(col, term.col);
- int *bp;
- TCursor c;
-
- if (col < 1 || row < 1) {
- fprintf(stderr,
- "tresize: error resizing to %dx%d\n", col, row);
- return;
- }
-
- /*
- * slide screen to keep cursor where we expect it -
- * tscrollup would work here, but we can optimize to
- * memmove because we're freeing the earlier lines
- */
- for (i = 0; i <= term.c.y - row; i++) {
- free(term.line[i]);
- free(term.alt[i]);
- }
- /* ensure that both src and dst are not NULL */
- if (i > 0) {
- memmove(term.line, term.line + i, row * sizeof(Line));
- memmove(term.alt, term.alt + i, row * sizeof(Line));
- }
- for (i += row; i < term.row; i++) {
- free(term.line[i]);
- free(term.alt[i]);
- }
-
- /* resize to new height */
- term.line = xrealloc(term.line, row * sizeof(Line));
- term.alt = xrealloc(term.alt, row * sizeof(Line));
- term.dirty = xrealloc(term.dirty, row * sizeof(*term.dirty));
- term.tabs = xrealloc(term.tabs, col * sizeof(*term.tabs));
-
- for (i = 0; i < HISTSIZE; i++) {
- term.hist[i] = xrealloc(term.hist[i], col * sizeof(Glyph));
- for (j = mincol; j < col; j++) {
- term.hist[i][j] = term.c.attr;
- term.hist[i][j].u = ' ';
- }
- }
-
- /* resize each row to new width, zero-pad if needed */
- for (i = 0; i < minrow; i++) {
- term.line[i] = xrealloc(term.line[i], col * sizeof(Glyph));
- term.alt[i] = xrealloc(term.alt[i], col * sizeof(Glyph));
- }
-
- /* allocate any new rows */
- for (/* i = minrow */; i < row; i++) {
- term.line[i] = xmalloc(col * sizeof(Glyph));
- term.alt[i] = xmalloc(col * sizeof(Glyph));
- }
- if (col > term.col) {
- bp = term.tabs + term.col;
-
- memset(bp, 0, sizeof(*term.tabs) * (col - term.col));
- while (--bp > term.tabs && !*bp)
- /* nothing */ ;
- for (bp += tabspaces; bp < term.tabs + col; bp += tabspaces)
- *bp = 1;
- }
- /* update terminal size */
- term.col = col;
- term.row = row;
- /* reset scrolling region */
- tsetscroll(0, row-1);
- /* make use of the LIMIT in tmoveto */
- tmoveto(term.c.x, term.c.y);
- /* Clearing both screens (it makes dirty all lines) */
- c = term.c;
- for (i = 0; i < 2; i++) {
- if (mincol < col && 0 < minrow) {
- tclearregion(mincol, 0, col - 1, minrow - 1);
- }
- if (0 < col && minrow < row) {
- tclearregion(0, minrow, col - 1, row - 1);
- }
- tswapscreen();
- tcursor(CURSOR_LOAD);
- }
- term.c = c;
-}
-
-void
-resettitle(void)
-{
- xsettitle(NULL);
-}
-
-void
-drawregion(int x1, int y1, int x2, int y2)
-{
- int y;
-
- for (y = y1; y < y2; y++) {
- if (!term.dirty[y])
- continue;
-
- term.dirty[y] = 0;
- xdrawline(TLINE(y), x1, y, x2);
- }
-}
-
-void
-draw(void)
-{
- int cx = term.c.x, ocx = term.ocx, ocy = term.ocy;
-
- if (!xstartdraw())
- return;
-
- /* adjust cursor position */
- LIMIT(term.ocx, 0, term.col-1);
- LIMIT(term.ocy, 0, term.row-1);
- if (term.line[term.ocy][term.ocx].mode & ATTR_WDUMMY)
- term.ocx--;
- if (term.line[term.c.y][cx].mode & ATTR_WDUMMY)
- cx--;
-
- drawregion(0, 0, term.col, term.row);
- if (term.scr == 0)
- xdrawcursor(cx, term.c.y, term.line[term.c.y][cx],
- term.ocx, term.ocy, term.line[term.ocy][term.ocx]);
- term.ocx = cx;
- term.ocy = term.c.y;
- xfinishdraw();
- if (ocx != term.ocx || ocy != term.ocy)
- xximspot(term.ocx, term.ocy);
-}
-
-void
-redraw(void)
-{
- tfulldirt();
- draw();
-}
diff --git a/.repos/st/st.c.orig b/.repos/st/st.c.orig
deleted file mode 100644
index a9338e1..0000000
--- a/.repos/st/st.c.orig
+++ /dev/null
@@ -1,2608 +0,0 @@
-/* See LICENSE for license details. */
-#include <ctype.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <pwd.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <signal.h>
-#include <sys/ioctl.h>
-#include <sys/select.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <termios.h>
-#include <unistd.h>
-#include <wchar.h>
-
-#include "st.h"
-#include "win.h"
-
-#if defined(__linux)
- #include <pty.h>
-#elif defined(__OpenBSD__) || defined(__NetBSD__) || defined(__APPLE__)
- #include <util.h>
-#elif defined(__FreeBSD__) || defined(__DragonFly__)
- #include <libutil.h>
-#endif
-
-/* Arbitrary sizes */
-#define UTF_INVALID 0xFFFD
-#define UTF_SIZ 4
-#define ESC_BUF_SIZ (128*UTF_SIZ)
-#define ESC_ARG_SIZ 16
-#define STR_BUF_SIZ ESC_BUF_SIZ
-#define STR_ARG_SIZ ESC_ARG_SIZ
-
-/* macros */
-#define IS_SET(flag) ((term.mode & (flag)) != 0)
-#define ISCONTROLC0(c) (BETWEEN(c, 0, 0x1f) || (c) == 0x7f)
-#define ISCONTROLC1(c) (BETWEEN(c, 0x80, 0x9f))
-#define ISCONTROL(c) (ISCONTROLC0(c) || ISCONTROLC1(c))
-#define ISDELIM(u) (u && wcschr(worddelimiters, u))
-
-enum term_mode {
- MODE_WRAP = 1 << 0,
- MODE_INSERT = 1 << 1,
- MODE_ALTSCREEN = 1 << 2,
- MODE_CRLF = 1 << 3,
- MODE_ECHO = 1 << 4,
- MODE_PRINT = 1 << 5,
- MODE_UTF8 = 1 << 6,
-};
-
-enum cursor_movement {
- CURSOR_SAVE,
- CURSOR_LOAD
-};
-
-enum cursor_state {
- CURSOR_DEFAULT = 0,
- CURSOR_WRAPNEXT = 1,
- CURSOR_ORIGIN = 2
-};
-
-enum charset {
- CS_GRAPHIC0,
- CS_GRAPHIC1,
- CS_UK,
- CS_USA,
- CS_MULTI,
- CS_GER,
- CS_FIN
-};
-
-enum escape_state {
- ESC_START = 1,
- ESC_CSI = 2,
- ESC_STR = 4, /* DCS, OSC, PM, APC */
- ESC_ALTCHARSET = 8,
- ESC_STR_END = 16, /* a final string was encountered */
- ESC_TEST = 32, /* Enter in test mode */
- ESC_UTF8 = 64,
-};
-
-typedef struct {
- Glyph attr; /* current char attributes */
- int x;
- int y;
- char state;
-} TCursor;
-
-typedef struct {
- int mode;
- int type;
- int snap;
- /*
- * Selection variables:
- * nb – normalized coordinates of the beginning of the selection
- * ne – normalized coordinates of the end of the selection
- * ob – original coordinates of the beginning of the selection
- * oe – original coordinates of the end of the selection
- */
- struct {
- int x, y;
- } nb, ne, ob, oe;
-
- int alt;
-} Selection;
-
-/* Internal representation of the screen */
-typedef struct {
- int row; /* nb row */
- int col; /* nb col */
- Line *line; /* screen */
- Line *alt; /* alternate screen */
- int *dirty; /* dirtyness of lines */
- TCursor c; /* cursor */
- int ocx; /* old cursor col */
- int ocy; /* old cursor row */
- int top; /* top scroll limit */
- int bot; /* bottom scroll limit */
- int mode; /* terminal mode flags */
- int esc; /* escape state flags */
- char trantbl[4]; /* charset table translation */
- int charset; /* current charset */
- int icharset; /* selected charset for sequence */
- int *tabs;
- Rune lastc; /* last printed char outside of sequence, 0 if control */
-} Term;
-
-/* CSI Escape sequence structs */
-/* ESC '[' [[ [<priv>] <arg> [;]] <mode> [<mode>]] */
-typedef struct {
- char buf[ESC_BUF_SIZ]; /* raw string */
- size_t len; /* raw string length */
- char priv;
- int arg[ESC_ARG_SIZ];
- int narg; /* nb of args */
- char mode[2];
-} CSIEscape;
-
-/* STR Escape sequence structs */
-/* ESC type [[ [<priv>] <arg> [;]] <mode>] ESC '\' */
-typedef struct {
- char type; /* ESC type ... */
- char *buf; /* allocated raw string */
- size_t siz; /* allocation size */
- size_t len; /* raw string length */
- char *args[STR_ARG_SIZ];
- int narg; /* nb of args */
-} STREscape;
-
-static void execsh(char *, char **);
-static void stty(char **);
-static void sigchld(int);
-static void ttywriteraw(const char *, size_t);
-
-static void csidump(void);
-static void csihandle(void);
-static void csiparse(void);
-static void csireset(void);
-static int eschandle(uchar);
-static void strdump(void);
-static void strhandle(void);
-static void strparse(void);
-static void strreset(void);
-
-static void tprinter(char *, size_t);
-static void tdumpsel(void);
-static void tdumpline(int);
-static void tdump(void);
-static void tclearregion(int, int, int, int);
-static void tcursor(int);
-static void tdeletechar(int);
-static void tdeleteline(int);
-static void tinsertblank(int);
-static void tinsertblankline(int);
-static int tlinelen(int);
-static void tmoveto(int, int);
-static void tmoveato(int, int);
-static void tnewline(int);
-static void tputtab(int);
-static void tputc(Rune);
-static void treset(void);
-static void tscrollup(int, int);
-static void tscrolldown(int, int);
-static void tsetattr(const int *, int);
-static void tsetchar(Rune, const Glyph *, int, int);
-static void tsetdirt(int, int);
-static void tsetscroll(int, int);
-static void tswapscreen(void);
-static void tsetmode(int, int, const int *, int);
-static int twrite(const char *, int, int);
-static void tfulldirt(void);
-static void tcontrolcode(uchar );
-static void tdectest(char );
-static void tdefutf8(char);
-static int32_t tdefcolor(const int *, int *, int);
-static void tdeftran(char);
-static void tstrsequence(uchar);
-
-static void drawregion(int, int, int, int);
-
-static void selnormalize(void);
-static void selscroll(int, int);
-static void selsnap(int *, int *, int);
-
-static size_t utf8decode(const char *, Rune *, size_t);
-static Rune utf8decodebyte(char, size_t *);
-static char utf8encodebyte(Rune, size_t);
-static size_t utf8validate(Rune *, size_t);
-
-static char *base64dec(const char *);
-static char base64dec_getc(const char **);
-
-static ssize_t xwrite(int, const char *, size_t);
-
-/* Globals */
-static Term term;
-static Selection sel;
-static CSIEscape csiescseq;
-static STREscape strescseq;
-static int iofd = 1;
-static int cmdfd;
-static pid_t pid;
-
-static const uchar utfbyte[UTF_SIZ + 1] = {0x80, 0, 0xC0, 0xE0, 0xF0};
-static const uchar utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8};
-static const Rune utfmin[UTF_SIZ + 1] = { 0, 0, 0x80, 0x800, 0x10000};
-static const Rune utfmax[UTF_SIZ + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF};
-
-ssize_t
-xwrite(int fd, const char *s, size_t len)
-{
- size_t aux = len;
- ssize_t r;
-
- while (len > 0) {
- r = write(fd, s, len);
- if (r < 0)
- return r;
- len -= r;
- s += r;
- }
-
- return aux;
-}
-
-void *
-xmalloc(size_t len)
-{
- void *p;
-
- if (!(p = malloc(len)))
- die("malloc: %s\n", strerror(errno));
-
- return p;
-}
-
-void *
-xrealloc(void *p, size_t len)
-{
- if ((p = realloc(p, len)) == NULL)
- die("realloc: %s\n", strerror(errno));
-
- return p;
-}
-
-char *
-xstrdup(const char *s)
-{
- char *p;
-
- if ((p = strdup(s)) == NULL)
- die("strdup: %s\n", strerror(errno));
-
- return p;
-}
-
-size_t
-utf8decode(const char *c, Rune *u, size_t clen)
-{
- size_t i, j, len, type;
- Rune udecoded;
-
- *u = UTF_INVALID;
- if (!clen)
- return 0;
- udecoded = utf8decodebyte(c[0], &len);
- if (!BETWEEN(len, 1, UTF_SIZ))
- return 1;
- for (i = 1, j = 1; i < clen && j < len; ++i, ++j) {
- udecoded = (udecoded << 6) | utf8decodebyte(c[i], &type);
- if (type != 0)
- return j;
- }
- if (j < len)
- return 0;
- *u = udecoded;
- utf8validate(u, len);
-
- return len;
-}
-
-Rune
-utf8decodebyte(char c, size_t *i)
-{
- for (*i = 0; *i < LEN(utfmask); ++(*i))
- if (((uchar)c & utfmask[*i]) == utfbyte[*i])
- return (uchar)c & ~utfmask[*i];
-
- return 0;
-}
-
-size_t
-utf8encode(Rune u, char *c)
-{
- size_t len, i;
-
- len = utf8validate(&u, 0);
- if (len > UTF_SIZ)
- return 0;
-
- for (i = len - 1; i != 0; --i) {
- c[i] = utf8encodebyte(u, 0);
- u >>= 6;
- }
- c[0] = utf8encodebyte(u, len);
-
- return len;
-}
-
-char
-utf8encodebyte(Rune u, size_t i)
-{
- return utfbyte[i] | (u & ~utfmask[i]);
-}
-
-size_t
-utf8validate(Rune *u, size_t i)
-{
- if (!BETWEEN(*u, utfmin[i], utfmax[i]) || BETWEEN(*u, 0xD800, 0xDFFF))
- *u = UTF_INVALID;
- for (i = 1; *u > utfmax[i]; ++i)
- ;
-
- return i;
-}
-
-static const char base64_digits[] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0,
- 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0, 0, 0, -1, 0, 0, 0, 0, 1,
- 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
- 22, 23, 24, 25, 0, 0, 0, 0, 0, 0, 26, 27, 28, 29, 30, 31, 32, 33, 34,
- 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-};
-
-char
-base64dec_getc(const char **src)
-{
- while (**src && !isprint(**src))
- (*src)++;
- return **src ? *((*src)++) : '='; /* emulate padding if string ends */
-}
-
-char *
-base64dec(const char *src)
-{
- size_t in_len = strlen(src);
- char *result, *dst;
-
- if (in_len % 4)
- in_len += 4 - (in_len % 4);
- result = dst = xmalloc(in_len / 4 * 3 + 1);
- while (*src) {
- int a = base64_digits[(unsigned char) base64dec_getc(&src)];
- int b = base64_digits[(unsigned char) base64dec_getc(&src)];
- int c = base64_digits[(unsigned char) base64dec_getc(&src)];
- int d = base64_digits[(unsigned char) base64dec_getc(&src)];
-
- /* invalid input. 'a' can be -1, e.g. if src is "\n" (c-str) */
- if (a == -1 || b == -1)
- break;
-
- *dst++ = (a << 2) | ((b & 0x30) >> 4);
- if (c == -1)
- break;
- *dst++ = ((b & 0x0f) << 4) | ((c & 0x3c) >> 2);
- if (d == -1)
- break;
- *dst++ = ((c & 0x03) << 6) | d;
- }
- *dst = '\0';
- return result;
-}
-
-void
-selinit(void)
-{
- sel.mode = SEL_IDLE;
- sel.snap = 0;
- sel.ob.x = -1;
-}
-
-int
-tlinelen(int y)
-{
- int i = term.col;
-
- if (term.line[y][i - 1].mode & ATTR_WRAP)
- return i;
-
- while (i > 0 && term.line[y][i - 1].u == ' ')
- --i;
-
- return i;
-}
-
-void
-selstart(int col, int row, int snap)
-{
- selclear();
- sel.mode = SEL_EMPTY;
- sel.type = SEL_REGULAR;
- sel.alt = IS_SET(MODE_ALTSCREEN);
- sel.snap = snap;
- sel.oe.x = sel.ob.x = col;
- sel.oe.y = sel.ob.y = row;
- selnormalize();
-
- if (sel.snap != 0)
- sel.mode = SEL_READY;
- tsetdirt(sel.nb.y, sel.ne.y);
-}
-
-void
-selextend(int col, int row, int type, int done)
-{
- int oldey, oldex, oldsby, oldsey, oldtype;
-
- if (sel.mode == SEL_IDLE)
- return;
- if (done && sel.mode == SEL_EMPTY) {
- selclear();
- return;
- }
-
- oldey = sel.oe.y;
- oldex = sel.oe.x;
- oldsby = sel.nb.y;
- oldsey = sel.ne.y;
- oldtype = sel.type;
-
- sel.oe.x = col;
- sel.oe.y = row;
- selnormalize();
- sel.type = type;
-
- if (oldey != sel.oe.y || oldex != sel.oe.x || oldtype != sel.type || sel.mode == SEL_EMPTY)
- tsetdirt(MIN(sel.nb.y, oldsby), MAX(sel.ne.y, oldsey));
-
- sel.mode = done ? SEL_IDLE : SEL_READY;
-}
-
-void
-selnormalize(void)
-{
- int i;
-
- if (sel.type == SEL_REGULAR && sel.ob.y != sel.oe.y) {
- sel.nb.x = sel.ob.y < sel.oe.y ? sel.ob.x : sel.oe.x;
- sel.ne.x = sel.ob.y < sel.oe.y ? sel.oe.x : sel.ob.x;
- } else {
- sel.nb.x = MIN(sel.ob.x, sel.oe.x);
- sel.ne.x = MAX(sel.ob.x, sel.oe.x);
- }
- sel.nb.y = MIN(sel.ob.y, sel.oe.y);
- sel.ne.y = MAX(sel.ob.y, sel.oe.y);
-
- selsnap(&sel.nb.x, &sel.nb.y, -1);
- selsnap(&sel.ne.x, &sel.ne.y, +1);
-
- /* expand selection over line breaks */
- if (sel.type == SEL_RECTANGULAR)
- return;
- i = tlinelen(sel.nb.y);
- if (i < sel.nb.x)
- sel.nb.x = i;
- if (tlinelen(sel.ne.y) <= sel.ne.x)
- sel.ne.x = term.col - 1;
-}
-
-int
-selected(int x, int y)
-{
- if (sel.mode == SEL_EMPTY || sel.ob.x == -1 ||
- sel.alt != IS_SET(MODE_ALTSCREEN))
- return 0;
-
- if (sel.type == SEL_RECTANGULAR)
- return BETWEEN(y, sel.nb.y, sel.ne.y)
- && BETWEEN(x, sel.nb.x, sel.ne.x);
-
- return BETWEEN(y, sel.nb.y, sel.ne.y)
- && (y != sel.nb.y || x >= sel.nb.x)
- && (y != sel.ne.y || x <= sel.ne.x);
-}
-
-void
-selsnap(int *x, int *y, int direction)
-{
- int newx, newy, xt, yt;
- int delim, prevdelim;
- const Glyph *gp, *prevgp;
-
- switch (sel.snap) {
- case SNAP_WORD:
- /*
- * Snap around if the word wraps around at the end or
- * beginning of a line.
- */
- prevgp = &term.line[*y][*x];
- prevdelim = ISDELIM(prevgp->u);
- for (;;) {
- newx = *x + direction;
- newy = *y;
- if (!BETWEEN(newx, 0, term.col - 1)) {
- newy += direction;
- newx = (newx + term.col) % term.col;
- if (!BETWEEN(newy, 0, term.row - 1))
- break;
-
- if (direction > 0)
- yt = *y, xt = *x;
- else
- yt = newy, xt = newx;
- if (!(term.line[yt][xt].mode & ATTR_WRAP))
- break;
- }
-
- if (newx >= tlinelen(newy))
- break;
-
- gp = &term.line[newy][newx];
- delim = ISDELIM(gp->u);
- if (!(gp->mode & ATTR_WDUMMY) && (delim != prevdelim
- || (delim && gp->u != prevgp->u)))
- break;
-
- *x = newx;
- *y = newy;
- prevgp = gp;
- prevdelim = delim;
- }
- break;
- case SNAP_LINE:
- /*
- * Snap around if the the previous line or the current one
- * has set ATTR_WRAP at its end. Then the whole next or
- * previous line will be selected.
- */
- *x = (direction < 0) ? 0 : term.col - 1;
- if (direction < 0) {
- for (; *y > 0; *y += direction) {
- if (!(term.line[*y-1][term.col-1].mode
- & ATTR_WRAP)) {
- break;
- }
- }
- } else if (direction > 0) {
- for (; *y < term.row-1; *y += direction) {
- if (!(term.line[*y][term.col-1].mode
- & ATTR_WRAP)) {
- break;
- }
- }
- }
- break;
- }
-}
-
-char *
-getsel(void)
-{
- char *str, *ptr;
- int y, bufsize, lastx, linelen;
- const Glyph *gp, *last;
-
- if (sel.ob.x == -1)
- return NULL;
-
- bufsize = (term.col+1) * (sel.ne.y-sel.nb.y+1) * UTF_SIZ;
- ptr = str = xmalloc(bufsize);
-
- /* append every set & selected glyph to the selection */
- for (y = sel.nb.y; y <= sel.ne.y; y++) {
- if ((linelen = tlinelen(y)) == 0) {
- *ptr++ = '\n';
- continue;
- }
-
- if (sel.type == SEL_RECTANGULAR) {
- gp = &term.line[y][sel.nb.x];
- lastx = sel.ne.x;
- } else {
- gp = &term.line[y][sel.nb.y == y ? sel.nb.x : 0];
- lastx = (sel.ne.y == y) ? sel.ne.x : term.col-1;
- }
- last = &term.line[y][MIN(lastx, linelen-1)];
- while (last >= gp && last->u == ' ')
- --last;
-
- for ( ; gp <= last; ++gp) {
- if (gp->mode & ATTR_WDUMMY)
- continue;
-
- ptr += utf8encode(gp->u, ptr);
- }
-
- /*
- * Copy and pasting of line endings is inconsistent
- * in the inconsistent terminal and GUI world.
- * The best solution seems like to produce '\n' when
- * something is copied from st and convert '\n' to
- * '\r', when something to be pasted is received by
- * st.
- * FIXME: Fix the computer world.
- */
- if ((y < sel.ne.y || lastx >= linelen) &&
- (!(last->mode & ATTR_WRAP) || sel.type == SEL_RECTANGULAR))
- *ptr++ = '\n';
- }
- *ptr = 0;
- return str;
-}
-
-void
-selclear(void)
-{
- if (sel.ob.x == -1)
- return;
- sel.mode = SEL_IDLE;
- sel.ob.x = -1;
- tsetdirt(sel.nb.y, sel.ne.y);
-}
-
-void
-die(const char *errstr, ...)
-{
- va_list ap;
-
- va_start(ap, errstr);
- vfprintf(stderr, errstr, ap);
- va_end(ap);
- exit(1);
-}
-
-void
-execsh(char *cmd, char **args)
-{
- char *sh, *prog, *arg;
- const struct passwd *pw;
-
- errno = 0;
- if ((pw = getpwuid(getuid())) == NULL) {
- if (errno)
- die("getpwuid: %s\n", strerror(errno));
- else
- die("who are you?\n");
- }
-
- if ((sh = getenv("SHELL")) == NULL)
- sh = (pw->pw_shell[0]) ? pw->pw_shell : cmd;
-
- if (args) {
- prog = args[0];
- arg = NULL;
- } else if (scroll) {
- prog = scroll;
- arg = utmp ? utmp : sh;
- } else if (utmp) {
- prog = utmp;
- arg = NULL;
- } else {
- prog = sh;
- arg = NULL;
- }
- DEFAULT(args, ((char *[]) {prog, arg, NULL}));
-
- unsetenv("COLUMNS");
- unsetenv("LINES");
- unsetenv("TERMCAP");
- setenv("LOGNAME", pw->pw_name, 1);
- setenv("USER", pw->pw_name, 1);
- setenv("SHELL", sh, 1);
- setenv("HOME", pw->pw_dir, 1);
- setenv("TERM", termname, 1);
-
- signal(SIGCHLD, SIG_DFL);
- signal(SIGHUP, SIG_DFL);
- signal(SIGINT, SIG_DFL);
- signal(SIGQUIT, SIG_DFL);
- signal(SIGTERM, SIG_DFL);
- signal(SIGALRM, SIG_DFL);
-
- execvp(prog, args);
- _exit(1);
-}
-
-void
-sigchld(int a)
-{
- int stat;
- pid_t p;
-
- if ((p = waitpid(pid, &stat, WNOHANG)) < 0)
- die("waiting for pid %hd failed: %s\n", pid, strerror(errno));
-
- if (pid != p)
- return;
-
- if (WIFEXITED(stat) && WEXITSTATUS(stat))
- die("child exited with status %d\n", WEXITSTATUS(stat));
- else if (WIFSIGNALED(stat))
- die("child terminated due to signal %d\n", WTERMSIG(stat));
- _exit(0);
-}
-
-void
-stty(char **args)
-{
- char cmd[_POSIX_ARG_MAX], **p, *q, *s;
- size_t n, siz;
-
- if ((n = strlen(stty_args)) > sizeof(cmd)-1)
- die("incorrect stty parameters\n");
- memcpy(cmd, stty_args, n);
- q = cmd + n;
- siz = sizeof(cmd) - n;
- for (p = args; p && (s = *p); ++p) {
- if ((n = strlen(s)) > siz-1)
- die("stty parameter length too long\n");
- *q++ = ' ';
- memcpy(q, s, n);
- q += n;
- siz -= n + 1;
- }
- *q = '\0';
- if (system(cmd) != 0)
- perror("Couldn't call stty");
-}
-
-int
-ttynew(const char *line, char *cmd, const char *out, char **args)
-{
- int m, s;
-
- if (out) {
- term.mode |= MODE_PRINT;
- iofd = (!strcmp(out, "-")) ?
- 1 : open(out, O_WRONLY | O_CREAT, 0666);
- if (iofd < 0) {
- fprintf(stderr, "Error opening %s:%s\n",
- out, strerror(errno));
- }
- }
-
- if (line) {
- if ((cmdfd = open(line, O_RDWR)) < 0)
- die("open line '%s' failed: %s\n",
- line, strerror(errno));
- dup2(cmdfd, 0);
- stty(args);
- return cmdfd;
- }
-
- /* seems to work fine on linux, openbsd and freebsd */
- if (openpty(&m, &s, NULL, NULL, NULL) < 0)
- die("openpty failed: %s\n", strerror(errno));
-
- switch (pid = fork()) {
- case -1:
- die("fork failed: %s\n", strerror(errno));
- break;
- case 0:
- close(iofd);
- close(m);
- setsid(); /* create a new process group */
- dup2(s, 0);
- dup2(s, 1);
- dup2(s, 2);
- if (ioctl(s, TIOCSCTTY, NULL) < 0)
- die("ioctl TIOCSCTTY failed: %s\n", strerror(errno));
- if (s > 2)
- close(s);
-#ifdef __OpenBSD__
- if (pledge("stdio getpw proc exec", NULL) == -1)
- die("pledge\n");
-#endif
- execsh(cmd, args);
- break;
- default:
-#ifdef __OpenBSD__
- if (pledge("stdio rpath tty proc", NULL) == -1)
- die("pledge\n");
-#endif
- close(s);
- cmdfd = m;
- signal(SIGCHLD, sigchld);
- break;
- }
- return cmdfd;
-}
-
-size_t
-ttyread(void)
-{
- static char buf[BUFSIZ];
- static int buflen = 0;
- int ret, written;
-
- /* append read bytes to unprocessed bytes */
- ret = read(cmdfd, buf+buflen, LEN(buf)-buflen);
-
- switch (ret) {
- case 0:
- exit(0);
- case -1:
- die("couldn't read from shell: %s\n", strerror(errno));
- default:
- buflen += ret;
- written = twrite(buf, buflen, 0);
- buflen -= written;
- /* keep any incomplete UTF-8 byte sequence for the next call */
- if (buflen > 0)
- memmove(buf, buf + written, buflen);
- return ret;
- }
-}
-
-void
-ttywrite(const char *s, size_t n, int may_echo)
-{
- const char *next;
-
- if (may_echo && IS_SET(MODE_ECHO))
- twrite(s, n, 1);
-
- if (!IS_SET(MODE_CRLF)) {
- ttywriteraw(s, n);
- return;
- }
-
- /* This is similar to how the kernel handles ONLCR for ttys */
- while (n > 0) {
- if (*s == '\r') {
- next = s + 1;
- ttywriteraw("\r\n", 2);
- } else {
- next = memchr(s, '\r', n);
- DEFAULT(next, s + n);
- ttywriteraw(s, next - s);
- }
- n -= next - s;
- s = next;
- }
-}
-
-void
-ttywriteraw(const char *s, size_t n)
-{
- fd_set wfd, rfd;
- ssize_t r;
- size_t lim = 256;
-
- /*
- * Remember that we are using a pty, which might be a modem line.
- * Writing too much will clog the line. That's why we are doing this
- * dance.
- * FIXME: Migrate the world to Plan 9.
- */
- while (n > 0) {
- FD_ZERO(&wfd);
- FD_ZERO(&rfd);
- FD_SET(cmdfd, &wfd);
- FD_SET(cmdfd, &rfd);
-
- /* Check if we can write. */
- if (pselect(cmdfd+1, &rfd, &wfd, NULL, NULL, NULL) < 0) {
- if (errno == EINTR)
- continue;
- die("select failed: %s\n", strerror(errno));
- }
- if (FD_ISSET(cmdfd, &wfd)) {
- /*
- * Only write the bytes written by ttywrite() or the
- * default of 256. This seems to be a reasonable value
- * for a serial line. Bigger values might clog the I/O.
- */
- if ((r = write(cmdfd, s, (n < lim)? n : lim)) < 0)
- goto write_error;
- if (r < n) {
- /*
- * We weren't able to write out everything.
- * This means the buffer is getting full
- * again. Empty it.
- */
- if (n < lim)
- lim = ttyread();
- n -= r;
- s += r;
- } else {
- /* All bytes have been written. */
- break;
- }
- }
- if (FD_ISSET(cmdfd, &rfd))
- lim = ttyread();
- }
- return;
-
-write_error:
- die("write error on tty: %s\n", strerror(errno));
-}
-
-void
-ttyresize(int tw, int th)
-{
- struct winsize w;
-
- w.ws_row = term.row;
- w.ws_col = term.col;
- w.ws_xpixel = tw;
- w.ws_ypixel = th;
- if (ioctl(cmdfd, TIOCSWINSZ, &w) < 0)
- fprintf(stderr, "Couldn't set window size: %s\n", strerror(errno));
-}
-
-void
-ttyhangup()
-{
- /* Send SIGHUP to shell */
- kill(pid, SIGHUP);
-}
-
-int
-tattrset(int attr)
-{
- int i, j;
-
- for (i = 0; i < term.row-1; i++) {
- for (j = 0; j < term.col-1; j++) {
- if (term.line[i][j].mode & attr)
- return 1;
- }
- }
-
- return 0;
-}
-
-void
-tsetdirt(int top, int bot)
-{
- int i;
-
- LIMIT(top, 0, term.row-1);
- LIMIT(bot, 0, term.row-1);
-
- for (i = top; i <= bot; i++)
- term.dirty[i] = 1;
-}
-
-void
-tsetdirtattr(int attr)
-{
- int i, j;
-
- for (i = 0; i < term.row-1; i++) {
- for (j = 0; j < term.col-1; j++) {
- if (term.line[i][j].mode & attr) {
- tsetdirt(i, i);
- break;
- }
- }
- }
-}
-
-void
-tfulldirt(void)
-{
- tsetdirt(0, term.row-1);
-}
-
-void
-tcursor(int mode)
-{
- static TCursor c[2];
- int alt = IS_SET(MODE_ALTSCREEN);
-
- if (mode == CURSOR_SAVE) {
- c[alt] = term.c;
- } else if (mode == CURSOR_LOAD) {
- term.c = c[alt];
- tmoveto(c[alt].x, c[alt].y);
- }
-}
-
-void
-treset(void)
-{
- uint i;
-
- term.c = (TCursor){{
- .mode = ATTR_NULL,
- .fg = defaultfg,
- .bg = defaultbg
- }, .x = 0, .y = 0, .state = CURSOR_DEFAULT};
-
- memset(term.tabs, 0, term.col * sizeof(*term.tabs));
- for (i = tabspaces; i < term.col; i += tabspaces)
- term.tabs[i] = 1;
- term.top = 0;
- term.bot = term.row - 1;
- term.mode = MODE_WRAP|MODE_UTF8;
- memset(term.trantbl, CS_USA, sizeof(term.trantbl));
- term.charset = 0;
-
- for (i = 0; i < 2; i++) {
- tmoveto(0, 0);
- tcursor(CURSOR_SAVE);
- tclearregion(0, 0, term.col-1, term.row-1);
- tswapscreen();
- }
-}
-
-void
-tnew(int col, int row)
-{
- term = (Term){ .c = { .attr = { .fg = defaultfg, .bg = defaultbg } } };
- tresize(col, row);
- treset();
-}
-
-void
-tswapscreen(void)
-{
- Line *tmp = term.line;
-
- term.line = term.alt;
- term.alt = tmp;
- term.mode ^= MODE_ALTSCREEN;
- tfulldirt();
-}
-
-void
-tscrolldown(int orig, int n)
-{
- int i;
- Line temp;
-
- LIMIT(n, 0, term.bot-orig+1);
-
- tsetdirt(orig, term.bot-n);
- tclearregion(0, term.bot-n+1, term.col-1, term.bot);
-
- for (i = term.bot; i >= orig+n; i--) {
- temp = term.line[i];
- term.line[i] = term.line[i-n];
- term.line[i-n] = temp;
- }
-
- selscroll(orig, n);
-}
-
-void
-tscrollup(int orig, int n)
-{
- int i;
- Line temp;
-
- LIMIT(n, 0, term.bot-orig+1);
-
- tclearregion(0, orig, term.col-1, orig+n-1);
- tsetdirt(orig+n, term.bot);
-
- for (i = orig; i <= term.bot-n; i++) {
- temp = term.line[i];
- term.line[i] = term.line[i+n];
- term.line[i+n] = temp;
- }
-
- selscroll(orig, -n);
-}
-
-void
-selscroll(int orig, int n)
-{
- if (sel.ob.x == -1)
- return;
-
- if (BETWEEN(sel.nb.y, orig, term.bot) != BETWEEN(sel.ne.y, orig, term.bot)) {
- selclear();
- } else if (BETWEEN(sel.nb.y, orig, term.bot)) {
- sel.ob.y += n;
- sel.oe.y += n;
- if (sel.ob.y < term.top || sel.ob.y > term.bot ||
- sel.oe.y < term.top || sel.oe.y > term.bot) {
- selclear();
- } else {
- selnormalize();
- }
- }
-}
-
-void
-tnewline(int first_col)
-{
- int y = term.c.y;
-
- if (y == term.bot) {
- tscrollup(term.top, 1);
- } else {
- y++;
- }
- tmoveto(first_col ? 0 : term.c.x, y);
-}
-
-void
-csiparse(void)
-{
- char *p = csiescseq.buf, *np;
- long int v;
-
- csiescseq.narg = 0;
- if (*p == '?') {
- csiescseq.priv = 1;
- p++;
- }
-
- csiescseq.buf[csiescseq.len] = '\0';
- while (p < csiescseq.buf+csiescseq.len) {
- np = NULL;
- v = strtol(p, &np, 10);
- if (np == p)
- v = 0;
- if (v == LONG_MAX || v == LONG_MIN)
- v = -1;
- csiescseq.arg[csiescseq.narg++] = v;
- p = np;
- if (*p != ';' || csiescseq.narg == ESC_ARG_SIZ)
- break;
- p++;
- }
- csiescseq.mode[0] = *p++;
- csiescseq.mode[1] = (p < csiescseq.buf+csiescseq.len) ? *p : '\0';
-}
-
-/* for absolute user moves, when decom is set */
-void
-tmoveato(int x, int y)
-{
- tmoveto(x, y + ((term.c.state & CURSOR_ORIGIN) ? term.top: 0));
-}
-
-void
-tmoveto(int x, int y)
-{
- int miny, maxy;
-
- if (term.c.state & CURSOR_ORIGIN) {
- miny = term.top;
- maxy = term.bot;
- } else {
- miny = 0;
- maxy = term.row - 1;
- }
- term.c.state &= ~CURSOR_WRAPNEXT;
- term.c.x = LIMIT(x, 0, term.col-1);
- term.c.y = LIMIT(y, miny, maxy);
-}
-
-void
-tsetchar(Rune u, const Glyph *attr, int x, int y)
-{
- static const char *vt100_0[62] = { /* 0x41 - 0x7e */
- "↑", "↓", "→", "←", "█", "▚", "☃", /* A - G */
- 0, 0, 0, 0, 0, 0, 0, 0, /* H - O */
- 0, 0, 0, 0, 0, 0, 0, 0, /* P - W */
- 0, 0, 0, 0, 0, 0, 0, " ", /* X - _ */
- "◆", "▒", "␉", "␌", "␍", "␊", "°", "±", /* ` - g */
- "␤", "␋", "┘", "┐", "┌", "└", "┼", "⎺", /* h - o */
- "⎻", "─", "⎼", "⎽", "├", "┤", "┴", "┬", /* p - w */
- "│", "≤", "≥", "π", "≠", "£", "·", /* x - ~ */
- };
-
- /*
- * The table is proudly stolen from rxvt.
- */
- if (term.trantbl[term.charset] == CS_GRAPHIC0 &&
- BETWEEN(u, 0x41, 0x7e) && vt100_0[u - 0x41])
- utf8decode(vt100_0[u - 0x41], &u, UTF_SIZ);
-
- if (term.line[y][x].mode & ATTR_WIDE) {
- if (x+1 < term.col) {
- term.line[y][x+1].u = ' ';
- term.line[y][x+1].mode &= ~ATTR_WDUMMY;
- }
- } else if (term.line[y][x].mode & ATTR_WDUMMY) {
- term.line[y][x-1].u = ' ';
- term.line[y][x-1].mode &= ~ATTR_WIDE;
- }
-
- term.dirty[y] = 1;
- term.line[y][x] = *attr;
- term.line[y][x].u = u;
-}
-
-void
-tclearregion(int x1, int y1, int x2, int y2)
-{
- int x, y, temp;
- Glyph *gp;
-
- if (x1 > x2)
- temp = x1, x1 = x2, x2 = temp;
- if (y1 > y2)
- temp = y1, y1 = y2, y2 = temp;
-
- LIMIT(x1, 0, term.col-1);
- LIMIT(x2, 0, term.col-1);
- LIMIT(y1, 0, term.row-1);
- LIMIT(y2, 0, term.row-1);
-
- for (y = y1; y <= y2; y++) {
- term.dirty[y] = 1;
- for (x = x1; x <= x2; x++) {
- gp = &term.line[y][x];
- if (selected(x, y))
- selclear();
- gp->fg = term.c.attr.fg;
- gp->bg = term.c.attr.bg;
- gp->mode = 0;
- gp->u = ' ';
- }
- }
-}
-
-void
-tdeletechar(int n)
-{
- int dst, src, size;
- Glyph *line;
-
- LIMIT(n, 0, term.col - term.c.x);
-
- dst = term.c.x;
- src = term.c.x + n;
- size = term.col - src;
- line = term.line[term.c.y];
-
- memmove(&line[dst], &line[src], size * sizeof(Glyph));
- tclearregion(term.col-n, term.c.y, term.col-1, term.c.y);
-}
-
-void
-tinsertblank(int n)
-{
- int dst, src, size;
- Glyph *line;
-
- LIMIT(n, 0, term.col - term.c.x);
-
- dst = term.c.x + n;
- src = term.c.x;
- size = term.col - dst;
- line = term.line[term.c.y];
-
- memmove(&line[dst], &line[src], size * sizeof(Glyph));
- tclearregion(src, term.c.y, dst - 1, term.c.y);
-}
-
-void
-tinsertblankline(int n)
-{
- if (BETWEEN(term.c.y, term.top, term.bot))
- tscrolldown(term.c.y, n);
-}
-
-void
-tdeleteline(int n)
-{
- if (BETWEEN(term.c.y, term.top, term.bot))
- tscrollup(term.c.y, n);
-}
-
-int32_t
-tdefcolor(const int *attr, int *npar, int l)
-{
- int32_t idx = -1;
- uint r, g, b;
-
- switch (attr[*npar + 1]) {
- case 2: /* direct color in RGB space */
- if (*npar + 4 >= l) {
- fprintf(stderr,
- "erresc(38): Incorrect number of parameters (%d)\n",
- *npar);
- break;
- }
- r = attr[*npar + 2];
- g = attr[*npar + 3];
- b = attr[*npar + 4];
- *npar += 4;
- if (!BETWEEN(r, 0, 255) || !BETWEEN(g, 0, 255) || !BETWEEN(b, 0, 255))
- fprintf(stderr, "erresc: bad rgb color (%u,%u,%u)\n",
- r, g, b);
- else
- idx = TRUECOLOR(r, g, b);
- break;
- case 5: /* indexed color */
- if (*npar + 2 >= l) {
- fprintf(stderr,
- "erresc(38): Incorrect number of parameters (%d)\n",
- *npar);
- break;
- }
- *npar += 2;
- if (!BETWEEN(attr[*npar], 0, 255))
- fprintf(stderr, "erresc: bad fgcolor %d\n", attr[*npar]);
- else
- idx = attr[*npar];
- break;
- case 0: /* implemented defined (only foreground) */
- case 1: /* transparent */
- case 3: /* direct color in CMY space */
- case 4: /* direct color in CMYK space */
- default:
- fprintf(stderr,
- "erresc(38): gfx attr %d unknown\n", attr[*npar]);
- break;
- }
-
- return idx;
-}
-
-void
-tsetattr(const int *attr, int l)
-{
- int i;
- int32_t idx;
-
- for (i = 0; i < l; i++) {
- switch (attr[i]) {
- case 0:
- term.c.attr.mode &= ~(
- ATTR_BOLD |
- ATTR_FAINT |
- ATTR_ITALIC |
- ATTR_UNDERLINE |
- ATTR_BLINK |
- ATTR_REVERSE |
- ATTR_INVISIBLE |
- ATTR_STRUCK );
- term.c.attr.fg = defaultfg;
- term.c.attr.bg = defaultbg;
- break;
- case 1:
- term.c.attr.mode |= ATTR_BOLD;
- break;
- case 2:
- term.c.attr.mode |= ATTR_FAINT;
- break;
- case 3:
- term.c.attr.mode |= ATTR_ITALIC;
- break;
- case 4:
- term.c.attr.mode |= ATTR_UNDERLINE;
- break;
- case 5: /* slow blink */
- /* FALLTHROUGH */
- case 6: /* rapid blink */
- term.c.attr.mode |= ATTR_BLINK;
- break;
- case 7:
- term.c.attr.mode |= ATTR_REVERSE;
- break;
- case 8:
- term.c.attr.mode |= ATTR_INVISIBLE;
- break;
- case 9:
- term.c.attr.mode |= ATTR_STRUCK;
- break;
- case 22:
- term.c.attr.mode &= ~(ATTR_BOLD | ATTR_FAINT);
- break;
- case 23:
- term.c.attr.mode &= ~ATTR_ITALIC;
- break;
- case 24:
- term.c.attr.mode &= ~ATTR_UNDERLINE;
- break;
- case 25:
- term.c.attr.mode &= ~ATTR_BLINK;
- break;
- case 27:
- term.c.attr.mode &= ~ATTR_REVERSE;
- break;
- case 28:
- term.c.attr.mode &= ~ATTR_INVISIBLE;
- break;
- case 29:
- term.c.attr.mode &= ~ATTR_STRUCK;
- break;
- case 38:
- if ((idx = tdefcolor(attr, &i, l)) >= 0)
- term.c.attr.fg = idx;
- break;
- case 39:
- term.c.attr.fg = defaultfg;
- break;
- case 48:
- if ((idx = tdefcolor(attr, &i, l)) >= 0)
- term.c.attr.bg = idx;
- break;
- case 49:
- term.c.attr.bg = defaultbg;
- break;
- default:
- if (BETWEEN(attr[i], 30, 37)) {
- term.c.attr.fg = attr[i] - 30;
- } else if (BETWEEN(attr[i], 40, 47)) {
- term.c.attr.bg = attr[i] - 40;
- } else if (BETWEEN(attr[i], 90, 97)) {
- term.c.attr.fg = attr[i] - 90 + 8;
- } else if (BETWEEN(attr[i], 100, 107)) {
- term.c.attr.bg = attr[i] - 100 + 8;
- } else {
- fprintf(stderr,
- "erresc(default): gfx attr %d unknown\n",
- attr[i]);
- csidump();
- }
- break;
- }
- }
-}
-
-void
-tsetscroll(int t, int b)
-{
- int temp;
-
- LIMIT(t, 0, term.row-1);
- LIMIT(b, 0, term.row-1);
- if (t > b) {
- temp = t;
- t = b;
- b = temp;
- }
- term.top = t;
- term.bot = b;
-}
-
-void
-tsetmode(int priv, int set, const int *args, int narg)
-{
- int alt; const int *lim;
-
- for (lim = args + narg; args < lim; ++args) {
- if (priv) {
- switch (*args) {
- case 1: /* DECCKM -- Cursor key */
- xsetmode(set, MODE_APPCURSOR);
- break;
- case 5: /* DECSCNM -- Reverse video */
- xsetmode(set, MODE_REVERSE);
- break;
- case 6: /* DECOM -- Origin */
- MODBIT(term.c.state, set, CURSOR_ORIGIN);
- tmoveato(0, 0);
- break;
- case 7: /* DECAWM -- Auto wrap */
- MODBIT(term.mode, set, MODE_WRAP);
- break;
- case 0: /* Error (IGNORED) */
- case 2: /* DECANM -- ANSI/VT52 (IGNORED) */
- case 3: /* DECCOLM -- Column (IGNORED) */
- case 4: /* DECSCLM -- Scroll (IGNORED) */
- case 8: /* DECARM -- Auto repeat (IGNORED) */
- case 18: /* DECPFF -- Printer feed (IGNORED) */
- case 19: /* DECPEX -- Printer extent (IGNORED) */
- case 42: /* DECNRCM -- National characters (IGNORED) */
- case 12: /* att610 -- Start blinking cursor (IGNORED) */
- break;
- case 25: /* DECTCEM -- Text Cursor Enable Mode */
- xsetmode(!set, MODE_HIDE);
- break;
- case 9: /* X10 mouse compatibility mode */
- xsetpointermotion(0);
- xsetmode(0, MODE_MOUSE);
- xsetmode(set, MODE_MOUSEX10);
- break;
- case 1000: /* 1000: report button press */
- xsetpointermotion(0);
- xsetmode(0, MODE_MOUSE);
- xsetmode(set, MODE_MOUSEBTN);
- break;
- case 1002: /* 1002: report motion on button press */
- xsetpointermotion(0);
- xsetmode(0, MODE_MOUSE);
- xsetmode(set, MODE_MOUSEMOTION);
- break;
- case 1003: /* 1003: enable all mouse motions */
- xsetpointermotion(set);
- xsetmode(0, MODE_MOUSE);
- xsetmode(set, MODE_MOUSEMANY);
- break;
- case 1004: /* 1004: send focus events to tty */
- xsetmode(set, MODE_FOCUS);
- break;
- case 1006: /* 1006: extended reporting mode */
- xsetmode(set, MODE_MOUSESGR);
- break;
- case 1034:
- xsetmode(set, MODE_8BIT);
- break;
- case 1049: /* swap screen & set/restore cursor as xterm */
- if (!allowaltscreen)
- break;
- tcursor((set) ? CURSOR_SAVE : CURSOR_LOAD);
- /* FALLTHROUGH */
- case 47: /* swap screen */
- case 1047:
- if (!allowaltscreen)
- break;
- alt = IS_SET(MODE_ALTSCREEN);
- if (alt) {
- tclearregion(0, 0, term.col-1,
- term.row-1);
- }
- if (set ^ alt) /* set is always 1 or 0 */
- tswapscreen();
- if (*args != 1049)
- break;
- /* FALLTHROUGH */
- case 1048:
- tcursor((set) ? CURSOR_SAVE : CURSOR_LOAD);
- break;
- case 2004: /* 2004: bracketed paste mode */
- xsetmode(set, MODE_BRCKTPASTE);
- break;
- /* Not implemented mouse modes. See comments there. */
- case 1001: /* mouse highlight mode; can hang the
- terminal by design when implemented. */
- case 1005: /* UTF-8 mouse mode; will confuse
- applications not supporting UTF-8
- and luit. */
- case 1015: /* urxvt mangled mouse mode; incompatible
- and can be mistaken for other control
- codes. */
- break;
- default:
- fprintf(stderr,
- "erresc: unknown private set/reset mode %d\n",
- *args);
- break;
- }
- } else {
- switch (*args) {
- case 0: /* Error (IGNORED) */
- break;
- case 2:
- xsetmode(set, MODE_KBDLOCK);
- break;
- case 4: /* IRM -- Insertion-replacement */
- MODBIT(term.mode, set, MODE_INSERT);
- break;
- case 12: /* SRM -- Send/Receive */
- MODBIT(term.mode, !set, MODE_ECHO);
- break;
- case 20: /* LNM -- Linefeed/new line */
- MODBIT(term.mode, set, MODE_CRLF);
- break;
- default:
- fprintf(stderr,
- "erresc: unknown set/reset mode %d\n",
- *args);
- break;
- }
- }
- }
-}
-
-void
-csihandle(void)
-{
- char buf[40];
- int len;
-
- switch (csiescseq.mode[0]) {
- default:
- unknown:
- fprintf(stderr, "erresc: unknown csi ");
- csidump();
- /* die(""); */
- break;
- case '@': /* ICH -- Insert <n> blank char */
- DEFAULT(csiescseq.arg[0], 1);
- tinsertblank(csiescseq.arg[0]);
- break;
- case 'A': /* CUU -- Cursor <n> Up */
- DEFAULT(csiescseq.arg[0], 1);
- tmoveto(term.c.x, term.c.y-csiescseq.arg[0]);
- break;
- case 'B': /* CUD -- Cursor <n> Down */
- case 'e': /* VPR --Cursor <n> Down */
- DEFAULT(csiescseq.arg[0], 1);
- tmoveto(term.c.x, term.c.y+csiescseq.arg[0]);
- break;
- case 'i': /* MC -- Media Copy */
- switch (csiescseq.arg[0]) {
- case 0:
- tdump();
- break;
- case 1:
- tdumpline(term.c.y);
- break;
- case 2:
- tdumpsel();
- break;
- case 4:
- term.mode &= ~MODE_PRINT;
- break;
- case 5:
- term.mode |= MODE_PRINT;
- break;
- }
- break;
- case 'c': /* DA -- Device Attributes */
- if (csiescseq.arg[0] == 0)
- ttywrite(vtiden, strlen(vtiden), 0);
- break;
- case 'b': /* REP -- if last char is printable print it <n> more times */
- DEFAULT(csiescseq.arg[0], 1);
- if (term.lastc)
- while (csiescseq.arg[0]-- > 0)
- tputc(term.lastc);
- break;
- case 'C': /* CUF -- Cursor <n> Forward */
- case 'a': /* HPR -- Cursor <n> Forward */
- DEFAULT(csiescseq.arg[0], 1);
- tmoveto(term.c.x+csiescseq.arg[0], term.c.y);
- break;
- case 'D': /* CUB -- Cursor <n> Backward */
- DEFAULT(csiescseq.arg[0], 1);
- tmoveto(term.c.x-csiescseq.arg[0], term.c.y);
- break;
- case 'E': /* CNL -- Cursor <n> Down and first col */
- DEFAULT(csiescseq.arg[0], 1);
- tmoveto(0, term.c.y+csiescseq.arg[0]);
- break;
- case 'F': /* CPL -- Cursor <n> Up and first col */
- DEFAULT(csiescseq.arg[0], 1);
- tmoveto(0, term.c.y-csiescseq.arg[0]);
- break;
- case 'g': /* TBC -- Tabulation clear */
- switch (csiescseq.arg[0]) {
- case 0: /* clear current tab stop */
- term.tabs[term.c.x] = 0;
- break;
- case 3: /* clear all the tabs */
- memset(term.tabs, 0, term.col * sizeof(*term.tabs));
- break;
- default:
- goto unknown;
- }
- break;
- case 'G': /* CHA -- Move to <col> */
- case '`': /* HPA */
- DEFAULT(csiescseq.arg[0], 1);
- tmoveto(csiescseq.arg[0]-1, term.c.y);
- break;
- case 'H': /* CUP -- Move to <row> <col> */
- case 'f': /* HVP */
- DEFAULT(csiescseq.arg[0], 1);
- DEFAULT(csiescseq.arg[1], 1);
- tmoveato(csiescseq.arg[1]-1, csiescseq.arg[0]-1);
- break;
- case 'I': /* CHT -- Cursor Forward Tabulation <n> tab stops */
- DEFAULT(csiescseq.arg[0], 1);
- tputtab(csiescseq.arg[0]);
- break;
- case 'J': /* ED -- Clear screen */
- switch (csiescseq.arg[0]) {
- case 0: /* below */
- tclearregion(term.c.x, term.c.y, term.col-1, term.c.y);
- if (term.c.y < term.row-1) {
- tclearregion(0, term.c.y+1, term.col-1,
- term.row-1);
- }
- break;
- case 1: /* above */
- if (term.c.y > 1)
- tclearregion(0, 0, term.col-1, term.c.y-1);
- tclearregion(0, term.c.y, term.c.x, term.c.y);
- break;
- case 2: /* all */
- tclearregion(0, 0, term.col-1, term.row-1);
- break;
- default:
- goto unknown;
- }
- break;
- case 'K': /* EL -- Clear line */
- switch (csiescseq.arg[0]) {
- case 0: /* right */
- tclearregion(term.c.x, term.c.y, term.col-1,
- term.c.y);
- break;
- case 1: /* left */
- tclearregion(0, term.c.y, term.c.x, term.c.y);
- break;
- case 2: /* all */
- tclearregion(0, term.c.y, term.col-1, term.c.y);
- break;
- }
- break;
- case 'S': /* SU -- Scroll <n> line up */
- DEFAULT(csiescseq.arg[0], 1);
- tscrollup(term.top, csiescseq.arg[0]);
- break;
- case 'T': /* SD -- Scroll <n> line down */
- DEFAULT(csiescseq.arg[0], 1);
- tscrolldown(term.top, csiescseq.arg[0]);
- break;
- case 'L': /* IL -- Insert <n> blank lines */
- DEFAULT(csiescseq.arg[0], 1);
- tinsertblankline(csiescseq.arg[0]);
- break;
- case 'l': /* RM -- Reset Mode */
- tsetmode(csiescseq.priv, 0, csiescseq.arg, csiescseq.narg);
- break;
- case 'M': /* DL -- Delete <n> lines */
- DEFAULT(csiescseq.arg[0], 1);
- tdeleteline(csiescseq.arg[0]);
- break;
- case 'X': /* ECH -- Erase <n> char */
- DEFAULT(csiescseq.arg[0], 1);
- tclearregion(term.c.x, term.c.y,
- term.c.x + csiescseq.arg[0] - 1, term.c.y);
- break;
- case 'P': /* DCH -- Delete <n> char */
- DEFAULT(csiescseq.arg[0], 1);
- tdeletechar(csiescseq.arg[0]);
- break;
- case 'Z': /* CBT -- Cursor Backward Tabulation <n> tab stops */
- DEFAULT(csiescseq.arg[0], 1);
- tputtab(-csiescseq.arg[0]);
- break;
- case 'd': /* VPA -- Move to <row> */
- DEFAULT(csiescseq.arg[0], 1);
- tmoveato(term.c.x, csiescseq.arg[0]-1);
- break;
- case 'h': /* SM -- Set terminal mode */
- tsetmode(csiescseq.priv, 1, csiescseq.arg, csiescseq.narg);
- break;
- case 'm': /* SGR -- Terminal attribute (color) */
- tsetattr(csiescseq.arg, csiescseq.narg);
- break;
- case 'n': /* DSR – Device Status Report (cursor position) */
- if (csiescseq.arg[0] == 6) {
- len = snprintf(buf, sizeof(buf), "\033[%i;%iR",
- term.c.y+1, term.c.x+1);
- ttywrite(buf, len, 0);
- }
- break;
- case 'r': /* DECSTBM -- Set Scrolling Region */
- if (csiescseq.priv) {
- goto unknown;
- } else {
- DEFAULT(csiescseq.arg[0], 1);
- DEFAULT(csiescseq.arg[1], term.row);
- tsetscroll(csiescseq.arg[0]-1, csiescseq.arg[1]-1);
- tmoveato(0, 0);
- }
- break;
- case 's': /* DECSC -- Save cursor position (ANSI.SYS) */
- tcursor(CURSOR_SAVE);
- break;
- case 'u': /* DECRC -- Restore cursor position (ANSI.SYS) */
- tcursor(CURSOR_LOAD);
- break;
- case ' ':
- switch (csiescseq.mode[1]) {
- case 'q': /* DECSCUSR -- Set Cursor Style */
- if (xsetcursor(csiescseq.arg[0]))
- goto unknown;
- break;
- default:
- goto unknown;
- }
- break;
- }
-}
-
-void
-csidump(void)
-{
- size_t i;
- uint c;
-
- fprintf(stderr, "ESC[");
- for (i = 0; i < csiescseq.len; i++) {
- c = csiescseq.buf[i] & 0xff;
- if (isprint(c)) {
- putc(c, stderr);
- } else if (c == '\n') {
- fprintf(stderr, "(\\n)");
- } else if (c == '\r') {
- fprintf(stderr, "(\\r)");
- } else if (c == 0x1b) {
- fprintf(stderr, "(\\e)");
- } else {
- fprintf(stderr, "(%02x)", c);
- }
- }
- putc('\n', stderr);
-}
-
-void
-csireset(void)
-{
- memset(&csiescseq, 0, sizeof(csiescseq));
-}
-
-void
-strhandle(void)
-{
- char *p = NULL, *dec;
- int j, narg, par;
-
- term.esc &= ~(ESC_STR_END|ESC_STR);
- strparse();
- par = (narg = strescseq.narg) ? atoi(strescseq.args[0]) : 0;
-
- switch (strescseq.type) {
- case ']': /* OSC -- Operating System Command */
- switch (par) {
- case 0:
- if (narg > 1) {
- xsettitle(strescseq.args[1]);
- xseticontitle(strescseq.args[1]);
- }
- return;
- case 1:
- if (narg > 1)
- xseticontitle(strescseq.args[1]);
- return;
- case 2:
- if (narg > 1)
- xsettitle(strescseq.args[1]);
- return;
- case 52:
- if (narg > 2 && allowwindowops) {
- dec = base64dec(strescseq.args[2]);
- if (dec) {
- xsetsel(dec);
- xclipcopy();
- } else {
- fprintf(stderr, "erresc: invalid base64\n");
- }
- }
- return;
- case 4: /* color set */
- if (narg < 3)
- break;
- p = strescseq.args[2];
- /* FALLTHROUGH */
- case 104: /* color reset, here p = NULL */
- j = (narg > 1) ? atoi(strescseq.args[1]) : -1;
- if (xsetcolorname(j, p)) {
- if (par == 104 && narg <= 1)
- return; /* color reset without parameter */
- fprintf(stderr, "erresc: invalid color j=%d, p=%s\n",
- j, p ? p : "(null)");
- } else {
- /*
- * TODO if defaultbg color is changed, borders
- * are dirty
- */
- redraw();
- }
- return;
- }
- break;
- case 'k': /* old title set compatibility */
- xsettitle(strescseq.args[0]);
- return;
- case 'P': /* DCS -- Device Control String */
- case '_': /* APC -- Application Program Command */
- case '^': /* PM -- Privacy Message */
- return;
- }
-
- fprintf(stderr, "erresc: unknown str ");
- strdump();
-}
-
-void
-strparse(void)
-{
- int c;
- char *p = strescseq.buf;
-
- strescseq.narg = 0;
- strescseq.buf[strescseq.len] = '\0';
-
- if (*p == '\0')
- return;
-
- while (strescseq.narg < STR_ARG_SIZ) {
- strescseq.args[strescseq.narg++] = p;
- while ((c = *p) != ';' && c != '\0')
- ++p;
- if (c == '\0')
- return;
- *p++ = '\0';
- }
-}
-
-void
-strdump(void)
-{
- size_t i;
- uint c;
-
- fprintf(stderr, "ESC%c", strescseq.type);
- for (i = 0; i < strescseq.len; i++) {
- c = strescseq.buf[i] & 0xff;
- if (c == '\0') {
- putc('\n', stderr);
- return;
- } else if (isprint(c)) {
- putc(c, stderr);
- } else if (c == '\n') {
- fprintf(stderr, "(\\n)");
- } else if (c == '\r') {
- fprintf(stderr, "(\\r)");
- } else if (c == 0x1b) {
- fprintf(stderr, "(\\e)");
- } else {
- fprintf(stderr, "(%02x)", c);
- }
- }
- fprintf(stderr, "ESC\\\n");
-}
-
-void
-strreset(void)
-{
- strescseq = (STREscape){
- .buf = xrealloc(strescseq.buf, STR_BUF_SIZ),
- .siz = STR_BUF_SIZ,
- };
-}
-
-void
-sendbreak(const Arg *arg)
-{
- if (tcsendbreak(cmdfd, 0))
- perror("Error sending break");
-}
-
-void
-tprinter(char *s, size_t len)
-{
- if (iofd != -1 && xwrite(iofd, s, len) < 0) {
- perror("Error writing to output file");
- close(iofd);
- iofd = -1;
- }
-}
-
-void
-toggleprinter(const Arg *arg)
-{
- term.mode ^= MODE_PRINT;
-}
-
-void
-printscreen(const Arg *arg)
-{
- tdump();
-}
-
-void
-printsel(const Arg *arg)
-{
- tdumpsel();
-}
-
-void
-tdumpsel(void)
-{
- char *ptr;
-
- if ((ptr = getsel())) {
- tprinter(ptr, strlen(ptr));
- free(ptr);
- }
-}
-
-void
-tdumpline(int n)
-{
- char buf[UTF_SIZ];
- const Glyph *bp, *end;
-
- bp = &term.line[n][0];
- end = &bp[MIN(tlinelen(n), term.col) - 1];
- if (bp != end || bp->u != ' ') {
- for ( ; bp <= end; ++bp)
- tprinter(buf, utf8encode(bp->u, buf));
- }
- tprinter("\n", 1);
-}
-
-void
-tdump(void)
-{
- int i;
-
- for (i = 0; i < term.row; ++i)
- tdumpline(i);
-}
-
-void
-tputtab(int n)
-{
- uint x = term.c.x;
-
- if (n > 0) {
- while (x < term.col && n--)
- for (++x; x < term.col && !term.tabs[x]; ++x)
- /* nothing */ ;
- } else if (n < 0) {
- while (x > 0 && n++)
- for (--x; x > 0 && !term.tabs[x]; --x)
- /* nothing */ ;
- }
- term.c.x = LIMIT(x, 0, term.col-1);
-}
-
-void
-tdefutf8(char ascii)
-{
- if (ascii == 'G')
- term.mode |= MODE_UTF8;
- else if (ascii == '@')
- term.mode &= ~MODE_UTF8;
-}
-
-void
-tdeftran(char ascii)
-{
- static char cs[] = "0B";
- static int vcs[] = {CS_GRAPHIC0, CS_USA};
- char *p;
-
- if ((p = strchr(cs, ascii)) == NULL) {
- fprintf(stderr, "esc unhandled charset: ESC ( %c\n", ascii);
- } else {
- term.trantbl[term.icharset] = vcs[p - cs];
- }
-}
-
-void
-tdectest(char c)
-{
- int x, y;
-
- if (c == '8') { /* DEC screen alignment test. */
- for (x = 0; x < term.col; ++x) {
- for (y = 0; y < term.row; ++y)
- tsetchar('E', &term.c.attr, x, y);
- }
- }
-}
-
-void
-tstrsequence(uchar c)
-{
- switch (c) {
- case 0x90: /* DCS -- Device Control String */
- c = 'P';
- break;
- case 0x9f: /* APC -- Application Program Command */
- c = '_';
- break;
- case 0x9e: /* PM -- Privacy Message */
- c = '^';
- break;
- case 0x9d: /* OSC -- Operating System Command */
- c = ']';
- break;
- }
- strreset();
- strescseq.type = c;
- term.esc |= ESC_STR;
-}
-
-void
-tcontrolcode(uchar ascii)
-{
- switch (ascii) {
- case '\t': /* HT */
- tputtab(1);
- return;
- case '\b': /* BS */
- tmoveto(term.c.x-1, term.c.y);
- return;
- case '\r': /* CR */
- tmoveto(0, term.c.y);
- return;
- case '\f': /* LF */
- case '\v': /* VT */
- case '\n': /* LF */
- /* go to first col if the mode is set */
- tnewline(IS_SET(MODE_CRLF));
- return;
- case '\a': /* BEL */
- if (term.esc & ESC_STR_END) {
- /* backwards compatibility to xterm */
- strhandle();
- } else {
- xbell();
- }
- break;
- case '\033': /* ESC */
- csireset();
- term.esc &= ~(ESC_CSI|ESC_ALTCHARSET|ESC_TEST);
- term.esc |= ESC_START;
- return;
- case '\016': /* SO (LS1 -- Locking shift 1) */
- case '\017': /* SI (LS0 -- Locking shift 0) */
- term.charset = 1 - (ascii - '\016');
- return;
- case '\032': /* SUB */
- tsetchar('?', &term.c.attr, term.c.x, term.c.y);
- /* FALLTHROUGH */
- case '\030': /* CAN */
- csireset();
- break;
- case '\005': /* ENQ (IGNORED) */
- case '\000': /* NUL (IGNORED) */
- case '\021': /* XON (IGNORED) */
- case '\023': /* XOFF (IGNORED) */
- case 0177: /* DEL (IGNORED) */
- return;
- case 0x80: /* TODO: PAD */
- case 0x81: /* TODO: HOP */
- case 0x82: /* TODO: BPH */
- case 0x83: /* TODO: NBH */
- case 0x84: /* TODO: IND */
- break;
- case 0x85: /* NEL -- Next line */
- tnewline(1); /* always go to first col */
- break;
- case 0x86: /* TODO: SSA */
- case 0x87: /* TODO: ESA */
- break;
- case 0x88: /* HTS -- Horizontal tab stop */
- term.tabs[term.c.x] = 1;
- break;
- case 0x89: /* TODO: HTJ */
- case 0x8a: /* TODO: VTS */
- case 0x8b: /* TODO: PLD */
- case 0x8c: /* TODO: PLU */
- case 0x8d: /* TODO: RI */
- case 0x8e: /* TODO: SS2 */
- case 0x8f: /* TODO: SS3 */
- case 0x91: /* TODO: PU1 */
- case 0x92: /* TODO: PU2 */
- case 0x93: /* TODO: STS */
- case 0x94: /* TODO: CCH */
- case 0x95: /* TODO: MW */
- case 0x96: /* TODO: SPA */
- case 0x97: /* TODO: EPA */
- case 0x98: /* TODO: SOS */
- case 0x99: /* TODO: SGCI */
- break;
- case 0x9a: /* DECID -- Identify Terminal */
- ttywrite(vtiden, strlen(vtiden), 0);
- break;
- case 0x9b: /* TODO: CSI */
- case 0x9c: /* TODO: ST */
- break;
- case 0x90: /* DCS -- Device Control String */
- case 0x9d: /* OSC -- Operating System Command */
- case 0x9e: /* PM -- Privacy Message */
- case 0x9f: /* APC -- Application Program Command */
- tstrsequence(ascii);
- return;
- }
- /* only CAN, SUB, \a and C1 chars interrupt a sequence */
- term.esc &= ~(ESC_STR_END|ESC_STR);
-}
-
-/*
- * returns 1 when the sequence is finished and it hasn't to read
- * more characters for this sequence, otherwise 0
- */
-int
-eschandle(uchar ascii)
-{
- switch (ascii) {
- case '[':
- term.esc |= ESC_CSI;
- return 0;
- case '#':
- term.esc |= ESC_TEST;
- return 0;
- case '%':
- term.esc |= ESC_UTF8;
- return 0;
- case 'P': /* DCS -- Device Control String */
- case '_': /* APC -- Application Program Command */
- case '^': /* PM -- Privacy Message */
- case ']': /* OSC -- Operating System Command */
- case 'k': /* old title set compatibility */
- tstrsequence(ascii);
- return 0;
- case 'n': /* LS2 -- Locking shift 2 */
- case 'o': /* LS3 -- Locking shift 3 */
- term.charset = 2 + (ascii - 'n');
- break;
- case '(': /* GZD4 -- set primary charset G0 */
- case ')': /* G1D4 -- set secondary charset G1 */
- case '*': /* G2D4 -- set tertiary charset G2 */
- case '+': /* G3D4 -- set quaternary charset G3 */
- term.icharset = ascii - '(';
- term.esc |= ESC_ALTCHARSET;
- return 0;
- case 'D': /* IND -- Linefeed */
- if (term.c.y == term.bot) {
- tscrollup(term.top, 1);
- } else {
- tmoveto(term.c.x, term.c.y+1);
- }
- break;
- case 'E': /* NEL -- Next line */
- tnewline(1); /* always go to first col */
- break;
- case 'H': /* HTS -- Horizontal tab stop */
- term.tabs[term.c.x] = 1;
- break;
- case 'M': /* RI -- Reverse index */
- if (term.c.y == term.top) {
- tscrolldown(term.top, 1);
- } else {
- tmoveto(term.c.x, term.c.y-1);
- }
- break;
- case 'Z': /* DECID -- Identify Terminal */
- ttywrite(vtiden, strlen(vtiden), 0);
- break;
- case 'c': /* RIS -- Reset to initial state */
- treset();
- resettitle();
- xloadcols();
- break;
- case '=': /* DECPAM -- Application keypad */
- xsetmode(1, MODE_APPKEYPAD);
- break;
- case '>': /* DECPNM -- Normal keypad */
- xsetmode(0, MODE_APPKEYPAD);
- break;
- case '7': /* DECSC -- Save Cursor */
- tcursor(CURSOR_SAVE);
- break;
- case '8': /* DECRC -- Restore Cursor */
- tcursor(CURSOR_LOAD);
- break;
- case '\\': /* ST -- String Terminator */
- if (term.esc & ESC_STR_END)
- strhandle();
- break;
- default:
- fprintf(stderr, "erresc: unknown sequence ESC 0x%02X '%c'\n",
- (uchar) ascii, isprint(ascii)? ascii:'.');
- break;
- }
- return 1;
-}
-
-void
-tputc(Rune u)
-{
- char c[UTF_SIZ];
- int control;
- int width, len;
- Glyph *gp;
-
- control = ISCONTROL(u);
- if (u < 127 || !IS_SET(MODE_UTF8)) {
- c[0] = u;
- width = len = 1;
- } else {
- len = utf8encode(u, c);
- if (!control && (width = wcwidth(u)) == -1)
- width = 1;
- }
-
- if (IS_SET(MODE_PRINT))
- tprinter(c, len);
-
- /*
- * STR sequence must be checked before anything else
- * because it uses all following characters until it
- * receives a ESC, a SUB, a ST or any other C1 control
- * character.
- */
- if (term.esc & ESC_STR) {
- if (u == '\a' || u == 030 || u == 032 || u == 033 ||
- ISCONTROLC1(u)) {
- term.esc &= ~(ESC_START|ESC_STR);
- term.esc |= ESC_STR_END;
- goto check_control_code;
- }
-
- if (strescseq.len+len >= strescseq.siz) {
- /*
- * Here is a bug in terminals. If the user never sends
- * some code to stop the str or esc command, then st
- * will stop responding. But this is better than
- * silently failing with unknown characters. At least
- * then users will report back.
- *
- * In the case users ever get fixed, here is the code:
- */
- /*
- * term.esc = 0;
- * strhandle();
- */
- if (strescseq.siz > (SIZE_MAX - UTF_SIZ) / 2)
- return;
- strescseq.siz *= 2;
- strescseq.buf = xrealloc(strescseq.buf, strescseq.siz);
- }
-
- memmove(&strescseq.buf[strescseq.len], c, len);
- strescseq.len += len;
- return;
- }
-
-check_control_code:
- /*
- * Actions of control codes must be performed as soon they arrive
- * because they can be embedded inside a control sequence, and
- * they must not cause conflicts with sequences.
- */
- if (control) {
- tcontrolcode(u);
- /*
- * control codes are not shown ever
- */
- if (!term.esc)
- term.lastc = 0;
- return;
- } else if (term.esc & ESC_START) {
- if (term.esc & ESC_CSI) {
- csiescseq.buf[csiescseq.len++] = u;
- if (BETWEEN(u, 0x40, 0x7E)
- || csiescseq.len >= \
- sizeof(csiescseq.buf)-1) {
- term.esc = 0;
- csiparse();
- csihandle();
- }
- return;
- } else if (term.esc & ESC_UTF8) {
- tdefutf8(u);
- } else if (term.esc & ESC_ALTCHARSET) {
- tdeftran(u);
- } else if (term.esc & ESC_TEST) {
- tdectest(u);
- } else {
- if (!eschandle(u))
- return;
- /* sequence already finished */
- }
- term.esc = 0;
- /*
- * All characters which form part of a sequence are not
- * printed
- */
- return;
- }
- if (selected(term.c.x, term.c.y))
- selclear();
-
- gp = &term.line[term.c.y][term.c.x];
- if (IS_SET(MODE_WRAP) && (term.c.state & CURSOR_WRAPNEXT)) {
- gp->mode |= ATTR_WRAP;
- tnewline(1);
- gp = &term.line[term.c.y][term.c.x];
- }
-
- if (IS_SET(MODE_INSERT) && term.c.x+width < term.col)
- memmove(gp+width, gp, (term.col - term.c.x - width) * sizeof(Glyph));
-
- if (term.c.x+width > term.col) {
- tnewline(1);
- gp = &term.line[term.c.y][term.c.x];
- }
-
- tsetchar(u, &term.c.attr, term.c.x, term.c.y);
- term.lastc = u;
-
- if (width == 2) {
- gp->mode |= ATTR_WIDE;
- if (term.c.x+1 < term.col) {
- gp[1].u = '\0';
- gp[1].mode = ATTR_WDUMMY;
- }
- }
- if (term.c.x+width < term.col) {
- tmoveto(term.c.x+width, term.c.y);
- } else {
- term.c.state |= CURSOR_WRAPNEXT;
- }
-}
-
-int
-twrite(const char *buf, int buflen, int show_ctrl)
-{
- int charsize;
- Rune u;
- int n;
-
- for (n = 0; n < buflen; n += charsize) {
- if (IS_SET(MODE_UTF8)) {
- /* process a complete utf8 char */
- charsize = utf8decode(buf + n, &u, buflen - n);
- if (charsize == 0)
- break;
- } else {
- u = buf[n] & 0xFF;
- charsize = 1;
- }
- if (show_ctrl && ISCONTROL(u)) {
- if (u & 0x80) {
- u &= 0x7f;
- tputc('^');
- tputc('[');
- } else if (u != '\n' && u != '\r' && u != '\t') {
- u ^= 0x40;
- tputc('^');
- }
- }
- tputc(u);
- }
- return n;
-}
-
-void
-tresize(int col, int row)
-{
- int i;
- int minrow = MIN(row, term.row);
- int mincol = MIN(col, term.col);
- int *bp;
- TCursor c;
-
- if (col < 1 || row < 1) {
- fprintf(stderr,
- "tresize: error resizing to %dx%d\n", col, row);
- return;
- }
-
- /*
- * slide screen to keep cursor where we expect it -
- * tscrollup would work here, but we can optimize to
- * memmove because we're freeing the earlier lines
- */
- for (i = 0; i <= term.c.y - row; i++) {
- free(term.line[i]);
- free(term.alt[i]);
- }
- /* ensure that both src and dst are not NULL */
- if (i > 0) {
- memmove(term.line, term.line + i, row * sizeof(Line));
- memmove(term.alt, term.alt + i, row * sizeof(Line));
- }
- for (i += row; i < term.row; i++) {
- free(term.line[i]);
- free(term.alt[i]);
- }
-
- /* resize to new height */
- term.line = xrealloc(term.line, row * sizeof(Line));
- term.alt = xrealloc(term.alt, row * sizeof(Line));
- term.dirty = xrealloc(term.dirty, row * sizeof(*term.dirty));
- term.tabs = xrealloc(term.tabs, col * sizeof(*term.tabs));
-
- /* resize each row to new width, zero-pad if needed */
- for (i = 0; i < minrow; i++) {
- term.line[i] = xrealloc(term.line[i], col * sizeof(Glyph));
- term.alt[i] = xrealloc(term.alt[i], col * sizeof(Glyph));
- }
-
- /* allocate any new rows */
- for (/* i = minrow */; i < row; i++) {
- term.line[i] = xmalloc(col * sizeof(Glyph));
- term.alt[i] = xmalloc(col * sizeof(Glyph));
- }
- if (col > term.col) {
- bp = term.tabs + term.col;
-
- memset(bp, 0, sizeof(*term.tabs) * (col - term.col));
- while (--bp > term.tabs && !*bp)
- /* nothing */ ;
- for (bp += tabspaces; bp < term.tabs + col; bp += tabspaces)
- *bp = 1;
- }
- /* update terminal size */
- term.col = col;
- term.row = row;
- /* reset scrolling region */
- tsetscroll(0, row-1);
- /* make use of the LIMIT in tmoveto */
- tmoveto(term.c.x, term.c.y);
- /* Clearing both screens (it makes dirty all lines) */
- c = term.c;
- for (i = 0; i < 2; i++) {
- if (mincol < col && 0 < minrow) {
- tclearregion(mincol, 0, col - 1, minrow - 1);
- }
- if (0 < col && minrow < row) {
- tclearregion(0, minrow, col - 1, row - 1);
- }
- tswapscreen();
- tcursor(CURSOR_LOAD);
- }
- term.c = c;
-}
-
-void
-resettitle(void)
-{
- xsettitle(NULL);
-}
-
-void
-drawregion(int x1, int y1, int x2, int y2)
-{
- int y;
-
- for (y = y1; y < y2; y++) {
- if (!term.dirty[y])
- continue;
-
- term.dirty[y] = 0;
- xdrawline(term.line[y], x1, y, x2);
- }
-}
-
-void
-draw(void)
-{
- int cx = term.c.x, ocx = term.ocx, ocy = term.ocy;
-
- if (!xstartdraw())
- return;
-
- /* adjust cursor position */
- LIMIT(term.ocx, 0, term.col-1);
- LIMIT(term.ocy, 0, term.row-1);
- if (term.line[term.ocy][term.ocx].mode & ATTR_WDUMMY)
- term.ocx--;
- if (term.line[term.c.y][cx].mode & ATTR_WDUMMY)
- cx--;
-
- drawregion(0, 0, term.col, term.row);
- xdrawcursor(cx, term.c.y, term.line[term.c.y][cx],
- term.ocx, term.ocy, term.line[term.ocy][term.ocx]);
- term.ocx = cx;
- term.ocy = term.c.y;
- xfinishdraw();
- if (ocx != term.ocx || ocy != term.ocy)
- xximspot(term.ocx, term.ocy);
-}
-
-void
-redraw(void)
-{
- tfulldirt();
- draw();
-}
diff --git a/.repos/st/st.h b/.repos/st/st.h
deleted file mode 100644
index adda2db..0000000
--- a/.repos/st/st.h
+++ /dev/null
@@ -1,127 +0,0 @@
-/* See LICENSE for license details. */
-
-#include <stdint.h>
-#include <sys/types.h>
-
-/* macros */
-#define MIN(a, b) ((a) < (b) ? (a) : (b))
-#define MAX(a, b) ((a) < (b) ? (b) : (a))
-#define LEN(a) (sizeof(a) / sizeof(a)[0])
-#define BETWEEN(x, a, b) ((a) <= (x) && (x) <= (b))
-#define DIVCEIL(n, d) (((n) + ((d) - 1)) / (d))
-#define DEFAULT(a, b) (a) = (a) ? (a) : (b)
-#define LIMIT(x, a, b) (x) = (x) < (a) ? (a) : (x) > (b) ? (b) : (x)
-#define ATTRCMP(a, b) ((a).mode != (b).mode || (a).fg != (b).fg || \
- (a).bg != (b).bg)
-#define TIMEDIFF(t1, t2) ((t1.tv_sec-t2.tv_sec)*1000 + \
- (t1.tv_nsec-t2.tv_nsec)/1E6)
-#define MODBIT(x, set, bit) ((set) ? ((x) |= (bit)) : ((x) &= ~(bit)))
-
-#define TRUECOLOR(r,g,b) (1 << 24 | (r) << 16 | (g) << 8 | (b))
-#define IS_TRUECOL(x) (1 << 24 & (x))
-
-enum glyph_attribute {
- ATTR_NULL = 0,
- ATTR_BOLD = 1 << 0,
- ATTR_FAINT = 1 << 1,
- ATTR_ITALIC = 1 << 2,
- ATTR_UNDERLINE = 1 << 3,
- ATTR_BLINK = 1 << 4,
- ATTR_REVERSE = 1 << 5,
- ATTR_INVISIBLE = 1 << 6,
- ATTR_STRUCK = 1 << 7,
- ATTR_WRAP = 1 << 8,
- ATTR_WIDE = 1 << 9,
- ATTR_WDUMMY = 1 << 10,
- ATTR_BOLD_FAINT = ATTR_BOLD | ATTR_FAINT,
-};
-
-enum selection_mode {
- SEL_IDLE = 0,
- SEL_EMPTY = 1,
- SEL_READY = 2
-};
-
-enum selection_type {
- SEL_REGULAR = 1,
- SEL_RECTANGULAR = 2
-};
-
-enum selection_snap {
- SNAP_WORD = 1,
- SNAP_LINE = 2
-};
-
-typedef unsigned char uchar;
-typedef unsigned int uint;
-typedef unsigned long ulong;
-typedef unsigned short ushort;
-
-typedef uint_least32_t Rune;
-
-#define Glyph Glyph_
-typedef struct {
- Rune u; /* character code */
- ushort mode; /* attribute flags */
- uint32_t fg; /* foreground */
- uint32_t bg; /* background */
-} Glyph;
-
-typedef Glyph *Line;
-
-typedef union {
- int i;
- uint ui;
- float f;
- const void *v;
- const char *s;
-} Arg;
-
-void die(const char *, ...);
-void redraw(void);
-void draw(void);
-
-void kscrolldown(const Arg *);
-void kscrollup(const Arg *);
-void printscreen(const Arg *);
-void printsel(const Arg *);
-void sendbreak(const Arg *);
-void toggleprinter(const Arg *);
-
-int tattrset(int);
-void tnew(int, int);
-void tresize(int, int);
-void tsetdirtattr(int);
-void ttyhangup(void);
-int ttynew(const char *, char *, const char *, char **);
-size_t ttyread(void);
-void ttyresize(int, int);
-void ttywrite(const char *, size_t, int);
-
-void resettitle(void);
-
-void selclear(void);
-void selinit(void);
-void selstart(int, int, int);
-void selextend(int, int, int, int);
-int selected(int, int);
-char *getsel(void);
-
-size_t utf8encode(Rune, char *);
-
-void *xmalloc(size_t);
-void *xrealloc(void *, size_t);
-char *xstrdup(const char *);
-
-/* config.h globals */
-extern char *utmp;
-extern char *scroll;
-extern char *stty_args;
-extern char *vtiden;
-extern wchar_t *worddelimiters;
-extern int allowaltscreen;
-extern int allowwindowops;
-extern char *termname;
-extern unsigned int tabspaces;
-extern unsigned int defaultfg;
-extern unsigned int defaultbg;
diff --git a/.repos/st/st.info b/.repos/st/st.info
deleted file mode 100644
index 8201ad6..0000000
--- a/.repos/st/st.info
+++ /dev/null
@@ -1,239 +0,0 @@
-st-mono| simpleterm monocolor,
- acsc=+C\,D-A.B0E``aaffgghFiGjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~,
- am,
- bce,
- bel=^G,
- blink=\E[5m,
- bold=\E[1m,
- cbt=\E[Z,
- cvvis=\E[?25h,
- civis=\E[?25l,
- clear=\E[H\E[2J,
- cnorm=\E[?12l\E[?25h,
- colors#2,
- cols#80,
- cr=^M,
- csr=\E[%i%p1%d;%p2%dr,
- cub=\E[%p1%dD,
- cub1=^H,
- cud1=^J,
- cud=\E[%p1%dB,
- cuf1=\E[C,
- cuf=\E[%p1%dC,
- cup=\E[%i%p1%d;%p2%dH,
- cuu1=\E[A,
- cuu=\E[%p1%dA,
- dch=\E[%p1%dP,
- dch1=\E[P,
- dim=\E[2m,
- dl=\E[%p1%dM,
- dl1=\E[M,
- ech=\E[%p1%dX,
- ed=\E[J,
- el=\E[K,
- el1=\E[1K,
- enacs=\E)0,
- flash=\E[?5h$<80/>\E[?5l,
- fsl=^G,
- home=\E[H,
- hpa=\E[%i%p1%dG,
- hs,
- ht=^I,
- hts=\EH,
- ich=\E[%p1%d@,
- il1=\E[L,
- il=\E[%p1%dL,
- ind=^J,
- indn=\E[%p1%dS,
- invis=\E[8m,
- is2=\E[4l\E>\E[?1034l,
- it#8,
- kel=\E[1;2F,
- ked=\E[1;5F,
- ka1=\E[1~,
- ka3=\E[5~,
- kc1=\E[4~,
- kc3=\E[6~,
- kbs=\177,
- kcbt=\E[Z,
- kb2=\EOu,
- kcub1=\EOD,
- kcud1=\EOB,
- kcuf1=\EOC,
- kcuu1=\EOA,
- kDC=\E[3;2~,
- kent=\EOM,
- kEND=\E[1;2F,
- kIC=\E[2;2~,
- kNXT=\E[6;2~,
- kPRV=\E[5;2~,
- kHOM=\E[1;2H,
- kLFT=\E[1;2D,
- kRIT=\E[1;2C,
- kind=\E[1;2B,
- kri=\E[1;2A,
- kclr=\E[3;5~,
- kdl1=\E[3;2~,
- kdch1=\E[3~,
- kich1=\E[2~,
- kend=\E[4~,
- kf1=\EOP,
- kf2=\EOQ,
- kf3=\EOR,
- kf4=\EOS,
- kf5=\E[15~,
- kf6=\E[17~,
- kf7=\E[18~,
- kf8=\E[19~,
- kf9=\E[20~,
- kf10=\E[21~,
- kf11=\E[23~,
- kf12=\E[24~,
- kf13=\E[1;2P,
- kf14=\E[1;2Q,
- kf15=\E[1;2R,
- kf16=\E[1;2S,
- kf17=\E[15;2~,
- kf18=\E[17;2~,
- kf19=\E[18;2~,
- kf20=\E[19;2~,
- kf21=\E[20;2~,
- kf22=\E[21;2~,
- kf23=\E[23;2~,
- kf24=\E[24;2~,
- kf25=\E[1;5P,
- kf26=\E[1;5Q,
- kf27=\E[1;5R,
- kf28=\E[1;5S,
- kf29=\E[15;5~,
- kf30=\E[17;5~,
- kf31=\E[18;5~,
- kf32=\E[19;5~,
- kf33=\E[20;5~,
- kf34=\E[21;5~,
- kf35=\E[23;5~,
- kf36=\E[24;5~,
- kf37=\E[1;6P,
- kf38=\E[1;6Q,
- kf39=\E[1;6R,
- kf40=\E[1;6S,
- kf41=\E[15;6~,
- kf42=\E[17;6~,
- kf43=\E[18;6~,
- kf44=\E[19;6~,
- kf45=\E[20;6~,
- kf46=\E[21;6~,
- kf47=\E[23;6~,
- kf48=\E[24;6~,
- kf49=\E[1;3P,
- kf50=\E[1;3Q,
- kf51=\E[1;3R,
- kf52=\E[1;3S,
- kf53=\E[15;3~,
- kf54=\E[17;3~,
- kf55=\E[18;3~,
- kf56=\E[19;3~,
- kf57=\E[20;3~,
- kf58=\E[21;3~,
- kf59=\E[23;3~,
- kf60=\E[24;3~,
- kf61=\E[1;4P,
- kf62=\E[1;4Q,
- kf63=\E[1;4R,
- khome=\E[1~,
- kil1=\E[2;5~,
- krmir=\E[2;2~,
- knp=\E[6~,
- kmous=\E[M,
- kpp=\E[5~,
- lines#24,
- mir,
- msgr,
- npc,
- op=\E[39;49m,
- pairs#64,
- mc0=\E[i,
- mc4=\E[4i,
- mc5=\E[5i,
- rc=\E8,
- rev=\E[7m,
- ri=\EM,
- rin=\E[%p1%dT,
- ritm=\E[23m,
- rmacs=\E(B,
- rmcup=\E[?1049l,
- rmir=\E[4l,
- rmkx=\E[?1l\E>,
- rmso=\E[27m,
- rmul=\E[24m,
- rs1=\Ec,
- rs2=\E[4l\E>\E[?1034l,
- sc=\E7,
- sitm=\E[3m,
- sgr0=\E[0m,
- smacs=\E(0,
- smcup=\E[?1049h,
- smir=\E[4h,
- smkx=\E[?1h\E=,
- smso=\E[7m,
- smul=\E[4m,
- tbc=\E[3g,
- tsl=\E]0;,
- xenl,
- vpa=\E[%i%p1%dd,
-# XTerm extensions
- rmxx=\E[29m,
- smxx=\E[9m,
-# disabled rep for now: causes some issues with older ncurses versions.
-# rep=%p1%c\E[%p2%{1}%-%db,
-# tmux extensions, see TERMINFO EXTENSIONS in tmux(1)
- Tc,
- Ms=\E]52;%p1%s;%p2%s\007,
- Se=\E[2 q,
- Ss=\E[%p1%d q,
-
-st| simpleterm,
- use=st-mono,
- colors#8,
- setab=\E[4%p1%dm,
- setaf=\E[3%p1%dm,
- setb=\E[4%?%p1%{1}%=%t4%e%p1%{3}%=%t6%e%p1%{4}%=%t1%e%p1%{6}%=%t3%e%p1%d%;m,
- setf=\E[3%?%p1%{1}%=%t4%e%p1%{3}%=%t6%e%p1%{4}%=%t1%e%p1%{6}%=%t3%e%p1%d%;m,
- sgr=%?%p9%t\E(0%e\E(B%;\E[0%?%p6%t;1%;%?%p2%t;4%;%?%p1%p3%|%t;7%;%?%p4%t;5%;%?%p7%t;8%;m,
-
-st-256color| simpleterm with 256 colors,
- use=st,
- ccc,
- colors#256,
- oc=\E]104\007,
- pairs#32767,
-# Nicked from xterm-256color
- initc=\E]4;%p1%d;rgb\:%p2%{255}%*%{1000}%/%2.2X/%p3%{255}%*%{1000}%/%2.2X/%p4%{255}%*%{1000}%/%2.2X\E\\,
- setab=\E[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m,
- setaf=\E[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m,
-
-st-meta| simpleterm with meta key,
- use=st,
- km,
- rmm=\E[?1034l,
- smm=\E[?1034h,
- rs2=\E[4l\E>\E[?1034h,
- is2=\E[4l\E>\E[?1034h,
-
-st-meta-256color| simpleterm with meta key and 256 colors,
- use=st-256color,
- km,
- rmm=\E[?1034l,
- smm=\E[?1034h,
- rs2=\E[4l\E>\E[?1034h,
- is2=\E[4l\E>\E[?1034h,
-
-st-bs| simpleterm with backspace as backspace,
- use=st,
- kbs=\010,
- kdch1=\177,
-
-st-bs-256color| simpleterm with backspace as backspace and 256colors,
- use=st-256color,
- kbs=\010,
- kdch1=\177,
diff --git a/.repos/st/st.o b/.repos/st/st.o
deleted file mode 100644
index 8abd057..0000000
--- a/.repos/st/st.o
+++ /dev/null
Binary files differ
diff --git a/.repos/st/win.h b/.repos/st/win.h
deleted file mode 100644
index e6e4369..0000000
--- a/.repos/st/win.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/* See LICENSE for license details. */
-
-enum win_mode {
- MODE_VISIBLE = 1 << 0,
- MODE_FOCUSED = 1 << 1,
- MODE_APPKEYPAD = 1 << 2,
- MODE_MOUSEBTN = 1 << 3,
- MODE_MOUSEMOTION = 1 << 4,
- MODE_REVERSE = 1 << 5,
- MODE_KBDLOCK = 1 << 6,
- MODE_HIDE = 1 << 7,
- MODE_APPCURSOR = 1 << 8,
- MODE_MOUSESGR = 1 << 9,
- MODE_8BIT = 1 << 10,
- MODE_BLINK = 1 << 11,
- MODE_FBLINK = 1 << 12,
- MODE_FOCUS = 1 << 13,
- MODE_MOUSEX10 = 1 << 14,
- MODE_MOUSEMANY = 1 << 15,
- MODE_BRCKTPASTE = 1 << 16,
- MODE_NUMLOCK = 1 << 17,
- MODE_MOUSE = MODE_MOUSEBTN|MODE_MOUSEMOTION|MODE_MOUSEX10\
- |MODE_MOUSEMANY,
-};
-
-void xbell(void);
-void xclipcopy(void);
-void xdrawcursor(int, int, Glyph, int, int, Glyph);
-void xdrawline(Line, int, int, int);
-void xfinishdraw(void);
-void xloadcols(void);
-int xsetcolorname(int, const char *);
-void xseticontitle(char *);
-void xsettitle(char *);
-int xsetcursor(int);
-void xsetmode(int, unsigned int);
-void xsetpointermotion(int);
-void xsetsel(char *);
-int xstartdraw(void);
-void xximspot(int, int);
diff --git a/.repos/st/x.c b/.repos/st/x.c
deleted file mode 100644
index 89786b8..0000000
--- a/.repos/st/x.c
+++ /dev/null
@@ -1,2067 +0,0 @@
-/* See LICENSE for license details. */
-#include <errno.h>
-#include <math.h>
-#include <limits.h>
-#include <locale.h>
-#include <signal.h>
-#include <sys/select.h>
-#include <time.h>
-#include <unistd.h>
-#include <libgen.h>
-#include <X11/Xatom.h>
-#include <X11/Xlib.h>
-#include <X11/cursorfont.h>
-#include <X11/keysym.h>
-#include <X11/Xft/Xft.h>
-#include <X11/XKBlib.h>
-
-char *argv0;
-#include "arg.h"
-#include "st.h"
-#include "win.h"
-
-/* types used in config.h */
-typedef struct {
- uint mod;
- KeySym keysym;
- void (*func)(const Arg *);
- const Arg arg;
-} Shortcut;
-
-typedef struct {
- uint mod;
- uint button;
- void (*func)(const Arg *);
- const Arg arg;
- uint release;
-} MouseShortcut;
-
-typedef struct {
- KeySym k;
- uint mask;
- char *s;
- /* three-valued logic variables: 0 indifferent, 1 on, -1 off */
- signed char appkey; /* application keypad */
- signed char appcursor; /* application cursor */
-} Key;
-
-/* X modifiers */
-#define XK_ANY_MOD UINT_MAX
-#define XK_NO_MOD 0
-#define XK_SWITCH_MOD (1<<13|1<<14)
-
-/* function definitions used in config.h */
-static void clipcopy(const Arg *);
-static void clippaste(const Arg *);
-static void numlock(const Arg *);
-static void selpaste(const Arg *);
-static void zoom(const Arg *);
-static void zoomabs(const Arg *);
-static void zoomreset(const Arg *);
-static void ttysend(const Arg *);
-
-/* config.h for applying patches and the configuration. */
-#include "config.h"
-
-/* XEMBED messages */
-#define XEMBED_FOCUS_IN 4
-#define XEMBED_FOCUS_OUT 5
-
-/* macros */
-#define IS_SET(flag) ((win.mode & (flag)) != 0)
-#define TRUERED(x) (((x) & 0xff0000) >> 8)
-#define TRUEGREEN(x) (((x) & 0xff00))
-#define TRUEBLUE(x) (((x) & 0xff) << 8)
-
-typedef XftDraw *Draw;
-typedef XftColor Color;
-typedef XftGlyphFontSpec GlyphFontSpec;
-
-/* Purely graphic info */
-typedef struct {
- int tw, th; /* tty width and height */
- int w, h; /* window width and height */
- int ch; /* char height */
- int cw; /* char width */
- int mode; /* window state/mode flags */
- int cursor; /* cursor style */
-} TermWindow;
-
-typedef struct {
- Display *dpy;
- Colormap cmap;
- Window win;
- Drawable buf;
- GlyphFontSpec *specbuf; /* font spec buffer used for rendering */
- Atom xembed, wmdeletewin, netwmname, netwmiconname, netwmpid;
- struct {
- XIM xim;
- XIC xic;
- XPoint spot;
- XVaNestedList spotlist;
- } ime;
- Draw draw;
- Visual *vis;
- XSetWindowAttributes attrs;
- int scr;
- int isfixed; /* is fixed geometry? */
- int l, t; /* left and top offset */
- int gm; /* geometry mask */
-} XWindow;
-
-typedef struct {
- Atom xtarget;
- char *primary, *clipboard;
- struct timespec tclick1;
- struct timespec tclick2;
-} XSelection;
-
-/* Font structure */
-#define Font Font_
-typedef struct {
- int height;
- int width;
- int ascent;
- int descent;
- int badslant;
- int badweight;
- short lbearing;
- short rbearing;
- XftFont *match;
- FcFontSet *set;
- FcPattern *pattern;
-} Font;
-
-/* Drawing Context */
-typedef struct {
- Color *col;
- size_t collen;
- Font font, bfont, ifont, ibfont;
- GC gc;
-} DC;
-
-static inline ushort sixd_to_16bit(int);
-static int xmakeglyphfontspecs(XftGlyphFontSpec *, const Glyph *, int, int, int);
-static void xdrawglyphfontspecs(const XftGlyphFontSpec *, Glyph, int, int, int);
-static void xdrawglyph(Glyph, int, int);
-static void xclear(int, int, int, int);
-static int xgeommasktogravity(int);
-static int ximopen(Display *);
-static void ximinstantiate(Display *, XPointer, XPointer);
-static void ximdestroy(XIM, XPointer, XPointer);
-static int xicdestroy(XIC, XPointer, XPointer);
-static void xinit(int, int);
-static void cresize(int, int);
-static void xresize(int, int);
-static void xhints(void);
-static int xloadcolor(int, const char *, Color *);
-static int xloadfont(Font *, FcPattern *);
-static void xloadfonts(const char *, double);
-static void xunloadfont(Font *);
-static void xunloadfonts(void);
-static void xsetenv(void);
-static void xseturgency(int);
-static int evcol(XEvent *);
-static int evrow(XEvent *);
-
-static void expose(XEvent *);
-static void visibility(XEvent *);
-static void unmap(XEvent *);
-static void kpress(XEvent *);
-static void cmessage(XEvent *);
-static void resize(XEvent *);
-static void focus(XEvent *);
-static uint buttonmask(uint);
-static int mouseaction(XEvent *, uint);
-static void brelease(XEvent *);
-static void bpress(XEvent *);
-static void bmotion(XEvent *);
-static void propnotify(XEvent *);
-static void selnotify(XEvent *);
-static void selclear_(XEvent *);
-static void selrequest(XEvent *);
-static void setsel(char *, Time);
-static void mousesel(XEvent *, int);
-static void mousereport(XEvent *);
-static char *kmap(KeySym, uint);
-static int match(uint, uint);
-
-static void run(void);
-static void usage(void);
-
-static void (*handler[LASTEvent])(XEvent *) = {
- [KeyPress] = kpress,
- [ClientMessage] = cmessage,
- [ConfigureNotify] = resize,
- [VisibilityNotify] = visibility,
- [UnmapNotify] = unmap,
- [Expose] = expose,
- [FocusIn] = focus,
- [FocusOut] = focus,
- [MotionNotify] = bmotion,
- [ButtonPress] = bpress,
- [ButtonRelease] = brelease,
-/*
- * Uncomment if you want the selection to disappear when you select something
- * different in another window.
- */
-/* [SelectionClear] = selclear_, */
- [SelectionNotify] = selnotify,
-/*
- * PropertyNotify is only turned on when there is some INCR transfer happening
- * for the selection retrieval.
- */
- [PropertyNotify] = propnotify,
- [SelectionRequest] = selrequest,
-};
-
-/* Globals */
-static DC dc;
-static XWindow xw;
-static XSelection xsel;
-static TermWindow win;
-
-/* Font Ring Cache */
-enum {
- FRC_NORMAL,
- FRC_ITALIC,
- FRC_BOLD,
- FRC_ITALICBOLD
-};
-
-typedef struct {
- XftFont *font;
- int flags;
- Rune unicodep;
-} Fontcache;
-
-/* Fontcache is an array now. A new font will be appended to the array. */
-static Fontcache *frc = NULL;
-static int frclen = 0;
-static int frccap = 0;
-static char *usedfont = NULL;
-static double usedfontsize = 0;
-static double defaultfontsize = 0;
-
-static char *opt_class = NULL;
-static char **opt_cmd = NULL;
-static char *opt_embed = NULL;
-static char *opt_font = NULL;
-static char *opt_io = NULL;
-static char *opt_line = NULL;
-static char *opt_name = NULL;
-static char *opt_title = NULL;
-
-static int oldbutton = 3; /* button event on startup: 3 = release */
-
-void
-clipcopy(const Arg *dummy)
-{
- Atom clipboard;
-
- free(xsel.clipboard);
- xsel.clipboard = NULL;
-
- if (xsel.primary != NULL) {
- xsel.clipboard = xstrdup(xsel.primary);
- clipboard = XInternAtom(xw.dpy, "CLIPBOARD", 0);
- XSetSelectionOwner(xw.dpy, clipboard, xw.win, CurrentTime);
- }
-}
-
-void
-clippaste(const Arg *dummy)
-{
- Atom clipboard;
-
- clipboard = XInternAtom(xw.dpy, "CLIPBOARD", 0);
- XConvertSelection(xw.dpy, clipboard, xsel.xtarget, clipboard,
- xw.win, CurrentTime);
-}
-
-void
-selpaste(const Arg *dummy)
-{
- XConvertSelection(xw.dpy, XA_PRIMARY, xsel.xtarget, XA_PRIMARY,
- xw.win, CurrentTime);
-}
-
-void
-numlock(const Arg *dummy)
-{
- win.mode ^= MODE_NUMLOCK;
-}
-
-void
-zoom(const Arg *arg)
-{
- Arg larg;
-
- larg.f = usedfontsize + arg->f;
- zoomabs(&larg);
-}
-
-void
-zoomabs(const Arg *arg)
-{
- xunloadfonts();
- xloadfonts(usedfont, arg->f);
- cresize(0, 0);
- redraw();
- xhints();
-}
-
-void
-zoomreset(const Arg *arg)
-{
- Arg larg;
-
- if (defaultfontsize > 0) {
- larg.f = defaultfontsize;
- zoomabs(&larg);
- }
-}
-
-void
-ttysend(const Arg *arg)
-{
- ttywrite(arg->s, strlen(arg->s), 1);
-}
-
-int
-evcol(XEvent *e)
-{
- int x = e->xbutton.x - borderpx;
- LIMIT(x, 0, win.tw - 1);
- return x / win.cw;
-}
-
-int
-evrow(XEvent *e)
-{
- int y = e->xbutton.y - borderpx;
- LIMIT(y, 0, win.th - 1);
- return y / win.ch;
-}
-
-void
-mousesel(XEvent *e, int done)
-{
- int type, seltype = SEL_REGULAR;
- uint state = e->xbutton.state & ~(Button1Mask | forcemousemod);
-
- for (type = 1; type < LEN(selmasks); ++type) {
- if (match(selmasks[type], state)) {
- seltype = type;
- break;
- }
- }
- selextend(evcol(e), evrow(e), seltype, done);
- if (done)
- setsel(getsel(), e->xbutton.time);
-}
-
-void
-mousereport(XEvent *e)
-{
- int len, x = evcol(e), y = evrow(e),
- button = e->xbutton.button, state = e->xbutton.state;
- char buf[40];
- static int ox, oy;
-
- /* from urxvt */
- if (e->xbutton.type == MotionNotify) {
- if (x == ox && y == oy)
- return;
- if (!IS_SET(MODE_MOUSEMOTION) && !IS_SET(MODE_MOUSEMANY))
- return;
- /* MOUSE_MOTION: no reporting if no button is pressed */
- if (IS_SET(MODE_MOUSEMOTION) && oldbutton == 3)
- return;
-
- button = oldbutton + 32;
- ox = x;
- oy = y;
- } else {
- if (!IS_SET(MODE_MOUSESGR) && e->xbutton.type == ButtonRelease) {
- button = 3;
- } else {
- button -= Button1;
- if (button >= 7)
- button += 128 - 7;
- else if (button >= 3)
- button += 64 - 3;
- }
- if (e->xbutton.type == ButtonPress) {
- oldbutton = button;
- ox = x;
- oy = y;
- } else if (e->xbutton.type == ButtonRelease) {
- oldbutton = 3;
- /* MODE_MOUSEX10: no button release reporting */
- if (IS_SET(MODE_MOUSEX10))
- return;
- if (button == 64 || button == 65)
- return;
- }
- }
-
- if (!IS_SET(MODE_MOUSEX10)) {
- button += ((state & ShiftMask ) ? 4 : 0)
- + ((state & Mod4Mask ) ? 8 : 0)
- + ((state & ControlMask) ? 16 : 0);
- }
-
- if (IS_SET(MODE_MOUSESGR)) {
- len = snprintf(buf, sizeof(buf), "\033[<%d;%d;%d%c",
- button, x+1, y+1,
- e->xbutton.type == ButtonRelease ? 'm' : 'M');
- } else if (x < 223 && y < 223) {
- len = snprintf(buf, sizeof(buf), "\033[M%c%c%c",
- 32+button, 32+x+1, 32+y+1);
- } else {
- return;
- }
-
- ttywrite(buf, len, 0);
-}
-
-uint
-buttonmask(uint button)
-{
- return button == Button1 ? Button1Mask
- : button == Button2 ? Button2Mask
- : button == Button3 ? Button3Mask
- : button == Button4 ? Button4Mask
- : button == Button5 ? Button5Mask
- : 0;
-}
-
-int
-mouseaction(XEvent *e, uint release)
-{
- MouseShortcut *ms;
-
- /* ignore Button<N>mask for Button<N> - it's set on release */
- uint state = e->xbutton.state & ~buttonmask(e->xbutton.button);
-
- for (ms = mshortcuts; ms < mshortcuts + LEN(mshortcuts); ms++) {
- if (ms->release == release &&
- ms->button == e->xbutton.button &&
- (match(ms->mod, state) || /* exact or forced */
- match(ms->mod, state & ~forcemousemod))) {
- ms->func(&(ms->arg));
- return 1;
- }
- }
-
- return 0;
-}
-
-void
-bpress(XEvent *e)
-{
- struct timespec now;
- int snap;
-
- if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forcemousemod)) {
- mousereport(e);
- return;
- }
-
- if (mouseaction(e, 0))
- return;
-
- if (e->xbutton.button == Button1) {
- /*
- * If the user clicks below predefined timeouts specific
- * snapping behaviour is exposed.
- */
- clock_gettime(CLOCK_MONOTONIC, &now);
- if (TIMEDIFF(now, xsel.tclick2) <= tripleclicktimeout) {
- snap = SNAP_LINE;
- } else if (TIMEDIFF(now, xsel.tclick1) <= doubleclicktimeout) {
- snap = SNAP_WORD;
- } else {
- snap = 0;
- }
- xsel.tclick2 = xsel.tclick1;
- xsel.tclick1 = now;
-
- selstart(evcol(e), evrow(e), snap);
- }
-}
-
-void
-propnotify(XEvent *e)
-{
- XPropertyEvent *xpev;
- Atom clipboard = XInternAtom(xw.dpy, "CLIPBOARD", 0);
-
- xpev = &e->xproperty;
- if (xpev->state == PropertyNewValue &&
- (xpev->atom == XA_PRIMARY ||
- xpev->atom == clipboard)) {
- selnotify(e);
- }
-}
-
-void
-selnotify(XEvent *e)
-{
- ulong nitems, ofs, rem;
- int format;
- uchar *data, *last, *repl;
- Atom type, incratom, property = None;
-
- incratom = XInternAtom(xw.dpy, "INCR", 0);
-
- ofs = 0;
- if (e->type == SelectionNotify)
- property = e->xselection.property;
- else if (e->type == PropertyNotify)
- property = e->xproperty.atom;
-
- if (property == None)
- return;
-
- do {
- if (XGetWindowProperty(xw.dpy, xw.win, property, ofs,
- BUFSIZ/4, False, AnyPropertyType,
- &type, &format, &nitems, &rem,
- &data)) {
- fprintf(stderr, "Clipboard allocation failed\n");
- return;
- }
-
- if (e->type == PropertyNotify && nitems == 0 && rem == 0) {
- /*
- * If there is some PropertyNotify with no data, then
- * this is the signal of the selection owner that all
- * data has been transferred. We won't need to receive
- * PropertyNotify events anymore.
- */
- MODBIT(xw.attrs.event_mask, 0, PropertyChangeMask);
- XChangeWindowAttributes(xw.dpy, xw.win, CWEventMask,
- &xw.attrs);
- }
-
- if (type == incratom) {
- /*
- * Activate the PropertyNotify events so we receive
- * when the selection owner does send us the next
- * chunk of data.
- */
- MODBIT(xw.attrs.event_mask, 1, PropertyChangeMask);
- XChangeWindowAttributes(xw.dpy, xw.win, CWEventMask,
- &xw.attrs);
-
- /*
- * Deleting the property is the transfer start signal.
- */
- XDeleteProperty(xw.dpy, xw.win, (int)property);
- continue;
- }
-
- /*
- * As seen in getsel:
- * Line endings are inconsistent in the terminal and GUI world
- * copy and pasting. When receiving some selection data,
- * replace all '\n' with '\r'.
- * FIXME: Fix the computer world.
- */
- repl = data;
- last = data + nitems * format / 8;
- while ((repl = memchr(repl, '\n', last - repl))) {
- *repl++ = '\r';
- }
-
- if (IS_SET(MODE_BRCKTPASTE) && ofs == 0)
- ttywrite("\033[200~", 6, 0);
- ttywrite((char *)data, nitems * format / 8, 1);
- if (IS_SET(MODE_BRCKTPASTE) && rem == 0)
- ttywrite("\033[201~", 6, 0);
- XFree(data);
- /* number of 32-bit chunks returned */
- ofs += nitems * format / 32;
- } while (rem > 0);
-
- /*
- * Deleting the property again tells the selection owner to send the
- * next data chunk in the property.
- */
- XDeleteProperty(xw.dpy, xw.win, (int)property);
-}
-
-void
-xclipcopy(void)
-{
- clipcopy(NULL);
-}
-
-void
-selclear_(XEvent *e)
-{
- selclear();
-}
-
-void
-selrequest(XEvent *e)
-{
- XSelectionRequestEvent *xsre;
- XSelectionEvent xev;
- Atom xa_targets, string, clipboard;
- char *seltext;
-
- xsre = (XSelectionRequestEvent *) e;
- xev.type = SelectionNotify;
- xev.requestor = xsre->requestor;
- xev.selection = xsre->selection;
- xev.target = xsre->target;
- xev.time = xsre->time;
- if (xsre->property == None)
- xsre->property = xsre->target;
-
- /* reject */
- xev.property = None;
-
- xa_targets = XInternAtom(xw.dpy, "TARGETS", 0);
- if (xsre->target == xa_targets) {
- /* respond with the supported type */
- string = xsel.xtarget;
- XChangeProperty(xsre->display, xsre->requestor, xsre->property,
- XA_ATOM, 32, PropModeReplace,
- (uchar *) &string, 1);
- xev.property = xsre->property;
- } else if (xsre->target == xsel.xtarget || xsre->target == XA_STRING) {
- /*
- * xith XA_STRING non ascii characters may be incorrect in the
- * requestor. It is not our problem, use utf8.
- */
- clipboard = XInternAtom(xw.dpy, "CLIPBOARD", 0);
- if (xsre->selection == XA_PRIMARY) {
- seltext = xsel.primary;
- } else if (xsre->selection == clipboard) {
- seltext = xsel.clipboard;
- } else {
- fprintf(stderr,
- "Unhandled clipboard selection 0x%lx\n",
- xsre->selection);
- return;
- }
- if (seltext != NULL) {
- XChangeProperty(xsre->display, xsre->requestor,
- xsre->property, xsre->target,
- 8, PropModeReplace,
- (uchar *)seltext, strlen(seltext));
- xev.property = xsre->property;
- }
- }
-
- /* all done, send a notification to the listener */
- if (!XSendEvent(xsre->display, xsre->requestor, 1, 0, (XEvent *) &xev))
- fprintf(stderr, "Error sending SelectionNotify event\n");
-}
-
-void
-setsel(char *str, Time t)
-{
- if (!str)
- return;
-
- free(xsel.primary);
- xsel.primary = str;
-
- XSetSelectionOwner(xw.dpy, XA_PRIMARY, xw.win, t);
- if (XGetSelectionOwner(xw.dpy, XA_PRIMARY) != xw.win)
- selclear();
-}
-
-void
-xsetsel(char *str)
-{
- setsel(str, CurrentTime);
-}
-
-void
-brelease(XEvent *e)
-{
- if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forcemousemod)) {
- mousereport(e);
- return;
- }
-
- if (mouseaction(e, 1))
- return;
- if (e->xbutton.button == Button1)
- mousesel(e, 1);
-}
-
-void
-bmotion(XEvent *e)
-{
- if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forcemousemod)) {
- mousereport(e);
- return;
- }
-
- mousesel(e, 0);
-}
-
-void
-cresize(int width, int height)
-{
- int col, row;
-
- if (width != 0)
- win.w = width;
- if (height != 0)
- win.h = height;
-
- col = (win.w - 2 * borderpx) / win.cw;
- row = (win.h - 2 * borderpx) / win.ch;
- col = MAX(1, col);
- row = MAX(1, row);
-
- tresize(col, row);
- xresize(col, row);
- ttyresize(win.tw, win.th);
-}
-
-void
-xresize(int col, int row)
-{
- win.tw = col * win.cw;
- win.th = row * win.ch;
-
- XFreePixmap(xw.dpy, xw.buf);
- xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h,
- DefaultDepth(xw.dpy, xw.scr));
- XftDrawChange(xw.draw, xw.buf);
- xclear(0, 0, win.w, win.h);
-
- /* resize to new width */
- xw.specbuf = xrealloc(xw.specbuf, col * sizeof(GlyphFontSpec));
-}
-
-ushort
-sixd_to_16bit(int x)
-{
- return x == 0 ? 0 : 0x3737 + 0x2828 * x;
-}
-
-int
-xloadcolor(int i, const char *name, Color *ncolor)
-{
- XRenderColor color = { .alpha = 0xffff };
-
- if (!name) {
- if (BETWEEN(i, 16, 255)) { /* 256 color */
- if (i < 6*6*6+16) { /* same colors as xterm */
- color.red = sixd_to_16bit( ((i-16)/36)%6 );
- color.green = sixd_to_16bit( ((i-16)/6) %6 );
- color.blue = sixd_to_16bit( ((i-16)/1) %6 );
- } else { /* greyscale */
- color.red = 0x0808 + 0x0a0a * (i - (6*6*6+16));
- color.green = color.blue = color.red;
- }
- return XftColorAllocValue(xw.dpy, xw.vis,
- xw.cmap, &color, ncolor);
- } else
- name = colorname[i];
- }
-
- return XftColorAllocName(xw.dpy, xw.vis, xw.cmap, name, ncolor);
-}
-
-void
-xloadcols(void)
-{
- int i;
- static int loaded;
- Color *cp;
-
- if (loaded) {
- for (cp = dc.col; cp < &dc.col[dc.collen]; ++cp)
- XftColorFree(xw.dpy, xw.vis, xw.cmap, cp);
- } else {
- dc.collen = MAX(LEN(colorname), 256);
- dc.col = xmalloc(dc.collen * sizeof(Color));
- }
-
- for (i = 0; i < dc.collen; i++)
- if (!xloadcolor(i, NULL, &dc.col[i])) {
- if (colorname[i])
- die("could not allocate color '%s'\n", colorname[i]);
- else
- die("could not allocate color %d\n", i);
- }
- loaded = 1;
-}
-
-int
-xsetcolorname(int x, const char *name)
-{
- Color ncolor;
-
- if (!BETWEEN(x, 0, dc.collen))
- return 1;
-
- if (!xloadcolor(x, name, &ncolor))
- return 1;
-
- XftColorFree(xw.dpy, xw.vis, xw.cmap, &dc.col[x]);
- dc.col[x] = ncolor;
-
- return 0;
-}
-
-/*
- * Absolute coordinates.
- */
-void
-xclear(int x1, int y1, int x2, int y2)
-{
- XftDrawRect(xw.draw,
- &dc.col[IS_SET(MODE_REVERSE)? defaultfg : defaultbg],
- x1, y1, x2-x1, y2-y1);
-}
-
-void
-xhints(void)
-{
- XClassHint class = {opt_name ? opt_name : termname,
- opt_class ? opt_class : termname};
- XWMHints wm = {.flags = InputHint, .input = 1};
- XSizeHints *sizeh;
-
- sizeh = XAllocSizeHints();
-
- sizeh->flags = PSize | PResizeInc | PBaseSize | PMinSize;
- sizeh->height = win.h;
- sizeh->width = win.w;
- sizeh->height_inc = win.ch;
- sizeh->width_inc = win.cw;
- sizeh->base_height = 2 * borderpx;
- sizeh->base_width = 2 * borderpx;
- sizeh->min_height = win.ch + 2 * borderpx;
- sizeh->min_width = win.cw + 2 * borderpx;
- if (xw.isfixed) {
- sizeh->flags |= PMaxSize;
- sizeh->min_width = sizeh->max_width = win.w;
- sizeh->min_height = sizeh->max_height = win.h;
- }
- if (xw.gm & (XValue|YValue)) {
- sizeh->flags |= USPosition | PWinGravity;
- sizeh->x = xw.l;
- sizeh->y = xw.t;
- sizeh->win_gravity = xgeommasktogravity(xw.gm);
- }
-
- XSetWMProperties(xw.dpy, xw.win, NULL, NULL, NULL, 0, sizeh, &wm,
- &class);
- XFree(sizeh);
-}
-
-int
-xgeommasktogravity(int mask)
-{
- switch (mask & (XNegative|YNegative)) {
- case 0:
- return NorthWestGravity;
- case XNegative:
- return NorthEastGravity;
- case YNegative:
- return SouthWestGravity;
- }
-
- return SouthEastGravity;
-}
-
-int
-xloadfont(Font *f, FcPattern *pattern)
-{
- FcPattern *configured;
- FcPattern *match;
- FcResult result;
- XGlyphInfo extents;
- int wantattr, haveattr;
-
- /*
- * Manually configure instead of calling XftMatchFont
- * so that we can use the configured pattern for
- * "missing glyph" lookups.
- */
- configured = FcPatternDuplicate(pattern);
- if (!configured)
- return 1;
-
- FcConfigSubstitute(NULL, configured, FcMatchPattern);
- XftDefaultSubstitute(xw.dpy, xw.scr, configured);
-
- match = FcFontMatch(NULL, configured, &result);
- if (!match) {
- FcPatternDestroy(configured);
- return 1;
- }
-
- if (!(f->match = XftFontOpenPattern(xw.dpy, match))) {
- FcPatternDestroy(configured);
- FcPatternDestroy(match);
- return 1;
- }
-
- if ((XftPatternGetInteger(pattern, "slant", 0, &wantattr) ==
- XftResultMatch)) {
- /*
- * Check if xft was unable to find a font with the appropriate
- * slant but gave us one anyway. Try to mitigate.
- */
- if ((XftPatternGetInteger(f->match->pattern, "slant", 0,
- &haveattr) != XftResultMatch) || haveattr < wantattr) {
- f->badslant = 1;
- fputs("font slant does not match\n", stderr);
- }
- }
-
- if ((XftPatternGetInteger(pattern, "weight", 0, &wantattr) ==
- XftResultMatch)) {
- if ((XftPatternGetInteger(f->match->pattern, "weight", 0,
- &haveattr) != XftResultMatch) || haveattr != wantattr) {
- f->badweight = 1;
- fputs("font weight does not match\n", stderr);
- }
- }
-
- XftTextExtentsUtf8(xw.dpy, f->match,
- (const FcChar8 *) ascii_printable,
- strlen(ascii_printable), &extents);
-
- f->set = NULL;
- f->pattern = configured;
-
- f->ascent = f->match->ascent;
- f->descent = f->match->descent;
- f->lbearing = 0;
- f->rbearing = f->match->max_advance_width;
-
- f->height = f->ascent + f->descent;
- f->width = DIVCEIL(extents.xOff, strlen(ascii_printable));
-
- return 0;
-}
-
-void
-xloadfonts(const char *fontstr, double fontsize)
-{
- FcPattern *pattern;
- double fontval;
-
- if (fontstr[0] == '-')
- pattern = XftXlfdParse(fontstr, False, False);
- else
- pattern = FcNameParse((const FcChar8 *)fontstr);
-
- if (!pattern)
- die("can't open font %s\n", fontstr);
-
- if (fontsize > 1) {
- FcPatternDel(pattern, FC_PIXEL_SIZE);
- FcPatternDel(pattern, FC_SIZE);
- FcPatternAddDouble(pattern, FC_PIXEL_SIZE, (double)fontsize);
- usedfontsize = fontsize;
- } else {
- if (FcPatternGetDouble(pattern, FC_PIXEL_SIZE, 0, &fontval) ==
- FcResultMatch) {
- usedfontsize = fontval;
- } else if (FcPatternGetDouble(pattern, FC_SIZE, 0, &fontval) ==
- FcResultMatch) {
- usedfontsize = -1;
- } else {
- /*
- * Default font size is 12, if none given. This is to
- * have a known usedfontsize value.
- */
- FcPatternAddDouble(pattern, FC_PIXEL_SIZE, 12);
- usedfontsize = 12;
- }
- defaultfontsize = usedfontsize;
- }
-
- if (xloadfont(&dc.font, pattern))
- die("can't open font %s\n", fontstr);
-
- if (usedfontsize < 0) {
- FcPatternGetDouble(dc.font.match->pattern,
- FC_PIXEL_SIZE, 0, &fontval);
- usedfontsize = fontval;
- if (fontsize == 0)
- defaultfontsize = fontval;
- }
-
- /* Setting character width and height. */
- win.cw = ceilf(dc.font.width * cwscale);
- win.ch = ceilf(dc.font.height * chscale);
-
- FcPatternDel(pattern, FC_SLANT);
- FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ITALIC);
- if (xloadfont(&dc.ifont, pattern))
- die("can't open font %s\n", fontstr);
-
- FcPatternDel(pattern, FC_WEIGHT);
- FcPatternAddInteger(pattern, FC_WEIGHT, FC_WEIGHT_BOLD);
- if (xloadfont(&dc.ibfont, pattern))
- die("can't open font %s\n", fontstr);
-
- FcPatternDel(pattern, FC_SLANT);
- FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ROMAN);
- if (xloadfont(&dc.bfont, pattern))
- die("can't open font %s\n", fontstr);
-
- FcPatternDestroy(pattern);
-}
-
-void
-xunloadfont(Font *f)
-{
- XftFontClose(xw.dpy, f->match);
- FcPatternDestroy(f->pattern);
- if (f->set)
- FcFontSetDestroy(f->set);
-}
-
-void
-xunloadfonts(void)
-{
- /* Free the loaded fonts in the font cache. */
- while (frclen > 0)
- XftFontClose(xw.dpy, frc[--frclen].font);
-
- xunloadfont(&dc.font);
- xunloadfont(&dc.bfont);
- xunloadfont(&dc.ifont);
- xunloadfont(&dc.ibfont);
-}
-
-int
-ximopen(Display *dpy)
-{
- XIMCallback imdestroy = { .client_data = NULL, .callback = ximdestroy };
- XICCallback icdestroy = { .client_data = NULL, .callback = xicdestroy };
-
- xw.ime.xim = XOpenIM(xw.dpy, NULL, NULL, NULL);
- if (xw.ime.xim == NULL)
- return 0;
-
- if (XSetIMValues(xw.ime.xim, XNDestroyCallback, &imdestroy, NULL))
- fprintf(stderr, "XSetIMValues: "
- "Could not set XNDestroyCallback.\n");
-
- xw.ime.spotlist = XVaCreateNestedList(0, XNSpotLocation, &xw.ime.spot,
- NULL);
-
- if (xw.ime.xic == NULL) {
- xw.ime.xic = XCreateIC(xw.ime.xim, XNInputStyle,
- XIMPreeditNothing | XIMStatusNothing,
- XNClientWindow, xw.win,
- XNDestroyCallback, &icdestroy,
- NULL);
- }
- if (xw.ime.xic == NULL)
- fprintf(stderr, "XCreateIC: Could not create input context.\n");
-
- return 1;
-}
-
-void
-ximinstantiate(Display *dpy, XPointer client, XPointer call)
-{
- if (ximopen(dpy))
- XUnregisterIMInstantiateCallback(xw.dpy, NULL, NULL, NULL,
- ximinstantiate, NULL);
-}
-
-void
-ximdestroy(XIM xim, XPointer client, XPointer call)
-{
- xw.ime.xim = NULL;
- XRegisterIMInstantiateCallback(xw.dpy, NULL, NULL, NULL,
- ximinstantiate, NULL);
- XFree(xw.ime.spotlist);
-}
-
-int
-xicdestroy(XIC xim, XPointer client, XPointer call)
-{
- xw.ime.xic = NULL;
- return 1;
-}
-
-void
-xinit(int cols, int rows)
-{
- XGCValues gcvalues;
- Cursor cursor;
- Window parent;
- pid_t thispid = getpid();
- XColor xmousefg, xmousebg;
-
- if (!(xw.dpy = XOpenDisplay(NULL)))
- die("can't open display\n");
- xw.scr = XDefaultScreen(xw.dpy);
- xw.vis = XDefaultVisual(xw.dpy, xw.scr);
-
- /* font */
- if (!FcInit())
- die("could not init fontconfig.\n");
-
- usedfont = (opt_font == NULL)? font : opt_font;
- xloadfonts(usedfont, 0);
-
- /* colors */
- xw.cmap = XDefaultColormap(xw.dpy, xw.scr);
- xloadcols();
-
- /* adjust fixed window geometry */
- win.w = 2 * borderpx + cols * win.cw;
- win.h = 2 * borderpx + rows * win.ch;
- if (xw.gm & XNegative)
- xw.l += DisplayWidth(xw.dpy, xw.scr) - win.w - 2;
- if (xw.gm & YNegative)
- xw.t += DisplayHeight(xw.dpy, xw.scr) - win.h - 2;
-
- /* Events */
- xw.attrs.background_pixel = dc.col[defaultbg].pixel;
- xw.attrs.border_pixel = dc.col[defaultbg].pixel;
- xw.attrs.bit_gravity = NorthWestGravity;
- xw.attrs.event_mask = FocusChangeMask | KeyPressMask | KeyReleaseMask
- | ExposureMask | VisibilityChangeMask | StructureNotifyMask
- | ButtonMotionMask | ButtonPressMask | ButtonReleaseMask;
- xw.attrs.colormap = xw.cmap;
-
- if (!(opt_embed && (parent = strtol(opt_embed, NULL, 0))))
- parent = XRootWindow(xw.dpy, xw.scr);
- xw.win = XCreateWindow(xw.dpy, parent, xw.l, xw.t,
- win.w, win.h, 0, XDefaultDepth(xw.dpy, xw.scr), InputOutput,
- xw.vis, CWBackPixel | CWBorderPixel | CWBitGravity
- | CWEventMask | CWColormap, &xw.attrs);
-
- memset(&gcvalues, 0, sizeof(gcvalues));
- gcvalues.graphics_exposures = False;
- dc.gc = XCreateGC(xw.dpy, parent, GCGraphicsExposures,
- &gcvalues);
- xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h,
- DefaultDepth(xw.dpy, xw.scr));
- XSetForeground(xw.dpy, dc.gc, dc.col[defaultbg].pixel);
- XFillRectangle(xw.dpy, xw.buf, dc.gc, 0, 0, win.w, win.h);
-
- /* font spec buffer */
- xw.specbuf = xmalloc(cols * sizeof(GlyphFontSpec));
-
- /* Xft rendering context */
- xw.draw = XftDrawCreate(xw.dpy, xw.buf, xw.vis, xw.cmap);
-
- /* input methods */
- if (!ximopen(xw.dpy)) {
- XRegisterIMInstantiateCallback(xw.dpy, NULL, NULL, NULL,
- ximinstantiate, NULL);
- }
-
- /* white cursor, black outline */
- cursor = XCreateFontCursor(xw.dpy, mouseshape);
- XDefineCursor(xw.dpy, xw.win, cursor);
-
- if (XParseColor(xw.dpy, xw.cmap, colorname[mousefg], &xmousefg) == 0) {
- xmousefg.red = 0xffff;
- xmousefg.green = 0xffff;
- xmousefg.blue = 0xffff;
- }
-
- if (XParseColor(xw.dpy, xw.cmap, colorname[mousebg], &xmousebg) == 0) {
- xmousebg.red = 0x0000;
- xmousebg.green = 0x0000;
- xmousebg.blue = 0x0000;
- }
-
- XRecolorCursor(xw.dpy, cursor, &xmousefg, &xmousebg);
-
- xw.xembed = XInternAtom(xw.dpy, "_XEMBED", False);
- xw.wmdeletewin = XInternAtom(xw.dpy, "WM_DELETE_WINDOW", False);
- xw.netwmname = XInternAtom(xw.dpy, "_NET_WM_NAME", False);
- xw.netwmiconname = XInternAtom(xw.dpy, "_NET_WM_ICON_NAME", False);
- XSetWMProtocols(xw.dpy, xw.win, &xw.wmdeletewin, 1);
-
- xw.netwmpid = XInternAtom(xw.dpy, "_NET_WM_PID", False);
- XChangeProperty(xw.dpy, xw.win, xw.netwmpid, XA_CARDINAL, 32,
- PropModeReplace, (uchar *)&thispid, 1);
-
- win.mode = MODE_NUMLOCK;
- resettitle();
- xhints();
- XMapWindow(xw.dpy, xw.win);
- XSync(xw.dpy, False);
-
- clock_gettime(CLOCK_MONOTONIC, &xsel.tclick1);
- clock_gettime(CLOCK_MONOTONIC, &xsel.tclick2);
- xsel.primary = NULL;
- xsel.clipboard = NULL;
- xsel.xtarget = XInternAtom(xw.dpy, "UTF8_STRING", 0);
- if (xsel.xtarget == None)
- xsel.xtarget = XA_STRING;
-}
-
-int
-xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x, int y)
-{
- float winx = borderpx + x * win.cw, winy = borderpx + y * win.ch, xp, yp;
- ushort mode, prevmode = USHRT_MAX;
- Font *font = &dc.font;
- int frcflags = FRC_NORMAL;
- float runewidth = win.cw;
- Rune rune;
- FT_UInt glyphidx;
- FcResult fcres;
- FcPattern *fcpattern, *fontpattern;
- FcFontSet *fcsets[] = { NULL };
- FcCharSet *fccharset;
- int i, f, numspecs = 0;
-
- for (i = 0, xp = winx, yp = winy + font->ascent; i < len; ++i) {
- /* Fetch rune and mode for current glyph. */
- rune = glyphs[i].u;
- mode = glyphs[i].mode;
-
- /* Skip dummy wide-character spacing. */
- if (mode == ATTR_WDUMMY)
- continue;
-
- /* Determine font for glyph if different from previous glyph. */
- if (prevmode != mode) {
- prevmode = mode;
- font = &dc.font;
- frcflags = FRC_NORMAL;
- runewidth = win.cw * ((mode & ATTR_WIDE) ? 2.0f : 1.0f);
- if ((mode & ATTR_ITALIC) && (mode & ATTR_BOLD)) {
- font = &dc.ibfont;
- frcflags = FRC_ITALICBOLD;
- } else if (mode & ATTR_ITALIC) {
- font = &dc.ifont;
- frcflags = FRC_ITALIC;
- } else if (mode & ATTR_BOLD) {
- font = &dc.bfont;
- frcflags = FRC_BOLD;
- }
- yp = winy + font->ascent;
- }
-
- /* Lookup character index with default font. */
- glyphidx = XftCharIndex(xw.dpy, font->match, rune);
- if (glyphidx) {
- specs[numspecs].font = font->match;
- specs[numspecs].glyph = glyphidx;
- specs[numspecs].x = (short)xp;
- specs[numspecs].y = (short)yp;
- xp += runewidth;
- numspecs++;
- continue;
- }
-
- /* Fallback on font cache, search the font cache for match. */
- for (f = 0; f < frclen; f++) {
- glyphidx = XftCharIndex(xw.dpy, frc[f].font, rune);
- /* Everything correct. */
- if (glyphidx && frc[f].flags == frcflags)
- break;
- /* We got a default font for a not found glyph. */
- if (!glyphidx && frc[f].flags == frcflags
- && frc[f].unicodep == rune) {
- break;
- }
- }
-
- /* Nothing was found. Use fontconfig to find matching font. */
- if (f >= frclen) {
- if (!font->set)
- font->set = FcFontSort(0, font->pattern,
- 1, 0, &fcres);
- fcsets[0] = font->set;
-
- /*
- * Nothing was found in the cache. Now use
- * some dozen of Fontconfig calls to get the
- * font for one single character.
- *
- * Xft and fontconfig are design failures.
- */
- fcpattern = FcPatternDuplicate(font->pattern);
- fccharset = FcCharSetCreate();
-
- FcCharSetAddChar(fccharset, rune);
- FcPatternAddCharSet(fcpattern, FC_CHARSET,
- fccharset);
- FcPatternAddBool(fcpattern, FC_SCALABLE, 1);
-
- FcConfigSubstitute(0, fcpattern,
- FcMatchPattern);
- FcDefaultSubstitute(fcpattern);
-
- fontpattern = FcFontSetMatch(0, fcsets, 1,
- fcpattern, &fcres);
-
- /* Allocate memory for the new cache entry. */
- if (frclen >= frccap) {
- frccap += 16;
- frc = xrealloc(frc, frccap * sizeof(Fontcache));
- }
-
- frc[frclen].font = XftFontOpenPattern(xw.dpy,
- fontpattern);
- if (!frc[frclen].font)
- die("XftFontOpenPattern failed seeking fallback font: %s\n",
- strerror(errno));
- frc[frclen].flags = frcflags;
- frc[frclen].unicodep = rune;
-
- glyphidx = XftCharIndex(xw.dpy, frc[frclen].font, rune);
-
- f = frclen;
- frclen++;
-
- FcPatternDestroy(fcpattern);
- FcCharSetDestroy(fccharset);
- }
-
- specs[numspecs].font = frc[f].font;
- specs[numspecs].glyph = glyphidx;
- specs[numspecs].x = (short)xp;
- specs[numspecs].y = (short)yp;
- xp += runewidth;
- numspecs++;
- }
-
- return numspecs;
-}
-
-void
-xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, int y)
-{
- int charlen = len * ((base.mode & ATTR_WIDE) ? 2 : 1);
- int winx = borderpx + x * win.cw, winy = borderpx + y * win.ch,
- width = charlen * win.cw;
- Color *fg, *bg, *temp, revfg, revbg, truefg, truebg;
- XRenderColor colfg, colbg;
- XRectangle r;
-
- /* Fallback on color display for attributes not supported by the font */
- if (base.mode & ATTR_ITALIC && base.mode & ATTR_BOLD) {
- if (dc.ibfont.badslant || dc.ibfont.badweight)
- base.fg = defaultattr;
- } else if ((base.mode & ATTR_ITALIC && dc.ifont.badslant) ||
- (base.mode & ATTR_BOLD && dc.bfont.badweight)) {
- base.fg = defaultattr;
- }
-
- if (IS_TRUECOL(base.fg)) {
- colfg.alpha = 0xffff;
- colfg.red = TRUERED(base.fg);
- colfg.green = TRUEGREEN(base.fg);
- colfg.blue = TRUEBLUE(base.fg);
- XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &colfg, &truefg);
- fg = &truefg;
- } else {
- fg = &dc.col[base.fg];
- }
-
- if (IS_TRUECOL(base.bg)) {
- colbg.alpha = 0xffff;
- colbg.green = TRUEGREEN(base.bg);
- colbg.red = TRUERED(base.bg);
- colbg.blue = TRUEBLUE(base.bg);
- XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &colbg, &truebg);
- bg = &truebg;
- } else {
- bg = &dc.col[base.bg];
- }
-
- /* Change basic system colors [0-7] to bright system colors [8-15] */
- if ((base.mode & ATTR_BOLD_FAINT) == ATTR_BOLD && BETWEEN(base.fg, 0, 7))
- fg = &dc.col[base.fg + 8];
-
- if (IS_SET(MODE_REVERSE)) {
- if (fg == &dc.col[defaultfg]) {
- fg = &dc.col[defaultbg];
- } else {
- colfg.red = ~fg->color.red;
- colfg.green = ~fg->color.green;
- colfg.blue = ~fg->color.blue;
- colfg.alpha = fg->color.alpha;
- XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &colfg,
- &revfg);
- fg = &revfg;
- }
-
- if (bg == &dc.col[defaultbg]) {
- bg = &dc.col[defaultfg];
- } else {
- colbg.red = ~bg->color.red;
- colbg.green = ~bg->color.green;
- colbg.blue = ~bg->color.blue;
- colbg.alpha = bg->color.alpha;
- XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &colbg,
- &revbg);
- bg = &revbg;
- }
- }
-
- if ((base.mode & ATTR_BOLD_FAINT) == ATTR_FAINT) {
- colfg.red = fg->color.red / 2;
- colfg.green = fg->color.green / 2;
- colfg.blue = fg->color.blue / 2;
- colfg.alpha = fg->color.alpha;
- XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &colfg, &revfg);
- fg = &revfg;
- }
-
- if (base.mode & ATTR_REVERSE) {
- temp = fg;
- fg = bg;
- bg = temp;
- }
-
- if (base.mode & ATTR_BLINK && win.mode & MODE_BLINK)
- fg = bg;
-
- if (base.mode & ATTR_INVISIBLE)
- fg = bg;
-
- /* Intelligent cleaning up of the borders. */
- if (x == 0) {
- xclear(0, (y == 0)? 0 : winy, borderpx,
- winy + win.ch +
- ((winy + win.ch >= borderpx + win.th)? win.h : 0));
- }
- if (winx + width >= borderpx + win.tw) {
- xclear(winx + width, (y == 0)? 0 : winy, win.w,
- ((winy + win.ch >= borderpx + win.th)? win.h : (winy + win.ch)));
- }
- if (y == 0)
- xclear(winx, 0, winx + width, borderpx);
- if (winy + win.ch >= borderpx + win.th)
- xclear(winx, winy + win.ch, winx + width, win.h);
-
- /* Clean up the region we want to draw to. */
- XftDrawRect(xw.draw, bg, winx, winy, width, win.ch);
-
- /* Set the clip region because Xft is sometimes dirty. */
- r.x = 0;
- r.y = 0;
- r.height = win.ch;
- r.width = width;
- XftDrawSetClipRectangles(xw.draw, winx, winy, &r, 1);
-
- /* Render the glyphs. */
- XftDrawGlyphFontSpec(xw.draw, fg, specs, len);
-
- /* Render underline and strikethrough. */
- if (base.mode & ATTR_UNDERLINE) {
- XftDrawRect(xw.draw, fg, winx, winy + dc.font.ascent + 1,
- width, 1);
- }
-
- if (base.mode & ATTR_STRUCK) {
- XftDrawRect(xw.draw, fg, winx, winy + 2 * dc.font.ascent / 3,
- width, 1);
- }
-
- /* Reset clip to none. */
- XftDrawSetClip(xw.draw, 0);
-}
-
-void
-xdrawglyph(Glyph g, int x, int y)
-{
- int numspecs;
- XftGlyphFontSpec spec;
-
- numspecs = xmakeglyphfontspecs(&spec, &g, 1, x, y);
- xdrawglyphfontspecs(&spec, g, numspecs, x, y);
-}
-
-void
-xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og)
-{
- Color drawcol;
-
- /* remove the old cursor */
- if (selected(ox, oy))
- og.mode ^= ATTR_REVERSE;
- xdrawglyph(og, ox, oy);
-
- if (IS_SET(MODE_HIDE))
- return;
-
- /*
- * Select the right color for the right mode.
- */
- g.mode &= ATTR_BOLD|ATTR_ITALIC|ATTR_UNDERLINE|ATTR_STRUCK|ATTR_WIDE;
-
- if (IS_SET(MODE_REVERSE)) {
- g.mode |= ATTR_REVERSE;
- g.bg = defaultfg;
- if (selected(cx, cy)) {
- drawcol = dc.col[defaultcs];
- g.fg = defaultrcs;
- } else {
- drawcol = dc.col[defaultrcs];
- g.fg = defaultcs;
- }
- } else {
- if (selected(cx, cy)) {
- g.fg = defaultfg;
- g.bg = defaultrcs;
- } else {
- g.fg = defaultbg;
- g.bg = defaultcs;
- }
- drawcol = dc.col[g.bg];
- }
-
- /* draw the new one */
- if (IS_SET(MODE_FOCUSED)) {
- switch (win.cursor) {
- case 7: /* st extension */
- g.u = 0x2603; /* snowman (U+2603) */
- /* FALLTHROUGH */
- case 0: /* Blinking Block */
- case 1: /* Blinking Block (Default) */
- case 2: /* Steady Block */
- xdrawglyph(g, cx, cy);
- break;
- case 3: /* Blinking Underline */
- case 4: /* Steady Underline */
- XftDrawRect(xw.draw, &drawcol,
- borderpx + cx * win.cw,
- borderpx + (cy + 1) * win.ch - \
- cursorthickness,
- win.cw, cursorthickness);
- break;
- case 5: /* Blinking bar */
- case 6: /* Steady bar */
- XftDrawRect(xw.draw, &drawcol,
- borderpx + cx * win.cw,
- borderpx + cy * win.ch,
- cursorthickness, win.ch);
- break;
- }
- } else {
- XftDrawRect(xw.draw, &drawcol,
- borderpx + cx * win.cw,
- borderpx + cy * win.ch,
- win.cw - 1, 1);
- XftDrawRect(xw.draw, &drawcol,
- borderpx + cx * win.cw,
- borderpx + cy * win.ch,
- 1, win.ch - 1);
- XftDrawRect(xw.draw, &drawcol,
- borderpx + (cx + 1) * win.cw - 1,
- borderpx + cy * win.ch,
- 1, win.ch - 1);
- XftDrawRect(xw.draw, &drawcol,
- borderpx + cx * win.cw,
- borderpx + (cy + 1) * win.ch - 1,
- win.cw, 1);
- }
-}
-
-void
-xsetenv(void)
-{
- char buf[sizeof(long) * 8 + 1];
-
- snprintf(buf, sizeof(buf), "%lu", xw.win);
- setenv("WINDOWID", buf, 1);
-}
-
-void
-xseticontitle(char *p)
-{
- XTextProperty prop;
- DEFAULT(p, opt_title);
-
- if (Xutf8TextListToTextProperty(xw.dpy, &p, 1, XUTF8StringStyle,
- &prop) != Success)
- return;
- XSetWMIconName(xw.dpy, xw.win, &prop);
- XSetTextProperty(xw.dpy, xw.win, &prop, xw.netwmiconname);
- XFree(prop.value);
-}
-
-void
-xsettitle(char *p)
-{
- XTextProperty prop;
- DEFAULT(p, opt_title);
-
- if (Xutf8TextListToTextProperty(xw.dpy, &p, 1, XUTF8StringStyle,
- &prop) != Success)
- return;
- XSetWMName(xw.dpy, xw.win, &prop);
- XSetTextProperty(xw.dpy, xw.win, &prop, xw.netwmname);
- XFree(prop.value);
-}
-
-int
-xstartdraw(void)
-{
- return IS_SET(MODE_VISIBLE);
-}
-
-void
-xdrawline(Line line, int x1, int y1, int x2)
-{
- int i, x, ox, numspecs;
- Glyph base, new;
- XftGlyphFontSpec *specs = xw.specbuf;
-
- numspecs = xmakeglyphfontspecs(specs, &line[x1], x2 - x1, x1, y1);
- i = ox = 0;
- for (x = x1; x < x2 && i < numspecs; x++) {
- new = line[x];
- if (new.mode == ATTR_WDUMMY)
- continue;
- if (selected(x, y1))
- new.mode ^= ATTR_REVERSE;
- if (i > 0 && ATTRCMP(base, new)) {
- xdrawglyphfontspecs(specs, base, i, ox, y1);
- specs += i;
- numspecs -= i;
- i = 0;
- }
- if (i == 0) {
- ox = x;
- base = new;
- }
- i++;
- }
- if (i > 0)
- xdrawglyphfontspecs(specs, base, i, ox, y1);
-}
-
-void
-xfinishdraw(void)
-{
- XCopyArea(xw.dpy, xw.buf, xw.win, dc.gc, 0, 0, win.w,
- win.h, 0, 0);
- XSetForeground(xw.dpy, dc.gc,
- dc.col[IS_SET(MODE_REVERSE)?
- defaultfg : defaultbg].pixel);
-}
-
-void
-xximspot(int x, int y)
-{
- if (xw.ime.xic == NULL)
- return;
-
- xw.ime.spot.x = borderpx + x * win.cw;
- xw.ime.spot.y = borderpx + (y + 1) * win.ch;
-
- XSetICValues(xw.ime.xic, XNPreeditAttributes, xw.ime.spotlist, NULL);
-}
-
-void
-expose(XEvent *ev)
-{
- redraw();
-}
-
-void
-visibility(XEvent *ev)
-{
- XVisibilityEvent *e = &ev->xvisibility;
-
- MODBIT(win.mode, e->state != VisibilityFullyObscured, MODE_VISIBLE);
-}
-
-void
-unmap(XEvent *ev)
-{
- win.mode &= ~MODE_VISIBLE;
-}
-
-void
-xsetpointermotion(int set)
-{
- MODBIT(xw.attrs.event_mask, set, PointerMotionMask);
- XChangeWindowAttributes(xw.dpy, xw.win, CWEventMask, &xw.attrs);
-}
-
-void
-xsetmode(int set, unsigned int flags)
-{
- int mode = win.mode;
- MODBIT(win.mode, set, flags);
- if ((win.mode & MODE_REVERSE) != (mode & MODE_REVERSE))
- redraw();
-}
-
-int
-xsetcursor(int cursor)
-{
- if (!BETWEEN(cursor, 0, 7)) /* 7: st extension */
- return 1;
- win.cursor = cursor;
- return 0;
-}
-
-void
-xseturgency(int add)
-{
- XWMHints *h = XGetWMHints(xw.dpy, xw.win);
-
- MODBIT(h->flags, add, XUrgencyHint);
- XSetWMHints(xw.dpy, xw.win, h);
- XFree(h);
-}
-
-void
-xbell(void)
-{
- if (!(IS_SET(MODE_FOCUSED)))
- xseturgency(1);
- if (bellvolume)
- XkbBell(xw.dpy, xw.win, bellvolume, (Atom)NULL);
-}
-
-void
-focus(XEvent *ev)
-{
- XFocusChangeEvent *e = &ev->xfocus;
-
- if (e->mode == NotifyGrab)
- return;
-
- if (ev->type == FocusIn) {
- if (xw.ime.xic)
- XSetICFocus(xw.ime.xic);
- win.mode |= MODE_FOCUSED;
- xseturgency(0);
- if (IS_SET(MODE_FOCUS))
- ttywrite("\033[I", 3, 0);
- } else {
- if (xw.ime.xic)
- XUnsetICFocus(xw.ime.xic);
- win.mode &= ~MODE_FOCUSED;
- if (IS_SET(MODE_FOCUS))
- ttywrite("\033[O", 3, 0);
- }
-}
-
-int
-match(uint mask, uint state)
-{
- return mask == XK_ANY_MOD || mask == (state & ~ignoremod);
-}
-
-char*
-kmap(KeySym k, uint state)
-{
- Key *kp;
- int i;
-
- /* Check for mapped keys out of X11 function keys. */
- for (i = 0; i < LEN(mappedkeys); i++) {
- if (mappedkeys[i] == k)
- break;
- }
- if (i == LEN(mappedkeys)) {
- if ((k & 0xFFFF) < 0xFD00)
- return NULL;
- }
-
- for (kp = key; kp < key + LEN(key); kp++) {
- if (kp->k != k)
- continue;
-
- if (!match(kp->mask, state))
- continue;
-
- if (IS_SET(MODE_APPKEYPAD) ? kp->appkey < 0 : kp->appkey > 0)
- continue;
- if (IS_SET(MODE_NUMLOCK) && kp->appkey == 2)
- continue;
-
- if (IS_SET(MODE_APPCURSOR) ? kp->appcursor < 0 : kp->appcursor > 0)
- continue;
-
- return kp->s;
- }
-
- return NULL;
-}
-
-void
-kpress(XEvent *ev)
-{
- XKeyEvent *e = &ev->xkey;
- KeySym ksym;
- char buf[64], *customkey;
- int len;
- Rune c;
- Status status;
- Shortcut *bp;
-
- if (IS_SET(MODE_KBDLOCK))
- return;
-
- if (xw.ime.xic)
- len = XmbLookupString(xw.ime.xic, e, buf, sizeof buf, &ksym, &status);
- else
- len = XLookupString(e, buf, sizeof buf, &ksym, NULL);
- /* 1. shortcuts */
- for (bp = shortcuts; bp < shortcuts + LEN(shortcuts); bp++) {
- if (ksym == bp->keysym && match(bp->mod, e->state)) {
- bp->func(&(bp->arg));
- return;
- }
- }
-
- /* 2. custom keys from config.h */
- if ((customkey = kmap(ksym, e->state))) {
- ttywrite(customkey, strlen(customkey), 1);
- return;
- }
-
- /* 3. composed string from input method */
- if (len == 0)
- return;
- if (len == 1 && e->state & Mod1Mask) {
- if (IS_SET(MODE_8BIT)) {
- if (*buf < 0177) {
- c = *buf | 0x80;
- len = utf8encode(c, buf);
- }
- } else {
- buf[1] = buf[0];
- buf[0] = '\033';
- len = 2;
- }
- }
- ttywrite(buf, len, 1);
-}
-
-void
-cmessage(XEvent *e)
-{
- /*
- * See xembed specs
- * http://standards.freedesktop.org/xembed-spec/xembed-spec-latest.html
- */
- if (e->xclient.message_type == xw.xembed && e->xclient.format == 32) {
- if (e->xclient.data.l[1] == XEMBED_FOCUS_IN) {
- win.mode |= MODE_FOCUSED;
- xseturgency(0);
- } else if (e->xclient.data.l[1] == XEMBED_FOCUS_OUT) {
- win.mode &= ~MODE_FOCUSED;
- }
- } else if (e->xclient.data.l[0] == xw.wmdeletewin) {
- ttyhangup();
- exit(0);
- }
-}
-
-void
-resize(XEvent *e)
-{
- if (e->xconfigure.width == win.w && e->xconfigure.height == win.h)
- return;
-
- cresize(e->xconfigure.width, e->xconfigure.height);
-}
-
-void
-run(void)
-{
- XEvent ev;
- int w = win.w, h = win.h;
- fd_set rfd;
- int xfd = XConnectionNumber(xw.dpy), ttyfd, xev, drawing;
- struct timespec seltv, *tv, now, lastblink, trigger;
- double timeout;
-
- /* Waiting for window mapping */
- do {
- XNextEvent(xw.dpy, &ev);
- /*
- * This XFilterEvent call is required because of XOpenIM. It
- * does filter out the key event and some client message for
- * the input method too.
- */
- if (XFilterEvent(&ev, None))
- continue;
- if (ev.type == ConfigureNotify) {
- w = ev.xconfigure.width;
- h = ev.xconfigure.height;
- }
- } while (ev.type != MapNotify);
-
- ttyfd = ttynew(opt_line, shell, opt_io, opt_cmd);
- cresize(w, h);
-
- for (timeout = -1, drawing = 0, lastblink = (struct timespec){0};;) {
- FD_ZERO(&rfd);
- FD_SET(ttyfd, &rfd);
- FD_SET(xfd, &rfd);
-
- if (XPending(xw.dpy))
- timeout = 0; /* existing events might not set xfd */
-
- seltv.tv_sec = timeout / 1E3;
- seltv.tv_nsec = 1E6 * (timeout - 1E3 * seltv.tv_sec);
- tv = timeout >= 0 ? &seltv : NULL;
-
- if (pselect(MAX(xfd, ttyfd)+1, &rfd, NULL, NULL, tv, NULL) < 0) {
- if (errno == EINTR)
- continue;
- die("select failed: %s\n", strerror(errno));
- }
- clock_gettime(CLOCK_MONOTONIC, &now);
-
- if (FD_ISSET(ttyfd, &rfd))
- ttyread();
-
- xev = 0;
- while (XPending(xw.dpy)) {
- xev = 1;
- XNextEvent(xw.dpy, &ev);
- if (XFilterEvent(&ev, None))
- continue;
- if (handler[ev.type])
- (handler[ev.type])(&ev);
- }
-
- /*
- * To reduce flicker and tearing, when new content or event
- * triggers drawing, we first wait a bit to ensure we got
- * everything, and if nothing new arrives - we draw.
- * We start with trying to wait minlatency ms. If more content
- * arrives sooner, we retry with shorter and shorter periods,
- * and eventually draw even without idle after maxlatency ms.
- * Typically this results in low latency while interacting,
- * maximum latency intervals during `cat huge.txt`, and perfect
- * sync with periodic updates from animations/key-repeats/etc.
- */
- if (FD_ISSET(ttyfd, &rfd) || xev) {
- if (!drawing) {
- trigger = now;
- drawing = 1;
- }
- timeout = (maxlatency - TIMEDIFF(now, trigger)) \
- / maxlatency * minlatency;
- if (timeout > 0)
- continue; /* we have time, try to find idle */
- }
-
- /* idle detected or maxlatency exhausted -> draw */
- timeout = -1;
- if (blinktimeout && tattrset(ATTR_BLINK)) {
- timeout = blinktimeout - TIMEDIFF(now, lastblink);
- if (timeout <= 0) {
- if (-timeout > blinktimeout) /* start visible */
- win.mode |= MODE_BLINK;
- win.mode ^= MODE_BLINK;
- tsetdirtattr(ATTR_BLINK);
- lastblink = now;
- timeout = blinktimeout;
- }
- }
-
- draw();
- XFlush(xw.dpy);
- drawing = 0;
- }
-}
-
-void
-usage(void)
-{
- die("usage: %s [-aiv] [-c class] [-f font] [-g geometry]"
- " [-n name] [-o file]\n"
- " [-T title] [-t title] [-w windowid]"
- " [[-e] command [args ...]]\n"
- " %s [-aiv] [-c class] [-f font] [-g geometry]"
- " [-n name] [-o file]\n"
- " [-T title] [-t title] [-w windowid] -l line"
- " [stty_args ...]\n", argv0, argv0);
-}
-
-int
-main(int argc, char *argv[])
-{
- xw.l = xw.t = 0;
- xw.isfixed = False;
- xsetcursor(cursorshape);
-
- ARGBEGIN {
- case 'a':
- allowaltscreen = 0;
- break;
- case 'c':
- opt_class = EARGF(usage());
- break;
- case 'e':
- if (argc > 0)
- --argc, ++argv;
- goto run;
- case 'f':
- opt_font = EARGF(usage());
- break;
- case 'g':
- xw.gm = XParseGeometry(EARGF(usage()),
- &xw.l, &xw.t, &cols, &rows);
- break;
- case 'i':
- xw.isfixed = 1;
- break;
- case 'o':
- opt_io = EARGF(usage());
- break;
- case 'l':
- opt_line = EARGF(usage());
- break;
- case 'n':
- opt_name = EARGF(usage());
- break;
- case 't':
- case 'T':
- opt_title = EARGF(usage());
- break;
- case 'w':
- opt_embed = EARGF(usage());
- break;
- case 'v':
- die("%s " VERSION "\n", argv0);
- break;
- default:
- usage();
- } ARGEND;
-
-run:
- if (argc > 0) /* eat all remaining arguments */
- opt_cmd = argv;
-
- if (!opt_title)
- opt_title = (opt_line || !opt_cmd) ? "st" : opt_cmd[0];
-
- setlocale(LC_CTYPE, "");
- XSetLocaleModifiers("");
- cols = MAX(cols, 1);
- rows = MAX(rows, 1);
- tnew(cols, rows);
- xinit(cols, rows);
- xsetenv();
- selinit();
- run();
-
- return 0;
-}
diff --git a/.repos/st/x.o b/.repos/st/x.o
deleted file mode 100644
index 3164225..0000000
--- a/.repos/st/x.o
+++ /dev/null
Binary files differ
diff --git a/.repos/tabbed/LICENSE b/.repos/tabbed/LICENSE
deleted file mode 100644
index d8e9678..0000000
--- a/.repos/tabbed/LICENSE
+++ /dev/null
@@ -1,23 +0,0 @@
-MIT/X Consortium License
-
-© 2009-2011 Enno Boland <g s01 de>
-© 2011,2015 Connor Lane Smith <cls@lubutu.com>
-© 2012-2015 Christoph Lohmann <20h@r-36.net>
-
-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/.repos/tabbed/Makefile b/.repos/tabbed/Makefile
deleted file mode 100644
index 1b95d15..0000000
--- a/.repos/tabbed/Makefile
+++ /dev/null
@@ -1,65 +0,0 @@
-# tabbed - tabbing interface
-# See LICENSE file for copyright and license details.
-
-include config.mk
-
-SRC = tabbed.c xembed.c
-OBJ = ${SRC:.c=.o}
-BIN = ${OBJ:.o=}
-
-all: options ${BIN}
-
-options:
- @echo tabbed build options:
- @echo "CFLAGS = ${CFLAGS}"
- @echo "LDFLAGS = ${LDFLAGS}"
- @echo "CC = ${CC}"
-
-.c.o:
- @echo CC $<
- @${CC} -c ${CFLAGS} $<
-
-${OBJ}: config.h config.mk
-
-config.h:
- @echo creating $@ from config.def.h
- @cp config.def.h $@
-
-.o:
- @echo CC -o $@
- @${CC} -o $@ $< ${LDFLAGS}
-
-clean:
- @echo cleaning
- @rm -f ${BIN} ${OBJ} tabbed-${VERSION}.tar.gz
-
-dist: clean
- @echo creating dist tarball
- @mkdir -p tabbed-${VERSION}
- @cp -R LICENSE Makefile README config.def.h config.mk \
- tabbed.1 arg.h ${SRC} tabbed-${VERSION}
- @tar -cf tabbed-${VERSION}.tar tabbed-${VERSION}
- @gzip tabbed-${VERSION}.tar
- @rm -rf tabbed-${VERSION}
-
-install: all
- @echo installing executable files to ${DESTDIR}${PREFIX}/bin
- @mkdir -p "${DESTDIR}${PREFIX}/bin"
- @cp -f ${BIN} "${DESTDIR}${PREFIX}/bin"
- @chmod 755 "${DESTDIR}${PREFIX}/bin/tabbed"
- @echo installing manual pages to ${DESTDIR}${MANPREFIX}/man1
- @mkdir -p "${DESTDIR}${MANPREFIX}/man1"
- @sed "s/VERSION/${VERSION}/g" < tabbed.1 > "${DESTDIR}${MANPREFIX}/man1/tabbed.1"
- @chmod 644 "${DESTDIR}${MANPREFIX}/man1/tabbed.1"
- @sed "s/VERSION/${VERSION}/g" < xembed.1 > "${DESTDIR}${MANPREFIX}/man1/xembed.1"
- @chmod 644 "${DESTDIR}${MANPREFIX}/man1/xembed.1"
-
-uninstall:
- @echo removing executable files from ${DESTDIR}${PREFIX}/bin
- @rm -f "${DESTDIR}${PREFIX}/bin/tabbed"
- @rm -f "${DESTDIR}${PREFIX}/bin/xembed"
- @echo removing manual pages from ${DESTDIR}${MANPREFIX}/man1
- @rm -f "${DESTDIR}${MANPREFIX}/man1/tabbed.1"
- @rm -f "${DESTDIR}${MANPREFIX}/man1/xembed.1"
-
-.PHONY: all options clean dist install uninstall
diff --git a/.repos/tabbed/README b/.repos/tabbed/README
deleted file mode 100644
index 4ed6bbe..0000000
--- a/.repos/tabbed/README
+++ /dev/null
@@ -1,22 +0,0 @@
-tabbed - generic tabbed interface
-=================================
-tabbed is a simple tabbed X window container.
-
-Requirements
-------------
-In order to build tabbed you need the Xlib header files.
-
-Installation
-------------
-Edit config.mk to match your local setup (tabbed is installed into
-the /usr/local namespace by default).
-
-Afterwards enter the following command to build and install tabbed
-(if necessary as root):
-
- make clean install
-
-Running tabbed
---------------
-See the man page for details.
-
diff --git a/.repos/tabbed/TODO b/.repos/tabbed/TODO
deleted file mode 100644
index 8e1986d..0000000
--- a/.repos/tabbed/TODO
+++ /dev/null
@@ -1,4 +0,0 @@
-# TODO
-* add some way to detach windows
-* add some way to attach windows
-
diff --git a/.repos/tabbed/arg.h b/.repos/tabbed/arg.h
deleted file mode 100644
index ba3fb3f..0000000
--- a/.repos/tabbed/arg.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * 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/.repos/tabbed/config.h b/.repos/tabbed/config.h
deleted file mode 100644
index defa426..0000000
--- a/.repos/tabbed/config.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-
-/* appearance */
-static const char font[] = "monospace:size=9";
-static const char* normbgcolor = "#222222";
-static const char* normfgcolor = "#cccccc";
-static const char* selbgcolor = "#555555";
-static const char* selfgcolor = "#ffffff";
-static const char* urgbgcolor = "#111111";
-static const char* urgfgcolor = "#cc0000";
-static const char before[] = "<";
-static const char after[] = ">";
-static const char titletrim[] = "...";
-static const int tabwidth = 200;
-static const Bool foreground = True;
-static Bool urgentswitch = False;
-
-/*
- * Where to place a new tab when it is opened. When npisrelative is True,
- * then the current position is changed + newposition. If npisrelative
- * is False, then newposition is an absolute position.
- */
-static int newposition = 0;
-static Bool npisrelative = False;
-
-#define SETPROP(p) { \
- .v = (char *[]){ "/bin/sh", "-c", \
- "prop=\"`xwininfo -children -id $1 | grep '^ 0x' |" \
- "sed -e's@^ *\\(0x[0-9a-f]*\\) \"\\([^\"]*\\)\".*@\\1 \\2@' |" \
- "xargs -0 printf %b | dmenu -l 10 -w $1`\" &&" \
- "xprop -id $1 -f $0 8s -set $0 \"$prop\"", \
- p, winid, NULL \
- } \
-}
-
-#define MODKEY ControlMask
-static Key keys[] = {
- /* modifier key function argument */
- { MODKEY|ShiftMask, XK_Return, focusonce, { 0 } },
- { MODKEY|ShiftMask, XK_Return, spawn, { 0 } },
-
- { MODKEY|ShiftMask, XK_l, rotate, { .i = +1 } },
- { MODKEY|ShiftMask, XK_h, rotate, { .i = -1 } },
- { MODKEY|ShiftMask, XK_j, movetab, { .i = -1 } },
- { MODKEY|ShiftMask, XK_k, movetab, { .i = +1 } },
- { MODKEY, XK_Tab, rotate, { .i = 0 } },
-
- { MODKEY, XK_grave, spawn, SETPROP("_TABBED_SELECT_TAB") },
- { MODKEY, XK_1, move, { .i = 0 } },
- { MODKEY, XK_2, move, { .i = 1 } },
- { MODKEY, XK_3, move, { .i = 2 } },
- { MODKEY, XK_4, move, { .i = 3 } },
- { MODKEY, XK_5, move, { .i = 4 } },
- { MODKEY, XK_6, move, { .i = 5 } },
- { MODKEY, XK_7, move, { .i = 6 } },
- { MODKEY, XK_8, move, { .i = 7 } },
- { MODKEY, XK_9, move, { .i = 8 } },
- { MODKEY, XK_0, move, { .i = 9 } },
-
- { MODKEY, XK_q, killclient, { 0 } },
-
- { MODKEY, XK_u, focusurgent, { 0 } },
- { MODKEY|ShiftMask, XK_u, toggle, { .v = (void*) &urgentswitch } },
-
- { 0, XK_F11, fullscreen, { 0 } },
-};
diff --git a/.repos/tabbed/config.mk b/.repos/tabbed/config.mk
deleted file mode 100644
index 29caa84..0000000
--- a/.repos/tabbed/config.mk
+++ /dev/null
@@ -1,33 +0,0 @@
-# tabbed version
-VERSION = 0.6
-
-# Customize below to fit your system
-
-# paths
-PREFIX = /usr/local
-MANPREFIX = ${PREFIX}/share/man
-
-X11INC = /usr/X11R6/include
-X11LIB = /usr/X11R6/lib
-
-# freetype
-FREETYPELIBS = -lfontconfig -lXft
-FREETYPEINC = /usr/include/freetype2
-# OpenBSD (uncomment)
-#FREETYPEINC = ${X11INC}/freetype2
-
-# includes and libs
-INCS = -I. -I/usr/include -I$(X11INC) -I${FREETYPEINC}
-LIBS = -L/usr/lib -lc -L${X11LIB} -lX11 ${FREETYPELIBS}
-
-# flags
-CPPFLAGS = -DVERSION=\"${VERSION}\" -D_DEFAULT_SOURCE
-CFLAGS = -std=c99 -pedantic -Wall -Os ${INCS} ${CPPFLAGS}
-LDFLAGS = -s ${LIBS}
-
-# Solaris
-#CFLAGS = -fast ${INCS} -DVERSION=\"${VERSION}\"
-#LDFLAGS = ${LIBS}
-
-# compiler and linker
-CC = cc
diff --git a/.repos/tabbed/tabbed.1 b/.repos/tabbed/tabbed.1
deleted file mode 100644
index 07bdbd7..0000000
--- a/.repos/tabbed/tabbed.1
+++ /dev/null
@@ -1,171 +0,0 @@
-.TH TABBED 1 tabbed\-VERSION
-.SH NAME
-tabbed \- generic tabbed interface
-.SH SYNOPSIS
-.B tabbed
-.RB [ \-c ]
-.RB [ \-d ]
-.RB [ \-k ]
-.RB [ \-s ]
-.RB [ \-v ]
-.RB [ \-g
-.IR geometry ]
-.RB [ \-n
-.IR name ]
-.RB [ \-p
-.RB [ s {+/-} ] \fIpos\fR ]
-.RB [ \-o
-.IR normbgcol ]
-.RB [ \-O
-.IR normfgcol ]
-.RB [ \-t
-.IR selbgcol ]
-.RB [ \-T
-.IR selfgcol ]
-.RB [ \-u
-.IR urgbgcol ]
-.RB [ \-U
-.IR urgfgcol ]
-.RB [ \-r
-.IR narg ]
-.RI [ "command ..." ]
-.SH DESCRIPTION
-.B tabbed
-is a simple tabbed container for applications which support XEmbed. Tabbed
-will then run the provided command with the xid of tabbed as appended
-argument. (See EXAMPLES.) The automatic spawning of the command can be
-disabled by providing the -s parameter. If no command is provided
-tabbed will just print its xid and run no command.
-.SH OPTIONS
-.TP
-.B \-c
-close tabbed when the last tab is closed. Mutually exclusive with -f.
-.TP
-.B \-d
-detaches tabbed from the terminal and prints its XID to stdout.
-.TP
-.B \-f
-fill up tabbed again by spawning the provided command, when the last tab is
-closed. Mutually exclusive with -c.
-.TP
-.BI \-g " geometry"
-defines the X11 geometry string, which will fixate the height and width of
-tabbed.
-The syntax is
-.RI [=][ width {xX} height ][{+-} xoffset {+-} yoffset ].
-See
-.BR XParseGeometry (3)
-for further details.
-.TP
-.B \-k
-close foreground tabbed client (instead of tabbed and all clients) when
-WM_DELETE_WINDOW is sent.
-.TP
-.BI \-n " name"
-will set the WM_CLASS attribute to
-.I name.
-.TP
-.BR \-p " [" s {+-}] \fIpos\fR
-will set the absolute or relative position of where to start a new tab. When
-.I pos
-is is given without 's' in front it is an absolute position. Then negative
-numbers will be the position from the last tab, where -1 is the last tab.
-If 's' is given, then
-.I pos
-is a relative position to the current selected tab. If this reaches the limits
-of the tabs; those limits then apply.
-.TP
-.BI \-r " narg"
-will replace the
-.I narg
-th argument in
-.I command
-with the window id, rather than appending it to the end.
-.TP
-.B \-s
-will disable automatic spawning of the command.
-.TP
-.BI \-o " normbgcol"
-defines the normal background color.
-.RI # RGB ,
-.RI # RRGGBB ,
-and X color names are supported.
-.TP
-.BI \-O " normfgcol"
-defines the normal foreground color.
-.TP
-.BI \-t " selbgcol"
-defines the selected background color.
-.TP
-.BI \-T " selfgbcol"
-defines the selected foreground color.
-.TP
-.BI \-u " urgbgcol"
-defines the urgent background color.
-.TP
-.BI \-U " urgfgbcol"
-defines the urgent foreground color.
-.TP
-.B \-v
-prints version information to stderr, then exits.
-.SH USAGE
-.TP
-.B Ctrl\-Shift\-Return
-open new tab
-.TP
-.B Ctrl\-Shift\-h
-previous tab
-.TP
-.B Ctrl\-Shift\-l
-next tab
-.TP
-.B Ctrl\-Shift\-j
-move selected tab one to the left
-.TP
-.B Ctrl\-Shift\-k
-move selected tab one to the right
-.TP
-.B Ctrl\-Shift\-u
-toggle autofocus of urgent tabs
-.TP
-.B Ctrl\-Tab
-toggle between the selected and last selected tab
-.TP
-.B Ctrl\-`
-open dmenu to either create a new tab appending the entered string or select
-an already existing tab.
-.TP
-.B Ctrl\-q
-close tab
-.TP
-.B Ctrl\-u
-focus next urgent tab
-.TP
-.B Ctrl\-[0..9]
-jumps to nth tab
-.TP
-.B F11
-Toggle fullscreen mode.
-.SH EXAMPLES
-$ tabbed surf -e
-.TP
-$ tabbed urxvt -embed
-.TP
-$ tabbed xterm -into
-.TP
-$ $(tabbed -d >/tmp/tabbed.xid); urxvt -embed $(</tmp/tabbed.xid);
-.TP
-$ tabbed -r 2 st -w '' -e tmux
-.SH CUSTOMIZATION
-.B tabbed
-can be customized by creating a custom config.h and (re)compiling the source
-code. This keeps it fast, secure and simple.
-.SH AUTHORS
-See the LICENSE file for the authors.
-.SH LICENSE
-See the LICENSE file for the terms of redistribution.
-.SH SEE ALSO
-.BR st (1),
-.BR xembed (1)
-.SH BUGS
-Please report them.
diff --git a/.repos/tabbed/tabbed.c b/.repos/tabbed/tabbed.c
deleted file mode 100644
index ff3ada0..0000000
--- a/.repos/tabbed/tabbed.c
+++ /dev/null
@@ -1,1366 +0,0 @@
-/*
- * See LICENSE file for copyright and license details.
- */
-
-#include <sys/wait.h>
-#include <locale.h>
-#include <signal.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <X11/Xatom.h>
-#include <X11/Xlib.h>
-#include <X11/Xproto.h>
-#include <X11/Xutil.h>
-#include <X11/XKBlib.h>
-#include <X11/Xft/Xft.h>
-
-#include "arg.h"
-
-/* XEMBED messages */
-#define XEMBED_EMBEDDED_NOTIFY 0
-#define XEMBED_WINDOW_ACTIVATE 1
-#define XEMBED_WINDOW_DEACTIVATE 2
-#define XEMBED_REQUEST_FOCUS 3
-#define XEMBED_FOCUS_IN 4
-#define XEMBED_FOCUS_OUT 5
-#define XEMBED_FOCUS_NEXT 6
-#define XEMBED_FOCUS_PREV 7
-/* 8-9 were used for XEMBED_GRAB_KEY/XEMBED_UNGRAB_KEY */
-#define XEMBED_MODALITY_ON 10
-#define XEMBED_MODALITY_OFF 11
-#define XEMBED_REGISTER_ACCELERATOR 12
-#define XEMBED_UNREGISTER_ACCELERATOR 13
-#define XEMBED_ACTIVATE_ACCELERATOR 14
-
-/* Details for XEMBED_FOCUS_IN: */
-#define XEMBED_FOCUS_CURRENT 0
-#define XEMBED_FOCUS_FIRST 1
-#define XEMBED_FOCUS_LAST 2
-
-/* Macros */
-#define MAX(a, b) ((a) > (b) ? (a) : (b))
-#define MIN(a, b) ((a) < (b) ? (a) : (b))
-#define LENGTH(x) (sizeof((x)) / sizeof(*(x)))
-#define CLEANMASK(mask) (mask & ~(numlockmask | LockMask))
-#define TEXTW(x) (textnw(x, strlen(x)) + dc.font.height)
-
-enum { ColFG, ColBG, ColLast }; /* color */
-enum { WMProtocols, WMDelete, WMName, WMState, WMFullscreen,
- XEmbed, WMSelectTab, WMLast }; /* default atoms */
-
-typedef union {
- int i;
- const void *v;
-} Arg;
-
-typedef struct {
- unsigned int mod;
- KeySym keysym;
- void (*func)(const Arg *);
- const Arg arg;
-} Key;
-
-typedef struct {
- int x, y, w, h;
- XftColor norm[ColLast];
- XftColor sel[ColLast];
- XftColor urg[ColLast];
- Drawable drawable;
- GC gc;
- struct {
- int ascent;
- int descent;
- int height;
- XftFont *xfont;
- } font;
-} DC; /* draw context */
-
-typedef struct {
- char name[256];
- Window win;
- int tabx;
- Bool urgent;
- Bool closed;
-} Client;
-
-/* function declarations */
-static void buttonpress(const XEvent *e);
-static void cleanup(void);
-static void clientmessage(const XEvent *e);
-static void configurenotify(const XEvent *e);
-static void configurerequest(const XEvent *e);
-static void createnotify(const XEvent *e);
-static void destroynotify(const XEvent *e);
-static void die(const char *errstr, ...);
-static void drawbar(void);
-static void drawtext(const char *text, XftColor col[ColLast]);
-static void *ecalloc(size_t n, size_t size);
-static void *erealloc(void *o, size_t size);
-static void expose(const XEvent *e);
-static void focus(int c);
-static void focusin(const XEvent *e);
-static void focusonce(const Arg *arg);
-static void focusurgent(const Arg *arg);
-static void fullscreen(const Arg *arg);
-static char *getatom(int a);
-static int getclient(Window w);
-static XftColor getcolor(const char *colstr);
-static int getfirsttab(void);
-static Bool gettextprop(Window w, Atom atom, char *text, unsigned int size);
-static void initfont(const char *fontstr);
-static Bool isprotodel(int c);
-static void keypress(const XEvent *e);
-static void killclient(const Arg *arg);
-static void manage(Window win);
-static void maprequest(const XEvent *e);
-static void move(const Arg *arg);
-static void movetab(const Arg *arg);
-static void propertynotify(const XEvent *e);
-static void resize(int c, int w, int h);
-static void rotate(const Arg *arg);
-static void run(void);
-static void sendxembed(int c, long msg, long detail, long d1, long d2);
-static void setcmd(int argc, char *argv[], int);
-static void setup(void);
-static void sigchld(int unused);
-static void spawn(const Arg *arg);
-static int textnw(const char *text, unsigned int len);
-static void toggle(const Arg *arg);
-static void unmanage(int c);
-static void unmapnotify(const XEvent *e);
-static void updatenumlockmask(void);
-static void updatetitle(int c);
-static int xerror(Display *dpy, XErrorEvent *ee);
-static void xsettitle(Window w, const char *str);
-
-/* variables */
-static int screen;
-static void (*handler[LASTEvent]) (const XEvent *) = {
- [ButtonPress] = buttonpress,
- [ClientMessage] = clientmessage,
- [ConfigureNotify] = configurenotify,
- [ConfigureRequest] = configurerequest,
- [CreateNotify] = createnotify,
- [UnmapNotify] = unmapnotify,
- [DestroyNotify] = destroynotify,
- [Expose] = expose,
- [FocusIn] = focusin,
- [KeyPress] = keypress,
- [MapRequest] = maprequest,
- [PropertyNotify] = propertynotify,
-};
-static int bh, wx, wy, ww, wh;
-static unsigned int numlockmask;
-static Bool running = True, nextfocus, doinitspawn = True,
- fillagain = False, closelastclient = False,
- killclientsfirst = False;
-static Display *dpy;
-static DC dc;
-static Atom wmatom[WMLast];
-static Window root, win;
-static Client **clients;
-static int nclients, sel = -1, lastsel = -1;
-static int (*xerrorxlib)(Display *, XErrorEvent *);
-static int cmd_append_pos;
-static char winid[64];
-static char **cmd;
-static char *wmname = "tabbed";
-static const char *geometry;
-
-char *argv0;
-
-/* configuration, allows nested code to access above variables */
-#include "config.h"
-
-void
-buttonpress(const XEvent *e)
-{
- const XButtonPressedEvent *ev = &e->xbutton;
- int i, fc;
- Arg arg;
-
- if (ev->y < 0 || ev->y > bh)
- return;
-
- if (((fc = getfirsttab()) > 0 && ev->x < TEXTW(before)) || ev->x < 0)
- return;
-
- for (i = fc; i < nclients; i++) {
- if (clients[i]->tabx > ev->x) {
- switch (ev->button) {
- case Button1:
- focus(i);
- break;
- case Button2:
- focus(i);
- killclient(NULL);
- break;
- case Button4: /* FALLTHROUGH */
- case Button5:
- arg.i = ev->button == Button4 ? -1 : 1;
- rotate(&arg);
- break;
- }
- break;
- }
- }
-}
-
-void
-cleanup(void)
-{
- int i;
-
- for (i = 0; i < nclients; i++) {
- focus(i);
- killclient(NULL);
- XReparentWindow(dpy, clients[i]->win, root, 0, 0);
- unmanage(i);
- }
- free(clients);
- clients = NULL;
-
- XFreePixmap(dpy, dc.drawable);
- XFreeGC(dpy, dc.gc);
- XDestroyWindow(dpy, win);
- XSync(dpy, False);
- free(cmd);
-}
-
-void
-clientmessage(const XEvent *e)
-{
- const XClientMessageEvent *ev = &e->xclient;
-
- if (ev->message_type == wmatom[WMProtocols] &&
- ev->data.l[0] == wmatom[WMDelete]) {
- if (nclients > 1 && killclientsfirst) {
- killclient(0);
- return;
- }
- running = False;
- }
-}
-
-void
-configurenotify(const XEvent *e)
-{
- const XConfigureEvent *ev = &e->xconfigure;
-
- if (ev->window == win && (ev->width != ww || ev->height != wh)) {
- ww = ev->width;
- wh = ev->height;
- XFreePixmap(dpy, dc.drawable);
- dc.drawable = XCreatePixmap(dpy, root, ww, wh,
- DefaultDepth(dpy, screen));
- if (sel > -1)
- resize(sel, ww, wh - bh);
- XSync(dpy, False);
- }
-}
-
-void
-configurerequest(const XEvent *e)
-{
- const XConfigureRequestEvent *ev = &e->xconfigurerequest;
- XWindowChanges wc;
- int c;
-
- if ((c = getclient(ev->window)) > -1) {
- wc.x = 0;
- wc.y = bh;
- wc.width = ww;
- wc.height = wh - bh;
- wc.border_width = 0;
- wc.sibling = ev->above;
- wc.stack_mode = ev->detail;
- XConfigureWindow(dpy, clients[c]->win, ev->value_mask, &wc);
- }
-}
-
-void
-createnotify(const XEvent *e)
-{
- const XCreateWindowEvent *ev = &e->xcreatewindow;
-
- if (ev->window != win && getclient(ev->window) < 0)
- manage(ev->window);
-}
-
-void
-destroynotify(const XEvent *e)
-{
- const XDestroyWindowEvent *ev = &e->xdestroywindow;
- int c;
-
- if ((c = getclient(ev->window)) > -1)
- unmanage(c);
-}
-
-void
-die(const char *errstr, ...)
-{
- va_list ap;
-
- va_start(ap, errstr);
- vfprintf(stderr, errstr, ap);
- va_end(ap);
- exit(EXIT_FAILURE);
-}
-
-void
-drawbar(void)
-{
- XftColor *col;
- int c, cc, fc, width;
- char *name = NULL;
-
- if (nclients == 0) {
- dc.x = 0;
- dc.w = ww;
- XFetchName(dpy, win, &name);
- drawtext(name ? name : "", dc.norm);
- XCopyArea(dpy, dc.drawable, win, dc.gc, 0, 0, ww, bh, 0, 0);
- XSync(dpy, False);
-
- return;
- }
-
- width = ww;
- cc = ww / tabwidth;
- if (nclients > cc)
- cc = (ww - TEXTW(before) - TEXTW(after)) / tabwidth;
-
- if ((fc = getfirsttab()) + cc < nclients) {
- dc.w = TEXTW(after);
- dc.x = width - dc.w;
- drawtext(after, dc.sel);
- width -= dc.w;
- }
- dc.x = 0;
-
- if (fc > 0) {
- dc.w = TEXTW(before);
- drawtext(before, dc.sel);
- dc.x += dc.w;
- width -= dc.w;
- }
-
- cc = MIN(cc, nclients);
- for (c = fc; c < fc + cc; c++) {
- dc.w = width / cc;
- if (c == sel) {
- col = dc.sel;
- dc.w += width % cc;
- } else {
- col = clients[c]->urgent ? dc.urg : dc.norm;
- }
- drawtext(clients[c]->name, col);
- dc.x += dc.w;
- clients[c]->tabx = dc.x;
- }
- XCopyArea(dpy, dc.drawable, win, dc.gc, 0, 0, ww, bh, 0, 0);
- XSync(dpy, False);
-}
-
-void
-drawtext(const char *text, XftColor col[ColLast])
-{
- int i, j, x, y, h, len, olen;
- char buf[256];
- XftDraw *d;
- XRectangle r = { dc.x, dc.y, dc.w, dc.h };
-
- XSetForeground(dpy, dc.gc, col[ColBG].pixel);
- XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1);
- if (!text)
- return;
-
- olen = strlen(text);
- h = dc.font.ascent + dc.font.descent;
- y = dc.y + (dc.h / 2) - (h / 2) + dc.font.ascent;
- x = dc.x + (h / 2);
-
- /* shorten text if necessary */
- for (len = MIN(olen, sizeof(buf));
- len && textnw(text, len) > dc.w - h; len--);
-
- if (!len)
- return;
-
- memcpy(buf, text, len);
- if (len < olen) {
- for (i = len, j = strlen(titletrim); j && i;
- buf[--i] = titletrim[--j])
- ;
- }
-
- d = XftDrawCreate(dpy, dc.drawable, DefaultVisual(dpy, screen), DefaultColormap(dpy, screen));
- XftDrawStringUtf8(d, &col[ColFG], dc.font.xfont, x, y, (XftChar8 *) buf, len);
- XftDrawDestroy(d);
-}
-
-void *
-ecalloc(size_t n, size_t size)
-{
- void *p;
-
- if (!(p = calloc(n, size)))
- die("%s: cannot calloc\n", argv0);
- return p;
-}
-
-void *
-erealloc(void *o, size_t size)
-{
- void *p;
-
- if (!(p = realloc(o, size)))
- die("%s: cannot realloc\n", argv0);
- return p;
-}
-
-void
-expose(const XEvent *e)
-{
- const XExposeEvent *ev = &e->xexpose;
-
- if (ev->count == 0 && win == ev->window)
- drawbar();
-}
-
-void
-focus(int c)
-{
- char buf[BUFSIZ] = "tabbed-"VERSION" ::";
- size_t i, n;
- XWMHints* wmh;
-
- /* If c, sel and clients are -1, raise tabbed-win itself */
- if (nclients == 0) {
- cmd[cmd_append_pos] = NULL;
- for(i = 0, n = strlen(buf); cmd[i] && n < sizeof(buf); i++)
- n += snprintf(&buf[n], sizeof(buf) - n, " %s", cmd[i]);
-
- xsettitle(win, buf);
- XRaiseWindow(dpy, win);
-
- return;
- }
-
- if (c < 0 || c >= nclients)
- return;
-
- resize(c, ww, wh - bh);
- XRaiseWindow(dpy, clients[c]->win);
- XSetInputFocus(dpy, clients[c]->win, RevertToParent, CurrentTime);
- sendxembed(c, XEMBED_FOCUS_IN, XEMBED_FOCUS_CURRENT, 0, 0);
- sendxembed(c, XEMBED_WINDOW_ACTIVATE, 0, 0, 0);
- xsettitle(win, clients[c]->name);
-
- if (sel != c) {
- lastsel = sel;
- sel = c;
- }
-
- if (clients[c]->urgent && (wmh = XGetWMHints(dpy, clients[c]->win))) {
- wmh->flags &= ~XUrgencyHint;
- XSetWMHints(dpy, clients[c]->win, wmh);
- clients[c]->urgent = False;
- XFree(wmh);
- }
-
- drawbar();
- XSync(dpy, False);
-}
-
-void
-focusin(const XEvent *e)
-{
- const XFocusChangeEvent *ev = &e->xfocus;
- int dummy;
- Window focused;
-
- if (ev->mode != NotifyUngrab) {
- XGetInputFocus(dpy, &focused, &dummy);
- if (focused == win)
- focus(sel);
- }
-}
-
-void
-focusonce(const Arg *arg)
-{
- nextfocus = True;
-}
-
-void
-focusurgent(const Arg *arg)
-{
- int c;
-
- if (sel < 0)
- return;
-
- for (c = (sel + 1) % nclients; c != sel; c = (c + 1) % nclients) {
- if (clients[c]->urgent) {
- focus(c);
- return;
- }
- }
-}
-
-void
-fullscreen(const Arg *arg)
-{
- XEvent e;
-
- e.type = ClientMessage;
- e.xclient.window = win;
- e.xclient.message_type = wmatom[WMState];
- e.xclient.format = 32;
- e.xclient.data.l[0] = 2;
- e.xclient.data.l[1] = wmatom[WMFullscreen];
- e.xclient.data.l[2] = 0;
- XSendEvent(dpy, root, False, SubstructureNotifyMask, &e);
-}
-
-char *
-getatom(int a)
-{
- static char buf[BUFSIZ];
- Atom adummy;
- int idummy;
- unsigned long ldummy;
- unsigned char *p = NULL;
-
- XGetWindowProperty(dpy, win, wmatom[a], 0L, BUFSIZ, False, XA_STRING,
- &adummy, &idummy, &ldummy, &ldummy, &p);
- if (p)
- strncpy(buf, (char *)p, LENGTH(buf)-1);
- else
- buf[0] = '\0';
- XFree(p);
-
- return buf;
-}
-
-int
-getclient(Window w)
-{
- int i;
-
- for (i = 0; i < nclients; i++) {
- if (clients[i]->win == w)
- return i;
- }
-
- return -1;
-}
-
-XftColor
-getcolor(const char *colstr)
-{
- XftColor color;
-
- if (!XftColorAllocName(dpy, DefaultVisual(dpy, screen), DefaultColormap(dpy, screen), colstr, &color))
- die("%s: cannot allocate color '%s'\n", argv0, colstr);
-
- return color;
-}
-
-int
-getfirsttab(void)
-{
- int cc, ret;
-
- if (sel < 0)
- return 0;
-
- cc = ww / tabwidth;
- if (nclients > cc)
- cc = (ww - TEXTW(before) - TEXTW(after)) / tabwidth;
-
- ret = sel - cc / 2 + (cc + 1) % 2;
- return ret < 0 ? 0 :
- ret + cc > nclients ? MAX(0, nclients - cc) :
- ret;
-}
-
-Bool
-gettextprop(Window w, Atom atom, char *text, unsigned int size)
-{
- char **list = NULL;
- int n;
- XTextProperty name;
-
- if (!text || size == 0)
- return False;
-
- text[0] = '\0';
- XGetTextProperty(dpy, w, &name, atom);
- if (!name.nitems)
- return False;
-
- if (name.encoding == XA_STRING) {
- strncpy(text, (char *)name.value, size - 1);
- } else if (XmbTextPropertyToTextList(dpy, &name, &list, &n) >= Success
- && n > 0 && *list) {
- strncpy(text, *list, size - 1);
- XFreeStringList(list);
- }
- text[size - 1] = '\0';
- XFree(name.value);
-
- return True;
-}
-
-void
-initfont(const char *fontstr)
-{
- if (!(dc.font.xfont = XftFontOpenName(dpy, screen, fontstr))
- && !(dc.font.xfont = XftFontOpenName(dpy, screen, "fixed")))
- die("error, cannot load font: '%s'\n", fontstr);
-
- dc.font.ascent = dc.font.xfont->ascent;
- dc.font.descent = dc.font.xfont->descent;
- dc.font.height = dc.font.ascent + dc.font.descent;
-}
-
-Bool
-isprotodel(int c)
-{
- int i, n;
- Atom *protocols;
- Bool ret = False;
-
- if (XGetWMProtocols(dpy, clients[c]->win, &protocols, &n)) {
- for (i = 0; !ret && i < n; i++) {
- if (protocols[i] == wmatom[WMDelete])
- ret = True;
- }
- XFree(protocols);
- }
-
- return ret;
-}
-
-void
-keypress(const XEvent *e)
-{
- const XKeyEvent *ev = &e->xkey;
- unsigned int i;
- KeySym keysym;
-
- keysym = XkbKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0, 0);
- for (i = 0; i < LENGTH(keys); i++) {
- if (keysym == keys[i].keysym &&
- CLEANMASK(keys[i].mod) == CLEANMASK(ev->state) &&
- keys[i].func)
- keys[i].func(&(keys[i].arg));
- }
-}
-
-void
-killclient(const Arg *arg)
-{
- XEvent ev;
-
- if (sel < 0)
- return;
-
- if (isprotodel(sel) && !clients[sel]->closed) {
- ev.type = ClientMessage;
- ev.xclient.window = clients[sel]->win;
- ev.xclient.message_type = wmatom[WMProtocols];
- ev.xclient.format = 32;
- ev.xclient.data.l[0] = wmatom[WMDelete];
- ev.xclient.data.l[1] = CurrentTime;
- XSendEvent(dpy, clients[sel]->win, False, NoEventMask, &ev);
- clients[sel]->closed = True;
- } else {
- XKillClient(dpy, clients[sel]->win);
- }
-}
-
-void
-manage(Window w)
-{
- updatenumlockmask();
- {
- int i, j, nextpos;
- unsigned int modifiers[] = { 0, LockMask, numlockmask,
- numlockmask | LockMask };
- KeyCode code;
- Client *c;
- XEvent e;
-
- XWithdrawWindow(dpy, w, 0);
- XReparentWindow(dpy, w, win, 0, bh);
- XSelectInput(dpy, w, PropertyChangeMask |
- StructureNotifyMask | EnterWindowMask);
- XSync(dpy, False);
-
- for (i = 0; i < LENGTH(keys); i++) {
- if ((code = XKeysymToKeycode(dpy, keys[i].keysym))) {
- for (j = 0; j < LENGTH(modifiers); j++) {
- XGrabKey(dpy, code, keys[i].mod |
- modifiers[j], w, True,
- GrabModeAsync, GrabModeAsync);
- }
- }
- }
-
- c = ecalloc(1, sizeof *c);
- c->win = w;
-
- nclients++;
- clients = erealloc(clients, sizeof(Client *) * nclients);
-
- if(npisrelative) {
- nextpos = sel + newposition;
- } else {
- if (newposition < 0)
- nextpos = nclients - newposition;
- else
- nextpos = newposition;
- }
- if (nextpos >= nclients)
- nextpos = nclients - 1;
- if (nextpos < 0)
- nextpos = 0;
-
- if (nclients > 1 && nextpos < nclients - 1)
- memmove(&clients[nextpos + 1], &clients[nextpos],
- sizeof(Client *) * (nclients - nextpos - 1));
-
- clients[nextpos] = c;
- updatetitle(nextpos);
-
- XLowerWindow(dpy, w);
- XMapWindow(dpy, w);
-
- e.xclient.window = w;
- e.xclient.type = ClientMessage;
- e.xclient.message_type = wmatom[XEmbed];
- e.xclient.format = 32;
- e.xclient.data.l[0] = CurrentTime;
- e.xclient.data.l[1] = XEMBED_EMBEDDED_NOTIFY;
- e.xclient.data.l[2] = 0;
- e.xclient.data.l[3] = win;
- e.xclient.data.l[4] = 0;
- XSendEvent(dpy, root, False, NoEventMask, &e);
-
- XSync(dpy, False);
-
- /* Adjust sel before focus does set it to lastsel. */
- if (sel >= nextpos)
- sel++;
- focus(nextfocus ? nextpos :
- sel < 0 ? 0 :
- sel);
- nextfocus = foreground;
- }
-}
-
-void
-maprequest(const XEvent *e)
-{
- const XMapRequestEvent *ev = &e->xmaprequest;
-
- if (getclient(ev->window) < 0)
- manage(ev->window);
-}
-
-void
-move(const Arg *arg)
-{
- if (arg->i >= 0 && arg->i < nclients)
- focus(arg->i);
-}
-
-void
-movetab(const Arg *arg)
-{
- int c;
- Client *new;
-
- if (sel < 0)
- return;
-
- c = (sel + arg->i) % nclients;
- if (c < 0)
- c += nclients;
-
- if (c == sel)
- return;
-
- new = clients[sel];
- if (sel < c)
- memmove(&clients[sel], &clients[sel+1],
- sizeof(Client *) * (c - sel));
- else
- memmove(&clients[c+1], &clients[c],
- sizeof(Client *) * (sel - c));
- clients[c] = new;
- sel = c;
-
- drawbar();
-}
-
-void
-propertynotify(const XEvent *e)
-{
- const XPropertyEvent *ev = &e->xproperty;
- XWMHints *wmh;
- int c;
- char* selection = NULL;
- Arg arg;
-
- if (ev->state == PropertyNewValue && ev->atom == wmatom[WMSelectTab]) {
- selection = getatom(WMSelectTab);
- if (!strncmp(selection, "0x", 2)) {
- arg.i = getclient(strtoul(selection, NULL, 0));
- move(&arg);
- } else {
- cmd[cmd_append_pos] = selection;
- arg.v = cmd;
- spawn(&arg);
- }
- } else if (ev->state == PropertyNewValue && ev->atom == XA_WM_HINTS &&
- (c = getclient(ev->window)) > -1 &&
- (wmh = XGetWMHints(dpy, clients[c]->win))) {
- if (wmh->flags & XUrgencyHint) {
- XFree(wmh);
- wmh = XGetWMHints(dpy, win);
- if (c != sel) {
- if (urgentswitch && wmh &&
- !(wmh->flags & XUrgencyHint)) {
- /* only switch, if tabbed was focused
- * since last urgency hint if WMHints
- * could not be received,
- * default to no switch */
- focus(c);
- } else {
- /* if no switch should be performed,
- * mark tab as urgent */
- clients[c]->urgent = True;
- drawbar();
- }
- }
- if (wmh && !(wmh->flags & XUrgencyHint)) {
- /* update tabbed urgency hint
- * if not set already */
- wmh->flags |= XUrgencyHint;
- XSetWMHints(dpy, win, wmh);
- }
- }
- XFree(wmh);
- } else if (ev->state != PropertyDelete && ev->atom == XA_WM_NAME &&
- (c = getclient(ev->window)) > -1) {
- updatetitle(c);
- }
-}
-
-void
-resize(int c, int w, int h)
-{
- XConfigureEvent ce;
- XWindowChanges wc;
-
- ce.x = 0;
- ce.y = bh;
- ce.width = wc.width = w;
- ce.height = wc.height = h;
- ce.type = ConfigureNotify;
- ce.display = dpy;
- ce.event = clients[c]->win;
- ce.window = clients[c]->win;
- ce.above = None;
- ce.override_redirect = False;
- ce.border_width = 0;
-
- XConfigureWindow(dpy, clients[c]->win, CWWidth | CWHeight, &wc);
- XSendEvent(dpy, clients[c]->win, False, StructureNotifyMask,
- (XEvent *)&ce);
-}
-
-void
-rotate(const Arg *arg)
-{
- int nsel = -1;
-
- if (sel < 0)
- return;
-
- if (arg->i == 0) {
- if (lastsel > -1)
- focus(lastsel);
- } else if (sel > -1) {
- /* Rotating in an arg->i step around the clients. */
- nsel = sel + arg->i;
- while (nsel >= nclients)
- nsel -= nclients;
- while (nsel < 0)
- nsel += nclients;
- focus(nsel);
- }
-}
-
-void
-run(void)
-{
- XEvent ev;
-
- /* main event loop */
- XSync(dpy, False);
- drawbar();
- if (doinitspawn == True)
- spawn(NULL);
-
- while (running) {
- XNextEvent(dpy, &ev);
- if (handler[ev.type])
- (handler[ev.type])(&ev); /* call handler */
- }
-}
-
-void
-sendxembed(int c, long msg, long detail, long d1, long d2)
-{
- XEvent e = { 0 };
-
- e.xclient.window = clients[c]->win;
- e.xclient.type = ClientMessage;
- e.xclient.message_type = wmatom[XEmbed];
- e.xclient.format = 32;
- e.xclient.data.l[0] = CurrentTime;
- e.xclient.data.l[1] = msg;
- e.xclient.data.l[2] = detail;
- e.xclient.data.l[3] = d1;
- e.xclient.data.l[4] = d2;
- XSendEvent(dpy, clients[c]->win, False, NoEventMask, &e);
-}
-
-void
-setcmd(int argc, char *argv[], int replace)
-{
- int i;
-
- cmd = ecalloc(argc + 3, sizeof(*cmd));
- if (argc == 0)
- return;
- for (i = 0; i < argc; i++)
- cmd[i] = argv[i];
- cmd[replace > 0 ? replace : argc] = winid;
- cmd_append_pos = argc + !replace;
- cmd[cmd_append_pos] = cmd[cmd_append_pos + 1] = NULL;
-}
-
-void
-setup(void)
-{
- int bitm, tx, ty, tw, th, dh, dw, isfixed;
- XWMHints *wmh;
- XClassHint class_hint;
- XSizeHints *size_hint;
-
- /* clean up any zombies immediately */
- sigchld(0);
-
- /* init screen */
- screen = DefaultScreen(dpy);
- root = RootWindow(dpy, screen);
- initfont(font);
- bh = dc.h = dc.font.height + 2;
-
- /* init atoms */
- wmatom[WMDelete] = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
- wmatom[WMFullscreen] = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN",
- False);
- wmatom[WMName] = XInternAtom(dpy, "_NET_WM_NAME", False);
- wmatom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False);
- wmatom[WMSelectTab] = XInternAtom(dpy, "_TABBED_SELECT_TAB", False);
- wmatom[WMState] = XInternAtom(dpy, "_NET_WM_STATE", False);
- wmatom[XEmbed] = XInternAtom(dpy, "_XEMBED", False);
-
- /* init appearance */
- wx = 0;
- wy = 0;
- ww = 800;
- wh = 600;
- isfixed = 0;
-
- if (geometry) {
- tx = ty = tw = th = 0;
- bitm = XParseGeometry(geometry, &tx, &ty, (unsigned *)&tw,
- (unsigned *)&th);
- if (bitm & XValue)
- wx = tx;
- if (bitm & YValue)
- wy = ty;
- if (bitm & WidthValue)
- ww = tw;
- if (bitm & HeightValue)
- wh = th;
- if (bitm & XNegative && wx == 0)
- wx = -1;
- if (bitm & YNegative && wy == 0)
- wy = -1;
- if (bitm & (HeightValue | WidthValue))
- isfixed = 1;
-
- dw = DisplayWidth(dpy, screen);
- dh = DisplayHeight(dpy, screen);
- if (wx < 0)
- wx = dw + wx - ww - 1;
- if (wy < 0)
- wy = dh + wy - wh - 1;
- }
-
- dc.norm[ColBG] = getcolor(normbgcolor);
- dc.norm[ColFG] = getcolor(normfgcolor);
- dc.sel[ColBG] = getcolor(selbgcolor);
- dc.sel[ColFG] = getcolor(selfgcolor);
- dc.urg[ColBG] = getcolor(urgbgcolor);
- dc.urg[ColFG] = getcolor(urgfgcolor);
- dc.drawable = XCreatePixmap(dpy, root, ww, wh,
- DefaultDepth(dpy, screen));
- dc.gc = XCreateGC(dpy, root, 0, 0);
-
- win = XCreateSimpleWindow(dpy, root, wx, wy, ww, wh, 0,
- dc.norm[ColFG].pixel, dc.norm[ColBG].pixel);
- XMapRaised(dpy, win);
- XSelectInput(dpy, win, SubstructureNotifyMask | FocusChangeMask |
- ButtonPressMask | ExposureMask | KeyPressMask |
- PropertyChangeMask | StructureNotifyMask |
- SubstructureRedirectMask);
- xerrorxlib = XSetErrorHandler(xerror);
-
- class_hint.res_name = wmname;
- class_hint.res_class = "tabbed";
- XSetClassHint(dpy, win, &class_hint);
-
- size_hint = XAllocSizeHints();
- if (!isfixed) {
- size_hint->flags = PSize;
- size_hint->height = wh;
- size_hint->width = ww;
- } else {
- size_hint->flags = PMaxSize | PMinSize;
- size_hint->min_width = size_hint->max_width = ww;
- size_hint->min_height = size_hint->max_height = wh;
- }
- wmh = XAllocWMHints();
- XSetWMProperties(dpy, win, NULL, NULL, NULL, 0, size_hint, wmh, NULL);
- XFree(size_hint);
- XFree(wmh);
-
- XSetWMProtocols(dpy, win, &wmatom[WMDelete], 1);
-
- snprintf(winid, sizeof(winid), "%lu", win);
- setenv("XEMBED", winid, 1);
-
- nextfocus = foreground;
- focus(-1);
-}
-
-void
-sigchld(int unused)
-{
- if (signal(SIGCHLD, sigchld) == SIG_ERR)
- die("%s: cannot install SIGCHLD handler", argv0);
-
- while (0 < waitpid(-1, NULL, WNOHANG));
-}
-
-void
-spawn(const Arg *arg)
-{
- if (fork() == 0) {
- if(dpy)
- close(ConnectionNumber(dpy));
-
- setsid();
- if (arg && arg->v) {
- execvp(((char **)arg->v)[0], (char **)arg->v);
- fprintf(stderr, "%s: execvp %s", argv0,
- ((char **)arg->v)[0]);
- } else {
- cmd[cmd_append_pos] = NULL;
- execvp(cmd[0], cmd);
- fprintf(stderr, "%s: execvp %s", argv0, cmd[0]);
- }
- perror(" failed");
- exit(0);
- }
-}
-
-int
-textnw(const char *text, unsigned int len)
-{
- XGlyphInfo ext;
- XftTextExtentsUtf8(dpy, dc.font.xfont, (XftChar8 *) text, len, &ext);
- return ext.xOff;
-}
-
-void
-toggle(const Arg *arg)
-{
- *(Bool*) arg->v = !*(Bool*) arg->v;
-}
-
-void
-unmanage(int c)
-{
- if (c < 0 || c >= nclients) {
- drawbar();
- XSync(dpy, False);
- return;
- }
-
- if (!nclients)
- return;
-
- if (c == 0) {
- /* First client. */
- nclients--;
- free(clients[0]);
- memmove(&clients[0], &clients[1], sizeof(Client *) * nclients);
- } else if (c == nclients - 1) {
- /* Last client. */
- nclients--;
- free(clients[c]);
- clients = erealloc(clients, sizeof(Client *) * nclients);
- } else {
- /* Somewhere inbetween. */
- free(clients[c]);
- memmove(&clients[c], &clients[c+1],
- sizeof(Client *) * (nclients - (c + 1)));
- nclients--;
- }
-
- if (nclients <= 0) {
- lastsel = sel = -1;
-
- if (closelastclient)
- running = False;
- else if (fillagain && running)
- spawn(NULL);
- } else {
- if (lastsel >= nclients)
- lastsel = nclients - 1;
- else if (lastsel > c)
- lastsel--;
-
- if (c == sel && lastsel >= 0) {
- focus(lastsel);
- } else {
- if (sel > c)
- sel--;
- if (sel >= nclients)
- sel = nclients - 1;
-
- focus(sel);
- }
- }
-
- drawbar();
- XSync(dpy, False);
-}
-
-void
-unmapnotify(const XEvent *e)
-{
- const XUnmapEvent *ev = &e->xunmap;
- int c;
-
- if ((c = getclient(ev->window)) > -1)
- unmanage(c);
-}
-
-void
-updatenumlockmask(void)
-{
- unsigned int i, j;
- XModifierKeymap *modmap;
-
- numlockmask = 0;
- modmap = XGetModifierMapping(dpy);
- for (i = 0; i < 8; i++) {
- for (j = 0; j < modmap->max_keypermod; j++) {
- if (modmap->modifiermap[i * modmap->max_keypermod + j]
- == XKeysymToKeycode(dpy, XK_Num_Lock))
- numlockmask = (1 << i);
- }
- }
- XFreeModifiermap(modmap);
-}
-
-void
-updatetitle(int c)
-{
- if (!gettextprop(clients[c]->win, wmatom[WMName], clients[c]->name,
- sizeof(clients[c]->name)))
- gettextprop(clients[c]->win, XA_WM_NAME, clients[c]->name,
- sizeof(clients[c]->name));
- if (sel == c)
- xsettitle(win, clients[c]->name);
- drawbar();
-}
-
-/* There's no way to check accesses to destroyed windows, thus those cases are
- * ignored (especially on UnmapNotify's). Other types of errors call Xlibs
- * default error handler, which may call exit. */
-int
-xerror(Display *dpy, XErrorEvent *ee)
-{
- if (ee->error_code == BadWindow
- || (ee->request_code == X_SetInputFocus &&
- ee->error_code == BadMatch)
- || (ee->request_code == X_PolyText8 &&
- ee->error_code == BadDrawable)
- || (ee->request_code == X_PolyFillRectangle &&
- ee->error_code == BadDrawable)
- || (ee->request_code == X_PolySegment &&
- ee->error_code == BadDrawable)
- || (ee->request_code == X_ConfigureWindow &&
- ee->error_code == BadMatch)
- || (ee->request_code == X_GrabButton &&
- ee->error_code == BadAccess)
- || (ee->request_code == X_GrabKey &&
- ee->error_code == BadAccess)
- || (ee->request_code == X_CopyArea &&
- ee->error_code == BadDrawable))
- return 0;
-
- fprintf(stderr, "%s: fatal error: request code=%d, error code=%d\n",
- argv0, ee->request_code, ee->error_code);
- return xerrorxlib(dpy, ee); /* may call exit */
-}
-
-void
-xsettitle(Window w, const char *str)
-{
- XTextProperty xtp;
-
- if (XmbTextListToTextProperty(dpy, (char **)&str, 1,
- XCompoundTextStyle, &xtp) == Success) {
- XSetTextProperty(dpy, w, &xtp, wmatom[WMName]);
- XSetTextProperty(dpy, w, &xtp, XA_WM_NAME);
- XFree(xtp.value);
- }
-}
-
-void
-usage(void)
-{
- die("usage: %s [-dfksv] [-g geometry] [-n name] [-p [s+/-]pos]\n"
- " [-r narg] [-o color] [-O color] [-t color] [-T color]\n"
- " [-u color] [-U color] command...\n", argv0);
-}
-
-int
-main(int argc, char *argv[])
-{
- Bool detach = False;
- int replace = 0;
- char *pstr;
-
- ARGBEGIN {
- case 'c':
- closelastclient = True;
- fillagain = False;
- break;
- case 'd':
- detach = True;
- break;
- case 'f':
- fillagain = True;
- break;
- case 'g':
- geometry = EARGF(usage());
- break;
- case 'k':
- killclientsfirst = True;
- break;
- case 'n':
- wmname = EARGF(usage());
- break;
- case 'O':
- normfgcolor = EARGF(usage());
- break;
- case 'o':
- normbgcolor = EARGF(usage());
- break;
- case 'p':
- pstr = EARGF(usage());
- if (pstr[0] == 's') {
- npisrelative = True;
- newposition = atoi(&pstr[1]);
- } else {
- newposition = atoi(pstr);
- }
- break;
- case 'r':
- replace = atoi(EARGF(usage()));
- break;
- case 's':
- doinitspawn = False;
- break;
- case 'T':
- selfgcolor = EARGF(usage());
- break;
- case 't':
- selbgcolor = EARGF(usage());
- break;
- case 'U':
- urgfgcolor = EARGF(usage());
- break;
- case 'u':
- urgbgcolor = EARGF(usage());
- break;
- case 'v':
- die("tabbed-"VERSION", © 2009-2016 tabbed engineers, "
- "see LICENSE for details.\n");
- break;
- default:
- usage();
- break;
- } ARGEND;
-
- if (argc < 1) {
- doinitspawn = False;
- fillagain = False;
- }
-
- setcmd(argc, argv, replace);
-
- if (!setlocale(LC_CTYPE, "") || !XSupportsLocale())
- fprintf(stderr, "%s: no locale support\n", argv0);
- if (!(dpy = XOpenDisplay(NULL)))
- die("%s: cannot open display\n", argv0);
-
- setup();
- printf("0x%lx\n", win);
- fflush(NULL);
-
- if (detach) {
- if (fork() == 0) {
- fclose(stdout);
- } else {
- if (dpy)
- close(ConnectionNumber(dpy));
- return EXIT_SUCCESS;
- }
- }
-
- run();
- cleanup();
- XCloseDisplay(dpy);
-
- return EXIT_SUCCESS;
-}
diff --git a/.repos/tabbed/xembed.1 b/.repos/tabbed/xembed.1
deleted file mode 100644
index 5b0c28c..0000000
--- a/.repos/tabbed/xembed.1
+++ /dev/null
@@ -1,35 +0,0 @@
-.TH XEMBED 1 tabbed\-VERSION
-.SH NAME
-xembed \- XEmbed foreground process
-.SH SYNOPSIS
-.B xembed
-.I flag command
-.RI [ "argument ..." ]
-.SH DESCRIPTION
-If the environment variable XEMBED is set, and
-.B xembed
-is in the foreground of its controlling tty, it will execute
-.IP
-command flag $XEMBED [argument ...]
-.LP
-Otherwise it will execute
-.IP
-command [argument ...]
-.LP
-.SH EXAMPLE
-In a terminal emulator within a
-.B tabbed
-session, the shell alias
-.IP
-$ alias surf='xembed -e surf'
-.LP
-will cause `surf' to open in a new tab, unless it is run in the background,
-i.e. `surf &', in which case it will instead open in a new window.
-.SH AUTHORS
-See the LICENSE file for the authors.
-.SH LICENSE
-See the LICENSE file for the terms of redistribution.
-.SH SEE ALSO
-.BR tabbed (1)
-.SH BUGS
-Please report them.
diff --git a/.repos/tabbed/xembed.c b/.repos/tabbed/xembed.c
deleted file mode 100644
index cbb0e97..0000000
--- a/.repos/tabbed/xembed.c
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * See LICENSE file for copyright and license details.
- */
-
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-int
-main(int argc, char *argv[])
-{
- char *xembed;
- int tty;
- pid_t pgrp, tcpgrp;
-
- if (argc < 3) {
- fprintf(stderr, "usage: %s flag cmd ...\n", argv[0]);
- return 2;
- }
-
- if (!(xembed = getenv("XEMBED")))
- goto noembed;
-
- if ((tty = open("/dev/tty", O_RDONLY)) < 0)
- goto noembed;
-
- pgrp = getpgrp();
- tcpgrp = tcgetpgrp(tty);
-
- close(tty);
-
- if (pgrp == tcpgrp) { /* in foreground of tty */
- argv[0] = argv[2];
- argv[2] = xembed;
- } else {
-noembed:
- argv += 2;
- }
-
- execvp(argv[0], argv);
-
- perror(argv[0]); /* failed to execute */
- return 1;
-}