summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortslil <tslil@posteo.de>2026-04-04 17:44:21 +0100
committertslil <tslil@posteo.de>2026-04-04 17:47:21 +0100
commit5413fb67d5454666cd4606ac51e8f8d1ae31aa6e (patch)
treeeffd7869b631e1e1a455b65eea1a1f12263b4bba
parent0c860a57966d4c0f4ef817b9c7f378de4623a236 (diff)
cleanup
-rw-r--r--.mg1
-rwxr-xr-x.xinitrc33
-rw-r--r--.zile15
-rw-r--r--alacritty/alacritty.toml21
-rw-r--r--dwl/.gitignore6
-rw-r--r--dwl/bstack.patch179
-rw-r--r--dwl/config.h197
-rw-r--r--dwl/correctly-match-blank-rule-strings.patch35
-rwxr-xr-xdwl/dwl.sh9
-rw-r--r--dwl/laptop_config.h199
-rw-r--r--dwl/pertag.patch167
-rw-r--r--dwl/rmaster.patch27
-rw-r--r--dwm-6.2/LICENSE37
-rw-r--r--dwm-6.2/Makefile51
-rw-r--r--dwm-6.2/README48
-rw-r--r--dwm-6.2/config.def.h129
-rw-r--r--dwm-6.2/config.h163
-rw-r--r--dwm-6.2/config.mk38
-rw-r--r--dwm-6.2/defaultlayoutpermonitor.diff58
-rw-r--r--dwm-6.2/drw.c435
-rw-r--r--dwm-6.2/drw.h57
-rw-r--r--dwm-6.2/dwm-autostart-20200610-cb3f58a.diff179
-rw-r--r--dwm-6.2/dwm-pertag-6.2.diff177
-rw-r--r--dwm-6.2/dwm-systray-6.2.diff746
-rw-r--r--dwm-6.2/dwm.1199
-rw-r--r--dwm-6.2/dwm.c2674
-rw-r--r--dwm-6.2/dwm.pngbin373 -> 0 bytes
-rw-r--r--dwm-6.2/transient.c42
-rw-r--r--dwm-6.2/util.c35
-rw-r--r--dwm-6.2/util.h8
-rw-r--r--kakrc31
-rw-r--r--printer.cfg167
-rw-r--r--qmk_atreus_layout/config.h14
-rw-r--r--qmk_atreus_layout/keymap.c76
-rw-r--r--somebar/.builds/archlinux.yml19
-rw-r--r--somebar/.builds/freebsd.yml20
-rw-r--r--somebar/.editorconfig5
-rw-r--r--somebar/.gitignore4
-rw-r--r--somebar/CHANGELOG.md19
-rw-r--r--somebar/LICENSE20
-rw-r--r--somebar/README.md113
-rw-r--r--somebar/contrib/colorless-status.patch15
-rw-r--r--somebar/contrib/dwm-like-tag-indicator.patch34
-rw-r--r--somebar/contrib/hide-vacant-tags.patch54
-rw-r--r--somebar/contrib/indicator-size-props.patch54
-rw-r--r--somebar/contrib/ipc.patch504
-rw-r--r--somebar/contrib/markup-in-status-messages.patch65
-rw-r--r--somebar/contrib/show-status-on-selected-monitor.patch43
-rw-r--r--somebar/meson.build31
-rw-r--r--somebar/protocols/meson.build22
-rw-r--r--somebar/protocols/wlr-layer-shell-unstable-v1.xml390
-rw-r--r--somebar/screenshot.pngbin6715 -> 0 bytes
-rw-r--r--somebar/somebar.155
-rw-r--r--somebar/src/bar.cpp321
-rw-r--r--somebar/src/bar.hpp74
-rw-r--r--somebar/src/common.hpp76
-rw-r--r--somebar/src/config.def.hpp27
-rw-r--r--somebar/src/config.hpp31
-rw-r--r--somebar/src/line_buffer.hpp71
-rw-r--r--somebar/src/main.cpp613
-rw-r--r--somebar/src/shm_buffer.cpp85
-rw-r--r--somebar/src/shm_buffer.hpp45
-rw-r--r--st-0.8.4/FAQ250
-rw-r--r--st-0.8.4/LEGACY17
-rw-r--r--st-0.8.4/LICENSE34
-rw-r--r--st-0.8.4/Makefile57
-rw-r--r--st-0.8.4/README34
-rw-r--r--st-0.8.4/TODO28
-rw-r--r--st-0.8.4/arg.h50
-rw-r--r--st-0.8.4/config.def.h477
-rw-r--r--st-0.8.4/config.def.h.orig470
-rw-r--r--st-0.8.4/config.h479
-rw-r--r--st-0.8.4/config.mk35
-rw-r--r--st-0.8.4/st-blinking_cursor-20200531-a2a7044.diff150
-rw-r--r--st-0.8.4/st-clipboard-0.8.3.diff12
-rw-r--r--st-0.8.4/st-gruvbox-dark-0.8.2.diff70
-rw-r--r--st-0.8.4/st-scrollback-20200419-72e3f6c.diff351
-rw-r--r--st-0.8.4/st-scrollback-mouse-20191024-a2c479c.diff13
-rw-r--r--st-0.8.4/st-scrollback-mouse-altscreen-20200416-5703aa0.diff63
-rw-r--r--st-0.8.4/st.1177
-rw-r--r--st-0.8.4/st.c2673
-rw-r--r--st-0.8.4/st.c.orig2668
-rw-r--r--st-0.8.4/st.h128
-rw-r--r--st-0.8.4/st.info239
-rw-r--r--st-0.8.4/win.h39
-rw-r--r--st-0.8.4/x.c2074
-rw-r--r--st-0.8.4/x.c.orig2052
-rw-r--r--stumpwm/init.lisp236
-rw-r--r--stumpwm/modules/modeline/fuzzytime/README.org9
-rw-r--r--stumpwm/modules/modeline/fuzzytime/fuzzytime.asd11
-rw-r--r--stumpwm/modules/modeline/fuzzytime/fuzzytime.lisp84
-rw-r--r--stumpwm/modules/modeline/fuzzytime/package.lisp5
-rw-r--r--zile-kill-region-or-backward-kill-word.patch85
93 files changed, 0 insertions, 22133 deletions
diff --git a/.mg b/.mg
deleted file mode 100644
index 0bca62a..0000000
--- a/.mg
+++ /dev/null
@@ -1 +0,0 @@
-make-backup-files
diff --git a/.xinitrc b/.xinitrc
deleted file mode 100755
index a8b9e20..0000000
--- a/.xinitrc
+++ /dev/null
@@ -1,33 +0,0 @@
-internal_keyboard=$(xinput --list | awk '/AT Translated/ { print(substr($7,4)) ; }')
-setxkbmap -device $internal_keyboard -model pc104curl-z -layout us -variant cmk_ed_dh -option terminate:ctrl_alt_bksp -option ctrl:nocaps
-
-# This is to catch lock-session from systemd
-xss-lock lock &
-xset s 300
-
-# No dpms
-xset -dpms
-
-# Themeing
-xrdb -merge ~/.Xdefaults
-xsetroot -cursor_name left_ptr
-
-# Fix screen tearing
-#picom --config ~/.config/picom.conf &
-
-# Physical screen management
-# [[ -f "$HOME/.umonitor.lock" ]] && rm $HOME/.umonitor.lock
-# umonitor --listen --quiet &
-
-# Automatic colour temperature adjustment for Baltimore
-redshift -l +39:-76 &
-
-# Network Manager in tray
-nm-applet &
-
-# PulseAudio in tray
-pasystray &
-
-# The only thing i really need
-dwm_status &
-exec dwm
diff --git a/.zile b/.zile
deleted file mode 100644
index 31189ab..0000000
--- a/.zile
+++ /dev/null
@@ -1,15 +0,0 @@
-;; Rebind keys with:
-;; (global-set-key "key" 'func)
-
-(setq inhibit-splash-screen t)
-(setq standard-indent 2)
-(setq tab-width 2)
-
-(setq fill-column 70)
-(setq auto-fill-mode nil)
-
-(setq ring-bell nil)
-
-(setq make-backup-files nil)
-
-(global-set-key "\M-h" 'backward-kill-word) \ No newline at end of file
diff --git a/alacritty/alacritty.toml b/alacritty/alacritty.toml
deleted file mode 100644
index d054e04..0000000
--- a/alacritty/alacritty.toml
+++ /dev/null
@@ -1,21 +0,0 @@
-import = ["~/.config/alacritty/themes/themes/gruvbox_dark.toml"]
-
-[font]
-size = 23.0
-builtin_box_drawing = false
-
-[font.bold]
-family = "Berkeley Mono"
-style = "Bold"
-
-[font.bold_italic]
-family = "Berkeley Mono"
-style = "Bold Italic"
-
-[font.italic]
-family = "Berkeley Mono"
-style = "Italic"
-
-[font.normal]
-family = "Berkeley Mono"
-style = "Regular"
diff --git a/dwl/.gitignore b/dwl/.gitignore
deleted file mode 100644
index 0dde90e..0000000
--- a/dwl/.gitignore
+++ /dev/null
@@ -1,6 +0,0 @@
-dwl
-*.o
-*-protocol.c
-*-protocol.h
-.ccls-cache
-config.h
diff --git a/dwl/bstack.patch b/dwl/bstack.patch
deleted file mode 100644
index 5b20051..0000000
--- a/dwl/bstack.patch
+++ /dev/null
@@ -1,179 +0,0 @@
-From 87898f8fbac5f917443d1d54e3c3797bf84a04d2 Mon Sep 17 00:00:00 2001
-From: wochap <gean.marroquin@gmail.com>
-Date: Wed, 22 Nov 2023 19:02:09 -0500
-Subject: [PATCH 1/2] apply main...Abanoub8:bottomstack.patch
-
----
- config.def.h | 4 +++
- dwl.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++
- 2 files changed, 88 insertions(+)
-
-diff --git a/config.def.h b/config.def.h
-index 4e30885b7..91f48d8bc 100644
---- a/config.def.h
-+++ b/config.def.h
-@@ -33,6 +33,8 @@ static const Layout layouts[] = {
- { "[]=", tile },
- { "><>", NULL }, /* no layout function means floating behavior */
- { "[M]", monocle },
-+ { "TTT", bstack },
-+ { "===", bstackhoriz },
- };
-
- /* monitors */
-@@ -132,6 +134,8 @@ static const Key keys[] = {
- { MODKEY, XKB_KEY_t, setlayout, {.v = &layouts[0]} },
- { MODKEY, XKB_KEY_f, setlayout, {.v = &layouts[1]} },
- { MODKEY, XKB_KEY_m, setlayout, {.v = &layouts[2]} },
-+ { MODKEY, XKB_KEY_u, setlayout, {.v = &layouts[3]} },
-+ { MODKEY, XKB_KEY_o, setlayout, {.v = &layouts[4]} },
- { MODKEY, XKB_KEY_space, setlayout, {0} },
- { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_space, togglefloating, {0} },
- { MODKEY, XKB_KEY_e, togglefullscreen, {0} },
-diff --git a/dwl.c b/dwl.c
-index a7d41b085..a6e9e125d 100644
---- a/dwl.c
-+++ b/dwl.c
-@@ -50,6 +50,7 @@
- #include <wlr/types/wlr_xdg_decoration_v1.h>
- #include <wlr/types/wlr_xdg_output_v1.h>
- #include <wlr/types/wlr_xdg_shell.h>
-+#include <wlr/util/box.h>
- #include <wlr/util/log.h>
- #include <xkbcommon/xkbcommon.h>
- #ifdef XWAYLAND
-@@ -318,6 +319,8 @@ static Monitor *xytomon(double x, double y);
- static void xytonode(double x, double y, struct wlr_surface **psurface,
- Client **pc, LayerSurface **pl, double *nx, double *ny);
- static void zoom(const Arg *arg);
-+static void bstack(Monitor *m);
-+static void bstackhoriz(Monitor *m);
-
- /* variables */
- static const char broken[] = "broken";
-@@ -2827,3 +2830,84 @@ main(int argc, char *argv[])
- usage:
- die("Usage: %s [-v] [-d] [-s startup command]", argv[0]);
- }
-+
-+static void
-+bstack(Monitor *m)
-+{
-+ int w, h, mh, mx, tx, ty, tw;
-+ unsigned int i, n = 0;
-+ Client *c;
-+
-+ wl_list_for_each(c, &clients, link)
-+ if (VISIBLEON(c, m) && !c->isfloating)
-+ n++;
-+ if (n == 0)
-+ return;
-+
-+ if (n > m->nmaster) {
-+ mh = m->nmaster ? m->mfact * m->w.height : 0;
-+ tw = m->w.width / (n - m->nmaster);
-+ ty = m->w.y + mh;
-+ } else {
-+ mh = m->w.height;
-+ tw = m->w.width;
-+ ty = m->w.y;
-+ }
-+
-+ i = mx = 0;
-+ tx = m-> w.x;
-+ wl_list_for_each(c, &clients, link) {
-+ if (!VISIBLEON(c, m) || c->isfloating)
-+ continue;
-+ if (i < m->nmaster) {
-+ w = (m->w.width - mx) / (MIN(n, m->nmaster) - i);
-+ resize(c, (struct wlr_box) { .x = m->w.x + mx, .y = m->w.y, .width = w - (2 * c->bw), .height = mh - (2 * c->bw) }, 0);
-+ mx += c->geom.width;
-+ } else {
-+ h = m->w.height - mh;
-+ resize(c, (struct wlr_box) { .x = tx, .y = ty, .width = tw - (2 * c->bw), .height = h - (2 * c->bw) }, 0);
-+ if (tw != m->w.width)
-+ tx += c->geom.width;
-+ }
-+ i++;
-+ }
-+}
-+
-+static void
-+bstackhoriz(Monitor *m) {
-+ int w, mh, mx, tx, ty, th;
-+ unsigned int i, n = 0;
-+ Client *c;
-+
-+ wl_list_for_each(c, &clients, link)
-+ if (VISIBLEON(c, m) && !c->isfloating)
-+ n ++;
-+ if (n == 0)
-+ return;
-+
-+ if (n > m->nmaster) {
-+ mh = m->nmaster ? m->mfact * m->w.height : 0;
-+ th = (m->w.height - mh) / (n - m->nmaster);
-+ ty = m->w.y + mh;
-+ } else {
-+ th = mh = m->w.height;
-+ ty = m->w.y;
-+ }
-+
-+ i = mx = 0;
-+ tx = m-> w.x;
-+ wl_list_for_each(c, &clients, link) {
-+ if (!VISIBLEON(c,m) || c->isfloating)
-+ continue;
-+ if (i < m->nmaster) {
-+ w = (m->w.width - mx) / (MIN(n, m->nmaster) - i);
-+ resize(c, (struct wlr_box) { .x = m->w.x + mx, .y = m->w.y, .width = w - (2 * c->bw), .height = mh - (2 * c->bw) }, 0);
-+ mx += c->geom.width;
-+ } else {
-+ resize(c, (struct wlr_box) { .x = tx, .y = ty, .width = m->w.width - (2 * c->bw), .height = th - (2 * c->bw) }, 0);
-+ if (th != m->w.height)
-+ ty += c->geom.height;
-+ }
-+ i++;
-+ }
-+}
-
-From 6d650c862e168fb6f9fbd78825945aeeca6f6270 Mon Sep 17 00:00:00 2001
-From: wochap <gean.marroquin@gmail.com>
-Date: Wed, 22 Nov 2023 19:03:00 -0500
-Subject: [PATCH 2/2] fix main...Abanoub8:bottomstack.patch, remove gaps
-
----
- dwl.c | 8 ++++----
- 1 file changed, 4 insertions(+), 4 deletions(-)
-
-diff --git a/dwl.c b/dwl.c
-index a6e9e125d..638714fdc 100644
---- a/dwl.c
-+++ b/dwl.c
-@@ -2861,11 +2861,11 @@ bstack(Monitor *m)
- continue;
- if (i < m->nmaster) {
- w = (m->w.width - mx) / (MIN(n, m->nmaster) - i);
-- resize(c, (struct wlr_box) { .x = m->w.x + mx, .y = m->w.y, .width = w - (2 * c->bw), .height = mh - (2 * c->bw) }, 0);
-+ resize(c, (struct wlr_box) { .x = m->w.x + mx, .y = m->w.y, .width = w, .height = mh }, 0);
- mx += c->geom.width;
- } else {
- h = m->w.height - mh;
-- resize(c, (struct wlr_box) { .x = tx, .y = ty, .width = tw - (2 * c->bw), .height = h - (2 * c->bw) }, 0);
-+ resize(c, (struct wlr_box) { .x = tx, .y = ty, .width = tw, .height = h }, 0);
- if (tw != m->w.width)
- tx += c->geom.width;
- }
-@@ -2901,10 +2901,10 @@ bstackhoriz(Monitor *m) {
- continue;
- if (i < m->nmaster) {
- w = (m->w.width - mx) / (MIN(n, m->nmaster) - i);
-- resize(c, (struct wlr_box) { .x = m->w.x + mx, .y = m->w.y, .width = w - (2 * c->bw), .height = mh - (2 * c->bw) }, 0);
-+ resize(c, (struct wlr_box) { .x = m->w.x + mx, .y = m->w.y, .width = w, .height = mh }, 0);
- mx += c->geom.width;
- } else {
-- resize(c, (struct wlr_box) { .x = tx, .y = ty, .width = m->w.width - (2 * c->bw), .height = th - (2 * c->bw) }, 0);
-+ resize(c, (struct wlr_box) { .x = tx, .y = ty, .width = m->w.width, .height = th }, 0);
- if (th != m->w.height)
- ty += c->geom.height;
- }
diff --git a/dwl/config.h b/dwl/config.h
deleted file mode 100644
index 5c2acf9..0000000
--- a/dwl/config.h
+++ /dev/null
@@ -1,197 +0,0 @@
-static int log_level = WLR_ERROR;
-
-/* Taken from https://github.com/djpohly/dwl/issues/466 */
-#define COLOR(hex) { ((hex >> 24) & 0xFF) / 255.0f, \
- ((hex >> 16) & 0xFF) / 255.0f, \
- ((hex >> 8) & 0xFF) / 255.0f, \
- (hex & 0xFF) / 255.0f }
-
-/* appearance */
-static const int sloppyfocus = 1; /* focus follows mouse */
-static const int bypass_surface_visibility = 0; /* 1 means idle inhibitors will disable idle tracking even if it's surface isn't visible */
-static const unsigned int borderpx = 2; /* border pixel of windows */
-static const float rootcolor[] = {0.3, 0.3, 0.3, 1.0};
-static const unsigned int gap = 10; /* inner gap between windows */
-static const float bordercolor[] = {0.266, 0.266, 0.266, 1.0}; // 44 44 44
-static const float focuscolor[] = {1.000, 0.549, 0.000, 1.0}; // ff 8c 00
-static const float urgentcolor[] = COLOR(0xff0000ff);
-/* To conform the xdg-protocol, set the alpha to zero to restore the old behavior */
-static const float fullscreen_bg[] = {0.1, 0.1, 0.1, 1.0};
-
-/* tagging */
-#define TAGCOUNT 8
-
-static const Rule rules[] = {
- /* app_id title tags mask isfloating monitor keep_focus */
-// { "firefox", "DWL_EMPTY_TITLE", 0, 1, -1 },
-// { "firefox", "Firefox — Sharing Indicator", 0, 1, -1 }
- { NULL, NULL, 0, 0, -1 }
-};
-
-/* layout(s) */
-static const Layout layouts[] = {
- /* symbol arrange function */
- { "[]=", tile },
- { "[M]", monocle },
- { "===", bstackhoriz },
- { "TTT", bstack },
- { "><>", NULL }, /* no layout function means floating behavior */
-};
-
-/* monitors */
-static const MonitorRule monrules[] = {
- /* name mfact nmaster scale layout rotate/reflect x y*/
- { "DP-3", 0.6, 1, 1, &layouts[0], WL_OUTPUT_TRANSFORM_NORMAL, 0, 0 },
- { "DP-1", 0.6, 1, 1, &layouts[2], WL_OUTPUT_TRANSFORM_90, -1, -1 },
- /* defaults */
- { NULL, 0.6, 1, 1, &layouts[0], WL_OUTPUT_TRANSFORM_NORMAL, -1, -1 },
-};
-
-/* keyboard */
-static const struct xkb_rule_names xkb_rules = {
- /* can specify fields: rules, model, layout, variant, options */
- /* example:
- .options = "ctrl:nocaps",
- */
- .options = NULL,
-};
-
-static const int repeat_rate = 25;
-static const int repeat_delay = 600;
-
-/* Trackpad */
-static const int tap_to_click = 1;
-static const int tap_and_drag = 1;
-static const int drag_lock = 1;
-static const int natural_scrolling = 0;
-static const int disable_while_typing = 1;
-static const int left_handed = 0;
-static const int middle_button_emulation = 0;
-/* You can choose between:
-LIBINPUT_CONFIG_SCROLL_NO_SCROLL
-LIBINPUT_CONFIG_SCROLL_2FG
-LIBINPUT_CONFIG_SCROLL_EDGE
-LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN
-*/
-static const enum libinput_config_scroll_method scroll_method = LIBINPUT_CONFIG_SCROLL_2FG;
-
-/* You can choose between:
-LIBINPUT_CONFIG_CLICK_METHOD_NONE
-LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS
-LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER
-*/
-static const enum libinput_config_click_method click_method = LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS;
-
-/* You can choose between:
-LIBINPUT_CONFIG_SEND_EVENTS_ENABLED
-LIBINPUT_CONFIG_SEND_EVENTS_DISABLED
-LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE
-*/
-static const uint32_t send_events_mode = LIBINPUT_CONFIG_SEND_EVENTS_ENABLED;
-
-/* You can choose between:
-LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT
-LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE
-*/
-static const enum libinput_config_accel_profile accel_profile = LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE;
-static const double accel_speed = 0.0;
-/* You can choose between:
-LIBINPUT_CONFIG_TAP_MAP_LRM -- 1/2/3 finger tap maps to left/right/middle
-LIBINPUT_CONFIG_TAP_MAP_LMR -- 1/2/3 finger tap maps to left/middle/right
-*/
-static const enum libinput_config_tap_button_map button_map = LIBINPUT_CONFIG_TAP_MAP_LRM;
-
-/* If you want to use the windows key for MODKEY, use WLR_MODIFIER_LOGO */
-#define MODKEY WLR_MODIFIER_LOGO
-
-#define TAGKEYS(KEY,SKEY,TAG) \
- { MODKEY, KEY, view, {.ui = 1 << TAG} }, \
- { MODKEY|WLR_MODIFIER_CTRL, KEY, toggleview, {.ui = 1 << TAG} }, \
- { MODKEY|WLR_MODIFIER_SHIFT, SKEY, tag, {.ui = 1 << TAG} }, \
- { MODKEY|WLR_MODIFIER_CTRL|WLR_MODIFIER_SHIFT,SKEY,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 const char *termcmd[] = { "foot", NULL };
-static const char *menucmd[] = { "run", NULL };
-static const char *now_playing[] = { "now_playing", NULL };
-static const char *albumbler[] = { "albumbler.py", NULL };
-static const char *mpc_toggle[] = { "mpc", "toggle", NULL };
-static const char *mpc_next[] = { "mpc", "next", NULL };
-static const char *mpc_prev[] = { "mpc", "prev", NULL };
-static const char *mpc_stop[] = { "mpc", "stop", NULL };
-static const char *slock[] = { "lock", NULL };
-static const char *flameshot[] = { "grim_slurp", NULL };
-
-static const char *vol_dn[] = { "pactl", "set-sink-volume", "0", "-2%", NULL };
-static const char *vol_up[] = { "pactl", "set-sink-volume", "0", "+2%", NULL };
-static const char *vol_mt[] = { "pactl", "set-sink-mute", "0", "toggle", NULL };
-
-static const Key keys[] = {
- /* Note that Shift changes certain key codes: c -> C, 2 -> at, etc. */
- { MODKEY, XKB_KEY_t, spawn, {.v = termcmd} },
- { MODKEY, XKB_KEY_d, spawn, {.v = menucmd} },
- { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_space, spawn, {.v = albumbler } },
- { MODKEY|WLR_MODIFIER_SHIFT|WLR_MODIFIER_CTRL, XKB_KEY_space, spawn, {.v = now_playing } },
- { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_X, spawn, {.v = slock } },
- { MODKEY, XKB_KEY_p, spawn, {.v = flameshot } },
- { MODKEY|WLR_MODIFIER_SHIFT|WLR_MODIFIER_CTRL, XKB_KEY_Q, quit, {0} },
-
- // Multimedia
- { 0, XKB_KEY_XF86AudioLowerVolume, spawn, {.v = vol_dn } },
- { 0, XKB_KEY_XF86AudioMute, spawn, {.v = vol_mt } },
- { 0, XKB_KEY_XF86AudioRaiseVolume, spawn, {.v = vol_up } },
- { 0, XKB_KEY_XF86AudioPlay, spawn, {.v = mpc_toggle } },
- { 0, XKB_KEY_XF86AudioStop, spawn, {.v = mpc_stop } },
- { 0, XKB_KEY_XF86AudioPrev, spawn, {.v = mpc_prev } },
- { 0, XKB_KEY_XF86AudioNext, spawn, {.v = mpc_next } },
-
- // Windows
- { MODKEY, XKB_KEY_c, focusstack, {.i = +1 } },
- { MODKEY, XKB_KEY_i, focusstack, {.i = -1 } },
- { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_C, incnmaster, {.i = +1 } },
- { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_I, incnmaster, {.i = -1 } },
- { MODKEY, XKB_KEY_e, setmfact, {.f = -0.05} },
- { MODKEY, XKB_KEY_n, setmfact, {.f = +0.05} },
- { MODKEY, XKB_KEY_Return, zoom, {0} },
- { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_K, killclient, {0} },
-
- // Layout
- { MODKEY, XKB_KEY_s, setlayout, {.v = &layouts[0]} },
- { MODKEY, XKB_KEY_r, setlayout, {.v = &layouts[1]} },
- { MODKEY, XKB_KEY_a, setlayout, {.v = &layouts[2]} },
- { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_S, setlayout, {.v = &layouts[3]} },
- { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_R, setlayout, {.v = &layouts[4]} },
- { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_A, togglefloating, {0} },
- { MODKEY, XKB_KEY_comma, focusmon, {.i = WLR_DIRECTION_RIGHT } },
- { MODKEY, XKB_KEY_b, focusmon, {.i = WLR_DIRECTION_LEFT } },
-
- // Tags
- { MODKEY, XKB_KEY_0, view, {.ui = ~0 } },
- { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_parenright,tag, {.ui = ~0 } },
- { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_less, tagmon, {.i = WLR_DIRECTION_RIGHT } },
- { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_B, tagmon, {.i = WLR_DIRECTION_LEFT } },
- { MODKEY, XKB_KEY_Tab, view, {.ui = 0 } },
- TAGKEYS( XKB_KEY_f, XKB_KEY_F, 0),
- TAGKEYS( XKB_KEY_u, XKB_KEY_U, 1),
- TAGKEYS( XKB_KEY_h, XKB_KEY_H, 2),
- TAGKEYS( XKB_KEY_period, XKB_KEY_greater, 3),
- TAGKEYS( XKB_KEY_v, XKB_KEY_V, 4),
- TAGKEYS( XKB_KEY_l, XKB_KEY_L, 5),
- TAGKEYS( XKB_KEY_o, XKB_KEY_O, 6),
- TAGKEYS( XKB_KEY_m, XKB_KEY_M, 7),
-
- /* Ctrl-Alt-Backspace and Ctrl-Alt-Fx used to be handled by X server */
- { WLR_MODIFIER_CTRL|WLR_MODIFIER_ALT,XKB_KEY_Terminate_Server, quit, {0} },
-#define CHVT(n) { WLR_MODIFIER_CTRL|WLR_MODIFIER_ALT,XKB_KEY_XF86Switch_VT_##n, chvt, {.ui = (n)} }
- CHVT(1), CHVT(2), CHVT(3), CHVT(4), CHVT(5), CHVT(6),
- CHVT(7), CHVT(8), CHVT(9), CHVT(10), CHVT(11), CHVT(12),
-};
-
-static const Button buttons[] = {
- { MODKEY, BTN_LEFT, moveresize, {.ui = CurMove} },
- { MODKEY, BTN_MIDDLE, togglefloating, {0} },
- { MODKEY, BTN_RIGHT, moveresize, {.ui = CurResize} },
-};
diff --git a/dwl/correctly-match-blank-rule-strings.patch b/dwl/correctly-match-blank-rule-strings.patch
deleted file mode 100644
index f9b3144..0000000
--- a/dwl/correctly-match-blank-rule-strings.patch
+++ /dev/null
@@ -1,35 +0,0 @@
-From 7cc541eb1092ba17bfe3d5afa77e609cda832016 Mon Sep 17 00:00:00 2001
-From: tslil clingman <>
-Date: Sat, 2 Dec 2023 10:57:35 +0100
-Subject: [PATCH 1/1] correctly match blank rule strings
-
-The bug before-hand was that specifying a blank rule string would
-match against any string (strstr(foo, "") is always true apparently),
-even though we already had a special case for !r->title and !r->id.
-
-This patch now sets the behaviour to r->title/r->id == NULL means
-match all, blank means match blank
----
- dwl.c | 5 +++--
- 1 file changed, 3 insertions(+), 2 deletions(-)
-
-diff --git a/dwl.c b/dwl.c
-index 03e999e..5a2a538 100644
---- a/dwl.c
-+++ b/dwl.c
-@@ -442,9 +442,10 @@ applyrules(Client *c)
- if (!(title = client_get_title(c)))
- title = broken;
-
-+#define MATCH(str1, str2) ((str2[0]==0 && str1[0]==0) || (str2[0] != 0 && strstr(str1, str2)))
- for (r = rules; r < END(rules); r++) {
-- if ((!r->title || strstr(title, r->title))
-- && (!r->id || strstr(appid, r->id))) {
-+ if ((!r->title || MATCH(title, r->title))
-+ && (!r->id || MATCH(appid, r->id))) {
- c->isfloating = r->isfloating;
- newtags |= r->tags;
- i = 0;
---
-2.43.0
-
diff --git a/dwl/dwl.sh b/dwl/dwl.sh
deleted file mode 100755
index 190db66..0000000
--- a/dwl/dwl.sh
+++ /dev/null
@@ -1,9 +0,0 @@
-#!/bin/sh
-
-killall dunst; dunst &
-
-swaybg -o DP-3 -i /home/tslil/store/pictures/dp3_back &
-swaybg -o DP-1 -m tile -i /home/tslil/store/pictures/dp1_back &
-
-yambar &
-cat - > /home/tslil/.cache/dwltags
diff --git a/dwl/laptop_config.h b/dwl/laptop_config.h
deleted file mode 100644
index fcce62e..0000000
--- a/dwl/laptop_config.h
+++ /dev/null
@@ -1,199 +0,0 @@
-static int log_level = WLR_ERROR;
-
-/* Taken from https://github.com/djpohly/dwl/issues/466 */
-#define COLOR(hex) { ((hex >> 24) & 0xFF) / 255.0f, \
- ((hex >> 16) & 0xFF) / 255.0f, \
- ((hex >> 8) & 0xFF) / 255.0f, \
- (hex & 0xFF) / 255.0f }
-
-/* appearance */
-static const int sloppyfocus = 1; /* focus follows mouse */
-static const int bypass_surface_visibility = 0; /* 1 means idle inhibitors will disable idle tracking even if it's surface isn't visible */
-static const unsigned int borderpx = 2; /* border pixel of windows */
-static const float rootcolor[] = {0.3, 0.3, 0.3, 1.0};
-static const float bordercolor[] = {0.266, 0.266, 0.266, 1.0}; // 44 44 44
-static const float focuscolor[] = {1.000, 0.549, 0.000, 1.0}; // ff 8c 00
-static const float urgentcolor[] = COLOR(0xff0000ff);
-static const float fullscreen_bg[] = {0.1, 0.1, 0.1, 1.0};
-
-/* tagging */
-#define TAGCOUNT 8
-
-static const Rule rules[] = {
- /* app_id title tags mask isfloating monitor */
- { "firefox", "", 0, 1, -1 }
-};
-
-/* layout(s) */
-static const Layout layouts[] = {
- /* symbol arrange function */
- { "[]=", tile },
- { "[M]", monocle },
- { "===", bstackhoriz },
- { "TTT", bstack },
- { "><>", NULL }, /* no layout function means floating behavior */
-};
-
-/* monitors */
-static const MonitorRule monrules[] = {
- /* name mfact nmaster scale layout rotate/reflect x y*/
- { NULL, 0.6, 1, 1, &layouts[0], WL_OUTPUT_TRANSFORM_NORMAL, -1, -1 },
-};
-
-/* keyboard */
-static const struct xkb_rule_names xkb_rules = {
- /* can specify fields: rules, model, layout, variant, options */
- /* example:
- .options = "ctrl:nocaps",
- */
- .model = "pc105awide",
- .layout = "vlom",
- .options = "ctrl:nocaps,ctrl:swap_lalt_lctl_lwin,ctrl:swap_rwin_rctl",
-};
-
-static const int repeat_rate = 25;
-static const int repeat_delay = 600;
-
-/* Trackpad */
-static const int tap_to_click = 1;
-static const int tap_and_drag = 1;
-static const int drag_lock = 1;
-static const int natural_scrolling = 0;
-static const int disable_while_typing = 1;
-static const int left_handed = 0;
-static const int middle_button_emulation = 0;
-/* You can choose between:
-LIBINPUT_CONFIG_SCROLL_NO_SCROLL
-LIBINPUT_CONFIG_SCROLL_2FG
-LIBINPUT_CONFIG_SCROLL_EDGE
-LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN
-*/
-static const enum libinput_config_scroll_method scroll_method = LIBINPUT_CONFIG_SCROLL_2FG;
-
-/* You can choose between:
-LIBINPUT_CONFIG_CLICK_METHOD_NONE
-LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS
-LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER
-*/
-static const enum libinput_config_click_method click_method = LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS;
-
-/* You can choose between:
-LIBINPUT_CONFIG_SEND_EVENTS_ENABLED
-LIBINPUT_CONFIG_SEND_EVENTS_DISABLED
-LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE
-*/
-static const uint32_t send_events_mode = LIBINPUT_CONFIG_SEND_EVENTS_ENABLED;
-
-/* You can choose between:
-LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT
-LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE
-*/
-static const enum libinput_config_accel_profile accel_profile = LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE;
-static const double accel_speed = 0.0;
-/* You can choose between:
-LIBINPUT_CONFIG_TAP_MAP_LRM -- 1/2/3 finger tap maps to left/right/middle
-LIBINPUT_CONFIG_TAP_MAP_LMR -- 1/2/3 finger tap maps to left/middle/right
-*/
-static const enum libinput_config_tap_button_map button_map = LIBINPUT_CONFIG_TAP_MAP_LRM;
-
-/* If you want to use the windows key for MODKEY, use WLR_MODIFIER_LOGO */
-#define MODKEY WLR_MODIFIER_LOGO
-
-#define TAGKEYS(KEY,SKEY,TAG) \
- { MODKEY, KEY, view, {.ui = 1 << TAG} }, \
- { MODKEY|WLR_MODIFIER_CTRL, KEY, toggleview, {.ui = 1 << TAG} }, \
- { MODKEY|WLR_MODIFIER_SHIFT, SKEY, tag, {.ui = 1 << TAG} }, \
- { MODKEY|WLR_MODIFIER_CTRL|WLR_MODIFIER_SHIFT,SKEY,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 const char *termcmd[] = { "foot", NULL };
-static const char *menucmd[] = { "run", NULL };
-static const char *now_playing[] = { "now_playing", NULL };
-static const char *albumbler[] = { "albumbler.py", NULL };
-static const char *mpc_toggle[] = { "mpc", "toggle", NULL };
-static const char *mpc_next[] = { "mpc", "next", NULL };
-static const char *mpc_prev[] = { "mpc", "prev", NULL };
-static const char *mpc_stop[] = { "mpc", "stop", NULL };
-static const char *slock[] = { "lock", NULL };
-static const char *flameshot[] = { "grim_slurp", NULL };
-
-static const char *vol_dn[] = { "pactl", "set-sink-volume", "0", "-2%", NULL };
-static const char *vol_up[] = { "pactl", "set-sink-volume", "0", "+2%", NULL };
-static const char *vol_mt[] = { "pactl", "set-sink-mute", "0", "toggle", NULL };
-
-static const char *light_up[] = { "light", "-A", "5", NULL };
-static const char *light_dn[] = { "light", "-U", "5", NULL };
-
-static const Key keys[] = {
- /* Note that Shift changes certain key codes: c -> C, 2 -> at, etc. */
- { MODKEY, XKB_KEY_t, spawn, {.v = termcmd} },
- { MODKEY, XKB_KEY_d, spawn, {.v = menucmd} },
- { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_space, spawn, {.v = albumbler } },
- { MODKEY|WLR_MODIFIER_SHIFT|WLR_MODIFIER_CTRL, XKB_KEY_space, spawn, {.v = now_playing } },
- { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_X, spawn, {.v = slock } },
- { MODKEY, XKB_KEY_p, spawn, {.v = flameshot } },
- { MODKEY|WLR_MODIFIER_SHIFT|WLR_MODIFIER_CTRL, XKB_KEY_Q, quit, {0} },
-
- // Multimedia
- { 0, XKB_KEY_XF86AudioLowerVolume, spawn, {.v = vol_dn } },
- { 0, XKB_KEY_XF86AudioMute, spawn, {.v = vol_mt } },
- { 0, XKB_KEY_XF86AudioRaiseVolume, spawn, {.v = vol_up } },
- { 0, XKB_KEY_XF86AudioPlay, spawn, {.v = mpc_toggle } },
- { 0, XKB_KEY_XF86AudioStop, spawn, {.v = mpc_stop } },
- { 0, XKB_KEY_XF86AudioPrev, spawn, {.v = mpc_prev } },
- { 0, XKB_KEY_XF86AudioNext, spawn, {.v = mpc_next } },
-
- // Brightness
- { 0, XKB_KEY_XF86MonBrightnessUp, spawn, {.v = light_up }},
- { 0, XKB_KEY_XF86MonBrightnessDown, spawn, {.v = light_dn }},
-
- // Windows
- { MODKEY, XKB_KEY_c, focusstack, {.i = +1 } },
- { MODKEY, XKB_KEY_i, focusstack, {.i = -1 } },
- { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_C, incnmaster, {.i = +1 } },
- { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_I, incnmaster, {.i = -1 } },
- { MODKEY, XKB_KEY_e, setmfact, {.f = -0.05} },
- { MODKEY, XKB_KEY_n, setmfact, {.f = +0.05} },
- { MODKEY, XKB_KEY_Return, zoom, {0} },
- { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_K, killclient, {0} },
-
- // Layout
- { MODKEY, XKB_KEY_s, setlayout, {.v = &layouts[0]} },
- { MODKEY, XKB_KEY_r, setlayout, {.v = &layouts[1]} },
- { MODKEY, XKB_KEY_a, setlayout, {.v = &layouts[2]} },
- { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_S, setlayout, {.v = &layouts[3]} },
- { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_R, setlayout, {.v = &layouts[4]} },
- { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_A, togglefloating, {0} },
- { MODKEY, XKB_KEY_comma, focusmon, {.i = WLR_DIRECTION_RIGHT } },
- { MODKEY, XKB_KEY_b, focusmon, {.i = WLR_DIRECTION_LEFT } },
-
- // Tags
- { MODKEY, XKB_KEY_0, view, {.ui = ~0 } },
- { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_parenright,tag, {.ui = ~0 } },
- { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_less, tagmon, {.i = WLR_DIRECTION_RIGHT } },
- { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_B, tagmon, {.i = WLR_DIRECTION_LEFT } },
- { MODKEY, XKB_KEY_Tab, view, {.ui = 0 } },
- TAGKEYS( XKB_KEY_f, XKB_KEY_F, 0),
- TAGKEYS( XKB_KEY_u, XKB_KEY_U, 1),
- TAGKEYS( XKB_KEY_h, XKB_KEY_H, 2),
- TAGKEYS( XKB_KEY_period, XKB_KEY_greater, 3),
- TAGKEYS( XKB_KEY_v, XKB_KEY_V, 4),
- TAGKEYS( XKB_KEY_l, XKB_KEY_L, 5),
- TAGKEYS( XKB_KEY_o, XKB_KEY_O, 6),
- TAGKEYS( XKB_KEY_m, XKB_KEY_M, 7),
-
- /* Ctrl-Alt-Backspace and Ctrl-Alt-Fx used to be handled by X server */
- { WLR_MODIFIER_CTRL|WLR_MODIFIER_ALT,XKB_KEY_Terminate_Server, quit, {0} },
-#define CHVT(n) { WLR_MODIFIER_CTRL|WLR_MODIFIER_ALT,XKB_KEY_XF86Switch_VT_##n, chvt, {.ui = (n)} }
- CHVT(1), CHVT(2), CHVT(3), CHVT(4), CHVT(5), CHVT(6),
- CHVT(7), CHVT(8), CHVT(9), CHVT(10), CHVT(11), CHVT(12),
-};
-
-static const Button buttons[] = {
- { MODKEY, BTN_LEFT, moveresize, {.ui = CurMove} },
- { MODKEY, BTN_MIDDLE, togglefloating, {0} },
- { MODKEY, BTN_RIGHT, moveresize, {.ui = CurResize} },
-};
diff --git a/dwl/pertag.patch b/dwl/pertag.patch
deleted file mode 100644
index a0c66d8..0000000
--- a/dwl/pertag.patch
+++ /dev/null
@@ -1,167 +0,0 @@
-From 8750e1255f6c8b799165186cd6cfdfa7af3ee56d Mon Sep 17 00:00:00 2001
-From: mortezadadgar <mortezadadgar97@gmail.com>
-Date: Sat, 26 Aug 2023 20:37:22 +0330
-Subject: [PATCH] Applied pertag
-
----
- dwl.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++++----
- 1 file changed, 70 insertions(+), 5 deletions(-)
-
-diff --git a/dwl.c b/dwl.c
-index 4ff5c37f7..6c104bbb0 100644
---- a/dwl.c
-+++ b/dwl.c
-@@ -94,6 +94,7 @@ typedef struct {
- const Arg arg;
- } Button;
-
-+typedef struct Pertag Pertag;
- typedef struct Monitor Monitor;
- typedef struct {
- /* Must keep these three elements in this order */
-@@ -185,6 +186,7 @@ struct Monitor {
- struct wlr_box w; /* window area, layout-relative */
- struct wl_list layers[4]; /* LayerSurface::link */
- const Layout *lt[2];
-+ Pertag *pertag;
- unsigned int seltags;
- unsigned int sellt;
- uint32_t tagset[2];
-@@ -413,6 +415,14 @@ static Atom netatom[NetLast];
- /* attempt to encapsulate suck into one file */
- #include "client.h"
-
-+struct Pertag {
-+ unsigned int curtag, prevtag; /* current and previous tag */
-+ int nmasters[TAGCOUNT + 1]; /* number of windows in master area */
-+ float mfacts[TAGCOUNT + 1]; /* mfacts per tag */
-+ unsigned int sellts[TAGCOUNT + 1]; /* selected layouts */
-+ const Layout *ltidxs[TAGCOUNT + 1][2]; /* matrix of tags and layouts indexes */
-+};
-+
- /* function implementations */
- void
- applybounds(Client *c, struct wlr_box *bbox)
-@@ -703,6 +713,7 @@ cleanupmon(struct wl_listener *listener, void *data)
- wlr_scene_output_destroy(m->scene_output);
- wlr_scene_node_destroy(&m->fullscreen_bg->node);
-
-+ free(m->pertag);
- closemon(m);
- free(m);
- }
-@@ -944,6 +955,18 @@ createmon(struct wl_listener *listener, void *data)
- wl_list_insert(&mons, &m->link);
- printstatus();
-
-+ m->pertag = calloc(1, sizeof(Pertag));
-+ m->pertag->curtag = m->pertag->prevtag = 1;
-+
-+ for (i = 0; i <= TAGCOUNT; 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;
-+ }
-+
- /* The xdg-protocol specifies:
- *
- * If the fullscreened surface is not opaque, the compositor must make
-@@ -1355,7 +1378,7 @@ incnmaster(const Arg *arg)
- {
- if (!arg || !selmon)
- return;
-- selmon->nmaster = MAX(selmon->nmaster + arg->i, 0);
-+ selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag] = MAX(selmon->nmaster + arg->i, 0);
- arrange(selmon);
- }
-
-@@ -2060,9 +2083,9 @@ setlayout(const Arg *arg)
- if (!selmon)
- return;
- 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, LENGTH(selmon->ltsymbol));
- arrange(selmon);
- printstatus();
-@@ -2079,7 +2102,7 @@ setmfact(const Arg *arg)
- f = arg->f < 1.0 ? arg->f + selmon->mfact : arg->f - 1.0;
- if (f < 0.1 || f > 0.9)
- return;
-- selmon->mfact = f;
-+ selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag] = f;
- arrange(selmon);
- }
-
-@@ -2423,10 +2446,30 @@ void
- toggleview(const Arg *arg)
- {
- uint32_t newtagset = selmon ? selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK) : 0;
-+ size_t i;
-
- if (!newtagset)
- return;
-
-+ 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];
-+
- selmon->tagset[selmon->seltags] = newtagset;
- focusclient(focustop(selmon), 1);
- arrange(selmon);
-@@ -2596,11 +2639,33 @@ urgent(struct wl_listener *listener, void *data)
- void
- view(const Arg *arg)
- {
-+ size_t i, tmptag;
-+
- if (!selmon || (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];
-+
- focusclient(focustop(selmon), 1);
- arrange(selmon);
- printstatus();
diff --git a/dwl/rmaster.patch b/dwl/rmaster.patch
deleted file mode 100644
index f6afd59..0000000
--- a/dwl/rmaster.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From fb5d9aab92bf5eae32b62d345290f61fec08a2fe Mon Sep 17 00:00:00 2001
-From: tslil clingman
-Date: Sun, 26 Nov 2023 16:38:01 +0100
-Subject: [PATCH] rmaster
-
----
- dwl.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/dwl.c b/dwl.c
-index 47e238e..3e9bd4a 100644
---- a/dwl.c
-+++ b/dwl.c
-@@ -2451,11 +2451,11 @@ tile(Monitor *m)
- if (!VISIBLEON(c, m) || c->isfloating || c->isfullscreen)
- continue;
- if (i < m->nmaster) {
-- resize(c, (struct wlr_box){.x = m->w.x, .y = m->w.y + my, .width = mw,
-+ resize(c, (struct wlr_box){.x = m->w.x + m->w.width - mw, .y = m->w.y + my, .width = mw,
- .height = (m->w.height - my) / (MIN(n, m->nmaster) - i)}, 0);
- my += c->geom.height;
- } else {
-- resize(c, (struct wlr_box){.x = m->w.x + mw, .y = m->w.y + ty,
-+ resize(c, (struct wlr_box){.x = m->w.x, .y = m->w.y + ty,
- .width = m->w.width - mw, .height = (m->w.height - ty) / (n - i)}, 0);
- ty += c->geom.height;
- }
diff --git a/dwm-6.2/LICENSE b/dwm-6.2/LICENSE
deleted file mode 100644
index d221f09..0000000
--- a/dwm-6.2/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/dwm-6.2/Makefile b/dwm-6.2/Makefile
deleted file mode 100644
index 77bcbc0..0000000
--- a/dwm-6.2/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/dwm-6.2/README b/dwm-6.2/README
deleted file mode 100644
index 95d4fd0..0000000
--- a/dwm-6.2/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/dwm-6.2/config.def.h b/dwm-6.2/config.def.h
deleted file mode 100644
index f736342..0000000
--- a/dwm-6.2/config.def.h
+++ /dev/null
@@ -1,129 +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 gappx = 6; /* gaps between windows */
-static const unsigned int snap = 32; /* snap pixel */
-static const unsigned int systraypinning = 0; /* 0: sloppy systray follows selected monitor, >0: pin systray to monitor X */
-static const unsigned int systrayspacing = 2; /* systray spacing */
-static const int systraypinningfailfirst = 1; /* 1: if pinning fails, display systray on the first monitor, False: display systray on the last monitor*/
-static const int showsystray = 1; /* 0 means no systray */
-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 lpm[] = {
- /* Index of preferred layout], if LENGTH(lpm)<#monitors -> default layout */
- 0, 1
-};
-
-static const Layout layouts[] = {
- /* symbol arrange function */
- { "[]=", tile }, /* first entry is default */
- { "><>", NULL }, /* no layout function means floating behavior */
- { "[M]", monocle },
- { "TTT", bstack },
- { "===", bstackhoriz },
-};
-
-/* 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_u, setlayout, {.v = &layouts[3]} },
- { MODKEY, XK_o, setlayout, {.v = &layouts[4]} },
- { 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/dwm-6.2/config.h b/dwm-6.2/config.h
deleted file mode 100644
index f86a868..0000000
--- a/dwm-6.2/config.h
+++ /dev/null
@@ -1,163 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-
-/* appearance */
-static const unsigned int borderpx = 2; /* border pixel of windows */
-static const unsigned int gappx = 3; /* gaps between windows */
-static const unsigned int snap = 16; /* snap pixel */
-static const unsigned int systraypinning = 0; /* 0: sloppy systray follows selected monitor, >0: pin systray to monitor X */
-static const unsigned int systrayspacing = 2; /* systray spacing */
-static const int systraypinningfailfirst = 1; /* 1: if pinning fails, display systray on the first monitor, False: display systray on the last monitor*/
-static const int showsystray = 1; /* 0 means no systray */
-static const int showbar = 1; /* 0 means no bar */
-static const int topbar = 0; /* 0 means bottom bar */
-static const char *fonts[] = { "BmPlus IBM VGA 9x16:size=12" };
-static const char col_gray1[] = "#000000";
-static const char col_gray2[] = "#444444";
-static const char col_gray3[] = "#bbbbbb";
-static const char col_gray4[] = "#eeeeee";
-static const char col_orang[] = "dark orange"; // "#ED9121";
-static const char *colors[][3] = {
- /* fg bg border */
- [SchemeNorm] = { col_gray3, col_gray1, col_gray2 },
- [SchemeSel] = { col_orang, col_gray2, col_orang },
-};
-
-/* tagging */
-static const char *tags[] = { "F", "U", "H", ".", "V", "L", "O", "M" };
-
-static const Rule rules[] = {
- /* xprop(1):
- * WM_CLASS(STRING) = instance, class
- * WM_NAME(STRING) = title
- */
- /* class instance title tags mask isfloating monitor */
- { NULL, NULL, NULL, 0, False, -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 lpm[] = {
- /* Index of preferred layout], if LENGTH(lpm)<#monitors -> default layout */
- 2, 0
-};
-
-static const Layout layouts[] = {
- /* symbol arrange function */
- { "[]=", tile }, /* first entry is default */
- { "[M]", monocle },
- { "===", bstackhoriz },
- { "TTT", bstack },
- { "><>", NULL }, /* no layout function means floating behavior */
-};
-
-/* 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 const char *termcmd[] = { "alacritty", NULL };
-static const char *menucmd[] = { "run", NULL };
-static const char *now_playing[] = { "now_playing", NULL };
-static const char *albumbler[] = { "albumbler.py", NULL };
-static const char *mpc_toggle[] = { "mpc", "toggle", NULL };
-static const char *mpc_next[] = { "mpc", "next", NULL };
-static const char *mpc_prev[] = { "mpc", "prev", NULL };
-static const char *mpc_stop[] = { "mpc", "stop", NULL };
-static const char *lock[] = { "lock", NULL };
-static const char *flameshot[] = { "flameshot", "gui", NULL };
-
-#define XF86AudioLowerVolume 0x1008ff11
-#define XF86AudioMute 0x1008ff12
-#define XF86AudioRaiseVolume 0x1008ff13
-#define XF86AudioPlay 0x1008ff14
-#define XF86AudioStop 0x1008ff15
-#define XF86AudioPrev 0x1008ff16
-#define XF86AudioNext 0x1008ff17
-
-static const char *vol_dn[] = { "pactl", "set-sink-volume", "0", "-5%", NULL };
-static const char *vol_up[] = { "pactl", "set-sink-volume", "0", "+5%", NULL };
-static const char *vol_mt[] = { "pactl", "set-sink-mute", "0", "toggle", NULL };
-
-static Key keys[] = {
- /* modifier key function argument */
-
- // Commands
- { MODKEY, XK_t, spawn, {.v = termcmd} },
- { MODKEY, XK_d, spawn, {.v = menucmd} },
- { MODKEY|ShiftMask, XK_space, spawn, {.v = albumbler } },
- { MODKEY|ShiftMask|ControlMask, XK_space, spawn, {.v = now_playing } },
- { MODKEY, XK_x, spawn, {.v = lock } },
- { MODKEY, XK_p, spawn, {.v = flameshot } },
- { MODKEY|ShiftMask|ControlMask, XK_q, quit, {0} },
-
- // Multimedia
- { 0, XF86AudioLowerVolume, spawn, {.v = vol_dn } },
- { 0, XF86AudioMute, spawn, {.v = vol_mt } },
- { 0, XF86AudioRaiseVolume, spawn, {.v = vol_up } },
- { 0, XF86AudioPlay, spawn, {.v = mpc_toggle } },
- { 0, XF86AudioStop, spawn, {.v = mpc_stop } },
- { 0, XF86AudioPrev, spawn, {.v = mpc_prev } },
- { 0, XF86AudioNext, spawn, {.v = mpc_next } },
-
- // Windows
- { MODKEY, XK_c, focusstack, {.i = +1 } },
- { MODKEY, XK_i, focusstack, {.i = -1 } },
- { MODKEY|ShiftMask, XK_c, incnmaster, {.i = +1 } },
- { MODKEY|ShiftMask, XK_i, incnmaster, {.i = -1 } },
- { MODKEY, XK_e, setmfact, {.f = -0.05} },
- { MODKEY, XK_n, setmfact, {.f = +0.05} },
- { MODKEY, XK_Return, zoom, {0} },
- { MODKEY, XK_Tab, view, {0} },
- { MODKEY|ShiftMask, XK_k, killclient, {0} },
-
- // Layout
- { MODKEY, XK_s, setlayout, {.v = &layouts[0]} },
- { MODKEY, XK_r, setlayout, {.v = &layouts[1]} },
- { MODKEY, XK_a, setlayout, {.v = &layouts[2]} },
- { MODKEY|ShiftMask, XK_s, setlayout, {.v = &layouts[3]} },
- { MODKEY|ShiftMask, XK_r, setlayout, {.v = &layouts[4]} },
- { MODKEY|ShiftMask, XK_a, togglefloating, {0} },
- { MODKEY, XK_comma, focusmon, {.i = -1 } },
- { MODKEY, XK_b, focusmon, {.i = +1 } },
-
- // Tags
- { MODKEY, XK_0, view, {.ui = ~0 } },
- { MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } },
- { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } },
- { MODKEY|ShiftMask, XK_b, tagmon, {.i = +1 } },
- TAGKEYS( XK_f, 0)
- TAGKEYS( XK_u, 1)
- TAGKEYS( XK_h, 2)
- TAGKEYS( XK_period, 3)
- TAGKEYS( XK_v, 4)
- TAGKEYS( XK_l, 5)
- TAGKEYS( XK_o, 6)
- TAGKEYS( XK_m, 7)
-};
-
-/* 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/dwm-6.2/config.mk b/dwm-6.2/config.mk
deleted file mode 100644
index 6d36cb7..0000000
--- a/dwm-6.2/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=2 -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/dwm-6.2/defaultlayoutpermonitor.diff b/dwm-6.2/defaultlayoutpermonitor.diff
deleted file mode 100644
index ba8e4f6..0000000
--- a/dwm-6.2/defaultlayoutpermonitor.diff
+++ /dev/null
@@ -1,58 +0,0 @@
-diff --git a/config.def.h b/config.def.h
-index a2ac963..7c87de8 100644
---- a/config.def.h
-+++ b/config.def.h
-@@ -37,6 +37,11 @@ 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 int lpm[] = {
-+ /* Index of preferred layout], if LENGTH(lpm)<#monitors -> default layout */
-+ 0, 1
-+};
-+
- static const Layout layouts[] = {
- /* symbol arrange function */
- { "[]=", tile }, /* first entry is default */
-diff --git a/dwm.c b/dwm.c
-index a96f33c..64cec29 100644
---- a/dwm.c
-+++ b/dwm.c
-@@ -142,6 +142,7 @@ typedef struct {
- } Rule;
-
- /* function declarations */
-+static void applydefaultlayouts();
- 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);
-@@ -276,6 +277,21 @@ static Window root, wmcheckwin;
- struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; };
-
- /* function implementations */
-+void
-+applydefaultlayouts()
-+{
-+ Monitor *m;
-+ int i = 0;
-+ for (m = mons; m; m = m->next) {
-+ if (i < LENGTH(lpm)) {
-+ m->lt[0] = &layouts[lpm[i]];
-+ m->lt[1] = &layouts[(lpm[i] + 1)/ % LENGTH(layouts)];
-+ strncpy(m->ltsymbol, layouts[i].symbol, sizeof m->ltsymbol);
-+ }
-+ i++;
-+ }
-+}
-+
- void
- applyrules(Client *c)
- {
-@@ -1911,6 +1927,7 @@ updategeom(void)
- cleanupmon(m);
- }
- }
-+ applydefaultlayouts();
- free(unique);
- } else
- #endif /* XINERAMA */
diff --git a/dwm-6.2/drw.c b/dwm-6.2/drw.c
deleted file mode 100644
index 8fd1ca4..0000000
--- a/dwm-6.2/drw.c
+++ /dev/null
@@ -1,435 +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.");
- }
-
- /* 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/dwm-6.2/drw.h b/dwm-6.2/drw.h
deleted file mode 100644
index 4bcd5ad..0000000
--- a/dwm-6.2/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/dwm-6.2/dwm-autostart-20200610-cb3f58a.diff b/dwm-6.2/dwm-autostart-20200610-cb3f58a.diff
deleted file mode 100644
index 7e17424..0000000
--- a/dwm-6.2/dwm-autostart-20200610-cb3f58a.diff
+++ /dev/null
@@ -1,179 +0,0 @@
-From 37e970479dc5d40e57fc0cbfeaa5e39941483237 Mon Sep 17 00:00:00 2001
-From: Gan Ainm <gan.ainm.riomhphost@gmail.com>
-Date: Wed, 10 Jun 2020 10:59:02 +0000
-Subject: [PATCH] dwm-xdgautostart-6.2.diff
-
-===================================================================
----
- dwm.1 | 23 +++++++++++++++++
- dwm.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- 2 files changed, 105 insertions(+)
-
-diff --git a/dwm.1 b/dwm.1
-index 13b3729..9533aa6 100644
---- a/dwm.1
-+++ b/dwm.1
-@@ -30,6 +30,14 @@ 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.
-+.P
-+On start, dwm can start additional programs that may be specified in two special
-+shell scripts (see the FILES section below), autostart_blocking.sh and
-+autostart.sh. The former is executed first and dwm will wait for its
-+termination before starting. The latter is executed in the background before
-+dwm enters its handler loop.
-+.P
-+Either of these files may be omitted.
- .SH OPTIONS
- .TP
- .B \-v
-@@ -152,6 +160,21 @@ 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 FILES
-+The files containing programs to be started along with dwm are searched for in
-+the following directories:
-+.IP "1. $XDG_DATA_HOME/dwm"
-+.IP "2. $HOME/.local/share/dwm"
-+.IP "3. $HOME/.dwm"
-+.P
-+The first existing directory is scanned for any of the autostart files below.
-+.TP 15
-+autostart.sh
-+This file is started as a shell background process before dwm enters its handler
-+loop.
-+.TP 15
-+autostart_blocking.sh
-+This file is started before any autostart.sh; dwm waits for its termination.
- .SH CUSTOMIZATION
- dwm is customized by creating a custom config.h and (re)compiling the source
- code. This keeps it fast, secure and simple.
-diff --git a/dwm.c b/dwm.c
-index 4465af1..2156b49 100644
---- a/dwm.c
-+++ b/dwm.c
-@@ -29,6 +29,7 @@
- #include <string.h>
- #include <unistd.h>
- #include <sys/types.h>
-+#include <sys/stat.h>
- #include <sys/wait.h>
- #include <X11/cursorfont.h>
- #include <X11/keysym.h>
-@@ -193,6 +194,7 @@ 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 runautostart(void);
- static void scan(void);
- static int sendevent(Client *c, Atom proto);
- static void sendmon(Client *c, Monitor *m);
-@@ -235,7 +237,11 @@ static int xerrorstart(Display *dpy, XErrorEvent *ee);
- static void zoom(const Arg *arg);
-
- /* variables */
-+static const char autostartblocksh[] = "autostart_blocking.sh";
-+static const char autostartsh[] = "autostart.sh";
- static const char broken[] = "broken";
-+static const char dwmdir[] = "dwm";
-+static const char localshare[] = ".local/share";
- static char stext[256];
- static int screen;
- static int sw, sh; /* X display screen geometry width, height */
-@@ -1380,6 +1386,83 @@ run(void)
- handler[ev.type](&ev); /* call handler */
- }
-
-+void
-+runautostart(void)
-+{
-+ char *pathpfx;
-+ char *path;
-+ char *xdgdatahome;
-+ char *home;
-+ struct stat sb;
-+
-+ if ((home = getenv("HOME")) == NULL)
-+ /* this is almost impossible */
-+ return;
-+
-+ /* if $XDG_DATA_HOME is set and not empty, use $XDG_DATA_HOME/dwm,
-+ * otherwise use ~/.local/share/dwm as autostart script directory
-+ */
-+ xdgdatahome = getenv("XDG_DATA_HOME");
-+ if (xdgdatahome != NULL && *xdgdatahome != '\0') {
-+ /* space for path segments, separators and nul */
-+ pathpfx = ecalloc(1, strlen(xdgdatahome) + strlen(dwmdir) + 2);
-+
-+ if (sprintf(pathpfx, "%s/%s", xdgdatahome, dwmdir) <= 0) {
-+ free(pathpfx);
-+ return;
-+ }
-+ } else {
-+ /* space for path segments, separators and nul */
-+ pathpfx = ecalloc(1, strlen(home) + strlen(localshare)
-+ + strlen(dwmdir) + 3);
-+
-+ if (sprintf(pathpfx, "%s/%s/%s", home, localshare, dwmdir) < 0) {
-+ free(pathpfx);
-+ return;
-+ }
-+ }
-+
-+ /* check if the autostart script directory exists */
-+ if (! (stat(pathpfx, &sb) == 0 && S_ISDIR(sb.st_mode))) {
-+ /* the XDG conformant path does not exist or is no directory
-+ * so we try ~/.dwm instead
-+ */
-+ char *pathpfx_new = realloc(pathpfx, strlen(home) + strlen(dwmdir) + 3);
-+ if(pathpfx_new == NULL) {
-+ free(pathpfx);
-+ return;
-+ }
-+ pathpfx = pathpfx_new;
-+
-+ if (sprintf(pathpfx, "%s/.%s", home, dwmdir) <= 0) {
-+ free(pathpfx);
-+ return;
-+ }
-+ }
-+
-+ /* try the blocking script first */
-+ path = ecalloc(1, strlen(pathpfx) + strlen(autostartblocksh) + 2);
-+ if (sprintf(path, "%s/%s", pathpfx, autostartblocksh) <= 0) {
-+ free(path);
-+ free(pathpfx);
-+ }
-+
-+ if (access(path, X_OK) == 0)
-+ system(path);
-+
-+ /* now the non-blocking script */
-+ if (sprintf(path, "%s/%s", pathpfx, autostartsh) <= 0) {
-+ free(path);
-+ free(pathpfx);
-+ }
-+
-+ if (access(path, X_OK) == 0)
-+ system(strcat(path, " &"));
-+
-+ free(pathpfx);
-+ free(path);
-+}
-+
- void
- scan(void)
- {
-@@ -2142,6 +2223,7 @@ main(int argc, char *argv[])
- die("pledge");
- #endif /* __OpenBSD__ */
- scan();
-+ runautostart();
- run();
- cleanup();
- XCloseDisplay(dpy);
---
-2.27.0
-
diff --git a/dwm-6.2/dwm-pertag-6.2.diff b/dwm-6.2/dwm-pertag-6.2.diff
deleted file mode 100644
index d753727..0000000
--- a/dwm-6.2/dwm-pertag-6.2.diff
+++ /dev/null
@@ -1,177 +0,0 @@
-diff --git a/dwm.c b/dwm.c
-index 4465af1..6474055 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 {
-@@ -271,6 +273,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]; };
-
-@@ -631,6 +642,7 @@ Monitor *
- createmon(void)
- {
- Monitor *m;
-+ unsigned int i;
-
- m = ecalloc(1, sizeof(Monitor));
- m->tagset[0] = m->tagset[1] = 1;
-@@ -641,6 +653,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;
- }
-
-@@ -966,7 +992,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);
- }
-
-@@ -1501,9 +1527,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);
-@@ -1522,7 +1548,7 @@ setmfact(const Arg *arg)
- f = arg->f < 1.0 ? arg->f + selmon->mfact : arg->f - 1.0;
- if (f < 0.1 || f > 0.9)
- return;
-- selmon->mfact = f;
-+ selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag] = f;
- arrange(selmon);
- }
-
-@@ -1699,7 +1725,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);
-@@ -1738,9 +1764,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);
- }
-@@ -2035,11 +2085,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/dwm-6.2/dwm-systray-6.2.diff b/dwm-6.2/dwm-systray-6.2.diff
deleted file mode 100644
index 27187ac..0000000
--- a/dwm-6.2/dwm-systray-6.2.diff
+++ /dev/null
@@ -1,746 +0,0 @@
-From 4001ccae7b1a41bdcb247b0cf095a51af7b68c28 Mon Sep 17 00:00:00 2001
-From: Igor Gevka <igor.gevka@gmail.com>
-Date: Sun, 16 Feb 2020 15:03:10 -0800
-Subject: [PATCH] [PATCH] Implements a system tray for dwm.
-
-Original author: Jan Christoph Ebersbach <jceb@e-jc.de>, inspired by http://code.google.com/p/dwm-plus
-URL: http://dwm.suckless.org/patches/systray
-dwm 6.2 port by Igor Gevka <igor.gevka@gmail.com>
----
- config.def.h | 4 +
- dwm.c | 404 +++++++++++++++++++++++++++++++++++++++++++++++----
- 2 files changed, 382 insertions(+), 26 deletions(-)
-
-diff --git a/config.def.h b/config.def.h
-index 1c0b587..2d824d1 100644
---- a/config.def.h
-+++ b/config.def.h
-@@ -3,6 +3,10 @@
- /* appearance */
- static const unsigned int borderpx = 1; /* border pixel of windows */
- static const unsigned int snap = 32; /* snap pixel */
-+static const unsigned int systraypinning = 0; /* 0: sloppy systray follows selected monitor, >0: pin systray to monitor X */
-+static const unsigned int systrayspacing = 2; /* systray spacing */
-+static const int systraypinningfailfirst = 1; /* 1: if pinning fails, display systray on the first monitor, False: display systray on the last monitor*/
-+static const int showsystray = 1; /* 0 means no systray */
- 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" };
-diff --git a/dwm.c b/dwm.c
-index 4465af1..3e361fa 100644
---- a/dwm.c
-+++ b/dwm.c
-@@ -57,12 +57,30 @@
- #define TAGMASK ((1 << LENGTH(tags)) - 1)
- #define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad)
-
-+#define SYSTEM_TRAY_REQUEST_DOCK 0
-+
-+/* XEMBED messages */
-+#define XEMBED_EMBEDDED_NOTIFY 0
-+#define XEMBED_WINDOW_ACTIVATE 1
-+#define XEMBED_FOCUS_IN 4
-+#define XEMBED_MODALITY_ON 10
-+
-+#define XEMBED_MAPPED (1 << 0)
-+#define XEMBED_WINDOW_ACTIVATE 1
-+#define XEMBED_WINDOW_DEACTIVATE 2
-+
-+#define VERSION_MAJOR 0
-+#define VERSION_MINOR 0
-+#define XEMBED_EMBEDDED_VERSION (VERSION_MAJOR << 16) | VERSION_MINOR
-+
- /* enums */
- enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
- enum { SchemeNorm, SchemeSel }; /* color schemes */
- enum { NetSupported, NetWMName, NetWMState, NetWMCheck,
-+ NetSystemTray, NetSystemTrayOP, NetSystemTrayOrientation, NetSystemTrayOrientationHorz,
- NetWMFullscreen, NetActiveWindow, NetWMWindowType,
- NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */
-+enum { Manager, Xembed, XembedInfo, XLast }; /* Xembed atoms */
- enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */
- enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle,
- ClkClientWin, ClkRootWin, ClkLast }; /* clicks */
-@@ -141,6 +159,12 @@ typedef struct {
- int monitor;
- } Rule;
-
-+typedef struct Systray Systray;
-+struct Systray {
-+ Window win;
-+ Client *icons;
-+};
-+
- /* function declarations */
- static void applyrules(Client *c);
- static int applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact);
-@@ -169,8 +193,10 @@ 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 unsigned int getsystraywidth();
- static int gettextprop(Window w, Atom atom, char *text, unsigned int size);
- static void grabbuttons(Client *c, int focused);
- static void grabkeys(void);
-@@ -188,13 +214,16 @@ 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 removesystrayicon(Client *i);
- static void resize(Client *c, int x, int y, int w, int h, int interact);
-+static void resizebarwin(Monitor *m);
- static void resizeclient(Client *c, int x, int y, int w, int h);
- static void resizemouse(const Arg *arg);
-+static void resizerequest(XEvent *e);
- static void restack(Monitor *m);
- static void run(void);
- static void scan(void);
--static int sendevent(Client *c, Atom proto);
-+static int sendevent(Window w, Atom proto, int m, long d0, long d1, long d2, long d3, long d4);
- static void sendmon(Client *c, Monitor *m);
- static void setclientstate(Client *c, long state);
- static void setfocus(Client *c);
-@@ -206,6 +235,7 @@ static void seturgent(Client *c, int urg);
- static void showhide(Client *c);
- static void sigchld(int unused);
- static void spawn(const Arg *arg);
-+static Monitor *systraytomon(Monitor *m);
- static void tag(const Arg *arg);
- static void tagmon(const Arg *arg);
- static void tile(Monitor *);
-@@ -223,18 +253,23 @@ static int updategeom(void);
- static void updatenumlockmask(void);
- static void updatesizehints(Client *c);
- static void updatestatus(void);
-+static void updatesystray(void);
-+static void updatesystrayicongeom(Client *i, int w, int h);
-+static void updatesystrayiconstate(Client *i, XPropertyEvent *ev);
- 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 Client *wintosystrayicon(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 Systray *systray = NULL;
- static const char broken[] = "broken";
- static char stext[256];
- static int screen;
-@@ -257,9 +292,10 @@ static void (*handler[LASTEvent]) (XEvent *) = {
- [MapRequest] = maprequest,
- [MotionNotify] = motionnotify,
- [PropertyNotify] = propertynotify,
-+ [ResizeRequest] = resizerequest,
- [UnmapNotify] = unmapnotify
- };
--static Atom wmatom[WMLast], netatom[NetLast];
-+static Atom wmatom[WMLast], netatom[NetLast], xatom[XLast];
- static int running = 1;
- static Cur *cursor[CurLast];
- static Clr **scheme;
-@@ -439,7 +475,7 @@ buttonpress(XEvent *e)
- arg.ui = 1 << i;
- } else if (ev->x < x + blw)
- click = ClkLtSymbol;
-- else if (ev->x > selmon->ww - TEXTW(stext))
-+ else if (ev->x > selmon->ww - TEXTW(stext) - getsystraywidth())
- click = ClkStatusText;
- else
- click = ClkWinTitle;
-@@ -482,6 +518,11 @@ cleanup(void)
- XUngrabKey(dpy, AnyKey, AnyModifier, root);
- while (mons)
- cleanupmon(mons);
-+ if (showsystray) {
-+ XUnmapWindow(dpy, systray->win);
-+ XDestroyWindow(dpy, systray->win);
-+ free(systray);
-+ }
- for (i = 0; i < CurLast; i++)
- drw_cur_free(drw, cursor[i]);
- for (i = 0; i < LENGTH(colors); i++)
-@@ -512,9 +553,57 @@ cleanupmon(Monitor *mon)
- void
- clientmessage(XEvent *e)
- {
-+ XWindowAttributes wa;
-+ XSetWindowAttributes swa;
- XClientMessageEvent *cme = &e->xclient;
- Client *c = wintoclient(cme->window);
-
-+ if (showsystray && cme->window == systray->win && cme->message_type == netatom[NetSystemTrayOP]) {
-+ /* add systray icons */
-+ if (cme->data.l[1] == SYSTEM_TRAY_REQUEST_DOCK) {
-+ if (!(c = (Client *)calloc(1, sizeof(Client))))
-+ die("fatal: could not malloc() %u bytes\n", sizeof(Client));
-+ if (!(c->win = cme->data.l[2])) {
-+ free(c);
-+ return;
-+ }
-+ c->mon = selmon;
-+ c->next = systray->icons;
-+ systray->icons = c;
-+ if (!XGetWindowAttributes(dpy, c->win, &wa)) {
-+ /* use sane defaults */
-+ wa.width = bh;
-+ wa.height = bh;
-+ wa.border_width = 0;
-+ }
-+ c->x = c->oldx = c->y = c->oldy = 0;
-+ c->w = c->oldw = wa.width;
-+ c->h = c->oldh = wa.height;
-+ c->oldbw = wa.border_width;
-+ c->bw = 0;
-+ c->isfloating = True;
-+ /* reuse tags field as mapped status */
-+ c->tags = 1;
-+ updatesizehints(c);
-+ updatesystrayicongeom(c, wa.width, wa.height);
-+ XAddToSaveSet(dpy, c->win);
-+ XSelectInput(dpy, c->win, StructureNotifyMask | PropertyChangeMask | ResizeRedirectMask);
-+ XReparentWindow(dpy, c->win, systray->win, 0, 0);
-+ /* use parents background color */
-+ swa.background_pixel = scheme[SchemeNorm][ColBg].pixel;
-+ XChangeWindowAttributes(dpy, c->win, CWBackPixel, &swa);
-+ sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_EMBEDDED_NOTIFY, 0 , systray->win, XEMBED_EMBEDDED_VERSION);
-+ /* FIXME not sure if I have to send these events, too */
-+ sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_FOCUS_IN, 0 , systray->win, XEMBED_EMBEDDED_VERSION);
-+ sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_WINDOW_ACTIVATE, 0 , systray->win, XEMBED_EMBEDDED_VERSION);
-+ sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_MODALITY_ON, 0 , systray->win, XEMBED_EMBEDDED_VERSION);
-+ XSync(dpy, False);
-+ resizebarwin(selmon);
-+ updatesystray();
-+ setclientstate(c, NormalState);
-+ }
-+ return;
-+ }
- if (!c)
- return;
- if (cme->message_type == netatom[NetWMState]) {
-@@ -567,7 +656,7 @@ configurenotify(XEvent *e)
- 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);
-+ resizebarwin(m);
- }
- focus(NULL);
- arrange(NULL);
-@@ -652,6 +741,11 @@ destroynotify(XEvent *e)
-
- if ((c = wintoclient(ev->window)))
- unmanage(c, 1);
-+ else if ((c = wintosystrayicon(ev->window))) {
-+ removesystrayicon(c);
-+ resizebarwin(selmon);
-+ updatesystray();
-+ }
- }
-
- void
-@@ -695,19 +789,23 @@ dirtomon(int dir)
- void
- drawbar(Monitor *m)
- {
-- int x, w, sw = 0;
-+ int x, w, sw = 0, stw = 0;
- int boxs = drw->fonts->h / 9;
- int boxw = drw->fonts->h / 6 + 2;
- unsigned int i, occ = 0, urg = 0;
- Client *c;
-
-+ if(showsystray && m == systraytomon(m))
-+ stw = getsystraywidth();
-+
- /* 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]);
-- sw = TEXTW(stext) - lrpad + 2; /* 2px right padding */
-- drw_text(drw, m->ww - sw, 0, sw, bh, 0, stext, 0);
-+ sw = TEXTW(stext) - lrpad / 2 + 2; /* 2px right padding */
-+ drw_text(drw, m->ww - sw - stw, 0, sw, bh, lrpad / 2 - 2, stext, 0);
- }
-
-+ resizebarwin(m);
- for (c = m->clients; c; c = c->next) {
- occ |= c->tags;
- if (c->isurgent)
-@@ -728,7 +826,7 @@ drawbar(Monitor *m)
- drw_setscheme(drw, scheme[SchemeNorm]);
- x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0);
-
-- if ((w = m->ww - sw - x) > bh) {
-+ if ((w = m->ww - sw - stw - 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);
-@@ -739,7 +837,7 @@ drawbar(Monitor *m)
- drw_rect(drw, x, 0, w, bh, 1, 1);
- }
- }
-- drw_map(drw, m->barwin, 0, 0, m->ww, bh);
-+ drw_map(drw, m->barwin, 0, 0, m->ww - stw, bh);
- }
-
- void
-@@ -776,8 +874,11 @@ expose(XEvent *e)
- Monitor *m;
- XExposeEvent *ev = &e->xexpose;
-
-- if (ev->count == 0 && (m = wintomon(ev->window)))
-+ if (ev->count == 0 && (m = wintomon(ev->window))) {
- drawbar(m);
-+ if (m == selmon)
-+ updatesystray();
-+ }
- }
-
- void
-@@ -862,10 +963,17 @@ getatomprop(Client *c, Atom prop)
- unsigned long dl;
- unsigned char *p = NULL;
- Atom da, atom = None;
-+ /* FIXME getatomprop should return the number of items and a pointer to
-+ * the stored data instead of this workaround */
-+ Atom req = XA_ATOM;
-+ if (prop == xatom[XembedInfo])
-+ req = xatom[XembedInfo];
-
-- if (XGetWindowProperty(dpy, c->win, prop, 0L, sizeof atom, False, XA_ATOM,
-+ if (XGetWindowProperty(dpy, c->win, prop, 0L, sizeof atom, False, req,
- &da, &di, &dl, &dl, &p) == Success && p) {
- atom = *(Atom *)p;
-+ if (da == xatom[XembedInfo] && dl == 2)
-+ atom = ((Atom *)p)[1];
- XFree(p);
- }
- return atom;
-@@ -899,6 +1007,16 @@ getstate(Window w)
- return result;
- }
-
-+unsigned int
-+getsystraywidth()
-+{
-+ unsigned int w = 0;
-+ Client *i;
-+ if(showsystray)
-+ for(i = systray->icons; i; w += i->w + systrayspacing, i = i->next) ;
-+ return w ? w + systrayspacing : 1;
-+}
-+
- int
- gettextprop(Window w, Atom atom, char *text, unsigned int size)
- {
-@@ -1003,7 +1121,7 @@ killclient(const Arg *arg)
- {
- if (!selmon->sel)
- return;
-- if (!sendevent(selmon->sel, wmatom[WMDelete])) {
-+ if (!sendevent(selmon->sel->win, wmatom[WMDelete], NoEventMask, wmatom[WMDelete], CurrentTime, 0 , 0, 0)) {
- XGrabServer(dpy);
- XSetErrorHandler(xerrordummy);
- XSetCloseDownMode(dpy, DestroyAll);
-@@ -1091,6 +1209,12 @@ maprequest(XEvent *e)
- {
- static XWindowAttributes wa;
- XMapRequestEvent *ev = &e->xmaprequest;
-+ Client *i;
-+ if ((i = wintosystrayicon(ev->window))) {
-+ sendevent(i->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_WINDOW_ACTIVATE, 0, systray->win, XEMBED_EMBEDDED_VERSION);
-+ resizebarwin(selmon);
-+ updatesystray();
-+ }
-
- if (!XGetWindowAttributes(dpy, ev->window, &wa))
- return;
-@@ -1215,6 +1339,16 @@ propertynotify(XEvent *e)
- Window trans;
- XPropertyEvent *ev = &e->xproperty;
-
-+ if ((c = wintosystrayicon(ev->window))) {
-+ if (ev->atom == XA_WM_NORMAL_HINTS) {
-+ updatesizehints(c);
-+ updatesystrayicongeom(c, c->w, c->h);
-+ }
-+ else
-+ updatesystrayiconstate(c, ev);
-+ resizebarwin(selmon);
-+ updatesystray();
-+ }
- if ((ev->window == root) && (ev->atom == XA_WM_NAME))
- updatestatus();
- else if (ev->state == PropertyDelete)
-@@ -1265,6 +1399,20 @@ recttomon(int x, int y, int w, int h)
- return r;
- }
-
-+void
-+removesystrayicon(Client *i)
-+{
-+ Client **ii;
-+
-+ if (!showsystray || !i)
-+ return;
-+ for (ii = &systray->icons; *ii && *ii != i; ii = &(*ii)->next);
-+ if (ii)
-+ *ii = i->next;
-+ free(i);
-+}
-+
-+
- void
- resize(Client *c, int x, int y, int w, int h, int interact)
- {
-@@ -1272,6 +1420,14 @@ resize(Client *c, int x, int y, int w, int h, int interact)
- resizeclient(c, x, y, w, h);
- }
-
-+void
-+resizebarwin(Monitor *m) {
-+ unsigned int w = m->ww;
-+ if (showsystray && m == systraytomon(m))
-+ w -= getsystraywidth();
-+ XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, w, bh);
-+}
-+
- void
- resizeclient(Client *c, int x, int y, int w, int h)
- {
-@@ -1344,6 +1500,19 @@ resizemouse(const Arg *arg)
- }
- }
-
-+void
-+resizerequest(XEvent *e)
-+{
-+ XResizeRequestEvent *ev = &e->xresizerequest;
-+ Client *i;
-+
-+ if ((i = wintosystrayicon(ev->window))) {
-+ updatesystrayicongeom(i, ev->width, ev->height);
-+ resizebarwin(selmon);
-+ updatesystray();
-+ }
-+}
-+
- void
- restack(Monitor *m)
- {
-@@ -1433,26 +1602,36 @@ setclientstate(Client *c, long state)
- }
-
- int
--sendevent(Client *c, Atom proto)
-+sendevent(Window w, Atom proto, int mask, long d0, long d1, long d2, long d3, long d4)
- {
- int n;
-- Atom *protocols;
-+ Atom *protocols, mt;
- int exists = 0;
- XEvent ev;
-
-- if (XGetWMProtocols(dpy, c->win, &protocols, &n)) {
-- while (!exists && n--)
-- exists = protocols[n] == proto;
-- XFree(protocols);
-+ if (proto == wmatom[WMTakeFocus] || proto == wmatom[WMDelete]) {
-+ mt = wmatom[WMProtocols];
-+ if (XGetWMProtocols(dpy, w, &protocols, &n)) {
-+ while (!exists && n--)
-+ exists = protocols[n] == proto;
-+ XFree(protocols);
-+ }
-+ }
-+ else {
-+ exists = True;
-+ mt = proto;
- }
- if (exists) {
- ev.type = ClientMessage;
-- ev.xclient.window = c->win;
-- ev.xclient.message_type = wmatom[WMProtocols];
-+ ev.xclient.window = w;
-+ ev.xclient.message_type = mt;
- ev.xclient.format = 32;
-- ev.xclient.data.l[0] = proto;
-- ev.xclient.data.l[1] = CurrentTime;
-- XSendEvent(dpy, c->win, False, NoEventMask, &ev);
-+ ev.xclient.data.l[0] = d0;
-+ ev.xclient.data.l[1] = d1;
-+ ev.xclient.data.l[2] = d2;
-+ ev.xclient.data.l[3] = d3;
-+ ev.xclient.data.l[4] = d4;
-+ XSendEvent(dpy, w, False, mask, &ev);
- }
- return exists;
- }
-@@ -1466,7 +1645,7 @@ setfocus(Client *c)
- XA_WINDOW, 32, PropModeReplace,
- (unsigned char *) &(c->win), 1);
- }
-- sendevent(c, wmatom[WMTakeFocus]);
-+ sendevent(c->win, wmatom[WMTakeFocus], NoEventMask, wmatom[WMTakeFocus], CurrentTime, 0, 0, 0);
- }
-
- void
-@@ -1555,6 +1734,10 @@ setup(void)
- wmatom[WMTakeFocus] = XInternAtom(dpy, "WM_TAKE_FOCUS", False);
- netatom[NetActiveWindow] = XInternAtom(dpy, "_NET_ACTIVE_WINDOW", False);
- netatom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False);
-+ netatom[NetSystemTray] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_S0", False);
-+ netatom[NetSystemTrayOP] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_OPCODE", False);
-+ netatom[NetSystemTrayOrientation] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_ORIENTATION", False);
-+ netatom[NetSystemTrayOrientationHorz] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_ORIENTATION_HORZ", 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);
-@@ -1562,6 +1745,9 @@ setup(void)
- 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);
-+ xatom[Manager] = XInternAtom(dpy, "MANAGER", False);
-+ xatom[Xembed] = XInternAtom(dpy, "_XEMBED", False);
-+ xatom[XembedInfo] = XInternAtom(dpy, "_XEMBED_INFO", False);
- /* init cursors */
- cursor[CurNormal] = drw_cur_create(drw, XC_left_ptr);
- cursor[CurResize] = drw_cur_create(drw, XC_sizing);
-@@ -1570,6 +1756,8 @@ setup(void)
- scheme = ecalloc(LENGTH(colors), sizeof(Clr *));
- for (i = 0; i < LENGTH(colors); i++)
- scheme[i] = drw_scm_create(drw, colors[i], 3);
-+ /* init system tray */
-+ updatesystray();
- /* init bars */
- updatebars();
- updatestatus();
-@@ -1701,7 +1889,18 @@ togglebar(const Arg *arg)
- {
- selmon->showbar = !selmon->showbar;
- updatebarpos(selmon);
-- XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh);
-+ resizebarwin(selmon);
-+ if (showsystray) {
-+ XWindowChanges wc;
-+ if (!selmon->showbar)
-+ wc.y = -bh;
-+ else if (selmon->showbar) {
-+ wc.y = 0;
-+ if (!selmon->topbar)
-+ wc.y = selmon->mh - bh;
-+ }
-+ XConfigureWindow(dpy, systray->win, CWY, &wc);
-+ }
- arrange(selmon);
- }
-
-@@ -1796,11 +1995,18 @@ unmapnotify(XEvent *e)
- else
- unmanage(c, 0);
- }
-+ else if ((c = wintosystrayicon(ev->window))) {
-+ /* KLUDGE! sometimes icons occasionally unmap their windows, but do
-+ * _not_ destroy them. We map those windows back */
-+ XMapRaised(dpy, c->win);
-+ updatesystray();
-+ }
- }
-
- void
- updatebars(void)
- {
-+ unsigned int w;
- Monitor *m;
- XSetWindowAttributes wa = {
- .override_redirect = True,
-@@ -1811,10 +2017,15 @@ updatebars(void)
- 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),
-+ w = m->ww;
-+ if (showsystray && m == systraytomon(m))
-+ w -= getsystraywidth();
-+ m->barwin = XCreateWindow(dpy, root, m->wx, m->by, w, bh, 0, DefaultDepth(dpy, screen),
- CopyFromParent, DefaultVisual(dpy, screen),
- CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa);
- XDefineCursor(dpy, m->barwin, cursor[CurNormal]->cursor);
-+ if (showsystray && m == systraytomon(m))
-+ XMapRaised(dpy, systray->win);
- XMapRaised(dpy, m->barwin);
- XSetClassHint(dpy, m->barwin, &ch);
- }
-@@ -1990,6 +2201,121 @@ updatestatus(void)
- if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext)))
- strcpy(stext, "dwm-"VERSION);
- drawbar(selmon);
-+ updatesystray();
-+}
-+
-+void
-+updatesystrayicongeom(Client *i, int w, int h)
-+{
-+ if (i) {
-+ i->h = bh;
-+ if (w == h)
-+ i->w = bh;
-+ else if (h == bh)
-+ i->w = w;
-+ else
-+ i->w = (int) ((float)bh * ((float)w / (float)h));
-+ applysizehints(i, &(i->x), &(i->y), &(i->w), &(i->h), False);
-+ /* force icons into the systray dimensions if they don't want to */
-+ if (i->h > bh) {
-+ if (i->w == i->h)
-+ i->w = bh;
-+ else
-+ i->w = (int) ((float)bh * ((float)i->w / (float)i->h));
-+ i->h = bh;
-+ }
-+ }
-+}
-+
-+void
-+updatesystrayiconstate(Client *i, XPropertyEvent *ev)
-+{
-+ long flags;
-+ int code = 0;
-+
-+ if (!showsystray || !i || ev->atom != xatom[XembedInfo] ||
-+ !(flags = getatomprop(i, xatom[XembedInfo])))
-+ return;
-+
-+ if (flags & XEMBED_MAPPED && !i->tags) {
-+ i->tags = 1;
-+ code = XEMBED_WINDOW_ACTIVATE;
-+ XMapRaised(dpy, i->win);
-+ setclientstate(i, NormalState);
-+ }
-+ else if (!(flags & XEMBED_MAPPED) && i->tags) {
-+ i->tags = 0;
-+ code = XEMBED_WINDOW_DEACTIVATE;
-+ XUnmapWindow(dpy, i->win);
-+ setclientstate(i, WithdrawnState);
-+ }
-+ else
-+ return;
-+ sendevent(i->win, xatom[Xembed], StructureNotifyMask, CurrentTime, code, 0,
-+ systray->win, XEMBED_EMBEDDED_VERSION);
-+}
-+
-+void
-+updatesystray(void)
-+{
-+ XSetWindowAttributes wa;
-+ XWindowChanges wc;
-+ Client *i;
-+ Monitor *m = systraytomon(NULL);
-+ unsigned int x = m->mx + m->mw;
-+ unsigned int w = 1;
-+
-+ if (!showsystray)
-+ return;
-+ if (!systray) {
-+ /* init systray */
-+ if (!(systray = (Systray *)calloc(1, sizeof(Systray))))
-+ die("fatal: could not malloc() %u bytes\n", sizeof(Systray));
-+ systray->win = XCreateSimpleWindow(dpy, root, x, m->by, w, bh, 0, 0, scheme[SchemeSel][ColBg].pixel);
-+ wa.event_mask = ButtonPressMask | ExposureMask;
-+ wa.override_redirect = True;
-+ wa.background_pixel = scheme[SchemeNorm][ColBg].pixel;
-+ XSelectInput(dpy, systray->win, SubstructureNotifyMask);
-+ XChangeProperty(dpy, systray->win, netatom[NetSystemTrayOrientation], XA_CARDINAL, 32,
-+ PropModeReplace, (unsigned char *)&netatom[NetSystemTrayOrientationHorz], 1);
-+ XChangeWindowAttributes(dpy, systray->win, CWEventMask|CWOverrideRedirect|CWBackPixel, &wa);
-+ XMapRaised(dpy, systray->win);
-+ XSetSelectionOwner(dpy, netatom[NetSystemTray], systray->win, CurrentTime);
-+ if (XGetSelectionOwner(dpy, netatom[NetSystemTray]) == systray->win) {
-+ sendevent(root, xatom[Manager], StructureNotifyMask, CurrentTime, netatom[NetSystemTray], systray->win, 0, 0);
-+ XSync(dpy, False);
-+ }
-+ else {
-+ fprintf(stderr, "dwm: unable to obtain system tray.\n");
-+ free(systray);
-+ systray = NULL;
-+ return;
-+ }
-+ }
-+ for (w = 0, i = systray->icons; i; i = i->next) {
-+ /* make sure the background color stays the same */
-+ wa.background_pixel = scheme[SchemeNorm][ColBg].pixel;
-+ XChangeWindowAttributes(dpy, i->win, CWBackPixel, &wa);
-+ XMapRaised(dpy, i->win);
-+ w += systrayspacing;
-+ i->x = w;
-+ XMoveResizeWindow(dpy, i->win, i->x, 0, i->w, i->h);
-+ w += i->w;
-+ if (i->mon != m)
-+ i->mon = m;
-+ }
-+ w = w ? w + systrayspacing : 1;
-+ x -= w;
-+ XMoveResizeWindow(dpy, systray->win, x, m->by, w, bh);
-+ wc.x = x; wc.y = m->by; wc.width = w; wc.height = bh;
-+ wc.stack_mode = Above; wc.sibling = m->barwin;
-+ XConfigureWindow(dpy, systray->win, CWX|CWY|CWWidth|CWHeight|CWSibling|CWStackMode, &wc);
-+ XMapWindow(dpy, systray->win);
-+ XMapSubwindows(dpy, systray->win);
-+ /* redraw background */
-+ XSetForeground(dpy, drw->gc, scheme[SchemeNorm][ColBg].pixel);
-+ XFillRectangle(dpy, systray->win, drw->gc, 0, 0, w, bh);
-+ XSync(dpy, False);
- }
-
- void
-@@ -2057,6 +2383,16 @@ wintoclient(Window w)
- return NULL;
- }
-
-+Client *
-+wintosystrayicon(Window w) {
-+ Client *i = NULL;
-+
-+ if (!showsystray || !w)
-+ return i;
-+ for (i = systray->icons; i && i->win != w; i = i->next) ;
-+ return i;
-+}
-+
- Monitor *
- wintomon(Window w)
- {
-@@ -2110,6 +2446,22 @@ xerrorstart(Display *dpy, XErrorEvent *ee)
- return -1;
- }
-
-+Monitor *
-+systraytomon(Monitor *m) {
-+ Monitor *t;
-+ int i, n;
-+ if(!systraypinning) {
-+ if(!m)
-+ return selmon;
-+ return m == selmon ? m : NULL;
-+ }
-+ for(n = 1, t = mons; t && t->next; n++, t = t->next) ;
-+ for(i = 1, t = mons; t && t->next && i < systraypinning; i++, t = t->next) ;
-+ if(systraypinningfailfirst && n < systraypinning)
-+ return mons;
-+ return t;
-+}
-+
- void
- zoom(const Arg *arg)
- {
---
-2.17.1
-
diff --git a/dwm-6.2/dwm.1 b/dwm-6.2/dwm.1
deleted file mode 100644
index 9533aa6..0000000
--- a/dwm-6.2/dwm.1
+++ /dev/null
@@ -1,199 +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.
-.P
-On start, dwm can start additional programs that may be specified in two special
-shell scripts (see the FILES section below), autostart_blocking.sh and
-autostart.sh. The former is executed first and dwm will wait for its
-termination before starting. The latter is executed in the background before
-dwm enters its handler loop.
-.P
-Either of these files may be omitted.
-.SH OPTIONS
-.TP
-.B \-v
-prints version information to standard output, 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 FILES
-The files containing programs to be started along with dwm are searched for in
-the following directories:
-.IP "1. $XDG_DATA_HOME/dwm"
-.IP "2. $HOME/.local/share/dwm"
-.IP "3. $HOME/.dwm"
-.P
-The first existing directory is scanned for any of the autostart files below.
-.TP 15
-autostart.sh
-This file is started as a shell background process before dwm enters its handler
-loop.
-.TP 15
-autostart_blocking.sh
-This file is started before any autostart.sh; dwm waits for its termination.
-.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/dwm-6.2/dwm.c b/dwm-6.2/dwm.c
deleted file mode 100644
index 7d1582c..0000000
--- a/dwm-6.2/dwm.c
+++ /dev/null
@@ -1,2674 +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/stat.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 + gappx)
-#define HEIGHT(X) ((X)->h + 2 * (X)->bw + gappx)
-#define TAGMASK ((1 << LENGTH(tags)) - 1)
-#define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad)
-
-#define SYSTEM_TRAY_REQUEST_DOCK 0
-
-/* XEMBED messages */
-#define XEMBED_EMBEDDED_NOTIFY 0
-#define XEMBED_WINDOW_ACTIVATE 1
-#define XEMBED_FOCUS_IN 4
-#define XEMBED_MODALITY_ON 10
-
-#define XEMBED_MAPPED (1 << 0)
-#define XEMBED_WINDOW_ACTIVATE 1
-#define XEMBED_WINDOW_DEACTIVATE 2
-
-#define VERSION_MAJOR 0
-#define VERSION_MINOR 0
-#define XEMBED_EMBEDDED_VERSION (VERSION_MAJOR << 16) | VERSION_MINOR
-
-/* enums */
-enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
-enum { SchemeNorm, SchemeSel }; /* color schemes */
-enum { NetSupported, NetWMName, NetWMState, NetWMCheck,
- NetSystemTray, NetSystemTrayOP, NetSystemTrayOrientation, NetSystemTrayOrientationHorz,
- NetWMFullscreen, NetActiveWindow, NetWMWindowType,
- NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */
-enum { Manager, Xembed, XembedInfo, XLast }; /* Xembed 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;
-
-typedef struct Systray Systray;
-struct Systray {
- Window win;
- Client *icons;
-};
-
-/* function declarations */
-static void applydefaultlayouts();
-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 unsigned int getsystraywidth();
-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 removesystrayicon(Client *i);
-static void resize(Client *c, int x, int y, int w, int h, int interact);
-static void resizebarwin(Monitor *m);
-static void resizeclient(Client *c, int x, int y, int w, int h);
-static void resizemouse(const Arg *arg);
-static void resizerequest(XEvent *e);
-static void restack(Monitor *m);
-static void run(void);
-static void scan(void);
-static int sendevent(Window w, Atom proto, int m, long d0, long d1, long d2, long d3, long d4);
-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 Monitor *systraytomon(Monitor *m);
-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 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 updatesystray(void);
-static void updatesystrayicongeom(Client *i, int w, int h);
-static void updatesystrayiconstate(Client *i, XPropertyEvent *ev);
-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 Client *wintosystrayicon(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);
-static void bstack(Monitor *m);
-static void bstackhoriz(Monitor *m);
-
-/* variables */
-static Systray *systray = NULL;
-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,
- [ResizeRequest] = resizerequest,
- [UnmapNotify] = unmapnotify
-};
-static Atom wmatom[WMLast], netatom[NetLast], xatom[XLast];
-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
-applydefaultlayouts()
-{
- Monitor *m;
- int i = 0;
- for (m = mons; m; m = m->next) {
- if (i < LENGTH(lpm)) {
- m->lt[0] = &layouts[lpm[i]];
- m->lt[1] = &layouts[(lpm[i] + 1) % LENGTH(layouts)];
- strncpy(m->ltsymbol, layouts[lpm[i]].symbol, sizeof m->ltsymbol);
- for (i = 0; i <= LENGTH(tags); i++) {
- m->pertag->ltidxs[i][0] = m->lt[0];
- m->pertag->ltidxs[i][1] = m->lt[1];
- }
- }
- i++;
- }
-}
-
-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;
- 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];
-}
-
-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 - TEXTW(stext) - getsystraywidth())
- 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);
- if (showsystray) {
- XUnmapWindow(dpy, systray->win);
- XDestroyWindow(dpy, systray->win);
- free(systray);
- }
- 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)
-{
- XWindowAttributes wa;
- XSetWindowAttributes swa;
- XClientMessageEvent *cme = &e->xclient;
- Client *c = wintoclient(cme->window);
-
- if (showsystray && cme->window == systray->win && cme->message_type == netatom[NetSystemTrayOP]) {
- /* add systray icons */
- if (cme->data.l[1] == SYSTEM_TRAY_REQUEST_DOCK) {
- if (!(c = (Client *)calloc(1, sizeof(Client))))
- die("fatal: could not malloc() %u bytes\n", sizeof(Client));
- if (!(c->win = cme->data.l[2])) {
- free(c);
- return;
- }
- c->mon = selmon;
- c->next = systray->icons;
- systray->icons = c;
- if (!XGetWindowAttributes(dpy, c->win, &wa)) {
- /* use sane defaults */
- wa.width = bh;
- wa.height = bh;
- wa.border_width = 0;
- }
- c->x = c->oldx = c->y = c->oldy = 0;
- c->w = c->oldw = wa.width;
- c->h = c->oldh = wa.height;
- c->oldbw = wa.border_width;
- c->bw = 0;
- c->isfloating = True;
- /* reuse tags field as mapped status */
- c->tags = 1;
- updatesizehints(c);
- updatesystrayicongeom(c, wa.width, wa.height);
- XAddToSaveSet(dpy, c->win);
- XSelectInput(dpy, c->win, StructureNotifyMask | PropertyChangeMask | ResizeRedirectMask);
- XReparentWindow(dpy, c->win, systray->win, 0, 0);
- /* use parents background color */
- swa.background_pixel = scheme[SchemeNorm][ColBg].pixel;
- XChangeWindowAttributes(dpy, c->win, CWBackPixel, &swa);
- sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_EMBEDDED_NOTIFY, 0 , systray->win, XEMBED_EMBEDDED_VERSION);
- /* FIXME not sure if I have to send these events, too */
- sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_FOCUS_IN, 0 , systray->win, XEMBED_EMBEDDED_VERSION);
- sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_WINDOW_ACTIVATE, 0 , systray->win, XEMBED_EMBEDDED_VERSION);
- sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_MODALITY_ON, 0 , systray->win, XEMBED_EMBEDDED_VERSION);
- XSync(dpy, False);
- resizebarwin(selmon);
- updatesystray();
- setclientstate(c, NormalState);
- }
- return;
- }
- 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);
- resizebarwin(m);
- }
- 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);
- else if ((c = wintosystrayicon(ev->window))) {
- removesystrayicon(c);
- resizebarwin(selmon);
- updatesystray();
- }
-}
-
-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, sw = 0, stw = 0;
- int boxs = drw->fonts->h / 9;
- int boxw = drw->fonts->h / 6 + 2;
- unsigned int i, occ = 0, urg = 0;
- Client *c;
-
- if(showsystray && m == systraytomon(m))
- stw = getsystraywidth();
-
- /* 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]);
- sw = TEXTW(stext) - lrpad / 2 + 2; /* 2px right padding */
- drw_text(drw, m->ww - sw - stw, 0, sw, bh, lrpad / 2 - 2, stext, 0);
- }
-
- resizebarwin(m);
- 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 - sw - stw - 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 - stw, 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);
- if (m == selmon)
- updatesystray();
- }
-}
-
-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)
- 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;
- /* FIXME getatomprop should return the number of items and a pointer to
- * the stored data instead of this workaround */
- Atom req = XA_ATOM;
- if (prop == xatom[XembedInfo])
- req = xatom[XembedInfo];
-
- if (XGetWindowProperty(dpy, c->win, prop, 0L, sizeof atom, False, req,
- &da, &di, &dl, &dl, &p) == Success && p) {
- atom = *(Atom *)p;
- if (da == xatom[XembedInfo] && dl == 2)
- atom = ((Atom *)p)[1];
- 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;
-}
-
-unsigned int
-getsystraywidth()
-{
- unsigned int w = 0;
- Client *i;
- if(showsystray)
- for(i = systray->icons; i; w += i->w + systrayspacing, i = i->next) ;
- return w ? w + systrayspacing : 1;
-}
-
-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->win, wmatom[WMDelete], NoEventMask, wmatom[WMDelete], CurrentTime, 0 , 0, 0)) {
- 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;
- Client *i;
- if ((i = wintosystrayicon(ev->window))) {
- sendevent(i->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_WINDOW_ACTIVATE, 0, systray->win, XEMBED_EMBEDDED_VERSION);
- resizebarwin(selmon);
- updatesystray();
- }
-
- 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 ((c = wintosystrayicon(ev->window))) {
- if (ev->atom == XA_WM_NORMAL_HINTS) {
- updatesizehints(c);
- updatesystrayicongeom(c, c->w, c->h);
- }
- else
- updatesystrayiconstate(c, ev);
- resizebarwin(selmon);
- updatesystray();
- }
- 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
-removesystrayicon(Client *i)
-{
- Client **ii;
-
- if (!showsystray || !i)
- return;
- for (ii = &systray->icons; *ii && *ii != i; ii = &(*ii)->next);
- if (ii)
- *ii = i->next;
- free(i);
-}
-
-
-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
-resizebarwin(Monitor *m) {
- unsigned int w = m->ww;
- if (showsystray && m == systraytomon(m))
- w -= getsystraywidth();
- XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, w, bh);
-}
-
-void
-resizeclient(Client *c, int x, int y, int w, int h)
-{
- XWindowChanges wc;
- unsigned int gapoffset;
- unsigned int gapincr;
-
- wc.border_width = c->bw;
-
- /* Do nothing if layout is floating */
- if (c->isfloating || c->mon->lt[c->mon->sellt]->arrange == NULL) {
- gapincr = gapoffset = 0;
- } else {
- gapoffset = gappx;
- gapincr = 2 * gappx;
- }
-
- c->oldx = c->x; c->x = wc.x = x + gapoffset;
- c->oldy = c->y; c->y = wc.y = y + gapoffset;
- c->oldw = c->w; c->w = wc.width = w - gapincr;
- c->oldh = c->h; c->h = wc.height = h - gapincr;
-
- 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
-resizerequest(XEvent *e)
-{
- XResizeRequestEvent *ev = &e->xresizerequest;
- Client *i;
-
- if ((i = wintosystrayicon(ev->window))) {
- updatesystrayicongeom(i, ev->width, ev->height);
- resizebarwin(selmon);
- updatesystray();
- }
-}
-
-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(Window w, Atom proto, int mask, long d0, long d1, long d2, long d3, long d4)
-{
- int n;
- Atom *protocols, mt;
- int exists = 0;
- XEvent ev;
-
- if (proto == wmatom[WMTakeFocus] || proto == wmatom[WMDelete]) {
- mt = wmatom[WMProtocols];
- if (XGetWMProtocols(dpy, w, &protocols, &n)) {
- while (!exists && n--)
- exists = protocols[n] == proto;
- XFree(protocols);
- }
- }
- else {
- exists = True;
- mt = proto;
- }
- if (exists) {
- ev.type = ClientMessage;
- ev.xclient.window = w;
- ev.xclient.message_type = mt;
- ev.xclient.format = 32;
- ev.xclient.data.l[0] = d0;
- ev.xclient.data.l[1] = d1;
- ev.xclient.data.l[2] = d2;
- ev.xclient.data.l[3] = d3;
- ev.xclient.data.l[4] = d4;
- XSendEvent(dpy, w, False, mask, &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->win, wmatom[WMTakeFocus], NoEventMask, wmatom[WMTakeFocus], CurrentTime, 0, 0, 0);
-}
-
-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.1 || f > 0.9)
- 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[NetSystemTray] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_S0", False);
- netatom[NetSystemTrayOP] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_OPCODE", False);
- netatom[NetSystemTrayOrientation] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_ORIENTATION", False);
- netatom[NetSystemTrayOrientationHorz] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_ORIENTATION_HORZ", 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);
- xatom[Manager] = XInternAtom(dpy, "MANAGER", False);
- xatom[Xembed] = XInternAtom(dpy, "_XEMBED", False);
- xatom[XembedInfo] = XInternAtom(dpy, "_XEMBED_INFO", 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 system tray */
- updatesystray();
- /* 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 (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->ww - mw, m->wy + my, mw - (2*c->bw), h - (2*c->bw), 0);
- my += HEIGHT(c);
- } else {
- h = (m->wh - ty) / (n - i);
- resize(c, m->wx, m->wy + ty, m->ww - mw - (2*c->bw), h - (2*c->bw), 0);
- ty += HEIGHT(c);
- }
-}
-
-void
-togglebar(const Arg *arg)
-{
- selmon->showbar = selmon->pertag->showbars[selmon->pertag->curtag] = !selmon->showbar;
- updatebarpos(selmon);
- resizebarwin(selmon);
- if (showsystray) {
- XWindowChanges wc;
- if (!selmon->showbar)
- wc.y = -bh;
- else if (selmon->showbar) {
- wc.y = 0;
- if (!selmon->topbar)
- wc.y = selmon->mh - bh;
- }
- XConfigureWindow(dpy, systray->win, CWY, &wc);
- }
- 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
-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);
- }
- else if ((c = wintosystrayicon(ev->window))) {
- /* KLUDGE! sometimes icons occasionally unmap their windows, but do
- * _not_ destroy them. We map those windows back */
- XMapRaised(dpy, c->win);
- updatesystray();
- }
-}
-
-void
-updatebars(void)
-{
- unsigned int w;
- 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;
- w = m->ww;
- if (showsystray && m == systraytomon(m))
- w -= getsystraywidth();
- m->barwin = XCreateWindow(dpy, root, m->wx, m->by, w, bh, 0, DefaultDepth(dpy, screen),
- CopyFromParent, DefaultVisual(dpy, screen),
- CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa);
- XDefineCursor(dpy, m->barwin, cursor[CurNormal]->cursor);
- if (showsystray && m == systraytomon(m))
- XMapRaised(dpy, systray->win);
- 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);
- }
- }
- applydefaultlayouts();
- 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);
- updatesystray();
-}
-
-void
-updatesystrayicongeom(Client *i, int w, int h)
-{
- if (i) {
- i->h = bh;
- if (w == h)
- i->w = bh;
- else if (h == bh)
- i->w = w;
- else
- i->w = (int) ((float)bh * ((float)w / (float)h));
- applysizehints(i, &(i->x), &(i->y), &(i->w), &(i->h), False);
- /* force icons into the systray dimensions if they don't want to */
- if (i->h > bh) {
- if (i->w == i->h)
- i->w = bh;
- else
- i->w = (int) ((float)bh * ((float)i->w / (float)i->h));
- i->h = bh;
- }
- }
-}
-
-void
-updatesystrayiconstate(Client *i, XPropertyEvent *ev)
-{
- long flags;
- int code = 0;
-
- if (!showsystray || !i || ev->atom != xatom[XembedInfo] ||
- !(flags = getatomprop(i, xatom[XembedInfo])))
- return;
-
- if (flags & XEMBED_MAPPED && !i->tags) {
- i->tags = 1;
- code = XEMBED_WINDOW_ACTIVATE;
- XMapRaised(dpy, i->win);
- setclientstate(i, NormalState);
- }
- else if (!(flags & XEMBED_MAPPED) && i->tags) {
- i->tags = 0;
- code = XEMBED_WINDOW_DEACTIVATE;
- XUnmapWindow(dpy, i->win);
- setclientstate(i, WithdrawnState);
- }
- else
- return;
- sendevent(i->win, xatom[Xembed], StructureNotifyMask, CurrentTime, code, 0,
- systray->win, XEMBED_EMBEDDED_VERSION);
-}
-
-void
-updatesystray(void)
-{
- XSetWindowAttributes wa;
- XWindowChanges wc;
- Client *i;
- Monitor *m = systraytomon(NULL);
- unsigned int x = m->mx + m->mw;
- unsigned int w = 1;
-
- if (!showsystray)
- return;
- if (!systray) {
- /* init systray */
- if (!(systray = (Systray *)calloc(1, sizeof(Systray))))
- die("fatal: could not malloc() %u bytes\n", sizeof(Systray));
- systray->win = XCreateSimpleWindow(dpy, root, x, m->by, w, bh, 0, 0, scheme[SchemeSel][ColBg].pixel);
- wa.event_mask = ButtonPressMask | ExposureMask;
- wa.override_redirect = True;
- wa.background_pixel = scheme[SchemeNorm][ColBg].pixel;
- XSelectInput(dpy, systray->win, SubstructureNotifyMask);
- XChangeProperty(dpy, systray->win, netatom[NetSystemTrayOrientation], XA_CARDINAL, 32,
- PropModeReplace, (unsigned char *)&netatom[NetSystemTrayOrientationHorz], 1);
- XChangeWindowAttributes(dpy, systray->win, CWEventMask|CWOverrideRedirect|CWBackPixel, &wa);
- XMapRaised(dpy, systray->win);
- XSetSelectionOwner(dpy, netatom[NetSystemTray], systray->win, CurrentTime);
- if (XGetSelectionOwner(dpy, netatom[NetSystemTray]) == systray->win) {
- sendevent(root, xatom[Manager], StructureNotifyMask, CurrentTime, netatom[NetSystemTray], systray->win, 0, 0);
- XSync(dpy, False);
- }
- else {
- fprintf(stderr, "dwm: unable to obtain system tray.\n");
- free(systray);
- systray = NULL;
- return;
- }
- }
- for (w = 0, i = systray->icons; i; i = i->next) {
- /* make sure the background color stays the same */
- wa.background_pixel = scheme[SchemeNorm][ColBg].pixel;
- XChangeWindowAttributes(dpy, i->win, CWBackPixel, &wa);
- XMapRaised(dpy, i->win);
- w += systrayspacing;
- i->x = w;
- XMoveResizeWindow(dpy, i->win, i->x, 0, i->w, i->h);
- w += i->w;
- if (i->mon != m)
- i->mon = m;
- }
- w = w ? w + systrayspacing : 1;
- x -= w;
- XMoveResizeWindow(dpy, systray->win, x, m->by, w, bh);
- wc.x = x; wc.y = m->by; wc.width = w; wc.height = bh;
- wc.stack_mode = Above; wc.sibling = m->barwin;
- XConfigureWindow(dpy, systray->win, CWX|CWY|CWWidth|CWHeight|CWSibling|CWStackMode, &wc);
- XMapWindow(dpy, systray->win);
- XMapSubwindows(dpy, systray->win);
- /* redraw background */
- XSetForeground(dpy, drw->gc, scheme[SchemeNorm][ColBg].pixel);
- XFillRectangle(dpy, systray->win, drw->gc, 0, 0, w, bh);
- XSync(dpy, False);
-}
-
-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;
-}
-
-Client *
-wintosystrayicon(Window w) {
- Client *i = NULL;
-
- if (!showsystray || !w)
- return i;
- for (i = systray->icons; i && i->win != w; i = i->next) ;
- return i;
-}
-
-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;
-}
-
-Monitor *
-systraytomon(Monitor *m) {
- Monitor *t;
- int i, n;
- if(!systraypinning) {
- if(!m)
- return selmon;
- return m == selmon ? m : NULL;
- }
- for(n = 1, t = mons; t && t->next; n++, t = t->next) ;
- for(i = 1, t = mons; t && t->next && i < systraypinning; i++, t = t->next) ;
- if(systraypinningfailfirst && n < systraypinning)
- return mons;
- return t;
-}
-
-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;
-}
-
-static void
-bstack(Monitor *m) {
- int w, h, mh, mx, tx, ty, tw;
- unsigned int i, n;
- Client *c;
-
- for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
- if (n == 0)
- return;
- if (n > m->nmaster) {
- mh = m->nmaster ? m->mfact * m->wh : 0;
- tw = m->ww / (n - m->nmaster);
- ty = m->wy + mh;
- } else {
- mh = m->wh;
- tw = m->ww;
- ty = m->wy;
- }
- for (i = mx = 0, tx = m->wx, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) {
- if (i < m->nmaster) {
- w = (m->ww - mx) / (MIN(n, m->nmaster) - i);
- resize(c, m->wx + mx, m->wy, w - (2 * c->bw), mh - (2 * c->bw), 0);
- mx += WIDTH(c);
- } else {
- h = m->wh - mh;
- resize(c, tx, ty, tw - (2 * c->bw), h - (2 * c->bw), 0);
- if (tw != m->ww)
- tx += WIDTH(c);
- }
- }
-}
-
-static void
-bstackhoriz(Monitor *m) {
- int w, mh, mx, tx, ty, th;
- unsigned int i, n;
- Client *c;
-
- for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
- if (n == 0)
- return;
- if (n > m->nmaster) {
- mh = m->nmaster ? m->mfact * m->wh : 0;
- th = (m->wh - mh) / (n - m->nmaster);
- ty = m->wy + mh;
- } else {
- th = mh = m->wh;
- ty = m->wy;
- }
- for (i = mx = 0, tx = m->wx, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) {
- if (i < m->nmaster) {
- w = (m->ww - mx) / (MIN(n, m->nmaster) - i);
- resize(c, m->wx + mx, m->wy, w - (2 * c->bw), mh - (2 * c->bw), 0);
- mx += WIDTH(c);
- } else {
- resize(c, tx, ty, m->ww - (2 * c->bw), th - (2 * c->bw), 0);
- if (th != m->wh)
- ty += HEIGHT(c);
- }
- }
-}
diff --git a/dwm-6.2/dwm.png b/dwm-6.2/dwm.png
deleted file mode 100644
index b1f9ba7..0000000
--- a/dwm-6.2/dwm.png
+++ /dev/null
Binary files differ
diff --git a/dwm-6.2/transient.c b/dwm-6.2/transient.c
deleted file mode 100644
index 040adb5..0000000
--- a/dwm-6.2/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/dwm-6.2/util.c b/dwm-6.2/util.c
deleted file mode 100644
index fe044fc..0000000
--- a/dwm-6.2/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/dwm-6.2/util.h b/dwm-6.2/util.h
deleted file mode 100644
index f633b51..0000000
--- a/dwm-6.2/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/kakrc b/kakrc
deleted file mode 100644
index 1588aab..0000000
--- a/kakrc
+++ /dev/null
@@ -1,31 +0,0 @@
-#colorscheme gruvbox-dark
-colorscheme dracula
-
-set-option global startup_info_version 9999999999
-set-option global ui_options terminal_assistant=dilbert
-#set-option -add global autoinfo normal
-
-set-option global indentwidth 4
-set-option global tabstop 4
-
-add-highlighter global/ show-matching
-
-map global normal <a-v> "k <a-j> ge"
-
-hook global WinCreate .* %{
- add-highlighter buffer/line-numbers number-lines -hlcursor
- add-highlighter buffer/eighty-columns column 80 default,rgb:301040
- add-highlighter buffer/whitespace regex '\h+$' 0:default,red
- add-highlighter buffer/brackets show-matching
- add-highlighter buffer/todo regex \b(TODO|FIXME|XXX|NOTE)\b 0:default+rb
-
- smarttab
- #indentguide-enable
- #indentguide-refresh-continuous
- #mark-show-enable
-}
-
-source "%val{config}/plugins/plug.kak/rc/plug.kak"
-plug "andreyorst/plug.kak" noload
-
-plug "andreyorst/smarttab.kak"
diff --git a/printer.cfg b/printer.cfg
deleted file mode 100644
index 11ae0e4..0000000
--- a/printer.cfg
+++ /dev/null
@@ -1,167 +0,0 @@
-# Klipper printer configuration
-
-[stepper_x]
-step_pin: PD7
-dir_pin: PC5
-enable_pin: !PD6
-step_distance: .01
-endstop_pin: ^!PC2
-position_endstop: -12
-position_max: 215
-position_min: -12
-homing_speed: 50
-
-[stepper_y]
-step_pin: PC6
-dir_pin: PC7
-enable_pin: !PD6
-step_distance: .01
-endstop_pin: ^!PC3
-position_endstop: -8
-position_min: -8
-position_max: 220
-homing_speed: 50
-
-[stepper_z]
-step_pin: PB3
-dir_pin: !PB2
-enable_pin: !PA5
-step_distance: .0025
-endstop_pin: probe:z_virtual_endstop
-position_max: 200
-homing_speed: 20
-
-[extruder]
-step_pin: PB1
-dir_pin: PB0
-enable_pin: !PD6
-step_distance: .0105
-nozzle_diameter: 0.400
-filament_diameter: 1.750
-heater_pin: PD5
-sensor_type: ATC Semitec 104GT-2
-sensor_pin: PA7
-control: pid
-pid_Kp: 25.81
-pid_Ki: 1.97
-pid_Kd: 84.57
-min_temp: 0
-max_temp: 275
-pressure_advance: 0.425 #0.475
-
-# [heater_bed]
-# heater_pin: PD4
-# sensor_type: ATC Semitec 104GT-2
-# sensor_pin: PA6
-# control: watermark
-# min_temp: 0
-# max_temp: 130
-
-[fan]
-pin: PB4
-
-[mcu]
-serial: /dev/serial/by-id/usb-1a86_USB2.0-Serial-if00-port0
-
-[printer]
-kinematics: cartesian
-max_velocity: 300
-max_accel: 1000
-max_z_velocity: 20
-max_z_accel: 100
-
-[display]
-lcd_type: hd44780
-rs_pin: PA3
-e_pin: PA2
-d4_pin: PD2
-d5_pin: PD3
-d6_pin: PC0
-d7_pin: PC1
-up_pin: PA1
-analog_range_up_pin: 9000, 13000
-down_pin: PA1
-analog_range_down_pin: 800, 1300
-click_pin: PA1
-analog_range_click_pin: 2000, 2500
-back_pin: PA1
-analog_range_back_pin: 4500, 5000
-#kill_pin: PA1
-#analog_range_kill_pin: 400, 600
-
-[bltouch]
-sensor_pin: ^PC4
-control_pin: PA4
-x_offset: 30
-y_offset: 0
-z_offset: 0.98 #0.87
-speed: 4
-samples: 2
-pin_move_time: 0.8
-pin_up_reports_not_triggered: true
-pin_up_touch_mode_reports_triggered: false
-
-[bed_mesh]
-speed: 50
-horizontal_move_z: 5
-mesh_min: 20,5
-mesh_max: 200,210
-probe_count: 3,3
-fade_start: 1.0
-fade_end: 0.0
-split_delta_z: .025
-move_check_distance: 7.0
-mesh_pps: 2,2
-algorithm: lagrange
-bicubic_tension: .2
-
-[force_move]
-enable_force_move: True
-
-[homing_override]
-gcode:
- G90 ; Use absolute position mode
- G1 Z15
- G28 X Y
- G0 X108 Y108 F6000 ; Centre of bed
- G28 Z
-set_position_z: 0.0
-
-[screws_tilt_adjust]
-screw1: -10,5
-screw1_name: front left screw
-screw2: 170,5
-screw2_name: front right screw
-screw3: 170,210
-screw3_name: rear right screw
-screw4: -10,210
-screw4_name: rear left screw
-horizontal_move_z: 5.
-speed: 50.
-screw_thread: CW-M3
-
-[virtual_sdcard]
-path: ~/.octoprint/uploads
-
-[idle_timeout]
-gcode:
- TURN_OFF_HEATERS
-timeout: 600
-
-# [pause_resume]
-
-# [gcode_macro M600]
-# default_parameter_X: -10
-# default_parameter_Y: 5
-# default_parameter_Z: 100
-# gcode:
-# SAVE_GCODE_STATE NAME=M600_state
-# PAUSE
-# G91
-# G1 E-.8 F2700
-# G1 Z{Z}
-# G90
-# G1 X{X} Y{Y} F3000
-# G91
-# G1 E-50 F1000
-# RESTORE_GCODE_STATE NAME=M600_state
diff --git a/qmk_atreus_layout/config.h b/qmk_atreus_layout/config.h
deleted file mode 100644
index 9b69a4a..0000000
--- a/qmk_atreus_layout/config.h
+++ /dev/null
@@ -1,14 +0,0 @@
-#pragma once
-
-// Prevent normal rollover on alphas from accidentally triggering mods.
-#define IGNORE_MOD_TAP_INTERRUPT
-
-// Recommended for heavy chording.
-#define QMK_KEYS_PER_SCAN 4
-
-// Mouse key speed and acceleration.
-#define MOUSEKEY_DELAY 0
-#define MOUSEKEY_INTERVAL 16
-#define MOUSEKEY_WHEEL_DELAY 0
-#define MOUSEKEY_MAX_SPEED 6
-#define MOUSEKEY_TIME_TO_MAX 64
diff --git a/qmk_atreus_layout/keymap.c b/qmk_atreus_layout/keymap.c
deleted file mode 100644
index 2f0c047..0000000
--- a/qmk_atreus_layout/keymap.c
+++ /dev/null
@@ -1,76 +0,0 @@
-#include QMK_KEYBOARD_H
-
-// build as: make atreus/astar_mirrored:moderately-miryoku:avrdude
-
-#undef TAPPING_TERM
-#define TAPPING_TERM 150
-#define IGNORE_MOD_TAP_INTERRUPT
-
-#define ____ KC_NO
-
-#define PCBDOWN 1
-
-enum layers { BASE, MBO, MEDIA, NAV, MOUSE, SYM, NUM, FUN, GAME };
-
-#define U_RDO KC_AGIN
-#define U_PST S(KC_INS)
-#define U_CPY C(KC_INS)
-#define U_CUT S(KC_DEL)
-#define U_UND KC_UNDO
-
-const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
- [BASE] = LAYOUT(
- KC_Q, KC_W, KC_F, KC_P, KC_B, KC_J, KC_L, KC_U, KC_Y, KC_SCLN,
- LGUI_T(KC_A), LALT_T(KC_R), LCTL_T(KC_S), LSFT_T(KC_T), KC_G, KC_M, LSFT_T(KC_N), LCTL_T(KC_E), LALT_T(KC_I), LGUI_T(KC_O),
- KC_Z, ALGR_T(KC_X), KC_C, KC_D, KC_V, KC_K, KC_H, KC_COMM, ALGR_T(KC_DOT), KC_QUOT,
- ____, ____, TO(GAME), LT(MOUSE, KC_SLSH), LT(NUM, KC_BSPC), LT(FUN, KC_TAB), LT(NAV, KC_ENT), LT(SYM, KC_SPC), LT(MEDIA, KC_BSLS), ____, ____, ____
- ),
- [NUM] = LAYOUT(
- RESET, KC_UNDS, KC_TILDE,KC_GRAVE,KC_NO, KC_LPRN, KC_7, KC_8, KC_9, KC_PLUS,
- KC_LGUI, KC_LALT, KC_LCTL, KC_LSFT, KC_ESC, KC_EQL, KC_4, KC_5, KC_6, KC_ASTR,
- KC_NO, KC_NO, KC_NO, KC_ALGR, KC_NO, KC_SLSH, KC_1, KC_2, KC_3, KC_MINS,
- ____, ____, ____, KC_NO, KC_NO, KC_NO, KC_COMM, KC_0, KC_DOT, ____, ____,
- ),
- [SYM] = LAYOUT(
- KC_EXLM, KC_AT, KC_HASH, KC_LCBR, KC_RCBR, KC_NO, KC_GRAVE,KC_TILDE,KC_UNDS, RESET,
- KC_EQL, KC_CIRC, KC_DLR, KC_LPRN, KC_RPRN, KC_ESC, KC_LSFT, KC_LCTL, KC_LALT, KC_LGUI,
- KC_AMPR, KC_PERC, KC_PIPE, KC_LBRC, KC_RBRC, KC_NO, KC_ALGR, KC_NO, KC_NO, KC_NO,
- ____, ____, ____, KC_UNDS, KC_LPRN, KC_RPRN, KC_NO, KC_NO, KC_NO, ____, ____, ____
- ),
- [MOUSE] = LAYOUT(
- KC_LGUI, KC_LALT, KC_LCTL, KC_LSFT, KC_NO, KC_WH_U, KC_WH_L, KC_MS_U, KC_WH_R, KC_NO,
- KC_NLCK, KC_BTN3, KC_BTN2, KC_BTN1, KC_LOCK, KC_WH_D, KC_MS_L, KC_MS_D, KC_MS_R, KC_NO,
- KC_NO, KC_NO, KC_ALGR, KC_NO, KC_NO, U_UND, U_CUT, U_CPY, U_PST, U_RDO,
- ____, ____, ____, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, ____, ____, ____
- ),
- [NAV] = LAYOUT(
- KC_PGUP, KC_HOME, KC_UP, KC_END, KC_INS, KC_NO, KC_GRAVE,KC_TILDE,KC_UNDS, RESET,
- KC_PGDN, KC_LEFT, KC_DOWN, KC_RGHT, KC_CLCK, KC_ESC, KC_LSFT, KC_LCTL, KC_LALT, KC_LGUI,
- U_UND, U_CUT, U_CPY, U_PST, U_RDO, KC_NO, KC_ALGR, KC_NO, KC_NO, KC_NO,
- ____, ____, ____, KC_SLSH, KC_BSPC, KC_TAB, KC_NO, KC_NO, KC_NO, ____, ____, ____
- ),
- [MEDIA] = LAYOUT(
- KC_NO, KC_NO, KC_VOLU, KC_NO, KC_NO, KC_NO, KC_GRAVE,KC_TILDE,KC_UNDS, RESET,
- KC_NO, KC_MPRV, KC_VOLD, KC_MNXT, KC_NO, KC_ESC, KC_LSFT, KC_LCTL, KC_LALT, KC_LGUI,
- RGB_MOD, RGB_HUI, RGB_SAI, RGB_VAI, RGB_TOG, KC_NO, KC_NO, KC_NO, KC_ALGR, KC_NO,
- ____, ____, ____, KC_MUTE, KC_MPLY, KC_MSTP, KC_NO, KC_NO, KC_NO, ____, ____, ____
- ),
- [MBO] = LAYOUT(
- U_RDO, U_PST, U_CPY, U_CUT, U_UND, U_RDO, U_PST, U_CPY, U_CUT, U_UND,
- KC_LGUI, KC_LALT, KC_LCTL, KC_LSFT, KC_TRNS, KC_ESC, KC_LSFT, KC_LCTL, KC_LALT, KC_LGUI,
- KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
- ____, ____, ____, KC_BTN2, KC_BTN3, KC_BTN1, KC_BTN1, KC_BTN3, KC_BTN2, ____, ____, ____
- ),
- [FUN] = LAYOUT(
- RESET, KC_UNDS, KC_TILDE,KC_GRAVE,KC_NO, KC_PSCR, KC_F7, KC_F8, KC_F9, KC_F12,
- KC_LGUI, KC_LALT, KC_LCTL, KC_LSFT, KC_ESC, KC_SLCK, KC_F4, KC_F5, KC_F6, KC_F11,
- KC_NO, KC_NO, KC_NO, KC_ALGR, KC_NO, KC_PAUS, KC_F1, KC_F2, KC_F3, KC_F10,
- ____, ____, ____, KC_NO, KC_NO, KC_NO, KC_ENT, KC_SPC, KC_APP, ____, ____, ____
- ),
- [GAME] = LAYOUT(
- KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O,
- KC_LSFT, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L,
- KC_LCTL, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM,KC_DOT,
- ____, ____, TO(BASE),KC_LALT, KC_SPC,KC_ESC, KC_ENT,KC_BSPC,KC_BSLS, ____, KC_SCLN,KC_P
- )
-};
diff --git a/somebar/.builds/archlinux.yml b/somebar/.builds/archlinux.yml
deleted file mode 100644
index 7c4f209..0000000
--- a/somebar/.builds/archlinux.yml
+++ /dev/null
@@ -1,19 +0,0 @@
-image: archlinux
-packages:
- - base-devel
- - meson
- - wayland
- - wayland-protocols
- - cairo
- - pango
-sources:
- - https://git.sr.ht/~raphi/somebar
-tasks:
- - setup: |
- cd somebar
- meson build --fatal-meson-warnings
- cp src/config.def.hpp src/config.hpp
- - build: |
- cd somebar/build
- ninja
- sudo ninja install
diff --git a/somebar/.builds/freebsd.yml b/somebar/.builds/freebsd.yml
deleted file mode 100644
index 90e6f1a..0000000
--- a/somebar/.builds/freebsd.yml
+++ /dev/null
@@ -1,20 +0,0 @@
-image: freebsd/latest
-packages:
- - devel/evdev-proto
- - devel/meson
- - devel/pkgconf
- - graphics/cairo
- - graphics/wayland
- - graphics/wayland-protocols
- - x11-toolkits/pango
-sources:
- - https://git.sr.ht/~raphi/somebar
-tasks:
- - setup: |
- cd somebar
- meson build --fatal-meson-warnings
- cp src/config.def.hpp src/config.hpp
- - build: |
- cd somebar/build
- ninja
- sudo ninja install \ No newline at end of file
diff --git a/somebar/.editorconfig b/somebar/.editorconfig
deleted file mode 100644
index 5c4a037..0000000
--- a/somebar/.editorconfig
+++ /dev/null
@@ -1,5 +0,0 @@
-root = true
-
-[*]
-indent_style = tab
-indent_brace_style = K&R
diff --git a/somebar/.gitignore b/somebar/.gitignore
deleted file mode 100644
index 50d749b..0000000
--- a/somebar/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-compile_commands.json
-build
-.cache
-src/config.hpp
diff --git a/somebar/CHANGELOG.md b/somebar/CHANGELOG.md
deleted file mode 100644
index a24e7ab..0000000
--- a/somebar/CHANGELOG.md
+++ /dev/null
@@ -1,19 +0,0 @@
-## [1.0.3] - 2022-12-11
-### Added
-- New patches: markup-in-status-messages, show-status-on-selected-monitor (benc)
-### Fixed
-- Fixed crash when an output disappears
-
-## [1.0.2] - 2022-11-27
-### Fixed
-- Fixed bug where hidden bar could not be shown anymore
-
-## [1.0.1] - 2022-11-25
-### Added
-- Manpage
-- New patches: indicator-size-props, hide-vacant-tags, colorless-status (medanisjbara)
-### Fixed
-- Remove spaces from title and layout symbol (benc)
-
-## [1.0.0] - 2022-04-23
-Initial release
diff --git a/somebar/LICENSE b/somebar/LICENSE
deleted file mode 100644
index 7bebc11..0000000
--- a/somebar/LICENSE
+++ /dev/null
@@ -1,20 +0,0 @@
-Copyright (c) 2021 Raphael Robatsch
-
-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 (including the next
-paragraph) 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/somebar/README.md b/somebar/README.md
deleted file mode 100644
index b61c935..0000000
--- a/somebar/README.md
+++ /dev/null
@@ -1,113 +0,0 @@
-# somebar - dwm-like bar for dwl
-
-![Screenshot](screenshot.png)
-
-The mailing list for this project is
-[~raphi/public-inbox@lists.sr.ht](mailto:~raphi/public-inbox@lists.sr.ht).
-
-## Dependencies
-
-* c++ compiler, meson, and ninja
-* wayland-scanner
-* libwayland-client
-* libwayland-cursor
-* libcairo
-* libpango
-* libpangocairo
-
-```
-sudo apt install build-essential meson ninja-build \
- libwayland-bin libwayland-client0 libwayland-cursor0 libwayland-dev \
- libcairo2 libcairo2-dev \
- libpango-1.0-0 libpango1.0-dev libpangocairo-1.0-0
-
-# or
-
-sudo pacman -S base-devel meson \
- wayland wayland-protocols cairo pango
-```
-
-## Configuration
-
-Copy `src/config.def.hpp` to `src/config.hpp`, and adjust if needed.
-
-## Building
-
-```
-cp src/config.def.hpp src/config.hpp
-meson setup build
-ninja -C build
-sudo ninja -C build install
-```
-
-## Usage
-
-You must start somebar using dwl's `-s` flag, e.g. `dwl -s somebar`.
-
-Somebar can be controlled by writing to `$XDG_RUNTIME_DIR/somebar-0`
-or the path defined by `-s` argument.
-The following commands are supported:
-
-* `status TEXT`: Updates the status bar
-* `hide MONITOR` Hides somebar on the specified monitor
-* `show MONITOR` Shows somebar on the specified monitor
-* `toggle MONITOR` Toggles somebar on the specified monitor
-
-MONITOR is an zxdg_output_v1 name, which can be determined e.g. using `weston-info`.
-Additionally, MONITOR can be `all` (all monitors) or `selected` (the monitor with focus).
-
-Commands can be sent either by writing to the file name above, or equivalently by calling
-somebar with the `-c` argument. For example: `somebar -c toggle all`. This is recommended
-for shell scripts, as there is no race-free way to write to a file only if it exists.
-
-The maintainer of somebar also maintains
-[someblocks](https://git.sr.ht/~raphi/someblocks/),
-a fork of [dwmblocks](https://github.com/torrinfail/dwmblocks) that outputs
-to somebar instead of dwm's bar.
-
-## IPC
-
-Out of the box, somebar cannot control dwl. Clicking on the tag bar has no
-effect, because there is no communication channel from somebar back to dwl.
-
-If you apply the patch `contrib/ipc.patch`, then somebar will
-
-1. Not read stdin anymore, and instead use a wayland extension to read dwl's
- state. This means you must close stdin yourself, if you choose to launch
- somebar using dwl's -s flag.
-2. somebar can use the same wayland extension to send commands back to dwl.
- This means that clicking on tags will switch to that tag (this can of course
- be customized in config.h).
-
-If you apply the IPC patch to somebar, then
-**dwl must have the [wayland-ipc patch](https://git.sr.ht/~raphi/dwl/blob/master/patches/wayland-ipc.patch) applied too**,
-since dwl must implement the wayland extension too.
-
-## Other patches
-
-Like all suckless software, somebar can be customized via patches. You can find some patches in the contrib folder with descriptions written in them.
-
-## License
-
-somebar - dwm-like bar for dwl
-
-Copyright (c) 2021 Raphael Robatsch
-
-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 (including the next
-paragraph) 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/somebar/contrib/colorless-status.patch b/somebar/contrib/colorless-status.patch
deleted file mode 100644
index f280070..0000000
--- a/somebar/contrib/colorless-status.patch
+++ /dev/null
@@ -1,15 +0,0 @@
-From: medanisjbara anis2834133766619@gmail.com
-Date: Mon, 14 Nov 2022 10:28:00
-Description: sets the color of status component to inactive
-diff --git a/src/bar.cpp b/src/bar.cpp
-index fab5a8f..aebe28b 100644
---- a/src/bar.cpp
-+++ b/src/bar.cpp
-@@ -266,6 +266,7 @@ void Bar::renderStatus()
- cairo_fill(_painter);
-
- _x = start;
-+ setColorScheme(colorInactive);
- renderComponent(_statusCmp);
- }
-
diff --git a/somebar/contrib/dwm-like-tag-indicator.patch b/somebar/contrib/dwm-like-tag-indicator.patch
deleted file mode 100644
index c4458e9..0000000
--- a/somebar/contrib/dwm-like-tag-indicator.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From: Henrique Possatto <henriquempossatto@gmail.com>
-Date: Mon, 26 Dec 2022 18:01:35 -0300
-Subject: [PATCH somebar] patch to show square tag indicator like dwm
-diff --git a/src/bar.cpp b/src/bar.cpp
-index 507ce62..4fda8b0 100644
---- a/src/bar.cpp
-+++ b/src/bar.cpp
-@@ -245,12 +245,17 @@ void Bar::renderTags()
- tag.state & TagState::Active ? colorActive : colorInactive,
- tag.state & TagState::Urgent);
- renderComponent(tag.component);
-- auto indicators = std::min(tag.numClients, static_cast<int>(_bufs->height/2));
-- for (auto ind = 0; ind < indicators; ind++) {
-- auto w = ind == tag.focusedClient ? 7 : 1;
-- cairo_move_to(_painter, tag.component.x, ind*2+0.5);
-- cairo_rel_line_to(_painter, w, 0);
-- cairo_close_path(_painter);
-+
-+ if(!tag.numClients)
-+ continue;
-+
-+ int s = barfont.height / 9;
-+ int w = barfont.height / 6 + 2;
-+ if (tag.focusedClient != -1) {
-+ cairo_rectangle(_painter, tag.component.x + s, s, w, w);
-+ cairo_fill(_painter);
-+ } else {
-+ cairo_rectangle(_painter, (double)(tag.component.x + s) + 0.5, (double)(s) + 0.5, w, w);
- cairo_set_line_width(_painter, 1);
- cairo_stroke(_painter);
- }
---
-2.39.0
-
diff --git a/somebar/contrib/hide-vacant-tags.patch b/somebar/contrib/hide-vacant-tags.patch
deleted file mode 100644
index 055dd51..0000000
--- a/somebar/contrib/hide-vacant-tags.patch
+++ /dev/null
@@ -1,54 +0,0 @@
-From: medanisjbara anis2834133766619@gmail.com
-Date: Mon, 14 Nov 2022 22:52:00
-Description: somebar equivalent of https://dwm.suckless.org/patches/hide_vacant_tags
-diff --git a/src/bar.cpp b/src/bar.cpp
-index fab5a8f..38e7b5f 100644
---- a/src/bar.cpp
-+++ b/src/bar.cpp
-@@ -240,13 +240,36 @@ void Bar::render()
-
- void Bar::renderTags()
- {
-+ // Check if all tags are active (Mod+0)
-+ bool allActive = true;
- for (auto &tag : _tags) {
-+ if (tag.state & TagState::Active){
-+ if (!allActive){
-+ allActive = true;
-+ break;
-+ }
-+ allActive = false;
-+ }
-+ }
-+
-+ bool renderThis;
-+ for (auto &tag : _tags) {
-+ renderThis = false;
- setColorScheme(
- tag.state & TagState::Active ? colorActive : colorInactive,
- tag.state & TagState::Urgent);
-- renderComponent(tag.component);
-+ // Reder active tag if it's the only one active
-+ if (!allActive && tag.state & TagState::Active)
-+ renderThis = true;
- auto indicators = std::min(tag.numClients, static_cast<int>(_bufs->height/2));
- for (auto ind = 0; ind < indicators; ind++) {
-+ // render tags having indicators
-+ if (tag.focusedClient == -1)
-+ renderThis = true;
-+ // render tags having the focused client
-+ if (tag.focusedClient == 0){
-+ renderThis = true;
-+ }
- auto w = ind == tag.focusedClient ? 7 : 1;
- cairo_move_to(_painter, tag.component.x, ind*2+0.5);
- cairo_rel_line_to(_painter, w, 0);
-@@ -254,6 +277,8 @@ void Bar::renderTags()
- cairo_set_line_width(_painter, 1);
- cairo_stroke(_painter);
- }
-+ if (renderThis)
-+ renderComponent(tag.component);
- }
- }
-
diff --git a/somebar/contrib/indicator-size-props.patch b/somebar/contrib/indicator-size-props.patch
deleted file mode 100644
index ac17520..0000000
--- a/somebar/contrib/indicator-size-props.patch
+++ /dev/null
@@ -1,54 +0,0 @@
-From: medanisjbara anis2834133766619@gmail.com
-Date: Mon, 15 Nov 2022 08:16:00
-Description: lets config.h customize indicators sizes
-diff --git a/src/bar.cpp b/src/bar.cpp
-index fab5a8f..c0e070c 100644
---- a/src/bar.cpp
-+++ b/src/bar.cpp
-@@ -247,11 +247,11 @@ void Bar::renderTags()
- renderComponent(tag.component);
- auto indicators = std::min(tag.numClients, static_cast<int>(_bufs->height/2));
- for (auto ind = 0; ind < indicators; ind++) {
-- auto w = ind == tag.focusedClient ? 7 : 1;
-+ auto w = ind == tag.focusedClient ? indprops.focused_width : indprops.width;
- cairo_move_to(_painter, tag.component.x, ind*2+0.5);
- cairo_rel_line_to(_painter, w, 0);
- cairo_close_path(_painter);
-- cairo_set_line_width(_painter, 1);
-+ cairo_set_line_width(_painter, ind == tag.focusedClient ? indprops.focused_height : indprops.height);
- cairo_stroke(_painter);
- }
- }
-diff --git a/src/common.hpp b/src/common.hpp
-index aed4480..acdca1b 100644
---- a/src/common.hpp
-+++ b/src/common.hpp
-@@ -34,6 +34,13 @@ struct Button {
- const Arg arg;
- };
-
-+struct IndicatorProps {
-+ int width;
-+ int height;
-+ int focused_width;
-+ int focused_height;
-+};
-+
- extern wl_display* display;
- extern wl_compositor* compositor;
- extern wl_shm* shm;
-diff --git a/src/config.def.hpp b/src/config.def.hpp
-index 40a8c95..d51fee8 100644
---- a/src/config.def.hpp
-+++ b/src/config.def.hpp
-@@ -25,3 +25,10 @@ static std::vector<std::string> tagNames = {
- constexpr Button buttons[] = {
- { ClkStatusText, BTN_RIGHT, spawn, {.v = termcmd} },
- };
-+
-+constexpr IndicatorProps indprops = {
-+ 5, /* unfocused indicator width */
-+ 5, /* unfocused indicator height */
-+ 7, /* focused indicator width */
-+ 1 /* focused indicator height */
-+};
diff --git a/somebar/contrib/ipc.patch b/somebar/contrib/ipc.patch
deleted file mode 100644
index 0b11123..0000000
--- a/somebar/contrib/ipc.patch
+++ /dev/null
@@ -1,504 +0,0 @@
-Replaces somebar's channel to dwl from stdin to a wayland extension.
-
-Normally, somebar reads dwl's state by reading from stdin. This requires
-that somebar is started from dwl, and does not allow sending commands back
-to dwl.
-
-This patch replaces this channel with a wayland protocol extension. somebar
-can use this protocol extension to observe and update the dwl window management
-state.
-
-Important! dwl must have the wayland-ipc patch applied for this to work!
-https://git.sr.ht/~raphi/dwl/blob/master/patches/wayland-ipc.patch
-diff --git a/protocols/meson.build b/protocols/meson.build
-index 7bd222b..5752608 100644
---- a/protocols/meson.build
-+++ b/protocols/meson.build
-@@ -15,6 +15,7 @@ wayland_xmls = [
- wl_protocol_dir + '/stable/xdg-shell/xdg-shell.xml',
- wl_protocol_dir + '/unstable/xdg-output/xdg-output-unstable-v1.xml',
- 'wlr-layer-shell-unstable-v1.xml',
-+ 'net-tapesoftware-dwl-wm-unstable-v1.xml',
- ]
- wayland_sources = [
- wayland_scanner_code.process(wayland_xmls),
-diff --git a/protocols/net-tapesoftware-dwl-wm-unstable-v1.xml b/protocols/net-tapesoftware-dwl-wm-unstable-v1.xml
-new file mode 100644
-index 0000000..390f5a1
---- /dev/null
-+++ b/protocols/net-tapesoftware-dwl-wm-unstable-v1.xml
-@@ -0,0 +1,164 @@
-+<?xml version="1.0" encoding="UTF-8"?>
-+<protocol name="net_tapesoftware_dwl_wm_unstable_v1">
-+ <copyright>
-+ Copyright (c) 2021 Raphael Robatsch
-+
-+ 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 (including the
-+ next paragraph) 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.
-+ </copyright>
-+
-+ <interface name="znet_tapesoftware_dwl_wm_v1" version="1">
-+ <description summary="control the dwl state">
-+ This interface is exposed as a global in the wl_registry.
-+
-+ Clients can use this protocol to receive updates of the window manager
-+ state (active tags, active layout, and focused window).
-+ Clients can also control this state.
-+
-+ After binding, the client will receive the available tags and layouts
-+ with the 'tag' and 'layout' events. These can be used in subsequent
-+ dwl_wm_monitor_v1.set_tags/set_layout requests, and to interpret the
-+ dwl_wm_monitor_v1.layout/tag events.
-+ </description>
-+
-+ <request name="release" type="destructor">
-+ <description summary="release dwl_wm">
-+ This request indicates that the client will not use the dwl_wm
-+ object any more. Objects that have been created through this instance
-+ are not affected.
-+ </description>
-+ </request>
-+
-+ <request name="get_monitor">
-+ <description summary="gets a dwl monitor from an output">
-+ Gets a dwl monitor for the specified output. The window manager
-+ state on the output can be controlled using the monitor.
-+ </description>
-+ <arg name="id" type="new_id" interface="znet_tapesoftware_dwl_wm_monitor_v1" />
-+ <arg name="output" type="object" interface="wl_output" />
-+ </request>
-+
-+ <event name="tag">
-+ <description summary="announces the presence of a tag">
-+ This event is sent immediately after binding.
-+ A roundtrip after binding guarantees that the client has received all tags.
-+ </description>
-+ <arg name="name" type="string"/>
-+ </event>
-+
-+ <event name="layout">
-+ <description summary="announces the presence of a layout">
-+ This event is sent immediately after binding.
-+ A roundtrip after binding guarantees that the client has received all layouts.
-+ </description>
-+ <arg name="name" type="string"/>
-+ </event>
-+ </interface>
-+
-+ <interface name="znet_tapesoftware_dwl_wm_monitor_v1" version="1">
-+ <description summary="control one monitor">
-+ Observes and controls one monitor.
-+
-+ Events are double-buffered: Clients should cache all events and only
-+ redraw themselves once the 'frame' event is sent.
-+
-+ Requests are not double-buffered: The compositor will update itself
-+ immediately.
-+ </description>
-+
-+ <enum name="tag_state">
-+ <entry name="none" value="0" summary="no state"/>
-+ <entry name="active" value="1" summary="tag is active"/>
-+ <entry name="urgent" value="2" summary="tag has at least one urgent client"/>
-+ </enum>
-+
-+ <request name="release" type="destructor">
-+ <description summary="release dwl_monitor">
-+ This request indicates that the client is done with this dwl_monitor.
-+ All further requests are ignored.
-+ </description>
-+ </request>
-+
-+ <event name="selected">
-+ <description summary="updates the selected state of the monitor">
-+ If 'selected' is nonzero, this monitor is the currently selected one.
-+ </description>
-+ <arg name="selected" type="uint"/>
-+ </event>
-+
-+ <event name="tag">
-+ <description summary="updates the state of one tag">
-+ Announces the update of a tag. num_clients and focused_client can be
-+ used to draw client indicators.
-+ </description>
-+ <arg name="tag" type="uint" summary="index of a tag received by the dwl_wm_v1.tag event." />
-+ <arg name="state" type="uint" enum="tag_state"/>
-+ <arg name="num_clients" type="uint" summary="number of clients on this tag"/>
-+ <arg name="focused_client" type="int" summary="out of num_clients. -1 if there is no focused client"/>
-+ </event>
-+
-+ <event name="layout">
-+ <description summary="updates the selected layout">
-+ Announces the update of the selected layout.
-+ </description>
-+ <arg name="layout" type="uint" summary="index of a layout received by the dwl_wm_v1.layout event."/>
-+ </event>
-+
-+ <event name="title">
-+ <description summary="updates the focused client">
-+ Announces the update of the selected client.
-+ </description>
-+ <arg name="title" type="string"/>
-+ </event>
-+
-+ <event name="frame">
-+ <description summary="end of status update sequence">
-+ Sent after all other events belonging to the status update has been sent.
-+ Clients should redraw themselves now.
-+ </description>
-+ </event>
-+
-+ <request name="set_tags">
-+ <description summary="sets the active tags on this monitor.">
-+ Changes are applied immediately.
-+ </description>
-+ <arg name="tagmask" type="uint" summary="bitmask of the tags that should be set."/>
-+ <arg name="toggle_tagset" type="uint"/>
-+ </request>
-+
-+ <request name="set_client_tags">
-+ <description summary="updates the tags of the focused client.">
-+ tags are updated as follows:
-+ new_tags = (current_tags AND and_tags) XOR xor_tags
-+
-+ Changes are applied immediately.
-+ </description>
-+ <arg name="and_tags" type="uint"/>
-+ <arg name="xor_tags" type="uint"/>
-+ </request>
-+
-+ <request name="set_layout">
-+ <description summary="sets the active layout on this monitor.">
-+ Changes are applied immediately.
-+ </description>
-+ <arg name="layout" type="uint" summary="index of a layout received by the dwl_wm_v1.layout event."/>
-+ </request>
-+ </interface>
-+</protocol>
-diff --git a/src/common.hpp b/src/common.hpp
-index aed4480..12a3e2e 100644
---- a/src/common.hpp
-+++ b/src/common.hpp
-@@ -10,6 +10,7 @@
- #include <cairo/cairo.h>
- #include <pango/pango.h>
- #include "wlr-layer-shell-unstable-v1-client-protocol.h"
-+#include "net-tapesoftware-dwl-wm-unstable-v1-client-protocol.h"
-
- struct Color {
- Color() {}
-@@ -38,7 +39,14 @@ extern wl_display* display;
- extern wl_compositor* compositor;
- extern wl_shm* shm;
- extern zwlr_layer_shell_v1* wlrLayerShell;
-+extern std::vector<std::string> tagNames;
-+extern std::vector<std::string> layoutNames;
-
-+void view(Monitor& m, const Arg& arg);
-+void toggleview(Monitor& m, const Arg& arg);
-+void setlayout(Monitor& m, const Arg& arg);
-+void tag(Monitor& m, const Arg& arg);
-+void toggletag(Monitor& m, const Arg& arg);
- void spawn(Monitor&, const Arg& arg);
- void setCloexec(int fd);
- [[noreturn]] void die(const char* why);
-@@ -59,6 +67,7 @@ WL_DELETER(wl_output, wl_output_release);
- WL_DELETER(wl_pointer, wl_pointer_release);
- WL_DELETER(wl_seat, wl_seat_release);
- WL_DELETER(wl_surface, wl_surface_destroy);
-+WL_DELETER(znet_tapesoftware_dwl_wm_monitor_v1, znet_tapesoftware_dwl_wm_monitor_v1_release);
- WL_DELETER(zwlr_layer_surface_v1, zwlr_layer_surface_v1_destroy);
-
- WL_DELETER(cairo_t, cairo_destroy);
-diff --git a/src/config.def.hpp b/src/config.def.hpp
-index 40a8c95..a9560cb 100644
---- a/src/config.def.hpp
-+++ b/src/config.def.hpp
-@@ -16,12 +16,11 @@ constexpr ColorScheme colorInactive = {Color(0xbb, 0xbb, 0xbb), Color(0x22, 0x22
- constexpr ColorScheme colorActive = {Color(0xee, 0xee, 0xee), Color(0x00, 0x55, 0x77)};
- constexpr const char* termcmd[] = {"foot", nullptr};
-
--static std::vector<std::string> tagNames = {
-- "1", "2", "3",
-- "4", "5", "6",
-- "7", "8", "9",
--};
--
- constexpr Button buttons[] = {
-+ { ClkTagBar, BTN_LEFT, view, {0} },
-+ { ClkTagBar, BTN_RIGHT, tag, {0} },
-+ { ClkTagBar, BTN_MIDDLE, toggletag, {0} },
-+ { ClkLayoutSymbol, BTN_LEFT, setlayout, {.ui = 0} },
-+ { ClkLayoutSymbol, BTN_RIGHT, setlayout, {.ui = 2} },
- { ClkStatusText, BTN_RIGHT, spawn, {.v = termcmd} },
- };
-diff --git a/src/main.cpp b/src/main.cpp
-index 6198d8b..9e7549a 100644
---- a/src/main.cpp
-+++ b/src/main.cpp
-@@ -3,7 +3,6 @@
-
- #include <algorithm>
- #include <cstdio>
--#include <sstream>
- #include <list>
- #include <optional>
- #include <utility>
-@@ -21,8 +20,8 @@
- #include "wlr-layer-shell-unstable-v1-client-protocol.h"
- #include "xdg-output-unstable-v1-client-protocol.h"
- #include "xdg-shell-client-protocol.h"
-+#include "net-tapesoftware-dwl-wm-unstable-v1-client-protocol.h"
- #include "common.hpp"
--#include "config.hpp"
- #include "bar.hpp"
- #include "line_buffer.hpp"
-
-@@ -34,6 +33,7 @@ struct Monitor {
- bool desiredVisibility {true};
- bool hasData;
- uint32_t tags;
-+ wl_unique_ptr<znet_tapesoftware_dwl_wm_monitor_v1> dwlMonitor;
- };
-
- struct SeatPointer {
-@@ -54,8 +54,6 @@ static void updatemon(Monitor &mon);
- static void onReady();
- static void setupStatusFifo();
- static void onStatus();
--static void onStdin();
--static void handleStdin(const std::string& line);
- static void updateVisibility(const std::string& name, bool(*updater)(bool));
- static void onGlobalAdd(void*, wl_registry* registry, uint32_t name, const char* interface, uint32_t version);
- static void onGlobalRemove(void*, wl_registry* registry, uint32_t name);
-@@ -67,6 +65,9 @@ wl_display* display;
- wl_compositor* compositor;
- wl_shm* shm;
- zwlr_layer_shell_v1* wlrLayerShell;
-+znet_tapesoftware_dwl_wm_v1* dwlWm;
-+std::vector<std::string> tagNames;
-+std::vector<std::string> layoutNames;
- static xdg_wm_base* xdgWmBase;
- static zxdg_output_manager_v1* xdgOutputManager;
- static wl_surface* cursorSurface;
-@@ -85,6 +86,26 @@ static int statusFifoFd {-1};
- static int statusFifoWriter {-1};
- static bool quitting {false};
-
-+void view(Monitor& m, const Arg& arg)
-+{
-+ znet_tapesoftware_dwl_wm_monitor_v1_set_tags(m.dwlMonitor.get(), arg.ui, 1);
-+}
-+void toggleview(Monitor& m, const Arg& arg)
-+{
-+ znet_tapesoftware_dwl_wm_monitor_v1_set_tags(m.dwlMonitor.get(), m.tags ^ arg.ui, 0);
-+}
-+void setlayout(Monitor& m, const Arg& arg)
-+{
-+ znet_tapesoftware_dwl_wm_monitor_v1_set_layout(m.dwlMonitor.get(), arg.ui);
-+}
-+void tag(Monitor& m, const Arg& arg)
-+{
-+ znet_tapesoftware_dwl_wm_monitor_v1_set_client_tags(m.dwlMonitor.get(), 0, arg.ui);
-+}
-+void toggletag(Monitor& m, const Arg& arg)
-+{
-+ znet_tapesoftware_dwl_wm_monitor_v1_set_client_tags(m.dwlMonitor.get(), ~0, arg.ui);
-+}
- void spawn(Monitor&, const Arg& arg)
- {
- if (fork() == 0) {
-@@ -189,11 +210,62 @@ static const struct wl_seat_listener seatListener = {
- .name = [](void*, wl_seat*, const char* name) { }
- };
-
-+static const struct znet_tapesoftware_dwl_wm_v1_listener dwlWmListener = {
-+ .tag = [](void*, znet_tapesoftware_dwl_wm_v1*, const char* name) {
-+ tagNames.push_back(name);
-+ },
-+ .layout = [](void*, znet_tapesoftware_dwl_wm_v1*, const char* name) {
-+ layoutNames.push_back(name);
-+ },
-+};
-+
-+static const struct znet_tapesoftware_dwl_wm_monitor_v1_listener dwlWmMonitorListener {
-+ .selected = [](void* mv, znet_tapesoftware_dwl_wm_monitor_v1*, uint32_t selected) {
-+ auto mon = static_cast<Monitor*>(mv);
-+ if (selected) {
-+ selmon = mon;
-+ } else if (selmon == mon) {
-+ selmon = nullptr;
-+ }
-+ mon->bar.setSelected(selected);
-+ },
-+ .tag = [](void* mv, znet_tapesoftware_dwl_wm_monitor_v1*, uint32_t tag, uint32_t state, uint32_t numClients, int32_t focusedClient) {
-+ auto mon = static_cast<Monitor*>(mv);
-+ int tagState = TagState::None;
-+ if (state & ZNET_TAPESOFTWARE_DWL_WM_MONITOR_V1_TAG_STATE_ACTIVE)
-+ tagState |= TagState::Active;
-+ if (state & ZNET_TAPESOFTWARE_DWL_WM_MONITOR_V1_TAG_STATE_URGENT)
-+ tagState |= TagState::Urgent;
-+ mon->bar.setTag(tag, tagState, numClients, focusedClient);
-+ uint32_t mask = 1 << tag;
-+ if (tagState & TagState::Active) {
-+ mon->tags |= mask;
-+ } else {
-+ mon->tags &= ~mask;
-+ }
-+ },
-+ .layout = [](void* mv, znet_tapesoftware_dwl_wm_monitor_v1*, uint32_t layout) {
-+ auto mon = static_cast<Monitor*>(mv);
-+ mon->bar.setLayout(layoutNames[layout]);
-+ },
-+ .title = [](void* mv, znet_tapesoftware_dwl_wm_monitor_v1*, const char* title) {
-+ auto mon = static_cast<Monitor*>(mv);
-+ mon->bar.setTitle(title);
-+ },
-+ .frame = [](void* mv, znet_tapesoftware_dwl_wm_monitor_v1*) {
-+ auto mon = static_cast<Monitor*>(mv);
-+ mon->hasData = true;
-+ updatemon(*mon);
-+ }
-+};
-+
- void setupMonitor(uint32_t name, wl_output* output) {
- auto& monitor = monitors.emplace_back(Monitor {name, {}, wl_unique_ptr<wl_output> {output}});
- monitor.bar.setStatus(lastStatus);
- auto xdgOutput = zxdg_output_manager_v1_get_xdg_output(xdgOutputManager, monitor.wlOutput.get());
- zxdg_output_v1_add_listener(xdgOutput, &xdgOutputListener, &monitor);
-+ monitor.dwlMonitor.reset(znet_tapesoftware_dwl_wm_v1_get_monitor(dwlWm, monitor.wlOutput.get()));
-+ znet_tapesoftware_dwl_wm_monitor_v1_add_listener(monitor.dwlMonitor.get(), &dwlWmMonitorListener, &monitor);
- }
-
- void updatemon(Monitor& mon)
-@@ -219,6 +291,7 @@ void onReady()
- requireGlobal(shm, "wl_shm");
- requireGlobal(wlrLayerShell, "zwlr_layer_shell_v1");
- requireGlobal(xdgOutputManager, "zxdg_output_manager_v1");
-+ requireGlobal(dwlWm, "znet_tapesoftware_dwl_wm_v1");
- setupStatusFifo();
- wl_display_roundtrip(display); // roundtrip so we receive all dwl tags etc.
-
-@@ -226,7 +299,6 @@ void onReady()
- for (auto output : uninitializedOutputs) {
- setupMonitor(output.first, output.second);
- }
-- wl_display_roundtrip(display); // wait for xdg_output names before we read stdin
- }
-
- void setupStatusFifo()
-@@ -259,66 +331,6 @@ void setupStatusFifo()
- }
- }
-
--static LineBuffer<512> stdinBuffer;
--static void onStdin()
--{
-- auto res = stdinBuffer.readLines(
-- [](void* p, size_t size) { return read(0, p, size); },
-- [](char* p, size_t size) { handleStdin({p, size}); });
-- if (res == 0) {
-- quitting = true;
-- }
--}
--
--static void handleStdin(const std::string& line)
--{
-- // this parses the lines that dwl sends in printstatus()
-- std::string monName, command;
-- auto stream = std::istringstream {line};
-- stream >> monName >> command;
-- if (!stream.good()) {
-- return;
-- }
-- auto mon = std::find_if(begin(monitors), end(monitors), [&](const Monitor& mon) {
-- return mon.xdgName == monName;
-- });
-- if (mon == end(monitors))
-- return;
-- if (command == "title") {
-- auto title = std::string {};
-- std::getline(stream, title);
-- mon->bar.setTitle(title);
-- } else if (command == "selmon") {
-- uint32_t selected;
-- stream >> selected;
-- mon->bar.setSelected(selected);
-- if (selected) {
-- selmon = &*mon;
-- } else if (selmon == &*mon) {
-- selmon = nullptr;
-- }
-- } else if (command == "tags") {
-- uint32_t occupied, tags, clientTags, urgent;
-- stream >> occupied >> tags >> clientTags >> urgent;
-- for (auto i=0u; i<tagNames.size(); i++) {
-- auto tagMask = 1 << i;
-- int state = TagState::None;
-- if (tags & tagMask)
-- state |= TagState::Active;
-- if (urgent & tagMask)
-- state |= TagState::Urgent;
-- mon->bar.setTag(i, state, occupied & tagMask ? 1 : 0, clientTags & tagMask ? 0 : -1);
-- }
-- mon->tags = tags;
-- } else if (command == "layout") {
-- auto layout = std::string {};
-- std::getline(stream, layout);
-- mon->bar.setLayout(layout);
-- }
-- mon->hasData = true;
-- updatemon(*mon);
--}
--
- const std::string prefixStatus = "status ";
- const std::string prefixShow = "show ";
- const std::string prefixHide = "hide ";
-@@ -393,6 +405,10 @@ void onGlobalAdd(void*, wl_registry* registry, uint32_t name, const char* interf
- xdg_wm_base_add_listener(xdgWmBase, &xdgWmBaseListener, nullptr);
- return;
- }
-+ if (reg.handle(dwlWm, znet_tapesoftware_dwl_wm_v1_interface, 1)) {
-+ znet_tapesoftware_dwl_wm_v1_add_listener(dwlWm, &dwlWmListener, nullptr);
-+ return;
-+ }
- if (wl_seat* wlSeat; reg.handle(wlSeat, wl_seat_interface, 7)) {
- auto& seat = seats.emplace_back(Seat {name, wl_unique_ptr<wl_seat> {wlSeat}});
- wl_seat_add_listener(wlSeat, &seatListener, &seat);
-@@ -494,10 +510,6 @@ int main(int argc, char* argv[])
- .fd = displayFd,
- .events = POLLIN,
- });
-- pollfds.push_back({
-- .fd = STDIN_FILENO,
-- .events = POLLIN,
-- });
- if (fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK) < 0) {
- diesys("fcntl F_SETFL");
- }
-@@ -522,8 +534,6 @@ int main(int argc, char* argv[])
- ev.events = POLLIN;
- waylandFlush();
- }
-- } else if (ev.fd == STDIN_FILENO && (ev.revents & POLLIN)) {
-- onStdin();
- } else if (ev.fd == statusFifoFd && (ev.revents & POLLIN)) {
- onStatus();
- } else if (ev.fd == signalSelfPipe[0] && (ev.revents & POLLIN)) {
diff --git a/somebar/contrib/markup-in-status-messages.patch b/somebar/contrib/markup-in-status-messages.patch
deleted file mode 100644
index ab7e998..0000000
--- a/somebar/contrib/markup-in-status-messages.patch
+++ /dev/null
@@ -1,65 +0,0 @@
-From: Ben Collerson <benc@benc.cc>
-Date: Tue, 29 Nov 2022 11:29:15 +1000
-Subject: [PATCH] markup in status messages
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Allows pango markup to be used in status messages which allow colours to
-be used to highlight parts of status bar messages. eg:
-
-battery: full <span color="#ffff00">🔇0</span> Tue 11-20 20:10
----
- src/bar.cpp | 16 +++++++++++++++-
- src/bar.hpp | 1 +
- 2 files changed, 16 insertions(+), 1 deletion(-)
-
-diff --git a/src/bar.cpp b/src/bar.cpp
-index 507ce62..a96c547 100644
---- a/src/bar.cpp
-+++ b/src/bar.cpp
-@@ -81,6 +81,11 @@ void BarComponent::setText(const std::string& text)
- pango_layout_set_text(pangoLayout.get(), _text->c_str(), _text->size());
- }
-
-+void BarComponent::setAttributes(PangoAttrList *attrs)
-+{
-+ pango_layout_set_attributes(pangoLayout.get(), attrs);
-+}
-+
- Bar::Bar()
- {
- _pangoContext.reset(pango_font_map_create_context(pango_cairo_font_map_get_default()));
-@@ -156,7 +161,16 @@ void Bar::setTitle(const std::string& title)
- }
- void Bar::setStatus(const std::string& status)
- {
-- _statusCmp.setText(status);
-+ char *buf;
-+ GError *error = NULL;
-+ PangoAttrList *attrs;
-+ if (pango_parse_markup(status.c_str(), -1, 0, &attrs, &buf, NULL, &error)) {
-+ _statusCmp.setText(buf);
-+ _statusCmp.setAttributes(attrs);
-+ }
-+ else {
-+ _statusCmp.setText(error->message);
-+ }
- }
-
- void Bar::invalidate()
-diff --git a/src/bar.hpp b/src/bar.hpp
-index 176a1bc..dfc2043 100644
---- a/src/bar.hpp
-+++ b/src/bar.hpp
-@@ -17,6 +17,7 @@ public:
- explicit BarComponent(wl_unique_ptr<PangoLayout> layout);
- int width() const;
- void setText(const std::string& text);
-+ void setAttributes(PangoAttrList *attrs);
- wl_unique_ptr<PangoLayout> pangoLayout;
- int x {0};
- };
---
-2.38.1
-
diff --git a/somebar/contrib/show-status-on-selected-monitor.patch b/somebar/contrib/show-status-on-selected-monitor.patch
deleted file mode 100644
index ab26835..0000000
--- a/somebar/contrib/show-status-on-selected-monitor.patch
+++ /dev/null
@@ -1,43 +0,0 @@
-From 1ca4603b79e888980fb46d5dc6aa0d6f8afa2b3c Mon Sep 17 00:00:00 2001
-From: Ben Collerson <benc@benc.cc>
-Date: Mon, 28 Nov 2022 13:22:16 +1000
-Subject: [PATCH] show status on selected monitor
-
----
- src/bar.cpp | 7 ++++++-
- src/main.cpp | 1 +
- 2 files changed, 7 insertions(+), 1 deletion(-)
-
-diff --git a/src/bar.cpp b/src/bar.cpp
-index 507ce62..f962927 100644
---- a/src/bar.cpp
-+++ b/src/bar.cpp
-@@ -156,7 +156,12 @@ void Bar::setTitle(const std::string& title)
- }
- void Bar::setStatus(const std::string& status)
- {
-- _statusCmp.setText(status);
-+ if (_selected) {
-+ _statusCmp.setText(status);
-+ }
-+ else {
-+ _statusCmp.setText("");
-+ }
- }
-
- void Bar::invalidate()
-diff --git a/src/main.cpp b/src/main.cpp
-index 6274959..c6fd401 100644
---- a/src/main.cpp
-+++ b/src/main.cpp
-@@ -307,6 +307,7 @@ static void handleStdin(const std::string& line)
- uint32_t selected;
- stream >> selected;
- mon->bar.setSelected(selected);
-+ mon->bar.setStatus(lastStatus);
- if (selected) {
- selmon = &*mon;
- } else if (selmon == &*mon) {
---
-2.38.1
-
diff --git a/somebar/meson.build b/somebar/meson.build
deleted file mode 100644
index 6ad5a0f..0000000
--- a/somebar/meson.build
+++ /dev/null
@@ -1,31 +0,0 @@
-project('somebar', ['c', 'cpp'],
- version: '0.1.0',
- default_options: [
- 'cpp_std=c++17',
- 'cpp_args=-Wno-parentheses',
- ])
-
-wayland_dep = dependency('wayland-client')
-wayland_cursor_dep = dependency('wayland-cursor')
-cairo_dep = dependency('cairo')
-pango_dep = dependency('pango')
-pangocairo_dep = dependency('pangocairo')
-
-subdir('protocols')
-
-executable('somebar',
- 'src/main.cpp',
- 'src/shm_buffer.cpp',
- 'src/bar.cpp',
- wayland_sources,
- dependencies: [
- wayland_dep,
- wayland_cursor_dep,
- cairo_dep,
- pango_dep,
- pangocairo_dep,
- ],
- install: true,
- cpp_args: '-DSOMEBAR_VERSION="@0@"'.format(meson.project_version()))
-
-install_man('somebar.1')
diff --git a/somebar/protocols/meson.build b/somebar/protocols/meson.build
deleted file mode 100644
index 7bd222b..0000000
--- a/somebar/protocols/meson.build
+++ /dev/null
@@ -1,22 +0,0 @@
-# adapted from https://github.com/swaywm/swayidle/blob/0467c1e03a5780ed8e3ba611f099a838822ab550/meson.build
-wayland_scanner = find_program('wayland-scanner')
-wayland_protos_dep = dependency('wayland-protocols')
-wl_protocol_dir = wayland_protos_dep.get_pkgconfig_variable('pkgdatadir')
-wayland_scanner_code = generator(
- wayland_scanner,
- output: '@BASENAME@-protocol.c',
- arguments: ['private-code', '@INPUT@', '@OUTPUT@'])
-wayland_scanner_client = generator(
- wayland_scanner,
- output: '@BASENAME@-client-protocol.h',
- arguments: ['client-header', '@INPUT@', '@OUTPUT@'])
-
-wayland_xmls = [
- wl_protocol_dir + '/stable/xdg-shell/xdg-shell.xml',
- wl_protocol_dir + '/unstable/xdg-output/xdg-output-unstable-v1.xml',
- 'wlr-layer-shell-unstable-v1.xml',
-]
-wayland_sources = [
- wayland_scanner_code.process(wayland_xmls),
- wayland_scanner_client.process(wayland_xmls),
-]
diff --git a/somebar/protocols/wlr-layer-shell-unstable-v1.xml b/somebar/protocols/wlr-layer-shell-unstable-v1.xml
deleted file mode 100644
index 78ba050..0000000
--- a/somebar/protocols/wlr-layer-shell-unstable-v1.xml
+++ /dev/null
@@ -1,390 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<protocol name="wlr_layer_shell_unstable_v1">
- <copyright>
- Copyright © 2017 Drew DeVault
-
- Permission to use, copy, modify, distribute, and sell this
- software and its documentation for any purpose is hereby granted
- without fee, provided that the above copyright notice appear in
- all copies and that both that copyright notice and this permission
- notice appear in supporting documentation, and that the name of
- the copyright holders not be used in advertising or publicity
- pertaining to distribution of the software without specific,
- written prior permission. The copyright holders make no
- representations about the suitability of this software for any
- purpose. It is provided "as is" without express or implied
- warranty.
-
- THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
- SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
- FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
- SPECIAL, 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.
- </copyright>
-
- <interface name="zwlr_layer_shell_v1" version="4">
- <description summary="create surfaces that are layers of the desktop">
- Clients can use this interface to assign the surface_layer role to
- wl_surfaces. Such surfaces are assigned to a "layer" of the output and
- rendered with a defined z-depth respective to each other. They may also be
- anchored to the edges and corners of a screen and specify input handling
- semantics. This interface should be suitable for the implementation of
- many desktop shell components, and a broad number of other applications
- that interact with the desktop.
- </description>
-
- <request name="get_layer_surface">
- <description summary="create a layer_surface from a surface">
- Create a layer surface for an existing surface. This assigns the role of
- layer_surface, or raises a protocol error if another role is already
- assigned.
-
- Creating a layer surface from a wl_surface which has a buffer attached
- or committed is a client error, and any attempts by a client to attach
- or manipulate a buffer prior to the first layer_surface.configure call
- must also be treated as errors.
-
- After creating a layer_surface object and setting it up, the client
- must perform an initial commit without any buffer attached.
- The compositor will reply with a layer_surface.configure event.
- The client must acknowledge it and is then allowed to attach a buffer
- to map the surface.
-
- You may pass NULL for output to allow the compositor to decide which
- output to use. Generally this will be the one that the user most
- recently interacted with.
-
- Clients can specify a namespace that defines the purpose of the layer
- surface.
- </description>
- <arg name="id" type="new_id" interface="zwlr_layer_surface_v1"/>
- <arg name="surface" type="object" interface="wl_surface"/>
- <arg name="output" type="object" interface="wl_output" allow-null="true"/>
- <arg name="layer" type="uint" enum="layer" summary="layer to add this surface to"/>
- <arg name="name_space" type="string" summary="namespace for the layer surface"/>
- </request>
-
- <enum name="error">
- <entry name="role" value="0" summary="wl_surface has another role"/>
- <entry name="invalid_layer" value="1" summary="layer value is invalid"/>
- <entry name="already_constructed" value="2" summary="wl_surface has a buffer attached or committed"/>
- </enum>
-
- <enum name="layer">
- <description summary="available layers for surfaces">
- These values indicate which layers a surface can be rendered in. They
- are ordered by z depth, bottom-most first. Traditional shell surfaces
- will typically be rendered between the bottom and top layers.
- Fullscreen shell surfaces are typically rendered at the top layer.
- Multiple surfaces can share a single layer, and ordering within a
- single layer is undefined.
- </description>
-
- <entry name="background" value="0"/>
- <entry name="bottom" value="1"/>
- <entry name="top" value="2"/>
- <entry name="overlay" value="3"/>
- </enum>
-
- <!-- Version 3 additions -->
-
- <request name="destroy" type="destructor" since="3">
- <description summary="destroy the layer_shell object">
- This request indicates that the client will not use the layer_shell
- object any more. Objects that have been created through this instance
- are not affected.
- </description>
- </request>
- </interface>
-
- <interface name="zwlr_layer_surface_v1" version="4">
- <description summary="layer metadata interface">
- An interface that may be implemented by a wl_surface, for surfaces that
- are designed to be rendered as a layer of a stacked desktop-like
- environment.
-
- Layer surface state (layer, size, anchor, exclusive zone,
- margin, interactivity) is double-buffered, and will be applied at the
- time wl_surface.commit of the corresponding wl_surface is called.
-
- Attaching a null buffer to a layer surface unmaps it.
-
- Unmapping a layer_surface means that the surface cannot be shown by the
- compositor until it is explicitly mapped again. The layer_surface
- returns to the state it had right after layer_shell.get_layer_surface.
- The client can re-map the surface by performing a commit without any
- buffer attached, waiting for a configure event and handling it as usual.
- </description>
-
- <request name="set_size">
- <description summary="sets the size of the surface">
- Sets the size of the surface in surface-local coordinates. The
- compositor will display the surface centered with respect to its
- anchors.
-
- If you pass 0 for either value, the compositor will assign it and
- inform you of the assignment in the configure event. You must set your
- anchor to opposite edges in the dimensions you omit; not doing so is a
- protocol error. Both values are 0 by default.
-
- Size is double-buffered, see wl_surface.commit.
- </description>
- <arg name="width" type="uint"/>
- <arg name="height" type="uint"/>
- </request>
-
- <request name="set_anchor">
- <description summary="configures the anchor point of the surface">
- Requests that the compositor anchor the surface to the specified edges
- and corners. If two orthogonal edges are specified (e.g. 'top' and
- 'left'), then the anchor point will be the intersection of the edges
- (e.g. the top left corner of the output); otherwise the anchor point
- will be centered on that edge, or in the center if none is specified.
-
- Anchor is double-buffered, see wl_surface.commit.
- </description>
- <arg name="anchor" type="uint" enum="anchor"/>
- </request>
-
- <request name="set_exclusive_zone">
- <description summary="configures the exclusive geometry of this surface">
- Requests that the compositor avoids occluding an area with other
- surfaces. The compositor's use of this information is
- implementation-dependent - do not assume that this region will not
- actually be occluded.
-
- A positive value is only meaningful if the surface is anchored to one
- edge or an edge and both perpendicular edges. If the surface is not
- anchored, anchored to only two perpendicular edges (a corner), anchored
- to only two parallel edges or anchored to all edges, a positive value
- will be treated the same as zero.
-
- A positive zone is the distance from the edge in surface-local
- coordinates to consider exclusive.
-
- Surfaces that do not wish to have an exclusive zone may instead specify
- how they should interact with surfaces that do. If set to zero, the
- surface indicates that it would like to be moved to avoid occluding
- surfaces with a positive exclusive zone. If set to -1, the surface
- indicates that it would not like to be moved to accommodate for other
- surfaces, and the compositor should extend it all the way to the edges
- it is anchored to.
-
- For example, a panel might set its exclusive zone to 10, so that
- maximized shell surfaces are not shown on top of it. A notification
- might set its exclusive zone to 0, so that it is moved to avoid
- occluding the panel, but shell surfaces are shown underneath it. A
- wallpaper or lock screen might set their exclusive zone to -1, so that
- they stretch below or over the panel.
-
- The default value is 0.
-
- Exclusive zone is double-buffered, see wl_surface.commit.
- </description>
- <arg name="zone" type="int"/>
- </request>
-
- <request name="set_margin">
- <description summary="sets a margin from the anchor point">
- Requests that the surface be placed some distance away from the anchor
- point on the output, in surface-local coordinates. Setting this value
- for edges you are not anchored to has no effect.
-
- The exclusive zone includes the margin.
-
- Margin is double-buffered, see wl_surface.commit.
- </description>
- <arg name="top" type="int"/>
- <arg name="right" type="int"/>
- <arg name="bottom" type="int"/>
- <arg name="left" type="int"/>
- </request>
-
- <enum name="keyboard_interactivity">
- <description summary="types of keyboard interaction possible for a layer shell surface">
- Types of keyboard interaction possible for layer shell surfaces. The
- rationale for this is twofold: (1) some applications are not interested
- in keyboard events and not allowing them to be focused can improve the
- desktop experience; (2) some applications will want to take exclusive
- keyboard focus.
- </description>
-
- <entry name="none" value="0">
- <description summary="no keyboard focus is possible">
- This value indicates that this surface is not interested in keyboard
- events and the compositor should never assign it the keyboard focus.
-
- This is the default value, set for newly created layer shell surfaces.
-
- This is useful for e.g. desktop widgets that display information or
- only have interaction with non-keyboard input devices.
- </description>
- </entry>
- <entry name="exclusive" value="1">
- <description summary="request exclusive keyboard focus">
- Request exclusive keyboard focus if this surface is above the shell surface layer.
-
- For the top and overlay layers, the seat will always give
- exclusive keyboard focus to the top-most layer which has keyboard
- interactivity set to exclusive. If this layer contains multiple
- surfaces with keyboard interactivity set to exclusive, the compositor
- determines the one receiving keyboard events in an implementation-
- defined manner. In this case, no guarantee is made when this surface
- will receive keyboard focus (if ever).
-
- For the bottom and background layers, the compositor is allowed to use
- normal focus semantics.
-
- This setting is mainly intended for applications that need to ensure
- they receive all keyboard events, such as a lock screen or a password
- prompt.
- </description>
- </entry>
- <entry name="on_demand" value="2" since="4">
- <description summary="request regular keyboard focus semantics">
- This requests the compositor to allow this surface to be focused and
- unfocused by the user in an implementation-defined manner. The user
- should be able to unfocus this surface even regardless of the layer
- it is on.
-
- Typically, the compositor will want to use its normal mechanism to
- manage keyboard focus between layer shell surfaces with this setting
- and regular toplevels on the desktop layer (e.g. click to focus).
- Nevertheless, it is possible for a compositor to require a special
- interaction to focus or unfocus layer shell surfaces (e.g. requiring
- a click even if focus follows the mouse normally, or providing a
- keybinding to switch focus between layers).
-
- This setting is mainly intended for desktop shell components (e.g.
- panels) that allow keyboard interaction. Using this option can allow
- implementing a desktop shell that can be fully usable without the
- mouse.
- </description>
- </entry>
- </enum>
-
- <request name="set_keyboard_interactivity">
- <description summary="requests keyboard events">
- Set how keyboard events are delivered to this surface. By default,
- layer shell surfaces do not receive keyboard events; this request can
- be used to change this.
-
- This setting is inherited by child surfaces set by the get_popup
- request.
-
- Layer surfaces receive pointer, touch, and tablet events normally. If
- you do not want to receive them, set the input region on your surface
- to an empty region.
-
- Keyboard interactivity is double-buffered, see wl_surface.commit.
- </description>
- <arg name="keyboard_interactivity" type="uint" enum="keyboard_interactivity"/>
- </request>
-
- <request name="get_popup">
- <description summary="assign this layer_surface as an xdg_popup parent">
- This assigns an xdg_popup's parent to this layer_surface. This popup
- should have been created via xdg_surface::get_popup with the parent set
- to NULL, and this request must be invoked before committing the popup's
- initial state.
-
- See the documentation of xdg_popup for more details about what an
- xdg_popup is and how it is used.
- </description>
- <arg name="popup" type="object" interface="xdg_popup"/>
- </request>
-
- <request name="ack_configure">
- <description summary="ack a configure event">
- When a configure event is received, if a client commits the
- surface in response to the configure event, then the client
- must make an ack_configure request sometime before the commit
- request, passing along the serial of the configure event.
-
- If the client receives multiple configure events before it
- can respond to one, it only has to ack the last configure event.
-
- A client is not required to commit immediately after sending
- an ack_configure request - it may even ack_configure several times
- before its next surface commit.
-
- A client may send multiple ack_configure requests before committing, but
- only the last request sent before a commit indicates which configure
- event the client really is responding to.
- </description>
- <arg name="serial" type="uint" summary="the serial from the configure event"/>
- </request>
-
- <request name="destroy" type="destructor">
- <description summary="destroy the layer_surface">
- This request destroys the layer surface.
- </description>
- </request>
-
- <event name="configure">
- <description summary="suggest a surface change">
- The configure event asks the client to resize its surface.
-
- Clients should arrange their surface for the new states, and then send
- an ack_configure request with the serial sent in this configure event at
- some point before committing the new surface.
-
- The client is free to dismiss all but the last configure event it
- received.
-
- The width and height arguments specify the size of the window in
- surface-local coordinates.
-
- The size is a hint, in the sense that the client is free to ignore it if
- it doesn't resize, pick a smaller size (to satisfy aspect ratio or
- resize in steps of NxM pixels). If the client picks a smaller size and
- is anchored to two opposite anchors (e.g. 'top' and 'bottom'), the
- surface will be centered on this axis.
-
- If the width or height arguments are zero, it means the client should
- decide its own window dimension.
- </description>
- <arg name="serial" type="uint"/>
- <arg name="width" type="uint"/>
- <arg name="height" type="uint"/>
- </event>
-
- <event name="closed">
- <description summary="surface should be closed">
- The closed event is sent by the compositor when the surface will no
- longer be shown. The output may have been destroyed or the user may
- have asked for it to be removed. Further changes to the surface will be
- ignored. The client should destroy the resource after receiving this
- event, and create a new surface if they so choose.
- </description>
- </event>
-
- <enum name="error">
- <entry name="invalid_surface_state" value="0" summary="provided surface state is invalid"/>
- <entry name="invalid_size" value="1" summary="size is invalid"/>
- <entry name="invalid_anchor" value="2" summary="anchor bitfield is invalid"/>
- <entry name="invalid_keyboard_interactivity" value="3" summary="keyboard interactivity is invalid"/>
- </enum>
-
- <enum name="anchor" bitfield="true">
- <entry name="top" value="1" summary="the top edge of the anchor rectangle"/>
- <entry name="bottom" value="2" summary="the bottom edge of the anchor rectangle"/>
- <entry name="left" value="4" summary="the left edge of the anchor rectangle"/>
- <entry name="right" value="8" summary="the right edge of the anchor rectangle"/>
- </enum>
-
- <!-- Version 2 additions -->
-
- <request name="set_layer" since="2">
- <description summary="change the layer of the surface">
- Change the layer that the surface is rendered on.
-
- Layer is double-buffered, see wl_surface.commit.
- </description>
- <arg name="layer" type="uint" enum="zwlr_layer_shell_v1.layer" summary="layer to move this surface to"/>
- </request>
- </interface>
-</protocol>
diff --git a/somebar/screenshot.png b/somebar/screenshot.png
deleted file mode 100644
index 7a800fb..0000000
--- a/somebar/screenshot.png
+++ /dev/null
Binary files differ
diff --git a/somebar/somebar.1 b/somebar/somebar.1
deleted file mode 100644
index d822770..0000000
--- a/somebar/somebar.1
+++ /dev/null
@@ -1,55 +0,0 @@
-.TH somebar 1 somebar\-1.0
-.SH NAME
-somebar \- dwm-like bar for dwl
-.SH SYNOPSIS
-.B somebar
-.RB [ \-h ]
-.RB [ \-v ]
-.RB [ \-s
-.IR path ]
-.RB [ \-c
-.IR command
-arguments... ]
-.SH DESCRIPTION
-somebar is a status bar for dwl, visually and functionally resembling the
-dwm bar.
-.SH USAGE
-You must start somebar using dwl's `-s` flag, e.g. `dwl -s somebar`.
-
-Somebar can be controlled by writing to $XDG_RUNTIME_DIR/somebar-0, or the path
-defined by the `-s` argument. The following commands are supported:
-.TP
-.B status TEXT
-Updates the status bar
-.TP
-.B hide MONITOR
-Hides somebar on the specified monitor
-.TP
-.B show MONITOR
-Shows somebar on the specified monitor
-.TP
-.B toggle MONITOR
-Toggles somebar on the specified monitor
-.P
-MONITOR is an zxdg_output_v1 name, which can be determined e.g. using `weston-info`.
-Additionally, MONITOR can be `all` (all monitors) or `selected` (the monitor with focus).
-
-Commands can be sent either by writing to the file name above, or equivalently by calling
-somebar with the `-c` argument. For example: `somebar -c toggle all`. This is recommended
-for shell scripts, as there is no race-free way to write to a file only if it exists.
-.SH OPTIONS
-.TP
-.B \-h
-Displays a short help text and exits
-.TP
-.B \-v
-Displays version information and exits
-.TP
-.B \-s
-Sets the path to the somebar control FIFO. The default value is
-$XDG_RUNTIME_DIR/somebar-0
-.TP
-.B \-c
-Sends a command to the control FIFO. See the USAGE section.
-.SH BUGS
-Send bug reports to ~raphi/public-inbox@lists.sr.ht
diff --git a/somebar/src/bar.cpp b/somebar/src/bar.cpp
deleted file mode 100644
index 38164cd..0000000
--- a/somebar/src/bar.cpp
+++ /dev/null
@@ -1,321 +0,0 @@
-// somebar - dwl barbar
-// See LICENSE file for copyright and license details.
-
-#include <wayland-client-protocol.h>
-#include <pango/pangocairo.h>
-#include "bar.hpp"
-#include "cairo.h"
-#include "config.hpp"
-#include "pango/pango-font.h"
-#include "pango/pango-fontmap.h"
-#include "pango/pango-layout.h"
-
-const zwlr_layer_surface_v1_listener Bar::_layerSurfaceListener = {
- [](void* owner, zwlr_layer_surface_v1*, uint32_t serial, uint32_t width, uint32_t height)
- {
- static_cast<Bar*>(owner)->layerSurfaceConfigure(serial, width, height);
- }
-};
-const wl_callback_listener Bar::_frameListener = {
- [](void* owner, wl_callback* cb, uint32_t)
- {
- static_cast<Bar*>(owner)->render();
- wl_callback_destroy(cb);
- }
-};
-
-struct Font {
- PangoFontDescription* description;
- int height {0};
-};
-static Font getFont()
-{
- auto fontMap = pango_cairo_font_map_get_default();
- if (!fontMap) {
- die("pango_cairo_font_map_get_default");
- }
- auto fontDesc = pango_font_description_from_string(font);
- if (!fontDesc) {
- die("pango_font_description_from_string");
- }
- auto tempContext = pango_font_map_create_context(fontMap);
- if (!tempContext) {
- die("pango_font_map_create_context");
- }
- auto font = pango_font_map_load_font(fontMap, tempContext, fontDesc);
- if (!font) {
- die("pango_font_map_load_font");
- }
- auto metrics = pango_font_get_metrics(font, pango_language_get_default());
- if (!metrics) {
- die("pango_font_get_metrics");
- }
-
- auto res = Font {};
- res.description = fontDesc;
- res.height = PANGO_PIXELS(pango_font_metrics_get_height(metrics));
-
- pango_font_metrics_unref(metrics);
- g_object_unref(font);
- g_object_unref(tempContext);
- return res;
-}
-static Font barfont = getFont();
-
-BarComponent::BarComponent() { }
-BarComponent::BarComponent(wl_unique_ptr<PangoLayout> layout)
- : pangoLayout {std::move(layout)}
-{
-}
-
-int BarComponent::width() const
-{
- int w, h;
- pango_layout_get_size(pangoLayout.get(), &w, &h);
- return PANGO_PIXELS(w);
-}
-
-void BarComponent::setText(const std::string& text)
-{
- _text = std::make_unique<std::string>(text);
- pango_layout_set_text(pangoLayout.get(), _text->c_str(), _text->size());
-}
-
-Bar::Bar()
-{
- _pangoContext.reset(pango_font_map_create_context(pango_cairo_font_map_get_default()));
- if (!_pangoContext) {
- die("pango_font_map_create_context");
- }
- for (const auto& tagName : tagNames) {
- _tags.push_back({ TagState::None, 0, 0, createComponent(tagName) });
- }
- _layoutCmp = createComponent();
- _titleCmp = createComponent();
- _statusCmp = createComponent();
-}
-
-const wl_surface* Bar::surface() const
-{
- return _surface.get();
-}
-
-bool Bar::visible() const
-{
- return _surface.get();
-}
-
-void Bar::show(wl_output* output)
-{
- if (visible()) {
- return;
- }
- _surface.reset(wl_compositor_create_surface(compositor));
- _layerSurface.reset(zwlr_layer_shell_v1_get_layer_surface(wlrLayerShell,
- _surface.get(), output, ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM, "net.tapesoftware.Somebar"));
- zwlr_layer_surface_v1_add_listener(_layerSurface.get(), &_layerSurfaceListener, this);
- auto anchor = topbar ? ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP : ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM;
- zwlr_layer_surface_v1_set_anchor(_layerSurface.get(),
- anchor | ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT);
-
- auto barSize = barfont.height + paddingY * 2;
- zwlr_layer_surface_v1_set_size(_layerSurface.get(), 0, barSize);
- zwlr_layer_surface_v1_set_exclusive_zone(_layerSurface.get(), barSize + gapY);
- wl_surface_commit(_surface.get());
-}
-
-void Bar::hide()
-{
- if (!visible()) {
- return;
- }
- _layerSurface.reset();
- _surface.reset();
- _bufs.reset();
-}
-
-void Bar::setTag(int tag, int state, int numClients, int focusedClient)
-{
- auto& t = _tags[tag];
- t.state = state;
- t.numClients = numClients;
- t.focusedClient = focusedClient;
-}
-
-void Bar::setSelected(bool selected)
-{
- _selected = selected;
-}
-void Bar::setLayout(const std::string& layout)
-{
- _layoutCmp.setText(layout);
-}
-void Bar::setTitle(const std::string& title)
-{
- _titleCmp.setText(title);
-}
-void Bar::setStatus(const std::string& status)
-{
- _statusCmp.setText(status);
-}
-
-void Bar::invalidate()
-{
- if (_invalid || !visible()) {
- return;
- }
- _invalid = true;
- auto frame = wl_surface_frame(_surface.get());
- wl_callback_add_listener(frame, &_frameListener, this);
- wl_surface_commit(_surface.get());
-}
-
-void Bar::click(Monitor* mon, int x, int, int btn)
-{
- Arg arg = {0};
- Arg* argp = nullptr;
- int control = ClkNone;
- if (x > _statusCmp.x) {
- control = ClkStatusText;
- } else if (x > _titleCmp.x) {
- control = ClkWinTitle;
- } else if (x > _layoutCmp.x) {
- control = ClkLayoutSymbol;
- } else for (auto tag = _tags.size()-1; tag >= 0; tag--) {
- if (x > _tags[tag].component.x) {
- control = ClkTagBar;
- arg.ui = 1<<tag;
- argp = &arg;
- break;
- }
- }
- for (const auto& button : buttons) {
- if (button.control == control && button.btn == btn) {
- button.func(*mon, *(argp ? argp : &button.arg));
- return;
- }
- }
-}
-
-void Bar::layerSurfaceConfigure(uint32_t serial, uint32_t width, uint32_t height)
-{
- zwlr_layer_surface_v1_ack_configure(_layerSurface.get(), serial);
- if (_bufs && width == _bufs->width && height == _bufs->height) {
- return;
- }
- _bufs.emplace(width, height, WL_SHM_FORMAT_XRGB8888);
- render();
-}
-
-void Bar::render()
-{
- if (!_bufs) {
- return;
- }
- auto img = wl_unique_ptr<cairo_surface_t> {cairo_image_surface_create_for_data(
- _bufs->data(),
- CAIRO_FORMAT_ARGB32,
- _bufs->width,
- _bufs->height,
- _bufs->stride
- )};
- auto painter = wl_unique_ptr<cairo_t> {cairo_create(img.get())};
- _painter = painter.get();
- pango_cairo_update_context(_painter, _pangoContext.get());
- _x = 0;
-
- renderTags();
- setColorScheme(_selected ? colorActive : colorInactive);
- renderComponent(_layoutCmp);
- renderComponent(_titleCmp);
- renderStatus();
-
- _painter = nullptr;
- wl_surface_attach(_surface.get(), _bufs->buffer(), 0, 0);
- wl_surface_damage(_surface.get(), 0, 0, _bufs->width, _bufs->height);
- wl_surface_commit(_surface.get());
- _bufs->flip();
- _invalid = false;
-}
-
-void Bar::renderTags()
-{
- for (auto &tag : _tags) {
- setColorScheme(
- tag.state & TagState::Active ? colorActive : colorInactive,
- tag.state & TagState::Urgent);
- renderComponent(tag.component);
-
- if(!tag.numClients)
- continue;
-
- int s = barfont.height / 9;
- int w = barfont.height / 6 + 2;
- if (tag.focusedClient != -1) {
- cairo_rectangle(_painter, tag.component.x + s, s, w, w);
- cairo_fill(_painter);
- } else {
- cairo_rectangle(_painter, (double)(tag.component.x + s) + 0.5, (double)(s) + 0.5, w, w);
- cairo_set_line_width(_painter, 1);
- cairo_stroke(_painter);
- }
- }
-}
-
-void Bar::renderStatus()
-{
- pango_cairo_update_layout(_painter, _statusCmp.pangoLayout.get());
- beginBg();
- auto start = _bufs->width - _statusCmp.width() - paddingX*2;
- cairo_rectangle(_painter, _x, 0, _bufs->width-_x+start, _bufs->height);
- cairo_fill(_painter);
-
- _x = start;
- setColorScheme(colorInactive);
- renderComponent(_statusCmp);
-}
-
-void Bar::setColorScheme(const ColorScheme& scheme, bool invert)
-{
- _colorScheme = invert
- ? ColorScheme {scheme.bg, scheme.fg}
- : ColorScheme {scheme.fg, scheme.bg};
-}
-static void setColor(cairo_t* painter, const Color& color)
-{
- cairo_set_source_rgba(painter,
- color.r/255.0, color.g/255.0, color.b/255.0, color.a/255.0);
-}
-void Bar::beginFg()
-{
- setColor(_painter, _colorScheme.fg);
-}
-void Bar::beginBg()
-{
- setColor(_painter, _colorScheme.bg);
-}
-
-void Bar::renderComponent(BarComponent& component)
-{
- pango_cairo_update_layout(_painter, component.pangoLayout.get());
- auto size = component.width() + paddingX*2;
- component.x = _x;
-
- beginBg();
- cairo_rectangle(_painter, _x, 0, size, _bufs->height);
- cairo_fill(_painter);
- cairo_move_to(_painter, _x+paddingX, paddingY);
-
- beginFg();
- pango_cairo_show_layout(_painter, component.pangoLayout.get());
- _x += size;
-}
-
-BarComponent Bar::createComponent(const std::string &initial)
-{
- auto layout = pango_layout_new(_pangoContext.get());
- pango_layout_set_font_description(layout, barfont.description);
- auto res = BarComponent {wl_unique_ptr<PangoLayout> {layout}};
- res.setText(initial);
- return res;
-}
diff --git a/somebar/src/bar.hpp b/somebar/src/bar.hpp
deleted file mode 100644
index 176a1bc..0000000
--- a/somebar/src/bar.hpp
+++ /dev/null
@@ -1,74 +0,0 @@
-// somebar - dwl bar
-// See LICENSE file for copyright and license details.
-
-#pragma once
-#include <optional>
-#include <string>
-#include <vector>
-#include <wayland-client.h>
-#include "wlr-layer-shell-unstable-v1-client-protocol.h"
-#include "common.hpp"
-#include "shm_buffer.hpp"
-
-class BarComponent {
- std::unique_ptr<std::string> _text;
-public:
- BarComponent();
- explicit BarComponent(wl_unique_ptr<PangoLayout> layout);
- int width() const;
- void setText(const std::string& text);
- wl_unique_ptr<PangoLayout> pangoLayout;
- int x {0};
-};
-
-struct Tag {
- int state;
- int numClients;
- int focusedClient;
- BarComponent component;
-};
-
-struct Monitor;
-class Bar {
- static const zwlr_layer_surface_v1_listener _layerSurfaceListener;
- static const wl_callback_listener _frameListener;
-
- wl_unique_ptr<wl_surface> _surface;
- wl_unique_ptr<zwlr_layer_surface_v1> _layerSurface;
- wl_unique_ptr<PangoContext> _pangoContext;
- std::optional<ShmBuffer> _bufs;
- std::vector<Tag> _tags;
- BarComponent _layoutCmp, _titleCmp, _statusCmp;
- bool _selected;
- bool _invalid {false};
-
- // only vaild during render()
- cairo_t* _painter {nullptr};
- int _x;
- ColorScheme _colorScheme;
-
- void layerSurfaceConfigure(uint32_t serial, uint32_t width, uint32_t height);
- void render();
- void renderTags();
- void renderStatus();
-
- // low-level rendering
- void setColorScheme(const ColorScheme& scheme, bool invert = false);
- void beginFg();
- void beginBg();
- void renderComponent(BarComponent& component);
- BarComponent createComponent(const std::string& initial = {});
-public:
- Bar();
- const wl_surface* surface() const;
- bool visible() const;
- void show(wl_output* output);
- void hide();
- void setTag(int tag, int state, int numClients, int focusedClient);
- void setSelected(bool selected);
- void setLayout(const std::string& layout);
- void setTitle(const std::string& title);
- void setStatus(const std::string& status);
- void invalidate();
- void click(Monitor* mon, int x, int y, int btn);
-};
diff --git a/somebar/src/common.hpp b/somebar/src/common.hpp
deleted file mode 100644
index c905358..0000000
--- a/somebar/src/common.hpp
+++ /dev/null
@@ -1,76 +0,0 @@
-// somebar - dwl bar
-// See LICENSE file for copyright and license details.
-
-#pragma once
-#include <memory>
-#include <string>
-#include <vector>
-#include <wayland-client.h>
-#include <linux/input-event-codes.h>
-#include <cairo/cairo.h>
-#include <pango/pango.h>
-#include "wlr-layer-shell-unstable-v1-client-protocol.h"
-
-struct Color {
- Color() {}
- constexpr Color(uint8_t r, uint8_t g, uint8_t b, uint8_t a=255) : r(r), g(g), b(b), a(a) { }
- uint8_t r, g, b, a {255};
-};
-struct ColorScheme {
- Color fg, bg;
-};
-union Arg {
- unsigned int ui;
- const void* v;
-};
-struct Monitor;
-
-enum TagState { None, Active = 0x01, Urgent = 0x02 };
-enum Control { ClkNone, ClkTagBar, ClkLayoutSymbol, ClkWinTitle, ClkStatusText };
-struct Button {
- int control;
- int btn; // <linux/input-event-codes.h>
- void (*func)(Monitor& mon, const Arg& arg);
- const Arg arg;
-};
-
-extern wl_display* display;
-extern wl_compositor* compositor;
-extern wl_shm* shm;
-extern zwlr_layer_shell_v1* wlrLayerShell;
-
-void spawn(Monitor&, const Arg& arg);
-void setCloexec(int fd);
-[[noreturn]] void die(const char* why);
-[[noreturn]] void diesys(const char* why);
-
-// wayland smart pointers
-template<typename T>
-struct WlDeleter;
-#define WL_DELETER(type, fn) template<> struct WlDeleter<type> { \
- void operator()(type* v) { if(v) fn(v); } \
- }
-
-template<typename T>
-using wl_unique_ptr = std::unique_ptr<T, WlDeleter<T>>;
-
-inline void wl_output_release_checked(wl_output* output) {
- if (wl_output_get_version(output) >= WL_OUTPUT_RELEASE_SINCE_VERSION) {
- wl_output_release(output);
- }
-}
-
-WL_DELETER(wl_buffer, wl_buffer_destroy);
-WL_DELETER(wl_output, wl_output_release_checked);
-WL_DELETER(wl_pointer, wl_pointer_release);
-WL_DELETER(wl_seat, wl_seat_release);
-WL_DELETER(wl_surface, wl_surface_destroy);
-WL_DELETER(zwlr_layer_surface_v1, zwlr_layer_surface_v1_destroy);
-
-WL_DELETER(cairo_t, cairo_destroy);
-WL_DELETER(cairo_surface_t, cairo_surface_destroy);
-
-WL_DELETER(PangoContext, g_object_unref);
-WL_DELETER(PangoLayout, g_object_unref);
-
-#undef WL_DELETER
diff --git a/somebar/src/config.def.hpp b/somebar/src/config.def.hpp
deleted file mode 100644
index 40a8c95..0000000
--- a/somebar/src/config.def.hpp
+++ /dev/null
@@ -1,27 +0,0 @@
-// somebar - dwl bar
-// See LICENSE file for copyright and license details.
-
-#pragma once
-#include "common.hpp"
-
-constexpr bool topbar = true;
-
-constexpr int paddingX = 10;
-constexpr int paddingY = 3;
-
-// See https://docs.gtk.org/Pango/type_func.FontDescription.from_string.html
-constexpr const char* font = "Sans 12";
-
-constexpr ColorScheme colorInactive = {Color(0xbb, 0xbb, 0xbb), Color(0x22, 0x22, 0x22)};
-constexpr ColorScheme colorActive = {Color(0xee, 0xee, 0xee), Color(0x00, 0x55, 0x77)};
-constexpr const char* termcmd[] = {"foot", nullptr};
-
-static std::vector<std::string> tagNames = {
- "1", "2", "3",
- "4", "5", "6",
- "7", "8", "9",
-};
-
-constexpr Button buttons[] = {
- { ClkStatusText, BTN_RIGHT, spawn, {.v = termcmd} },
-};
diff --git a/somebar/src/config.hpp b/somebar/src/config.hpp
deleted file mode 100644
index caf0178..0000000
--- a/somebar/src/config.hpp
+++ /dev/null
@@ -1,31 +0,0 @@
-// somebar - dwl bar
-// See LICENSE file for copyright and license details.
-
-#pragma once
-#include "common.hpp"
-
-constexpr bool topbar = false;
-
-constexpr int paddingX = 10;
-constexpr int paddingY = 3;
-constexpr int gapY = 3;
-
-// See https://docs.gtk.org/Pango/type_func.FontDescription.from_string.html
-constexpr const char* font = "BmPlus IBM VGA 9x16 8";
-
-constexpr Color orange = Color(0xff, 0x8c, 0x00);
-constexpr Color gray2 = Color(0x00, 0x00, 0x00);
-
-constexpr ColorScheme colorInactive = {orange, gray2};
-constexpr ColorScheme colorActive = {gray2, orange};
-constexpr const char* termcmd[] = {"foot", nullptr};
-
-static std::vector<std::string> tagNames = {
- "F", "U", "H",
- ".", "V", "L",
- "O", "M"
-};
-
-constexpr Button buttons[] = {
- { ClkStatusText, BTN_RIGHT, spawn, {.v = termcmd} },
-};
diff --git a/somebar/src/line_buffer.hpp b/somebar/src/line_buffer.hpp
deleted file mode 100644
index a5497bf..0000000
--- a/somebar/src/line_buffer.hpp
+++ /dev/null
@@ -1,71 +0,0 @@
-// somebar - dwl bar
-// See LICENSE file for copyright and license details.
-
-#pragma once
-#include <array>
-#include <algorithm>
-#include <sys/types.h>
-
-// reads data from Reader, and passes complete lines to Consumer.
-template<size_t BufSize>
-class LineBuffer {
- using Iterator = typename std::array<char, BufSize>::iterator;
- std::array<char, BufSize> _buffer;
- Iterator _bufferedTo;
- Iterator _consumedTo;
- bool _discardLine {false};
-public:
- LineBuffer()
- : _bufferedTo {_buffer.begin()}
- , _consumedTo {_buffer.begin()}
- {
- }
-
- template<typename Reader, typename Consumer>
- ssize_t readLines(const Reader& reader, const Consumer& consumer)
- {
- while (true) {
- auto bytesRead = reader(_bufferedTo, _buffer.end() - _bufferedTo);
- if (bytesRead <= 0) {
- return bytesRead;
- }
- _bufferedTo += bytesRead;
- dispatchLines(consumer);
- resetBuffer();
- }
- }
-private:
- template<typename Consumer>
- void dispatchLines(const Consumer& consumer)
- {
- while (true) {
- auto separator = std::find(_consumedTo, _bufferedTo, '\n');
- if (separator == _bufferedTo) {
- break;
- }
- size_t lineLength = separator - _consumedTo;
- if (!_discardLine) {
- consumer(_consumedTo, lineLength);
- }
- _consumedTo = separator + 1;
- _discardLine = false;
- }
- }
-
- void resetBuffer()
- {
- size_t bytesRemaining = _bufferedTo - _consumedTo;
- if (bytesRemaining == _buffer.size()) {
- // line too long
- _discardLine = true;
- _consumedTo = _buffer.begin();
- _bufferedTo = _buffer.begin();
- } else {
- // move the last partial message to the front of the buffer, so a full-sized
- // message will fit
- std::copy(_consumedTo, _bufferedTo, _buffer.begin());
- _consumedTo = _buffer.begin();
- _bufferedTo = _consumedTo + bytesRemaining;
- }
- }
-};
diff --git a/somebar/src/main.cpp b/somebar/src/main.cpp
deleted file mode 100644
index 6274959..0000000
--- a/somebar/src/main.cpp
+++ /dev/null
@@ -1,613 +0,0 @@
-// somebar - dwl bar
-// See LICENSE file for copyright and license details.
-
-#include <algorithm>
-#include <cstdio>
-#include <sstream>
-#include <list>
-#include <optional>
-#include <utility>
-#include <vector>
-#include <fcntl.h>
-#include <poll.h>
-#include <signal.h>
-#include <sys/mman.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <linux/input-event-codes.h>
-#include <wayland-client.h>
-#include <wayland-cursor.h>
-#include "wlr-layer-shell-unstable-v1-client-protocol.h"
-#include "xdg-output-unstable-v1-client-protocol.h"
-#include "xdg-shell-client-protocol.h"
-#include "common.hpp"
-#include "config.hpp"
-#include "bar.hpp"
-#include "line_buffer.hpp"
-
-struct Monitor {
- uint32_t registryName;
- std::string xdgName;
- wl_unique_ptr<wl_output> wlOutput;
- Bar bar;
- bool desiredVisibility {true};
- bool hasData;
- uint32_t tags;
-};
-
-struct SeatPointer {
- wl_unique_ptr<wl_pointer> wlPointer;
- Monitor* focusedMonitor;
- int x, y;
- std::vector<int> btns;
-};
-struct Seat {
- uint32_t name;
- wl_unique_ptr<wl_seat> wlSeat;
- std::optional<SeatPointer> pointer;
-};
-
-static Monitor* monitorFromSurface(const wl_surface* surface);
-static void setupMonitor(uint32_t name, wl_output* output);
-static void updatemon(Monitor &mon);
-static void onReady();
-static void setupStatusFifo();
-static void onStatus();
-static void onStdin();
-static void handleStdin(const std::string& line);
-static void updateVisibility(const std::string& name, bool(*updater)(bool));
-static void onGlobalAdd(void*, wl_registry* registry, uint32_t name, const char* interface, uint32_t version);
-static void onGlobalRemove(void*, wl_registry* registry, uint32_t name);
-static void requireGlobal(const void* p, const char* name);
-static void waylandFlush();
-static void cleanup();
-
-wl_display* display;
-wl_compositor* compositor;
-wl_shm* shm;
-zwlr_layer_shell_v1* wlrLayerShell;
-static xdg_wm_base* xdgWmBase;
-static zxdg_output_manager_v1* xdgOutputManager;
-static wl_surface* cursorSurface;
-static wl_cursor_image* cursorImage;
-static bool ready;
-static std::list<Monitor> monitors;
-static std::vector<std::pair<uint32_t, wl_output*>> uninitializedOutputs;
-static std::list<Seat> seats;
-static Monitor* selmon;
-static std::string lastStatus;
-static std::string statusFifoName;
-static std::vector<pollfd> pollfds;
-static std::array<int, 2> signalSelfPipe;
-static int displayFd {-1};
-static int statusFifoFd {-1};
-static int statusFifoWriter {-1};
-static bool quitting {false};
-
-void spawn(Monitor&, const Arg& arg)
-{
- if (fork() == 0) {
- auto argv = static_cast<char* const*>(arg.v);
- setsid();
- execvp(argv[0], argv);
- fprintf(stderr, "somebar: execvp %s ", argv[0]);
- perror(" failed");
- exit(1);
- }
-}
-
-static const struct xdg_wm_base_listener xdgWmBaseListener = {
- [](void*, xdg_wm_base* sender, uint32_t serial) {
- xdg_wm_base_pong(sender, serial);
- }
-};
-
-static const struct zxdg_output_v1_listener xdgOutputListener = {
- .logical_position = [](void*, zxdg_output_v1*, int, int) { },
- .logical_size = [](void*, zxdg_output_v1*, int, int) { },
- .done = [](void*, zxdg_output_v1*) { },
- .name = [](void* mp, zxdg_output_v1* xdgOutput, const char* name) {
- auto& monitor = *static_cast<Monitor*>(mp);
- monitor.xdgName = name;
- zxdg_output_v1_destroy(xdgOutput);
- },
- .description = [](void*, zxdg_output_v1*, const char*) { },
-};
-
-Monitor* monitorFromSurface(const wl_surface* surface)
-{
- auto mon = std::find_if(begin(monitors), end(monitors), [surface](const Monitor& mon) {
- return mon.bar.surface() == surface;
- });
- return mon != end(monitors) ? &*mon : nullptr;
-}
-static const struct wl_pointer_listener pointerListener = {
- .enter = [](void* sp, wl_pointer* pointer, uint32_t serial,
- wl_surface* surface, wl_fixed_t x, wl_fixed_t y)
- {
- auto& seat = *static_cast<Seat*>(sp);
- seat.pointer->focusedMonitor = monitorFromSurface(surface);
- if (!cursorImage) {
- auto cursorTheme = wl_cursor_theme_load(nullptr, 24, shm);
- cursorImage = wl_cursor_theme_get_cursor(cursorTheme, "left_ptr")->images[0];
- cursorSurface = wl_compositor_create_surface(compositor);
- wl_surface_attach(cursorSurface, wl_cursor_image_get_buffer(cursorImage), 0, 0);
- wl_surface_commit(cursorSurface);
- }
- wl_pointer_set_cursor(pointer, serial, cursorSurface,
- cursorImage->hotspot_x, cursorImage->hotspot_y);
- },
- .leave = [](void* sp, wl_pointer*, uint32_t serial, wl_surface*) {
- auto& seat = *static_cast<Seat*>(sp);
- seat.pointer->focusedMonitor = nullptr;
- },
- .motion = [](void* sp, wl_pointer*, uint32_t, wl_fixed_t x, wl_fixed_t y) {
- auto& seat = *static_cast<Seat*>(sp);
- seat.pointer->x = wl_fixed_to_int(x);
- seat.pointer->y = wl_fixed_to_int(y);
- },
- .button = [](void* sp, wl_pointer*, uint32_t, uint32_t, uint32_t button, uint32_t pressed) {
- auto& seat = *static_cast<Seat*>(sp);
- auto it = std::find(begin(seat.pointer->btns), end(seat.pointer->btns), button);
- if (pressed == WL_POINTER_BUTTON_STATE_PRESSED && it == end(seat.pointer->btns)) {
- seat.pointer->btns.push_back(button);
- } else if (pressed == WL_POINTER_BUTTON_STATE_RELEASED && it != end(seat.pointer->btns)) {
- seat.pointer->btns.erase(it);
- }
- },
- .axis = [](void* sp, wl_pointer*, uint32_t, uint32_t, wl_fixed_t) { },
- .frame = [](void* sp, wl_pointer*) {
- auto& seat = *static_cast<Seat*>(sp);
- auto mon = seat.pointer->focusedMonitor;
- if (!mon) {
- return;
- }
- for (auto btn : seat.pointer->btns) {
- mon->bar.click(mon, seat.pointer->x, seat.pointer->y, btn);
- }
- seat.pointer->btns.clear();
- },
- .axis_source = [](void*, wl_pointer*, uint32_t) { },
- .axis_stop = [](void*, wl_pointer*, uint32_t, uint32_t) { },
- .axis_discrete = [](void*, wl_pointer*, uint32_t, int32_t) { },
-};
-
-static const struct wl_seat_listener seatListener = {
- .capabilities = [](void* sp, wl_seat*, uint32_t cap)
- {
- auto& seat = *static_cast<Seat*>(sp);
- auto hasPointer = cap & WL_SEAT_CAPABILITY_POINTER;
- if (!seat.pointer && hasPointer) {
- auto &pointer = seat.pointer.emplace();
- pointer.wlPointer = wl_unique_ptr<wl_pointer> {wl_seat_get_pointer(seat.wlSeat.get())};
- wl_pointer_add_listener(seat.pointer->wlPointer.get(), &pointerListener, &seat);
- } else if (seat.pointer && !hasPointer) {
- seat.pointer.reset();
- }
- },
- .name = [](void*, wl_seat*, const char* name) { }
-};
-
-void setupMonitor(uint32_t name, wl_output* output) {
- auto& monitor = monitors.emplace_back(Monitor {name, {}, wl_unique_ptr<wl_output> {output}});
- monitor.bar.setStatus(lastStatus);
- auto xdgOutput = zxdg_output_manager_v1_get_xdg_output(xdgOutputManager, monitor.wlOutput.get());
- zxdg_output_v1_add_listener(xdgOutput, &xdgOutputListener, &monitor);
-}
-
-void updatemon(Monitor& mon)
-{
- if (!mon.hasData) {
- return;
- }
- if (mon.desiredVisibility) {
- if (mon.bar.visible()) {
- mon.bar.invalidate();
- } else {
- mon.bar.show(mon.wlOutput.get());
- }
- } else if (mon.bar.visible()) {
- mon.bar.hide();
- }
-}
-
-// called after we have received the initial batch of globals
-void onReady()
-{
- requireGlobal(compositor, "wl_compositor");
- requireGlobal(shm, "wl_shm");
- requireGlobal(wlrLayerShell, "zwlr_layer_shell_v1");
- requireGlobal(xdgOutputManager, "zxdg_output_manager_v1");
- setupStatusFifo();
- wl_display_roundtrip(display); // roundtrip so we receive all dwl tags etc.
-
- ready = true;
- for (auto output : uninitializedOutputs) {
- setupMonitor(output.first, output.second);
- }
- wl_display_roundtrip(display); // wait for xdg_output names before we read stdin
-}
-
-bool createFifo(std::string path)
-{
- auto result = mkfifo(path.c_str(), 0666);
- if (result == 0) {
- auto fd = open(path.c_str(), O_CLOEXEC | O_NONBLOCK | O_RDONLY);
- if (fd < 0) {
- diesys("open status fifo reader");
- }
- statusFifoName = path;
- statusFifoFd = fd;
-
- fd = open(path.c_str(), O_CLOEXEC | O_WRONLY);
- if (fd < 0) {
- diesys("open status fifo writer");
- }
- statusFifoWriter = fd;
-
- pollfds.push_back({
- .fd = statusFifoFd,
- .events = POLLIN,
- });
- return true;
- } else if (errno != EEXIST) {
- diesys("mkfifo");
- }
-
- return false;
-}
-
-void setupStatusFifo()
-{
- if (!statusFifoName.empty()) {
- createFifo(statusFifoName);
- return;
- }
-
- for (auto i=0; i<100; i++) {
- auto path = std::string{getenv("XDG_RUNTIME_DIR")} + "/somebar-" + std::to_string(i);
- if (createFifo(path)) {
- return;
- }
- }
-}
-
-static LineBuffer<512> stdinBuffer;
-static void onStdin()
-{
- auto res = stdinBuffer.readLines(
- [](void* p, size_t size) { return read(0, p, size); },
- [](char* p, size_t size) { handleStdin({p, size}); });
- if (res == 0) {
- quitting = true;
- }
-}
-
-static void handleStdin(const std::string& line)
-{
- // this parses the lines that dwl sends in printstatus()
- std::string monName, command;
- auto stream = std::istringstream {line};
- stream >> monName >> command;
- if (!stream.good()) {
- return;
- }
- auto mon = std::find_if(begin(monitors), end(monitors), [&](const Monitor& mon) {
- return mon.xdgName == monName;
- });
- if (mon == end(monitors))
- return;
- if (command == "title") {
- auto title = std::string {};
- stream >> std::ws;
- std::getline(stream, title);
- mon->bar.setTitle(title);
- } else if (command == "selmon") {
- uint32_t selected;
- stream >> selected;
- mon->bar.setSelected(selected);
- if (selected) {
- selmon = &*mon;
- } else if (selmon == &*mon) {
- selmon = nullptr;
- }
- } else if (command == "tags") {
- uint32_t occupied, tags, clientTags, urgent;
- stream >> occupied >> tags >> clientTags >> urgent;
- for (auto i=0u; i<tagNames.size(); i++) {
- auto tagMask = 1 << i;
- int state = TagState::None;
- if (tags & tagMask)
- state |= TagState::Active;
- if (urgent & tagMask)
- state |= TagState::Urgent;
- mon->bar.setTag(i, state, occupied & tagMask ? 1 : 0, clientTags & tagMask ? 0 : -1);
- }
- mon->tags = tags;
- } else if (command == "layout") {
- auto layout = std::string {};
- stream >> std::ws;
- std::getline(stream, layout);
- mon->bar.setLayout(layout);
- }
- mon->hasData = true;
- updatemon(*mon);
-}
-
-const std::string prefixStatus = "status ";
-const std::string prefixShow = "show ";
-const std::string prefixHide = "hide ";
-const std::string prefixToggle = "toggle ";
-const std::string argAll = "all";
-const std::string argSelected = "selected";
-
-static LineBuffer<512> statusBuffer;
-void onStatus()
-{
- statusBuffer.readLines(
- [](void* p, size_t size) {
- return read(statusFifoFd, p, size);
- },
- [](const char* buffer, size_t n) {
- auto str = std::string {buffer, n};
- if (str.rfind(prefixStatus, 0) == 0) {
- lastStatus = str.substr(prefixStatus.size());
- for (auto &monitor : monitors) {
- monitor.bar.setStatus(lastStatus);
- monitor.bar.invalidate();
- }
- } else if (str.rfind(prefixShow, 0) == 0) {
- updateVisibility(str.substr(prefixShow.size()), [](bool) { return true; });
- } else if (str.rfind(prefixHide, 0) == 0) {
- updateVisibility(str.substr(prefixHide.size()), [](bool) { return false; });
- } else if (str.rfind(prefixToggle, 0) == 0) {
- updateVisibility(str.substr(prefixToggle.size()), [](bool vis) { return !vis; });
- }
- });
-}
-
-void updateVisibility(const std::string& name, bool(*updater)(bool))
-{
- auto isCurrent = name == argSelected;
- auto isAll = name == argAll;
- for (auto& mon : monitors) {
- if (isAll ||
- isCurrent && &mon == selmon ||
- mon.xdgName == name) {
- auto newVisibility = updater(mon.desiredVisibility);
- if (newVisibility != mon.desiredVisibility) {
- mon.desiredVisibility = newVisibility;
- updatemon(mon);
- }
- }
- }
-}
-
-struct HandleGlobalHelper {
- wl_registry* registry;
- uint32_t name;
- const char* interface;
-
- template<typename T>
- bool handle(T& store, const wl_interface& iface, int version) {
- if (strcmp(interface, iface.name)) {
- return false;
- }
- store = static_cast<T>(wl_registry_bind(registry, name, &iface, version));
- return true;
- }
-};
-void onGlobalAdd(void*, wl_registry* registry, uint32_t name, const char* interface, uint32_t version)
-{
- auto reg = HandleGlobalHelper { registry, name, interface };
- if (reg.handle(compositor, wl_compositor_interface, 4)) return;
- if (reg.handle(shm, wl_shm_interface, 1)) return;
- if (reg.handle(wlrLayerShell, zwlr_layer_shell_v1_interface, 4)) return;
- if (reg.handle(xdgOutputManager, zxdg_output_manager_v1_interface, 3)) return;
- if (reg.handle(xdgWmBase, xdg_wm_base_interface, 2)) {
- xdg_wm_base_add_listener(xdgWmBase, &xdgWmBaseListener, nullptr);
- return;
- }
- if (wl_seat* wlSeat; reg.handle(wlSeat, wl_seat_interface, 7)) {
- auto& seat = seats.emplace_back(Seat {name, wl_unique_ptr<wl_seat> {wlSeat}});
- wl_seat_add_listener(wlSeat, &seatListener, &seat);
- return;
- }
- if (wl_output* output; reg.handle(output, wl_output_interface, 1)) {
- if (ready) {
- setupMonitor(name, output);
- } else {
- uninitializedOutputs.push_back({name, output});
- }
- return;
- }
-}
-void onGlobalRemove(void*, wl_registry* registry, uint32_t name)
-{
- monitors.remove_if([name](const Monitor &mon) { return mon.registryName == name; });
- seats.remove_if([name](const Seat &seat) { return seat.name == name; });
-}
-static const struct wl_registry_listener registry_listener = {
- .global = onGlobalAdd,
- .global_remove = onGlobalRemove,
-};
-
-int main(int argc, char* argv[])
-{
- int opt;
- while ((opt = getopt(argc, argv, "chvs:")) != -1) {
- switch (opt) {
- case 's':
- statusFifoName = optarg;
- break;
- case 'h':
- printf("Usage: %s [-h] [-v] [-s path to the fifo] [-c command]\n", argv[0]);
- printf(" -h: Show this help\n");
- printf(" -v: Show somebar version\n");
- printf(" -s: Change path to the fifo (default is \"$XDG_RUNTIME_DIR/somebar-0\")\n");
- printf(" -c: Sends a command to sombar. See README for details.\n");
- printf("If any of these are specified (except -s), somebar exits after the action.\n");
- printf("Otherwise, somebar will display itself.\n");
- exit(0);
- case 'v':
- printf("somebar " SOMEBAR_VERSION "\n");
- exit(0);
- case 'c':
- if (optind >= argc) {
- die("Expected command");
- }
- if (statusFifoName.empty()) {
- statusFifoName = std::string {getenv("XDG_RUNTIME_DIR")} + "/somebar-0";
- }
- statusFifoWriter = open(statusFifoName.c_str(), O_WRONLY | O_CLOEXEC);
- if (statusFifoWriter < 0) {
- fprintf(stderr, "could not open %s: ", statusFifoName.c_str());
- perror("");
- exit(1);
- }
- auto str = std::string {};
- for (auto i = optind; i<argc; i++) {
- if (i > optind) str += " ";
- str += argv[i];
- }
- str += "\n";
- write(statusFifoWriter, str.c_str(), str.size());
- exit(0);
- }
- }
-
- if (pipe(signalSelfPipe.data()) < 0) {
- diesys("pipe");
- }
- setCloexec(signalSelfPipe[0]);
- setCloexec(signalSelfPipe[1]);
-
- struct sigaction sighandler = {};
- sighandler.sa_handler = [](int) {
- if (write(signalSelfPipe[1], "0", 1) < 0) {
- diesys("write");
- }
- };
- if (sigaction(SIGTERM, &sighandler, nullptr) < 0) {
- diesys("sigaction");
- }
- if (sigaction(SIGINT, &sighandler, nullptr) < 0) {
- diesys("sigaction");
- }
-
- struct sigaction chld_handler = {};
- chld_handler.sa_handler = SIG_IGN;
- if (sigaction(SIGCHLD, &chld_handler, nullptr) < 0) {
- die("sigaction");
- }
-
- pollfds.push_back({
- .fd = signalSelfPipe[0],
- .events = POLLIN,
- });
-
- display = wl_display_connect(nullptr);
- if (!display) {
- die("Failed to connect to Wayland display");
- }
- displayFd = wl_display_get_fd(display);
-
- auto registry = wl_display_get_registry(display);
- wl_registry_add_listener(registry, &registry_listener, nullptr);
- wl_display_roundtrip(display);
- onReady();
-
- pollfds.push_back({
- .fd = displayFd,
- .events = POLLIN,
- });
- pollfds.push_back({
- .fd = STDIN_FILENO,
- .events = POLLIN,
- });
- if (fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK) < 0) {
- diesys("fcntl F_SETFL");
- }
-
- while (!quitting) {
- waylandFlush();
- if (poll(pollfds.data(), pollfds.size(), -1) < 0) {
- if (errno != EINTR) {
- diesys("poll");
- }
- } else {
- for (auto& ev : pollfds) {
- if (ev.revents & POLLNVAL) {
- die("poll revents contains POLLNVAL");
- } else if (ev.fd == displayFd) {
- if (ev.revents & POLLIN) {
- if (wl_display_dispatch(display) < 0) {
- die("wl_display_dispatch");
- }
- }
- if (ev.revents & POLLOUT) {
- ev.events = POLLIN;
- waylandFlush();
- }
- } else if (ev.fd == STDIN_FILENO && (ev.revents & POLLIN)) {
- onStdin();
- } else if (ev.fd == statusFifoFd && (ev.revents & POLLIN)) {
- onStatus();
- } else if (ev.fd == signalSelfPipe[0] && (ev.revents & POLLIN)) {
- quitting = true;
- }
- }
- }
- }
- cleanup();
-}
-
-void requireGlobal(const void* p, const char* name)
-{
- if (p) return;
- fprintf(stderr, "Wayland compositor does not export required global %s, aborting.\n", name);
- cleanup();
- exit(1);
-}
-
-void waylandFlush()
-{
- wl_display_dispatch_pending(display);
- if (wl_display_flush(display) < 0 && errno == EAGAIN) {
- for (auto& ev : pollfds) {
- if (ev.fd == displayFd) {
- ev.events |= POLLOUT;
- }
- }
- }
-}
-
-void setCloexec(int fd)
-{
- int flags = fcntl(fd, F_GETFD);
- if (flags == -1) {
- diesys("fcntl FD_GETFD");
- }
- if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) < 0) {
- diesys("fcntl FD_SETFD");
- }
-}
-
-void cleanup() {
- if (!statusFifoName.empty()) {
- unlink(statusFifoName.c_str());
- }
-}
-
-void die(const char* why) {
- fprintf(stderr, "error: %s failed, aborting\n", why);
- cleanup();
- exit(1);
-}
-
-void diesys(const char* why) {
- perror(why);
- cleanup();
- exit(1);
-}
diff --git a/somebar/src/shm_buffer.cpp b/somebar/src/shm_buffer.cpp
deleted file mode 100644
index 59baf6f..0000000
--- a/somebar/src/shm_buffer.cpp
+++ /dev/null
@@ -1,85 +0,0 @@
-// somebar - dwl bar
-// See LICENSE file for copyright and license details.
-
-#include <fcntl.h>
-#include <sys/mman.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include "shm_buffer.hpp"
-#include "common.hpp"
-
-static int createAnonShm();
-constexpr int n = 2;
-
-ShmBuffer::ShmBuffer(int w, int h, wl_shm_format format)
- : width(w)
- , height(h)
- , stride(w*4)
-{
- auto oneSize = stride*size_t(h);
- auto totalSize = oneSize * n;
- auto fd = createAnonShm();
- if (fd < 0) {
- diesys("memfd_create");
- }
- if (ftruncate(fd, totalSize) < 0) {
- diesys("ftruncate");
- }
- auto pool = wl_shm_create_pool(shm, fd, totalSize);
- auto ptr = reinterpret_cast<uint8_t*>(mmap(nullptr, totalSize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0));
- if (!ptr) {
- diesys("mmap");
- }
- _mapping = MemoryMapping {ptr, totalSize};
- close(fd);
- for (auto i=0; i<n; i++) {
- auto offset = oneSize*i;
- _buffers[i] = {
- ptr+offset,
- wl_unique_ptr<wl_buffer> { wl_shm_pool_create_buffer(pool, offset, width, height, stride, format) },
- };
- }
- wl_shm_pool_destroy(pool);
-}
-
-uint8_t* ShmBuffer::data()
-{
- return _buffers[_current].data;
-}
-
-wl_buffer* ShmBuffer::buffer()
-{
- return _buffers[_current].buffer.get();
-}
-
-void ShmBuffer::flip()
-{
- _current = 1-_current;
-}
-
-#if defined(__linux__)
-int createAnonShm() {
- return memfd_create("wl_shm", MFD_CLOEXEC);
-}
-#elif defined(__FreeBSD__)
-int createAnonShm() {
- auto fd = shm_open(SHM_ANON, O_CREAT | O_RDWR, 0600);
- setCloexec(fd);
- return fd;
-}
-#elif defined(__OpenBSD__)
-int createAnonShm() {
- char name[] = "/wl_shm-XXXXXX";
- auto fd = shm_mkstemp(name);
- if (fd >= 0) {
- auto res = shm_unlink(name);
- if (res < 0) {
- return res;
- }
- }
- setCloexec(fd);
- return fd;
-}
-#else
-#error "your system has no sane method of creating an anonymous shared memory object. no, calling shm_open in a loop is not sane."
-#endif
diff --git a/somebar/src/shm_buffer.hpp b/somebar/src/shm_buffer.hpp
deleted file mode 100644
index f6927dd..0000000
--- a/somebar/src/shm_buffer.hpp
+++ /dev/null
@@ -1,45 +0,0 @@
-// somebar - dwl bar
-// See LICENSE file for copyright and license details.
-
-#pragma once
-#include <array>
-#include <sys/mman.h>
-#include <wayland-client.h>
-#include "common.hpp"
-
-class MemoryMapping {
- void* _ptr {nullptr};
- size_t _size {0};
-public:
- MemoryMapping() { }
- explicit MemoryMapping(void* ptr, size_t size) : _ptr(ptr), _size(size) { }
- MemoryMapping(const MemoryMapping&) = delete;
- MemoryMapping(MemoryMapping&& other) { swap(other); }
- MemoryMapping& operator=(const MemoryMapping& other) = delete;
- MemoryMapping& operator=(MemoryMapping&& other) { swap(other); return *this; }
- ~MemoryMapping() { if (_ptr) munmap(_ptr, _size); }
- void swap(MemoryMapping &other) {
- using std::swap;
- swap(_ptr, other._ptr);
- swap(_size, other._size);
- }
-};
-
-// double buffered shm
-// format is must be 32-bit
-class ShmBuffer {
- struct Buf {
- uint8_t* data {nullptr};
- wl_unique_ptr<wl_buffer> buffer;
- };
- std::array<Buf, 2> _buffers;
- int _current {0};
- MemoryMapping _mapping;
-public:
- const uint32_t width, height, stride;
-
- explicit ShmBuffer(int width, int height, wl_shm_format format);
- uint8_t* data();
- wl_buffer* buffer();
- void flip();
-};
diff --git a/st-0.8.4/FAQ b/st-0.8.4/FAQ
deleted file mode 100644
index 0f9609d..0000000
--- a/st-0.8.4/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/st-0.8.4/LEGACY b/st-0.8.4/LEGACY
deleted file mode 100644
index bf28b1e..0000000
--- a/st-0.8.4/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/st-0.8.4/LICENSE b/st-0.8.4/LICENSE
deleted file mode 100644
index d80eb47..0000000
--- a/st-0.8.4/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/st-0.8.4/Makefile b/st-0.8.4/Makefile
deleted file mode 100644
index 470ac86..0000000
--- a/st-0.8.4/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/st-0.8.4/README b/st-0.8.4/README
deleted file mode 100644
index 6a846ed..0000000
--- a/st-0.8.4/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/st-0.8.4/TODO b/st-0.8.4/TODO
deleted file mode 100644
index 5f74cd5..0000000
--- a/st-0.8.4/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/st-0.8.4/arg.h b/st-0.8.4/arg.h
deleted file mode 100644
index a22e019..0000000
--- a/st-0.8.4/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/st-0.8.4/config.def.h b/st-0.8.4/config.def.h
deleted file mode 100644
index 851684c..0000000
--- a/st-0.8.4/config.def.h
+++ /dev/null
@@ -1,477 +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 */
- [0] = "#282828", /* hard contrast: #1d2021 / soft contrast: #32302f */
- [1] = "#cc241d", /* red */
- [2] = "#98971a", /* green */
- [3] = "#d79921", /* yellow */
- [4] = "#458588", /* blue */
- [5] = "#b16286", /* magenta */
- [6] = "#689d6a", /* cyan */
- [7] = "#a89984", /* white */
-
- /* 8 bright colors */
- [8] = "#928374", /* black */
- [9] = "#fb4934", /* red */
- [10] = "#b8bb26", /* green */
- [11] = "#fabd2f", /* yellow */
- [12] = "#83a598", /* blue */
- [13] = "#d3869b", /* magenta */
- [14] = "#8ec07c", /* cyan */
- [15] = "#ebdbb2", /* white */
-};
-
-/*
- * Default colors (colorname index)
- * foreground, background, cursor
- */
-unsigned int defaultfg = 15;
-unsigned int defaultbg = 0;
-static unsigned int defaultcs = 15;
-static unsigned int defaultrcs = 257;
-
-/*
- * https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h4-Functions-using-CSI-_-ordered-by-the-final-character-lparen-s-rparen:CSI-Ps-SP-q.1D81
- * Default style of cursor
- * 0: Blinking block
- * 1: Blinking block (default)
- * 2: Steady block ("█")
- * 3: Blinking underline
- * 4: Steady underline ("_")
- * 5: Blinking bar
- * 6: Steady bar ("|")
- * 7: Blinking st cursor
- * 8: Steady st cursor
- */
-static unsigned int cursorstyle = 1;
-static Rune stcursor = 0x2603; /* snowman (U+2603) */
-
-/*
- * 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, Button4, kscrollup, {.i = 1}, 0, /* !alt */ -1 },
- { XK_ANY_MOD, Button5, kscrolldown, {.i = 1}, 0, /* !alt */ -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"} },
-};
-
-/* 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} },
- { ShiftMask, XK_Page_Up, kscrollup, {.i = -1} },
- { ShiftMask, XK_Page_Down, kscrolldown, {.i = -1} },
-};
-
-/*
- * 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/st-0.8.4/config.def.h.orig b/st-0.8.4/config.def.h.orig
deleted file mode 100644
index 2b5ea87..0000000
--- a/st-0.8.4/config.def.h.orig
+++ /dev/null
@@ -1,470 +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 */
- [0] = "#282828", /* hard contrast: #1d2021 / soft contrast: #32302f */
- [1] = "#cc241d", /* red */
- [2] = "#98971a", /* green */
- [3] = "#d79921", /* yellow */
- [4] = "#458588", /* blue */
- [5] = "#b16286", /* magenta */
- [6] = "#689d6a", /* cyan */
- [7] = "#a89984", /* white */
-
- /* 8 bright colors */
- [8] = "#928374", /* black */
- [9] = "#fb4934", /* red */
- [10] = "#b8bb26", /* green */
- [11] = "#fabd2f", /* yellow */
- [12] = "#83a598", /* blue */
- [13] = "#d3869b", /* magenta */
- [14] = "#8ec07c", /* cyan */
- [15] = "#ebdbb2", /* white */
-};
-
-/*
- * Default colors (colorname index)
- * foreground, background, cursor
- */
-unsigned int defaultfg = 15;
-unsigned int defaultbg = 0;
-static unsigned int defaultcs = 15;
-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, Button4, kscrollup, {.i = 1}, 0, /* !alt */ -1 },
- { XK_ANY_MOD, Button5, kscrolldown, {.i = 1}, 0, /* !alt */ -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"} },
-};
-
-/* 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} },
- { ShiftMask, XK_Page_Up, kscrollup, {.i = -1} },
- { ShiftMask, XK_Page_Down, kscrolldown, {.i = -1} },
-};
-
-/*
- * 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/st-0.8.4/config.h b/st-0.8.4/config.h
deleted file mode 100644
index d08e089..0000000
--- a/st-0.8.4/config.h
+++ /dev/null
@@ -1,479 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-
-/*
- * appearance
- *
- * font: see http://freedesktop.org/software/fontconfig/fontconfig-user.html
- */
-static char *font = "Sudo:size=16: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[] = {
- "#3b4252", /* black */
- "#bf616a", /* red */
- "#a3be8c", /* green */
- "#ebcb8b", /* yellow */
- "#81a1c1", /* blue */
- "#b48ead", /* magenta */
- "#88c0d0", /* cyan */
- "#e5e9f0", /* white */
- /* 8 bright colors */
- "#4c566a", /* black */
- "#bf616a", /* red */
- "#a3be8c", /* green */
- "#ebcb8b", /* yellow */
- "#81a1c1", /* blue */
- "#b48ead", /* magenta */
- "#8fbcbb", /* cyan */
- "#eceff4", /* white */
- [255] = 0,
- /* more colors can be added after 255 to use with DefaultXX */
- "#2e3440", /* background */
- "#d8dee9", /* foreground */
-};
-
-/*
- * Default colors (colorname index)
- * foreground, background, cursor
- */
-unsigned int defaultfg = 257;
-unsigned int defaultbg = 256;
-static unsigned int defaultcs = 257;
-static unsigned int defaultrcs = 256;
-
-/*
- * https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h4-Functions-using-CSI-_-ordered-by-the-final-character-lparen-s-rparen:CSI-Ps-SP-q.1D81
- * Default style of cursor
- * 0: Blinking block
- * 1: Blinking block (default)
- * 2: Steady block ("█")
- * 3: Blinking underline
- * 4: Steady underline ("_")
- * 5: Blinking bar
- * 6: Steady bar ("|")
- * 7: Blinking st cursor
- * 8: Steady st cursor
- */
-static unsigned int cursorshape = 2;
-static unsigned int cursorstyle = 1;
-static Rune stcursor = 0x2603;
-
-/*
- * 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, Button4, kscrollup, {.i = 1}, 0, /* !alt */ -1 },
- { XK_ANY_MOD, Button5, kscrolldown, {.i = 1}, 0, /* !alt */ -1 },
- { XK_ANY_MOD, Button2, clippaste, {.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, clippaste, {.i = 0} },
- { ShiftMask, XK_Insert, clippaste, {.i = 0} },
- { TERMMOD, XK_Num_Lock, numlock, {.i = 0} },
- { ShiftMask, XK_Page_Up, kscrollup, {.i = -1} },
- { ShiftMask, XK_Page_Down, kscrolldown, {.i = -1} },
-};
-
-/*
- * 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/st-0.8.4/config.mk b/st-0.8.4/config.mk
deleted file mode 100644
index c070a4a..0000000
--- a/st-0.8.4/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/st-0.8.4/st-blinking_cursor-20200531-a2a7044.diff b/st-0.8.4/st-blinking_cursor-20200531-a2a7044.diff
deleted file mode 100644
index d544f74..0000000
--- a/st-0.8.4/st-blinking_cursor-20200531-a2a7044.diff
+++ /dev/null
@@ -1,150 +0,0 @@
-From bff176133618854676bbdc74c0099f184d3da365 Mon Sep 17 00:00:00 2001
-From: Steve Ward <planet36@gmail.com>
-Date: Sun, 31 May 2020 22:48:25 -0400
-Subject: [PATCH] Allow blinking cursor
-
----
- config.def.h | 19 +++++++++++++------
- x.c | 42 ++++++++++++++++++++++++++++++++----------
- 2 files changed, 45 insertions(+), 16 deletions(-)
-
-diff --git a/config.def.h b/config.def.h
-index 6f05dce..3dbe915 100644
---- a/config.def.h
-+++ b/config.def.h
-@@ -133,13 +133,20 @@ static unsigned int defaultcs = 256;
- static unsigned int defaultrcs = 257;
-
- /*
-- * Default shape of cursor
-- * 2: Block ("█")
-- * 4: Underline ("_")
-- * 6: Bar ("|")
-- * 7: Snowman ("☃")
-+ * https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h4-Functions-using-CSI-_-ordered-by-the-final-character-lparen-s-rparen:CSI-Ps-SP-q.1D81
-+ * Default style of cursor
-+ * 0: Blinking block
-+ * 1: Blinking block (default)
-+ * 2: Steady block ("█")
-+ * 3: Blinking underline
-+ * 4: Steady underline ("_")
-+ * 5: Blinking bar
-+ * 6: Steady bar ("|")
-+ * 7: Blinking st cursor
-+ * 8: Steady st cursor
- */
--static unsigned int cursorshape = 2;
-+static unsigned int cursorstyle = 1;
-+static Rune stcursor = 0x2603; /* snowman (U+2603) */
-
- /*
- * Default columns and rows numbers
-diff --git a/x.c b/x.c
-index 210f184..bd80a5e 100644
---- a/x.c
-+++ b/x.c
-@@ -253,6 +253,7 @@ static char *opt_name = NULL;
- static char *opt_title = NULL;
-
- static int oldbutton = 3; /* button event on startup: 3 = release */
-+static int cursorblinks = 0;
-
- void
- clipcopy(const Arg *dummy)
-@@ -1526,16 +1527,19 @@ xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og)
- /* draw the new one */
- if (IS_SET(MODE_FOCUSED)) {
- switch (win.cursor) {
-- case 7: /* st extension */
-- g.u = 0x2603; /* snowman (U+2603) */
-+ case 0: /* Blinking block */
-+ case 1: /* Blinking block (default) */
-+ if (IS_SET(MODE_BLINK))
-+ break;
- /* FALLTHROUGH */
-- case 0: /* Blinking Block */
-- case 1: /* Blinking Block (Default) */
-- case 2: /* Steady Block */
-+ case 2: /* Steady block */
- xdrawglyph(g, cx, cy);
- break;
-- case 3: /* Blinking Underline */
-- case 4: /* Steady Underline */
-+ case 3: /* Blinking underline */
-+ if (IS_SET(MODE_BLINK))
-+ break;
-+ /* FALLTHROUGH */
-+ case 4: /* Steady underline */
- XftDrawRect(xw.draw, &drawcol,
- borderpx + cx * win.cw,
- borderpx + (cy + 1) * win.ch - \
-@@ -1543,12 +1547,23 @@ xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og)
- win.cw, cursorthickness);
- break;
- case 5: /* Blinking bar */
-+ if (IS_SET(MODE_BLINK))
-+ break;
-+ /* FALLTHROUGH */
- case 6: /* Steady bar */
- XftDrawRect(xw.draw, &drawcol,
- borderpx + cx * win.cw,
- borderpx + cy * win.ch,
- cursorthickness, win.ch);
- break;
-+ case 7: /* Blinking st cursor */
-+ if (IS_SET(MODE_BLINK))
-+ break;
-+ /* FALLTHROUGH */
-+ case 8: /* Steady st cursor */
-+ g.u = stcursor;
-+ xdrawglyph(g, cx, cy);
-+ break;
- }
- } else {
- XftDrawRect(xw.draw, &drawcol,
-@@ -1690,9 +1705,12 @@ xsetmode(int set, unsigned int flags)
- int
- xsetcursor(int cursor)
- {
-- if (!BETWEEN(cursor, 0, 7)) /* 7: st extension */
-+ if (!BETWEEN(cursor, 0, 8)) /* 7-8: st extensions */
- return 1;
- win.cursor = cursor;
-+ cursorblinks = win.cursor == 0 || win.cursor == 1 ||
-+ win.cursor == 3 || win.cursor == 5 ||
-+ win.cursor == 7;
- return 0;
- }
-
-@@ -1936,6 +1954,10 @@ run(void)
- if (FD_ISSET(ttyfd, &rfd) || xev) {
- if (!drawing) {
- trigger = now;
-+ if (IS_SET(MODE_BLINK)) {
-+ win.mode ^= MODE_BLINK;
-+ }
-+ lastblink = now;
- drawing = 1;
- }
- timeout = (maxlatency - TIMEDIFF(now, trigger)) \
-@@ -1946,7 +1968,7 @@ run(void)
-
- /* idle detected or maxlatency exhausted -> draw */
- timeout = -1;
-- if (blinktimeout && tattrset(ATTR_BLINK)) {
-+ if (blinktimeout && (cursorblinks || tattrset(ATTR_BLINK))) {
- timeout = blinktimeout - TIMEDIFF(now, lastblink);
- if (timeout <= 0) {
- if (-timeout > blinktimeout) /* start visible */
-@@ -1982,7 +2004,7 @@ main(int argc, char *argv[])
- {
- xw.l = xw.t = 0;
- xw.isfixed = False;
-- xsetcursor(cursorshape);
-+ xsetcursor(cursorstyle);
-
- ARGBEGIN {
- case 'a':
---
-2.20.1
-
diff --git a/st-0.8.4/st-clipboard-0.8.3.diff b/st-0.8.4/st-clipboard-0.8.3.diff
deleted file mode 100644
index c1e0e9e..0000000
--- a/st-0.8.4/st-clipboard-0.8.3.diff
+++ /dev/null
@@ -1,12 +0,0 @@
-diff --git a/x.c b/x.c
-index e5f1737..5cabd60 100644
---- a/x.c
-+++ b/x.c
-@@ -673,6 +673,7 @@ setsel(char *str, Time t)
- XSetSelectionOwner(xw.dpy, XA_PRIMARY, xw.win, t);
- if (XGetSelectionOwner(xw.dpy, XA_PRIMARY) != xw.win)
- selclear();
-+ clipcopy(NULL);
- }
-
- void
diff --git a/st-0.8.4/st-gruvbox-dark-0.8.2.diff b/st-0.8.4/st-gruvbox-dark-0.8.2.diff
deleted file mode 100644
index c8390f0..0000000
--- a/st-0.8.4/st-gruvbox-dark-0.8.2.diff
+++ /dev/null
@@ -1,70 +0,0 @@
-diff --git a/config.def.h b/config.def.h
-index 877afab..6a1699f 100644
---- a/config.def.h
-+++ b/config.def.h
-@@ -84,41 +84,35 @@ static 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",
--};
-
-+ /* 8 normal colors */
-+ [0] = "#282828", /* hard contrast: #1d2021 / soft contrast: #32302f */
-+ [1] = "#cc241d", /* red */
-+ [2] = "#98971a", /* green */
-+ [3] = "#d79921", /* yellow */
-+ [4] = "#458588", /* blue */
-+ [5] = "#b16286", /* magenta */
-+ [6] = "#689d6a", /* cyan */
-+ [7] = "#a89984", /* white */
-+
-+ /* 8 bright colors */
-+ [8] = "#928374", /* black */
-+ [9] = "#fb4934", /* red */
-+ [10] = "#b8bb26", /* green */
-+ [11] = "#fabd2f", /* yellow */
-+ [12] = "#83a598", /* blue */
-+ [13] = "#d3869b", /* magenta */
-+ [14] = "#8ec07c", /* cyan */
-+ [15] = "#ebdbb2", /* white */
-+};
-
- /*
- * Default colors (colorname index)
-- * foreground, background, cursor, reverse cursor
-+ * foreground, background, cursor
- */
--unsigned int defaultfg = 7;
--unsigned int defaultbg = 0;
--static unsigned int defaultcs = 256;
-+unsigned int defaultfg = 15;
-+unsigned int defaultbg = 0;
-+static unsigned int defaultcs = 15;
- static unsigned int defaultrcs = 257;
-
- /*
diff --git a/st-0.8.4/st-scrollback-20200419-72e3f6c.diff b/st-0.8.4/st-scrollback-20200419-72e3f6c.diff
deleted file mode 100644
index e72999c..0000000
--- a/st-0.8.4/st-scrollback-20200419-72e3f6c.diff
+++ /dev/null
@@ -1,351 +0,0 @@
-diff --git a/config.def.h b/config.def.h
-index 0895a1f..eef24df 100644
---- a/config.def.h
-+++ b/config.def.h
-@@ -188,6 +188,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 0ce6ac2..641edc0 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,
-@@ -117,6 +121,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 */
-@@ -185,8 +192,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(int *, int);
- static void tsetchar(Rune, Glyph *, int, int);
- static void tsetdirt(int, int);
-@@ -415,10 +422,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;
-@@ -527,7 +534,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;
-@@ -542,14 +549,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)))
-@@ -570,14 +577,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;
- }
-@@ -608,13 +615,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;
-
-@@ -849,6 +856,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);
-@@ -1060,13 +1070,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);
-
-@@ -1076,17 +1126,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);
-
-@@ -1096,7 +1157,8 @@ tscrollup(int orig, int n)
- term.line[i+n] = temp;
- }
-
-- selscroll(orig, -n);
-+ if (term.scr == 0)
-+ selscroll(orig, -n);
- }
-
- void
-@@ -1135,7 +1197,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++;
- }
-@@ -1300,14 +1362,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
-@@ -1738,11 +1800,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);
-@@ -2248,7 +2310,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);
- }
-@@ -2261,7 +2323,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);
- }
-@@ -2482,7 +2544,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;
-@@ -2519,6 +2581,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));
-@@ -2577,7 +2647,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);
- }
- }
-
-@@ -2598,8 +2668,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 d978458..b9a4eeb 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/st-0.8.4/st-scrollback-mouse-20191024-a2c479c.diff b/st-0.8.4/st-scrollback-mouse-20191024-a2c479c.diff
deleted file mode 100644
index 49eba8e..0000000
--- a/st-0.8.4/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/st-0.8.4/st-scrollback-mouse-altscreen-20200416-5703aa0.diff b/st-0.8.4/st-scrollback-mouse-altscreen-20200416-5703aa0.diff
deleted file mode 100644
index fbade29..0000000
--- a/st-0.8.4/st-scrollback-mouse-altscreen-20200416-5703aa0.diff
+++ /dev/null
@@ -1,63 +0,0 @@
-diff --git a/config.def.h b/config.def.h
-index 4b3bf15..1986316 100644
---- a/config.def.h
-+++ b/config.def.h
-@@ -163,8 +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, Button4, kscrollup, {.i = 1}, 0, /* !alt */ -1 },
-+ { XK_ANY_MOD, Button5, kscrolldown, {.i = 1}, 0, /* !alt */ -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/st.c b/st.c
-index f8b6f67..dd4cb31 100644
---- st.c
-+++ st.c
-@@ -1045,6 +1045,11 @@ tnew(int col, int row)
- treset();
- }
-
-+int tisaltscr(void)
-+{
-+ return IS_SET(MODE_ALTSCREEN);
-+}
-+
- void
- tswapscreen(void)
- {
-diff --git a/st.h b/st.h
-index 1332cf1..f9ad815 100644
---- st.h
-+++ st.h
-@@ -89,6 +89,7 @@ void sendbreak(const Arg *);
- void toggleprinter(const Arg *);
-
- int tattrset(int);
-+int tisaltscr(void);
- void tnew(int, int);
- void tresize(int, int);
- void tsetdirtattr(int);
-diff --git a/x.c b/x.c
-index e5f1737..b8fbd7b 100644
---- x.c
-+++ x.c
-@@ -34,6 +34,7 @@ typedef struct {
- void (*func)(const Arg *);
- const Arg arg;
- uint release;
-+ int altscrn; /* 0: don't care, -1: not alt screen, 1: alt screen */
- } MouseShortcut;
-
- typedef struct {
-@@ -446,6 +447,7 @@ mouseaction(XEvent *e, uint release)
- for (ms = mshortcuts; ms < mshortcuts + LEN(mshortcuts); ms++) {
- if (ms->release == release &&
- ms->button == e->xbutton.button &&
-+ (!ms->altscrn || (ms->altscrn == (tisaltscr() ? 1 : -1))) &&
- (match(ms->mod, state) || /* exact or forced */
- match(ms->mod, state & ~forcemousemod))) {
- ms->func(&(ms->arg));
diff --git a/st-0.8.4/st.1 b/st-0.8.4/st.1
deleted file mode 100644
index 39120b4..0000000
--- a/st-0.8.4/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/st-0.8.4/st.c b/st-0.8.4/st.c
deleted file mode 100644
index 166f037..0000000
--- a/st-0.8.4/st.c
+++ /dev/null
@@ -1,2673 +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(int *, int);
-static void tsetchar(Rune, Glyph *, int, int);
-static void tsetdirt(int, int);
-static void tsetscroll(int, int);
-static void tswapscreen(void);
-static void tsetmode(int, int, 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(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 uchar utfbyte[UTF_SIZ + 1] = {0x80, 0, 0xC0, 0xE0, 0xF0};
-static uchar utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8};
-static Rune utfmin[UTF_SIZ + 1] = { 0, 0, 0x80, 0x800, 0x10000};
-static 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(char *s)
-{
- if ((s = strdup(s)) == NULL)
- die("strdup: %s\n", strerror(errno));
-
- return s;
-}
-
-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;
- 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;
- 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(char *line, char *cmd, 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);
- 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));
- close(s);
- close(m);
-#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();
-}
-
-int tisaltscr(void)
-{
- return IS_SET(MODE_ALTSCREEN);
-}
-
-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, Glyph *attr, int x, int y)
-{
- static 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(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(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, int *args, int narg)
-{
- int alt, *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:
- case 1:
- 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];
- 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/st-0.8.4/st.c.orig b/st-0.8.4/st.c.orig
deleted file mode 100644
index edec064..0000000
--- a/st-0.8.4/st.c.orig
+++ /dev/null
@@ -1,2668 +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(int *, int);
-static void tsetchar(Rune, Glyph *, int, int);
-static void tsetdirt(int, int);
-static void tsetscroll(int, int);
-static void tswapscreen(void);
-static void tsetmode(int, int, 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(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 uchar utfbyte[UTF_SIZ + 1] = {0x80, 0, 0xC0, 0xE0, 0xF0};
-static uchar utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8};
-static Rune utfmin[UTF_SIZ + 1] = { 0, 0, 0x80, 0x800, 0x10000};
-static 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(char *s)
-{
- if ((s = strdup(s)) == NULL)
- die("strdup: %s\n", strerror(errno));
-
- return s;
-}
-
-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;
- 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;
- 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(char *line, char *cmd, 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);
- 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));
- close(s);
- close(m);
-#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, Glyph *attr, int x, int y)
-{
- static 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(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(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, int *args, int narg)
-{
- int alt, *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:
- case 1:
- 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];
- 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/st-0.8.4/st.h b/st-0.8.4/st.h
deleted file mode 100644
index 36cdb65..0000000
--- a/st-0.8.4/st.h
+++ /dev/null
@@ -1,128 +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);
-int tisaltscr(void);
-void tnew(int, int);
-void tresize(int, int);
-void tsetdirtattr(int);
-void ttyhangup(void);
-int ttynew(char *, char *, 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(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/st-0.8.4/st.info b/st-0.8.4/st.info
deleted file mode 100644
index 8201ad6..0000000
--- a/st-0.8.4/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/st-0.8.4/win.h b/st-0.8.4/win.h
deleted file mode 100644
index a6ef1b9..0000000
--- a/st-0.8.4/win.h
+++ /dev/null
@@ -1,39 +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 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/st-0.8.4/x.c b/st-0.8.4/x.c
deleted file mode 100644
index b0fcbea..0000000
--- a/st-0.8.4/x.c
+++ /dev/null
@@ -1,2074 +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;
- int altscrn; /* 0: don't care, -1: not alt screen, 1: alt screen */
-} 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)
-
-/* 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, 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(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 */
-static int cursorblinks = 0;
-
-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 >= 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 &&
- (!ms->altscrn || (ms->altscrn == (tisaltscr() ? 1 : -1))) &&
- (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();
- clipcopy(NULL);
-}
-
-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(char *fontstr, double fontsize)
-{
- FcPattern *pattern;
- double fontval;
-
- if (fontstr[0] == '-')
- pattern = XftXlfdParse(fontstr, False, False);
- else
- pattern = FcNameParse((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);
- 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 0: /* Blinking block */
- case 1: /* Blinking block (default) */
- if (IS_SET(MODE_BLINK))
- break;
- /* FALLTHROUGH */
- case 2: /* Steady block */
- xdrawglyph(g, cx, cy);
- break;
- case 3: /* Blinking underline */
- if (IS_SET(MODE_BLINK))
- break;
- /* FALLTHROUGH */
- 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 */
- if (IS_SET(MODE_BLINK))
- break;
- /* FALLTHROUGH */
- case 6: /* Steady bar */
- XftDrawRect(xw.draw, &drawcol,
- borderpx + cx * win.cw,
- borderpx + cy * win.ch,
- cursorthickness, win.ch);
- break;
- case 7: /* Blinking st cursor */
- if (IS_SET(MODE_BLINK))
- break;
- /* FALLTHROUGH */
- case 8: /* Steady st cursor */
- g.u = stcursor;
- xdrawglyph(g, cx, cy);
- 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
-xsettitle(char *p)
-{
- XTextProperty prop;
- DEFAULT(p, opt_title);
-
- Xutf8TextListToTextProperty(xw.dpy, &p, 1, XUTF8StringStyle,
- &prop);
- 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, 8)) /* 7-8: st extensions */
- return 1;
- win.cursor = cursor;
- cursorblinks = win.cursor == 0 || win.cursor == 1 ||
- win.cursor == 3 || win.cursor == 5 ||
- win.cursor == 7;
- 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;
- if (IS_SET(MODE_BLINK)) {
- win.mode ^= MODE_BLINK;
- }
- lastblink = 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 && (cursorblinks || 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(cursorstyle);
-
- 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/st-0.8.4/x.c.orig b/st-0.8.4/x.c.orig
deleted file mode 100644
index d8e698a..0000000
--- a/st-0.8.4/x.c.orig
+++ /dev/null
@@ -1,2052 +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;
- int altscrn; /* 0: don't care, -1: not alt screen, 1: alt screen */
-} 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)
-
-/* 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, 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(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 >= 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 &&
- (!ms->altscrn || (ms->altscrn == (tisaltscr() ? 1 : -1))) &&
- (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();
- clipcopy(NULL);
-}
-
-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(char *fontstr, double fontsize)
-{
- FcPattern *pattern;
- double fontval;
-
- if (fontstr[0] == '-')
- pattern = XftXlfdParse(fontstr, False, False);
- else
- pattern = FcNameParse((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);
- 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
-xsettitle(char *p)
-{
- XTextProperty prop;
- DEFAULT(p, opt_title);
-
- Xutf8TextListToTextProperty(xw.dpy, &p, 1, XUTF8StringStyle,
- &prop);
- 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/stumpwm/init.lisp b/stumpwm/init.lisp
deleted file mode 100644
index 3436f06..0000000
--- a/stumpwm/init.lisp
+++ /dev/null
@@ -1,236 +0,0 @@
-;; Time-stamp: <2018-06-24 23:12:19 (tslil)>
-(IN-PACKAGE STUMPWM)
-
-;; Startup stuff
-(SETF *STARTUP-MESSAGE* NIL)
-(RUN-COMMANDS "exec $TERMINAL -e $HOME/bin/tma")
-(SET-PREFIX-KEY (KBD "XF86Launch9"))
-
-;; Window decorations
-(SETF *MESSAGE-WINDOW-GRAVITY* :CENTER
- *INPUT-WINDOW-GRAVITY* :CENTER)
-(SETF *TIMEOUT-WAIT* 5)
-(SETF *MAXSIZE-BORDER-WIDTH* 1)
-(SETF *NORMAL-BORDER-WIDTH* 1)
-(SETF *TRANSIENT-BORDER-WIDTH* 1)
-(SETF *WINDOW-BORDER-STYLE* :THIN)
-(SET-FRAME-OUTLINE-WIDTH 1)
-(SET-MSG-BORDER-WIDTH 3)
-
-;; Groups
-(GRENAME "def")
-(GNEWBG "one")
-(GNEWBG "two")
-
-(SETF *FRAME-NUMBER-MAP* "neioarst123456789"
- *FRAME-INDICATOR-TEXT* " This frame has focus. ")
-
-;; =============================================================================
-;; Functions
-;; Dropwhile
-(DEFUN DROPWHILE (PREDICATE LIST)
- (LOOP :WHILE (FUNCALL PREDICATE (CAR LIST))
- :DO (POP LIST))
- LIST)
-
-;; Notifications
-(DEFUN MY-MESSAGE (LOCATION STRING)
- (LET ((OLD-LOCATION *message-window-gravity*))
- (SETF *message-window-gravity* LOCATION)
- (ECHO STRING)
- (SETF *message-window-gravity* OLD-LOCATION)))
-
-;; Volume
-(DEFUN VOLUME-MODIFY (MIXER ACTION)
- (LET* ((OUTPUT (RUN-PROG-COLLECT-OUTPUT "/usr/bin/amixer" "set"
- MIXER
- (CASE ACTION
- (:INC "2%+")
- (:DEC "2%-")
- (:MUT "toggle"))))
- (PARSED (DROPWHILE #'(LAMBDA (F)
- (NOT (EQ #\: (CHAR F (1- (LENGTH F))))))
- (SPLIT-STRING (CAR (LAST (SPLIT-STRING
- OUTPUT))) "[ \[]+"))))
- (MY-MESSAGE :TOP-RIGHT
- (FORMAT NIL "~A: ~A [~A]"
- MIXER (NTH 3 PARSED) (NTH 5 PARSED)))))
-
-(DEFUN MAIL-INFO ()
- (LET ((NUM (PARSE-INTEGER
- (RUN-PROG-COLLECT-OUTPUT "/usr/bin/notmuch" "count" "tag:unread"))))
- (IF (>= 0 NUM) "^7no unread emails^n"
- (FORMAT NIL "~r^7 unread ~[email~:;emails~]^n" NUM (1- NUM)))))
-
-(DEFUN BATTERY-INFO ()
- (LET* ((RAW (RUN-PROG-COLLECT-OUTPUT "/usr/bin/acpi"))
- (BAT0 (FIRST (SPLIT-STRING RAW)))
- (PARSED (CDR (DROPWHILE #'(LAMBDA (F) (NOT (EQ #\: (CHAR F (1- (LENGTH F))))))
- (SPLIT-STRING BAT0 "[ ,]+"))))
- (STAT (NTH 0 PARSED))
- (PERC (NTH 1 PARSED))
- (PNUM (PARSE-INTEGER (SUBSEQ PERC 0 (1- (LENGTH PERC)))))
- (TIME (NTH 2 PARSED)))
- (FORMAT NIL "~[^1~;^3~:;^2~]~c ~d%, ~a"
- (FLOOR (* 4 (/ PNUM 100)))
- (CHAR STAT 0)
- PNUM
- (OR TIME "not charging"))))
-
-
-;; =============================================================================
-;; Commands
-
-;; Volume
-(DEFCOMMAND VOLUME-INC (MIXER) (:REST) (volume-modify MIXER :INC))
-(DEFCOMMAND VOLUME-DEC (MIXER) (:REST) (volume-modify MIXER :DEC))
-(DEFCOMMAND VOLUME-MUT (MIXER) (:REST) (volume-modify MIXER :MUT))
-
-;; Switch to stuff
-(DEFCOMMAND SELECT-GROUP-FROM-LIST () (:REST)
- ;; lifted from group.lisp source because there weren't any nice
- ;; wrappers like in the case of windows (below)
- (LET* ((GROUPS (SORT-GROUPS (CURRENT-SCREEN)))
- (NAMES (MAPCAR (LAMBDA (G)
- `(,(FORMAT-EXPAND *GROUP-FORMATTERS* "%t" G)
- . ,G))
- (IF *LIST-HIDDEN-GROUPS*
- GROUPS (NON-HIDDEN-GROUPS GROUPS))))
- (CHOICE (CDR (SELECT-FROM-MENU (CURRENT-SCREEN) NAMES
- "Switch to which group?"))))
- (WHEN CHOICE (SWITCH-TO-GROUP CHOICE))))
-
-(DEFCOMMAND MY-PULL-FROM-WINDOWLIST () (:REST) ; I wanted a prompt...
- (LET ((CHOICE (SELECT-WINDOW-FROM-MENU (ALL-WINDOWS) "%n %t"
- "Pull which window to this frame?")))
- (WHEN CHOICE (PULL-WINDOW CHOICE))))
-
-;; Email
-(DEFCOMMAND CHECK-NEW-MAIL () (:REST)
- (MY-MESSAGE :CENTER (MAIL-INFO)))
-;; Battery
-(DEFCOMMAND BATTERY-STATS () (:REST)
- (MY-MESSAGE :CENTER (BATTERY-INFO)))
-
-;; =============================================================================
-;; Bindings
-
-;; Free stuff -- where are all these other keys being bound?
-(setf *root-map* (make-sparse-keymap))
-
-;; Volume
-(DEFINE-KEY *TOP-MAP* (KBD "XF86AudioRaiseVolume") "volume-inc Master")
-(DEFINE-KEY *TOP-MAP* (KBD "XF86AudioLowerVolume") "volume-dec Master")
-(DEFINE-KEY *TOP-MAP* (KBD "XF86Launch1") "volume-mut Master")
-(DEFINE-KEY *TOP-MAP* (KBD "S-XF86AudioRaiseVolume") "volume-inc Headphone")
-(DEFINE-KEY *TOP-MAP* (KBD "S-XF86AudioLowerVolume") "volume-dec Headphone")
-(DEFINE-KEY *TOP-MAP* (KBD "S-XF86Launch1") "volume-mut Headphone")
-
-;; Misc
-(DEFINE-KEY *TOP-MAP* (KBD "XF86ScreenSaver") "exec lock")
-(DEFINE-KEY *TOP-MAP* (KBD "XF86Battery") "battery-stats")
-(DEFINE-KEY *TOP-MAP* (KBD "XF86WebCam") "check-new-mail")
-(DEFINE-KEY *TOP-MAP* (KBD "XF86MonBrightnessUp") "exec xbacklight -inc 10")
-(DEFINE-KEY *TOP-MAP* (KBD "XF86MonBrightnessDown") "exec xbacklight -dec 10")
-
-;; =============================================================================
-;; Root bindings
-(DEFINE-KEY *ROOT-MAP* (KBD "C-Q") "quit")
-(DEFINE-KEY *ROOT-MAP* (KBD "C-g") "abort")
-
-(DEFINE-KEY *ROOT-MAP* (KBD "g") "gmove")
-(DEFINE-KEY *ROOT-MAP* (KBD "G") "gmerge")
-(DEFINE-KEY *ROOT-MAP* (KBD "TAB") "select-group-from-list")
-(DEFINE-KEY *ROOT-MAP* (KBD "l") "gselect def")
-(DEFINE-KEY *ROOT-MAP* (KBD "u") "gselect one")
-(DEFINE-KEY *ROOT-MAP* (KBD "y") "gselect two")
-(DEFINE-KEY *ROOT-MAP* (KBD "M-l") "gmove def")
-(DEFINE-KEY *ROOT-MAP* (KBD "M-u") "gmove one")
-(DEFINE-KEY *ROOT-MAP* (KBD "M-y") "gmove two")
-
-(DEFINE-KEY *ROOT-MAP* (KBD "s") "exec")
-(DEFINE-KEY *ROOT-MAP* (KBD "S") "swank-toggle")
-(DEFINE-KEY *ROOT-MAP* (KBD "'") "time")
-(DEFINE-KEY *ROOT-MAP* (KBD ";") "eval")
-(DEFINE-KEY *ROOT-MAP* (KBD ":") "colon")
-(DEFINE-KEY *ROOT-MAP* (KBD "K") "delete")
-(DEFINE-KEY *ROOT-MAP* (KBD "C-K") "kill")
-(DEFINE-KEY *ROOT-MAP* (KBD "q") "exec $BROWSER")
-(DEFINE-KEY *ROOT-MAP* (KBD "E") "emacs")
-(DEFINE-KEY *ROOT-MAP* (KBD "c") "exec $TERMINAL -e tmux")
-(DEFINE-KEY *ROOT-MAP* (KBD "C") "exec $TERMINAL")
-
-(DEFINE-KEY *ROOT-MAP* (KBD "h") "hsplit")
-(DEFINE-KEY *ROOT-MAP* (KBD "v") "vsplit")
-(DEFINE-KEY *ROOT-MAP* (KBD "r") "remove")
-(DEFINE-KEY *ROOT-MAP* (KBD "a") "iresize")
-(DEFINE-KEY *ROOT-MAP* (KBD "x") "exchange-direction")
-(DEFINE-KEY *ROOT-MAP* (KBD "b") "banish")
-
-(DEFINE-KEY *ROOT-MAP* (KBD "space") "my-pull-from-windowlist")
-(DEFINE-KEY *ROOT-MAP* (KBD "C-w") "select-window")
-(DEFINE-KEY *ROOT-MAP* (KBD "W") "pull-window-by-number")
-
-(DEFINE-KEY *ROOT-MAP* (KBD "P") "prev-in-frame")
-(DEFINE-KEY *ROOT-MAP* (KBD "N") "next-in-frame")
-(DEFINE-KEY *ROOT-MAP* (KBD "p") "pull-hidden-previous")
-(DEFINE-KEY *ROOT-MAP* (KBD "n") "pull-hidden-next")
-
-(DEFINE-KEY *ROOT-MAP* (KBD "O") "only")
-
-(DEFINE-KEY *ROOT-MAP* (KBD ",") "move-focus left")
-(DEFINE-KEY *ROOT-MAP* (KBD ".") "move-focus right")
-(DEFINE-KEY *ROOT-MAP* (KBD "i") "move-focus up")
-(DEFINE-KEY *ROOT-MAP* (KBD "o") "move-focus down")
-(DEFINE-KEY *ROOT-MAP* (KBD "M-.") "move-window right")
-(DEFINE-KEY *ROOT-MAP* (KBD "M-,") "move-window left")
-(DEFINE-KEY *ROOT-MAP* (KBD "M-i") "move-window up")
-(DEFINE-KEY *ROOT-MAP* (KBD "M-o") "move-window down")
-
-;; =============================================================================
-;; Visual
-
-;; Set the font
-(REQUIRE 'CLX-TRUETYPE)
-(LOAD-MODULE "ttf-fonts")
-(XFT:CACHE-FONTS)
-(SET-FONT (MAKE-INSTANCE 'XFT:FONT :FAMILY "DejaVu Sans Mono" :SUBFAMILY "Book" :SIZE 12))
-
-;; Modeline
-(LOAD-MODULE "fuzzytime")
-(SETF *MODE-LINE-TIMEOUT* 60
- *SCREEN-MODE-LINE-FORMAT* '("%F ^>" (:EVAL (MAIL-INFO)) " " (:EVAL (BATTERY-INFO)))
- *MODE-LINE-FOREGROUND-COLOR* "black"
- *MODE-LINE-BACKGROUND-COLOR* "#EAFFFF"
- FUZZYTIME:*MINUTE-GRANULARITY* 5
- FUZZYTIME:*FUZZYTIME-FORMAT* '(:MINUTES :HOURS "^7 in the ^n" :PERIOD "^7 on ^n" :DOW "^7 the ^n" :DAY))
-(TOGGLE-MODE-LINE (CURRENT-SCREEN) (CURRENT-HEAD))
-
-;; Colours
-;; TODO: Fix colours
-(SET-FOCUS-COLOR "darkred")
-(SET-UNFOCUS-COLOR "#32302f")
-(SET-WIN-BG-COLOR "black")
-(SET-BORDER-COLOR "grey30")
-(SET-FG-COLOR "black")
-(SET-BG-COLOR "#FFFFEA")
-
-;; =============================================================================
-;; Swank
-
-(QL:QUICKLOAD :SWANK)
-(REQUIRE 'SWANK)
-
-(DEFVAR *SWANK-SERVER-RUNNING* NIL)
-
-(DEFCOMMAND SWANK-TOGGLE () ()
- (IF *SWANK-SERVER-RUNNING*
- (PROGN
- (SWANK:STOP-SERVER 4005)
- (MY-MESSAGE :CENTER "Stopping swank.")
- (SETF *SWANK-SERVER-RUNNING* NIL))
- (PROGN
- (SWANK:CREATE-SERVER :DONT-CLOSE T
- :PORT 4005)
- (MY-MESSAGE :CENTER "Starting swank.")
- (SETF *SWANK-SERVER-RUNNING* T))))
diff --git a/stumpwm/modules/modeline/fuzzytime/README.org b/stumpwm/modules/modeline/fuzzytime/README.org
deleted file mode 100644
index fbfc14f..0000000
--- a/stumpwm/modules/modeline/fuzzytime/README.org
+++ /dev/null
@@ -1,9 +0,0 @@
-** Usage
-Put:
-#+BEGIN_SRC lisp
-(load-module "fuzzytime")
-#+END_SRC
-in =~/.stumpwmrc= and then use =%F= in the mode-line format string.
-
-The output format and granularity may be customised by changing
-~*fuzzytime-format*~ and ~*minute-granularity*~ respectively.
diff --git a/stumpwm/modules/modeline/fuzzytime/fuzzytime.asd b/stumpwm/modules/modeline/fuzzytime/fuzzytime.asd
deleted file mode 100644
index 82a630b..0000000
--- a/stumpwm/modules/modeline/fuzzytime/fuzzytime.asd
+++ /dev/null
@@ -1,11 +0,0 @@
-;;;; fuzzytime.asd
-
-(asdf:defsystem #:fuzzytime
- :description "A module to display a fuzzy date and time in the modeline of StumpWM"
- :author "Tslil Clingman <tslil@posteo.de>"
- :license "GPLv3"
- :depends-on (#:stumpwm)
- :serial t
- :components ((:file "package")
- (:file "fuzzytime")))
-
diff --git a/stumpwm/modules/modeline/fuzzytime/fuzzytime.lisp b/stumpwm/modules/modeline/fuzzytime/fuzzytime.lisp
deleted file mode 100644
index 9a703a3..0000000
--- a/stumpwm/modules/modeline/fuzzytime/fuzzytime.lisp
+++ /dev/null
@@ -1,84 +0,0 @@
-;;;; fuzzytime.lisp
-
-(IN-PACKAGE #:FUZZYTIME)
-
-(EXPORT '(*FUZZYTIME-FORMAT* *MINUTE-GRANULARITY*))
-
-(PUSHNEW '(#\F LOCAL-TIME-TO-FUZZY) *SCREEN-MODE-LINE-FORMATTERS* :TEST 'EQUAL)
-
-(DEFPARAMETER *MINUTE-GRANULARITY* 10
- "Minutes are rounded to the nearest multiple of *minute-granularity*")
-
-(DEFPARAMETER *FUZZYTIME-FORMAT*
- '(:MINUTES :HOURS " in the " :PERIOD " on " :DOW
- " the " :DAY " of " :MONTH)
- "Format of the output, a list of strings and keywords. Valid keywords are:
-:minutes
-:hours
-:period
-:dow (name of the day of the week)
-:udow (name of the day of the week, capitalised)
-:dn (number of the day of the week)
-:day (day of the month)
-:mnum (number of the month)
-:month (name of the month, capitalised)
-:umonth (name of the month)")
-
-(DEFVAR *MONTH-NAMES*
- (MAKE-ARRAY '(12) :INITIAL-CONTENTS
- '("january" "february" "march" "april" "may" "june" "july"
- "august" "september" "october" "november" "december")))
-
-(DEFVAR *DOW-NAMES*
- (MAKE-ARRAY '(7) :INITIAL-CONTENTS
- '("monday" "tuesday" "wednesday"
- "thursday" "friday" "saturday"
- "sunday")))
-
-(DEFUN MINUTES-TO-WORDS (MIN)
- (IF (OR (<= MIN 0) (>= MIN 60)) ""
- (FLET ((FRAC (M) (COND
- ((= M 30) "half")
- ((= M 15) "quarter")
- (T (FORMAT NIL "~r" M)))))
- (FORMAT NIL "~a ~a " (FRAC (IF (> MIN 30) (- 60 MIN) MIN))
- (IF (> MIN 30) "to" "past")))))
-
-(DEFUN HOUR-TO-WORDS (HOUR MIN)
- (LET ((H (MOD
- (IF (> MIN 30) (1+ HOUR) HOUR )
- 12)))
- (FORMAT NIL "~r~a"
- (IF (= H 0) 12 H)
- (IF (OR (= MIN 0) (= MIN 60)) " o'clock" ""))))
-
-(DEFUN PERIOD-INDICATOR (HOUR)
- (IF (< HOUR 12) "morning"
- (IF (< HOUR 17) "afternoon" "evening")))
-
-(DEFUN LOCAL-TIME-TO-FUZZY (ML)
- (DECLARE (IGNORE ML))
- (MULTIPLE-VALUE-BIND (SECONDS MINUTES HOUR DAY MONTH YEAR DOW)
- (GET-DECODED-TIME)
- (DECLARE (IGNORE SECONDS) (IGNORE YEAR))
- (LET* ((MIN (* *MINUTE-GRANULARITY*
- (ROUND (/ MINUTES *MINUTE-GRANULARITY*))))
- (MS (MINUTES-TO-WORDS MIN))
- (HS (HOUR-TO-WORDS HOUR MIN))
- (PS (PERIOD-INDICATOR HOUR))
- (DN (ELT *DOW-NAMES* DOW))
- (MN (ELT *MONTH-NAMES* (1- MONTH))))
- (APPLY #'CONCATENATE 'STRING
- (LOOP FOR E IN *FUZZYTIME-FORMAT* COLLECT
- (CASE E
- (:MINUTES MS)
- (:HOURS HS)
- (:PERIOD PS)
- (:DOW DN)
- (:UDOW (STRING-CAPITALIZE DN))
- (:MONTH MN)
- (:UMONTH (STRING-CAPITALIZE MN))
- (:DNUM (FORMAT NIL "~a" DOW))
- (:DAY (FORMAT NIL "~:r" DAY))
- (:MNUM (FORMAT NIL "~a" MONTH))
- (OTHERWISE E)))))))
diff --git a/stumpwm/modules/modeline/fuzzytime/package.lisp b/stumpwm/modules/modeline/fuzzytime/package.lisp
deleted file mode 100644
index 944e195..0000000
--- a/stumpwm/modules/modeline/fuzzytime/package.lisp
+++ /dev/null
@@ -1,5 +0,0 @@
-;;;; package.lisp
-
-(defpackage #:fuzzytime
- (:use #:cl :stumpwm))
-
diff --git a/zile-kill-region-or-backward-kill-word.patch b/zile-kill-region-or-backward-kill-word.patch
deleted file mode 100644
index fb6ddeb..0000000
--- a/zile-kill-region-or-backward-kill-word.patch
+++ /dev/null
@@ -1,85 +0,0 @@
-diff --git a/src/buffer.c b/src/buffer.c
-index bbb487c6..9656418c 100644
---- a/src/buffer.c
-+++ b/src/buffer.c
-@@ -436,6 +436,16 @@ warn_if_readonly_buffer (void)
- return false;
- }
-
-+bool
-+check_if_no_mark (void) {
-+ if ((!cur_bp->mark) ||
-+ (!get_buffer_mark_active (cur_bp)))
-+ {
-+ return true;
-+ }
-+ return false;
-+}
-+
- bool
- warn_if_no_mark (void)
- {
-diff --git a/src/extern.h b/src/extern.h
-index 277e1619..2b04edc3 100644
---- a/src/extern.h
-+++ b/src/extern.h
-@@ -74,6 +74,7 @@ _GL_ATTRIBUTE_PURE const char *get_buffer_filename_or_name (Buffer bp);
- void set_buffer_names (Buffer bp, const char *filename);
- _GL_ATTRIBUTE_PURE Buffer find_buffer (const char *name);
- void switch_to_buffer (Buffer bp);
-+bool check_if_no_mark (void);
- bool warn_if_no_mark (void);
- bool warn_if_readonly_buffer (void);
- #define FIELD(ty, field) \
-diff --git a/src/killring.c b/src/killring.c
-index 750acb1d..50753ac7 100644
---- a/src/killring.c
-+++ b/src/killring.c
-@@ -211,6 +211,34 @@ kill_text (long uniarg, Function mark_func)
- return true;
- }
-
-+DEFUN_ARGS ("kill-region-or-backward-kill-word",
-+ kill_region_or_backward_kill_word,
-+ INT_OR_UNIARG (arg))
-+/*+
-+Kill (\"cut\") text between point and mark, if they are both
-+active, otherwise performs \\[backward-kill-word]. This deletes the
-+text from the buffer and saves it in the kill ring. The command
-+\\[yank] can retrieve it from there.
-+
-+Any command that calls this function is a \"kill command\". If the
-+previous command was also a kill command, the text killed this time
-+appends to the text killed last time to make one entry in the kill
-+ring.
-+
-+If the buffer is read-only, Zile will beep and refrain from deleting
-+the text, but put the text in the kill ring anyway. This means that
-+you can use the killing commands to copy text from a read-only buffer.
-++*/
-+{
-+ INT_OR_UNIARG_INIT (arg);
-+ if (check_if_no_mark ()) {
-+ ok = kill_text (-arg, F_mark_word);
-+ } else {
-+ ok = copy_or_kill_the_region(true);
-+ }
-+}
-+END_DEFUN
-+
- DEFUN_ARGS ("kill-word", kill_word,
- INT_OR_UNIARG (arg))
- /*+
-diff --git a/src/tbl_bindings.pl b/src/tbl_bindings.pl
-index 61240d15..797e3bfa 100644
---- a/src/tbl_bindings.pl
-+++ b/src/tbl_bindings.pl
-@@ -70,7 +70,7 @@
- "keyboard-quit" => ["\\C-g"],
- "kill-buffer" => ["\\C-xk"],
- "kill-line" => ["\\C-k"],
-- "kill-region" => ["\\C-w"],
-+ "kill-region-or-backward-kill-word" => ["\\C-w"],
- "kill-sexp" => ["\\C-\\M-k"],
- "kill-word" => ["\\M-d"],
- "list-buffers" => ["\\C-x\\C-b"],