From 0c609481d5c18500228af63ac9f517afcabc71ac Mon Sep 17 00:00:00 2001 From: coast Date: Fri, 4 Jul 2025 15:27:31 +0330 Subject: [PATCH] moved suckless to somewhere else --- .zprofile | 10 +- suckless/dmenu/LICENSE | 30 - suckless/dmenu/Makefile | 58 - suckless/dmenu/README | 24 - suckless/dmenu/arg.h | 49 - suckless/dmenu/config.def.h | 23 - suckless/dmenu/config.h | 23 - suckless/dmenu/config.mk | 32 - suckless/dmenu/dmenu | Bin 42296 -> 0 bytes suckless/dmenu/dmenu.1 | 194 - suckless/dmenu/dmenu.c | 795 ---- suckless/dmenu/dmenu.o | Bin 32232 -> 0 bytes suckless/dmenu/dmenu_path | 13 - suckless/dmenu/dmenu_run | 2 - suckless/dmenu/drw.c | 448 -- suckless/dmenu/drw.h | 58 - suckless/dmenu/drw.o | Bin 11464 -> 0 bytes suckless/dmenu/stest | Bin 16288 -> 0 bytes suckless/dmenu/stest.1 | 90 - suckless/dmenu/stest.c | 109 - suckless/dmenu/stest.o | Bin 5344 -> 0 bytes suckless/dmenu/util.c | 37 - suckless/dmenu/util.h | 9 - suckless/dmenu/util.o | Bin 2472 -> 0 bytes suckless/dwm/#dwm.c# | 2302 ---------- suckless/dwm/LICENSE | 38 - suckless/dwm/Makefile | 45 - suckless/dwm/README | 48 - suckless/dwm/README.md | 30 - suckless/dwm/attachaside.diff | 93 - suckless/dwm/config.def.h | 129 - suckless/dwm/config.h | 164 - suckless/dwm/config.h~ | 165 - suckless/dwm/config.mk | 39 - suckless/dwm/configure | 40 - suckless/dwm/drw.c | 448 -- suckless/dwm/drw.h | 58 - suckless/dwm/drw.o | Bin 11464 -> 0 bytes suckless/dwm/dwm | Bin 73952 -> 0 bytes suckless/dwm/dwm.1 | 186 - suckless/dwm/dwm.c | 2302 ---------- suckless/dwm/dwm.c.orig | 2278 ---------- suckless/dwm/dwm.c.rej | 20 - suckless/dwm/dwm.o | Bin 63136 -> 0 bytes suckless/dwm/dwm.png | Bin 373 -> 0 bytes suckless/dwm/mkconfig/config.mk.freebsd | 59 - suckless/dwm/mkconfig/config.mk.linux | 55 - suckless/dwm/mkconfig/config.mk.openbsd | 57 - suckless/dwm/mkconfig/config.mk.solaris | 58 - suckless/dwm/movestack.c | 48 - suckless/dwm/patch/attachx.c | 20 - suckless/dwm/patch/attachx.h | 2 - suckless/dwm/patch/bar.c | 39 - suckless/dwm/patch/bar.h | 2 - suckless/dwm/patch/bar_alpha.c | 43 - suckless/dwm/patch/bar_alpha.h | 4 - suckless/dwm/patch/bar_indicators.c | 104 - suckless/dwm/patch/bar_indicators.h | 21 - suckless/dwm/patch/bar_ltsymbol.c | 18 - suckless/dwm/patch/bar_ltsymbol.h | 4 - suckless/dwm/patch/bar_status.c | 20 - suckless/dwm/patch/bar_status.h | 4 - suckless/dwm/patch/bar_tagicons.c | 9 - suckless/dwm/patch/bar_tagicons.h | 8 - suckless/dwm/patch/bar_tags.c | 81 - suckless/dwm/patch/bar_tags.h | 4 - suckless/dwm/patch/bar_wintitle.c | 48 - suckless/dwm/patch/bar_wintitle.h | 4 - suckless/dwm/patch/cool_autostart.c | 29 - suckless/dwm/patch/cool_autostart.h | 2 - .../dwm/patch/dwm-alpha-20230401-348f655.diff | Bin 1024 -> 0 bytes suckless/dwm/patch/dwmc | 130 - suckless/dwm/patch/dwmc.c | 85 - suckless/dwm/patch/dwmc.h | 14 - suckless/dwm/patch/fullscreen.c | 15 - suckless/dwm/patch/fullscreen.h | 2 - suckless/dwm/patch/hidevacanttags.diff | 49 - suckless/dwm/patch/hidevacanttags.diff.orig | 49 - suckless/dwm/patch/hidevacanttags.diff.rej | 44 - suckless/dwm/patch/include.c | 27 - suckless/dwm/patch/include.h | 26 - suckless/dwm/patch/ipc/IPCClient.h | 62 - suckless/dwm/patch/ipc/dwm-msg.c | 549 --- suckless/dwm/patch/ipc/yajl_dumps.h | 66 - suckless/dwm/patch/layout_facts.c | 24 - suckless/dwm/patch/layout_tile.c | 41 - suckless/dwm/patch/layout_tile.h | 2 - suckless/dwm/patch/moveresize.c | 65 - suckless/dwm/patch/moveresize.h | 2 - suckless/dwm/patch/movestack.c | 51 - suckless/dwm/patch/movestack.h | 2 - suckless/dwm/patch/scratchpad.c | 77 - suckless/dwm/patch/scratchpad.h | 9 - suckless/dwm/patch/swallow.c | 212 - suckless/dwm/patch/swallow.h | 8 - suckless/dwm/patch/togglefullscreen.c | 10 - suckless/dwm/patch/togglefullscreen.h | 2 - suckless/dwm/patch/vanitygaps.c | 177 - suckless/dwm/patch/vanitygaps.h | 16 - suckless/dwm/patch/xrdb.c | 73 - suckless/dwm/patch/xrdb.h | 22 - .../dwm-attachaside-20160718-56a31dc.diff | 92 - .../patches/dwm-bar-height-spacing-6.3.diff | 25 - .../dwm-barpadding-20211020-a786211.diff | 118 - suckless/dwm/patches/dwm-fullgaps-6.4.diff | 94 - .../patches/dwm-notitle-20210715-138b405.diff | 81 - .../patches/dwm-restartsig-20180523-6.2.diff | 139 - .../dwm/patches/dwm-statusallmons-6.2.diff | 25 - suckless/dwm/patches/dwm-warp-6.4.diff | 79 - suckless/dwm/patches/dwm-xrdb-6.4.diff | 203 - suckless/dwm/patches/hidevacanttags.diff | 48 - suckless/dwm/readme.dwm.txt | 48 - suckless/dwm/transient.c | 42 - suckless/dwm/util.c | 37 - suckless/dwm/util.h | 9 - suckless/dwm/util.o | Bin 2472 -> 0 bytes suckless/dwmblocks | 1 - suckless/slstatus/LICENSE | 43 - suckless/slstatus/Makefile | 69 - suckless/slstatus/arg.h | 33 - suckless/slstatus/components/battery.c | 247 -- suckless/slstatus/components/battery.o | Bin 5208 -> 0 bytes suckless/slstatus/components/cat.c | 32 - suckless/slstatus/components/cat.o | Bin 2128 -> 0 bytes suckless/slstatus/components/cpu.c | 157 - suckless/slstatus/components/cpu.o | Bin 3168 -> 0 bytes suckless/slstatus/components/datetime.c | 20 - suckless/slstatus/components/datetime.o | Bin 1960 -> 0 bytes suckless/slstatus/components/disk.c | 59 - suckless/slstatus/components/disk.o | Bin 3168 -> 0 bytes suckless/slstatus/components/entropy.c | 29 - suckless/slstatus/components/entropy.o | Bin 1824 -> 0 bytes suckless/slstatus/components/hostname.c | 17 - suckless/slstatus/components/hostname.o | Bin 1680 -> 0 bytes suckless/slstatus/components/ip.c | 61 - suckless/slstatus/components/ip.o | Bin 2592 -> 0 bytes suckless/slstatus/components/kernel_release.c | 19 - suckless/slstatus/components/kernel_release.o | Bin 1872 -> 0 bytes .../slstatus/components/keyboard_indicators.c | 50 - .../slstatus/components/keyboard_indicators.o | Bin 2448 -> 0 bytes suckless/slstatus/components/keymap.c | 86 - suckless/slstatus/components/keymap.o | Bin 4048 -> 0 bytes suckless/slstatus/components/load_avg.c | 19 - suckless/slstatus/components/load_avg.o | Bin 1904 -> 0 bytes suckless/slstatus/components/netspeeds.c | 129 - suckless/slstatus/components/netspeeds.o | Bin 2824 -> 0 bytes suckless/slstatus/components/num_files.c | 32 - suckless/slstatus/components/num_files.o | Bin 2192 -> 0 bytes suckless/slstatus/components/pixVol.sh | 10 - suckless/slstatus/components/ram.c | 212 - suckless/slstatus/components/ram.o | Bin 3128 -> 0 bytes suckless/slstatus/components/run_command.c | 31 - suckless/slstatus/components/run_command.o | Bin 2144 -> 0 bytes suckless/slstatus/components/swap.c | 274 -- suckless/slstatus/components/swap.o | Bin 3928 -> 0 bytes suckless/slstatus/components/temperature.c | 73 - suckless/slstatus/components/temperature.o | Bin 1744 -> 0 bytes suckless/slstatus/components/uptime.c | 34 - suckless/slstatus/components/uptime.o | Bin 2024 -> 0 bytes suckless/slstatus/components/user.c | 33 - suckless/slstatus/components/user.o | Bin 2240 -> 0 bytes suckless/slstatus/components/volume.c | 219 - suckless/slstatus/components/volume.o | Bin 3632 -> 0 bytes suckless/slstatus/components/wifi.c | 267 -- suckless/slstatus/components/wifi.o | Bin 4320 -> 0 bytes suckless/slstatus/config.def.h | 81 - suckless/slstatus/config.h | 74 - suckless/slstatus/config.h~ | 77 - suckless/slstatus/config.mk | 22 - suckless/slstatus/slstatus | Bin 31248 -> 0 bytes suckless/slstatus/slstatus.1 | 47 - suckless/slstatus/slstatus.c | 134 - suckless/slstatus/slstatus.h | 84 - suckless/slstatus/slstatus.o | Bin 6376 -> 0 bytes suckless/slstatus/util.c | 141 - suckless/slstatus/util.h | 16 - suckless/slstatus/util.o | Bin 5592 -> 0 bytes suckless/st/LEGACY | 17 - suckless/st/LICENSE | 34 - suckless/st/Makefile | 52 - suckless/st/README | 34 - suckless/st/TODO | 28 - suckless/st/arg.h | 50 - suckless/st/boxdraw.c | 194 - suckless/st/boxdraw_data.h | 214 - suckless/st/config.def.h | 517 --- suckless/st/config.h | 479 --- suckless/st/config.h.save | 486 --- suckless/st/config.h.save.1 | 486 --- suckless/st/config.h.save.2 | 486 --- suckless/st/config.h.save.3 | 486 --- suckless/st/config.mk | 38 - suckless/st/graphics.c | 3812 ----------------- suckless/st/graphics.h | 107 - suckless/st/hb.c | 125 - suckless/st/hb.h | 14 - suckless/st/hb.o | Bin 4304 -> 0 bytes suckless/st/icat-mini.sh | 800 ---- suckless/st/khash.h | 627 --- suckless/st/kvec.h | 90 - suckless/st/rowcolumn_diacritics_helpers.c | 391 -- suckless/st/st | Bin 120544 -> 0 bytes ...st-alpha-changealpha-20230519-b44f2ad.diff | 194 - suckless/st/st.1 | 177 - suckless/st/st.c | 2799 ------------ suckless/st/st.h | 130 - suckless/st/st.info | 243 -- suckless/st/st.o | Bin 82832 -> 0 bytes suckless/st/win.h | 41 - suckless/st/x.c | 2319 ---------- suckless/st/x.o | Bin 86904 -> 0 bytes 211 files changed, 9 insertions(+), 32476 deletions(-) delete mode 100644 suckless/dmenu/LICENSE delete mode 100644 suckless/dmenu/Makefile delete mode 100644 suckless/dmenu/README delete mode 100644 suckless/dmenu/arg.h delete mode 100644 suckless/dmenu/config.def.h delete mode 100644 suckless/dmenu/config.h delete mode 100644 suckless/dmenu/config.mk delete mode 100755 suckless/dmenu/dmenu delete mode 100644 suckless/dmenu/dmenu.1 delete mode 100644 suckless/dmenu/dmenu.c delete mode 100644 suckless/dmenu/dmenu.o delete mode 100644 suckless/dmenu/dmenu_path delete mode 100644 suckless/dmenu/dmenu_run delete mode 100644 suckless/dmenu/drw.c delete mode 100644 suckless/dmenu/drw.h delete mode 100644 suckless/dmenu/drw.o delete mode 100755 suckless/dmenu/stest delete mode 100644 suckless/dmenu/stest.1 delete mode 100644 suckless/dmenu/stest.c delete mode 100644 suckless/dmenu/stest.o delete mode 100644 suckless/dmenu/util.c delete mode 100644 suckless/dmenu/util.h delete mode 100644 suckless/dmenu/util.o delete mode 100644 suckless/dwm/#dwm.c# delete mode 100644 suckless/dwm/LICENSE delete mode 100644 suckless/dwm/Makefile delete mode 100644 suckless/dwm/README delete mode 100644 suckless/dwm/README.md delete mode 100644 suckless/dwm/attachaside.diff delete mode 100644 suckless/dwm/config.def.h delete mode 100644 suckless/dwm/config.h delete mode 100644 suckless/dwm/config.h~ delete mode 100644 suckless/dwm/config.mk delete mode 100644 suckless/dwm/configure delete mode 100644 suckless/dwm/drw.c delete mode 100644 suckless/dwm/drw.h delete mode 100644 suckless/dwm/drw.o delete mode 100755 suckless/dwm/dwm delete mode 100644 suckless/dwm/dwm.1 delete mode 100644 suckless/dwm/dwm.c delete mode 100644 suckless/dwm/dwm.c.orig delete mode 100644 suckless/dwm/dwm.c.rej delete mode 100644 suckless/dwm/dwm.o delete mode 100644 suckless/dwm/dwm.png delete mode 100644 suckless/dwm/mkconfig/config.mk.freebsd delete mode 100644 suckless/dwm/mkconfig/config.mk.linux delete mode 100644 suckless/dwm/mkconfig/config.mk.openbsd delete mode 100644 suckless/dwm/mkconfig/config.mk.solaris delete mode 100644 suckless/dwm/movestack.c delete mode 100644 suckless/dwm/patch/attachx.c delete mode 100644 suckless/dwm/patch/attachx.h delete mode 100644 suckless/dwm/patch/bar.c delete mode 100644 suckless/dwm/patch/bar.h delete mode 100644 suckless/dwm/patch/bar_alpha.c delete mode 100644 suckless/dwm/patch/bar_alpha.h delete mode 100644 suckless/dwm/patch/bar_indicators.c delete mode 100644 suckless/dwm/patch/bar_indicators.h delete mode 100644 suckless/dwm/patch/bar_ltsymbol.c delete mode 100644 suckless/dwm/patch/bar_ltsymbol.h delete mode 100644 suckless/dwm/patch/bar_status.c delete mode 100644 suckless/dwm/patch/bar_status.h delete mode 100644 suckless/dwm/patch/bar_tagicons.c delete mode 100644 suckless/dwm/patch/bar_tagicons.h delete mode 100644 suckless/dwm/patch/bar_tags.c delete mode 100644 suckless/dwm/patch/bar_tags.h delete mode 100644 suckless/dwm/patch/bar_wintitle.c delete mode 100644 suckless/dwm/patch/bar_wintitle.h delete mode 100644 suckless/dwm/patch/cool_autostart.c delete mode 100644 suckless/dwm/patch/cool_autostart.h delete mode 100644 suckless/dwm/patch/dwm-alpha-20230401-348f655.diff delete mode 100644 suckless/dwm/patch/dwmc delete mode 100644 suckless/dwm/patch/dwmc.c delete mode 100644 suckless/dwm/patch/dwmc.h delete mode 100644 suckless/dwm/patch/fullscreen.c delete mode 100644 suckless/dwm/patch/fullscreen.h delete mode 100644 suckless/dwm/patch/hidevacanttags.diff delete mode 100644 suckless/dwm/patch/hidevacanttags.diff.orig delete mode 100644 suckless/dwm/patch/hidevacanttags.diff.rej delete mode 100644 suckless/dwm/patch/include.c delete mode 100644 suckless/dwm/patch/include.h delete mode 100644 suckless/dwm/patch/ipc/IPCClient.h delete mode 100644 suckless/dwm/patch/ipc/dwm-msg.c delete mode 100644 suckless/dwm/patch/ipc/yajl_dumps.h delete mode 100644 suckless/dwm/patch/layout_facts.c delete mode 100644 suckless/dwm/patch/layout_tile.c delete mode 100644 suckless/dwm/patch/layout_tile.h delete mode 100644 suckless/dwm/patch/moveresize.c delete mode 100644 suckless/dwm/patch/moveresize.h delete mode 100644 suckless/dwm/patch/movestack.c delete mode 100644 suckless/dwm/patch/movestack.h delete mode 100644 suckless/dwm/patch/scratchpad.c delete mode 100644 suckless/dwm/patch/scratchpad.h delete mode 100644 suckless/dwm/patch/swallow.c delete mode 100644 suckless/dwm/patch/swallow.h delete mode 100644 suckless/dwm/patch/togglefullscreen.c delete mode 100644 suckless/dwm/patch/togglefullscreen.h delete mode 100644 suckless/dwm/patch/vanitygaps.c delete mode 100644 suckless/dwm/patch/vanitygaps.h delete mode 100644 suckless/dwm/patch/xrdb.c delete mode 100644 suckless/dwm/patch/xrdb.h delete mode 100644 suckless/dwm/patches/dwm-attachaside-20160718-56a31dc.diff delete mode 100644 suckless/dwm/patches/dwm-bar-height-spacing-6.3.diff delete mode 100755 suckless/dwm/patches/dwm-barpadding-20211020-a786211.diff delete mode 100755 suckless/dwm/patches/dwm-fullgaps-6.4.diff delete mode 100755 suckless/dwm/patches/dwm-notitle-20210715-138b405.diff delete mode 100755 suckless/dwm/patches/dwm-restartsig-20180523-6.2.diff delete mode 100755 suckless/dwm/patches/dwm-statusallmons-6.2.diff delete mode 100755 suckless/dwm/patches/dwm-warp-6.4.diff delete mode 100755 suckless/dwm/patches/dwm-xrdb-6.4.diff delete mode 100644 suckless/dwm/patches/hidevacanttags.diff delete mode 100644 suckless/dwm/readme.dwm.txt delete mode 100644 suckless/dwm/transient.c delete mode 100644 suckless/dwm/util.c delete mode 100644 suckless/dwm/util.h delete mode 100644 suckless/dwm/util.o delete mode 160000 suckless/dwmblocks delete mode 100644 suckless/slstatus/LICENSE delete mode 100644 suckless/slstatus/Makefile delete mode 100644 suckless/slstatus/arg.h delete mode 100644 suckless/slstatus/components/battery.c delete mode 100644 suckless/slstatus/components/battery.o delete mode 100644 suckless/slstatus/components/cat.c delete mode 100644 suckless/slstatus/components/cat.o delete mode 100644 suckless/slstatus/components/cpu.c delete mode 100644 suckless/slstatus/components/cpu.o delete mode 100644 suckless/slstatus/components/datetime.c delete mode 100644 suckless/slstatus/components/datetime.o delete mode 100644 suckless/slstatus/components/disk.c delete mode 100644 suckless/slstatus/components/disk.o delete mode 100644 suckless/slstatus/components/entropy.c delete mode 100644 suckless/slstatus/components/entropy.o delete mode 100644 suckless/slstatus/components/hostname.c delete mode 100644 suckless/slstatus/components/hostname.o delete mode 100644 suckless/slstatus/components/ip.c delete mode 100644 suckless/slstatus/components/ip.o delete mode 100644 suckless/slstatus/components/kernel_release.c delete mode 100644 suckless/slstatus/components/kernel_release.o delete mode 100644 suckless/slstatus/components/keyboard_indicators.c delete mode 100644 suckless/slstatus/components/keyboard_indicators.o delete mode 100644 suckless/slstatus/components/keymap.c delete mode 100644 suckless/slstatus/components/keymap.o delete mode 100644 suckless/slstatus/components/load_avg.c delete mode 100644 suckless/slstatus/components/load_avg.o delete mode 100644 suckless/slstatus/components/netspeeds.c delete mode 100644 suckless/slstatus/components/netspeeds.o delete mode 100644 suckless/slstatus/components/num_files.c delete mode 100644 suckless/slstatus/components/num_files.o delete mode 100644 suckless/slstatus/components/pixVol.sh delete mode 100644 suckless/slstatus/components/ram.c delete mode 100644 suckless/slstatus/components/ram.o delete mode 100644 suckless/slstatus/components/run_command.c delete mode 100644 suckless/slstatus/components/run_command.o delete mode 100644 suckless/slstatus/components/swap.c delete mode 100644 suckless/slstatus/components/swap.o delete mode 100644 suckless/slstatus/components/temperature.c delete mode 100644 suckless/slstatus/components/temperature.o delete mode 100644 suckless/slstatus/components/uptime.c delete mode 100644 suckless/slstatus/components/uptime.o delete mode 100644 suckless/slstatus/components/user.c delete mode 100644 suckless/slstatus/components/user.o delete mode 100644 suckless/slstatus/components/volume.c delete mode 100644 suckless/slstatus/components/volume.o delete mode 100644 suckless/slstatus/components/wifi.c delete mode 100644 suckless/slstatus/components/wifi.o delete mode 100644 suckless/slstatus/config.def.h delete mode 100644 suckless/slstatus/config.h delete mode 100644 suckless/slstatus/config.h~ delete mode 100644 suckless/slstatus/config.mk delete mode 100755 suckless/slstatus/slstatus delete mode 100644 suckless/slstatus/slstatus.1 delete mode 100644 suckless/slstatus/slstatus.c delete mode 100644 suckless/slstatus/slstatus.h delete mode 100644 suckless/slstatus/slstatus.o delete mode 100644 suckless/slstatus/util.c delete mode 100644 suckless/slstatus/util.h delete mode 100644 suckless/slstatus/util.o delete mode 100644 suckless/st/LEGACY delete mode 100644 suckless/st/LICENSE delete mode 100644 suckless/st/Makefile delete mode 100644 suckless/st/README delete mode 100644 suckless/st/TODO delete mode 100644 suckless/st/arg.h delete mode 100644 suckless/st/boxdraw.c delete mode 100644 suckless/st/boxdraw_data.h delete mode 100644 suckless/st/config.def.h delete mode 100644 suckless/st/config.h delete mode 100644 suckless/st/config.h.save delete mode 100644 suckless/st/config.h.save.1 delete mode 100644 suckless/st/config.h.save.2 delete mode 100644 suckless/st/config.h.save.3 delete mode 100644 suckless/st/config.mk delete mode 100644 suckless/st/graphics.c delete mode 100644 suckless/st/graphics.h delete mode 100644 suckless/st/hb.c delete mode 100644 suckless/st/hb.h delete mode 100644 suckless/st/hb.o delete mode 100755 suckless/st/icat-mini.sh delete mode 100644 suckless/st/khash.h delete mode 100644 suckless/st/kvec.h delete mode 100644 suckless/st/rowcolumn_diacritics_helpers.c delete mode 100755 suckless/st/st delete mode 100644 suckless/st/st-alpha-changealpha-20230519-b44f2ad.diff delete mode 100644 suckless/st/st.1 delete mode 100644 suckless/st/st.c delete mode 100644 suckless/st/st.h delete mode 100644 suckless/st/st.info delete mode 100644 suckless/st/st.o delete mode 100644 suckless/st/win.h delete mode 100644 suckless/st/x.c delete mode 100644 suckless/st/x.o diff --git a/.zprofile b/.zprofile index 331502e..25c6539 100644 --- a/.zprofile +++ b/.zprofile @@ -26,10 +26,18 @@ alias \ cleae="clear" \ clera="clear" \ hotp="htop" \ - copykey='cat ~/.local/key/vault1.key | xclip -sel clipboard' + copykey='cat ~/.local/key/vault1.key | xclip -sel clipboard' \ grep --color=auto < /dev/null &>/dev/null && alias grep='grep --color=auto' +#utilize sbase coreutils when in shell +export GNU_PATH_BACKUP="$PATH" +export PATH="/bin/sbaseutils/bin:$PATH" +export COREUTILSMODE="POSIX" +alias gnumode='export PATH="/usr/bin:/bin:$GNU_PATH_BACKUP"; export COREUTILSMODE="GNU"' +alias posixmode='export PATH="/home/coast/.local/sbase/bin:$HOME/.local/bin:$GNU_PATH_BACKUP"; export COREUTILSMODE="POSIX"' + + export PATH="$HOME/.local/bin:$PATH" export PATH="/usr/pkg/sbin:/usr/pkg/bin:$PATH" export PATH="$PATH:/home/coast/.spicetify" diff --git a/suckless/dmenu/LICENSE b/suckless/dmenu/LICENSE deleted file mode 100644 index 2a64b28..0000000 --- a/suckless/dmenu/LICENSE +++ /dev/null @@ -1,30 +0,0 @@ -MIT/X Consortium License - -© 2006-2019 Anselm R Garbe -© 2006-2008 Sander van Dijk -© 2006-2007 Michał Janeczek -© 2007 Kris Maglione -© 2009 Gottox -© 2009 Markus Schnalke -© 2009 Evan Gates -© 2010-2012 Connor Lane Smith -© 2014-2022 Hiltjo Posthuma -© 2015-2019 Quentin Rameau - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the "Software"), -to deal in the Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. diff --git a/suckless/dmenu/Makefile b/suckless/dmenu/Makefile deleted file mode 100644 index 458c524..0000000 --- a/suckless/dmenu/Makefile +++ /dev/null @@ -1,58 +0,0 @@ -# dmenu - dynamic menu -# See LICENSE file for copyright and license details. - -include config.mk - -SRC = drw.c dmenu.c stest.c util.c -OBJ = $(SRC:.c=.o) - -all: dmenu stest - -.c.o: - $(CC) -c $(CFLAGS) $< - -config.h: - cp config.def.h $@ - -$(OBJ): arg.h config.h config.mk drw.h - -dmenu: dmenu.o drw.o util.o - $(CC) -o $@ dmenu.o drw.o util.o $(LDFLAGS) - -stest: stest.o - $(CC) -o $@ stest.o $(LDFLAGS) - -clean: - rm -f dmenu stest $(OBJ) dmenu-$(VERSION).tar.gz - -dist: clean - mkdir -p dmenu-$(VERSION) - cp LICENSE Makefile README arg.h config.def.h config.mk dmenu.1\ - drw.h util.h dmenu_path dmenu_run stest.1 $(SRC)\ - dmenu-$(VERSION) - tar -cf dmenu-$(VERSION).tar dmenu-$(VERSION) - gzip dmenu-$(VERSION).tar - rm -rf dmenu-$(VERSION) - -install: all - mkdir -p $(DESTDIR)$(PREFIX)/bin - cp -f dmenu dmenu_path dmenu_run stest $(DESTDIR)$(PREFIX)/bin - chmod 755 $(DESTDIR)$(PREFIX)/bin/dmenu - chmod 755 $(DESTDIR)$(PREFIX)/bin/dmenu_path - chmod 755 $(DESTDIR)$(PREFIX)/bin/dmenu_run - chmod 755 $(DESTDIR)$(PREFIX)/bin/stest - mkdir -p $(DESTDIR)$(MANPREFIX)/man1 - sed "s/VERSION/$(VERSION)/g" < dmenu.1 > $(DESTDIR)$(MANPREFIX)/man1/dmenu.1 - sed "s/VERSION/$(VERSION)/g" < stest.1 > $(DESTDIR)$(MANPREFIX)/man1/stest.1 - chmod 644 $(DESTDIR)$(MANPREFIX)/man1/dmenu.1 - chmod 644 $(DESTDIR)$(MANPREFIX)/man1/stest.1 - -uninstall: - rm -f $(DESTDIR)$(PREFIX)/bin/dmenu\ - $(DESTDIR)$(PREFIX)/bin/dmenu_path\ - $(DESTDIR)$(PREFIX)/bin/dmenu_run\ - $(DESTDIR)$(PREFIX)/bin/stest\ - $(DESTDIR)$(MANPREFIX)/man1/dmenu.1\ - $(DESTDIR)$(MANPREFIX)/man1/stest.1 - -.PHONY: all clean dist install uninstall diff --git a/suckless/dmenu/README b/suckless/dmenu/README deleted file mode 100644 index a8fcdfe..0000000 --- a/suckless/dmenu/README +++ /dev/null @@ -1,24 +0,0 @@ -dmenu - dynamic menu -==================== -dmenu is an efficient dynamic menu for X. - - -Requirements ------------- -In order to build dmenu you need the Xlib header files. - - -Installation ------------- -Edit config.mk to match your local setup (dmenu is installed into -the /usr/local namespace by default). - -Afterwards enter the following command to build and install dmenu -(if necessary as root): - - make clean install - - -Running dmenu -------------- -See the man page for details. diff --git a/suckless/dmenu/arg.h b/suckless/dmenu/arg.h deleted file mode 100644 index e94e02b..0000000 --- a/suckless/dmenu/arg.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copy me if you can. - * by 20h - */ - -#ifndef ARG_H__ -#define ARG_H__ - -extern char *argv0; - -/* use main(int argc, char *argv[]) */ -#define ARGBEGIN for (argv0 = *argv, argv++, argc--;\ - argv[0] && argv[0][0] == '-'\ - && argv[0][1];\ - argc--, argv++) {\ - char argc_;\ - char **argv_;\ - int brk_;\ - if (argv[0][1] == '-' && argv[0][2] == '\0') {\ - argv++;\ - argc--;\ - break;\ - }\ - for (brk_ = 0, argv[0]++, argv_ = argv;\ - argv[0][0] && !brk_;\ - argv[0]++) {\ - if (argv_ != argv)\ - break;\ - argc_ = argv[0][0];\ - switch (argc_) - -#define ARGEND }\ - } - -#define ARGC() argc_ - -#define EARGF(x) ((argv[0][1] == '\0' && argv[1] == NULL)?\ - ((x), abort(), (char *)0) :\ - (brk_ = 1, (argv[0][1] != '\0')?\ - (&argv[0][1]) :\ - (argc--, argv++, argv[0]))) - -#define ARGF() ((argv[0][1] == '\0' && argv[1] == NULL)?\ - (char *)0 :\ - (brk_ = 1, (argv[0][1] != '\0')?\ - (&argv[0][1]) :\ - (argc--, argv++, argv[0]))) - -#endif diff --git a/suckless/dmenu/config.def.h b/suckless/dmenu/config.def.h deleted file mode 100644 index 1edb647..0000000 --- a/suckless/dmenu/config.def.h +++ /dev/null @@ -1,23 +0,0 @@ -/* See LICENSE file for copyright and license details. */ -/* Default settings; can be overriden by command line. */ - -static int topbar = 1; /* -b option; if 0, dmenu appears at bottom */ -/* -fn option overrides fonts[0]; default X11 font or font set */ -static const char *fonts[] = { - "monospace:size=10" -}; -static const char *prompt = NULL; /* -p option; prompt to the left of input field */ -static const char *colors[SchemeLast][2] = { - /* fg bg */ - [SchemeNorm] = { "#bbbbbb", "#222222" }, - [SchemeSel] = { "#eeeeee", "#005577" }, - [SchemeOut] = { "#000000", "#00ffff" }, -}; -/* -l option; if nonzero, dmenu uses vertical list with given number of lines */ -static unsigned int lines = 0; - -/* - * Characters not considered part of a word while deleting words - * for example: " /?\"&[]" - */ -static const char worddelimiters[] = " "; diff --git a/suckless/dmenu/config.h b/suckless/dmenu/config.h deleted file mode 100644 index 1edb647..0000000 --- a/suckless/dmenu/config.h +++ /dev/null @@ -1,23 +0,0 @@ -/* See LICENSE file for copyright and license details. */ -/* Default settings; can be overriden by command line. */ - -static int topbar = 1; /* -b option; if 0, dmenu appears at bottom */ -/* -fn option overrides fonts[0]; default X11 font or font set */ -static const char *fonts[] = { - "monospace:size=10" -}; -static const char *prompt = NULL; /* -p option; prompt to the left of input field */ -static const char *colors[SchemeLast][2] = { - /* fg bg */ - [SchemeNorm] = { "#bbbbbb", "#222222" }, - [SchemeSel] = { "#eeeeee", "#005577" }, - [SchemeOut] = { "#000000", "#00ffff" }, -}; -/* -l option; if nonzero, dmenu uses vertical list with given number of lines */ -static unsigned int lines = 0; - -/* - * Characters not considered part of a word while deleting words - * for example: " /?\"&[]" - */ -static const char worddelimiters[] = " "; diff --git a/suckless/dmenu/config.mk b/suckless/dmenu/config.mk deleted file mode 100644 index 137f7c8..0000000 --- a/suckless/dmenu/config.mk +++ /dev/null @@ -1,32 +0,0 @@ -# dmenu version -VERSION = 5.3 - -# paths -PREFIX = /usr/local -MANPREFIX = $(PREFIX)/share/man - -X11INC = /usr/X11R6/include -X11LIB = /usr/X11R6/lib - -# Xinerama, comment if you don't want it -XINERAMALIBS = -lXinerama -XINERAMAFLAGS = -DXINERAMA - -# freetype -FREETYPELIBS = -lfontconfig -lXft -FREETYPEINC = /usr/include/freetype2 -# OpenBSD (uncomment) -#FREETYPEINC = $(X11INC)/freetype2 -#MANPREFIX = ${PREFIX}/man - -# includes and libs -INCS = -I$(X11INC) -I$(FREETYPEINC) -LIBS = -L$(X11LIB) -lX11 $(XINERAMALIBS) $(FREETYPELIBS) - -# flags -CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700 -D_POSIX_C_SOURCE=200809L -DVERSION=\"$(VERSION)\" $(XINERAMAFLAGS) -CFLAGS = -std=c99 -pedantic -Wall -Os $(INCS) $(CPPFLAGS) -LDFLAGS = $(LIBS) - -# compiler and linker -CC = cc diff --git a/suckless/dmenu/dmenu b/suckless/dmenu/dmenu deleted file mode 100755 index 28c9d8aba8111ef1e0c76c65faead57dcc84e44c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 42296 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 R>B>Lzs46ksP{6 -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#ifdef XINERAMA -#include -#endif -#include - -#include "drw.h" -#include "util.h" - -/* macros */ -#define INTERSECT(x,y,w,h,r) (MAX(0, MIN((x)+(w),(r).x_org+(r).width) - MAX((x),(r).x_org)) \ - * MAX(0, MIN((y)+(h),(r).y_org+(r).height) - MAX((y),(r).y_org))) -#define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad) - -/* enums */ -enum { SchemeNorm, SchemeSel, SchemeOut, SchemeLast }; /* color schemes */ - -struct item { - char *text; - struct item *left, *right; - int out; -}; - -static char text[BUFSIZ] = ""; -static char *embed; -static int bh, mw, mh; -static int inputw = 0, promptw; -static int lrpad; /* sum of left and right padding */ -static size_t cursor; -static struct item *items = NULL; -static struct item *matches, *matchend; -static struct item *prev, *curr, *next, *sel; -static int mon = -1, screen; - -static Atom clip, utf8; -static Display *dpy; -static Window root, parentwin, win; -static XIC xic; - -static Drw *drw; -static Clr *scheme[SchemeLast]; - -#include "config.h" - -static int (*fstrncmp)(const char *, const char *, size_t) = strncmp; -static char *(*fstrstr)(const char *, const char *) = strstr; - -static unsigned int -textw_clamp(const char *str, unsigned int n) -{ - unsigned int w = drw_fontset_getwidth_clamp(drw, str, n) + lrpad; - return MIN(w, n); -} - -static void -appenditem(struct item *item, struct item **list, struct item **last) -{ - if (*last) - (*last)->right = item; - else - *list = item; - - item->left = *last; - item->right = NULL; - *last = item; -} - -static void -calcoffsets(void) -{ - int i, n; - - if (lines > 0) - n = lines * bh; - else - n = mw - (promptw + inputw + TEXTW("<") + TEXTW(">")); - /* calculate which items will begin the next page and previous page */ - for (i = 0, next = curr; next; next = next->right) - if ((i += (lines > 0) ? bh : textw_clamp(next->text, n)) > n) - break; - for (i = 0, prev = curr; prev && prev->left; prev = prev->left) - if ((i += (lines > 0) ? bh : textw_clamp(prev->left->text, n)) > n) - break; -} - -static void -cleanup(void) -{ - size_t i; - - XUngrabKeyboard(dpy, CurrentTime); - for (i = 0; i < SchemeLast; i++) - free(scheme[i]); - for (i = 0; items && items[i].text; ++i) - free(items[i].text); - free(items); - drw_free(drw); - XSync(dpy, False); - XCloseDisplay(dpy); -} - -static char * -cistrstr(const char *h, const char *n) -{ - size_t i; - - if (!n[0]) - return (char *)h; - - for (; *h; ++h) { - for (i = 0; n[i] && tolower((unsigned char)n[i]) == - tolower((unsigned char)h[i]); ++i) - ; - if (n[i] == '\0') - return (char *)h; - } - return NULL; -} - -static int -drawitem(struct item *item, int x, int y, int w) -{ - if (item == sel) - drw_setscheme(drw, scheme[SchemeSel]); - else if (item->out) - drw_setscheme(drw, scheme[SchemeOut]); - else - drw_setscheme(drw, scheme[SchemeNorm]); - - return drw_text(drw, x, y, w, bh, lrpad / 2, item->text, 0); -} - -static void -drawmenu(void) -{ - unsigned int curpos; - struct item *item; - int x = 0, y = 0, w; - - drw_setscheme(drw, scheme[SchemeNorm]); - drw_rect(drw, 0, 0, mw, mh, 1, 1); - - if (prompt && *prompt) { - drw_setscheme(drw, scheme[SchemeSel]); - x = drw_text(drw, x, 0, promptw, bh, lrpad / 2, prompt, 0); - } - /* draw input field */ - w = (lines > 0 || !matches) ? mw - x : inputw; - drw_setscheme(drw, scheme[SchemeNorm]); - drw_text(drw, x, 0, w, bh, lrpad / 2, text, 0); - - curpos = TEXTW(text) - TEXTW(&text[cursor]); - if ((curpos += lrpad / 2 - 1) < w) { - drw_setscheme(drw, scheme[SchemeNorm]); - drw_rect(drw, x + curpos, 2, 2, bh - 4, 1, 0); - } - - if (lines > 0) { - /* draw vertical list */ - for (item = curr; item != next; item = item->right) - drawitem(item, x, y += bh, mw - x); - } else if (matches) { - /* draw horizontal list */ - x += inputw; - w = TEXTW("<"); - if (curr->left) { - drw_setscheme(drw, scheme[SchemeNorm]); - drw_text(drw, x, 0, w, bh, lrpad / 2, "<", 0); - } - x += w; - for (item = curr; item != next; item = item->right) - x = drawitem(item, x, 0, textw_clamp(item->text, mw - x - TEXTW(">"))); - if (next) { - w = TEXTW(">"); - drw_setscheme(drw, scheme[SchemeNorm]); - drw_text(drw, mw - w, 0, w, bh, lrpad / 2, ">", 0); - } - } - drw_map(drw, win, 0, 0, mw, mh); -} - -static void -grabfocus(void) -{ - struct timespec ts = { .tv_sec = 0, .tv_nsec = 10000000 }; - Window focuswin; - int i, revertwin; - - for (i = 0; i < 100; ++i) { - XGetInputFocus(dpy, &focuswin, &revertwin); - if (focuswin == win) - return; - XSetInputFocus(dpy, win, RevertToParent, CurrentTime); - nanosleep(&ts, NULL); - } - die("cannot grab focus"); -} - -static void -grabkeyboard(void) -{ - struct timespec ts = { .tv_sec = 0, .tv_nsec = 1000000 }; - int i; - - if (embed) - return; - /* try to grab keyboard, we may have to wait for another process to ungrab */ - for (i = 0; i < 1000; i++) { - if (XGrabKeyboard(dpy, DefaultRootWindow(dpy), True, GrabModeAsync, - GrabModeAsync, CurrentTime) == GrabSuccess) - return; - nanosleep(&ts, NULL); - } - die("cannot grab keyboard"); -} - -static void -match(void) -{ - static char **tokv = NULL; - static int tokn = 0; - - char buf[sizeof text], *s; - int i, tokc = 0; - size_t len, textsize; - struct item *item, *lprefix, *lsubstr, *prefixend, *substrend; - - strcpy(buf, text); - /* separate input text into tokens to be matched individually */ - for (s = strtok(buf, " "); s; tokv[tokc - 1] = s, s = strtok(NULL, " ")) - if (++tokc > tokn && !(tokv = realloc(tokv, ++tokn * sizeof *tokv))) - die("cannot realloc %zu bytes:", tokn * sizeof *tokv); - len = tokc ? strlen(tokv[0]) : 0; - - matches = lprefix = lsubstr = matchend = prefixend = substrend = NULL; - textsize = strlen(text) + 1; - for (item = items; item && item->text; item++) { - for (i = 0; i < tokc; i++) - if (!fstrstr(item->text, tokv[i])) - break; - if (i != tokc) /* not all tokens match */ - continue; - /* exact matches go first, then prefixes, then substrings */ - if (!tokc || !fstrncmp(text, item->text, textsize)) - appenditem(item, &matches, &matchend); - else if (!fstrncmp(tokv[0], item->text, len)) - appenditem(item, &lprefix, &prefixend); - else - appenditem(item, &lsubstr, &substrend); - } - if (lprefix) { - if (matches) { - matchend->right = lprefix; - lprefix->left = matchend; - } else - matches = lprefix; - matchend = prefixend; - } - if (lsubstr) { - if (matches) { - matchend->right = lsubstr; - lsubstr->left = matchend; - } else - matches = lsubstr; - matchend = substrend; - } - curr = sel = matches; - calcoffsets(); -} - -static void -insert(const char *str, ssize_t n) -{ - if (strlen(text) + n > sizeof text - 1) - return; - /* move existing text out of the way, insert new text, and update cursor */ - memmove(&text[cursor + n], &text[cursor], sizeof text - cursor - MAX(n, 0)); - if (n > 0) - memcpy(&text[cursor], str, n); - cursor += n; - match(); -} - -static size_t -nextrune(int inc) -{ - ssize_t n; - - /* return location of next utf8 rune in the given direction (+1 or -1) */ - for (n = cursor + inc; n + inc >= 0 && (text[n] & 0xc0) == 0x80; n += inc) - ; - return n; -} - -static void -movewordedge(int dir) -{ - if (dir < 0) { /* move cursor to the start of the word*/ - while (cursor > 0 && strchr(worddelimiters, text[nextrune(-1)])) - cursor = nextrune(-1); - while (cursor > 0 && !strchr(worddelimiters, text[nextrune(-1)])) - cursor = nextrune(-1); - } else { /* move cursor to the end of the word */ - while (text[cursor] && strchr(worddelimiters, text[cursor])) - cursor = nextrune(+1); - while (text[cursor] && !strchr(worddelimiters, text[cursor])) - cursor = nextrune(+1); - } -} - -static void -keypress(XKeyEvent *ev) -{ - char buf[64]; - int len; - KeySym ksym = NoSymbol; - Status status; - - len = XmbLookupString(xic, ev, buf, sizeof buf, &ksym, &status); - switch (status) { - default: /* XLookupNone, XBufferOverflow */ - return; - case XLookupChars: /* composed string from input method */ - goto insert; - case XLookupKeySym: - case XLookupBoth: /* a KeySym and a string are returned: use keysym */ - break; - } - - if (ev->state & ControlMask) { - switch(ksym) { - case XK_a: ksym = XK_Home; break; - case XK_b: ksym = XK_Left; break; - case XK_c: ksym = XK_Escape; break; - case XK_d: ksym = XK_Delete; break; - case XK_e: ksym = XK_End; break; - case XK_f: ksym = XK_Right; break; - case XK_g: ksym = XK_Escape; break; - case XK_h: ksym = XK_BackSpace; break; - case XK_i: ksym = XK_Tab; break; - case XK_j: /* fallthrough */ - case XK_J: /* fallthrough */ - case XK_m: /* fallthrough */ - case XK_M: ksym = XK_Return; ev->state &= ~ControlMask; break; - case XK_n: ksym = XK_Down; break; - case XK_p: ksym = XK_Up; break; - - case XK_k: /* delete right */ - text[cursor] = '\0'; - match(); - break; - case XK_u: /* delete left */ - insert(NULL, 0 - cursor); - break; - case XK_w: /* delete word */ - while (cursor > 0 && strchr(worddelimiters, text[nextrune(-1)])) - insert(NULL, nextrune(-1) - cursor); - while (cursor > 0 && !strchr(worddelimiters, text[nextrune(-1)])) - insert(NULL, nextrune(-1) - cursor); - break; - case XK_y: /* paste selection */ - case XK_Y: - XConvertSelection(dpy, (ev->state & ShiftMask) ? clip : XA_PRIMARY, - utf8, utf8, win, CurrentTime); - return; - case XK_Left: - case XK_KP_Left: - movewordedge(-1); - goto draw; - case XK_Right: - case XK_KP_Right: - movewordedge(+1); - goto draw; - case XK_Return: - case XK_KP_Enter: - break; - case XK_bracketleft: - cleanup(); - exit(1); - default: - return; - } - } else if (ev->state & Mod1Mask) { - switch(ksym) { - case XK_b: - movewordedge(-1); - goto draw; - case XK_f: - movewordedge(+1); - goto draw; - case XK_g: ksym = XK_Home; break; - case XK_G: ksym = XK_End; break; - case XK_h: ksym = XK_Up; break; - case XK_j: ksym = XK_Next; break; - case XK_k: ksym = XK_Prior; break; - case XK_l: ksym = XK_Down; break; - default: - return; - } - } - - switch(ksym) { - default: -insert: - if (!iscntrl((unsigned char)*buf)) - insert(buf, len); - break; - case XK_Delete: - case XK_KP_Delete: - if (text[cursor] == '\0') - return; - cursor = nextrune(+1); - /* fallthrough */ - case XK_BackSpace: - if (cursor == 0) - return; - insert(NULL, nextrune(-1) - cursor); - break; - case XK_End: - case XK_KP_End: - if (text[cursor] != '\0') { - cursor = strlen(text); - break; - } - if (next) { - /* jump to end of list and position items in reverse */ - curr = matchend; - calcoffsets(); - curr = prev; - calcoffsets(); - while (next && (curr = curr->right)) - calcoffsets(); - } - sel = matchend; - break; - case XK_Escape: - cleanup(); - exit(1); - case XK_Home: - case XK_KP_Home: - if (sel == matches) { - cursor = 0; - break; - } - sel = curr = matches; - calcoffsets(); - break; - case XK_Left: - case XK_KP_Left: - if (cursor > 0 && (!sel || !sel->left || lines > 0)) { - cursor = nextrune(-1); - break; - } - if (lines > 0) - return; - /* fallthrough */ - case XK_Up: - case XK_KP_Up: - if (sel && sel->left && (sel = sel->left)->right == curr) { - curr = prev; - calcoffsets(); - } - break; - case XK_Next: - case XK_KP_Next: - if (!next) - return; - sel = curr = next; - calcoffsets(); - break; - case XK_Prior: - case XK_KP_Prior: - if (!prev) - return; - sel = curr = prev; - calcoffsets(); - break; - case XK_Return: - case XK_KP_Enter: - puts((sel && !(ev->state & ShiftMask)) ? sel->text : text); - if (!(ev->state & ControlMask)) { - cleanup(); - exit(0); - } - if (sel) - sel->out = 1; - break; - case XK_Right: - case XK_KP_Right: - if (text[cursor] != '\0') { - cursor = nextrune(+1); - break; - } - if (lines > 0) - return; - /* fallthrough */ - case XK_Down: - case XK_KP_Down: - if (sel && sel->right && (sel = sel->right) == next) { - curr = next; - calcoffsets(); - } - break; - case XK_Tab: - if (!sel) - return; - cursor = strnlen(sel->text, sizeof text - 1); - memcpy(text, sel->text, cursor); - text[cursor] = '\0'; - match(); - break; - } - -draw: - drawmenu(); -} - -static void -paste(void) -{ - char *p, *q; - int di; - unsigned long dl; - Atom da; - - /* we have been given the current selection, now insert it into input */ - if (XGetWindowProperty(dpy, win, utf8, 0, (sizeof text / 4) + 1, False, - utf8, &da, &di, &dl, &dl, (unsigned char **)&p) - == Success && p) { - insert(p, (q = strchr(p, '\n')) ? q - p : (ssize_t)strlen(p)); - XFree(p); - } - drawmenu(); -} - -static void -readstdin(void) -{ - char *line = NULL; - size_t i, itemsiz = 0, linesiz = 0; - ssize_t len; - - /* read each line from stdin and add it to the item list */ - for (i = 0; (len = getline(&line, &linesiz, stdin)) != -1; i++) { - if (i + 1 >= itemsiz) { - itemsiz += 256; - if (!(items = realloc(items, itemsiz * sizeof(*items)))) - die("cannot realloc %zu bytes:", itemsiz * sizeof(*items)); - } - if (line[len - 1] == '\n') - line[len - 1] = '\0'; - if (!(items[i].text = strdup(line))) - die("strdup:"); - - items[i].out = 0; - } - free(line); - if (items) - items[i].text = NULL; - lines = MIN(lines, i); -} - -static void -run(void) -{ - XEvent ev; - - while (!XNextEvent(dpy, &ev)) { - if (XFilterEvent(&ev, win)) - continue; - switch(ev.type) { - case DestroyNotify: - if (ev.xdestroywindow.window != win) - break; - cleanup(); - exit(1); - case Expose: - if (ev.xexpose.count == 0) - drw_map(drw, win, 0, 0, mw, mh); - break; - case FocusIn: - /* regrab focus from parent window */ - if (ev.xfocus.window != win) - grabfocus(); - break; - case KeyPress: - keypress(&ev.xkey); - break; - case SelectionNotify: - if (ev.xselection.property == utf8) - paste(); - break; - case VisibilityNotify: - if (ev.xvisibility.state != VisibilityUnobscured) - XRaiseWindow(dpy, win); - break; - } - } -} - -static void -setup(void) -{ - int x, y, i, j; - unsigned int du; - XSetWindowAttributes swa; - XIM xim; - Window w, dw, *dws; - XWindowAttributes wa; - XClassHint ch = {"dmenu", "dmenu"}; -#ifdef XINERAMA - XineramaScreenInfo *info; - Window pw; - int a, di, n, area = 0; -#endif - /* init appearance */ - for (j = 0; j < SchemeLast; j++) - scheme[j] = drw_scm_create(drw, colors[j], 2); - - clip = XInternAtom(dpy, "CLIPBOARD", False); - utf8 = XInternAtom(dpy, "UTF8_STRING", False); - - /* calculate menu geometry */ - bh = drw->fonts->h + 2; - lines = MAX(lines, 0); - mh = (lines + 1) * bh; -#ifdef XINERAMA - i = 0; - if (parentwin == root && (info = XineramaQueryScreens(dpy, &n))) { - XGetInputFocus(dpy, &w, &di); - if (mon >= 0 && mon < n) - i = mon; - else if (w != root && w != PointerRoot && w != None) { - /* find top-level window containing current input focus */ - do { - if (XQueryTree(dpy, (pw = w), &dw, &w, &dws, &du) && dws) - XFree(dws); - } while (w != root && w != pw); - /* find xinerama screen with which the window intersects most */ - if (XGetWindowAttributes(dpy, pw, &wa)) - for (j = 0; j < n; j++) - if ((a = INTERSECT(wa.x, wa.y, wa.width, wa.height, info[j])) > area) { - area = a; - i = j; - } - } - /* no focused window is on screen, so use pointer location instead */ - if (mon < 0 && !area && XQueryPointer(dpy, root, &dw, &dw, &x, &y, &di, &di, &du)) - for (i = 0; i < n; i++) - if (INTERSECT(x, y, 1, 1, info[i]) != 0) - break; - - x = info[i].x_org; - y = info[i].y_org + (topbar ? 0 : info[i].height - mh); - mw = info[i].width; - XFree(info); - } else -#endif - { - if (!XGetWindowAttributes(dpy, parentwin, &wa)) - die("could not get embedding window attributes: 0x%lx", - parentwin); - x = 0; - y = topbar ? 0 : wa.height - mh; - mw = wa.width; - } - promptw = (prompt && *prompt) ? TEXTW(prompt) - lrpad / 4 : 0; - inputw = mw / 3; /* input width: ~33% of monitor width */ - match(); - - /* create menu window */ - swa.override_redirect = True; - swa.background_pixel = scheme[SchemeNorm][ColBg].pixel; - swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask; - win = XCreateWindow(dpy, root, x, y, mw, mh, 0, - CopyFromParent, CopyFromParent, CopyFromParent, - CWOverrideRedirect | CWBackPixel | CWEventMask, &swa); - XSetClassHint(dpy, win, &ch); - - /* input methods */ - if ((xim = XOpenIM(dpy, NULL, NULL, NULL)) == NULL) - die("XOpenIM failed: could not open input device"); - - xic = XCreateIC(xim, XNInputStyle, XIMPreeditNothing | XIMStatusNothing, - XNClientWindow, win, XNFocusWindow, win, NULL); - - XMapRaised(dpy, win); - if (embed) { - XReparentWindow(dpy, win, parentwin, x, y); - XSelectInput(dpy, parentwin, FocusChangeMask | SubstructureNotifyMask); - if (XQueryTree(dpy, parentwin, &dw, &w, &dws, &du) && dws) { - for (i = 0; i < du && dws[i] != win; ++i) - XSelectInput(dpy, dws[i], FocusChangeMask); - XFree(dws); - } - grabfocus(); - } - drw_resize(drw, mw, mh); - drawmenu(); -} - -static void -usage(void) -{ - die("usage: dmenu [-bfiv] [-l lines] [-p prompt] [-fn font] [-m monitor]\n" - " [-nb color] [-nf color] [-sb color] [-sf color] [-w windowid]"); -} - -int -main(int argc, char *argv[]) -{ - XWindowAttributes wa; - int i, fast = 0; - - for (i = 1; i < argc; i++) - /* these options take no arguments */ - if (!strcmp(argv[i], "-v")) { /* prints version information */ - puts("dmenu-"VERSION); - exit(0); - } else if (!strcmp(argv[i], "-b")) /* appears at the bottom of the screen */ - topbar = 0; - else if (!strcmp(argv[i], "-f")) /* grabs keyboard before reading stdin */ - fast = 1; - else if (!strcmp(argv[i], "-i")) { /* case-insensitive item matching */ - fstrncmp = strncasecmp; - fstrstr = cistrstr; - } else if (i + 1 == argc) - usage(); - /* these options take one argument */ - else if (!strcmp(argv[i], "-l")) /* number of lines in vertical list */ - lines = atoi(argv[++i]); - else if (!strcmp(argv[i], "-m")) - mon = atoi(argv[++i]); - else if (!strcmp(argv[i], "-p")) /* adds prompt to left of input field */ - prompt = argv[++i]; - else if (!strcmp(argv[i], "-fn")) /* font or font set */ - fonts[0] = argv[++i]; - else if (!strcmp(argv[i], "-nb")) /* normal background color */ - colors[SchemeNorm][ColBg] = argv[++i]; - else if (!strcmp(argv[i], "-nf")) /* normal foreground color */ - colors[SchemeNorm][ColFg] = argv[++i]; - else if (!strcmp(argv[i], "-sb")) /* selected background color */ - colors[SchemeSel][ColBg] = argv[++i]; - else if (!strcmp(argv[i], "-sf")) /* selected foreground color */ - colors[SchemeSel][ColFg] = argv[++i]; - else if (!strcmp(argv[i], "-w")) /* embedding window id */ - embed = argv[++i]; - else - usage(); - - if (!setlocale(LC_CTYPE, "") || !XSupportsLocale()) - fputs("warning: no locale support\n", stderr); - if (!(dpy = XOpenDisplay(NULL))) - die("cannot open display"); - screen = DefaultScreen(dpy); - root = RootWindow(dpy, screen); - if (!embed || !(parentwin = strtol(embed, NULL, 0))) - parentwin = root; - if (!XGetWindowAttributes(dpy, parentwin, &wa)) - die("could not get embedding window attributes: 0x%lx", - parentwin); - drw = drw_create(dpy, screen, root, wa.width, wa.height); - if (!drw_fontset_create(drw, fonts, LENGTH(fonts))) - die("no fonts could be loaded."); - lrpad = drw->fonts->h; - -#ifdef __OpenBSD__ - if (pledge("stdio rpath", NULL) == -1) - die("pledge"); -#endif - - if (fast && !isatty(0)) { - grabkeyboard(); - readstdin(); - } else { - readstdin(); - grabkeyboard(); - } - setup(); - run(); - - return 1; /* unreachable */ -} diff --git a/suckless/dmenu/dmenu.o b/suckless/dmenu/dmenu.o deleted file mode 100644 index 7028ae2daa555d11717602f0a2abc65b6437e531..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32232 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 -#include -#include -#include -#include - -#include "drw.h" -#include "util.h" - -#define UTF_INVALID 0xFFFD - -static int -utf8decode(const char *s_in, long *u, int *err) -{ - static const unsigned char lens[] = { - /* 0XXXX */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - /* 10XXX */ 0, 0, 0, 0, 0, 0, 0, 0, /* invalid */ - /* 110XX */ 2, 2, 2, 2, - /* 1110X */ 3, 3, - /* 11110 */ 4, - /* 11111 */ 0, /* invalid */ - }; - static const unsigned char leading_mask[] = { 0x7F, 0x1F, 0x0F, 0x07 }; - static const unsigned int overlong[] = { 0x0, 0x80, 0x0800, 0x10000 }; - - const unsigned char *s = (const unsigned char *)s_in; - int len = lens[*s >> 3]; - *u = UTF_INVALID; - *err = 1; - if (len == 0) - return 1; - - long cp = s[0] & leading_mask[len - 1]; - for (int i = 1; i < len; ++i) { - if (s[i] == '\0' || (s[i] & 0xC0) != 0x80) - return i; - cp = (cp << 6) | (s[i] & 0x3F); - } - /* out of range, surrogate, overlong encoding */ - if (cp > 0x10FFFF || (cp >> 11) == 0x1B || cp < overlong[len - 1]) - return len; - - *err = 0; - *u = cp; - return len; -} - -Drw * -drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h) -{ - Drw *drw = ecalloc(1, sizeof(Drw)); - - drw->dpy = dpy; - drw->screen = screen; - drw->root = root; - drw->w = w; - drw->h = h; - drw->drawable = XCreatePixmap(dpy, root, w, h, DefaultDepth(dpy, screen)); - drw->gc = XCreateGC(dpy, root, 0, NULL); - XSetLineAttributes(dpy, drw->gc, 1, LineSolid, CapButt, JoinMiter); - - return drw; -} - -void -drw_resize(Drw *drw, unsigned int w, unsigned int h) -{ - if (!drw) - return; - - drw->w = w; - drw->h = h; - if (drw->drawable) - XFreePixmap(drw->dpy, drw->drawable); - drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, DefaultDepth(drw->dpy, drw->screen)); -} - -void -drw_free(Drw *drw) -{ - XFreePixmap(drw->dpy, drw->drawable); - XFreeGC(drw->dpy, drw->gc); - drw_fontset_free(drw->fonts); - free(drw); -} - -/* This function is an implementation detail. Library users should use - * drw_fontset_create instead. - */ -static Fnt * -xfont_create(Drw *drw, const char *fontname, FcPattern *fontpattern) -{ - Fnt *font; - XftFont *xfont = NULL; - FcPattern *pattern = NULL; - - if (fontname) { - /* Using the pattern found at font->xfont->pattern does not yield the - * same substitution results as using the pattern returned by - * FcNameParse; using the latter results in the desired fallback - * behaviour whereas the former just results in missing-character - * rectangles being drawn, at least with some fonts. */ - if (!(xfont = XftFontOpenName(drw->dpy, drw->screen, fontname))) { - fprintf(stderr, "error, cannot load font from name: '%s'\n", fontname); - return NULL; - } - if (!(pattern = FcNameParse((FcChar8 *) fontname))) { - fprintf(stderr, "error, cannot parse font name to pattern: '%s'\n", fontname); - XftFontClose(drw->dpy, xfont); - return NULL; - } - } else if (fontpattern) { - if (!(xfont = XftFontOpenPattern(drw->dpy, fontpattern))) { - fprintf(stderr, "error, cannot load font from pattern.\n"); - return NULL; - } - } else { - die("no font specified."); - } - - font = ecalloc(1, sizeof(Fnt)); - font->xfont = xfont; - font->pattern = pattern; - font->h = xfont->ascent + xfont->descent; - font->dpy = drw->dpy; - - return font; -} - -static void -xfont_free(Fnt *font) -{ - if (!font) - return; - if (font->pattern) - FcPatternDestroy(font->pattern); - XftFontClose(font->dpy, font->xfont); - free(font); -} - -Fnt* -drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount) -{ - Fnt *cur, *ret = NULL; - size_t i; - - if (!drw || !fonts) - return NULL; - - for (i = 1; i <= fontcount; i++) { - if ((cur = xfont_create(drw, fonts[fontcount - i], NULL))) { - cur->next = ret; - ret = cur; - } - } - return (drw->fonts = ret); -} - -void -drw_fontset_free(Fnt *font) -{ - if (font) { - drw_fontset_free(font->next); - xfont_free(font); - } -} - -void -drw_clr_create(Drw *drw, Clr *dest, const char *clrname) -{ - if (!drw || !dest || !clrname) - return; - - if (!XftColorAllocName(drw->dpy, DefaultVisual(drw->dpy, drw->screen), - DefaultColormap(drw->dpy, drw->screen), - clrname, dest)) - die("error, cannot allocate color '%s'", clrname); -} - -/* Wrapper to create color schemes. The caller has to call free(3) on the - * returned color scheme when done using it. */ -Clr * -drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount) -{ - size_t i; - Clr *ret; - - /* need at least two colors for a scheme */ - if (!drw || !clrnames || clrcount < 2 || !(ret = ecalloc(clrcount, sizeof(XftColor)))) - return NULL; - - for (i = 0; i < clrcount; i++) - drw_clr_create(drw, &ret[i], clrnames[i]); - return ret; -} - -void -drw_setfontset(Drw *drw, Fnt *set) -{ - if (drw) - drw->fonts = set; -} - -void -drw_setscheme(Drw *drw, Clr *scm) -{ - if (drw) - drw->scheme = scm; -} - -void -drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert) -{ - if (!drw || !drw->scheme) - return; - XSetForeground(drw->dpy, drw->gc, invert ? drw->scheme[ColBg].pixel : drw->scheme[ColFg].pixel); - if (filled) - XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h); - else - XDrawRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w - 1, h - 1); -} - -int -drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert) -{ - int ty, ellipsis_x = 0; - unsigned int tmpw, ew, ellipsis_w = 0, ellipsis_len, hash, h0, h1; - XftDraw *d = NULL; - Fnt *usedfont, *curfont, *nextfont; - int utf8strlen, utf8charlen, utf8err, render = x || y || w || h; - long utf8codepoint = 0; - const char *utf8str; - FcCharSet *fccharset; - FcPattern *fcpattern; - FcPattern *match; - XftResult result; - int charexists = 0, overflow = 0; - /* keep track of a couple codepoints for which we have no match. */ - static unsigned int nomatches[128], ellipsis_width, invalid_width; - static const char invalid[] = "�"; - - if (!drw || (render && (!drw->scheme || !w)) || !text || !drw->fonts) - return 0; - - if (!render) { - w = invert ? invert : ~invert; - } else { - XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].pixel); - XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h); - if (w < lpad) - return x + w; - d = XftDrawCreate(drw->dpy, drw->drawable, - DefaultVisual(drw->dpy, drw->screen), - DefaultColormap(drw->dpy, drw->screen)); - x += lpad; - w -= lpad; - } - - usedfont = drw->fonts; - if (!ellipsis_width && render) - ellipsis_width = drw_fontset_getwidth(drw, "..."); - if (!invalid_width && render) - invalid_width = drw_fontset_getwidth(drw, invalid); - while (1) { - ew = ellipsis_len = utf8err = utf8charlen = utf8strlen = 0; - utf8str = text; - nextfont = NULL; - while (*text) { - utf8charlen = utf8decode(text, &utf8codepoint, &utf8err); - for (curfont = drw->fonts; curfont; curfont = curfont->next) { - charexists = charexists || XftCharExists(drw->dpy, curfont->xfont, utf8codepoint); - if (charexists) { - drw_font_getexts(curfont, text, utf8charlen, &tmpw, NULL); - if (ew + ellipsis_width <= w) { - /* keep track where the ellipsis still fits */ - ellipsis_x = x + ew; - ellipsis_w = w - ew; - ellipsis_len = utf8strlen; - } - - if (ew + tmpw > w) { - overflow = 1; - /* called from drw_fontset_getwidth_clamp(): - * it wants the width AFTER the overflow - */ - if (!render) - x += tmpw; - else - utf8strlen = ellipsis_len; - } else if (curfont == usedfont) { - text += utf8charlen; - utf8strlen += utf8err ? 0 : utf8charlen; - ew += utf8err ? 0 : tmpw; - } else { - nextfont = curfont; - } - break; - } - } - - if (overflow || !charexists || nextfont || utf8err) - break; - else - charexists = 0; - } - - if (utf8strlen) { - if (render) { - ty = y + (h - usedfont->h) / 2 + usedfont->xfont->ascent; - XftDrawStringUtf8(d, &drw->scheme[invert ? ColBg : ColFg], - usedfont->xfont, x, ty, (XftChar8 *)utf8str, utf8strlen); - } - x += ew; - w -= ew; - } - if (utf8err && (!render || invalid_width < w)) { - if (render) - drw_text(drw, x, y, w, h, 0, invalid, invert); - x += invalid_width; - w -= invalid_width; - } - if (render && overflow) - drw_text(drw, ellipsis_x, y, ellipsis_w, h, 0, "...", invert); - - if (!*text || overflow) { - break; - } else if (nextfont) { - charexists = 0; - usedfont = nextfont; - } else { - /* Regardless of whether or not a fallback font is found, the - * character must be drawn. */ - charexists = 1; - - hash = (unsigned int)utf8codepoint; - hash = ((hash >> 16) ^ hash) * 0x21F0AAAD; - hash = ((hash >> 15) ^ hash) * 0xD35A2D97; - h0 = ((hash >> 15) ^ hash) % LENGTH(nomatches); - h1 = (hash >> 17) % LENGTH(nomatches); - /* avoid expensive XftFontMatch call when we know we won't find a match */ - if (nomatches[h0] == utf8codepoint || nomatches[h1] == utf8codepoint) - goto no_match; - - fccharset = FcCharSetCreate(); - FcCharSetAddChar(fccharset, utf8codepoint); - - if (!drw->fonts->pattern) { - /* Refer to the comment in xfont_create for more information. */ - die("the first font in the cache must be loaded from a font string."); - } - - fcpattern = FcPatternDuplicate(drw->fonts->pattern); - FcPatternAddCharSet(fcpattern, FC_CHARSET, fccharset); - FcPatternAddBool(fcpattern, FC_SCALABLE, FcTrue); - - FcConfigSubstitute(NULL, fcpattern, FcMatchPattern); - FcDefaultSubstitute(fcpattern); - match = XftFontMatch(drw->dpy, drw->screen, fcpattern, &result); - - FcCharSetDestroy(fccharset); - FcPatternDestroy(fcpattern); - - if (match) { - usedfont = xfont_create(drw, NULL, match); - if (usedfont && XftCharExists(drw->dpy, usedfont->xfont, utf8codepoint)) { - for (curfont = drw->fonts; curfont->next; curfont = curfont->next) - ; /* NOP */ - curfont->next = usedfont; - } else { - xfont_free(usedfont); - nomatches[nomatches[h0] ? h1 : h0] = utf8codepoint; -no_match: - usedfont = drw->fonts; - } - } - } - } - if (d) - XftDrawDestroy(d); - - return x + (render ? w : 0); -} - -void -drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h) -{ - if (!drw) - return; - - XCopyArea(drw->dpy, drw->drawable, win, drw->gc, x, y, w, h, x, y); - XSync(drw->dpy, False); -} - -unsigned int -drw_fontset_getwidth(Drw *drw, const char *text) -{ - if (!drw || !drw->fonts || !text) - return 0; - return drw_text(drw, 0, 0, 0, 0, 0, text, 0); -} - -unsigned int -drw_fontset_getwidth_clamp(Drw *drw, const char *text, unsigned int n) -{ - unsigned int tmp = 0; - if (drw && drw->fonts && text && n) - tmp = drw_text(drw, 0, 0, 0, 0, 0, text, n); - return MIN(n, tmp); -} - -void -drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h) -{ - XGlyphInfo ext; - - if (!font || !text) - return; - - XftTextExtentsUtf8(font->dpy, font->xfont, (XftChar8 *)text, len, &ext); - if (w) - *w = ext.xOff; - if (h) - *h = font->h; -} - -Cur * -drw_cur_create(Drw *drw, int shape) -{ - Cur *cur; - - if (!drw || !(cur = ecalloc(1, sizeof(Cur)))) - return NULL; - - cur->cursor = XCreateFontCursor(drw->dpy, shape); - - return cur; -} - -void -drw_cur_free(Drw *drw, Cur *cursor) -{ - if (!cursor) - return; - - XFreeCursor(drw->dpy, cursor->cursor); - free(cursor); -} diff --git a/suckless/dmenu/drw.h b/suckless/dmenu/drw.h deleted file mode 100644 index fd7631b..0000000 --- a/suckless/dmenu/drw.h +++ /dev/null @@ -1,58 +0,0 @@ -/* See LICENSE file for copyright and license details. */ - -typedef struct { - Cursor cursor; -} Cur; - -typedef struct Fnt { - Display *dpy; - unsigned int h; - XftFont *xfont; - FcPattern *pattern; - struct Fnt *next; -} Fnt; - -enum { ColFg, ColBg }; /* Clr scheme index */ -typedef XftColor Clr; - -typedef struct { - unsigned int w, h; - Display *dpy; - int screen; - Window root; - Drawable drawable; - GC gc; - Clr *scheme; - Fnt *fonts; -} Drw; - -/* Drawable abstraction */ -Drw *drw_create(Display *dpy, int screen, Window win, unsigned int w, unsigned int h); -void drw_resize(Drw *drw, unsigned int w, unsigned int h); -void drw_free(Drw *drw); - -/* Fnt abstraction */ -Fnt *drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount); -void drw_fontset_free(Fnt* set); -unsigned int drw_fontset_getwidth(Drw *drw, const char *text); -unsigned int drw_fontset_getwidth_clamp(Drw *drw, const char *text, unsigned int n); -void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h); - -/* Colorscheme abstraction */ -void drw_clr_create(Drw *drw, Clr *dest, const char *clrname); -Clr *drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount); - -/* Cursor abstraction */ -Cur *drw_cur_create(Drw *drw, int shape); -void drw_cur_free(Drw *drw, Cur *cursor); - -/* Drawing context manipulation */ -void drw_setfontset(Drw *drw, Fnt *set); -void drw_setscheme(Drw *drw, Clr *scm); - -/* Drawing functions */ -void drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert); -int drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert); - -/* Map functions */ -void drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h); diff --git a/suckless/dmenu/drw.o b/suckless/dmenu/drw.o deleted file mode 100644 index 69dbfa9f910b2da334855d573d810016a6cee0e0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11464 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 TbCK}Az4Z=B(Roci-Q)ikvLk1R diff --git a/suckless/dmenu/stest b/suckless/dmenu/stest deleted file mode 100755 index 344348c8b4475cfa76e784684ed48abf70241fb0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16288 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 -© 2007-2011 Peter Hartlich -© 2007-2009 Szabolcs Nagy -© 2007-2009 Christof Musik -© 2007-2009 Premysl Hruby -© 2007-2008 Enno Gottox Boland -© 2008 Martin Hurton -© 2008 Neale Pickett -© 2009 Mate Nagy -© 2010-2016 Hiltjo Posthuma -© 2010-2012 Connor Lane Smith -© 2011 Christoph Lohmann <20h@r-36.net> -© 2015-2016 Quentin Rameau -© 2015-2016 Eric Pruitt -© 2016-2017 Markus Teich -© 2020-2022 Chris Down - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the "Software"), -to deal in the Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. diff --git a/suckless/dwm/Makefile b/suckless/dwm/Makefile deleted file mode 100644 index ffa69b4..0000000 --- a/suckless/dwm/Makefile +++ /dev/null @@ -1,45 +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: dwm - -.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 clean dist install uninstall diff --git a/suckless/dwm/README b/suckless/dwm/README deleted file mode 100644 index 95d4fd0..0000000 --- a/suckless/dwm/README +++ /dev/null @@ -1,48 +0,0 @@ -dwm - dynamic window manager -============================ -dwm is an extremely fast, small, and dynamic window manager for X. - - -Requirements ------------- -In order to build dwm you need the Xlib header files. - - -Installation ------------- -Edit config.mk to match your local setup (dwm is installed into -the /usr/local namespace by default). - -Afterwards enter the following command to build and install dwm (if -necessary as root): - - make clean install - - -Running dwm ------------ -Add the following line to your .xinitrc to start dwm using startx: - - exec dwm - -In order to connect dwm to a specific display, make sure that -the DISPLAY environment variable is set correctly, e.g.: - - DISPLAY=foo.bar:1 exec dwm - -(This will start dwm on display :1 of the host foo.bar.) - -In order to display status info in the bar, you can do something -like this in your .xinitrc: - - while xsetroot -name "`date` `uptime | sed 's/.*,//'`" - do - sleep 1 - done & - exec dwm - - -Configuration -------------- -The configuration of dwm is done by creating a custom config.h -and (re)compiling the source code. diff --git a/suckless/dwm/README.md b/suckless/dwm/README.md deleted file mode 100644 index 70e3d98..0000000 --- a/suckless/dwm/README.md +++ /dev/null @@ -1,30 +0,0 @@ -## DWM -This is one of my favorite window managers, it's great - very customizable. -Credits to Swindles McCoop on Github and YouTube, I've cloned their dwm build and made my own configurations to it. - -## Compiling -### Dependencies -X11, Xinerama, xcb, freetype, rofi, slock, Alacritty -### Instructions -Run `./configure` to properly set up `config.mk`. -#### Linux -`make && sudo make install` -#### BSD -`gmake && doas gmake install` - -## Keybinds: -- `MODKEY + Enter` - Spawn Alacritty (MUST BE INSTALLED) -- `MODKEY + Shift + Enter`, `F12` - Toggle scratchpad terminal -- `MODKEY + r` - Rofi (MUST BE INSTALLED) -- `MODKEY + s` - Kill window -- `MODKEY + m` - Toggle status bar -- `MODKEY + f` - Toggle fullscreen -- `MODKEY + o/O` - Increase/decrease number of masters -- `MODKEY + j/k` - Move focus down/up -- `MODKEY + J/K` - Move window in stack down/up -- `MODKEY + SHIFTMASK + q` - Kill DWM -- `MODKEY + Space` - Set all windows to Floating mode -- `MODKEY + K/J` - Change focused window in on the direction of K/J on a qwerty keyboard -- `MODKEY + SHIFTMASK + K/J` - Move window in on the direction of K/J on a qwerty keyboard -- `MODKEY + H/L` - Expand/shrink master window in direction of H/L on a qwerty keyboard -- `MODKEY + SHIFTMASK + L` - Lock using slock (MUST BE INSTALLED) \ No newline at end of file diff --git a/suckless/dwm/attachaside.diff b/suckless/dwm/attachaside.diff deleted file mode 100644 index 2f34ac2..0000000 --- a/suckless/dwm/attachaside.diff +++ /dev/null @@ -1,93 +0,0 @@ -diff --git a/dwm.c b/dwm.c -index f1d86b2..8b04e0b 100644 ---- a/dwm.c -+++ b/dwm.c -@@ -49,7 +49,8 @@ - #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 ISVISIBLEONTAG(C, T) ((C->tags & T)) -+#define ISVISIBLE(C) ISVISIBLEONTAG(C, 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) -@@ -147,6 +148,7 @@ static int applysizehints(Client *c, int *x, int *y, int *w, int *h, int interac - static void arrange(Monitor *m); - static void arrangemon(Monitor *m); - static void attach(Client *c); -+static void attachaside(Client *c); - static void attachstack(Client *c); - static void buttonpress(XEvent *e); - static void checkotherwm(void); -@@ -184,6 +186,7 @@ static void maprequest(XEvent *e); - static void monocle(Monitor *m); - static void motionnotify(XEvent *e); - static void movemouse(const Arg *arg); -+static Client *nexttagged(Client *c); - static Client *nexttiled(Client *c); - static void pop(Client *c); - static void propertynotify(XEvent *e); -@@ -408,6 +411,17 @@ attach(Client *c) - c->mon->clients = c; - } - -+void -+attachaside(Client *c) { -+ Client *at = nexttagged(c); -+ if(!at) { -+ attach(c); -+ return; -+ } -+ c->next = at->next; -+ at->next = c; -+} -+ - void - attachstack(Client *c) - { -@@ -1074,7 +1088,7 @@ manage(Window w, XWindowAttributes *wa) - c->isfloating = c->oldstate = trans != None || c->isfixed; - if (c->isfloating) - XRaiseWindow(dpy, c->win); -- attach(c); -+ attachaside(c); - attachstack(c); - XChangeProperty(dpy, root, netatom[NetClientList], XA_WINDOW, 32, PropModeAppend, - (unsigned char *) &(c->win), 1); -@@ -1202,6 +1216,16 @@ movemouse(const Arg *arg) - } - } - -+Client * -+nexttagged(Client *c) { -+ Client *walked = c->mon->clients; -+ for(; -+ walked && (walked->isfloating || !ISVISIBLEONTAG(walked, c->tags)); -+ walked = walked->next -+ ); -+ return walked; -+} -+ - Client * - nexttiled(Client *c) - { -@@ -1427,7 +1451,7 @@ sendmon(Client *c, Monitor *m) - detachstack(c); - c->mon = m; - c->tags = m->tagset[m->seltags]; /* assign tags of target monitor */ -- attach(c); -+ attachaside(c); - attachstack(c); - focus(NULL); - arrange(NULL); -@@ -1915,7 +1939,7 @@ updategeom(void) - m->clients = c->next; - detachstack(c); - c->mon = mons; -- attach(c); -+ attachaside(c); - attachstack(c); - } - if (m == selmon) - diff --git a/suckless/dwm/config.def.h b/suckless/dwm/config.def.h deleted file mode 100644 index ac4674b..0000000 --- a/suckless/dwm/config.def.h +++ /dev/null @@ -1,129 +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 = 14; /* gaps between windows */ -static const unsigned int snap = 3; /* snap pixel */ -static const int user_bh = 12; /* 2 is the default spacing around the bar's font */ -static const int showbar = 1; /* 0 means no bar */ -static const int topbar = 1; /* 0 means bottom bar */ -static const int vertpad = 10; /* vertical padding of bar */ -static const int sidepad = 16; /* horizontal padding of bar */ -static const char *fonts[] = {"CaskaydiaMonoNerdFont-Bold:size=9.2"}; -static const char dmenufont[] = "CaskaydiaMonoNerdFont-Bold:size=10.6"; -static char normbgcolor[] = "#222222"; -static char normbordercolor[] = "#444444"; -static char normfgcolor[] = "#bbbbbb"; -static char selfgcolor[] = "#eeeeee"; -static char selbordercolor[] = "#005577"; -static char selbgcolor[] = "#005577"; -static char *colors[][3] = { - /* fg bg border */ - [SchemeNorm] = { normfgcolor, normbgcolor, normbordercolor }, - [SchemeSel] = { selfgcolor, selbgcolor, selbordercolor }, -}; - -/* tagging */ -static const char *tags[] = { "","","","","", }; - -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, 0, -1 }, -}; - -/* layout(s) */ -static const float mfact = 0.50; /* factor of master area size [0.05..0.95] */ -static const int nmaster = 1; /* number of clients in master area */ -static const int resizehints = 0; /* 1 means respect size hints in tiled resizals */ -static const int lockfullscreen = 1; /* 1 will force focus on the fullscreen window */ - -static const Layout layouts[] = { - /* symbol arrange function */ - {"", tile}, /* first entry is default */ - {"󰭩", NULL}, /* no layout function means floating behavior */ - {"", monocle}, -}; - - - -/* key definitions */ -#define MODKEY Mod4Mask -#define TAGKEYS(KEY,TAG) \ - { MODKEY, KEY, view, {.ui = 1 << TAG} }, \ - { MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG} }, \ - { MODKEY|ShiftMask, KEY, tag, {.ui = 1 << TAG} }, \ - { MODKEY|ControlMask|ShiftMask, KEY, toggletag, {.ui = 1 << TAG} }, - -/* helper for spawning shell commands in the pre dwm-5.0 fashion */ -#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } } - -/* commands */ -static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */ -static const char *dmenucmd[] = { "dmenu_run", "-fn", dmenufont, "-nb", normbgcolor, "-nf", normfgcolor, "-sb", selbordercolor, "-sf", selfgcolor, NULL }; -static const char *termcmd[] = {"bash", "-c", "st -e bash & walrs -R -q ",NULL}; - -#include "movestack.c" -static const Key keys[] = { - /* modifier key function argument */ - { MODKEY, XK_n, xrdb, {.v = NULL } }, - { 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|ShiftMask, XK_j, movestack, {.i = +1 } }, - { MODKEY|ShiftMask, XK_k, movestack, {.i = -1 } }, - { MODKEY, XK_Return, zoom, {0} }, - { MODKEY, XK_Tab, view, {0} }, - { MODKEY|ShiftMask, XK_c, killclient, {0} }, - { MODKEY, XK_t, setlayout, {.v = &layouts[0]} }, - { MODKEY, XK_f, setlayout, {.v = &layouts[1]} }, - { MODKEY, XK_m, setlayout, {.v = &layouts[2]} }, - { MODKEY, XK_space, setlayout, {0} }, - { MODKEY|ShiftMask, XK_space, togglefloating, {0} }, - { MODKEY, XK_0, view, {.ui = ~0 } }, - { MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } }, - { MODKEY, XK_comma, focusmon, {.i = -1 } }, - { MODKEY, XK_period, focusmon, {.i = +1 } }, - { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } }, - { MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } }, - { MODKEY, XK_minus, setgaps, {.i = -1 } }, - { MODKEY, XK_equal, setgaps, {.i = +1 } }, - { MODKEY|ShiftMask, XK_equal, setgaps, {.i = 0 } }, - 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} }, - { MODKEY|ControlMask|ShiftMask, XK_q, quit, {1} }, -}; - -/* button definitions */ -/* click can be ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */ -static const Button buttons[] = { - /* click event mask button function argument */ - { ClkLtSymbol, 0, Button1, setlayout, {0} }, - { ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} }, - { 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/suckless/dwm/config.h b/suckless/dwm/config.h deleted file mode 100644 index 3878b2b..0000000 --- a/suckless/dwm/config.h +++ /dev/null @@ -1,164 +0,0 @@ -/* See LICENSE file for copyright and license details. */ - -/* appearance */ -static const unsigned int borderpx = 2.5; /* border pixel of windows */ -static const unsigned int gappx = 14; /* gaps between windows */ -static const unsigned int snap = 3; /* snap pixel */ -static const int user_bh = 12; /* 2 is the default spacing around the bar's font */ -static const int showbar = 1; /* 0 means no bar */ -static const int topbar = 0; /* 0 means bottom bar */ -static const int vertpad = 10; /* vertical padding of bar */ -static const int sidepad = 400; /* horizontal padding of bar */ -static const char *fonts[] = {"CaskaydiaMonoNerdFont-Bold:size=9.2"}; -static const char dmenufont[] = "CaskaydiaMonoNerdFont-Bold:size=10.6"; -static char normbgcolor[] = "#222222"; -static char normbordercolor[] = "#444444"; -static char normfgcolor[] = "#bbbbbb"; -static char selfgcolor[] = "#222222"; -static char selbordercolor[] = "#555555"; -static char selbgcolor[] = "#DB940A"; -static char *colors[][3] = { - /* fg bg border */ - [SchemeNorm] = { normfgcolor, normbgcolor, normbordercolor }, - [SchemeSel] = { selfgcolor, selbgcolor, selbordercolor }, -}; - -/* tagging */ -static const char *tags[] = { "[one]", "[two]", "[three]", "[four]", "[five]", "[six]", "[seven]", "[eight]", "[nine]" }; - -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, 0, -1 }, -}; - -/* layout(s) */ -static const float mfact = 0.50; /* factor of master area size [0.05..0.95] */ -static const int nmaster = 1; /* number of clients in master area */ -static const int resizehints = 0; /* 1 means respect size hints in tiled resizals */ -static const int lockfullscreen = 1; /* 1 will force focus on the fullscreen window */ - -static const Layout layouts[] = { - /* symbol arrange function */ - {"[]=", tile}, /* first entry is default */ - {"<#>", NULL}, /* no layout function means floating behavior */ - {"<@>", monocle}, -}; - -static const char *ranger[] = { "st", "-e", "ranger", NULL }; -static const char *firemenu[] = { "firemenu", NULL }; - -#include -//different commands per OS -#ifdef __linux__ - #define VOL_UP "pamixer --allow-boost -i 10; kill -44 $(pidof dwmblocks)" - #define XK_UP "pamixer --allow-boost -i 5; kill -44 $(pidof dwmblocks)" - #define VOL_DOWN "pamixer --allow-boost -d 10; kill -44 $(pidof dwmblocks)" - #define XK_DOWN "pamixer --allow-boost -d 5; kill -44 $(pidof dwmblocks)" - #define VOL_MUTE "pamixer -t; kill -44 $(pidof dwmblocks)" - #define VOL_KILL "kill -44 $(pidof dwmblocks)" -#elif __OpenBSD__ - #define VOL_UP "sndioctl output.level=+0.10; pkill -SIGUSR1 dwmblocks" - #define XK_UP "sndioctl output.level=+0.05; pkill -SIGUSR1 dwmblocks" - #define VOL_DOWN "sndioctl output.level=-0.10; pkill -SIGUSR1 dwmblocks" - #define XK_DOWN "sndioctl output.level=-0.05; pkill -SIGUSR1 dwmblocks" - #define VOL_MUTE "sndioctl output.mute=!; pkill -SIGUSR1 dwmblocks" - #define VOL_KILL "pkill -SIGUSR1 dwmblocks" -#elif __FreeBSD__ - #define VOL_UP "sndioctl output.level=+0.10" - #define XK_UP "sndioctl output.level=+0.05" - #define VOL_DOWN "sndioctl output.level=-0.10" - #define XK_DOWN "sndioctl output.level=-0.05" - #define VOL_MUTE "sndioctl output.level=-1" - #define VOL_KILL "pkill -SIGUSR2 dwmblocks" -#endif - -/* key definitions */ -#define MODKEY Mod4Mask -#define TAGKEYS(KEY,TAG) \ - { MODKEY, KEY, view, {.ui = 1 << TAG} }, \ - { MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG} }, \ - { MODKEY|ShiftMask, KEY, tag, {.ui = 1 << TAG} }, \ - { MODKEY|ControlMask|ShiftMask, KEY, toggletag, {.ui = 1 << TAG} }, - -/* helper for spawning shell commands in the pre dwm-5.0 fashion */ -#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } } - -/* commands */ -static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */ -static const char *dmenucmd[] = { "dmenu_run", "-fn", dmenufont, "-nb", "#222222", "-nf", "#bbbbbb", "-sb", "#DB940A", "-sf", "#222222", NULL }; -static const char *termcmd[] = {"zsh", "-c", "st -e zsh & walrs -R -q ",NULL}; - -#include "movestack.c" -static Key keys[] = { - /*modifierkey function argument */ - { Mod4Mask|ShiftMask, XK_r, spawn, {.v = firemenu } }, - { MODKEY, XK_f, spawn, {.v = ranger } }, - { MODKEY, XK_r, spawn, {.v = dmenucmd } }, - { MODKEY, XK_j, focusstack, {.i = +1 } }, - { MODKEY|ControlMask, XK_n, focusstack, {.i = +1 } }, - { MODKEY|ControlMask, XK_p, focusstack, {.i = -1 } }, - { MODKEY, XK_k, focusstack, {.i = -1 } }, - { MODKEY, XK_Tab, view, {0} }, - { MODKEY|ShiftMask, XK_F5, xrdb, {.v = NULL } }, - { MODKEY, XK_t, setlayout, {.v = &layouts[0]} }, - { MODKEY, XK_space, setlayout, {0} }, - - 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, XK_h, setmfact, {.f = -0.05} }, - { MODKEY, XK_l, setmfact, {.f = +0.05} }, - { MODKEY|ShiftMask, XK_q, quit, {0} }, - { MODKEY, XK_b, spawn, SHCMD("floorp") }, - { MODKEY, XK_m, togglebar, {0} }, - { MODKEY, XK_o, incnmaster, {.i = +1 } }, - { MODKEY, XK_Return, spawn, {.v = termcmd } }, - { MODKEY, XK_KP_Enter, spawn, {.v = termcmd } }, - { MODKEY, XK_grave, spawn, {.v = termcmd } }, -// { MODKEY|ShiftMask, XK_o, incnmaster {.i = -1 } }, - { MODKEY, XK_s, killclient, {0} }, - { MODKEY|ShiftMask, XK_j, movestack, {.i = +1 } }, - { MODKEY|ShiftMask, XK_k, movestack, {.i = -1 } }, - { MODKEY|ControlMask|ShiftMask, XK_n, movestack, {.i = +1 } }, - { MODKEY|ControlMask|ShiftMask, XK_p, movestack, {.i = -1 } }, - - //volume control - { Mod1Mask, XK_equal, spawn, SHCMD(VOL_UP) }, - { Mod1Mask, XK_minus, spawn, SHCMD(VOL_DOWN) }, - { Mod1Mask, XK_minus, spawn, SHCMD(VOL_DOWN) }, - { 0, XF86XK_AudioMute, spawn, SHCMD(VOL_MUTE) }, - { 0, XF86XK_AudioRaiseVolume, spawn, SHCMD(XK_UP) }, - { 0, XF86XK_AudioLowerVolume, spawn, SHCMD(XK_DOWN) }, - //lock - { MODKEY|ShiftMask, XK_l, spawn, SHCMD("slock") }, - { 0, XK_Print, spawn, SHCMD("flameshot gui -r | xclip -selection clipboard -t image/png && notify-send 'Screenshot taken!'") }, -}; - - -/* button definitions */ -/* click can be ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */ -static const Button buttons[] = { - /* click event mask button function argument */ - { ClkLtSymbol, 0, Button1, setlayout, {0} }, - { ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} }, - { 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/suckless/dwm/config.h~ b/suckless/dwm/config.h~ deleted file mode 100644 index 6af2dd0..0000000 --- a/suckless/dwm/config.h~ +++ /dev/null @@ -1,165 +0,0 @@ - -/* See LICENSE file for copyright and license details. */ - -/* appearance */ -static const unsigned int borderpx = 2.5; /* border pixel of windows */ -static const unsigned int gappx = 14; /* gaps between windows */ -static const unsigned int snap = 3; /* snap pixel */ -static const int user_bh = 12; /* 2 is the default spacing around the bar's font */ -static const int showbar = 1; /* 0 means no bar */ -static const int topbar = 1; /* 0 means bottom bar */ -static const int vertpad = 10; /* vertical padding of bar */ -static const int sidepad = 400; /* horizontal padding of bar */ -static const char *fonts[] = {"CaskaydiaMonoNerdFont-Bold:size=9.2"}; -static const char dmenufont[] = "CaskaydiaMonoNerdFont-Bold:size=10.6"; -static char normbgcolor[] = "#222222"; -static char normbordercolor[] = "#444444"; -static char normfgcolor[] = "#bbbbbb"; -static char selfgcolor[] = "#222222"; -static char selbordercolor[] = "#555555"; -static char selbgcolor[] = "#DB940A"; -static char *colors[][3] = { - /* fg bg border */ - [SchemeNorm] = { normfgcolor, normbgcolor, normbordercolor }, - [SchemeSel] = { selfgcolor, selbgcolor, selbordercolor }, -}; - -/* tagging */ -static const char *tags[] = { "[one]", "[two]", "[three]", "[four]", "[five]", "[six]", "[seven]", "[eight]", "[nine]" }; - -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, 0, -1 }, -}; - -/* layout(s) */ -static const float mfact = 0.50; /* factor of master area size [0.05..0.95] */ -static const int nmaster = 1; /* number of clients in master area */ -static const int resizehints = 0; /* 1 means respect size hints in tiled resizals */ -static const int lockfullscreen = 1; /* 1 will force focus on the fullscreen window */ - -static const Layout layouts[] = { - /* symbol arrange function */ - {"[]=", tile}, /* first entry is default */ - {"<#>", NULL}, /* no layout function means floating behavior */ - {"<@>", monocle}, -}; - -static const char *ranger[] = { "st", "-e", "ranger", NULL }; -static const char *firemenu[] = { "firemenu", NULL }; - -#include -//different commands per OS -#ifdef __linux__ - #define VOL_UP "pamixer --allow-boost -i 10; kill -44 $(pidof dwmblocks)" - #define XK_UP "pamixer --allow-boost -i 5; kill -44 $(pidof dwmblocks)" - #define VOL_DOWN "pamixer --allow-boost -d 10; kill -44 $(pidof dwmblocks)" - #define XK_DOWN "pamixer --allow-boost -d 5; kill -44 $(pidof dwmblocks)" - #define VOL_MUTE "pamixer -t; kill -44 $(pidof dwmblocks)" - #define VOL_KILL "kill -44 $(pidof dwmblocks)" -#elif __OpenBSD__ - #define VOL_UP "sndioctl output.level=+0.10; pkill -SIGUSR1 dwmblocks" - #define XK_UP "sndioctl output.level=+0.05; pkill -SIGUSR1 dwmblocks" - #define VOL_DOWN "sndioctl output.level=-0.10; pkill -SIGUSR1 dwmblocks" - #define XK_DOWN "sndioctl output.level=-0.05; pkill -SIGUSR1 dwmblocks" - #define VOL_MUTE "sndioctl output.mute=!; pkill -SIGUSR1 dwmblocks" - #define VOL_KILL "pkill -SIGUSR1 dwmblocks" -#elif __FreeBSD__ - #define VOL_UP "sndioctl output.level=+0.10" - #define XK_UP "sndioctl output.level=+0.05" - #define VOL_DOWN "sndioctl output.level=-0.10" - #define XK_DOWN "sndioctl output.level=-0.05" - #define VOL_MUTE "sndioctl output.level=-1" - #define VOL_KILL "pkill -SIGUSR2 dwmblocks" -#endif - -/* key definitions */ -#define MODKEY Mod4Mask -#define TAGKEYS(KEY,TAG) \ - { MODKEY, KEY, view, {.ui = 1 << TAG} }, \ - { MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG} }, \ - { MODKEY|ShiftMask, KEY, tag, {.ui = 1 << TAG} }, \ - { MODKEY|ControlMask|ShiftMask, KEY, toggletag, {.ui = 1 << TAG} }, - -/* helper for spawning shell commands in the pre dwm-5.0 fashion */ -#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } } - -/* commands */ -static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */ -static const char *dmenucmd[] = { "dmenu_run", "-fn", dmenufont, "-nb", normbgcolor, "-nf", normfgcolor, "-sb", selbordercolor, "-sf", selfgcolor, NULL }; -static const char *termcmd[] = {"zsh", "-c", "st -e zsh & walrs -R -q ",NULL}; - -#include "movestack.c" -static Key keys[] = { - /*modifierkey function argument */ - { Mod4Mask|ShiftMask, XK_r, spawn, {.v = firemenu } }, - { MODKEY, XK_f, spawn, {.v = ranger } }, - { MODKEY, XK_r, spawn, {.v = dmenucmd } }, - { MODKEY, XK_j, focusstack, {.i = +1 } }, - { MODKEY|ControlMask, XK_n, focusstack, {.i = +1 } }, - { MODKEY|ControlMask, XK_p, focusstack, {.i = -1 } }, - { MODKEY, XK_k, focusstack, {.i = -1 } }, - { MODKEY, XK_Tab, view, {0} }, - { MODKEY|ShiftMask, XK_F5, xrdb, {.v = NULL } }, - { MODKEY, XK_t, setlayout, {.v = &layouts[0]} }, - { MODKEY, XK_space, setlayout, {0} }, - - 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, XK_h, setmfact, {.f = -0.05} }, - { MODKEY, XK_l, setmfact, {.f = +0.05} }, - { MODKEY|ShiftMask, XK_q, quit, {0} }, - { MODKEY, XK_b, spawn, SHCMD("mullvad-browser") }, - { MODKEY, XK_m, togglebar, {0} }, - { MODKEY, XK_o, incnmaster, {.i = +1 } }, - { MODKEY, XK_Return, spawn, {.v = termcmd } }, - { MODKEY, XK_KP_Enter, spawn, {.v = termcmd } }, - { MODKEY, XK_grave, spawn, {.v = termcmd } }, -// { MODKEY|ShiftMask, XK_o, incnmaster {.i = -1 } }, - { MODKEY, XK_s, killclient, {0} }, - { MODKEY|ShiftMask, XK_j, movestack, {.i = +1 } }, - { MODKEY|ShiftMask, XK_k, movestack, {.i = -1 } }, - { MODKEY|ControlMask|ShiftMask, XK_n, movestack, {.i = +1 } }, - { MODKEY|ControlMask|ShiftMask, XK_p, movestack, {.i = -1 } }, - - //volume control - { Mod1Mask, XK_equal, spawn, SHCMD(VOL_UP) }, - { Mod1Mask, XK_minus, spawn, SHCMD(VOL_DOWN) }, - { Mod1Mask, XK_minus, spawn, SHCMD(VOL_DOWN) }, - { 0, XF86XK_AudioMute, spawn, SHCMD(VOL_MUTE) }, - { 0, XF86XK_AudioRaiseVolume, spawn, SHCMD(XK_UP) }, - { 0, XF86XK_AudioLowerVolume, spawn, SHCMD(XK_DOWN) }, - //lock - { MODKEY|ShiftMask, XK_l, spawn, SHCMD("slock") }, - { 0, XK_Print, spawn, SHCMD("flameshot gui -r | xclip -selection clipboard -t image/png && notify-send 'Screenshot taken!'") }, -}; - - -/* button definitions */ -/* click can be ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */ -static const Button buttons[] = { - /* click event mask button function argument */ - { ClkLtSymbol, 0, Button1, setlayout, {0} }, - { ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} }, - { 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/suckless/dwm/config.mk b/suckless/dwm/config.mk deleted file mode 100644 index 8efca9a..0000000 --- a/suckless/dwm/config.mk +++ /dev/null @@ -1,39 +0,0 @@ -# dwm version -VERSION = 6.5 - -# 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 -#MANPREFIX = ${PREFIX}/man - -# includes and libs -INCS = -I${X11INC} -I${FREETYPEINC} -LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} - -# flags -CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700L -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/suckless/dwm/configure b/suckless/dwm/configure deleted file mode 100644 index 69e51e6..0000000 --- a/suckless/dwm/configure +++ /dev/null @@ -1,40 +0,0 @@ -#!/bin/sh - -#OS=$(printf 'Linux\nOpenBSD\nFreeBSD\nSolaris' | fzf --layout=reverse --height 40%) -OS=$(uname) - -case $OS in - Linux) cp -f mkconfig/config.mk.linux config.mk ;; - OpenBSD) cp -f mkconfig/config.mk.openbsd config.mk ;; - FreeBSD) cp -f mkconfig/config.mk.freebsd config.mk ;; - Solaris) cp -f mkconfig/config.mk.solaris config.mk ;; -esac - -#sed -i 's/##/#/g' config.mk -#sed -i '14 s/^/#/' config.mk -#sed -i '15 s/^/#/' config.mk -#sed -i '25 s/^/#/' config.mk -#sed -i '27 s/^/#/' config.mk -#sed -i '29 s/^/#/' config.mk -#sed -i '65 s/^/#/' config.mk -#sed -i '66 s/^/#/' config.mk -#sed -i 's/##/#/g' config.mk -# -#if [ "$OS" = "Linux" ]; then -# true -#else if [ "$OS" = "OpenBSD" ]; then -# sed -i '27 s/.//' config.mk -# sed -i '29 s/.//' config.mk -#else if [ "$OS" = "FreeBSD" ]; then -# sed -i '14 s/.//' config.mk -# sed -i '15 s/.//' config.mk -# sed -i '25 s/.//' config.mk -#else if [ "$OS" = "Solaris" ]; then -# sed -i '65 s/.//' config.mk -# sed -i '66 s/.//' config.mk -#fi -#fi -#fi -#fi -# -#sed -i 's/##/#/g' config.mk diff --git a/suckless/dwm/drw.c b/suckless/dwm/drw.c deleted file mode 100644 index 6be5dee..0000000 --- a/suckless/dwm/drw.c +++ /dev/null @@ -1,448 +0,0 @@ -/* See LICENSE file for copyright and license details. */ -#include -#include -#include -#include -#include - -#include "drw.h" -#include "util.h" - -#define UTF_INVALID 0xFFFD - -static int -utf8decode(const char *s_in, long *u, int *err) -{ - static const unsigned char lens[] = { - /* 0XXXX */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - /* 10XXX */ 0, 0, 0, 0, 0, 0, 0, 0, /* invalid */ - /* 110XX */ 2, 2, 2, 2, - /* 1110X */ 3, 3, - /* 11110 */ 4, - /* 11111 */ 0, /* invalid */ - }; - static const unsigned char leading_mask[] = { 0x7F, 0x1F, 0x0F, 0x07 }; - static const unsigned int overlong[] = { 0x0, 0x80, 0x0800, 0x10000 }; - - const unsigned char *s = (const unsigned char *)s_in; - int len = lens[*s >> 3]; - *u = UTF_INVALID; - *err = 1; - if (len == 0) - return 1; - - long cp = s[0] & leading_mask[len - 1]; - for (int i = 1; i < len; ++i) { - if (s[i] == '\0' || (s[i] & 0xC0) != 0x80) - return i; - cp = (cp << 6) | (s[i] & 0x3F); - } - /* out of range, surrogate, overlong encoding */ - if (cp > 0x10FFFF || (cp >> 11) == 0x1B || cp < overlong[len - 1]) - return len; - - *err = 0; - *u = cp; - return len; -} - -Drw * -drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h) -{ - Drw *drw = ecalloc(1, sizeof(Drw)); - - drw->dpy = dpy; - drw->screen = screen; - drw->root = root; - drw->w = w; - drw->h = h; - drw->drawable = XCreatePixmap(dpy, root, w, h, DefaultDepth(dpy, screen)); - drw->gc = XCreateGC(dpy, root, 0, NULL); - XSetLineAttributes(dpy, drw->gc, 1, LineSolid, CapButt, JoinMiter); - - return drw; -} - -void -drw_resize(Drw *drw, unsigned int w, unsigned int h) -{ - if (!drw) - return; - - drw->w = w; - drw->h = h; - if (drw->drawable) - XFreePixmap(drw->dpy, drw->drawable); - drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, DefaultDepth(drw->dpy, drw->screen)); -} - -void -drw_free(Drw *drw) -{ - XFreePixmap(drw->dpy, drw->drawable); - XFreeGC(drw->dpy, drw->gc); - drw_fontset_free(drw->fonts); - free(drw); -} - -/* This function is an implementation detail. Library users should use - * drw_fontset_create instead. - */ -static Fnt * -xfont_create(Drw *drw, const char *fontname, FcPattern *fontpattern) -{ - Fnt *font; - XftFont *xfont = NULL; - FcPattern *pattern = NULL; - - if (fontname) { - /* Using the pattern found at font->xfont->pattern does not yield the - * same substitution results as using the pattern returned by - * FcNameParse; using the latter results in the desired fallback - * behaviour whereas the former just results in missing-character - * rectangles being drawn, at least with some fonts. */ - if (!(xfont = XftFontOpenName(drw->dpy, drw->screen, fontname))) { - fprintf(stderr, "error, cannot load font from name: '%s'\n", fontname); - return NULL; - } - if (!(pattern = FcNameParse((FcChar8 *) fontname))) { - fprintf(stderr, "error, cannot parse font name to pattern: '%s'\n", fontname); - XftFontClose(drw->dpy, xfont); - return NULL; - } - } else if (fontpattern) { - if (!(xfont = XftFontOpenPattern(drw->dpy, fontpattern))) { - fprintf(stderr, "error, cannot load font from pattern.\n"); - return NULL; - } - } else { - die("no font specified."); - } - - font = ecalloc(1, sizeof(Fnt)); - font->xfont = xfont; - font->pattern = pattern; - font->h = xfont->ascent + xfont->descent; - font->dpy = drw->dpy; - - return font; -} - -static void -xfont_free(Fnt *font) -{ - if (!font) - return; - if (font->pattern) - FcPatternDestroy(font->pattern); - XftFontClose(font->dpy, font->xfont); - free(font); -} - -Fnt* -drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount) -{ - Fnt *cur, *ret = NULL; - size_t i; - - if (!drw || !fonts) - return NULL; - - for (i = 1; i <= fontcount; i++) { - if ((cur = xfont_create(drw, fonts[fontcount - i], NULL))) { - cur->next = ret; - ret = cur; - } - } - return (drw->fonts = ret); -} - -void -drw_fontset_free(Fnt *font) -{ - if (font) { - drw_fontset_free(font->next); - xfont_free(font); - } -} - -void -drw_clr_create(Drw *drw, Clr *dest, const char *clrname) -{ - if (!drw || !dest || !clrname) - return; - - if (!XftColorAllocName(drw->dpy, DefaultVisual(drw->dpy, drw->screen), - DefaultColormap(drw->dpy, drw->screen), - clrname, dest)) - die("error, cannot allocate color '%s'", clrname); -} - -/* Wrapper to create color schemes. The caller has to call free(3) on the - * returned color scheme when done using it. */ -Clr * -drw_scm_create(Drw *drw, char *clrnames[], size_t clrcount) -{ - size_t i; - Clr *ret; - - /* need at least two colors for a scheme */ - if (!drw || !clrnames || clrcount < 2 || !(ret = ecalloc(clrcount, sizeof(XftColor)))) - return NULL; - - for (i = 0; i < clrcount; i++) - drw_clr_create(drw, &ret[i], clrnames[i]); - return ret; -} - -void -drw_setfontset(Drw *drw, Fnt *set) -{ - if (drw) - drw->fonts = set; -} - -void -drw_setscheme(Drw *drw, Clr *scm) -{ - if (drw) - drw->scheme = scm; -} - -void -drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert) -{ - if (!drw || !drw->scheme) - return; - XSetForeground(drw->dpy, drw->gc, invert ? drw->scheme[ColBg].pixel : drw->scheme[ColFg].pixel); - if (filled) - XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h); - else - XDrawRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w - 1, h - 1); -} - -int -drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert) -{ - int ty, ellipsis_x = 0; - unsigned int tmpw, ew, ellipsis_w = 0, ellipsis_len, hash, h0, h1; - XftDraw *d = NULL; - Fnt *usedfont, *curfont, *nextfont; - int utf8strlen, utf8charlen, utf8err, render = x || y || w || h; - long utf8codepoint = 0; - const char *utf8str; - FcCharSet *fccharset; - FcPattern *fcpattern; - FcPattern *match; - XftResult result; - int charexists = 0, overflow = 0; - /* keep track of a couple codepoints for which we have no match. */ - static unsigned int nomatches[128], ellipsis_width, invalid_width; - static const char invalid[] = "�"; - - if (!drw || (render && (!drw->scheme || !w)) || !text || !drw->fonts) - return 0; - - if (!render) { - w = invert ? invert : ~invert; - } else { - XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].pixel); - XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h); - if (w < lpad) - return x + w; - d = XftDrawCreate(drw->dpy, drw->drawable, - DefaultVisual(drw->dpy, drw->screen), - DefaultColormap(drw->dpy, drw->screen)); - x += lpad; - w -= lpad; - } - - usedfont = drw->fonts; - if (!ellipsis_width && render) - ellipsis_width = drw_fontset_getwidth(drw, "..."); - if (!invalid_width && render) - invalid_width = drw_fontset_getwidth(drw, invalid); - while (1) { - ew = ellipsis_len = utf8err = utf8charlen = utf8strlen = 0; - utf8str = text; - nextfont = NULL; - while (*text) { - utf8charlen = utf8decode(text, &utf8codepoint, &utf8err); - for (curfont = drw->fonts; curfont; curfont = curfont->next) { - charexists = charexists || XftCharExists(drw->dpy, curfont->xfont, utf8codepoint); - if (charexists) { - drw_font_getexts(curfont, text, utf8charlen, &tmpw, NULL); - if (ew + ellipsis_width <= w) { - /* keep track where the ellipsis still fits */ - ellipsis_x = x + ew; - ellipsis_w = w - ew; - ellipsis_len = utf8strlen; - } - - if (ew + tmpw > w) { - overflow = 1; - /* called from drw_fontset_getwidth_clamp(): - * it wants the width AFTER the overflow - */ - if (!render) - x += tmpw; - else - utf8strlen = ellipsis_len; - } else if (curfont == usedfont) { - text += utf8charlen; - utf8strlen += utf8err ? 0 : utf8charlen; - ew += utf8err ? 0 : tmpw; - } else { - nextfont = curfont; - } - break; - } - } - - if (overflow || !charexists || nextfont || utf8err) - break; - else - charexists = 0; - } - - if (utf8strlen) { - if (render) { - ty = y + (h - usedfont->h) / 2 + usedfont->xfont->ascent; - XftDrawStringUtf8(d, &drw->scheme[invert ? ColBg : ColFg], - usedfont->xfont, x, ty, (XftChar8 *)utf8str, utf8strlen); - } - x += ew; - w -= ew; - } - if (utf8err && (!render || invalid_width < w)) { - if (render) - drw_text(drw, x, y, w, h, 0, invalid, invert); - x += invalid_width; - w -= invalid_width; - } - if (render && overflow) - drw_text(drw, ellipsis_x, y, ellipsis_w, h, 0, "...", invert); - - if (!*text || overflow) { - break; - } else if (nextfont) { - charexists = 0; - usedfont = nextfont; - } else { - /* Regardless of whether or not a fallback font is found, the - * character must be drawn. */ - charexists = 1; - - hash = (unsigned int)utf8codepoint; - hash = ((hash >> 16) ^ hash) * 0x21F0AAAD; - hash = ((hash >> 15) ^ hash) * 0xD35A2D97; - h0 = ((hash >> 15) ^ hash) % LENGTH(nomatches); - h1 = (hash >> 17) % LENGTH(nomatches); - /* avoid expensive XftFontMatch call when we know we won't find a match */ - if (nomatches[h0] == utf8codepoint || nomatches[h1] == utf8codepoint) - goto no_match; - - fccharset = FcCharSetCreate(); - FcCharSetAddChar(fccharset, utf8codepoint); - - if (!drw->fonts->pattern) { - /* Refer to the comment in xfont_create for more information. */ - die("the first font in the cache must be loaded from a font string."); - } - - fcpattern = FcPatternDuplicate(drw->fonts->pattern); - FcPatternAddCharSet(fcpattern, FC_CHARSET, fccharset); - FcPatternAddBool(fcpattern, FC_SCALABLE, FcTrue); - - FcConfigSubstitute(NULL, fcpattern, FcMatchPattern); - FcDefaultSubstitute(fcpattern); - match = XftFontMatch(drw->dpy, drw->screen, fcpattern, &result); - - FcCharSetDestroy(fccharset); - FcPatternDestroy(fcpattern); - - if (match) { - usedfont = xfont_create(drw, NULL, match); - if (usedfont && XftCharExists(drw->dpy, usedfont->xfont, utf8codepoint)) { - for (curfont = drw->fonts; curfont->next; curfont = curfont->next) - ; /* NOP */ - curfont->next = usedfont; - } else { - xfont_free(usedfont); - nomatches[nomatches[h0] ? h1 : h0] = utf8codepoint; -no_match: - usedfont = drw->fonts; - } - } - } - } - if (d) - XftDrawDestroy(d); - - return x + (render ? w : 0); -} - -void -drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h) -{ - if (!drw) - return; - - XCopyArea(drw->dpy, drw->drawable, win, drw->gc, x, y, w, h, x, y); - XSync(drw->dpy, False); -} - -unsigned int -drw_fontset_getwidth(Drw *drw, const char *text) -{ - if (!drw || !drw->fonts || !text) - return 0; - return drw_text(drw, 0, 0, 0, 0, 0, text, 0); -} - -unsigned int -drw_fontset_getwidth_clamp(Drw *drw, const char *text, unsigned int n) -{ - unsigned int tmp = 0; - if (drw && drw->fonts && text && n) - tmp = drw_text(drw, 0, 0, 0, 0, 0, text, n); - return MIN(n, tmp); -} - -void -drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h) -{ - XGlyphInfo ext; - - if (!font || !text) - return; - - XftTextExtentsUtf8(font->dpy, font->xfont, (XftChar8 *)text, len, &ext); - if (w) - *w = ext.xOff; - if (h) - *h = font->h; -} - -Cur * -drw_cur_create(Drw *drw, int shape) -{ - Cur *cur; - - if (!drw || !(cur = ecalloc(1, sizeof(Cur)))) - return NULL; - - cur->cursor = XCreateFontCursor(drw->dpy, shape); - - return cur; -} - -void -drw_cur_free(Drw *drw, Cur *cursor) -{ - if (!cursor) - return; - - XFreeCursor(drw->dpy, cursor->cursor); - free(cursor); -} diff --git a/suckless/dwm/drw.h b/suckless/dwm/drw.h deleted file mode 100644 index bdbf950..0000000 --- a/suckless/dwm/drw.h +++ /dev/null @@ -1,58 +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); -unsigned int drw_fontset_getwidth_clamp(Drw *drw, const char *text, unsigned int n); -void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h); - -/* Colorscheme abstraction */ -void drw_clr_create(Drw *drw, Clr *dest, const char *clrname); -Clr *drw_scm_create(Drw *drw, char *clrnames[], size_t clrcount); - -/* Cursor abstraction */ -Cur *drw_cur_create(Drw *drw, int shape); -void drw_cur_free(Drw *drw, Cur *cursor); - -/* Drawing context manipulation */ -void drw_setfontset(Drw *drw, Fnt *set); -void drw_setscheme(Drw *drw, Clr *scm); - -/* Drawing functions */ -void drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert); -int drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert); - -/* Map functions */ -void drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h); diff --git a/suckless/dwm/drw.o b/suckless/dwm/drw.o deleted file mode 100644 index 69dbfa9f910b2da334855d573d810016a6cee0e0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11464 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 TbCK}Az4Z=B(Roci-Q)ikvLk1R diff --git a/suckless/dwm/dwm b/suckless/dwm/dwm deleted file mode 100755 index ee9c01163ab1b58a22efc481e797d55d3c982963..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 73952 zcmeEvdw3K@)^|^mfpE)=nrK9jQ3g%qmSBPz$Vi4vpaTO8BtRf2gk(YjA&JQh#2W-B z0opc-inrBuS=V)4FDqUaQ4|uc(e)DI4Rz%vVmAYbpnx~#`QwcxJkK*O#$@8OPb_yMM^tNpg5;pxZU8N-T11+Tqa<*Uj`%|-cIKUZ*L zn5MR;7HaKDGSXkgdrCfI=v81&3yt|Us`-qeP0go;TH66R@f#Gz#?Y_o zgBEJ#O+`Lxm;dfZZBA~QTAs1}HQL)l;i!e0o(-?6oIf&ScvacZs>

!_bDTkwZsj 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef XINERAMA -#include -#endif /* XINERAMA */ -#include - -#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 ISVISIBLEONTAG(C, T) ((C->tags & T)) -#define ISVISIBLE(C) ISVISIBLEONTAG(C, C->mon->tagset[C->mon->seltags]) -#define MOUSEMASK (BUTTONMASK|PointerMotionMask) -#define WIDTH(X) ((X)->w + 2 * (X)->bw) -#define HEIGHT(X) ((X)->h + 2 * (X)->bw) -#define TAGMASK ((1 << LENGTH(tags)) - 1) -#define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad) -#define XRDB_LOAD_COLOR(R,V) if (XrmGetResource(xrdb, R, NULL, &type, &value) == True) { \ - if (value.addr != NULL && strnlen(value.addr, 8) == 7 && value.addr[0] == '#') { \ - int i = 1; \ - for (; i <= 6; i++) { \ - if (value.addr[i] < 48) break; \ - if (value.addr[i] > 57 && value.addr[i] < 65) break; \ - if (value.addr[i] > 70 && value.addr[i] < 97) break; \ - if (value.addr[i] > 102) break; \ - } \ - if (i == 7) { \ - strncpy(V, value.addr, 7); \ - V[7] = '\0'; \ - } \ - } \ - } - -/* enums */ -enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */ -enum { SchemeNorm, SchemeSel }; /* color schemes */ -enum { NetSupported, NetWMName, NetWMState, NetWMCheck, - NetWMFullscreen, NetActiveWindow, NetWMWindowType, - NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */ -enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */ -enum { ClkTagBar, ClkLtSymbol, ClkStatusText, 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, hintsvalid; - int bw, oldbw; - unsigned int tags; - int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen; - Client *next; - Client *snext; - Monitor *mon; - Window win; -}; - -typedef struct { - unsigned int mod; - KeySym keysym; - void (*func)(const Arg *); - const Arg arg; -} Key; - -typedef struct { - const char *symbol; - void (*arrange)(Monitor *); -} Layout; - -struct Monitor { - char ltsymbol[16]; - float mfact; - int nmaster; - int num; - int by; /* bar geometry */ - int mx, my, mw, mh; /* screen size */ - int wx, wy, ww, wh; /* window area */ - int gappx; /* gaps between windows */ - unsigned int seltags; - unsigned int sellt; - unsigned int tagset[2]; - int showbar; - int topbar; - Client *clients; - Client *sel; - Client *stack; - Monitor *next; - Window barwin; - const Layout *lt[2]; -}; - -typedef struct { - const char *class; - const char *instance; - const char *title; - unsigned int tags; - int isfloating; - int monitor; -} Rule; - -/* function declarations */ -static void applyrules(Client *c); -static int applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact); -static void arrange(Monitor *m); -static void arrangemon(Monitor *m); -static void attach(Client *c); -static void attachaside(Client *c); -static void attachstack(Client *c); -static void buttonpress(XEvent *e); -static void checkotherwm(void); -static void cleanup(void); -static void cleanupmon(Monitor *mon); -static void clientmessage(XEvent *e); -static void configure(Client *c); -static void configurenotify(XEvent *e); -static void configurerequest(XEvent *e); -static Monitor *createmon(void); -static void destroynotify(XEvent *e); -static void detach(Client *c); -static void detachstack(Client *c); -static Monitor *dirtomon(int dir); -static void drawbar(Monitor *m); -static void drawbars(void); -static void enternotify(XEvent *e); -static void expose(XEvent *e); -static void focus(Client *c); -static void focusin(XEvent *e); -static void focusmon(const Arg *arg); -static void focusstack(const Arg *arg); -static Atom getatomprop(Client *c, Atom prop); -static int getrootptr(int *x, int *y); -static long getstate(Window w); -static int gettextprop(Window w, Atom atom, char *text, unsigned int size); -static void grabbuttons(Client *c, int focused); -static void grabkeys(void); -static void incnmaster(const Arg *arg); -static void keypress(XEvent *e); -static void killclient(const Arg *arg); -static void loadxrdb(void); -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 *nexttagged(Client *c); -static Client *nexttiled(Client *c); -static void pop(Client *c); -static void propertynotify(XEvent *e); -static void quit(const Arg *arg); -static Monitor *recttomon(int x, int y, int w, int h); -static void resize(Client *c, int x, int y, int w, int h, int interact); -static void resizeclient(Client *c, int x, int y, int w, int h); -static void resizemouse(const Arg *arg); -static void restack(Monitor *m); -static void run(void); -static void scan(void); -static int sendevent(Client *c, Atom proto); -static void sendmon(Client *c, Monitor *m); -static void setclientstate(Client *c, long state); -static void setfocus(Client *c); -static void setfullscreen(Client *c, int fullscreen); -static void setgaps(const Arg *arg); -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 spawn(const Arg *arg); -static void tag(const Arg *arg); -static void tagmon(const Arg *arg); -static void tile(Monitor *m); -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 updatetitle(Client *c); -static void updatewindowtype(Client *c); -static void updatewmhints(Client *c); -static void view(const Arg *arg); -static void warp(const Client *c); -static Client *wintoclient(Window w); -static Monitor *wintomon(Window w); -static int xerror(Display *dpy, XErrorEvent *ee); -static int xerrordummy(Display *dpy, XErrorEvent *ee); -static int xerrorstart(Display *dpy, XErrorEvent *ee); -static void xrdb(const Arg *arg); -static void zoom(const Arg *arg); -static void sighup(int unused); -static void sigterm(int unused); - - -/* variables */ -static const char broken[] = "broken"; -static char stext[256]; -static int screen; -static int sw, sh; /* X display screen geometry width, height */ -static int bh; /* bar height */ -static int lrpad; /* sum of left and right padding for text */ -static int vp; /* vertical padding for bar */ -static int sp; /* side padding for bar */ -static int (*xerrorxlib)(Display *, XErrorEvent *); -static unsigned int numlockmask = 0; -static void (*handler[LASTEvent]) (XEvent *) = { - [ButtonPress] = buttonpress, - [ClientMessage] = clientmessage, - [ConfigureRequest] = configurerequest, - [ConfigureNotify] = configurenotify, - [DestroyNotify] = destroynotify, - [EnterNotify] = enternotify, - [Expose] = expose, - [FocusIn] = focusin, - [KeyPress] = keypress, - [MappingNotify] = mappingnotify, - [MapRequest] = maprequest, - [MotionNotify] = motionnotify, - [PropertyNotify] = propertynotify, - [UnmapNotify] = unmapnotify -}; -static Atom wmatom[WMLast], netatom[NetLast]; -static int restart = 0; -static int running = 1; -static Cur *cursor[CurLast]; -static Clr **scheme; -static Display *dpy; -static Drw *drw; -static Monitor *mons, *selmon; -static Window root, wmcheckwin; - -/* configuration, allows nested code to access above variables */ -#include "config.h" - -/* compile-time check if all tags fit into an unsigned int bit array. */ -struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; }; - -/* function implementations */ -void -applyrules(Client *c) -{ - const char *class, *instance; - unsigned int i; - const Rule *r; - Monitor *m; - XClassHint ch = { NULL, NULL }; - - /* rule matching */ - c->isfloating = 0; - c->tags = 0; - XGetClassHint(dpy, c->win, &ch); - class = ch.res_class ? ch.res_class : broken; - instance = ch.res_name ? ch.res_name : broken; - - for (i = 0; i < LENGTH(rules); i++) { - r = &rules[i]; - if ((!r->title || strstr(c->name, r->title)) - && (!r->class || strstr(class, r->class)) - && (!r->instance || strstr(instance, r->instance))) - { - c->isfloating = r->isfloating; - c->tags |= r->tags; - 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) { - if (!c->hintsvalid) - updatesizehints(c); - /* 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 -attachaside(Client *c) { - Client *at = nexttagged(c); - if(!at) { - attach(c); - return; - } - c->next = at->next; - at->next = 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 + TEXTW(selmon->ltsymbol)) - click = ClkLtSymbol; - else - click = ClkStatusText; - } else if ((c = wintoclient(ev->window))) { - focus(c); - restack(selmon); - XAllowEvents(dpy, ReplayPointer, CurrentTime); - click = ClkClientWin; - } - for (i = 0; i < LENGTH(buttons); i++) - if (click == buttons[i].click && buttons[i].func && buttons[i].button == ev->button - && CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state)) - buttons[i].func(click == ClkTagBar && buttons[i].arg.i == 0 ? &arg : &buttons[i].arg); -} - -void -checkotherwm(void) -{ - xerrorxlib = XSetErrorHandler(xerrorstart); - /* this causes an error if some other window manager is running */ - XSelectInput(dpy, DefaultRootWindow(dpy), SubstructureRedirectMask); - XSync(dpy, False); - XSetErrorHandler(xerror); - XSync(dpy, False); -} - -void -cleanup(void) -{ - Arg a = {.ui = ~0}; - Layout foo = { "", NULL }; - Monitor *m; - size_t i; - - view(&a); - selmon->lt[selmon->sellt] = &foo; - for (m = mons; m; m = m->next) - while (m->stack) - unmanage(m->stack, 0); - XUngrabKey(dpy, AnyKey, AnyModifier, root); - while (mons) - cleanupmon(mons); - for (i = 0; i < CurLast; i++) - drw_cur_free(drw, cursor[i]); - for (i = 0; i < LENGTH(colors); i++) - free(scheme[i]); - free(scheme); - XDestroyWindow(dpy, wmcheckwin); - drw_free(drw); - XSync(dpy, False); - XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime); - XDeleteProperty(dpy, root, netatom[NetActiveWindow]); -} - -void -cleanupmon(Monitor *mon) -{ - Monitor *m; - - if (mon == mons) - mons = mons->next; - else { - for (m = mons; m && m->next != mon; m = m->next); - m->next = mon->next; - } - XUnmapWindow(dpy, mon->barwin); - XDestroyWindow(dpy, mon->barwin); - free(mon); -} - -void -clientmessage(XEvent *e) -{ - XClientMessageEvent *cme = &e->xclient; - Client *c = wintoclient(cme->window); - - if (!c) - return; - if (cme->message_type == netatom[NetWMState]) { - if (cme->data.l[1] == netatom[NetWMFullscreen] - || cme->data.l[2] == netatom[NetWMFullscreen]) - setfullscreen(c, (cme->data.l[0] == 1 /* _NET_WM_STATE_ADD */ - || (cme->data.l[0] == 2 /* _NET_WM_STATE_TOGGLE */ && !c->isfullscreen))); - } else if (cme->message_type == netatom[NetActiveWindow]) { - if (c != selmon->sel && !c->isurgent) - seturgent(c, 1); - } -} - -void -configure(Client *c) -{ - XConfigureEvent ce; - - ce.type = ConfigureNotify; - ce.display = dpy; - ce.event = c->win; - ce.window = c->win; - ce.x = c->x; - ce.y = c->y; - ce.width = c->w; - ce.height = c->h; - ce.border_width = c->bw; - ce.above = None; - ce.override_redirect = False; - XSendEvent(dpy, c->win, False, StructureNotifyMask, (XEvent *)&ce); -} - -void -configurenotify(XEvent *e) -{ - Monitor *m; - Client *c; - XConfigureEvent *ev = &e->xconfigure; - int dirty; - - /* TODO: updategeom handling sucks, needs to be simplified */ - if (ev->window == root) { - dirty = (sw != ev->width || sh != ev->height); - sw = ev->width; - sh = ev->height; - if (updategeom() || dirty) { - drw_resize(drw, sw, bh); - updatebars(); - for (m = mons; m; m = m->next) { - for (c = m->clients; c; c = c->next) - if (c->isfullscreen) - resizeclient(c, m->mx, m->my, m->mw, m->mh); - XMoveResizeWindow(dpy, m->barwin, m->wx + sp, m->by + vp, m->ww - 2 * sp, bh); - } - focus(NULL); - arrange(NULL); - } - } -} - -void -configurerequest(XEvent *e) -{ - Client *c; - Monitor *m; - XConfigureRequestEvent *ev = &e->xconfigurerequest; - XWindowChanges wc; - - if ((c = wintoclient(ev->window))) { - if (ev->value_mask & CWBorderWidth) - c->bw = ev->border_width; - else if (c->isfloating || !selmon->lt[selmon->sellt]->arrange) { - m = c->mon; - if (ev->value_mask & CWX) { - c->oldx = c->x; - c->x = m->mx + ev->x; - } - if (ev->value_mask & CWY) { - c->oldy = c->y; - c->y = m->my + ev->y; - } - if (ev->value_mask & CWWidth) { - c->oldw = c->w; - c->w = ev->width; - } - if (ev->value_mask & CWHeight) { - c->oldh = c->h; - c->h = ev->height; - } - if ((c->x + c->w) > m->mx + m->mw && c->isfloating) - c->x = m->mx + (m->mw / 2 - WIDTH(c) / 2); /* center in x direction */ - if ((c->y + c->h) > m->my + m->mh && c->isfloating) - c->y = m->my + (m->mh / 2 - HEIGHT(c) / 2); /* center in y direction */ - if ((ev->value_mask & (CWX|CWY)) && !(ev->value_mask & (CWWidth|CWHeight))) - configure(c); - if (ISVISIBLE(c)) - XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h); - } else - configure(c); - } else { - wc.x = ev->x; - wc.y = ev->y; - wc.width = ev->width; - wc.height = ev->height; - wc.border_width = ev->border_width; - wc.sibling = ev->above; - wc.stack_mode = ev->detail; - XConfigureWindow(dpy, ev->window, ev->value_mask, &wc); - } - XSync(dpy, False); -} - -Monitor * -createmon(void) -{ - Monitor *m; - - m = ecalloc(1, sizeof(Monitor)); - m->tagset[0] = m->tagset[1] = 1; - m->mfact = mfact; - m->nmaster = nmaster; - m->showbar = showbar; - m->topbar = topbar; - m->gappx = gappx; - m->lt[0] = &layouts[0]; - m->lt[1] = &layouts[1 % LENGTH(layouts)]; - strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol); - return m; -} - -void -destroynotify(XEvent *e) -{ - Client *c; - XDestroyWindowEvent *ev = &e->xdestroywindow; - - if ((c = wintoclient(ev->window))) - unmanage(c, 1); -} - -void -detach(Client *c) -{ - Client **tc; - - for (tc = &c->mon->clients; *tc && *tc != c; tc = &(*tc)->next); - *tc = c->next; -} - -void -detachstack(Client *c) -{ - Client **tc, *t; - - for (tc = &c->mon->stack; *tc && *tc != c; tc = &(*tc)->snext); - *tc = c->snext; - - if (c == c->mon->sel) { - for (t = c->mon->stack; t && !ISVISIBLE(t); t = t->snext); - c->mon->sel = t; - } -} - -Monitor * -dirtomon(int dir) -{ - Monitor *m = NULL; - - if (dir > 0) { - if (!(m = selmon->next)) - m = mons; - } else if (selmon == mons) - for (m = mons; m->next; m = m->next); - else - for (m = mons; m->next != selmon; m = m->next); - return m; -} - -void -drawbar(Monitor *m) -{ - int x, w, tw = 0; - unsigned int i, occ = 0, urg = 0; - Client *c; - - if (!m->showbar) - return; - - /* draw status first so it can be overdrawn by tags later */ - if (m == selmon || 1) { /* status is only drawn on selected monitor */ - drw_setscheme(drw, scheme[SchemeNorm]); - tw = TEXTW(stext) - lrpad + 2; /* 2px right padding */ - drw_text(drw, m->ww - tw - 2 * sp, 0, tw, bh, 0, stext, 0); - } - - for (c = m->clients; c; c = c->next) { - occ |= c->tags; - if (c->isurgent) - urg |= c->tags; - } - x = 0; - for (i = 0; i < LENGTH(tags); i++) { - w = TEXTW(tags[i]); - drw_setscheme(drw, scheme[m->tagset[m->seltags] & 1 << i ? SchemeSel : SchemeNorm]); - drw_text(drw, x, 0, w, bh, lrpad / 2, tags[i], urg & 1 << i); - x += w; - } - w = TEXTW(m->ltsymbol); - drw_setscheme(drw, scheme[SchemeNorm]); - x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0); - - if ((w = m->ww - tw - x) > bh) { - drw_setscheme(drw, scheme[SchemeNorm]); - drw_rect(drw, x, 0, w - 2 * sp, bh, 1, 1); - } - drw_map(drw, m->barwin, 0, 0, m->ww, bh); -} - -void -drawbars(void) -{ - Monitor *m; - - for (m = mons; m; m = m->next) - drawbar(m); -} - -void -enternotify(XEvent *e) -{ - Client *c; - Monitor *m; - XCrossingEvent *ev = &e->xcrossing; - - if ((ev->mode != NotifyNormal || ev->detail == NotifyInferior) && ev->window != root) - return; - c = wintoclient(ev->window); - m = c ? c->mon : wintomon(ev->window); - if (m != selmon) { - unfocus(selmon->sel, 1); - selmon = m; - } else if (!c || c == selmon->sel) - return; - focus(c); -} - -void -expose(XEvent *e) -{ - Monitor *m; - XExposeEvent *ev = &e->xexpose; - - if (ev->count == 0 && (m = wintomon(ev->window))) - drawbar(m); -} - -void -focus(Client *c) -{ - if (!c || !ISVISIBLE(c)) - for (c = selmon->stack; c && !ISVISIBLE(c); c = c->snext); - if (selmon->sel && selmon->sel != c) - unfocus(selmon->sel, 0); - if (c) { - if (c->mon != selmon) - selmon = c->mon; - if (c->isurgent) - seturgent(c, 0); - detachstack(c); - attachstack(c); - grabbuttons(c, 1); - XSetWindowBorder(dpy, c->win, scheme[SchemeSel][ColBorder].pixel); - setfocus(c); - } else { - XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime); - XDeleteProperty(dpy, root, netatom[NetActiveWindow]); - } - selmon->sel = c; - drawbars(); -} - -/* there are some broken focus acquiring clients needing extra handling */ -void -focusin(XEvent *e) -{ - XFocusChangeEvent *ev = &e->xfocus; - - if (selmon->sel && ev->window != selmon->sel->win) - setfocus(selmon->sel); -} - -void -focusmon(const Arg *arg) -{ - Monitor *m; - - if (!mons->next) - return; - if ((m = dirtomon(arg->i)) == selmon) - return; - unfocus(selmon->sel, 0); - selmon = m; - focus(NULL); - warp(selmon->sel); -} - -void -focusstack(const Arg *arg) -{ - Client *c = NULL, *i; - - if (!selmon->sel || (selmon->sel->isfullscreen && lockfullscreen)) - return; - if (arg->i > 0) { - for (c = selmon->sel->next; c && !ISVISIBLE(c); c = c->next); - if (!c) - for (c = selmon->clients; c && !ISVISIBLE(c); c = c->next); - } else { - for (i = selmon->clients; i != selmon->sel; i = i->next) - if (ISVISIBLE(i)) - c = i; - if (!c) - for (; i; i = i->next) - if (ISVISIBLE(i)) - c = i; - } - if (c) { - focus(c); - restack(selmon); - } -} - -Atom -getatomprop(Client *c, Atom prop) -{ - int di; - unsigned long dl; - unsigned char *p = NULL; - Atom da, atom = None; - - if (XGetWindowProperty(dpy, c->win, prop, 0L, sizeof atom, False, XA_ATOM, - &da, &di, &dl, &dl, &p) == Success && p) { - atom = *(Atom *)p; - XFree(p); - } - return atom; -} - -int -getrootptr(int *x, int *y) -{ - int di; - unsigned int dui; - Window dummy; - - return XQueryPointer(dpy, root, &dummy, &dummy, x, y, &di, &di, &dui); -} - -long -getstate(Window w) -{ - int format; - long result = -1; - unsigned char *p = NULL; - unsigned long n, extra; - Atom real; - - if (XGetWindowProperty(dpy, w, wmatom[WMState], 0L, 2L, False, wmatom[WMState], - &real, &format, &n, &extra, (unsigned char **)&p) != Success) - return -1; - if (n != 0) - result = *p; - XFree(p); - return result; -} - -int -gettextprop(Window w, Atom atom, char *text, unsigned int size) -{ - char **list = NULL; - int n; - XTextProperty name; - - if (!text || size == 0) - return 0; - text[0] = '\0'; - if (!XGetTextProperty(dpy, w, &name, atom) || !name.nitems) - return 0; - if (name.encoding == XA_STRING) { - strncpy(text, (char *)name.value, size - 1); - } else if (XmbTextPropertyToTextList(dpy, &name, &list, &n) >= Success && n > 0 && *list) { - strncpy(text, *list, size - 1); - XFreeStringList(list); - } - text[size - 1] = '\0'; - XFree(name.value); - return 1; -} - -void -grabbuttons(Client *c, int focused) -{ - updatenumlockmask(); - { - unsigned int i, j; - unsigned int modifiers[] = { 0, LockMask, numlockmask, numlockmask|LockMask }; - XUngrabButton(dpy, AnyButton, AnyModifier, c->win); - if (!focused) - XGrabButton(dpy, AnyButton, AnyModifier, c->win, False, - BUTTONMASK, GrabModeSync, GrabModeSync, None, None); - for (i = 0; i < LENGTH(buttons); i++) - if (buttons[i].click == ClkClientWin) - for (j = 0; j < LENGTH(modifiers); j++) - XGrabButton(dpy, buttons[i].button, - buttons[i].mask | modifiers[j], - c->win, False, BUTTONMASK, - GrabModeAsync, GrabModeSync, None, None); - } -} - -void -grabkeys(void) -{ - updatenumlockmask(); - { - unsigned int i, j, k; - unsigned int modifiers[] = { 0, LockMask, numlockmask, numlockmask|LockMask }; - int start, end, skip; - KeySym *syms; - - XUngrabKey(dpy, AnyKey, AnyModifier, root); - XDisplayKeycodes(dpy, &start, &end); - syms = XGetKeyboardMapping(dpy, start, end - start + 1, &skip); - if (!syms) - return; - for (k = start; k <= end; k++) - for (i = 0; i < LENGTH(keys); i++) - /* skip modifier codes, we do that ourselves */ - if (keys[i].keysym == syms[(k - start) * skip]) - for (j = 0; j < LENGTH(modifiers); j++) - XGrabKey(dpy, k, - keys[i].mod | modifiers[j], - root, True, - GrabModeAsync, GrabModeAsync); - XFree(syms); - } -} - -void -incnmaster(const Arg *arg) -{ - selmon->nmaster = MAX(selmon->nmaster + arg->i, 0); - arrange(selmon); -} - -#ifdef XINERAMA -static int -isuniquegeom(XineramaScreenInfo *unique, size_t n, XineramaScreenInfo *info) -{ - while (n--) - if (unique[n].x_org == info->x_org && unique[n].y_org == info->y_org - && unique[n].width == info->width && unique[n].height == info->height) - return 0; - return 1; -} -#endif /* XINERAMA */ - -void -keypress(XEvent *e) -{ - unsigned int i; - KeySym keysym; - XKeyEvent *ev; - - ev = &e->xkey; - keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0); - for (i = 0; i < LENGTH(keys); i++) - if (keysym == keys[i].keysym - && CLEANMASK(keys[i].mod) == CLEANMASK(ev->state) - && keys[i].func) - keys[i].func(&(keys[i].arg)); -} - -void -killclient(const Arg *arg) -{ - if (!selmon->sel) - return; - if (!sendevent(selmon->sel, wmatom[WMDelete])) { - XGrabServer(dpy); - XSetErrorHandler(xerrordummy); - XSetCloseDownMode(dpy, DestroyAll); - XKillClient(dpy, selmon->sel->win); - XSync(dpy, False); - XSetErrorHandler(xerror); - XUngrabServer(dpy); - } -} - -void -loadxrdb() -{ - Display *display; - char * resm; - XrmDatabase xrdb; - char *type; - XrmValue value; - - display = XOpenDisplay(NULL); - - if (display != NULL) { - resm = XResourceManagerString(display); - - if (resm != NULL) { - xrdb = XrmGetStringDatabase(resm); - - if (xrdb != NULL) { - XRDB_LOAD_COLOR("dwm.color2", normbordercolor); - XRDB_LOAD_COLOR("dwm.background", normbgcolor); - XRDB_LOAD_COLOR("dwm.color7", normfgcolor); - XRDB_LOAD_COLOR("dwm.color6", selbordercolor); - XRDB_LOAD_COLOR("dwm.color11", selbgcolor); - XRDB_LOAD_COLOR("dwm.color15", selfgcolor); - } - } - } - - XCloseDisplay(display); -} - -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->wx + c->mon->ww) - c->x = c->mon->wx + c->mon->ww - WIDTH(c); - if (c->y + HEIGHT(c) > c->mon->wy + c->mon->wh) - c->y = c->mon->wy + c->mon->wh - HEIGHT(c); - c->x = MAX(c->x, c->mon->wx); - c->y = MAX(c->y, c->mon->wy); - 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); - attachaside(c); - attachstack(c); - XChangeProperty(dpy, root, netatom[NetClientList], XA_WINDOW, 32, PropModeAppend, - (unsigned char *) &(c->win), 1); - XMoveResizeWindow(dpy, c->win, c->x + 2 * sw, c->y, c->w, c->h); /* some windows require this */ - setclientstate(c, NormalState); - if (c->mon == selmon) - unfocus(selmon->sel, 0); - c->mon->sel = c; - arrange(c->mon); - XMapWindow(dpy, c->win); - focus(NULL); -} - -void -mappingnotify(XEvent *e) -{ - XMappingEvent *ev = &e->xmapping; - - XRefreshKeyboardMapping(ev); - if (ev->request == MappingKeyboard) - grabkeys(); -} - -void -maprequest(XEvent *e) -{ - static XWindowAttributes wa; - XMapRequestEvent *ev = &e->xmaprequest; - - if (!XGetWindowAttributes(dpy, ev->window, &wa) || 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, ""); - 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 * -nexttagged(Client *c) { - Client *walked = c->mon->clients; - for(; - walked && (walked->isfloating || !ISVISIBLEONTAG(walked, c->tags)); - walked = walked->next - ); - return walked; -} - -Client * -nexttiled(Client *c) -{ - for (; c && (c->isfloating || !ISVISIBLE(c)); c = c->next); - return c; -} - -void -pop(Client *c) -{ - detach(c); - attach(c); - focus(c); - arrange(c->mon); -} - -void -propertynotify(XEvent *e) -{ - Client *c; - Window trans; - XPropertyEvent *ev = &e->xproperty; - - if ((ev->window == root) && (ev->atom == XA_WM_NAME)) - updatestatus(); - else if (ev->state == PropertyDelete) - return; /* ignore */ - else if ((c = wintoclient(ev->window))) { - switch(ev->atom) { - default: break; - case XA_WM_TRANSIENT_FOR: - if (!c->isfloating && (XGetTransientForHint(dpy, c->win, &trans)) && - (c->isfloating = (wintoclient(trans)) != NULL)) - arrange(c->mon); - break; - case XA_WM_NORMAL_HINTS: - c->hintsvalid = 0; - break; - case XA_WM_HINTS: - updatewmhints(c); - drawbars(); - break; - } - if (ev->atom == XA_WM_NAME || ev->atom == netatom[NetWMName]) - updatetitle(c); - if (ev->atom == netatom[NetWMWindowType]) - updatewindowtype(c); - } -} - -void -quit(const Arg *arg) -{ - if(arg->i) restart = 1; - running = 0; -} - -Monitor * -recttomon(int x, int y, int w, int h) -{ - Monitor *m, *r = selmon; - int a, area = 0; - - for (m = mons; m; m = m->next) - if ((a = INTERSECT(x, y, w, h, m)) > area) { - area = a; - r = m; - } - return r; -} - -void -resize(Client *c, int x, int y, int w, int h, int interact) -{ - if (applysizehints(c, &x, &y, &w, &h, interact)) - resizeclient(c, x, y, w, h); -} - -void -resizeclient(Client *c, int x, int y, int w, int h) -{ - XWindowChanges wc; - - c->oldx = c->x; c->x = wc.x = x; - c->oldy = c->y; c->y = wc.y = y; - c->oldw = c->w; c->w = wc.width = w; - c->oldh = c->h; c->h = wc.height = h; - wc.border_width = c->bw; - XConfigureWindow(dpy, c->win, CWX|CWY|CWWidth|CWHeight|CWBorderWidth, &wc); - configure(c); - XSync(dpy, False); -} - -void -resizemouse(const Arg *arg) -{ - int x, y, ocw, och, 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); - ocw = c->w; - och = c->h; - if (XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync, - None, cursor[CurResize]->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; - - nw = MAX(ocw + (ev.xmotion.x - x), 1); - nh = MAX(och + (ev.xmotion.y - y), 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); - XUngrabPointer(dpy, CurrentTime); - while (XCheckMaskEvent(dpy, EnterWindowMask, &ev)); - if ((m = recttomon(c->x, c->y, c->w, c->h)) != selmon) { - sendmon(c, m); - selmon = m; - focus(NULL); - } -} - -void -restack(Monitor *m) -{ - Client *c; - XEvent ev; - XWindowChanges wc; - - drawbar(m); - if (!m->sel) - return; - if (m->sel->isfloating || !m->lt[m->sellt]->arrange) - XRaiseWindow(dpy, m->sel->win); - if (m->lt[m->sellt]->arrange) { - wc.stack_mode = Below; - wc.sibling = m->barwin; - for (c = m->stack; c; c = c->snext) - if (!c->isfloating && ISVISIBLE(c)) { - XConfigureWindow(dpy, c->win, CWSibling|CWStackMode, &wc); - wc.sibling = c->win; - } - } - if (m == selmon && (m->tagset[m->seltags] & m->sel->tags) && m->lt[m->sellt]->arrange != &monocle) - warp(m->sel); - 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 */ - attachaside(c); - attachstack(c); - focus(NULL); - arrange(NULL); -} - -void -setclientstate(Client *c, long state) -{ - long data[] = { state, None }; - - XChangeProperty(dpy, c->win, wmatom[WMState], wmatom[WMState], 32, - PropModeReplace, (unsigned char *)data, 2); -} - -int -sendevent(Client *c, Atom proto) -{ - int n; - Atom *protocols; - int exists = 0; - XEvent ev; - - if (XGetWMProtocols(dpy, c->win, &protocols, &n)) { - while (!exists && n--) - exists = protocols[n] == proto; - XFree(protocols); - } - if (exists) { - ev.type = ClientMessage; - ev.xclient.window = c->win; - ev.xclient.message_type = wmatom[WMProtocols]; - ev.xclient.format = 32; - ev.xclient.data.l[0] = proto; - ev.xclient.data.l[1] = CurrentTime; - XSendEvent(dpy, c->win, False, NoEventMask, &ev); - } - return exists; -} - -void -setfocus(Client *c) -{ - if (!c->neverfocus) { - XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime); - XChangeProperty(dpy, root, netatom[NetActiveWindow], - XA_WINDOW, 32, PropModeReplace, - (unsigned char *) &(c->win), 1); - } - sendevent(c, wmatom[WMTakeFocus]); -} - -void -setfullscreen(Client *c, int fullscreen) -{ - if (fullscreen && !c->isfullscreen) { - XChangeProperty(dpy, c->win, netatom[NetWMState], XA_ATOM, 32, - PropModeReplace, (unsigned char*)&netatom[NetWMFullscreen], 1); - c->isfullscreen = 1; - c->oldstate = c->isfloating; - c->oldbw = c->bw; - c->bw = 0; - c->isfloating = 1; - resizeclient(c, c->mon->mx, c->mon->my, c->mon->mw, c->mon->mh); - XRaiseWindow(dpy, c->win); - } else if (!fullscreen && c->isfullscreen){ - XChangeProperty(dpy, c->win, netatom[NetWMState], XA_ATOM, 32, - PropModeReplace, (unsigned char*)0, 0); - c->isfullscreen = 0; - c->isfloating = c->oldstate; - c->bw = c->oldbw; - c->x = c->oldx; - c->y = c->oldy; - c->w = c->oldw; - c->h = c->oldh; - resizeclient(c, c->x, c->y, c->w, c->h); - arrange(c->mon); - } -} - -void -setgaps(const Arg *arg) -{ - if ((arg->i == 0) || (selmon->gappx + arg->i < 0)) - selmon->gappx = 0; - else - selmon->gappx += arg->i; - arrange(selmon); -} - -void -setlayout(const Arg *arg) -{ - if (!arg || !arg->v || arg->v != selmon->lt[selmon->sellt]) - selmon->sellt ^= 1; - if (arg && arg->v) - selmon->lt[selmon->sellt] = (Layout *)arg->v; - strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, sizeof selmon->ltsymbol); - if (selmon->sel) - arrange(selmon); - else - drawbar(selmon); -} - -/* arg > 1.0 will set mfact absolutely */ -void -setmfact(const Arg *arg) -{ - float f; - - if (!arg || !selmon->lt[selmon->sellt]->arrange) - return; - f = arg->f < 1.0 ? arg->f + selmon->mfact : arg->f - 1.0; - if (f < 0.05 || f > 0.95) - return; - selmon->mfact = f; - arrange(selmon); -} - -void -setup(void) -{ - int i; - XSetWindowAttributes wa; - Atom utf8string; - struct sigaction sa; - - /* do not transform children into zombies when they terminate */ - sigemptyset(&sa.sa_mask); - sa.sa_flags = SA_NOCLDSTOP | SA_NOCLDWAIT | SA_RESTART; - sa.sa_handler = SIG_IGN; - sigaction(SIGCHLD, &sa, NULL); - - /* clean up any zombies (inherited from .xinitrc etc) immediately */ - while (waitpid(-1, NULL, WNOHANG) > 0); - - signal(SIGHUP, sighup); - signal(SIGTERM, sigterm); - - /* 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 + user_bh; - - sp = sidepad; - vp = (topbar == 1) ? vertpad : - vertpad; - updategeom(); - - /* init atoms */ - utf8string = XInternAtom(dpy, "UTF8_STRING", False); - wmatom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False); - wmatom[WMDelete] = XInternAtom(dpy, "WM_DELETE_WINDOW", False); - wmatom[WMState] = XInternAtom(dpy, "WM_STATE", False); - wmatom[WMTakeFocus] = XInternAtom(dpy, "WM_TAKE_FOCUS", False); - netatom[NetActiveWindow] = XInternAtom(dpy, "_NET_ACTIVE_WINDOW", False); - netatom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False); - netatom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False); - netatom[NetWMState] = XInternAtom(dpy, "_NET_WM_STATE", False); - netatom[NetWMCheck] = XInternAtom(dpy, "_NET_SUPPORTING_WM_CHECK", False); - netatom[NetWMFullscreen] = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False); - netatom[NetWMWindowType] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False); - netatom[NetWMWindowTypeDialog] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DIALOG", False); - netatom[NetClientList] = XInternAtom(dpy, "_NET_CLIENT_LIST", False); - /* init cursors */ - cursor[CurNormal] = drw_cur_create(drw, XC_left_ptr); - cursor[CurResize] = drw_cur_create(drw, XC_sizing); - cursor[CurMove] = drw_cur_create(drw, XC_fleur); - /* init appearance */ - scheme = ecalloc(LENGTH(colors), sizeof(Clr *)); - for (i = 0; i < LENGTH(colors); i++) - scheme[i] = drw_scm_create(drw, colors[i], 3); - /* init bars */ - updatebars(); - updatestatus(); - /* supporting window for NetWMCheck */ - wmcheckwin = XCreateSimpleWindow(dpy, root, 0, 0, 1, 1, 0, 0, 0); - XChangeProperty(dpy, wmcheckwin, netatom[NetWMCheck], XA_WINDOW, 32, - PropModeReplace, (unsigned char *) &wmcheckwin, 1); - XChangeProperty(dpy, wmcheckwin, netatom[NetWMName], utf8string, 8, - PropModeReplace, (unsigned char *) "dwm", 3); - XChangeProperty(dpy, root, netatom[NetWMCheck], XA_WINDOW, 32, - PropModeReplace, (unsigned char *) &wmcheckwin, 1); - /* EWMH support per view */ - XChangeProperty(dpy, root, netatom[NetSupported], XA_ATOM, 32, - PropModeReplace, (unsigned char *) netatom, NetLast); - XDeleteProperty(dpy, root, netatom[NetClientList]); - /* select events */ - wa.cursor = cursor[CurNormal]->cursor; - wa.event_mask = SubstructureRedirectMask|SubstructureNotifyMask - |ButtonPressMask|PointerMotionMask|EnterWindowMask - |LeaveWindowMask|StructureNotifyMask|PropertyChangeMask; - XChangeWindowAttributes(dpy, root, CWEventMask|CWCursor, &wa); - XSelectInput(dpy, root, wa.event_mask); - grabkeys(); - focus(NULL); -} - -void -seturgent(Client *c, int urg) -{ - XWMHints *wmh; - - c->isurgent = urg; - if (!(wmh = XGetWMHints(dpy, c->win))) - return; - wmh->flags = urg ? (wmh->flags | XUrgencyHint) : (wmh->flags & ~XUrgencyHint); - XSetWMHints(dpy, c->win, wmh); - XFree(wmh); -} - -void -showhide(Client *c) -{ - if (!c) - return; - if (ISVISIBLE(c)) { - /* show clients top down */ - XMoveWindow(dpy, c->win, c->x, c->y); - if ((!c->mon->lt[c->mon->sellt]->arrange || c->isfloating) && !c->isfullscreen) - resize(c, c->x, c->y, c->w, c->h, 0); - showhide(c->snext); - } else { - /* hide clients bottom up */ - showhide(c->snext); - XMoveWindow(dpy, c->win, WIDTH(c) * -2, c->y); - } -} - -void -sighup(int unused) -{ - Arg a = {.i = 1}; - quit(&a); -} - -void -sigterm(int unused) -{ - Arg a = {.i = 0}; - quit(&a); -} - -void -spawn(const Arg *arg) -{ - struct sigaction sa; - - if (arg->v == dmenucmd) - dmenumon[0] = '0' + selmon->num; - if (fork() == 0) { - if (dpy) - close(ConnectionNumber(dpy)); - setsid(); - - sigemptyset(&sa.sa_mask); - sa.sa_flags = 0; - sa.sa_handler = SIG_DFL; - sigaction(SIGCHLD, &sa, NULL); - - execvp(((char **)arg->v)[0], (char **)arg->v); - die("dwm: execvp '%s' failed:", ((char **)arg->v)[0]); - } -} - -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 - m->gappx; - for (i = 0, my = ty = m->gappx, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) - if (i < m->nmaster) { - h = (m->wh - my) / (MIN(n, m->nmaster) - i) - m->gappx; - resize(c, m->wx + m->gappx, m->wy + my, mw - (2*c->bw) - m->gappx, h - (2*c->bw), 0); - if (my + HEIGHT(c) + m->gappx < m->wh) - my += HEIGHT(c) + m->gappx; - } else { - h = (m->wh - ty) / (n - i) - m->gappx; - resize(c, m->wx + mw + m->gappx, m->wy + ty, m->ww - mw - (2*c->bw) - 2*m->gappx, h - (2*c->bw), 0); - if (ty + HEIGHT(c) + m->gappx < m->wh) - ty += HEIGHT(c) + m->gappx; - } -} - -void -togglebar(const Arg *arg) -{ - selmon->showbar = !selmon->showbar; - updatebarpos(selmon); - XMoveResizeWindow(dpy, selmon->barwin, selmon->wx + sp, selmon->by + vp, selmon->ww - 2 * sp, bh); - arrange(selmon); -} - -void -togglefloating(const Arg *arg) -{ - if (!selmon->sel) - return; - if (selmon->sel->isfullscreen) /* no support for fullscreen windows */ - return; - selmon->sel->isfloating = !selmon->sel->isfloating || selmon->sel->isfixed; - if (selmon->sel->isfloating) - resize(selmon->sel, selmon->sel->x, selmon->sel->y, - selmon->sel->w, selmon->sel->h, 0); - arrange(selmon); -} - -void -toggletag(const Arg *arg) -{ - unsigned int newtags; - - if (!selmon->sel) - return; - newtags = selmon->sel->tags ^ (arg->ui & TAGMASK); - if (newtags) { - selmon->sel->tags = newtags; - focus(NULL); - arrange(selmon); - } -} - -void -toggleview(const Arg *arg) -{ - unsigned int newtagset = selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK); - - if (newtagset) { - selmon->tagset[selmon->seltags] = newtagset; - focus(NULL); - arrange(selmon); - } -} - -void -unfocus(Client *c, int setfocus) -{ - if (!c) - return; - grabbuttons(c, 0); - XSetWindowBorder(dpy, c->win, scheme[SchemeNorm][ColBorder].pixel); - if (setfocus) { - XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime); - XDeleteProperty(dpy, root, netatom[NetActiveWindow]); - } -} - -void -unmanage(Client *c, int destroyed) -{ - Monitor *m = c->mon; - XWindowChanges wc; - - detach(c); - detachstack(c); - if (!destroyed) { - wc.border_width = c->oldbw; - XGrabServer(dpy); /* avoid race conditions */ - XSetErrorHandler(xerrordummy); - XSelectInput(dpy, c->win, NoEventMask); - XConfigureWindow(dpy, c->win, CWBorderWidth, &wc); /* restore border */ - XUngrabButton(dpy, AnyButton, AnyModifier, c->win); - setclientstate(c, WithdrawnState); - XSync(dpy, False); - XSetErrorHandler(xerror); - XUngrabServer(dpy); - } - free(c); - focus(NULL); - updateclientlist(); - arrange(m); -} - -void -unmapnotify(XEvent *e) -{ - Client *c; - XUnmapEvent *ev = &e->xunmap; - - if ((c = wintoclient(ev->window))) { - if (ev->send_event) - setclientstate(c, WithdrawnState); - else - unmanage(c, 0); - } -} - -void -updatebars(void) -{ - Monitor *m; - XSetWindowAttributes wa = { - .override_redirect = True, - .background_pixmap = ParentRelative, - .event_mask = ButtonPressMask|ExposureMask - }; - XClassHint ch = {"dwm", "dwm"}; - for (m = mons; m; m = m->next) { - if (m->barwin) - continue; - m->barwin = XCreateWindow(dpy, root, m->wx + sp, m->by + vp, m->ww - 2 * sp, bh, 0, DefaultDepth(dpy, screen), - CopyFromParent, DefaultVisual(dpy, screen), - CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa); - XDefineCursor(dpy, m->barwin, cursor[CurNormal]->cursor); - XMapRaised(dpy, m->barwin); - XSetClassHint(dpy, m->barwin, &ch); - } -} - -void -updatebarpos(Monitor *m) -{ - m->wy = m->my; - m->wh = m->mh; - if (m->showbar) { - m->wh = m->wh - vertpad - bh; - m->by = m->topbar ? m->wy : m->wy + m->wh + vertpad; - m->wy = m->topbar ? m->wy + bh + vp : m->wy; - } else - m->by = -bh - vp; -} - -void -updateclientlist(void) -{ - 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; - - /* new monitors if nn > n */ - for (i = n; i < nn; 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); - } - /* removed monitors if n > nn */ - 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; - attachaside(c); - attachstack(c); - } - if (m == selmon) - selmon = mons; - cleanupmon(m); - } - free(unique); - } else -#endif /* XINERAMA */ - { /* default monitor setup */ - if (!mons) - mons = createmon(); - if (mons->mw != sw || mons->mh != sh) { - dirty = 1; - mons->mw = mons->ww = sw; - mons->mh = mons->wh = sh; - updatebarpos(mons); - } - } - if (dirty) { - selmon = mons; - selmon = wintomon(root); - } - return dirty; -} - -void -updatenumlockmask(void) -{ - unsigned int i, j; - XModifierKeymap *modmap; - - numlockmask = 0; - modmap = XGetModifierMapping(dpy); - for (i = 0; i < 8; i++) - for (j = 0; j < modmap->max_keypermod; j++) - if (modmap->modifiermap[i * modmap->max_keypermod + j] - == XKeysymToKeycode(dpy, XK_Num_Lock)) - numlockmask = (1 << i); - XFreeModifiermap(modmap); -} - -void -updatesizehints(Client *c) -{ - long msize; - XSizeHints size; - - if (!XGetWMNormalHints(dpy, c->win, &size, &msize)) - /* size is uninitialized, ensure that size.flags aren't used */ - size.flags = PSize; - if (size.flags & PBaseSize) { - c->basew = size.base_width; - c->baseh = size.base_height; - } else if (size.flags & PMinSize) { - c->basew = size.min_width; - c->baseh = size.min_height; - } else - c->basew = c->baseh = 0; - if (size.flags & PResizeInc) { - c->incw = size.width_inc; - c->inch = size.height_inc; - } else - c->incw = c->inch = 0; - if (size.flags & PMaxSize) { - c->maxw = size.max_width; - c->maxh = size.max_height; - } else - c->maxw = c->maxh = 0; - if (size.flags & PMinSize) { - c->minw = size.min_width; - c->minh = size.min_height; - } else if (size.flags & PBaseSize) { - c->minw = size.base_width; - c->minh = size.base_height; - } else - c->minw = c->minh = 0; - if (size.flags & PAspect) { - c->mina = (float)size.min_aspect.y / size.min_aspect.x; - c->maxa = (float)size.max_aspect.x / size.max_aspect.y; - } else - c->maxa = c->mina = 0.0; - c->isfixed = (c->maxw && c->maxh && c->maxw == c->minw && c->maxh == c->minh); - c->hintsvalid = 1; -} - -void -updatestatus(void) -{ - Monitor* m; - if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext))) - strcpy(stext, "dwm-"VERSION); - for(m = mons; m; m = m->next) - drawbar(m); -} - -void -updatetitle(Client *c) -{ - if (!gettextprop(c->win, netatom[NetWMName], c->name, sizeof c->name)) - gettextprop(c->win, XA_WM_NAME, c->name, sizeof c->name); - if (c->name[0] == '\0') /* hack to mark broken clients */ - strcpy(c->name, broken); -} - -void -updatewindowtype(Client *c) -{ - Atom state = getatomprop(c, netatom[NetWMState]); - Atom wtype = getatomprop(c, netatom[NetWMWindowType]); - - if (state == netatom[NetWMFullscreen]) - setfullscreen(c, 1); - if (wtype == netatom[NetWMWindowTypeDialog]) - c->isfloating = 1; -} - -void -updatewmhints(Client *c) -{ - XWMHints *wmh; - - if ((wmh = XGetWMHints(dpy, c->win))) { - if (c == selmon->sel && wmh->flags & XUrgencyHint) { - wmh->flags &= ~XUrgencyHint; - XSetWMHints(dpy, c->win, wmh); - } else - c->isurgent = (wmh->flags & XUrgencyHint) ? 1 : 0; - if (wmh->flags & InputHint) - c->neverfocus = !wmh->input; - else - c->neverfocus = 0; - XFree(wmh); - } -} - -void -view(const Arg *arg) -{ - if ((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags]) - return; - selmon->seltags ^= 1; /* toggle sel tagset */ - if (arg->ui & TAGMASK) - selmon->tagset[selmon->seltags] = arg->ui & TAGMASK; - focus(NULL); - arrange(selmon); -} - -void -warp(const Client *c) -{ - int x, y; - - if (!c) { - XWarpPointer(dpy, None, root, 0, 0, 0, 0, selmon->wx + selmon->ww / 2, selmon->wy + selmon->wh / 2); - return; - } - - if (!getrootptr(&x, &y) || - (x > c->x - c->bw && - y > c->y - c->bw && - x < c->x + c->w + c->bw*2 && - y < c->y + c->h + c->bw*2) || - (y > c->mon->by && y < c->mon->by + bh) || - (c->mon->topbar && !y)) - return; - - XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w / 2, c->h / 2); -} - -Client * -wintoclient(Window w) -{ - Client *c; - Monitor *m; - - for (m = mons; m; m = m->next) - for (c = m->clients; c; c = c->next) - if (c->win == w) - return c; - return NULL; -} - -Monitor * -wintomon(Window w) -{ - int x, y; - Client *c; - Monitor *m; - - if (w == root && getrootptr(&x, &y)) - return recttomon(x, y, 1, 1); - for (m = mons; m; m = m->next) - if (w == m->barwin) - return m; - if ((c = wintoclient(w))) - return c->mon; - return selmon; -} - -/* There's no way to check accesses to destroyed windows, thus those cases are - * ignored (especially on UnmapNotify's). Other types of errors call Xlibs - * default error handler, which may call exit. */ -int -xerror(Display *dpy, XErrorEvent *ee) -{ - if (ee->error_code == BadWindow - || (ee->request_code == X_SetInputFocus && ee->error_code == BadMatch) - || (ee->request_code == X_PolyText8 && ee->error_code == BadDrawable) - || (ee->request_code == X_PolyFillRectangle && ee->error_code == BadDrawable) - || (ee->request_code == X_PolySegment && ee->error_code == BadDrawable) - || (ee->request_code == X_ConfigureWindow && ee->error_code == BadMatch) - || (ee->request_code == X_GrabButton && ee->error_code == BadAccess) - || (ee->request_code == X_GrabKey && ee->error_code == BadAccess) - || (ee->request_code == X_CopyArea && ee->error_code == BadDrawable)) - return 0; - fprintf(stderr, "dwm: fatal error: request code=%d, error code=%d\n", - ee->request_code, ee->error_code); - return xerrorxlib(dpy, ee); /* may call exit */ -} - -int -xerrordummy(Display *dpy, XErrorEvent *ee) -{ - return 0; -} - -/* Startup Error handler to check if another window manager - * is already running. */ -int -xerrorstart(Display *dpy, XErrorEvent *ee) -{ - die("dwm: another window manager is already running"); - return -1; -} - -void -xrdb(const Arg *arg) -{ - loadxrdb(); - int i; - for (i = 0; i < LENGTH(colors); i++) - scheme[i] = drw_scm_create(drw, colors[i], 3); - focus(NULL); - arrange(NULL); -} - -void -zoom(const Arg *arg) -{ - Client *c = selmon->sel; - - if (!selmon->lt[selmon->sellt]->arrange || !c || c->isfloating) - return; - if (c == nexttiled(selmon->clients) && !(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(); - XrmInitialize(); - loadxrdb(); - setup(); -#ifdef __OpenBSD__ - if (pledge("stdio rpath proc exec", NULL) == -1) - die("pledge"); -#endif /* __OpenBSD__ */ - scan(); - run(); - if(restart) execvp(argv[0], argv); - cleanup(); - XCloseDisplay(dpy); - return EXIT_SUCCESS; -} diff --git a/suckless/dwm/dwm.c.orig b/suckless/dwm/dwm.c.orig deleted file mode 100644 index 7fd5c88..0000000 --- a/suckless/dwm/dwm.c.orig +++ /dev/null @@ -1,2278 +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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef XINERAMA -#include -#endif /* XINERAMA */ -#include - -#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 MOUSEMASK (BUTTONMASK|PointerMotionMask) -#define WIDTH(X) ((X)->w + 2 * (X)->bw) -#define HEIGHT(X) ((X)->h + 2 * (X)->bw) -#define TAGMASK ((1 << LENGTH(tags)) - 1) -#define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad) -#define XRDB_LOAD_COLOR(R,V) if (XrmGetResource(xrdb, R, NULL, &type, &value) == True) { \ - if (value.addr != NULL && strnlen(value.addr, 8) == 7 && value.addr[0] == '#') { \ - int i = 1; \ - for (; i <= 6; i++) { \ - if (value.addr[i] < 48) break; \ - if (value.addr[i] > 57 && value.addr[i] < 65) break; \ - if (value.addr[i] > 70 && value.addr[i] < 97) break; \ - if (value.addr[i] > 102) break; \ - } \ - if (i == 7) { \ - strncpy(V, value.addr, 7); \ - V[7] = '\0'; \ - } \ - } \ - } - -/* enums */ -enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */ -enum { SchemeNorm, SchemeSel }; /* color schemes */ -enum { NetSupported, NetWMName, NetWMState, NetWMCheck, - NetWMFullscreen, NetActiveWindow, NetWMWindowType, - NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */ -enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */ -enum { ClkTagBar, ClkLtSymbol, ClkStatusText, 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, hintsvalid; - int bw, oldbw; - unsigned int tags; - int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen; - Client *next; - Client *snext; - Monitor *mon; - Window win; -}; - -typedef struct { - unsigned int mod; - KeySym keysym; - void (*func)(const Arg *); - const Arg arg; -} Key; - -typedef struct { - const char *symbol; - void (*arrange)(Monitor *); -} Layout; - -struct Monitor { - char ltsymbol[16]; - float mfact; - int nmaster; - int num; - int by; /* bar geometry */ - int mx, my, mw, mh; /* screen size */ - int wx, wy, ww, wh; /* window area */ - int gappx; /* gaps between windows */ - unsigned int seltags; - unsigned int sellt; - unsigned int tagset[2]; - int showbar; - int topbar; - Client *clients; - Client *sel; - Client *stack; - Monitor *next; - Window barwin; - const Layout *lt[2]; -}; - -typedef struct { - const char *class; - const char *instance; - const char *title; - unsigned int tags; - int isfloating; - int monitor; -} Rule; - -/* function declarations */ -static void applyrules(Client *c); -static int applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact); -static void arrange(Monitor *m); -static void arrangemon(Monitor *m); -static void attach(Client *c); -static void attachstack(Client *c); -static void buttonpress(XEvent *e); -static void checkotherwm(void); -static void cleanup(void); -static void cleanupmon(Monitor *mon); -static void clientmessage(XEvent *e); -static void configure(Client *c); -static void configurenotify(XEvent *e); -static void configurerequest(XEvent *e); -static Monitor *createmon(void); -static void destroynotify(XEvent *e); -static void detach(Client *c); -static void detachstack(Client *c); -static Monitor *dirtomon(int dir); -static void drawbar(Monitor *m); -static void drawbars(void); -static void enternotify(XEvent *e); -static void expose(XEvent *e); -static void focus(Client *c); -static void focusin(XEvent *e); -static void focusmon(const Arg *arg); -static void focusstack(const Arg *arg); -static Atom getatomprop(Client *c, Atom prop); -static int getrootptr(int *x, int *y); -static long getstate(Window w); -static int gettextprop(Window w, Atom atom, char *text, unsigned int size); -static void grabbuttons(Client *c, int focused); -static void grabkeys(void); -static void incnmaster(const Arg *arg); -static void keypress(XEvent *e); -static void killclient(const Arg *arg); -static void loadxrdb(void); -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 *c); -static void propertynotify(XEvent *e); -static void quit(const Arg *arg); -static Monitor *recttomon(int x, int y, int w, int h); -static void resize(Client *c, int x, int y, int w, int h, int interact); -static void resizeclient(Client *c, int x, int y, int w, int h); -static void resizemouse(const Arg *arg); -static void restack(Monitor *m); -static void run(void); -static void scan(void); -static int sendevent(Client *c, Atom proto); -static void sendmon(Client *c, Monitor *m); -static void setclientstate(Client *c, long state); -static void setfocus(Client *c); -static void setfullscreen(Client *c, int fullscreen); -static void setgaps(const Arg *arg); -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 spawn(const Arg *arg); -static void tag(const Arg *arg); -static void tagmon(const Arg *arg); -static void tile(Monitor *m); -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 updatetitle(Client *c); -static void updatewindowtype(Client *c); -static void updatewmhints(Client *c); -static void view(const Arg *arg); -static void warp(const Client *c); -static Client *wintoclient(Window w); -static Monitor *wintomon(Window w); -static int xerror(Display *dpy, XErrorEvent *ee); -static int xerrordummy(Display *dpy, XErrorEvent *ee); -static int xerrorstart(Display *dpy, XErrorEvent *ee); -static void xrdb(const Arg *arg); -static void zoom(const Arg *arg); -static void sighup(int unused); -static void sigterm(int unused); - - -/* variables */ -static const char broken[] = "broken"; -static char stext[256]; -static int screen; -static int sw, sh; /* X display screen geometry width, height */ -static int bh; /* bar height */ -static int lrpad; /* sum of left and right padding for text */ -static int vp; /* vertical padding for bar */ -static int sp; /* side padding for bar */ -static int (*xerrorxlib)(Display *, XErrorEvent *); -static unsigned int numlockmask = 0; -static void (*handler[LASTEvent]) (XEvent *) = { - [ButtonPress] = buttonpress, - [ClientMessage] = clientmessage, - [ConfigureRequest] = configurerequest, - [ConfigureNotify] = configurenotify, - [DestroyNotify] = destroynotify, - [EnterNotify] = enternotify, - [Expose] = expose, - [FocusIn] = focusin, - [KeyPress] = keypress, - [MappingNotify] = mappingnotify, - [MapRequest] = maprequest, - [MotionNotify] = motionnotify, - [PropertyNotify] = propertynotify, - [UnmapNotify] = unmapnotify -}; -static Atom wmatom[WMLast], netatom[NetLast]; -static int restart = 0; -static int running = 1; -static Cur *cursor[CurLast]; -static Clr **scheme; -static Display *dpy; -static Drw *drw; -static Monitor *mons, *selmon; -static Window root, wmcheckwin; - -/* configuration, allows nested code to access above variables */ -#include "config.h" - -/* compile-time check if all tags fit into an unsigned int bit array. */ -struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; }; - -/* function implementations */ -void -applyrules(Client *c) -{ - const char *class, *instance; - unsigned int i; - const Rule *r; - Monitor *m; - XClassHint ch = { NULL, NULL }; - - /* rule matching */ - c->isfloating = 0; - c->tags = 0; - XGetClassHint(dpy, c->win, &ch); - class = ch.res_class ? ch.res_class : broken; - instance = ch.res_name ? ch.res_name : broken; - - for (i = 0; i < LENGTH(rules); i++) { - r = &rules[i]; - if ((!r->title || strstr(c->name, r->title)) - && (!r->class || strstr(class, r->class)) - && (!r->instance || strstr(instance, r->instance))) - { - c->isfloating = r->isfloating; - c->tags |= r->tags; - 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) { - if (!c->hintsvalid) - updatesizehints(c); - /* 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 + TEXTW(selmon->ltsymbol)) - click = ClkLtSymbol; - else - click = ClkStatusText; - } else if ((c = wintoclient(ev->window))) { - focus(c); - restack(selmon); - XAllowEvents(dpy, ReplayPointer, CurrentTime); - click = ClkClientWin; - } - for (i = 0; i < LENGTH(buttons); i++) - if (click == buttons[i].click && buttons[i].func && buttons[i].button == ev->button - && CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state)) - buttons[i].func(click == ClkTagBar && buttons[i].arg.i == 0 ? &arg : &buttons[i].arg); -} - -void -checkotherwm(void) -{ - xerrorxlib = XSetErrorHandler(xerrorstart); - /* this causes an error if some other window manager is running */ - XSelectInput(dpy, DefaultRootWindow(dpy), SubstructureRedirectMask); - XSync(dpy, False); - XSetErrorHandler(xerror); - XSync(dpy, False); -} - -void -cleanup(void) -{ - Arg a = {.ui = ~0}; - Layout foo = { "", NULL }; - Monitor *m; - size_t i; - - view(&a); - selmon->lt[selmon->sellt] = &foo; - for (m = mons; m; m = m->next) - while (m->stack) - unmanage(m->stack, 0); - XUngrabKey(dpy, AnyKey, AnyModifier, root); - while (mons) - cleanupmon(mons); - for (i = 0; i < CurLast; i++) - drw_cur_free(drw, cursor[i]); - for (i = 0; i < LENGTH(colors); i++) - free(scheme[i]); - free(scheme); - XDestroyWindow(dpy, wmcheckwin); - drw_free(drw); - XSync(dpy, False); - XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime); - XDeleteProperty(dpy, root, netatom[NetActiveWindow]); -} - -void -cleanupmon(Monitor *mon) -{ - Monitor *m; - - if (mon == mons) - mons = mons->next; - else { - for (m = mons; m && m->next != mon; m = m->next); - m->next = mon->next; - } - XUnmapWindow(dpy, mon->barwin); - XDestroyWindow(dpy, mon->barwin); - free(mon); -} - -void -clientmessage(XEvent *e) -{ - XClientMessageEvent *cme = &e->xclient; - Client *c = wintoclient(cme->window); - - if (!c) - return; - if (cme->message_type == netatom[NetWMState]) { - if (cme->data.l[1] == netatom[NetWMFullscreen] - || cme->data.l[2] == netatom[NetWMFullscreen]) - setfullscreen(c, (cme->data.l[0] == 1 /* _NET_WM_STATE_ADD */ - || (cme->data.l[0] == 2 /* _NET_WM_STATE_TOGGLE */ && !c->isfullscreen))); - } else if (cme->message_type == netatom[NetActiveWindow]) { - if (c != selmon->sel && !c->isurgent) - seturgent(c, 1); - } -} - -void -configure(Client *c) -{ - XConfigureEvent ce; - - ce.type = ConfigureNotify; - ce.display = dpy; - ce.event = c->win; - ce.window = c->win; - ce.x = c->x; - ce.y = c->y; - ce.width = c->w; - ce.height = c->h; - ce.border_width = c->bw; - ce.above = None; - ce.override_redirect = False; - XSendEvent(dpy, c->win, False, StructureNotifyMask, (XEvent *)&ce); -} - -void -configurenotify(XEvent *e) -{ - Monitor *m; - Client *c; - XConfigureEvent *ev = &e->xconfigure; - int dirty; - - /* TODO: updategeom handling sucks, needs to be simplified */ - if (ev->window == root) { - dirty = (sw != ev->width || sh != ev->height); - sw = ev->width; - sh = ev->height; - if (updategeom() || dirty) { - drw_resize(drw, sw, bh); - updatebars(); - for (m = mons; m; m = m->next) { - for (c = m->clients; c; c = c->next) - if (c->isfullscreen) - resizeclient(c, m->mx, m->my, m->mw, m->mh); - XMoveResizeWindow(dpy, m->barwin, m->wx + sp, m->by + vp, m->ww - 2 * sp, bh); - } - focus(NULL); - arrange(NULL); - } - } -} - -void -configurerequest(XEvent *e) -{ - Client *c; - Monitor *m; - XConfigureRequestEvent *ev = &e->xconfigurerequest; - XWindowChanges wc; - - if ((c = wintoclient(ev->window))) { - if (ev->value_mask & CWBorderWidth) - c->bw = ev->border_width; - else if (c->isfloating || !selmon->lt[selmon->sellt]->arrange) { - m = c->mon; - if (ev->value_mask & CWX) { - c->oldx = c->x; - c->x = m->mx + ev->x; - } - if (ev->value_mask & CWY) { - c->oldy = c->y; - c->y = m->my + ev->y; - } - if (ev->value_mask & CWWidth) { - c->oldw = c->w; - c->w = ev->width; - } - if (ev->value_mask & CWHeight) { - c->oldh = c->h; - c->h = ev->height; - } - if ((c->x + c->w) > m->mx + m->mw && c->isfloating) - c->x = m->mx + (m->mw / 2 - WIDTH(c) / 2); /* center in x direction */ - if ((c->y + c->h) > m->my + m->mh && c->isfloating) - c->y = m->my + (m->mh / 2 - HEIGHT(c) / 2); /* center in y direction */ - if ((ev->value_mask & (CWX|CWY)) && !(ev->value_mask & (CWWidth|CWHeight))) - configure(c); - if (ISVISIBLE(c)) - XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h); - } else - configure(c); - } else { - wc.x = ev->x; - wc.y = ev->y; - wc.width = ev->width; - wc.height = ev->height; - wc.border_width = ev->border_width; - wc.sibling = ev->above; - wc.stack_mode = ev->detail; - XConfigureWindow(dpy, ev->window, ev->value_mask, &wc); - } - XSync(dpy, False); -} - -Monitor * -createmon(void) -{ - Monitor *m; - - m = ecalloc(1, sizeof(Monitor)); - m->tagset[0] = m->tagset[1] = 1; - m->mfact = mfact; - m->nmaster = nmaster; - m->showbar = showbar; - m->topbar = topbar; - m->gappx = gappx; - m->lt[0] = &layouts[0]; - m->lt[1] = &layouts[1 % LENGTH(layouts)]; - strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol); - return m; -} - -void -destroynotify(XEvent *e) -{ - Client *c; - XDestroyWindowEvent *ev = &e->xdestroywindow; - - if ((c = wintoclient(ev->window))) - unmanage(c, 1); -} - -void -detach(Client *c) -{ - Client **tc; - - for (tc = &c->mon->clients; *tc && *tc != c; tc = &(*tc)->next); - *tc = c->next; -} - -void -detachstack(Client *c) -{ - Client **tc, *t; - - for (tc = &c->mon->stack; *tc && *tc != c; tc = &(*tc)->snext); - *tc = c->snext; - - if (c == c->mon->sel) { - for (t = c->mon->stack; t && !ISVISIBLE(t); t = t->snext); - c->mon->sel = t; - } -} - -Monitor * -dirtomon(int dir) -{ - Monitor *m = NULL; - - if (dir > 0) { - if (!(m = selmon->next)) - m = mons; - } else if (selmon == mons) - for (m = mons; m->next; m = m->next); - else - for (m = mons; m->next != selmon; m = m->next); - return m; -} - -void -drawbar(Monitor *m) -{ - int x, w, tw = 0; - unsigned int i, occ = 0, urg = 0; - Client *c; - - if (!m->showbar) - return; - - /* draw status first so it can be overdrawn by tags later */ - if (m == selmon || 1) { /* status is only drawn on selected monitor */ - drw_setscheme(drw, scheme[SchemeNorm]); - tw = TEXTW(stext) - lrpad + 2; /* 2px right padding */ - drw_text(drw, m->ww - tw - 2 * sp, 0, tw, bh, 0, stext, 0); - } - - for (c = m->clients; c; c = c->next) { - occ |= c->tags; - if (c->isurgent) - urg |= c->tags; - } - x = 0; - for (i = 0; i < LENGTH(tags); i++) { - w = TEXTW(tags[i]); - drw_setscheme(drw, scheme[m->tagset[m->seltags] & 1 << i ? SchemeSel : SchemeNorm]); - drw_text(drw, x, 0, w, bh, lrpad / 2, tags[i], urg & 1 << i); - x += w; - } - w = TEXTW(m->ltsymbol); - drw_setscheme(drw, scheme[SchemeNorm]); - x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0); - - if ((w = m->ww - tw - x) > bh) { - drw_setscheme(drw, scheme[SchemeNorm]); - drw_rect(drw, x, 0, w - 2 * sp, bh, 1, 1); - } - drw_map(drw, m->barwin, 0, 0, m->ww, bh); -} - -void -drawbars(void) -{ - Monitor *m; - - for (m = mons; m; m = m->next) - drawbar(m); -} - -void -enternotify(XEvent *e) -{ - Client *c; - Monitor *m; - XCrossingEvent *ev = &e->xcrossing; - - if ((ev->mode != NotifyNormal || ev->detail == NotifyInferior) && ev->window != root) - return; - c = wintoclient(ev->window); - m = c ? c->mon : wintomon(ev->window); - if (m != selmon) { - unfocus(selmon->sel, 1); - selmon = m; - } else if (!c || c == selmon->sel) - return; - focus(c); -} - -void -expose(XEvent *e) -{ - Monitor *m; - XExposeEvent *ev = &e->xexpose; - - if (ev->count == 0 && (m = wintomon(ev->window))) - drawbar(m); -} - -void -focus(Client *c) -{ - if (!c || !ISVISIBLE(c)) - for (c = selmon->stack; c && !ISVISIBLE(c); c = c->snext); - if (selmon->sel && selmon->sel != c) - unfocus(selmon->sel, 0); - if (c) { - if (c->mon != selmon) - selmon = c->mon; - if (c->isurgent) - seturgent(c, 0); - detachstack(c); - attachstack(c); - grabbuttons(c, 1); - XSetWindowBorder(dpy, c->win, scheme[SchemeSel][ColBorder].pixel); - setfocus(c); - } else { - XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime); - XDeleteProperty(dpy, root, netatom[NetActiveWindow]); - } - selmon->sel = c; - drawbars(); -} - -/* there are some broken focus acquiring clients needing extra handling */ -void -focusin(XEvent *e) -{ - XFocusChangeEvent *ev = &e->xfocus; - - if (selmon->sel && ev->window != selmon->sel->win) - setfocus(selmon->sel); -} - -void -focusmon(const Arg *arg) -{ - Monitor *m; - - if (!mons->next) - return; - if ((m = dirtomon(arg->i)) == selmon) - return; - unfocus(selmon->sel, 0); - selmon = m; - focus(NULL); - warp(selmon->sel); -} - -void -focusstack(const Arg *arg) -{ - Client *c = NULL, *i; - - if (!selmon->sel || (selmon->sel->isfullscreen && lockfullscreen)) - return; - if (arg->i > 0) { - for (c = selmon->sel->next; c && !ISVISIBLE(c); c = c->next); - if (!c) - for (c = selmon->clients; c && !ISVISIBLE(c); c = c->next); - } else { - for (i = selmon->clients; i != selmon->sel; i = i->next) - if (ISVISIBLE(i)) - c = i; - if (!c) - for (; i; i = i->next) - if (ISVISIBLE(i)) - c = i; - } - if (c) { - focus(c); - restack(selmon); - } -} - -Atom -getatomprop(Client *c, Atom prop) -{ - int di; - unsigned long dl; - unsigned char *p = NULL; - Atom da, atom = None; - - if (XGetWindowProperty(dpy, c->win, prop, 0L, sizeof atom, False, XA_ATOM, - &da, &di, &dl, &dl, &p) == Success && p) { - atom = *(Atom *)p; - XFree(p); - } - return atom; -} - -int -getrootptr(int *x, int *y) -{ - int di; - unsigned int dui; - Window dummy; - - return XQueryPointer(dpy, root, &dummy, &dummy, x, y, &di, &di, &dui); -} - -long -getstate(Window w) -{ - int format; - long result = -1; - unsigned char *p = NULL; - unsigned long n, extra; - Atom real; - - if (XGetWindowProperty(dpy, w, wmatom[WMState], 0L, 2L, False, wmatom[WMState], - &real, &format, &n, &extra, (unsigned char **)&p) != Success) - return -1; - if (n != 0) - result = *p; - XFree(p); - return result; -} - -int -gettextprop(Window w, Atom atom, char *text, unsigned int size) -{ - char **list = NULL; - int n; - XTextProperty name; - - if (!text || size == 0) - return 0; - text[0] = '\0'; - if (!XGetTextProperty(dpy, w, &name, atom) || !name.nitems) - return 0; - if (name.encoding == XA_STRING) { - strncpy(text, (char *)name.value, size - 1); - } else if (XmbTextPropertyToTextList(dpy, &name, &list, &n) >= Success && n > 0 && *list) { - strncpy(text, *list, size - 1); - XFreeStringList(list); - } - text[size - 1] = '\0'; - XFree(name.value); - return 1; -} - -void -grabbuttons(Client *c, int focused) -{ - updatenumlockmask(); - { - unsigned int i, j; - unsigned int modifiers[] = { 0, LockMask, numlockmask, numlockmask|LockMask }; - XUngrabButton(dpy, AnyButton, AnyModifier, c->win); - if (!focused) - XGrabButton(dpy, AnyButton, AnyModifier, c->win, False, - BUTTONMASK, GrabModeSync, GrabModeSync, None, None); - for (i = 0; i < LENGTH(buttons); i++) - if (buttons[i].click == ClkClientWin) - for (j = 0; j < LENGTH(modifiers); j++) - XGrabButton(dpy, buttons[i].button, - buttons[i].mask | modifiers[j], - c->win, False, BUTTONMASK, - GrabModeAsync, GrabModeSync, None, None); - } -} - -void -grabkeys(void) -{ - updatenumlockmask(); - { - unsigned int i, j, k; - unsigned int modifiers[] = { 0, LockMask, numlockmask, numlockmask|LockMask }; - int start, end, skip; - KeySym *syms; - - XUngrabKey(dpy, AnyKey, AnyModifier, root); - XDisplayKeycodes(dpy, &start, &end); - syms = XGetKeyboardMapping(dpy, start, end - start + 1, &skip); - if (!syms) - return; - for (k = start; k <= end; k++) - for (i = 0; i < LENGTH(keys); i++) - /* skip modifier codes, we do that ourselves */ - if (keys[i].keysym == syms[(k - start) * skip]) - for (j = 0; j < LENGTH(modifiers); j++) - XGrabKey(dpy, k, - keys[i].mod | modifiers[j], - root, True, - GrabModeAsync, GrabModeAsync); - XFree(syms); - } -} - -void -incnmaster(const Arg *arg) -{ - selmon->nmaster = MAX(selmon->nmaster + arg->i, 0); - arrange(selmon); -} - -#ifdef XINERAMA -static int -isuniquegeom(XineramaScreenInfo *unique, size_t n, XineramaScreenInfo *info) -{ - while (n--) - if (unique[n].x_org == info->x_org && unique[n].y_org == info->y_org - && unique[n].width == info->width && unique[n].height == info->height) - return 0; - return 1; -} -#endif /* XINERAMA */ - -void -keypress(XEvent *e) -{ - unsigned int i; - KeySym keysym; - XKeyEvent *ev; - - ev = &e->xkey; - keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0); - for (i = 0; i < LENGTH(keys); i++) - if (keysym == keys[i].keysym - && CLEANMASK(keys[i].mod) == CLEANMASK(ev->state) - && keys[i].func) - keys[i].func(&(keys[i].arg)); -} - -void -killclient(const Arg *arg) -{ - if (!selmon->sel) - return; - if (!sendevent(selmon->sel, wmatom[WMDelete])) { - XGrabServer(dpy); - XSetErrorHandler(xerrordummy); - XSetCloseDownMode(dpy, DestroyAll); - XKillClient(dpy, selmon->sel->win); - XSync(dpy, False); - XSetErrorHandler(xerror); - XUngrabServer(dpy); - } -} - -void -loadxrdb() -{ - Display *display; - char * resm; - XrmDatabase xrdb; - char *type; - XrmValue value; - - display = XOpenDisplay(NULL); - - if (display != NULL) { - resm = XResourceManagerString(display); - - if (resm != NULL) { - xrdb = XrmGetStringDatabase(resm); - - if (xrdb != NULL) { - XRDB_LOAD_COLOR("dwm.color2", normbordercolor); - XRDB_LOAD_COLOR("dwm.background", normbgcolor); - XRDB_LOAD_COLOR("dwm.color7", normfgcolor); - XRDB_LOAD_COLOR("dwm.color6", selbordercolor); - XRDB_LOAD_COLOR("dwm.color11", selbgcolor); - XRDB_LOAD_COLOR("dwm.color15", selfgcolor); - } - } - } - - XCloseDisplay(display); -} - -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->wx + c->mon->ww) - c->x = c->mon->wx + c->mon->ww - WIDTH(c); - if (c->y + HEIGHT(c) > c->mon->wy + c->mon->wh) - c->y = c->mon->wy + c->mon->wh - HEIGHT(c); - c->x = MAX(c->x, c->mon->wx); - c->y = MAX(c->y, c->mon->wy); - c->bw = borderpx; - - wc.border_width = c->bw; - XConfigureWindow(dpy, w, CWBorderWidth, &wc); - XSetWindowBorder(dpy, w, scheme[SchemeNorm][ColBorder].pixel); - configure(c); /* propagates border_width, if size doesn't change */ - updatewindowtype(c); - updatesizehints(c); - updatewmhints(c); - XSelectInput(dpy, w, EnterWindowMask|FocusChangeMask|PropertyChangeMask|StructureNotifyMask); - grabbuttons(c, 0); - if (!c->isfloating) - c->isfloating = c->oldstate = trans != None || c->isfixed; - if (c->isfloating) - XRaiseWindow(dpy, c->win); - attach(c); - attachstack(c); - XChangeProperty(dpy, root, netatom[NetClientList], XA_WINDOW, 32, PropModeAppend, - (unsigned char *) &(c->win), 1); - XMoveResizeWindow(dpy, c->win, c->x + 2 * sw, c->y, c->w, c->h); /* some windows require this */ - setclientstate(c, NormalState); - if (c->mon == selmon) - unfocus(selmon->sel, 0); - c->mon->sel = c; - arrange(c->mon); - XMapWindow(dpy, c->win); - focus(NULL); -} - -void -mappingnotify(XEvent *e) -{ - XMappingEvent *ev = &e->xmapping; - - XRefreshKeyboardMapping(ev); - if (ev->request == MappingKeyboard) - grabkeys(); -} - -void -maprequest(XEvent *e) -{ - static XWindowAttributes wa; - XMapRequestEvent *ev = &e->xmaprequest; - - if (!XGetWindowAttributes(dpy, ev->window, &wa) || 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, ""); - for (c = nexttiled(m->clients); c; c = nexttiled(c->next)) - resize(c, m->wx, m->wy, m->ww - 2 * c->bw, m->wh - 2 * c->bw, 0); -} - -void -motionnotify(XEvent *e) -{ - static Monitor *mon = NULL; - Monitor *m; - XMotionEvent *ev = &e->xmotion; - - if (ev->window != root) - return; - if ((m = recttomon(ev->x_root, ev->y_root, 1, 1)) != mon && mon) { - unfocus(selmon->sel, 1); - selmon = m; - focus(NULL); - } - mon = m; -} - -void -movemouse(const Arg *arg) -{ - int x, y, ocx, ocy, nx, ny; - Client *c; - Monitor *m; - XEvent ev; - Time lasttime = 0; - - if (!(c = selmon->sel)) - return; - if (c->isfullscreen) /* no support moving fullscreen windows by mouse */ - return; - restack(selmon); - ocx = c->x; - ocy = c->y; - if (XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync, - None, cursor[CurMove]->cursor, CurrentTime) != GrabSuccess) - return; - if (!getrootptr(&x, &y)) - return; - do { - XMaskEvent(dpy, MOUSEMASK|ExposureMask|SubstructureRedirectMask, &ev); - switch(ev.type) { - case ConfigureRequest: - case Expose: - case MapRequest: - handler[ev.type](&ev); - break; - case MotionNotify: - if ((ev.xmotion.time - lasttime) <= (1000 / 60)) - continue; - lasttime = ev.xmotion.time; - - nx = ocx + (ev.xmotion.x - x); - ny = ocy + (ev.xmotion.y - y); - if (abs(selmon->wx - nx) < snap) - nx = selmon->wx; - else if (abs((selmon->wx + selmon->ww) - (nx + WIDTH(c))) < snap) - nx = selmon->wx + selmon->ww - WIDTH(c); - if (abs(selmon->wy - ny) < snap) - ny = selmon->wy; - else if (abs((selmon->wy + selmon->wh) - (ny + HEIGHT(c))) < snap) - ny = selmon->wy + selmon->wh - HEIGHT(c); - if (!c->isfloating && selmon->lt[selmon->sellt]->arrange - && (abs(nx - c->x) > snap || abs(ny - c->y) > snap)) - togglefloating(NULL); - if (!selmon->lt[selmon->sellt]->arrange || c->isfloating) - resize(c, nx, ny, c->w, c->h, 1); - break; - } - } while (ev.type != ButtonRelease); - XUngrabPointer(dpy, CurrentTime); - if ((m = recttomon(c->x, c->y, c->w, c->h)) != selmon) { - sendmon(c, m); - selmon = m; - focus(NULL); - } -} - -Client * -nexttiled(Client *c) -{ - for (; c && (c->isfloating || !ISVISIBLE(c)); c = c->next); - return c; -} - -void -pop(Client *c) -{ - detach(c); - attach(c); - focus(c); - arrange(c->mon); -} - -void -propertynotify(XEvent *e) -{ - Client *c; - Window trans; - XPropertyEvent *ev = &e->xproperty; - - if ((ev->window == root) && (ev->atom == XA_WM_NAME)) - updatestatus(); - else if (ev->state == PropertyDelete) - return; /* ignore */ - else if ((c = wintoclient(ev->window))) { - switch(ev->atom) { - default: break; - case XA_WM_TRANSIENT_FOR: - if (!c->isfloating && (XGetTransientForHint(dpy, c->win, &trans)) && - (c->isfloating = (wintoclient(trans)) != NULL)) - arrange(c->mon); - break; - case XA_WM_NORMAL_HINTS: - c->hintsvalid = 0; - break; - case XA_WM_HINTS: - updatewmhints(c); - drawbars(); - break; - } - if (ev->atom == XA_WM_NAME || ev->atom == netatom[NetWMName]) - updatetitle(c); - if (ev->atom == netatom[NetWMWindowType]) - updatewindowtype(c); - } -} - -void -quit(const Arg *arg) -{ - if(arg->i) restart = 1; - running = 0; -} - -Monitor * -recttomon(int x, int y, int w, int h) -{ - Monitor *m, *r = selmon; - int a, area = 0; - - for (m = mons; m; m = m->next) - if ((a = INTERSECT(x, y, w, h, m)) > area) { - area = a; - r = m; - } - return r; -} - -void -resize(Client *c, int x, int y, int w, int h, int interact) -{ - if (applysizehints(c, &x, &y, &w, &h, interact)) - resizeclient(c, x, y, w, h); -} - -void -resizeclient(Client *c, int x, int y, int w, int h) -{ - XWindowChanges wc; - - c->oldx = c->x; c->x = wc.x = x; - c->oldy = c->y; c->y = wc.y = y; - c->oldw = c->w; c->w = wc.width = w; - c->oldh = c->h; c->h = wc.height = h; - wc.border_width = c->bw; - XConfigureWindow(dpy, c->win, CWX|CWY|CWWidth|CWHeight|CWBorderWidth, &wc); - configure(c); - XSync(dpy, False); -} - -void -resizemouse(const Arg *arg) -{ - int x, y, ocw, och, 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); - ocw = c->w; - och = c->h; - if (XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync, - None, cursor[CurResize]->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; - - nw = MAX(ocw + (ev.xmotion.x - x), 1); - nh = MAX(och + (ev.xmotion.y - y), 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); - XUngrabPointer(dpy, CurrentTime); - while (XCheckMaskEvent(dpy, EnterWindowMask, &ev)); - if ((m = recttomon(c->x, c->y, c->w, c->h)) != selmon) { - sendmon(c, m); - selmon = m; - focus(NULL); - } -} - -void -restack(Monitor *m) -{ - Client *c; - XEvent ev; - XWindowChanges wc; - - drawbar(m); - if (!m->sel) - return; - if (m->sel->isfloating || !m->lt[m->sellt]->arrange) - XRaiseWindow(dpy, m->sel->win); - if (m->lt[m->sellt]->arrange) { - wc.stack_mode = Below; - wc.sibling = m->barwin; - for (c = m->stack; c; c = c->snext) - if (!c->isfloating && ISVISIBLE(c)) { - XConfigureWindow(dpy, c->win, CWSibling|CWStackMode, &wc); - wc.sibling = c->win; - } - } - if (m == selmon && (m->tagset[m->seltags] & m->sel->tags) && m->lt[m->sellt]->arrange != &monocle) - warp(m->sel); - XSync(dpy, False); - while (XCheckMaskEvent(dpy, EnterWindowMask, &ev)); -} - -void -run(void) -{ - XEvent ev; - /* main event loop */ - XSync(dpy, False); - while (running && !XNextEvent(dpy, &ev)) - if (handler[ev.type]) - handler[ev.type](&ev); /* call handler */ -} - -void -scan(void) -{ - unsigned int i, num; - Window d1, d2, *wins = NULL; - XWindowAttributes wa; - - if (XQueryTree(dpy, root, &d1, &d2, &wins, &num)) { - for (i = 0; i < num; i++) { - if (!XGetWindowAttributes(dpy, wins[i], &wa) - || wa.override_redirect || XGetTransientForHint(dpy, wins[i], &d1)) - continue; - if (wa.map_state == IsViewable || getstate(wins[i]) == IconicState) - manage(wins[i], &wa); - } - for (i = 0; i < num; i++) { /* now the transients */ - if (!XGetWindowAttributes(dpy, wins[i], &wa)) - continue; - if (XGetTransientForHint(dpy, wins[i], &d1) - && (wa.map_state == IsViewable || getstate(wins[i]) == IconicState)) - manage(wins[i], &wa); - } - if (wins) - XFree(wins); - } -} - -void -sendmon(Client *c, Monitor *m) -{ - if (c->mon == m) - return; - unfocus(c, 1); - detach(c); - detachstack(c); - c->mon = m; - c->tags = m->tagset[m->seltags]; /* assign tags of target monitor */ - attach(c); - attachstack(c); - focus(NULL); - arrange(NULL); -} - -void -setclientstate(Client *c, long state) -{ - long data[] = { state, None }; - - XChangeProperty(dpy, c->win, wmatom[WMState], wmatom[WMState], 32, - PropModeReplace, (unsigned char *)data, 2); -} - -int -sendevent(Client *c, Atom proto) -{ - int n; - Atom *protocols; - int exists = 0; - XEvent ev; - - if (XGetWMProtocols(dpy, c->win, &protocols, &n)) { - while (!exists && n--) - exists = protocols[n] == proto; - XFree(protocols); - } - if (exists) { - ev.type = ClientMessage; - ev.xclient.window = c->win; - ev.xclient.message_type = wmatom[WMProtocols]; - ev.xclient.format = 32; - ev.xclient.data.l[0] = proto; - ev.xclient.data.l[1] = CurrentTime; - XSendEvent(dpy, c->win, False, NoEventMask, &ev); - } - return exists; -} - -void -setfocus(Client *c) -{ - if (!c->neverfocus) { - XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime); - XChangeProperty(dpy, root, netatom[NetActiveWindow], - XA_WINDOW, 32, PropModeReplace, - (unsigned char *) &(c->win), 1); - } - sendevent(c, wmatom[WMTakeFocus]); -} - -void -setfullscreen(Client *c, int fullscreen) -{ - if (fullscreen && !c->isfullscreen) { - XChangeProperty(dpy, c->win, netatom[NetWMState], XA_ATOM, 32, - PropModeReplace, (unsigned char*)&netatom[NetWMFullscreen], 1); - c->isfullscreen = 1; - c->oldstate = c->isfloating; - c->oldbw = c->bw; - c->bw = 0; - c->isfloating = 1; - resizeclient(c, c->mon->mx, c->mon->my, c->mon->mw, c->mon->mh); - XRaiseWindow(dpy, c->win); - } else if (!fullscreen && c->isfullscreen){ - XChangeProperty(dpy, c->win, netatom[NetWMState], XA_ATOM, 32, - PropModeReplace, (unsigned char*)0, 0); - c->isfullscreen = 0; - c->isfloating = c->oldstate; - c->bw = c->oldbw; - c->x = c->oldx; - c->y = c->oldy; - c->w = c->oldw; - c->h = c->oldh; - resizeclient(c, c->x, c->y, c->w, c->h); - arrange(c->mon); - } -} - -void -setgaps(const Arg *arg) -{ - if ((arg->i == 0) || (selmon->gappx + arg->i < 0)) - selmon->gappx = 0; - else - selmon->gappx += arg->i; - arrange(selmon); -} - -void -setlayout(const Arg *arg) -{ - if (!arg || !arg->v || arg->v != selmon->lt[selmon->sellt]) - selmon->sellt ^= 1; - if (arg && arg->v) - selmon->lt[selmon->sellt] = (Layout *)arg->v; - strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, sizeof selmon->ltsymbol); - if (selmon->sel) - arrange(selmon); - else - drawbar(selmon); -} - -/* arg > 1.0 will set mfact absolutely */ -void -setmfact(const Arg *arg) -{ - float f; - - if (!arg || !selmon->lt[selmon->sellt]->arrange) - return; - f = arg->f < 1.0 ? arg->f + selmon->mfact : arg->f - 1.0; - if (f < 0.05 || f > 0.95) - return; - selmon->mfact = f; - arrange(selmon); -} - -void -setup(void) -{ - int i; - XSetWindowAttributes wa; - Atom utf8string; - struct sigaction sa; - - /* do not transform children into zombies when they terminate */ - sigemptyset(&sa.sa_mask); - sa.sa_flags = SA_NOCLDSTOP | SA_NOCLDWAIT | SA_RESTART; - sa.sa_handler = SIG_IGN; - sigaction(SIGCHLD, &sa, NULL); - - /* clean up any zombies (inherited from .xinitrc etc) immediately */ - while (waitpid(-1, NULL, WNOHANG) > 0); - - signal(SIGHUP, sighup); - signal(SIGTERM, sigterm); - - /* 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 + user_bh; - - sp = sidepad; - vp = (topbar == 1) ? vertpad : - vertpad; - updategeom(); - - /* init atoms */ - utf8string = XInternAtom(dpy, "UTF8_STRING", False); - wmatom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False); - wmatom[WMDelete] = XInternAtom(dpy, "WM_DELETE_WINDOW", False); - wmatom[WMState] = XInternAtom(dpy, "WM_STATE", False); - wmatom[WMTakeFocus] = XInternAtom(dpy, "WM_TAKE_FOCUS", False); - netatom[NetActiveWindow] = XInternAtom(dpy, "_NET_ACTIVE_WINDOW", False); - netatom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False); - netatom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False); - netatom[NetWMState] = XInternAtom(dpy, "_NET_WM_STATE", False); - netatom[NetWMCheck] = XInternAtom(dpy, "_NET_SUPPORTING_WM_CHECK", False); - netatom[NetWMFullscreen] = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False); - netatom[NetWMWindowType] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False); - netatom[NetWMWindowTypeDialog] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DIALOG", False); - netatom[NetClientList] = XInternAtom(dpy, "_NET_CLIENT_LIST", False); - /* init cursors */ - cursor[CurNormal] = drw_cur_create(drw, XC_left_ptr); - cursor[CurResize] = drw_cur_create(drw, XC_sizing); - cursor[CurMove] = drw_cur_create(drw, XC_fleur); - /* init appearance */ - scheme = ecalloc(LENGTH(colors), sizeof(Clr *)); - for (i = 0; i < LENGTH(colors); i++) - scheme[i] = drw_scm_create(drw, colors[i], 3); - /* init bars */ - updatebars(); - updatestatus(); - /* supporting window for NetWMCheck */ - wmcheckwin = XCreateSimpleWindow(dpy, root, 0, 0, 1, 1, 0, 0, 0); - XChangeProperty(dpy, wmcheckwin, netatom[NetWMCheck], XA_WINDOW, 32, - PropModeReplace, (unsigned char *) &wmcheckwin, 1); - XChangeProperty(dpy, wmcheckwin, netatom[NetWMName], utf8string, 8, - PropModeReplace, (unsigned char *) "dwm", 3); - XChangeProperty(dpy, root, netatom[NetWMCheck], XA_WINDOW, 32, - PropModeReplace, (unsigned char *) &wmcheckwin, 1); - /* EWMH support per view */ - XChangeProperty(dpy, root, netatom[NetSupported], XA_ATOM, 32, - PropModeReplace, (unsigned char *) netatom, NetLast); - XDeleteProperty(dpy, root, netatom[NetClientList]); - /* select events */ - wa.cursor = cursor[CurNormal]->cursor; - wa.event_mask = SubstructureRedirectMask|SubstructureNotifyMask - |ButtonPressMask|PointerMotionMask|EnterWindowMask - |LeaveWindowMask|StructureNotifyMask|PropertyChangeMask; - XChangeWindowAttributes(dpy, root, CWEventMask|CWCursor, &wa); - XSelectInput(dpy, root, wa.event_mask); - grabkeys(); - focus(NULL); -} - -void -seturgent(Client *c, int urg) -{ - XWMHints *wmh; - - c->isurgent = urg; - if (!(wmh = XGetWMHints(dpy, c->win))) - return; - wmh->flags = urg ? (wmh->flags | XUrgencyHint) : (wmh->flags & ~XUrgencyHint); - XSetWMHints(dpy, c->win, wmh); - XFree(wmh); -} - -void -showhide(Client *c) -{ - if (!c) - return; - if (ISVISIBLE(c)) { - /* show clients top down */ - XMoveWindow(dpy, c->win, c->x, c->y); - if ((!c->mon->lt[c->mon->sellt]->arrange || c->isfloating) && !c->isfullscreen) - resize(c, c->x, c->y, c->w, c->h, 0); - showhide(c->snext); - } else { - /* hide clients bottom up */ - showhide(c->snext); - XMoveWindow(dpy, c->win, WIDTH(c) * -2, c->y); - } -} - -void -sighup(int unused) -{ - Arg a = {.i = 1}; - quit(&a); -} - -void -sigterm(int unused) -{ - Arg a = {.i = 0}; - quit(&a); -} - -void -spawn(const Arg *arg) -{ - struct sigaction sa; - - if (arg->v == dmenucmd) - dmenumon[0] = '0' + selmon->num; - if (fork() == 0) { - if (dpy) - close(ConnectionNumber(dpy)); - setsid(); - - sigemptyset(&sa.sa_mask); - sa.sa_flags = 0; - sa.sa_handler = SIG_DFL; - sigaction(SIGCHLD, &sa, NULL); - - execvp(((char **)arg->v)[0], (char **)arg->v); - die("dwm: execvp '%s' failed:", ((char **)arg->v)[0]); - } -} - -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 - m->gappx; - for (i = 0, my = ty = m->gappx, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) - if (i < m->nmaster) { - h = (m->wh - my) / (MIN(n, m->nmaster) - i) - m->gappx; - resize(c, m->wx + m->gappx, m->wy + my, mw - (2*c->bw) - m->gappx, h - (2*c->bw), 0); - if (my + HEIGHT(c) + m->gappx < m->wh) - my += HEIGHT(c) + m->gappx; - } else { - h = (m->wh - ty) / (n - i) - m->gappx; - resize(c, m->wx + mw + m->gappx, m->wy + ty, m->ww - mw - (2*c->bw) - 2*m->gappx, h - (2*c->bw), 0); - if (ty + HEIGHT(c) + m->gappx < m->wh) - ty += HEIGHT(c) + m->gappx; - } -} - -void -togglebar(const Arg *arg) -{ - selmon->showbar = !selmon->showbar; - updatebarpos(selmon); - XMoveResizeWindow(dpy, selmon->barwin, selmon->wx + sp, selmon->by + vp, selmon->ww - 2 * sp, bh); - arrange(selmon); -} - -void -togglefloating(const Arg *arg) -{ - if (!selmon->sel) - return; - if (selmon->sel->isfullscreen) /* no support for fullscreen windows */ - return; - selmon->sel->isfloating = !selmon->sel->isfloating || selmon->sel->isfixed; - if (selmon->sel->isfloating) - resize(selmon->sel, selmon->sel->x, selmon->sel->y, - selmon->sel->w, selmon->sel->h, 0); - arrange(selmon); -} - -void -toggletag(const Arg *arg) -{ - unsigned int newtags; - - if (!selmon->sel) - return; - newtags = selmon->sel->tags ^ (arg->ui & TAGMASK); - if (newtags) { - selmon->sel->tags = newtags; - focus(NULL); - arrange(selmon); - } -} - -void -toggleview(const Arg *arg) -{ - unsigned int newtagset = selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK); - - if (newtagset) { - selmon->tagset[selmon->seltags] = newtagset; - focus(NULL); - arrange(selmon); - } -} - -void -unfocus(Client *c, int setfocus) -{ - if (!c) - return; - grabbuttons(c, 0); - XSetWindowBorder(dpy, c->win, scheme[SchemeNorm][ColBorder].pixel); - if (setfocus) { - XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime); - XDeleteProperty(dpy, root, netatom[NetActiveWindow]); - } -} - -void -unmanage(Client *c, int destroyed) -{ - Monitor *m = c->mon; - XWindowChanges wc; - - detach(c); - detachstack(c); - if (!destroyed) { - wc.border_width = c->oldbw; - XGrabServer(dpy); /* avoid race conditions */ - XSetErrorHandler(xerrordummy); - XSelectInput(dpy, c->win, NoEventMask); - XConfigureWindow(dpy, c->win, CWBorderWidth, &wc); /* restore border */ - XUngrabButton(dpy, AnyButton, AnyModifier, c->win); - setclientstate(c, WithdrawnState); - XSync(dpy, False); - XSetErrorHandler(xerror); - XUngrabServer(dpy); - } - free(c); - focus(NULL); - updateclientlist(); - arrange(m); -} - -void -unmapnotify(XEvent *e) -{ - Client *c; - XUnmapEvent *ev = &e->xunmap; - - if ((c = wintoclient(ev->window))) { - if (ev->send_event) - setclientstate(c, WithdrawnState); - else - unmanage(c, 0); - } -} - -void -updatebars(void) -{ - Monitor *m; - XSetWindowAttributes wa = { - .override_redirect = True, - .background_pixmap = ParentRelative, - .event_mask = ButtonPressMask|ExposureMask - }; - XClassHint ch = {"dwm", "dwm"}; - for (m = mons; m; m = m->next) { - if (m->barwin) - continue; - m->barwin = XCreateWindow(dpy, root, m->wx + sp, m->by + vp, m->ww - 2 * sp, bh, 0, DefaultDepth(dpy, screen), - CopyFromParent, DefaultVisual(dpy, screen), - CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa); - XDefineCursor(dpy, m->barwin, cursor[CurNormal]->cursor); - XMapRaised(dpy, m->barwin); - XSetClassHint(dpy, m->barwin, &ch); - } -} - -void -updatebarpos(Monitor *m) -{ - m->wy = m->my; - m->wh = m->mh; - if (m->showbar) { - m->wh = m->wh - vertpad - bh; - m->by = m->topbar ? m->wy : m->wy + m->wh + vertpad; - m->wy = m->topbar ? m->wy + bh + vp : m->wy; - } else - m->by = -bh - vp; -} - -void -updateclientlist(void) -{ - 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; - - /* new monitors if nn > n */ - for (i = n; i < nn; 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); - } - /* removed monitors if n > nn */ - for (i = nn; i < n; i++) { - for (m = mons; m && m->next; m = m->next); - while ((c = m->clients)) { - dirty = 1; - m->clients = c->next; - detachstack(c); - c->mon = mons; - attach(c); - attachstack(c); - } - if (m == selmon) - selmon = mons; - cleanupmon(m); - } - free(unique); - } else -#endif /* XINERAMA */ - { /* default monitor setup */ - if (!mons) - mons = createmon(); - if (mons->mw != sw || mons->mh != sh) { - dirty = 1; - mons->mw = mons->ww = sw; - mons->mh = mons->wh = sh; - updatebarpos(mons); - } - } - if (dirty) { - selmon = mons; - selmon = wintomon(root); - } - return dirty; -} - -void -updatenumlockmask(void) -{ - unsigned int i, j; - XModifierKeymap *modmap; - - numlockmask = 0; - modmap = XGetModifierMapping(dpy); - for (i = 0; i < 8; i++) - for (j = 0; j < modmap->max_keypermod; j++) - if (modmap->modifiermap[i * modmap->max_keypermod + j] - == XKeysymToKeycode(dpy, XK_Num_Lock)) - numlockmask = (1 << i); - XFreeModifiermap(modmap); -} - -void -updatesizehints(Client *c) -{ - long msize; - XSizeHints size; - - if (!XGetWMNormalHints(dpy, c->win, &size, &msize)) - /* size is uninitialized, ensure that size.flags aren't used */ - size.flags = PSize; - if (size.flags & PBaseSize) { - c->basew = size.base_width; - c->baseh = size.base_height; - } else if (size.flags & PMinSize) { - c->basew = size.min_width; - c->baseh = size.min_height; - } else - c->basew = c->baseh = 0; - if (size.flags & PResizeInc) { - c->incw = size.width_inc; - c->inch = size.height_inc; - } else - c->incw = c->inch = 0; - if (size.flags & PMaxSize) { - c->maxw = size.max_width; - c->maxh = size.max_height; - } else - c->maxw = c->maxh = 0; - if (size.flags & PMinSize) { - c->minw = size.min_width; - c->minh = size.min_height; - } else if (size.flags & PBaseSize) { - c->minw = size.base_width; - c->minh = size.base_height; - } else - c->minw = c->minh = 0; - if (size.flags & PAspect) { - c->mina = (float)size.min_aspect.y / size.min_aspect.x; - c->maxa = (float)size.max_aspect.x / size.max_aspect.y; - } else - c->maxa = c->mina = 0.0; - c->isfixed = (c->maxw && c->maxh && c->maxw == c->minw && c->maxh == c->minh); - c->hintsvalid = 1; -} - -void -updatestatus(void) -{ - Monitor* m; - if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext))) - strcpy(stext, "dwm-"VERSION); - for(m = mons; m; m = m->next) - drawbar(m); -} - -void -updatetitle(Client *c) -{ - if (!gettextprop(c->win, netatom[NetWMName], c->name, sizeof c->name)) - gettextprop(c->win, XA_WM_NAME, c->name, sizeof c->name); - if (c->name[0] == '\0') /* hack to mark broken clients */ - strcpy(c->name, broken); -} - -void -updatewindowtype(Client *c) -{ - Atom state = getatomprop(c, netatom[NetWMState]); - Atom wtype = getatomprop(c, netatom[NetWMWindowType]); - - if (state == netatom[NetWMFullscreen]) - setfullscreen(c, 1); - if (wtype == netatom[NetWMWindowTypeDialog]) - c->isfloating = 1; -} - -void -updatewmhints(Client *c) -{ - XWMHints *wmh; - - if ((wmh = XGetWMHints(dpy, c->win))) { - if (c == selmon->sel && wmh->flags & XUrgencyHint) { - wmh->flags &= ~XUrgencyHint; - XSetWMHints(dpy, c->win, wmh); - } else - c->isurgent = (wmh->flags & XUrgencyHint) ? 1 : 0; - if (wmh->flags & InputHint) - c->neverfocus = !wmh->input; - else - c->neverfocus = 0; - XFree(wmh); - } -} - -void -view(const Arg *arg) -{ - if ((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags]) - return; - selmon->seltags ^= 1; /* toggle sel tagset */ - if (arg->ui & TAGMASK) - selmon->tagset[selmon->seltags] = arg->ui & TAGMASK; - focus(NULL); - arrange(selmon); -} - -void -warp(const Client *c) -{ - int x, y; - - if (!c) { - XWarpPointer(dpy, None, root, 0, 0, 0, 0, selmon->wx + selmon->ww / 2, selmon->wy + selmon->wh / 2); - return; - } - - if (!getrootptr(&x, &y) || - (x > c->x - c->bw && - y > c->y - c->bw && - x < c->x + c->w + c->bw*2 && - y < c->y + c->h + c->bw*2) || - (y > c->mon->by && y < c->mon->by + bh) || - (c->mon->topbar && !y)) - return; - - XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w / 2, c->h / 2); -} - -Client * -wintoclient(Window w) -{ - Client *c; - Monitor *m; - - for (m = mons; m; m = m->next) - for (c = m->clients; c; c = c->next) - if (c->win == w) - return c; - return NULL; -} - -Monitor * -wintomon(Window w) -{ - int x, y; - Client *c; - Monitor *m; - - if (w == root && getrootptr(&x, &y)) - return recttomon(x, y, 1, 1); - for (m = mons; m; m = m->next) - if (w == m->barwin) - return m; - if ((c = wintoclient(w))) - return c->mon; - return selmon; -} - -/* There's no way to check accesses to destroyed windows, thus those cases are - * ignored (especially on UnmapNotify's). Other types of errors call Xlibs - * default error handler, which may call exit. */ -int -xerror(Display *dpy, XErrorEvent *ee) -{ - if (ee->error_code == BadWindow - || (ee->request_code == X_SetInputFocus && ee->error_code == BadMatch) - || (ee->request_code == X_PolyText8 && ee->error_code == BadDrawable) - || (ee->request_code == X_PolyFillRectangle && ee->error_code == BadDrawable) - || (ee->request_code == X_PolySegment && ee->error_code == BadDrawable) - || (ee->request_code == X_ConfigureWindow && ee->error_code == BadMatch) - || (ee->request_code == X_GrabButton && ee->error_code == BadAccess) - || (ee->request_code == X_GrabKey && ee->error_code == BadAccess) - || (ee->request_code == X_CopyArea && ee->error_code == BadDrawable)) - return 0; - fprintf(stderr, "dwm: fatal error: request code=%d, error code=%d\n", - ee->request_code, ee->error_code); - return xerrorxlib(dpy, ee); /* may call exit */ -} - -int -xerrordummy(Display *dpy, XErrorEvent *ee) -{ - return 0; -} - -/* Startup Error handler to check if another window manager - * is already running. */ -int -xerrorstart(Display *dpy, XErrorEvent *ee) -{ - die("dwm: another window manager is already running"); - return -1; -} - -void -xrdb(const Arg *arg) -{ - loadxrdb(); - int i; - for (i = 0; i < LENGTH(colors); i++) - scheme[i] = drw_scm_create(drw, colors[i], 3); - focus(NULL); - arrange(NULL); -} - -void -zoom(const Arg *arg) -{ - Client *c = selmon->sel; - - if (!selmon->lt[selmon->sellt]->arrange || !c || c->isfloating) - return; - if (c == nexttiled(selmon->clients) && !(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(); - XrmInitialize(); - loadxrdb(); - setup(); -#ifdef __OpenBSD__ - if (pledge("stdio rpath proc exec", NULL) == -1) - die("pledge"); -#endif /* __OpenBSD__ */ - scan(); - run(); - if(restart) execvp(argv[0], argv); - cleanup(); - XCloseDisplay(dpy); - return EXIT_SUCCESS; -} diff --git a/suckless/dwm/dwm.c.rej b/suckless/dwm/dwm.c.rej deleted file mode 100644 index a9d5891..0000000 --- a/suckless/dwm/dwm.c.rej +++ /dev/null @@ -1,20 +0,0 @@ ---- dwm.c -+++ dwm.c -@@ -1461,7 +1485,7 @@ sendmon(Client *c, Monitor *m) - detachstack(c); - c->mon = m; - c->tags = m->tagset[m->seltags]; /* assign tags of target monitor */ -- attach(c); -+ attachaside(c); - attachstack(c); - focus(NULL); - arrange(NULL); -@@ -1914,7 +1938,7 @@ updategeom(void) - m->clients = c->next; - detachstack(c); - c->mon = mons; -- attach(c); -+ attachaside(c); - attachstack(c); - } - if (m == selmon) diff --git a/suckless/dwm/dwm.o b/suckless/dwm/dwm.o deleted file mode 100644 index 796d8ceb38142243113e1cd0804597be45c8e2e9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 63136 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 W-sSp8oD7#^a2|NjqeSJkEf diff --git a/suckless/dwm/dwm.png b/suckless/dwm/dwm.png deleted file mode 100644 index b1f9ba7e5f4cc7350ee2392ebcea5fcbe00fb49b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 373 zcmeAS@N?(olHy`uVBq!ia0vp^2Y@($g9*gC@m3f}u_bxCyDx`7I;J! zGca%iWx0hJ8D`Cq01C2~c>21sUt<^MF=V?Ztt9{yk}YwKC~?lu%}vcKVQ?-=O)N=G zQ7F$W$xsN%NL6t6^bL5QqM8R(c+=CxF{I+w+q;fj4F)_6j>`Z3pZ>_($QEQ&92OXP z%lpEKGwG8$G-U1H{@Y%;mx-mNK|p|siBVAj$Z~Mt-~h6K0!}~{PyozQ07(f5fTdVi zm=-zT`NweeJ#%S&{fequZGmkDDC*%x$$Sa*fAP=$`nJkhx1Y~k<8b2;Hq)FOdV=P$ q&oWzoxz_&nv&n0)xBzV8k*jsxheTIy&cCY600f?{elF{r5}E*x)opSB diff --git a/suckless/dwm/mkconfig/config.mk.freebsd b/suckless/dwm/mkconfig/config.mk.freebsd deleted file mode 100644 index e3fb9ab..0000000 --- a/suckless/dwm/mkconfig/config.mk.freebsd +++ /dev/null @@ -1,59 +0,0 @@ -# dwm version -VERSION = 6.3 - -# Customize below to fit your system - -# paths -PREFIX = /usr/local -MANPREFIX = ${PREFIX}/share/man - -X11INC = /usr/X11R6/include -X11LIB = /usr/X11R6/lib - -X11INC = /usr/local/include -X11LIB = /usr/local/lib - -# Xinerama, comment if you don't want it -XINERAMALIBS = -lXinerama -XINERAMAFLAGS = -DXINERAMA - -# freetype -FREETYPELIBS = -lfontconfig -lXft -FREETYPEINC = /usr/include/freetype2 -FREETYPEINC = /usr/local/include/freetype2 - -# Uncomment this for the alpha patch and the winicon patch (BAR_ALPHA_PATCH, BAR_WINICON_PATCH) -XRENDER = -lXrender - -# Uncomment this for the mdpcontrol patch / MDPCONTROL_PATCH -#MPDCLIENT = -lmpdclient - -# Uncomment for the pango patch / BAR_PANGO_PATCH -#PANGOINC = `pkg-config --cflags xft pango pangoxft` -#PANGOLIB = `pkg-config --libs xft pango pangoxft` - -# Uncomment for the ipc patch / IPC_PATCH -#YAJLLIBS = -lyajl -#YAJLINC = -I/usr/include/yajl - -# Uncomment this for the rounded corners patch / ROUNDED_CORNERS_PATCH -#XEXTLIB = -lXext - -# Uncomment this for the swallow patch / SWALLOW_PATCH -XCBLIBS = -lX11-xcb -lxcb -lxcb-res - -# This is needed for the winicon and tagpreview patches / BAR_WINICON_PATCH / BAR_TAGPREVIEW_PATCH -#IMLIB2LIBS = -lImlib2 - -# includes and libs -INCS = -I${X11INC} -I${FREETYPEINC} ${YAJLINC} ${PANGOINC} -LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} ${XRENDER} ${MPDCLIENT} ${XEXTLIB} ${XCBLIBS} ${KVMLIB} ${PANGOLIB} ${YAJLLIBS} ${IMLIB2LIBS} - -# flags -CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=200809L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} -#CFLAGS = -g -std=c99 -pedantic -Wall -O0 ${INCS} ${CPPFLAGS} -CFLAGS = -std=c99 -pedantic -Wall -Wno-unused-function -Wno-deprecated-declarations -Os ${INCS} ${CPPFLAGS} -LDFLAGS = ${LIBS} - -# compiler and linker -CC = cc diff --git a/suckless/dwm/mkconfig/config.mk.linux b/suckless/dwm/mkconfig/config.mk.linux deleted file mode 100644 index 7b3b027..0000000 --- a/suckless/dwm/mkconfig/config.mk.linux +++ /dev/null @@ -1,55 +0,0 @@ -# dwm version -VERSION = 6.3 - -# 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 - -# Uncomment this for the alpha patch and the winicon patch (BAR_ALPHA_PATCH, BAR_WINICON_PATCH) -XRENDER = -lXrender - -# Uncomment this for the mdpcontrol patch / MDPCONTROL_PATCH -#MPDCLIENT = -lmpdclient - -# Uncomment for the pango patch / BAR_PANGO_PATCH -#PANGOINC = `pkg-config --cflags xft pango pangoxft` -#PANGOLIB = `pkg-config --libs xft pango pangoxft` - -# Uncomment for the ipc patch / IPC_PATCH -#YAJLLIBS = -lyajl -#YAJLINC = -I/usr/include/yajl - -# Uncomment this for the rounded corners patch / ROUNDED_CORNERS_PATCH -#XEXTLIB = -lXext - -# Uncomment this for the swallow patch / SWALLOW_PATCH -XCBLIBS = -lX11-xcb -lxcb -lxcb-res - -# This is needed for the winicon and tagpreview patches / BAR_WINICON_PATCH / BAR_TAGPREVIEW_PATCH -#IMLIB2LIBS = -lImlib2 - -# includes and libs -INCS = -I${X11INC} -I${FREETYPEINC} ${YAJLINC} ${PANGOINC} -LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} ${XRENDER} ${MPDCLIENT} ${XEXTLIB} ${XCBLIBS} ${KVMLIB} ${PANGOLIB} ${YAJLLIBS} ${IMLIB2LIBS} - -# flags -CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=200809L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} -#CFLAGS = -g -std=c99 -pedantic -Wall -O0 ${INCS} ${CPPFLAGS} -CFLAGS = -std=c99 -pedantic -Wall -Wno-unused-function -Wno-deprecated-declarations -Os ${INCS} ${CPPFLAGS} -LDFLAGS = ${LIBS} - -# compiler and linker -CC = cc diff --git a/suckless/dwm/mkconfig/config.mk.openbsd b/suckless/dwm/mkconfig/config.mk.openbsd deleted file mode 100644 index 6651dbb..0000000 --- a/suckless/dwm/mkconfig/config.mk.openbsd +++ /dev/null @@ -1,57 +0,0 @@ -# dwm version -VERSION = 6.3 - -# 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 -FREETYPEINC = ${X11INC}/freetype2 -KVMLIB = -lkvm - -# Uncomment this for the alpha patch and the winicon patch (BAR_ALPHA_PATCH, BAR_WINICON_PATCH) -XRENDER = -lXrender - -# Uncomment this for the mdpcontrol patch / MDPCONTROL_PATCH -#MPDCLIENT = -lmpdclient - -# Uncomment for the pango patch / BAR_PANGO_PATCH -#PANGOINC = `pkg-config --cflags xft pango pangoxft` -#PANGOLIB = `pkg-config --libs xft pango pangoxft` - -# Uncomment for the ipc patch / IPC_PATCH -#YAJLLIBS = -lyajl -#YAJLINC = -I/usr/include/yajl - -# Uncomment this for the rounded corners patch / ROUNDED_CORNERS_PATCH -#XEXTLIB = -lXext - -# Uncomment this for the swallow patch / SWALLOW_PATCH -XCBLIBS = -lX11-xcb -lxcb -lxcb-res - -# This is needed for the winicon and tagpreview patches / BAR_WINICON_PATCH / BAR_TAGPREVIEW_PATCH -#IMLIB2LIBS = -lImlib2 - -# includes and libs -INCS = -I${X11INC} -I${FREETYPEINC} ${YAJLINC} ${PANGOINC} -LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} ${XRENDER} ${MPDCLIENT} ${XEXTLIB} ${XCBLIBS} ${KVMLIB} ${PANGOLIB} ${YAJLLIBS} ${IMLIB2LIBS} - -# flags -CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=200809L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} -#CFLAGS = -g -std=c99 -pedantic -Wall -O0 ${INCS} ${CPPFLAGS} -CFLAGS = -std=c99 -pedantic -Wall -Wno-unused-function -Wno-deprecated-declarations -Os ${INCS} ${CPPFLAGS} -LDFLAGS = ${LIBS} - -# compiler and linker -CC = cc diff --git a/suckless/dwm/mkconfig/config.mk.solaris b/suckless/dwm/mkconfig/config.mk.solaris deleted file mode 100644 index 7a6d93f..0000000 --- a/suckless/dwm/mkconfig/config.mk.solaris +++ /dev/null @@ -1,58 +0,0 @@ -# dwm version -VERSION = 6.3 - -# 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 - -# Uncomment this for the alpha patch and the winicon patch (BAR_ALPHA_PATCH, BAR_WINICON_PATCH) -XRENDER = -lXrender - -# Uncomment this for the mdpcontrol patch / MDPCONTROL_PATCH -#MPDCLIENT = -lmpdclient - -# Uncomment for the pango patch / BAR_PANGO_PATCH -#PANGOINC = `pkg-config --cflags xft pango pangoxft` -#PANGOLIB = `pkg-config --libs xft pango pangoxft` - -# Uncomment for the ipc patch / IPC_PATCH -#YAJLLIBS = -lyajl -#YAJLINC = -I/usr/include/yajl - -# Uncomment this for the rounded corners patch / ROUNDED_CORNERS_PATCH -#XEXTLIB = -lXext - -# Uncomment this for the swallow patch / SWALLOW_PATCH -XCBLIBS = -lX11-xcb -lxcb -lxcb-res - -# This is needed for the winicon and tagpreview patches / BAR_WINICON_PATCH / BAR_TAGPREVIEW_PATCH -#IMLIB2LIBS = -lImlib2 - -# includes and libs -INCS = -I${X11INC} -I${FREETYPEINC} ${YAJLINC} ${PANGOINC} -LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} ${XRENDER} ${MPDCLIENT} ${XEXTLIB} ${XCBLIBS} ${KVMLIB} ${PANGOLIB} ${YAJLLIBS} ${IMLIB2LIBS} - -# flags -CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=200809L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} -#CFLAGS = -g -std=c99 -pedantic -Wall -O0 ${INCS} ${CPPFLAGS} -CFLAGS = -std=c99 -pedantic -Wall -Wno-unused-function -Wno-deprecated-declarations -Os ${INCS} ${CPPFLAGS} -LDFLAGS = ${LIBS} - -CFLAGS = -fast ${INCS} -DVERSION=\"${VERSION}\" -LDFLAGS = ${LIBS} - -# compiler and linker -CC = cc diff --git a/suckless/dwm/movestack.c b/suckless/dwm/movestack.c deleted file mode 100644 index 520f4ae..0000000 --- a/suckless/dwm/movestack.c +++ /dev/null @@ -1,48 +0,0 @@ -void -movestack(const Arg *arg) { - Client *c = NULL, *p = NULL, *pc = NULL, *i; - - if(arg->i > 0) { - /* find the client after selmon->sel */ - for(c = selmon->sel->next; c && (!ISVISIBLE(c) || c->isfloating); c = c->next); - if(!c) - for(c = selmon->clients; c && (!ISVISIBLE(c) || c->isfloating); c = c->next); - - } - else { - /* find the client before selmon->sel */ - for(i = selmon->clients; i != selmon->sel; i = i->next) - if(ISVISIBLE(i) && !i->isfloating) - c = i; - if(!c) - for(; i; i = i->next) - if(ISVISIBLE(i) && !i->isfloating) - c = i; - } - /* find the client before selmon->sel and c */ - for(i = selmon->clients; i && (!p || !pc); i = i->next) { - if(i->next == selmon->sel) - p = i; - if(i->next == c) - pc = i; - } - - /* swap c and selmon->sel selmon->clients in the selmon->clients list */ - if(c && c != selmon->sel) { - Client *temp = selmon->sel->next==c?selmon->sel:selmon->sel->next; - selmon->sel->next = c->next==selmon->sel?c:c->next; - c->next = temp; - - if(p && p != c) - p->next = c; - if(pc && pc != selmon->sel) - pc->next = selmon->sel; - - if(selmon->sel == selmon->clients) - selmon->clients = c; - else if(c == selmon->clients) - selmon->clients = selmon->sel; - - arrange(selmon); - } -} \ No newline at end of file diff --git a/suckless/dwm/patch/attachx.c b/suckless/dwm/patch/attachx.c deleted file mode 100644 index c683dce..0000000 --- a/suckless/dwm/patch/attachx.c +++ /dev/null @@ -1,20 +0,0 @@ -void -attachx(Client *c) -{ - Client *at; - - - unsigned int n; - for (at = c->mon->clients, n = 0; at; at = at->next) - if (!at->isfloating && ISVISIBLEONTAG(at, c->tags)) - if (++n >= c->mon->nmaster) - break; - - if (at && c->mon->nmaster) { - c->next = at->next; - at->next = c; - return; - } - attach(c); // master (default) -} - diff --git a/suckless/dwm/patch/attachx.h b/suckless/dwm/patch/attachx.h deleted file mode 100644 index e522d27..0000000 --- a/suckless/dwm/patch/attachx.h +++ /dev/null @@ -1,2 +0,0 @@ -static void attachx(Client *c); - diff --git a/suckless/dwm/patch/bar.c b/suckless/dwm/patch/bar.c deleted file mode 100644 index 65e1a69..0000000 --- a/suckless/dwm/patch/bar.c +++ /dev/null @@ -1,39 +0,0 @@ -void -barhover(XEvent *e, Bar *bar) -{ - const BarRule *br; - Monitor *m = bar->mon; - XMotionEvent *ev = &e->xmotion; - BarArg barg = { 0, 0, 0, 0 }; - int r; - - for (r = 0; r < LENGTH(barrules); r++) { - br = &barrules[r]; - if (br->bar != bar->idx || (br->monitor == 'A' && m != selmon) || br->hoverfunc == NULL) - continue; - if (br->monitor != 'A' && br->monitor != -1 && br->monitor != bar->mon->num) - continue; - if (bar->x[r] > ev->x || ev->x > bar->x[r] + bar->w[r]) - continue; - - barg.x = ev->x - bar->x[r]; - barg.y = ev->y - bar->borderpx; - barg.w = bar->w[r]; - barg.h = bar->bh - 2 * bar->borderpx; - - br->hoverfunc(bar, &barg, ev); - break; - } -} - -Bar * -wintobar(Window win) -{ - Monitor *m; - Bar *bar; - for (m = mons; m; m = m->next) - for (bar = m->bar; bar; bar = bar->next) - if (bar->win == win) - return bar; - return NULL; -} diff --git a/suckless/dwm/patch/bar.h b/suckless/dwm/patch/bar.h deleted file mode 100644 index 3e006dc..0000000 --- a/suckless/dwm/patch/bar.h +++ /dev/null @@ -1,2 +0,0 @@ -static void barhover(XEvent *e, Bar *bar); -static Bar *wintobar(Window win); diff --git a/suckless/dwm/patch/bar_alpha.c b/suckless/dwm/patch/bar_alpha.c deleted file mode 100644 index 465f6f2..0000000 --- a/suckless/dwm/patch/bar_alpha.c +++ /dev/null @@ -1,43 +0,0 @@ - -static int useargb = 0; -static Visual *visual; -static int depth; -static Colormap cmap; - -void -xinitvisual() -{ - XVisualInfo *infos; - XRenderPictFormat *fmt; - int nitems; - int i; - - XVisualInfo tpl = { - .screen = screen, - .depth = 32, - .class = TrueColor - }; - long masks = VisualScreenMask | VisualDepthMask | VisualClassMask; - - infos = XGetVisualInfo(dpy, masks, &tpl, &nitems); - visual = NULL; - for (i = 0; i < nitems; i ++) { - fmt = XRenderFindVisualFormat(dpy, infos[i].visual); - if (fmt->type == PictTypeDirect && fmt->direct.alphaMask) { - visual = infos[i].visual; - depth = infos[i].depth; - cmap = XCreateColormap(dpy, root, visual, AllocNone); - useargb = 1; - break; - } - } - - XFree(infos); - - if (!visual) { - visual = DefaultVisual(dpy, screen); - depth = DefaultDepth(dpy, screen); - cmap = DefaultColormap(dpy, screen); - } -} - diff --git a/suckless/dwm/patch/bar_alpha.h b/suckless/dwm/patch/bar_alpha.h deleted file mode 100644 index 1c2a012..0000000 --- a/suckless/dwm/patch/bar_alpha.h +++ /dev/null @@ -1,4 +0,0 @@ -#define OPAQUE 0xffU - -static void xinitvisual(); - diff --git a/suckless/dwm/patch/bar_indicators.c b/suckless/dwm/patch/bar_indicators.c deleted file mode 100644 index b003fc8..0000000 --- a/suckless/dwm/patch/bar_indicators.c +++ /dev/null @@ -1,104 +0,0 @@ -/* Indicator properties, you can override these in your config.h if you want. */ -#ifndef TAGSINDICATOR -#define TAGSINDICATOR 1 // 0 = off, 1 = on if >1 client/view tag, 2 = always on -#endif -#ifndef TAGSPX -#define TAGSPX 5 // # pixels for tag grid boxes -#endif -#ifndef TAGSROWS -#define TAGSROWS 3 // # rows in tag grid (9 tags, e.g. 3x3) -#endif - -void -drawindicator(Monitor *m, Client *c, unsigned int occ, int x, int y, int w, int h, unsigned int tag, int filled, int invert, int type) -{ - int i, boxw, boxs, indn = 0; - if (!(occ & 1 << tag) || type == INDICATOR_NONE) - return; - - boxs = drw->fonts->h / 9; - boxw = drw->fonts->h / 6 + 2; - if (filled == -1) - filled = m == selmon && m->sel && m->sel->tags & 1 << tag; - - switch (type) { - default: - case INDICATOR_TOP_LEFT_SQUARE: - drw_rect(drw, x + boxs, y + boxs, boxw, boxw, filled, invert); - break; - case INDICATOR_TOP_LEFT_LARGER_SQUARE: - drw_rect(drw, x + boxs + 2, y + boxs+1, boxw+1, boxw+1, filled, invert); - break; - case INDICATOR_TOP_BAR: - drw_rect(drw, x + boxw, y, w - ( 2 * boxw + 1), boxw/2, filled, invert); - break; - case INDICATOR_TOP_BAR_SLIM: - drw_rect(drw, x + boxw, y, w - ( 2 * boxw + 1), 1, 0, invert); - break; - case INDICATOR_BOTTOM_BAR: - drw_rect(drw, x + boxw, y + h - boxw/2, w - ( 2 * boxw + 1), boxw/2, filled, invert); - break; - case INDICATOR_BOTTOM_BAR_SLIM: - drw_rect(drw, x + boxw, y + h - 1, w - ( 2 * boxw + 1), 1, 0, invert); - break; - case INDICATOR_BOX: - drw_rect(drw, x + boxw, y, w - 2 * boxw, h, 0, invert); - break; - case INDICATOR_BOX_WIDER: - drw_rect(drw, x + boxw/2, y, w - boxw, h, 0, invert); - break; - case INDICATOR_BOX_FULL: - drw_rect(drw, x, y, w - 2, h, 0, invert); - break; - case INDICATOR_CLIENT_DOTS: - for (c = m->clients; c; c = c->next) { - if (c->tags & (1 << tag)) { - drw_rect(drw, x, 1 + (indn * 2), m->sel == c ? 6 : 1, 1, 1, invert); - indn++; - } - if (h <= 1 + (indn * 2)) { - indn = 0; - x += 2; - } - } - break; - case INDICATOR_RIGHT_TAGS: - if (!c) - break; - for (i = 0; i < NUMTAGS; i++) { - drw_rect(drw, - ( x + w - 2 - ((NUMTAGS / TAGSROWS) * TAGSPX) - - (i % (NUMTAGS/TAGSROWS)) + ((i % (NUMTAGS / TAGSROWS)) * TAGSPX) - ), - ( y + 2 + ((i / (NUMTAGS/TAGSROWS)) * TAGSPX) - - ((i / (NUMTAGS/TAGSROWS))) - ), - TAGSPX, TAGSPX, (c->tags >> i) & 1, 0 - ); - } - break; - case INDICATOR_PLUS_AND_LARGER_SQUARE: - boxs += 2; - boxw += 2; - /* falls through */ - case INDICATOR_PLUS_AND_SQUARE: - drw_rect(drw, x + boxs, y + boxs, boxw % 2 ? boxw : boxw + 1, boxw % 2 ? boxw : boxw + 1, filled, invert); - /* falls through */ - case INDICATOR_PLUS: - if (!(boxw % 2)) - boxw += 1; - drw_rect(drw, x + boxs + boxw / 2, y + boxs, 1, boxw, filled, invert); // | - drw_rect(drw, x + boxs, y + boxs + boxw / 2, boxw + 1, 1, filled, invert); // ‒ - break; - } -} - -void -drawstateindicator(Monitor *m, Client *c, unsigned int occ, int x, int y, int w, int h, unsigned int tag, int filled, int invert) -{ - if (c->isfloating) - drawindicator(m, c, occ, x, y, w, h, tag, filled, invert, floatindicatortype); - else - drawindicator(m, c, occ, x, y, w, h, tag, filled, invert, tiledindicatortype); -} - diff --git a/suckless/dwm/patch/bar_indicators.h b/suckless/dwm/patch/bar_indicators.h deleted file mode 100644 index c66e4f0..0000000 --- a/suckless/dwm/patch/bar_indicators.h +++ /dev/null @@ -1,21 +0,0 @@ -enum { - INDICATOR_NONE, - INDICATOR_TOP_LEFT_SQUARE, - INDICATOR_TOP_LEFT_LARGER_SQUARE, - INDICATOR_TOP_BAR, - INDICATOR_TOP_BAR_SLIM, - INDICATOR_BOTTOM_BAR, - INDICATOR_BOTTOM_BAR_SLIM, - INDICATOR_BOX, - INDICATOR_BOX_WIDER, - INDICATOR_BOX_FULL, - INDICATOR_CLIENT_DOTS, - INDICATOR_RIGHT_TAGS, - INDICATOR_PLUS, - INDICATOR_PLUS_AND_SQUARE, - INDICATOR_PLUS_AND_LARGER_SQUARE, -}; - -static void drawindicator(Monitor *m, Client *c, unsigned int occ, int x, int y, int w, int h, unsigned int tag, int filled, int invert, int type); -static void drawstateindicator(Monitor *m, Client *c, unsigned int occ, int x, int y, int w, int h, unsigned int tag, int filled, int invert); - diff --git a/suckless/dwm/patch/bar_ltsymbol.c b/suckless/dwm/patch/bar_ltsymbol.c deleted file mode 100644 index 1fbd1b8..0000000 --- a/suckless/dwm/patch/bar_ltsymbol.c +++ /dev/null @@ -1,18 +0,0 @@ -int -width_ltsymbol(Bar *bar, BarArg *a) -{ - return TEXTW(bar->mon->ltsymbol); -} - -int -draw_ltsymbol(Bar *bar, BarArg *a) -{ - return drw_text(drw, a->x, a->y, a->w, a->h, lrpad / 2, bar->mon->ltsymbol, 0, False); -} - -int -click_ltsymbol(Bar *bar, Arg *arg, BarArg *a) -{ - return ClkLtSymbol; -} - diff --git a/suckless/dwm/patch/bar_ltsymbol.h b/suckless/dwm/patch/bar_ltsymbol.h deleted file mode 100644 index 4de5720..0000000 --- a/suckless/dwm/patch/bar_ltsymbol.h +++ /dev/null @@ -1,4 +0,0 @@ -static int width_ltsymbol(Bar *bar, BarArg *a); -static int draw_ltsymbol(Bar *bar, BarArg *a); -static int click_ltsymbol(Bar *bar, Arg *arg, BarArg *a); - diff --git a/suckless/dwm/patch/bar_status.c b/suckless/dwm/patch/bar_status.c deleted file mode 100644 index 65595e0..0000000 --- a/suckless/dwm/patch/bar_status.c +++ /dev/null @@ -1,20 +0,0 @@ -int -width_status(Bar *bar, BarArg *a) -{ - return TEXTWM(stext); -} - - -int -draw_status(Bar *bar, BarArg *a) -{ - return drw_text(drw, a->x, a->y, a->w, a->h, lrpad / 2, stext, 0, True); -} - - -int -click_status(Bar *bar, Arg *arg, BarArg *a) -{ - return ClkStatusText; -} - diff --git a/suckless/dwm/patch/bar_status.h b/suckless/dwm/patch/bar_status.h deleted file mode 100644 index c580597..0000000 --- a/suckless/dwm/patch/bar_status.h +++ /dev/null @@ -1,4 +0,0 @@ -static int width_status(Bar *bar, BarArg *a); -static int draw_status(Bar *bar, BarArg *a); -static int click_status(Bar *bar, Arg *arg, BarArg *a); - diff --git a/suckless/dwm/patch/bar_tagicons.c b/suckless/dwm/patch/bar_tagicons.c deleted file mode 100644 index 57d1629..0000000 --- a/suckless/dwm/patch/bar_tagicons.c +++ /dev/null @@ -1,9 +0,0 @@ -char * -tagicon(Monitor *m, int tag) -{ - int tagindex = tag + NUMTAGS * m->num; - if (tagindex >= LENGTH(tagicons[DEFAULT_TAGS])) - tagindex = tagindex % LENGTH(tagicons[DEFAULT_TAGS]); - return tagicons[DEFAULT_TAGS][tagindex]; -} - diff --git a/suckless/dwm/patch/bar_tagicons.h b/suckless/dwm/patch/bar_tagicons.h deleted file mode 100644 index 16fad2a..0000000 --- a/suckless/dwm/patch/bar_tagicons.h +++ /dev/null @@ -1,8 +0,0 @@ -enum { - DEFAULT_TAGS, - ALTERNATIVE_TAGS, - ALT_TAGS_DECORATION, -}; - -static char * tagicon(Monitor *m, int tag); - diff --git a/suckless/dwm/patch/bar_tags.c b/suckless/dwm/patch/bar_tags.c deleted file mode 100644 index 8aa37b2..0000000 --- a/suckless/dwm/patch/bar_tags.c +++ /dev/null @@ -1,81 +0,0 @@ -int -width_tags(Bar *bar, BarArg *a) -{ - int w, i; - Client *c; - unsigned int occ = 0; - for (c = bar->mon->clients; c; c = c->next) - occ |= c->tags == 255 ? 0 : c->tags; - - for (w = 0, i = 0; i < NUMTAGS; i++) { - if (!(occ & 1 << i || bar->mon->tagset[bar->mon->seltags] & 1 << i)) - continue; - w += TEXTW(tagicon(bar->mon, i)); - } - return w; -} - -int -draw_tags(Bar *bar, BarArg *a) -{ - int invert; - int w, x = a->x; - unsigned int i, occ = 0, urg = 0; - char *icon; - Client *c; - Monitor *m = bar->mon; - - for (c = m->clients; c; c = c->next) { - occ |= c->tags == 255 ? 0 : c->tags; - if (c->isurgent) - urg |= c->tags; - } - for (i = 0; i < NUMTAGS; i++) { - /* do not draw vacant tags */ - if (!(occ & 1 << i || m->tagset[m->seltags] & 1 << i)) - continue; - - icon = tagicon(bar->mon, i); - invert = 0; - w = TEXTW(icon); - drw_setscheme(drw, scheme[ - m->tagset[m->seltags] & 1 << i - ? SchemeTagsSel - : urg & 1 << i - ? SchemeUrg - : SchemeTagsNorm - ]); - drw_text(drw, x, a->y, w, a->h, lrpad / 2, icon, invert, False); - drawindicator(m, NULL, occ, x, a->y, w, a->h, i, -1, invert, tagindicatortype); - x += w; - } - - return 1; -} - -int -click_tags(Bar *bar, Arg *arg, BarArg *a) -{ - int i = 0, x = 0; - Client *c; - unsigned int occ = 0; - for (c = bar->mon->clients; c; c = c->next) - occ |= c->tags == 255 ? 0 : c->tags; - - do { - if (!(occ & 1 << i || bar->mon->tagset[bar->mon->seltags] & 1 << i)) - continue; - x += TEXTW(tagicon(bar->mon, i)); - } while (a->x >= x && ++i < NUMTAGS); - if (i < NUMTAGS) { - arg->ui = 1 << i; - } - return ClkTagBar; -} - -int -hover_tags(Bar *bar, BarArg *a, XMotionEvent *ev) -{ - - return 1; -} diff --git a/suckless/dwm/patch/bar_tags.h b/suckless/dwm/patch/bar_tags.h deleted file mode 100644 index 70040d2..0000000 --- a/suckless/dwm/patch/bar_tags.h +++ /dev/null @@ -1,4 +0,0 @@ -static int width_tags(Bar *bar, BarArg *a); -static int draw_tags(Bar *bar, BarArg *a); -static int click_tags(Bar *bar, Arg *arg, BarArg *a); -static int hover_tags(Bar *bar, BarArg *a, XMotionEvent *ev); diff --git a/suckless/dwm/patch/bar_wintitle.c b/suckless/dwm/patch/bar_wintitle.c deleted file mode 100644 index d086736..0000000 --- a/suckless/dwm/patch/bar_wintitle.c +++ /dev/null @@ -1,48 +0,0 @@ -int -width_wintitle(Bar *bar, BarArg *a) -{ - return a->w; -} - -int -draw_wintitle(Bar *bar, BarArg *a) -{ - int x = a->x + lrpad / 2, w = a->w - lrpad / 2; - Monitor *m = bar->mon; - Client *c = m->sel; - - if (!c) { - drw_setscheme(drw, scheme[SchemeTitleNorm]); - drw_rect(drw, x, a->y, w, a->h, 1, 1); - return 0; - } - - int tpad = lrpad / 2; - int tx = x; - int tw = w; - - drw_setscheme(drw, scheme[m == selmon ? SchemeTitleSel : SchemeTitleNorm]); - - if (w <= TEXTW("A") - lrpad + tpad) // reduce text padding if wintitle is too small - tpad = (w - TEXTW("A") + lrpad < 0 ? 0 : (w - TEXTW("A") + lrpad) / 2); - - XSetForeground(drw->dpy, drw->gc, drw->scheme[ColBg].pixel); - XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, a->y, w, a->h); - - - tx += tpad; - tw -= lrpad; - - - drw_text(drw, tx, a->y, tw, a->h, 0, c->name, 0, False); - - drawstateindicator(m, c, 1, x, a->y, w, a->h, 0, 0, c->isfixed); - return 1; -} - -int -click_wintitle(Bar *bar, Arg *arg, BarArg *a) -{ - return ClkWinTitle; -} - diff --git a/suckless/dwm/patch/bar_wintitle.h b/suckless/dwm/patch/bar_wintitle.h deleted file mode 100644 index 7e8cce5..0000000 --- a/suckless/dwm/patch/bar_wintitle.h +++ /dev/null @@ -1,4 +0,0 @@ -static int width_wintitle(Bar *bar, BarArg *a); -static int draw_wintitle(Bar *bar, BarArg *a); -static int click_wintitle(Bar *bar, Arg *arg, BarArg *a); - diff --git a/suckless/dwm/patch/cool_autostart.c b/suckless/dwm/patch/cool_autostart.c deleted file mode 100644 index ffd4ba3..0000000 --- a/suckless/dwm/patch/cool_autostart.c +++ /dev/null @@ -1,29 +0,0 @@ -/* dwm will keep pid's of processes from autostart array and kill them at quit */ -static pid_t *autostart_pids; -static size_t autostart_len; - -/* execute command from autostart array */ -static void -autostart_exec() -{ - const char *const *p; - size_t i = 0; - - /* count entries */ - for (p = autostart; *p; autostart_len++, p++) - while (*++p); - - autostart_pids = malloc(autostart_len * sizeof(pid_t)); - for (p = autostart; *p; i++, p++) { - if ((autostart_pids[i] = fork()) == 0) { - setsid(); - execvp(*p, (char *const *)p); - fprintf(stderr, "dwm: execvp %s\n", *p); - perror(" failed"); - _exit(EXIT_FAILURE); - } - /* skip arguments */ - while (*++p); - } -} - diff --git a/suckless/dwm/patch/cool_autostart.h b/suckless/dwm/patch/cool_autostart.h deleted file mode 100644 index 5534d99..0000000 --- a/suckless/dwm/patch/cool_autostart.h +++ /dev/null @@ -1,2 +0,0 @@ -static void autostart_exec(void); - diff --git a/suckless/dwm/patch/dwm-alpha-20230401-348f655.diff b/suckless/dwm/patch/dwm-alpha-20230401-348f655.diff deleted file mode 100644 index 06d7405020018ddf3cacee90fd4af10487da3d20..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1024 ScmZQz7zLvtFd70QH3R?z00031 diff --git a/suckless/dwm/patch/dwmc b/suckless/dwm/patch/dwmc deleted file mode 100644 index 3880428..0000000 --- a/suckless/dwm/patch/dwmc +++ /dev/null @@ -1,130 +0,0 @@ -#!/usr/bin/env bash - -signal() { - xsetroot -name "fsignal:$*" -} - -case $# in -1) - case $1 in - focusurgent) ;& - mirrorlayout) ;& - mpdcontrol) ;& - pushdown) ;& - pushup) ;& - self_restart) ;& - setlayout) ;& - setcfact) ;& - switchcol) ;& - view) ;& - viewall) ;& - viewtoleft) ;& - viewtoright) ;& - tagtoleft) ;& - tagtoright) ;& - tagandviewtoleft) ;& - tagandviewtoright) ;& - transfer) ;& - transferall) ;& - togglealttag) ;& - togglebar) ;& - togglefloating) ;& - togglefullscreen) ;& - fullscreen) ;& - togglefakefullscreen) ;& - togglesticky) ;& - togglehorizontalmax) ;& - toggleverticalmax) ;& - togglemax) ;& - togglegaps) ;& - defaultgaps) ;& - unfloatvisible) ;& - winview) ;& - xrdb) ;& - zoom) ;& - killclient) ;& - quit) - signal $1 - ;; - *) - echo "Unknown command ($1) or missing one argument." - exit 1 - ;; - esac - ;; -2) - case $1 in - cyclelayout) ;& - explace) ;& - moveplace) ;& - mpdchange) ;& - setkeymode) ;& - switchtag) ;& - togglescratch) ;& - view) - signal $1 ui $2 - ;; - viewex) ;& - toggleviewex) ;& - tagallmon) ;& - tagswapmon) ;& - tagex) ;& - toggletagex) ;& - setborderpx) ;& - setgaps) ;& - setlayoutex) ;& - setlayoutaxisex) ;& - swapfocus) ;& - focusstack) ;& - pushstack) ;& - inplacerotate) ;& - rotatestack) ;& - rotatelayoutaxis) ;& - incnmaster) ;& - incnstack) ;& - incrgaps) ;& - incrigaps) ;& - incrogaps) ;& - incrihgaps) ;& - incrivgaps) ;& - incrohgaps) ;& - incrovgaps) ;& - movestack) ;& - shiftview) ;& - shiftviewclients) ;& - focusmon) ;& - tagmon) - signal $1 i $2 - ;; - setcfact) ;& - setmfact) - signal $1 f $2 - ;; - *) - echo "Unknown command ($1) or too many arguments" - exit 1 - ;; - esac - ;; -5) - case $1 in - setgaps) - # Expects "setgaps oh ov ih iv" where -1 means to keep existing values - [ $2 = -1 ] && oh=128 || oh=$2 - [ $3 = -1 ] && ov=128 || ov=$3 - [ $4 = -1 ] && ih=128 || ih=$4 - [ $5 = -1 ] && iv=128 || iv=$5 - signal $1 i $(((oh << 24) + (ov << 16) + (ih << 8) + iv)) - ;; - *) - echo "Unknown command ($1) or too many arguments" - exit 1 - ;; - esac - ;; -*) - echo "Unknown command ($1) or too many arguments" - exit 1 - ;; -esac - diff --git a/suckless/dwm/patch/dwmc.c b/suckless/dwm/patch/dwmc.c deleted file mode 100644 index a892ff7..0000000 --- a/suckless/dwm/patch/dwmc.c +++ /dev/null @@ -1,85 +0,0 @@ -void -setlayoutex(const Arg *arg) -{ - setlayout(&((Arg) { .v = &layouts[arg->i] })); -} - -void -viewex(const Arg *arg) -{ - view(&((Arg) { .ui = 1 << arg->ui })); -} - -void -viewallex(const Arg *arg) -{ - view(&((Arg){.ui = ~SPTAGMASK})); -} - -void -toggleviewex(const Arg *arg) -{ - toggleview(&((Arg) { .ui = 1 << arg->ui })); -} - -void -tagex(const Arg *arg) -{ - tag(&((Arg) { .ui = 1 << arg->ui })); -} - -void -toggletagex(const Arg *arg) -{ - toggletag(&((Arg) { .ui = 1 << arg->ui })); -} - -void -tagallex(const Arg *arg) -{ - tag(&((Arg){.ui = ~SPTAGMASK})); -} - -int -fake_signal(void) -{ - char fsignal[256]; - char indicator[9] = "fsignal:"; - char str_sig[50]; - char param[16]; - int i, len_str_sig, n, paramn; - size_t len_fsignal, len_indicator = strlen(indicator); - Arg arg; - - // Get root name property - if (gettextprop(root, XA_WM_NAME, fsignal, sizeof(fsignal))) { - len_fsignal = strlen(fsignal); - - // Check if this is indeed a fake signal - if (len_indicator > len_fsignal ? 0 : strncmp(indicator, fsignal, len_indicator) == 0) { - paramn = sscanf(fsignal+len_indicator, "%s%n%s%n", str_sig, &len_str_sig, param, &n); - - if (paramn == 1) arg = (Arg) {0}; - else if (paramn > 2) return 1; - else if (strncmp(param, "i", n - len_str_sig) == 0) - sscanf(fsignal + len_indicator + n, "%i", &(arg.i)); - else if (strncmp(param, "ui", n - len_str_sig) == 0) - sscanf(fsignal + len_indicator + n, "%u", &(arg.ui)); - else if (strncmp(param, "f", n - len_str_sig) == 0) - sscanf(fsignal + len_indicator + n, "%f", &(arg.f)); - else return 1; - - // Check if a signal was found, and if so handle it - for (i = 0; i < LENGTH(signals); i++) - if (strncmp(str_sig, signals[i].sig, len_str_sig) == 0 && signals[i].func) - signals[i].func(&(arg)); - - // A fake signal was sent - return 1; - } - } - - // No fake signal was sent, so proceed with update - return 0; -} - diff --git a/suckless/dwm/patch/dwmc.h b/suckless/dwm/patch/dwmc.h deleted file mode 100644 index 66e23a9..0000000 --- a/suckless/dwm/patch/dwmc.h +++ /dev/null @@ -1,14 +0,0 @@ -typedef struct { - const char * sig; - void (*func)(const Arg *); -} Signal; - -static void setlayoutex(const Arg *arg); -static void viewex(const Arg *arg); -static void viewallex(const Arg *arg); -static void toggleviewex(const Arg *arg); -static void tagex(const Arg *arg); -static void toggletagex(const Arg *arg); -static void tagallex(const Arg *arg); -static int fake_signal(void); - diff --git a/suckless/dwm/patch/fullscreen.c b/suckless/dwm/patch/fullscreen.c deleted file mode 100644 index 5fb682a..0000000 --- a/suckless/dwm/patch/fullscreen.c +++ /dev/null @@ -1,15 +0,0 @@ -Layout *last_layout; - -void -fullscreen(const Arg *arg) -{ - int monocle_pos = 0; - if (selmon->showbar || last_layout == NULL) { - for (last_layout = (Layout *)layouts; last_layout != selmon->lt[selmon->sellt]; last_layout++); - setlayout(&((Arg) { .v = &layouts[monocle_pos] })); - } else { - setlayout(&((Arg) { .v = last_layout })); - } - togglebar(arg); -} - diff --git a/suckless/dwm/patch/fullscreen.h b/suckless/dwm/patch/fullscreen.h deleted file mode 100644 index 72983e1..0000000 --- a/suckless/dwm/patch/fullscreen.h +++ /dev/null @@ -1,2 +0,0 @@ -static void fullscreen(const Arg *arg); - diff --git a/suckless/dwm/patch/hidevacanttags.diff b/suckless/dwm/patch/hidevacanttags.diff deleted file mode 100644 index 0b02555..0000000 --- a/suckless/dwm/patch/hidevacanttags.diff +++ /dev/null @@ -1,49 +0,0 @@ -:100644 100644 f1d86b2 0000000 M dwm.c - -diff --git a/dwm.c b/dwm.c -index f1d86b2..d41cc14 100644 ---- a/dwm.c -+++ b/dwm.c -@@ -433,9 +433,15 @@ buttonpress(XEvent *e) - } - if (ev->window == selmon->barwin) { - i = x = 0; -- do -+ unsigned int occ = 0; -+ for(c = m->clients; c; c=c->next) -+ occ |= c->tags == TAGMASK ? 0 : c->tags; -+ do { -+ /* Do not reserve space for vacant tags */ -+ if (!(occ & 1 << i || m->tagset[m->seltags] & 1 << i)) -+ continue; - x += TEXTW(tags[i]); -- while (ev->x >= x && ++i < LENGTH(tags)); -+ } while (ev->x >= x && ++i < LENGTH(tags)); - if (i < LENGTH(tags)) { - click = ClkTagBar; - arg.ui = 1 << i; -@@ -715,19 +721,18 @@ drawbar(Monitor *m) - } - - for (c = m->clients; c; c = c->next) { -- occ |= c->tags; -+ occ |= c->tags == TAGMASK ? 0 : c->tags; - if (c->isurgent) - urg |= c->tags; - } - x = 0; - for (i = 0; i < LENGTH(tags); i++) { -+ /* Do not draw vacant tags */ -+ if(!(occ & 1 << i || m->tagset[m->seltags] & 1 << i)) -+ continue; - 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 = TEXTW(m->ltsymbol); - diff --git a/suckless/dwm/patch/hidevacanttags.diff.orig b/suckless/dwm/patch/hidevacanttags.diff.orig deleted file mode 100644 index 0b02555..0000000 --- a/suckless/dwm/patch/hidevacanttags.diff.orig +++ /dev/null @@ -1,49 +0,0 @@ -:100644 100644 f1d86b2 0000000 M dwm.c - -diff --git a/dwm.c b/dwm.c -index f1d86b2..d41cc14 100644 ---- a/dwm.c -+++ b/dwm.c -@@ -433,9 +433,15 @@ buttonpress(XEvent *e) - } - if (ev->window == selmon->barwin) { - i = x = 0; -- do -+ unsigned int occ = 0; -+ for(c = m->clients; c; c=c->next) -+ occ |= c->tags == TAGMASK ? 0 : c->tags; -+ do { -+ /* Do not reserve space for vacant tags */ -+ if (!(occ & 1 << i || m->tagset[m->seltags] & 1 << i)) -+ continue; - x += TEXTW(tags[i]); -- while (ev->x >= x && ++i < LENGTH(tags)); -+ } while (ev->x >= x && ++i < LENGTH(tags)); - if (i < LENGTH(tags)) { - click = ClkTagBar; - arg.ui = 1 << i; -@@ -715,19 +721,18 @@ drawbar(Monitor *m) - } - - for (c = m->clients; c; c = c->next) { -- occ |= c->tags; -+ occ |= c->tags == TAGMASK ? 0 : c->tags; - if (c->isurgent) - urg |= c->tags; - } - x = 0; - for (i = 0; i < LENGTH(tags); i++) { -+ /* Do not draw vacant tags */ -+ if(!(occ & 1 << i || m->tagset[m->seltags] & 1 << i)) -+ continue; - 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 = TEXTW(m->ltsymbol); - diff --git a/suckless/dwm/patch/hidevacanttags.diff.rej b/suckless/dwm/patch/hidevacanttags.diff.rej deleted file mode 100644 index a6fdf1d..0000000 --- a/suckless/dwm/patch/hidevacanttags.diff.rej +++ /dev/null @@ -1,44 +0,0 @@ ---- dwm.c -+++ dwm.c -@@ -433,9 +433,15 @@ buttonpress(XEvent *e) - } - if (ev->window == selmon->barwin) { - i = x = 0; -- do -+ unsigned int occ = 0; -+ for(c = m->clients; c; c=c->next) -+ occ |= c->tags == TAGMASK ? 0 : c->tags; -+ do { -+ /* Do not reserve space for vacant tags */ -+ if (!(occ & 1 << i || m->tagset[m->seltags] & 1 << i)) -+ continue; - x += TEXTW(tags[i]); -- while (ev->x >= x && ++i < LENGTH(tags)); -+ } while (ev->x >= x && ++i < LENGTH(tags)); - if (i < LENGTH(tags)) { - click = ClkTagBar; - arg.ui = 1 << i; -@@ -715,19 +721,18 @@ drawbar(Monitor *m) - } - - for (c = m->clients; c; c = c->next) { -- occ |= c->tags; -+ occ |= c->tags == TAGMASK ? 0 : c->tags; - if (c->isurgent) - urg |= c->tags; - } - x = 0; - for (i = 0; i < LENGTH(tags); i++) { -+ /* Do not draw vacant tags */ -+ if(!(occ & 1 << i || m->tagset[m->seltags] & 1 << i)) -+ continue; - 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 = TEXTW(m->ltsymbol); diff --git a/suckless/dwm/patch/include.c b/suckless/dwm/patch/include.c deleted file mode 100644 index 7130889..0000000 --- a/suckless/dwm/patch/include.c +++ /dev/null @@ -1,27 +0,0 @@ -/* Bar functionality */ -#include "bar_indicators.c" -#include "bar_tagicons.c" -#include "bar.c" - -#include "bar_alpha.c" -#include "bar_ltsymbol.c" -#include "bar_status.c" -#include "bar_tags.c" -#include "bar_wintitle.c" - -/* Other patches */ -#include "attachx.c" -#include "cool_autostart.c" -#include "dwmc.c" -#include "fullscreen.c" -#include "moveresize.c" -#include "movestack.c" -#include "scratchpad.c" -#include "swallow.c" -#include "togglefullscreen.c" -#include "vanitygaps.c" -#include "xrdb.c" -/* Layouts */ -#include "layout_facts.c" -#include "layout_tile.c" - diff --git a/suckless/dwm/patch/include.h b/suckless/dwm/patch/include.h deleted file mode 100644 index de7c6ec..0000000 --- a/suckless/dwm/patch/include.h +++ /dev/null @@ -1,26 +0,0 @@ -/* Bar functionality */ -#include "bar_indicators.h" -#include "bar_tagicons.h" -#include "bar.h" - -#include "bar_alpha.h" -#include "bar_ltsymbol.h" -#include "bar_status.h" -#include "bar_tags.h" -#include "bar_wintitle.h" - -/* Other patches */ -#include "attachx.h" -#include "cool_autostart.h" -#include "dwmc.h" -#include "fullscreen.h" -#include "moveresize.h" -#include "movestack.h" -#include "scratchpad.h" -#include "swallow.h" -#include "togglefullscreen.h" -#include "vanitygaps.h" -#include "xrdb.h" -/* Layouts */ -#include "layout_tile.h" - diff --git a/suckless/dwm/patch/ipc/IPCClient.h b/suckless/dwm/patch/ipc/IPCClient.h deleted file mode 100644 index ee93030..0000000 --- a/suckless/dwm/patch/ipc/IPCClient.h +++ /dev/null @@ -1,62 +0,0 @@ -#ifndef IPC_CLIENT_H_ -#define IPC_CLIENT_H_ - -#include -#include -#include - -typedef struct IPCClient IPCClient; -/** - * This structure contains the details of an IPC Client and pointers for a - * linked list - */ -struct IPCClient { - int fd; - int subscriptions; - - char *buffer; - uint32_t buffer_size; - - struct epoll_event event; - IPCClient *next; - IPCClient *prev; -}; - -typedef IPCClient *IPCClientList; - -/** - * Allocate memory for new IPCClient with the specified file descriptor and - * initialize struct. - * - * @param fd File descriptor of IPC client - * - * @return Address to allocated IPCClient struct - */ -IPCClient *ipc_client_new(int fd); - -/** - * Add an IPC Client to the specified list - * - * @param list Address of the list to add the client to - * @param nc Address of the IPCClient - */ -void ipc_list_add_client(IPCClientList *list, IPCClient *nc); - -/** - * Remove an IPCClient from the specified list - * - * @param list Address of the list to remove the client from - * @param c Address of the IPCClient - */ -void ipc_list_remove_client(IPCClientList *list, IPCClient *c); - -/** - * Get an IPCClient from the specified IPCClient list - * - * @param list List to remove the client from - * @param fd File descriptor of the IPCClient - */ -IPCClient *ipc_list_get_client(IPCClientList list, int fd); - -#endif // IPC_CLIENT_H_ - diff --git a/suckless/dwm/patch/ipc/dwm-msg.c b/suckless/dwm/patch/ipc/dwm-msg.c deleted file mode 100644 index ca1e1a4..0000000 --- a/suckless/dwm/patch/ipc/dwm-msg.c +++ /dev/null @@ -1,549 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define IPC_MAGIC "DWM-IPC" -// clang-format off -#define IPC_MAGIC_ARR { 'D', 'W', 'M', '-', 'I', 'P', 'C' } -// clang-format on -#define IPC_MAGIC_LEN 7 // Not including null char - -#define IPC_EVENT_TAG_CHANGE "tag_change_event" -#define IPC_EVENT_CLIENT_FOCUS_CHANGE "client_focus_change_event" -#define IPC_EVENT_LAYOUT_CHANGE "layout_change_event" -#define IPC_EVENT_MONITOR_FOCUS_CHANGE "monitor_focus_change_event" -#define IPC_EVENT_FOCUSED_TITLE_CHANGE "focused_title_change_event" -#define IPC_EVENT_FOCUSED_STATE_CHANGE "focused_state_change_event" - -#define YSTR(str) yajl_gen_string(gen, (unsigned char *)str, strlen(str)) -#define YINT(num) yajl_gen_integer(gen, num) -#define YDOUBLE(num) yajl_gen_double(gen, num) -#define YBOOL(v) yajl_gen_bool(gen, v) -#define YNULL() yajl_gen_null(gen) -#define YARR(body) \ - { \ - yajl_gen_array_open(gen); \ - body; \ - yajl_gen_array_close(gen); \ - } -#define YMAP(body) \ - { \ - yajl_gen_map_open(gen); \ - body; \ - yajl_gen_map_close(gen); \ - } - -typedef unsigned long Window; - -const char *DEFAULT_SOCKET_PATH = "/tmp/dwm.sock"; -static int sock_fd = -1; -static unsigned int ignore_reply = 0; - -typedef enum IPCMessageType { - IPC_TYPE_RUN_COMMAND = 0, - IPC_TYPE_GET_MONITORS = 1, - IPC_TYPE_GET_TAGS = 2, - IPC_TYPE_GET_LAYOUTS = 3, - IPC_TYPE_GET_DWM_CLIENT = 4, - IPC_TYPE_SUBSCRIBE = 5, - IPC_TYPE_EVENT = 6 -} IPCMessageType; - -// Every IPC message must begin with this -typedef struct dwm_ipc_header { - uint8_t magic[IPC_MAGIC_LEN]; - uint32_t size; - uint8_t type; -} __attribute((packed)) dwm_ipc_header_t; - -static int -recv_message(uint8_t *msg_type, uint32_t *reply_size, uint8_t **reply) -{ - uint32_t read_bytes = 0; - const int32_t to_read = sizeof(dwm_ipc_header_t); - char header[to_read]; - char *walk = header; - - // Try to read header - while (read_bytes < to_read) { - ssize_t n = read(sock_fd, header + read_bytes, to_read - read_bytes); - - if (n == 0) { - if (read_bytes == 0) { - fprintf(stderr, "Unexpectedly reached EOF while reading header."); - fprintf(stderr, - "Read %" PRIu32 " bytes, expected %" PRIu32 " total bytes.\n", - read_bytes, to_read); - return -2; - } else { - fprintf(stderr, "Unexpectedly reached EOF while reading header."); - fprintf(stderr, - "Read %" PRIu32 " bytes, expected %" PRIu32 " total bytes.\n", - read_bytes, to_read); - return -3; - } - } else if (n == -1) { - return -1; - } - - read_bytes += n; - } - - // Check if magic string in header matches - if (memcmp(walk, IPC_MAGIC, IPC_MAGIC_LEN) != 0) { - fprintf(stderr, "Invalid magic string. Got '%.*s', expected '%s'\n", - IPC_MAGIC_LEN, walk, IPC_MAGIC); - return -3; - } - - walk += IPC_MAGIC_LEN; - - // Extract reply size - memcpy(reply_size, walk, sizeof(uint32_t)); - walk += sizeof(uint32_t); - - // Extract message type - memcpy(msg_type, walk, sizeof(uint8_t)); - walk += sizeof(uint8_t); - - (*reply) = malloc(*reply_size); - - // Extract payload - read_bytes = 0; - while (read_bytes < *reply_size) { - ssize_t n = read(sock_fd, *reply + read_bytes, *reply_size - read_bytes); - - if (n == 0) { - fprintf(stderr, "Unexpectedly reached EOF while reading payload."); - fprintf(stderr, "Read %" PRIu32 " bytes, expected %" PRIu32 " bytes.\n", - read_bytes, *reply_size); - free(*reply); - return -2; - } else if (n == -1) { - if (errno == EINTR || errno == EAGAIN) continue; - free(*reply); - return -1; - } - - read_bytes += n; - } - - return 0; -} - -static int -read_socket(IPCMessageType *msg_type, uint32_t *msg_size, char **msg) -{ - int ret = -1; - - while (ret != 0) { - ret = recv_message((uint8_t *)msg_type, msg_size, (uint8_t **)msg); - - if (ret < 0) { - // Try again (non-fatal error) - if (ret == -1 && (errno == EINTR || errno == EAGAIN)) continue; - - fprintf(stderr, "Error receiving response from socket. "); - fprintf(stderr, "The connection might have been lost.\n"); - exit(2); - } - } - - return 0; -} - -static ssize_t -write_socket(const void *buf, size_t count) -{ - size_t written = 0; - - while (written < count) { - const ssize_t n = - write(sock_fd, ((uint8_t *)buf) + written, count - written); - - if (n == -1) { - if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) - continue; - else - return n; - } - written += n; - } - return written; -} - -static void -connect_to_socket() -{ - struct sockaddr_un addr; - - int sock = socket(AF_UNIX, SOCK_STREAM, 0); - - // Initialize struct to 0 - memset(&addr, 0, sizeof(struct sockaddr_un)); - - addr.sun_family = AF_UNIX; - strcpy(addr.sun_path, DEFAULT_SOCKET_PATH); - - connect(sock, (const struct sockaddr *)&addr, sizeof(struct sockaddr_un)); - - sock_fd = sock; -} - -static int -send_message(IPCMessageType msg_type, uint32_t msg_size, uint8_t *msg) -{ - dwm_ipc_header_t header = { - .magic = IPC_MAGIC_ARR, .size = msg_size, .type = msg_type}; - - size_t header_size = sizeof(dwm_ipc_header_t); - size_t total_size = header_size + msg_size; - - uint8_t buffer[total_size]; - - // Copy header to buffer - memcpy(buffer, &header, header_size); - // Copy message to buffer - memcpy(buffer + header_size, msg, header.size); - - write_socket(buffer, total_size); - - return 0; -} - -static int -is_float(const char *s) -{ - size_t len = strlen(s); - int is_dot_used = 0; - int is_minus_used = 0; - - // Floats can only have one decimal point in between or digits - // Optionally, floats can also be below zero (negative) - for (int i = 0; i < len; i++) { - if (isdigit(s[i])) - continue; - else if (!is_dot_used && s[i] == '.' && i != 0 && i != len - 1) { - is_dot_used = 1; - continue; - } else if (!is_minus_used && s[i] == '-' && i == 0) { - is_minus_used = 1; - continue; - } else - return 0; - } - - return 1; -} - -static int -is_unsigned_int(const char *s) -{ - size_t len = strlen(s); - - // Unsigned int can only have digits - for (int i = 0; i < len; i++) { - if (isdigit(s[i])) - continue; - else - return 0; - } - - return 1; -} - -static int -is_signed_int(const char *s) -{ - size_t len = strlen(s); - - // Signed int can only have digits and a negative sign at the start - for (int i = 0; i < len; i++) { - if (isdigit(s[i])) - continue; - else if (i == 0 && s[i] == '-') { - continue; - } else - return 0; - } - - return 1; -} - -static void -flush_socket_reply() -{ - IPCMessageType reply_type; - uint32_t reply_size; - char *reply; - - read_socket(&reply_type, &reply_size, &reply); - - free(reply); -} - -static void -print_socket_reply() -{ - IPCMessageType reply_type; - uint32_t reply_size; - char *reply; - - read_socket(&reply_type, &reply_size, &reply); - - printf("%.*s\n", reply_size, reply); - fflush(stdout); - free(reply); -} - -static int -run_command(const char *name, char *args[], int argc) -{ - const unsigned char *msg; - size_t msg_size; - - yajl_gen gen = yajl_gen_alloc(NULL); - - // Message format: - // { - // "command": "", - // "args": [ ... ] - // } - // clang-format off - YMAP( - YSTR("command"); YSTR(name); - YSTR("args"); YARR( - for (int i = 0; i < argc; i++) { - if (is_signed_int(args[i])) { - long long num = atoll(args[i]); - YINT(num); - } else if (is_float(args[i])) { - float num = atof(args[i]); - YDOUBLE(num); - } else { - YSTR(args[i]); - } - } - ) - ) - // clang-format on - - yajl_gen_get_buf(gen, &msg, &msg_size); - - send_message(IPC_TYPE_RUN_COMMAND, msg_size, (uint8_t *)msg); - - if (!ignore_reply) - print_socket_reply(); - else - flush_socket_reply(); - - yajl_gen_free(gen); - - return 0; -} - -static int -get_monitors() -{ - send_message(IPC_TYPE_GET_MONITORS, 1, (uint8_t *)""); - print_socket_reply(); - return 0; -} - -static int -get_tags() -{ - send_message(IPC_TYPE_GET_TAGS, 1, (uint8_t *)""); - print_socket_reply(); - - return 0; -} - -static int -get_layouts() -{ - send_message(IPC_TYPE_GET_LAYOUTS, 1, (uint8_t *)""); - print_socket_reply(); - - return 0; -} - -static int -get_dwm_client(Window win) -{ - const unsigned char *msg; - size_t msg_size; - - yajl_gen gen = yajl_gen_alloc(NULL); - - // Message format: - // { - // "client_window_id": "" - // } - // clang-format off - YMAP( - YSTR("client_window_id"); YINT(win); - ) - // clang-format on - - yajl_gen_get_buf(gen, &msg, &msg_size); - - send_message(IPC_TYPE_GET_DWM_CLIENT, msg_size, (uint8_t *)msg); - - print_socket_reply(); - - yajl_gen_free(gen); - - return 0; -} - -static int -subscribe(const char *event) -{ - const unsigned char *msg; - size_t msg_size; - - yajl_gen gen = yajl_gen_alloc(NULL); - - // Message format: - // { - // "event": "", - // "action": "subscribe" - // } - // clang-format off - YMAP( - YSTR("event"); YSTR(event); - YSTR("action"); YSTR("subscribe"); - ) - // clang-format on - - yajl_gen_get_buf(gen, &msg, &msg_size); - - send_message(IPC_TYPE_SUBSCRIBE, msg_size, (uint8_t *)msg); - - if (!ignore_reply) - print_socket_reply(); - else - flush_socket_reply(); - - yajl_gen_free(gen); - - return 0; -} - -static void -usage_error(const char *prog_name, const char *format, ...) -{ - va_list args; - va_start(args, format); - - fprintf(stderr, "Error: "); - vfprintf(stderr, format, args); - fprintf(stderr, "\nusage: %s [...]\n", prog_name); - fprintf(stderr, "Try '%s help'\n", prog_name); - - va_end(args); - exit(1); -} - -static void -print_usage(const char *name) -{ - printf("usage: %s [options] [...]\n", name); - puts(""); - puts("Commands:"); - puts(" run_command [args...] Run an IPC command"); - puts(""); - puts(" get_monitors Get monitor properties"); - puts(""); - puts(" get_tags Get list of tags"); - puts(""); - puts(" get_layouts Get list of layouts"); - puts(""); - puts(" get_dwm_client Get dwm client proprties"); - puts(""); - puts(" subscribe [events...] Subscribe to specified events"); - puts(" Options: " IPC_EVENT_TAG_CHANGE ","); - puts(" " IPC_EVENT_LAYOUT_CHANGE ","); - puts(" " IPC_EVENT_CLIENT_FOCUS_CHANGE ","); - puts(" " IPC_EVENT_MONITOR_FOCUS_CHANGE ","); - puts(" " IPC_EVENT_FOCUSED_TITLE_CHANGE ","); - puts(" " IPC_EVENT_FOCUSED_STATE_CHANGE); - puts(""); - puts(" help Display this message"); - puts(""); - puts("Options:"); - puts(" --ignore-reply Don't print reply messages from"); - puts(" run_command and subscribe."); - puts(""); -} - -int -main(int argc, char *argv[]) -{ - const char *prog_name = argv[0]; - - connect_to_socket(); - if (sock_fd == -1) { - fprintf(stderr, "Failed to connect to socket\n"); - return 1; - } - - int i = 1; - if (i < argc && strcmp(argv[i], "--ignore-reply") == 0) { - ignore_reply = 1; - i++; - } - - if (i >= argc) usage_error(prog_name, "Expected an argument, got none"); - - if (!argc || strcmp(argv[i], "help") == 0) - print_usage(prog_name); - else if (strcmp(argv[i], "run_command") == 0) { - if (++i >= argc) usage_error(prog_name, "No command specified"); - // Command name - char *command = argv[i]; - // Command arguments are everything after command name - char **command_args = argv + ++i; - // Number of command arguments - int command_argc = argc - i; - run_command(command, command_args, command_argc); - } else if (strcmp(argv[i], "get_monitors") == 0) { - get_monitors(); - } else if (strcmp(argv[i], "get_tags") == 0) { - get_tags(); - } else if (strcmp(argv[i], "get_layouts") == 0) { - get_layouts(); - } else if (strcmp(argv[i], "get_dwm_client") == 0) { - if (++i < argc) { - if (is_unsigned_int(argv[i])) { - Window win = atol(argv[i]); - get_dwm_client(win); - } else - usage_error(prog_name, "Expected unsigned integer argument"); - } else - usage_error(prog_name, "Expected the window id"); - } else if (strcmp(argv[i], "subscribe") == 0) { - if (++i < argc) { - for (int j = i; j < argc; j++) subscribe(argv[j]); - } else - usage_error(prog_name, "Expected event name"); - // Keep listening for events forever - while (1) { - print_socket_reply(); - } - } else - usage_error(prog_name, "Invalid argument '%s'", argv[i]); - - return 0; -} - diff --git a/suckless/dwm/patch/ipc/yajl_dumps.h b/suckless/dwm/patch/ipc/yajl_dumps.h deleted file mode 100644 index bb57a17..0000000 --- a/suckless/dwm/patch/ipc/yajl_dumps.h +++ /dev/null @@ -1,66 +0,0 @@ -#ifndef YAJL_DUMPS_H_ -#define YAJL_DUMPS_H_ - -#include -#include - -#define YSTR(str) yajl_gen_string(gen, (unsigned char *)str, strlen(str)) -#define YINT(num) yajl_gen_integer(gen, num) -#define YDOUBLE(num) yajl_gen_double(gen, num) -#define YBOOL(v) yajl_gen_bool(gen, v) -#define YNULL() yajl_gen_null(gen) -#define YARR(body) \ - { \ - yajl_gen_array_open(gen); \ - body; \ - yajl_gen_array_close(gen); \ - } -#define YMAP(body) \ - { \ - yajl_gen_map_open(gen); \ - body; \ - yajl_gen_map_close(gen); \ - } - -int dump_tag(yajl_gen gen, const char *name, const int tag_mask); - -int dump_tags(yajl_gen gen, int tags_len); - -int dump_client(yajl_gen gen, Client *c); - -int dump_monitor(yajl_gen gen, Monitor *mon, int is_selected); - -int dump_monitors(yajl_gen gen, Monitor *mons, Monitor *selmon); - -int dump_layouts(yajl_gen gen, const Layout layouts[], const int layouts_len); - -int dump_tag_state(yajl_gen gen, TagState state); - -int dump_tag_event(yajl_gen gen, int mon_num, TagState old_state, - TagState new_state); - -int dump_client_focus_change_event(yajl_gen gen, Client *old_client, - Client *new_client, int mon_num); - -int dump_layout_change_event(yajl_gen gen, const int mon_num, - const char *old_symbol, const Layout *old_layout, - const char *new_symbol, const Layout *new_layout); - -int dump_monitor_focus_change_event(yajl_gen gen, const int last_mon_num, - const int new_mon_num); - -int dump_focused_title_change_event(yajl_gen gen, const int mon_num, - const Window client_id, - const char *old_name, const char *new_name); - -int dump_client_state(yajl_gen gen, const ClientState *state); - -int dump_focused_state_change_event(yajl_gen gen, const int mon_num, - const Window client_id, - const ClientState *old_state, - const ClientState *new_state); - -int dump_error_message(yajl_gen gen, const char *reason); - -#endif // YAJL_DUMPS_H_ - diff --git a/suckless/dwm/patch/layout_facts.c b/suckless/dwm/patch/layout_facts.c deleted file mode 100644 index 241d344..0000000 --- a/suckless/dwm/patch/layout_facts.c +++ /dev/null @@ -1,24 +0,0 @@ -void -getfacts(Monitor *m, int msize, int ssize, float *mf, float *sf, int *mr, int *sr) -{ - unsigned int n; - float mfacts, sfacts; - int mtotal = 0, stotal = 0; - Client *c; - - for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); - mfacts = MIN(n, m->nmaster); - sfacts = n - m->nmaster; - - for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++) - if (n < m->nmaster) - mtotal += msize / mfacts; - else - stotal += ssize / sfacts; - - *mf = mfacts; // total factor of master area - *sf = sfacts; // total factor of stack area - *mr = msize - mtotal; // the remainder (rest) of pixels after an even master split - *sr = ssize - stotal; // the remainder (rest) of pixels after an even stack split -} - diff --git a/suckless/dwm/patch/layout_tile.c b/suckless/dwm/patch/layout_tile.c deleted file mode 100644 index 8d41d2a..0000000 --- a/suckless/dwm/patch/layout_tile.c +++ /dev/null @@ -1,41 +0,0 @@ -static void -tile(Monitor *m) -{ - unsigned int i, n; - int mx = 0, my = 0, mh = 0, mw = 0; - int sx = 0, sy = 0, sh = 0, sw = 0; - float mfacts, sfacts; - int mrest, srest; - Client *c; - - - int oh, ov, ih, iv; - getgaps(m, &oh, &ov, &ih, &iv, &n); - - if (n == 0) - return; - - sx = mx = m->wx + ov; - sy = my = m->wy + oh; - mh = m->wh - 2*oh - ih * (MIN(n, m->nmaster) - 1); - sh = m->wh - 2*oh - ih * (n - m->nmaster - 1); - sw = mw = m->ww - 2*ov; - - if (m->nmaster && n > m->nmaster) { - sw = (mw - iv) * (1 - m->mfact); - mw = (mw - iv) * m->mfact; - sx = mx + mw + iv; - } - - getfacts(m, mh, sh, &mfacts, &sfacts, &mrest, &srest); - - for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) - if (i < m->nmaster) { - resize(c, mx, my, mw - (2*c->bw), (mh / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), 0); - my += HEIGHT(c) + ih; - } else { - resize(c, sx, sy, sw - (2*c->bw), (sh / sfacts) + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), 0); - sy += HEIGHT(c) + ih; - } -} - diff --git a/suckless/dwm/patch/layout_tile.h b/suckless/dwm/patch/layout_tile.h deleted file mode 100644 index 78cafc8..0000000 --- a/suckless/dwm/patch/layout_tile.h +++ /dev/null @@ -1,2 +0,0 @@ -static void tile(Monitor *); - diff --git a/suckless/dwm/patch/moveresize.c b/suckless/dwm/patch/moveresize.c deleted file mode 100644 index 75d58e2..0000000 --- a/suckless/dwm/patch/moveresize.c +++ /dev/null @@ -1,65 +0,0 @@ -void -moveresize(const Arg *arg) { - /* only floating windows can be moved */ - Client *c; - c = selmon->sel; - int x, y, w, h, nx, ny, nw, nh, ox, oy, ow, oh; - char xAbs, yAbs, wAbs, hAbs; - int msx, msy, dx, dy, nmx, nmy; - unsigned int dui; - Window dummy; - - if (!c || !arg) - return; - if (selmon->lt[selmon->sellt]->arrange && !c->isfloating) - return; - if (sscanf((char *)arg->v, "%d%c %d%c %d%c %d%c", &x, &xAbs, &y, &yAbs, &w, &wAbs, &h, &hAbs) != 8) - return; - - /* compute new window position; prevent window from be positioned outside the current monitor */ - nw = c->w + w; - if (wAbs == 'W') - nw = w < selmon->mw - 2 * c->bw ? w : selmon->mw - 2 * c->bw; - - nh = c->h + h; - if (hAbs == 'H') - nh = h < selmon->mh - 2 * c->bw ? h : selmon->mh - 2 * c->bw; - - nx = c->x + x; - if (xAbs == 'X') { - if (x < selmon->mx) - nx = selmon->mx; - else if (x > selmon->mx + selmon->mw) - nx = selmon->mx + selmon->mw - nw - 2 * c->bw; - else - nx = x; - } - - ny = c->y + y; - if (yAbs == 'Y') { - if (y < selmon->my) - ny = selmon->my; - else if (y > selmon->my + selmon->mh) - ny = selmon->my + selmon->mh - nh - 2 * c->bw; - else - ny = y; - } - - ox = c->x; - oy = c->y; - ow = c->w; - oh = c->h; - - XRaiseWindow(dpy, c->win); - Bool xqp = XQueryPointer(dpy, root, &dummy, &dummy, &msx, &msy, &dx, &dy, &dui); - resize(c, nx, ny, nw, nh, True); - - /* move cursor along with the window to avoid problems caused by the sloppy focus */ - if (xqp && ox <= msx && (ox + ow) >= msx && oy <= msy && (oy + oh) >= msy) - { - nmx = c->x - ox + c->w - ow; - nmy = c->y - oy + c->h - oh; - XWarpPointer(dpy, None, None, 0, 0, 0, 0, nmx, nmy); - } -} - diff --git a/suckless/dwm/patch/moveresize.h b/suckless/dwm/patch/moveresize.h deleted file mode 100644 index 919ebad..0000000 --- a/suckless/dwm/patch/moveresize.h +++ /dev/null @@ -1,2 +0,0 @@ -static void moveresize(const Arg *arg); - diff --git a/suckless/dwm/patch/movestack.c b/suckless/dwm/patch/movestack.c deleted file mode 100644 index fe97f1d..0000000 --- a/suckless/dwm/patch/movestack.c +++ /dev/null @@ -1,51 +0,0 @@ -void -movestack(const Arg *arg) -{ - Client *c = NULL, *p = NULL, *pc = NULL, *i; - if (arg->i > 0) { - if (!selmon->sel) - return; - /* find the client after selmon->sel */ - for (c = selmon->sel->next; c && (!ISVISIBLE(c) || c->isfloating); c = c->next); - if (!c) - for (c = selmon->clients; c && (!ISVISIBLE(c) || c->isfloating); c = c->next); - } - else { - /* find the client before selmon->sel */ - for (i = selmon->clients; i != selmon->sel; i = i->next) - if(ISVISIBLE(i) && !i->isfloating) - c = i; - if (!c) - for (; i; i = i->next) - if (ISVISIBLE(i) && !i->isfloating) - c = i; - } - - /* find the client before selmon->sel and c */ - for (i = selmon->clients; i && (!p || !pc); i = i->next) { - if (i->next == selmon->sel) - p = i; - if (i->next == c) - pc = i; - } - - /* swap c and selmon->sel selmon->clients in the selmon->clients list */ - if (c && c != selmon->sel) { - Client *temp = selmon->sel->next==c?selmon->sel:selmon->sel->next; - selmon->sel->next = c->next==selmon->sel?c:c->next; - c->next = temp; - - if (p && p != c) - p->next = c; - if (pc && pc != selmon->sel) - pc->next = selmon->sel; - - if (selmon->sel == selmon->clients) - selmon->clients = c; - else if (c == selmon->clients) - selmon->clients = selmon->sel; - - arrange(selmon); - } -} - diff --git a/suckless/dwm/patch/movestack.h b/suckless/dwm/patch/movestack.h deleted file mode 100644 index 25f198f..0000000 --- a/suckless/dwm/patch/movestack.h +++ /dev/null @@ -1,2 +0,0 @@ -static void movestack(const Arg *arg); - diff --git a/suckless/dwm/patch/scratchpad.c b/suckless/dwm/patch/scratchpad.c deleted file mode 100644 index 9e24ff6..0000000 --- a/suckless/dwm/patch/scratchpad.c +++ /dev/null @@ -1,77 +0,0 @@ -void -removescratch(const Arg *arg) -{ - Client *c = selmon->sel; - if (!c) - return; - unsigned int scratchtag = SPTAG(arg->ui); - c->tags = c->mon->tagset[c->mon->seltags] ^ scratchtag; - arrange(c->mon); -} - -void -setscratch(const Arg *arg) -{ - Client *c = selmon->sel; - if (!c) - return; - unsigned int scratchtag = SPTAG(arg->ui); - c->tags = scratchtag; - arrange(c->mon); -} - -void -togglescratch(const Arg *arg) -{ - Client *c = NULL, *next = NULL, *found = NULL; - Monitor *mon; - unsigned int scratchtag = SPTAG(arg->ui); - unsigned int newtagset = 0; - int nh = 0, nw = 0; - Arg sparg = {.v = scratchpads[arg->ui].cmd}; - - for (mon = mons; mon; mon = mon->next) { - for (c = mon->clients; c; c = next) { - next = c->next; - if (!(c->tags & scratchtag)) - continue; - - found = c; - - if (HIDDEN(c)) { - XMapWindow(dpy, c->win); - setclientstate(c, NormalState); - newtagset = 0; - } else - newtagset = selmon->tagset[selmon->seltags] ^ scratchtag; - - if (c->mon != selmon) { - if (c->mon->tagset[c->mon->seltags] & SPTAGMASK) - c->mon->tagset[c->mon->seltags] ^= scratchtag; - if (c->w > selmon->ww) - nw = selmon->ww - c->bw * 2; - if (c->h > selmon->wh) - nh = selmon->wh - c->bw * 2; - if (nw > 0 || nh > 0) - resizeclient(c, c->x, c->y, nw ? nw : c->w, nh ? nh : c->h); - sendmon(c, selmon); - } - } - } - - if (found) { - if (newtagset) { - selmon->tagset[selmon->seltags] = newtagset; - focus(NULL); - arrange(selmon); - } - if (ISVISIBLE(found)) { - focus(found); - restack(selmon); - } - } else { - selmon->tagset[selmon->seltags] |= scratchtag; - spawn(&sparg); - } -} - diff --git a/suckless/dwm/patch/scratchpad.h b/suckless/dwm/patch/scratchpad.h deleted file mode 100644 index 6230266..0000000 --- a/suckless/dwm/patch/scratchpad.h +++ /dev/null @@ -1,9 +0,0 @@ -typedef struct { - const char *name; - const void *cmd; -} Sp; - -static void removescratch(const Arg *arg); -static void setscratch(const Arg *arg); -static void togglescratch(const Arg *arg); - diff --git a/suckless/dwm/patch/swallow.c b/suckless/dwm/patch/swallow.c deleted file mode 100644 index 0d65353..0000000 --- a/suckless/dwm/patch/swallow.c +++ /dev/null @@ -1,212 +0,0 @@ -#include -#include -#ifdef __OpenBSD__ -#include -#include -#endif /* __OpenBSD__ */ - -static int scanner; -static xcb_connection_t *xcon; - -int -swallow(Client *p, Client *c) -{ - Client *s; - XWindowChanges wc; - - if (c->noswallow > 0 || c->isterminal) - return 0; - if (c->noswallow < 0 && !swallowfloating && c->isfloating) - return 0; - - XMapWindow(dpy, c->win); - - detach(c); - detachstack(c); - - setclientstate(c, WithdrawnState); - XUnmapWindow(dpy, p->win); - - p->swallowing = c; - c->mon = p->mon; - - Window w = p->win; - p->win = c->win; - c->win = w; - - XChangeProperty(dpy, c->win, netatom[NetClientList], XA_WINDOW, 32, PropModeReplace, - (unsigned char *) &(p->win), 1); - - updatetitle(p); - s = scanner ? c : p; - - wc.border_width = p->bw; - XConfigureWindow(dpy, p->win, CWBorderWidth, &wc); - XMoveResizeWindow(dpy, p->win, s->x, s->y, s->w, s->h); - XSetWindowBorder(dpy, p->win, scheme[SchemeNorm][ColBorder].pixel); - - arrange(p->mon); - configure(p); - updateclientlist(); - - return 1; -} - -void -unswallow(Client *c) -{ - XWindowChanges wc; - c->win = c->swallowing->win; - - free(c->swallowing); - c->swallowing = NULL; - - XDeleteProperty(dpy, c->win, netatom[NetClientList]); - - /* unfullscreen the client */ - setfullscreen(c, 0); - updatetitle(c); - arrange(c->mon); - XMapWindow(dpy, c->win); - - wc.border_width = c->bw; - XConfigureWindow(dpy, c->win, CWBorderWidth, &wc); - XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h); - XSetWindowBorder(dpy, c->win, scheme[SchemeNorm][ColBorder].pixel); - - setclientstate(c, NormalState); - focus(NULL); - arrange(c->mon); -} - -pid_t -winpid(Window w) -{ - pid_t result = 0; - - #ifdef __linux__ - xcb_res_client_id_spec_t spec = {0}; - spec.client = w; - spec.mask = XCB_RES_CLIENT_ID_MASK_LOCAL_CLIENT_PID; - - xcb_generic_error_t *e = NULL; - xcb_res_query_client_ids_cookie_t c = xcb_res_query_client_ids(xcon, 1, &spec); - xcb_res_query_client_ids_reply_t *r = xcb_res_query_client_ids_reply(xcon, c, &e); - - if (!r) - return (pid_t)0; - - xcb_res_client_id_value_iterator_t i = xcb_res_query_client_ids_ids_iterator(r); - for (; i.rem; xcb_res_client_id_value_next(&i)) { - spec = i.data->spec; - if (spec.mask & XCB_RES_CLIENT_ID_MASK_LOCAL_CLIENT_PID) { - uint32_t *t = xcb_res_client_id_value_value(i.data); - result = *t; - break; - } - } - - free(r); - - if (result == (pid_t)-1) - result = 0; - - #endif /* __linux__ */ - #ifdef __OpenBSD__ - Atom type; - int format; - unsigned long len, bytes; - unsigned char *prop; - pid_t ret; - - if (XGetWindowProperty(dpy, w, XInternAtom(dpy, "_NET_WM_PID", 1), 0, 1, False, AnyPropertyType, &type, &format, &len, &bytes, &prop) != Success || !prop) - return 0; - - ret = *(pid_t*)prop; - XFree(prop); - result = ret; - #endif /* __OpenBSD__ */ - - return result; -} - -pid_t -getparentprocess(pid_t p) -{ - unsigned int v = 0; - -#ifdef __linux__ - FILE *f; - char buf[256]; - snprintf(buf, sizeof(buf) - 1, "/proc/%u/stat", (unsigned)p); - - if (!(f = fopen(buf, "r"))) - return (pid_t)0; - - if (fscanf(f, "%*u %*s %*c %u", (unsigned *)&v) != 1) - v = (pid_t)0; - fclose(f); -#endif /* __linux__ */ -#ifdef __OpenBSD__ - int n; - kvm_t *kd; - struct kinfo_proc *kp; - - kd = kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, NULL); - if (!kd) - return 0; - - kp = kvm_getprocs(kd, KERN_PROC_PID, p, sizeof(*kp), &n); - v = kp->p_ppid; -#endif /* __OpenBSD__ */ - return (pid_t)v; -} - -int -isdescprocess(pid_t p, pid_t c) -{ - while (p != c && c != 0) - c = getparentprocess(c); - - return (int)c; -} - -Client * -termforwin(const Client *w) -{ - Client *c; - Monitor *m; - - if (!w->pid || w->isterminal) - return NULL; - - c = selmon->sel; - if (c && c->isterminal && !c->swallowing && c->pid && isdescprocess(c->pid, w->pid)) - return c; - - for (m = mons; m; m = m->next) { - for (c = m->clients; c; c = c->next) { - if (c->isterminal && !c->swallowing && c->pid && isdescprocess(c->pid, w->pid)) - return c; - } - } - - return NULL; -} - -Client * -swallowingclient(Window w) -{ - Client *c; - Monitor *m; - - for (m = mons; m; m = m->next) { - for (c = m->clients; c; c = c->next) { - if (c->swallowing && c->swallowing->win == w) - return c; - } - } - - return NULL; -} - diff --git a/suckless/dwm/patch/swallow.h b/suckless/dwm/patch/swallow.h deleted file mode 100644 index 529fea9..0000000 --- a/suckless/dwm/patch/swallow.h +++ /dev/null @@ -1,8 +0,0 @@ -static pid_t getparentprocess(pid_t p); -static int isdescprocess(pid_t p, pid_t c); -static int swallow(Client *p, Client *c); -static Client *swallowingclient(Window w); -static Client *termforwin(const Client *c); -static void unswallow(Client *c); -static pid_t winpid(Window w); - diff --git a/suckless/dwm/patch/togglefullscreen.c b/suckless/dwm/patch/togglefullscreen.c deleted file mode 100644 index a62edef..0000000 --- a/suckless/dwm/patch/togglefullscreen.c +++ /dev/null @@ -1,10 +0,0 @@ -void -togglefullscreen(const Arg *arg) -{ - Client *c = selmon->sel; - if (!c) - return; - - setfullscreen(c, !c->isfullscreen); -} - diff --git a/suckless/dwm/patch/togglefullscreen.h b/suckless/dwm/patch/togglefullscreen.h deleted file mode 100644 index 96a6770..0000000 --- a/suckless/dwm/patch/togglefullscreen.h +++ /dev/null @@ -1,2 +0,0 @@ -static void togglefullscreen(const Arg *arg); - diff --git a/suckless/dwm/patch/vanitygaps.c b/suckless/dwm/patch/vanitygaps.c deleted file mode 100644 index d8d5e6e..0000000 --- a/suckless/dwm/patch/vanitygaps.c +++ /dev/null @@ -1,177 +0,0 @@ -/* Settings */ -static int enablegaps = 1; - -static void -setgaps(int oh, int ov, int ih, int iv) -{ - if (oh < 0) oh = 0; - if (ov < 0) ov = 0; - if (ih < 0) ih = 0; - if (iv < 0) iv = 0; - - selmon->gappoh = oh; - selmon->gappov = ov; - selmon->gappih = ih; - selmon->gappiv = iv; - - - arrange(selmon); -} - -/* External function that takes one integer and splits it - * into four gap values: - * - outer horizontal (oh) - * - outer vertical (ov) - * - inner horizontal (ih) - * - inner vertical (iv) - * - * Each value is represented as one byte with the uppermost - * bit of each byte indicating whether or not to keep the - * current value. - * - * Example: - * - * 10000000 10000000 00001111 00001111 - * | | | | - * + keep oh + keep ov + ih 15px + iv 15px - * - * This gives an int of: - * 10000000100000000000111100001111 = 2155876111 - * - * Thus this command should set inner gaps to 15: - * xsetroot -name "fsignal:setgaps i 2155876111" - */ -static void -setgapsex(const Arg *arg) -{ - int oh = selmon->gappoh; - int ov = selmon->gappov; - int ih = selmon->gappih; - int iv = selmon->gappiv; - - if (!(arg->i & (1 << 31))) - oh = (arg->i & 0x7f000000) >> 24; - if (!(arg->i & (1 << 23))) - ov = (arg->i & 0x7f0000) >> 16; - if (!(arg->i & (1 << 15))) - ih = (arg->i & 0x7f00) >> 8; - if (!(arg->i & (1 << 7))) - iv = (arg->i & 0x7f); - - /* Auto enable gaps if disabled */ - if (!enablegaps) - enablegaps = 1; - - setgaps(oh, ov, ih, iv); -} - -static void -togglegaps(const Arg *arg) -{ - enablegaps = !enablegaps; - - arrange(NULL); -} - -static void -defaultgaps(const Arg *arg) -{ - setgaps(gappoh, gappov, gappih, gappiv); -} - -static void -incrgaps(const Arg *arg) -{ - setgaps( - selmon->gappoh + arg->i, - selmon->gappov + arg->i, - selmon->gappih + arg->i, - selmon->gappiv + arg->i - ); -} - -static void -incrigaps(const Arg *arg) -{ - setgaps( - selmon->gappoh, - selmon->gappov, - selmon->gappih + arg->i, - selmon->gappiv + arg->i - ); -} - -static void -incrogaps(const Arg *arg) -{ - setgaps( - selmon->gappoh + arg->i, - selmon->gappov + arg->i, - selmon->gappih, - selmon->gappiv - ); -} - -static void -incrohgaps(const Arg *arg) -{ - setgaps( - selmon->gappoh + arg->i, - selmon->gappov, - selmon->gappih, - selmon->gappiv - ); -} - -static void -incrovgaps(const Arg *arg) -{ - setgaps( - selmon->gappoh, - selmon->gappov + arg->i, - selmon->gappih, - selmon->gappiv - ); -} - -static void -incrihgaps(const Arg *arg) -{ - setgaps( - selmon->gappoh, - selmon->gappov, - selmon->gappih + arg->i, - selmon->gappiv - ); -} - -static void -incrivgaps(const Arg *arg) -{ - setgaps( - selmon->gappoh, - selmon->gappov, - selmon->gappih, - selmon->gappiv + arg->i - ); -} - -static void -getgaps(Monitor *m, int *oh, int *ov, int *ih, int *iv, unsigned int *nc) -{ - unsigned int n, oe, ie; - oe = ie = enablegaps; - Client *c; - - for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); - if (n == 1) { - oe *= smartgaps_fact; // outer gaps disabled or multiplied when only one client - } - - *oh = m->gappoh*oe; // outer horizontal gap - *ov = m->gappov*oe; // outer vertical gap - *ih = m->gappih*ie; // inner horizontal gap - *iv = m->gappiv*ie; // inner vertical gap - *nc = n; // number of clients -} - diff --git a/suckless/dwm/patch/vanitygaps.h b/suckless/dwm/patch/vanitygaps.h deleted file mode 100644 index 8a3ed0b..0000000 --- a/suckless/dwm/patch/vanitygaps.h +++ /dev/null @@ -1,16 +0,0 @@ -/* Key binding functions */ -static void defaultgaps(const Arg *arg); -static void incrgaps(const Arg *arg); -static void incrigaps(const Arg *arg); -static void incrogaps(const Arg *arg); -static void incrohgaps(const Arg *arg); -static void incrovgaps(const Arg *arg); -static void incrihgaps(const Arg *arg); -static void incrivgaps(const Arg *arg); -static void togglegaps(const Arg *arg); - -/* Internals */ -static void getgaps(Monitor *m, int *oh, int *ov, int *ih, int *iv, unsigned int *nc); -static void setgaps(int oh, int ov, int ih, int iv); -static void setgapsex(const Arg *arg); - diff --git a/suckless/dwm/patch/xrdb.c b/suckless/dwm/patch/xrdb.c deleted file mode 100644 index f450023..0000000 --- a/suckless/dwm/patch/xrdb.c +++ /dev/null @@ -1,73 +0,0 @@ -void -loadxrdb() -{ - Display *display; - char * resm; - XrmDatabase xrdb; - char *type; - XrmValue value; - - display = XOpenDisplay(NULL); - - if (display != NULL) { - resm = XResourceManagerString(display); - - if (resm != NULL) { - xrdb = XrmGetStringDatabase(resm); - - if (xrdb != NULL) { - XRDB_LOAD_COLOR("dwm.normfgcolor", normfgcolor); - XRDB_LOAD_COLOR("dwm.normbgcolor", normbgcolor); - XRDB_LOAD_COLOR("dwm.normbordercolor", normbordercolor); - XRDB_LOAD_COLOR("dwm.normfloatcolor", normfloatcolor); - XRDB_LOAD_COLOR("dwm.selfgcolor", selfgcolor); - XRDB_LOAD_COLOR("dwm.selbgcolor", selbgcolor); - XRDB_LOAD_COLOR("dwm.selbordercolor", selbordercolor); - XRDB_LOAD_COLOR("dwm.selfloatcolor", selfloatcolor); - XRDB_LOAD_COLOR("dwm.titlenormfgcolor", titlenormfgcolor); - XRDB_LOAD_COLOR("dwm.titlenormbgcolor", titlenormbgcolor); - XRDB_LOAD_COLOR("dwm.titlenormbordercolor", titlenormbordercolor); - XRDB_LOAD_COLOR("dwm.titlenormfloatcolor", titlenormfloatcolor); - XRDB_LOAD_COLOR("dwm.titleselfgcolor", titleselfgcolor); - XRDB_LOAD_COLOR("dwm.titleselbgcolor", titleselbgcolor); - XRDB_LOAD_COLOR("dwm.titleselbordercolor", titleselbordercolor); - XRDB_LOAD_COLOR("dwm.titleselfloatcolor", titleselfloatcolor); - XRDB_LOAD_COLOR("dwm.tagsnormfgcolor", tagsnormfgcolor); - XRDB_LOAD_COLOR("dwm.tagsnormbgcolor", tagsnormbgcolor); - XRDB_LOAD_COLOR("dwm.tagsnormbordercolor", tagsnormbordercolor); - XRDB_LOAD_COLOR("dwm.tagsnormfloatcolor", tagsnormfloatcolor); - XRDB_LOAD_COLOR("dwm.tagsselfgcolor", tagsselfgcolor); - XRDB_LOAD_COLOR("dwm.tagsselbgcolor", tagsselbgcolor); - XRDB_LOAD_COLOR("dwm.tagsselbordercolor", tagsselbordercolor); - XRDB_LOAD_COLOR("dwm.tagsselfloatcolor", tagsselfloatcolor); - XRDB_LOAD_COLOR("dwm.hidnormfgcolor", hidnormfgcolor); - XRDB_LOAD_COLOR("dwm.hidnormbgcolor", hidnormbgcolor); - XRDB_LOAD_COLOR("dwm.hidselfgcolor", hidselfgcolor); - XRDB_LOAD_COLOR("dwm.hidselbgcolor", hidselbgcolor); - XRDB_LOAD_COLOR("dwm.urgfgcolor", urgfgcolor); - XRDB_LOAD_COLOR("dwm.urgbgcolor", urgbgcolor); - XRDB_LOAD_COLOR("dwm.urgbordercolor", urgbordercolor); - XRDB_LOAD_COLOR("dwm.urgfloatcolor", urgfloatcolor); - - XrmDestroyDatabase(xrdb); - } - } - } - - XCloseDisplay(display); -} - -void -xrdb(const Arg *arg) -{ - loadxrdb(); - int i; - for (i = 0; i < LENGTH(colors); i++) - scheme[i] = drw_scm_create(drw, colors[i], - alphas[i], - ColCount - ); - focus(NULL); - arrange(NULL); -} - diff --git a/suckless/dwm/patch/xrdb.h b/suckless/dwm/patch/xrdb.h deleted file mode 100644 index 3787bec..0000000 --- a/suckless/dwm/patch/xrdb.h +++ /dev/null @@ -1,22 +0,0 @@ -#include - -#define XRDB_LOAD_COLOR(R,V) if (XrmGetResource(xrdb, R, NULL, &type, &value) == True) { \ - if (value.addr != NULL && strnlen(value.addr, 8) == 7 && value.addr[0] == '#') { \ - int i = 1; \ - for (; i <= 6; i++) { \ - if (value.addr[i] < 48) break; \ - if (value.addr[i] > 57 && value.addr[i] < 65) break; \ - if (value.addr[i] > 70 && value.addr[i] < 97) break; \ - if (value.addr[i] > 102) break; \ - } \ - if (i == 7) { \ - strncpy(V, value.addr, 7); \ - V[7] = '\0'; \ - } \ - } \ - } - -static void loadxrdb(void); -static void xrdb(const Arg *arg); - - diff --git a/suckless/dwm/patches/dwm-attachaside-20160718-56a31dc.diff b/suckless/dwm/patches/dwm-attachaside-20160718-56a31dc.diff deleted file mode 100644 index b8471af..0000000 --- a/suckless/dwm/patches/dwm-attachaside-20160718-56a31dc.diff +++ /dev/null @@ -1,92 +0,0 @@ -diff --git a/dwm.c b/dwm.c -index b2bc9bd..58a86fa 100644 ---- a/dwm.c -+++ b/dwm.c -@@ -49,7 +49,8 @@ - #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 ISVISIBLEONTAG(C, T) ((C->tags & T)) -+#define ISVISIBLE(C) ISVISIBLEONTAG(C, 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) -@@ -148,6 +149,7 @@ static int applysizehints(Client *c, int *x, int *y, int *w, int *h, int interac - static void arrange(Monitor *m); - static void arrangemon(Monitor *m); - static void attach(Client *c); -+static void attachaside(Client *c); - static void attachstack(Client *c); - static void buttonpress(XEvent *e); - static void checkotherwm(void); -@@ -185,6 +187,7 @@ static void maprequest(XEvent *e); - static void monocle(Monitor *m); - static void motionnotify(XEvent *e); - static void movemouse(const Arg *arg); -+static Client *nexttagged(Client *c); - static Client *nexttiled(Client *c); - static void pop(Client *); - static void propertynotify(XEvent *e); -@@ -408,6 +411,17 @@ attach(Client *c) - } - - void -+attachaside(Client *c) { -+ Client *at = nexttagged(c); -+ if(!at) { -+ attach(c); -+ return; -+ } -+ c->next = at->next; -+ at->next = c; -+} -+ -+void - attachstack(Client *c) - { - c->snext = c->mon->stack; -@@ -1079,7 +1093,7 @@ manage(Window w, XWindowAttributes *wa) - c->isfloating = c->oldstate = trans != None || c->isfixed; - if (c->isfloating) - XRaiseWindow(dpy, c->win); -- attach(c); -+ attachaside(c); - attachstack(c); - XChangeProperty(dpy, root, netatom[NetClientList], XA_WINDOW, 32, PropModeAppend, - (unsigned char *) &(c->win), 1); -@@ -1213,6 +1227,16 @@ movemouse(const Arg *arg) - } - - Client * -+nexttagged(Client *c) { -+ Client *walked = c->mon->clients; -+ for(; -+ walked && (walked->isfloating || !ISVISIBLEONTAG(walked, c->tags)); -+ walked = walked->next -+ ); -+ return walked; -+} -+ -+Client * - nexttiled(Client *c) - { - for (; c && (c->isfloating || !ISVISIBLE(c)); c = c->next); -@@ -1437,7 +1461,7 @@ sendmon(Client *c, Monitor *m) - detachstack(c); - c->mon = m; - c->tags = m->tagset[m->seltags]; /* assign tags of target monitor */ -- attach(c); -+ attachaside(c); - attachstack(c); - focus(NULL); - arrange(NULL); -@@ -1890,7 +1914,7 @@ updategeom(void) - m->clients = c->next; - detachstack(c); - c->mon = mons; -- attach(c); -+ attachaside(c); - attachstack(c); - } - if (m == selmon) diff --git a/suckless/dwm/patches/dwm-bar-height-spacing-6.3.diff b/suckless/dwm/patches/dwm-bar-height-spacing-6.3.diff deleted file mode 100644 index cbdeb9a..0000000 --- a/suckless/dwm/patches/dwm-bar-height-spacing-6.3.diff +++ /dev/null @@ -1,25 +0,0 @@ -diff --git a/config.def.h b/config.def.h -index 1c0b587..9814500 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -5,6 +5,7 @@ static const unsigned int borderpx = 1; /* border pixel of windows */ - static const unsigned int snap = 32; /* snap pixel */ - static const int showbar = 1; /* 0 means no bar */ - static const int topbar = 1; /* 0 means bottom bar */ -+static const int user_bh = 2; /* 2 is the default spacing around the bar's font */ - static const char *fonts[] = { "monospace:size=10" }; - static const char dmenufont[] = "monospace:size=10"; - static const char col_gray1[] = "#222222"; -diff --git a/dwm.c b/dwm.c -index 4465af1..2c27cb3 100644 ---- a/dwm.c -+++ b/dwm.c -@@ -1545,7 +1545,7 @@ setup(void) - if (!drw_fontset_create(drw, fonts, LENGTH(fonts))) - die("no fonts could be loaded."); - lrpad = drw->fonts->h; -- bh = drw->fonts->h + 2; -+ bh = drw->fonts->h + user_bh; - updategeom(); - /* init atoms */ - utf8string = XInternAtom(dpy, "UTF8_STRING", False); diff --git a/suckless/dwm/patches/dwm-barpadding-20211020-a786211.diff b/suckless/dwm/patches/dwm-barpadding-20211020-a786211.diff deleted file mode 100755 index 7842181..0000000 --- a/suckless/dwm/patches/dwm-barpadding-20211020-a786211.diff +++ /dev/null @@ -1,118 +0,0 @@ -From a3cfb215f7f647d83d67e33df8f33a73e43bd65f Mon Sep 17 00:00:00 2001 -From: Bakkeby -Date: Wed, 20 Oct 2021 09:14:07 +0200 -Subject: [PATCH] barpadding: adds space between the statusbar and the edge of - the screen - ---- - config.def.h | 2 ++ - dwm.c | 25 +++++++++++++++---------- - 2 files changed, 17 insertions(+), 10 deletions(-) - -diff --git a/config.def.h b/config.def.h -index a2ac963..f0b739f 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -5,6 +5,8 @@ static const unsigned int borderpx = 1; /* border pixel of windows */ - static const unsigned int snap = 32; /* snap pixel */ - static const int showbar = 1; /* 0 means no bar */ - static const int topbar = 1; /* 0 means bottom bar */ -+static const int vertpad = 10; /* vertical padding of bar */ -+static const int sidepad = 10; /* horizontal padding of bar */ - static const char *fonts[] = { "monospace:size=10" }; - static const char dmenufont[] = "monospace:size=10"; - static const char col_gray1[] = "#222222"; -diff --git a/dwm.c b/dwm.c -index 5e4d494..df6d0d7 100644 ---- a/dwm.c -+++ b/dwm.c -@@ -242,6 +242,8 @@ 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 vp; /* vertical padding for bar */ -+static int sp; /* side padding for bar */ - static int (*xerrorxlib)(Display *, XErrorEvent *); - static unsigned int numlockmask = 0; - static void (*handler[LASTEvent]) (XEvent *) = { -@@ -568,7 +570,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); -+ XMoveResizeWindow(dpy, m->barwin, m->wx + sp, m->by + vp, m->ww - 2 * sp, bh); - } - focus(NULL); - arrange(NULL); -@@ -706,7 +708,7 @@ drawbar(Monitor *m) - if (m == selmon) { /* status is only drawn on selected monitor */ - drw_setscheme(drw, scheme[SchemeNorm]); - tw = TEXTW(stext) - lrpad + 2; /* 2px right padding */ -- drw_text(drw, m->ww - tw, 0, tw, bh, 0, stext, 0); -+ drw_text(drw, m->ww - tw - 2 * sp, 0, tw, bh, 0, stext, 0); - } - - for (c = m->clients; c; c = c->next) { -@@ -732,12 +734,12 @@ drawbar(Monitor *m) - if ((w = m->ww - tw - x) > bh) { - if (m->sel) { - drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]); -- drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0); -+ drw_text(drw, x, 0, w - 2 * sp, 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_rect(drw, x, 0, w - 2 * sp, bh, 1, 1); - } - } - drw_map(drw, m->barwin, 0, 0, m->ww, bh); -@@ -1547,7 +1549,10 @@ setup(void) - die("no fonts could be loaded."); - lrpad = drw->fonts->h; - bh = drw->fonts->h + 2; -+ sp = sidepad; -+ vp = (topbar == 1) ? vertpad : - vertpad; - updategeom(); -+ - /* init atoms */ - utf8string = XInternAtom(dpy, "UTF8_STRING", False); - wmatom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False); -@@ -1704,7 +1709,7 @@ togglebar(const Arg *arg) - { - selmon->showbar = !selmon->showbar; - updatebarpos(selmon); -- XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh); -+ XMoveResizeWindow(dpy, selmon->barwin, selmon->wx + sp, selmon->by + vp, selmon->ww - 2 * sp, bh); - arrange(selmon); - } - -@@ -1814,7 +1819,7 @@ 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), -+ m->barwin = XCreateWindow(dpy, root, m->wx + sp, m->by + vp, m->ww - 2 * sp, bh, 0, DefaultDepth(dpy, screen), - CopyFromParent, DefaultVisual(dpy, screen), - CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa); - XDefineCursor(dpy, m->barwin, cursor[CurNormal]->cursor); -@@ -1829,11 +1834,11 @@ 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; -+ m->wh = m->wh - vertpad - bh; -+ m->by = m->topbar ? m->wy : m->wy + m->wh + vertpad; -+ m->wy = m->topbar ? m->wy + bh + vp : m->wy; - } else -- m->by = -bh; -+ m->by = -bh - vp; - } - - void --- -2.33.0 - diff --git a/suckless/dwm/patches/dwm-fullgaps-6.4.diff b/suckless/dwm/patches/dwm-fullgaps-6.4.diff deleted file mode 100755 index dc52139..0000000 --- a/suckless/dwm/patches/dwm-fullgaps-6.4.diff +++ /dev/null @@ -1,94 +0,0 @@ -diff -up a/config.def.h b/config.def.h ---- a/config.def.h -+++ b/config.def.h -@@ -2,6 +2,7 @@ - - /* appearance */ - static const unsigned int borderpx = 1; /* border pixel of windows */ -+static const unsigned int gappx = 5; /* gaps between windows */ - static const unsigned int snap = 32; /* snap pixel */ - static const int showbar = 1; /* 0 means no bar */ - static const int topbar = 1; /* 0 means bottom bar */ -@@ -85,6 +86,9 @@ static const Key keys[] = { - { MODKEY, XK_period, focusmon, {.i = +1 } }, - { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } }, - { MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } }, -+ { MODKEY, XK_minus, setgaps, {.i = -1 } }, -+ { MODKEY, XK_equal, setgaps, {.i = +1 } }, -+ { MODKEY|ShiftMask, XK_equal, setgaps, {.i = 0 } }, - TAGKEYS( XK_1, 0) - TAGKEYS( XK_2, 1) - TAGKEYS( XK_3, 2) -diff -up a/dwm.c b/dwm.c ---- a/dwm.c 2023-04-30 -+++ b/dwm.c 2023-04-30 -@@ -119,6 +119,7 @@ struct Monitor { - int by; /* bar geometry */ - int mx, my, mw, mh; /* screen size */ - int wx, wy, ww, wh; /* window area */ -+ int gappx; /* gaps between windows */ - unsigned int seltags; - unsigned int sellt; - unsigned int tagset[2]; -@@ -200,6 +201,7 @@ static void sendmon(Client *c, Monitor * - static void setclientstate(Client *c, long state); - static void setfocus(Client *c); - static void setfullscreen(Client *c, int fullscreen); -+static void setgaps(const Arg *arg); - static void setlayout(const Arg *arg); - static void setmfact(const Arg *arg); - static void setup(void); -@@ -641,6 +643,7 @@ createmon(void) - m->nmaster = nmaster; - m->showbar = showbar; - m->topbar = topbar; -+ m->gappx = gappx; - m->lt[0] = &layouts[0]; - m->lt[1] = &layouts[1 % LENGTH(layouts)]; - strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol); -@@ -1508,6 +1511,16 @@ setfullscreen(Client *c, int fullscreen) - } - - void -+setgaps(const Arg *arg) -+{ -+ if ((arg->i == 0) || (selmon->gappx + arg->i < 0)) -+ selmon->gappx = 0; -+ else -+ selmon->gappx += arg->i; -+ arrange(selmon); -+} -+ -+void - setlayout(const Arg *arg) - { - if (!arg || !arg->v || arg->v != selmon->lt[selmon->sellt]) -@@ -1697,18 +1710,18 @@ tile(Monitor *m) - if (n > m->nmaster) - mw = m->nmaster ? m->ww * m->mfact : 0; - else -- mw = m->ww; -- for (i = my = ty = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) -- if (i < m->nmaster) { -- h = (m->wh - my) / (MIN(n, m->nmaster) - i); -- resize(c, m->wx, m->wy + my, mw - (2*c->bw), h - (2*c->bw), 0); -- if (my + HEIGHT(c) < m->wh) -- my += HEIGHT(c); -+ mw = m->ww - m->gappx; -+ for (i = 0, my = ty = m->gappx, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) -+ if (i < m->nmaster) { -+ h = (m->wh - my) / (MIN(n, m->nmaster) - i) - m->gappx; -+ resize(c, m->wx + m->gappx, m->wy + my, mw - (2*c->bw) - m->gappx, h - (2*c->bw), 0); -+ if (my + HEIGHT(c) + m->gappx < m->wh) -+ my += HEIGHT(c) + m->gappx; - } else { -- h = (m->wh - ty) / (n - i); -- resize(c, m->wx + mw, m->wy + ty, m->ww - mw - (2*c->bw), h - (2*c->bw), 0); -- if (ty + HEIGHT(c) < m->wh) -- ty += HEIGHT(c); -+ h = (m->wh - ty) / (n - i) - m->gappx; -+ resize(c, m->wx + mw + m->gappx, m->wy + ty, m->ww - mw - (2*c->bw) - 2*m->gappx, h - (2*c->bw), 0); -+ if (ty + HEIGHT(c) + m->gappx < m->wh) -+ ty += HEIGHT(c) + m->gappx; - } - } diff --git a/suckless/dwm/patches/dwm-notitle-20210715-138b405.diff b/suckless/dwm/patches/dwm-notitle-20210715-138b405.diff deleted file mode 100755 index bc8a3e5..0000000 --- a/suckless/dwm/patches/dwm-notitle-20210715-138b405.diff +++ /dev/null @@ -1,81 +0,0 @@ -From a3a7e94f59553689656871a65ea9ce90169a7c91 Mon Sep 17 00:00:00 2001 -From: birdalicous -Date: Thu, 15 Jul 2021 12:28:29 +0100 -Subject: [PATCH] notitle patch applied# - ---- - config.def.h | 1 - - dwm.c | 20 ++++---------------- - 2 files changed, 4 insertions(+), 17 deletions(-) - -diff --git a/config.def.h b/config.def.h -index a2ac963..eac20b4 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -103,7 +103,6 @@ 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} }, -diff --git a/dwm.c b/dwm.c -index 5e4d494..6cd9fb7 100644 ---- a/dwm.c -+++ b/dwm.c -@@ -64,8 +64,8 @@ enum { NetSupported, NetWMName, NetWMState, NetWMCheck, - NetWMFullscreen, NetActiveWindow, NetWMWindowType, - NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */ - enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */ --enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, -- ClkClientWin, ClkRootWin, ClkLast }; /* clicks */ -+enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkClientWin, -+ ClkRootWin, ClkLast }; /* clicks */ - - typedef union { - int i; -@@ -440,10 +440,8 @@ buttonpress(XEvent *e) - arg.ui = 1 << i; - } else if (ev->x < x + blw) - click = ClkLtSymbol; -- else if (ev->x > selmon->ww - (int)TEXTW(stext)) -- click = ClkStatusText; - else -- click = ClkWinTitle; -+ click = ClkStatusText; - } else if ((c = wintoclient(ev->window))) { - focus(c); - restack(selmon); -@@ -730,15 +728,8 @@ drawbar(Monitor *m) - x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0); - - if ((w = m->ww - tw - x) > bh) { -- if (m->sel) { -- drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]); -- drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0); -- if (m->sel->isfloating) -- drw_rect(drw, x + boxs, boxs, boxw, boxw, m->sel->isfixed, 0); -- } else { - drw_setscheme(drw, scheme[SchemeNorm]); - drw_rect(drw, x, 0, w, bh, 1, 1); -- } - } - drw_map(drw, m->barwin, 0, 0, m->ww, bh); - } -@@ -1236,11 +1227,8 @@ propertynotify(XEvent *e) - drawbars(); - break; - } -- if (ev->atom == XA_WM_NAME || ev->atom == netatom[NetWMName]) { -+ 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); - } --- -2.32.0 - diff --git a/suckless/dwm/patches/dwm-restartsig-20180523-6.2.diff b/suckless/dwm/patches/dwm-restartsig-20180523-6.2.diff deleted file mode 100755 index f1f8680..0000000 --- a/suckless/dwm/patches/dwm-restartsig-20180523-6.2.diff +++ /dev/null @@ -1,139 +0,0 @@ -From 2991f37f0aaf44b9f9b11e7893ff0af8eb88f649 Mon Sep 17 00:00:00 2001 -From: Christopher Drelich -Date: Wed, 23 May 2018 22:50:38 -0400 -Subject: [PATCH] Modifies quit to handle restarts and adds SIGHUP and SIGTERM - handlers. - -Modified quit() to restart if it receives arg .i = 1 -MOD+CTRL+SHIFT+Q was added to confid.def.h to do just that. - -Signal handlers were handled for SIGHUP and SIGTERM. -If dwm receives these signals it calls quit() with -arg .i = to 1 or 0, respectively. - -To restart dwm: -MOD+CTRL+SHIFT+Q -or -kill -HUP dwmpid - -To quit dwm cleanly: -MOD+SHIFT+Q -or -kill -TERM dwmpid ---- - config.def.h | 1 + - dwm.1 | 10 ++++++++++ - dwm.c | 22 ++++++++++++++++++++++ - 3 files changed, 33 insertions(+) - -diff --git a/config.def.h b/config.def.h -index a9ac303..e559429 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -94,6 +94,7 @@ static Key keys[] = { - TAGKEYS( XK_8, 7) - TAGKEYS( XK_9, 8) - { MODKEY|ShiftMask, XK_q, quit, {0} }, -+ { MODKEY|ControlMask|ShiftMask, XK_q, quit, {1} }, - }; - - /* button definitions */ -diff --git a/dwm.1 b/dwm.1 -index 13b3729..36a331c 100644 ---- a/dwm.1 -+++ b/dwm.1 -@@ -142,6 +142,9 @@ Add/remove all windows with nth tag to/from the view. - .TP - .B Mod1\-Shift\-q - Quit dwm. -+.TP -+.B Mod1\-Control\-Shift\-q -+Restart dwm. - .SS Mouse commands - .TP - .B Mod1\-Button1 -@@ -155,6 +158,13 @@ Resize focused window while dragging. Tiled windows will be toggled to the float - .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 SIGNALS -+.TP -+.B SIGHUP - 1 -+Restart the dwm process. -+.TP -+.B SIGTERM - 15 -+Cleanly terminate the dwm process. - .SH SEE ALSO - .BR dmenu (1), - .BR st (1) -diff --git a/dwm.c b/dwm.c -index bb95e26..286eecd 100644 ---- a/dwm.c -+++ b/dwm.c -@@ -205,6 +205,8 @@ static void setup(void); - static void seturgent(Client *c, int urg); - static void showhide(Client *c); - static void sigchld(int unused); -+static void sighup(int unused); -+static void sigterm(int unused); - static void spawn(const Arg *arg); - static void tag(const Arg *arg); - static void tagmon(const Arg *arg); -@@ -260,6 +262,7 @@ static void (*handler[LASTEvent]) (XEvent *) = { - [UnmapNotify] = unmapnotify - }; - static Atom wmatom[WMLast], netatom[NetLast]; -+static int restart = 0; - static int running = 1; - static Cur *cursor[CurLast]; - static Clr **scheme; -@@ -1248,6 +1251,7 @@ propertynotify(XEvent *e) - void - quit(const Arg *arg) - { -+ if(arg->i) restart = 1; - running = 0; - } - -@@ -1536,6 +1540,9 @@ setup(void) - /* clean up any zombies immediately */ - sigchld(0); - -+ signal(SIGHUP, sighup); -+ signal(SIGTERM, sigterm); -+ - /* init screen */ - screen = DefaultScreen(dpy); - sw = DisplayWidth(dpy, screen); -@@ -1637,6 +1644,20 @@ sigchld(int unused) - } - - void -+sighup(int unused) -+{ -+ Arg a = {.i = 1}; -+ quit(&a); -+} -+ -+void -+sigterm(int unused) -+{ -+ Arg a = {.i = 0}; -+ quit(&a); -+} -+ -+void - spawn(const Arg *arg) - { - if (arg->v == dmenucmd) -@@ -2139,6 +2160,7 @@ main(int argc, char *argv[]) - setup(); - scan(); - run(); -+ if(restart) execvp(argv[0], argv); - cleanup(); - XCloseDisplay(dpy); - return EXIT_SUCCESS; --- -2.7.4 - diff --git a/suckless/dwm/patches/dwm-statusallmons-6.2.diff b/suckless/dwm/patches/dwm-statusallmons-6.2.diff deleted file mode 100755 index 9d9633d..0000000 --- a/suckless/dwm/patches/dwm-statusallmons-6.2.diff +++ /dev/null @@ -1,25 +0,0 @@ -diff -up a/dwm.c b/dwm.c ---- a/dwm.c 2020-07-09 16:49:10.023585649 +0200 -+++ b/dwm.c 2020-07-09 16:49:43.497542191 +0200 -@@ -702,7 +702,7 @@ drawbar(Monitor *m) - Client *c; - - /* draw status first so it can be overdrawn by tags later */ -- if (m == selmon) { /* status is only drawn on selected monitor */ -+ if (m == selmon || 1) { /* 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); -@@ -1987,9 +1987,11 @@ updatesizehints(Client *c) - void - updatestatus(void) - { -+ Monitor* m; - if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext))) - strcpy(stext, "dwm-"VERSION); -- drawbar(selmon); -+ for(m = mons; m; m = m->next) -+ drawbar(m); - } - - void diff --git a/suckless/dwm/patches/dwm-warp-6.4.diff b/suckless/dwm/patches/dwm-warp-6.4.diff deleted file mode 100755 index 02fcdba..0000000 --- a/suckless/dwm/patches/dwm-warp-6.4.diff +++ /dev/null @@ -1,79 +0,0 @@ -From a229c36f51ad6f8b40109ed53c643f242351962a Mon Sep 17 00:00:00 2001 -From: Jonas Dujava -Date: Fri, 26 May 2023 22:14:48 +0200 -Subject: [PATCH] Warp patch - -Warps the mouse cursor to the center of the currently focused -window or screen when the mouse cursor is - (a) on a different screen, or - (b) on top of a different window. - -This version properly handles warping to windows that have not been -mapped yet (before it resulted in a change of the stack order). -See the discussion in (thanks goes to Bakkeby): - https://github.com/bakkeby/patches/issues/60 ---- - dwm.c | 26 ++++++++++++++++++++++++++ - 1 file changed, 26 insertions(+) - -diff --git a/dwm.c b/dwm.c -index e5efb6a..7ea6c14 100644 ---- a/dwm.c -+++ b/dwm.c -@@ -228,6 +228,7 @@ static void updatetitle(Client *c); - static void updatewindowtype(Client *c); - static void updatewmhints(Client *c); - static void view(const Arg *arg); -+static void warp(const Client *c); - static Client *wintoclient(Window w); - static Monitor *wintomon(Window w); - static int xerror(Display *dpy, XErrorEvent *ee); -@@ -834,6 +835,7 @@ focusmon(const Arg *arg) - unfocus(selmon->sel, 0); - selmon = m; - focus(NULL); -+ warp(selmon->sel); - } - - void -@@ -1366,6 +1368,8 @@ restack(Monitor *m) - wc.sibling = c->win; - } - } -+ if (m == selmon && (m->tagset[m->seltags] & m->sel->tags) && m->lt[m->sellt]->arrange != &monocle) -+ warp(m->sel); - XSync(dpy, False); - while (XCheckMaskEvent(dpy, EnterWindowMask, &ev)); - } -@@ -2044,6 +2048,28 @@ view(const Arg *arg) - arrange(selmon); - } - -+void -+warp(const Client *c) -+{ -+ int x, y; -+ -+ if (!c) { -+ XWarpPointer(dpy, None, root, 0, 0, 0, 0, selmon->wx + selmon->ww / 2, selmon->wy + selmon->wh / 2); -+ return; -+ } -+ -+ if (!getrootptr(&x, &y) || -+ (x > c->x - c->bw && -+ y > c->y - c->bw && -+ x < c->x + c->w + c->bw*2 && -+ y < c->y + c->h + c->bw*2) || -+ (y > c->mon->by && y < c->mon->by + bh) || -+ (c->mon->topbar && !y)) -+ return; -+ -+ XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w / 2, c->h / 2); -+} -+ - Client * - wintoclient(Window w) - { --- -2.40.1 - diff --git a/suckless/dwm/patches/dwm-xrdb-6.4.diff b/suckless/dwm/patches/dwm-xrdb-6.4.diff deleted file mode 100755 index 929b4e6..0000000 --- a/suckless/dwm/patches/dwm-xrdb-6.4.diff +++ /dev/null @@ -1,203 +0,0 @@ -From e7c65d2ce902a19a20daa751b42f8ba0209fdb61 Mon Sep 17 00:00:00 2001 -From: NekoCWD -Date: Sun, 22 Jan 2023 23:42:57 +0300 -Subject: [PATCH] [dwm] xrdb update 6.4 - ---- - config.def.h | 22 ++++++++++--------- - drw.c | 2 +- - drw.h | 2 +- - dwm.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++ - 4 files changed, 76 insertions(+), 12 deletions(-) - -diff --git a/config.def.h b/config.def.h -index 061ad66..686b947 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -7,15 +7,16 @@ 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 }, -+static char normbgcolor[] = "#222222"; -+static char normbordercolor[] = "#444444"; -+static char normfgcolor[] = "#bbbbbb"; -+static char selfgcolor[] = "#eeeeee"; -+static char selbordercolor[] = "#005577"; -+static char selbgcolor[] = "#005577"; -+static char *colors[][3] = { -+ /* fg bg border */ -+ [SchemeNorm] = { normfgcolor, normbgcolor, normbordercolor }, -+ [SchemeSel] = { selfgcolor, selbgcolor, selbordercolor }, - }; - - /* tagging */ -@@ -56,7 +57,7 @@ static const Layout layouts[] = { - #define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } } - - /* commands */ --static const char *dmenucmd[] = { "dmenu_run", "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL }; -+static const char *dmenucmd[] = { "dmenu_run", "-fn", dmenufont, "-nb", normbgcolor, "-nf", normfgcolor, "-sb", selbordercolor, "-sf", selfgcolor, NULL }; - static const char *termcmd[] = { "st", NULL }; - - static const Key keys[] = { -@@ -84,6 +85,7 @@ static const Key keys[] = { - { MODKEY, XK_period, focusmon, {.i = +1 } }, - { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } }, - { MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } }, -+ { MODKEY, XK_F5, xrdb, {.v = NULL } }, - TAGKEYS( XK_1, 0) - TAGKEYS( XK_2, 1) - TAGKEYS( XK_3, 2) -diff --git a/drw.c b/drw.c -index a58a2b4..f8a82f5 100644 ---- a/drw.c -+++ b/drw.c -@@ -195,7 +195,7 @@ drw_clr_create(Drw *drw, Clr *dest, const char *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) -+drw_scm_create(Drw *drw, char *clrnames[], size_t clrcount) - { - size_t i; - Clr *ret; -diff --git a/drw.h b/drw.h -index 6471431..bdbf950 100644 ---- a/drw.h -+++ b/drw.h -@@ -40,7 +40,7 @@ void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned in - - /* 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); -+Clr *drw_scm_create(Drw *drw, char *clrnames[], size_t clrcount); - - /* Cursor abstraction */ - Cur *drw_cur_create(Drw *drw, int shape); -diff --git a/dwm.c b/dwm.c -index e5efb6a..3fe76be 100644 ---- a/dwm.c -+++ b/dwm.c -@@ -35,6 +35,7 @@ - #include - #include - #include -+#include - #include - #ifdef XINERAMA - #include -@@ -56,6 +57,21 @@ - #define HEIGHT(X) ((X)->h + 2 * (X)->bw) - #define TAGMASK ((1 << LENGTH(tags)) - 1) - #define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad) -+#define XRDB_LOAD_COLOR(R,V) if (XrmGetResource(xrdb, R, NULL, &type, &value) == True) { \ -+ if (value.addr != NULL && strnlen(value.addr, 8) == 7 && value.addr[0] == '#') { \ -+ int i = 1; \ -+ for (; i <= 6; i++) { \ -+ if (value.addr[i] < 48) break; \ -+ if (value.addr[i] > 57 && value.addr[i] < 65) break; \ -+ if (value.addr[i] > 70 && value.addr[i] < 97) break; \ -+ if (value.addr[i] > 102) break; \ -+ } \ -+ if (i == 7) { \ -+ strncpy(V, value.addr, 7); \ -+ V[7] = '\0'; \ -+ } \ -+ } \ -+ } - - /* enums */ - enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */ -@@ -178,6 +194,7 @@ static void grabkeys(void); - static void incnmaster(const Arg *arg); - static void keypress(XEvent *e); - static void killclient(const Arg *arg); -+static void loadxrdb(void); - static void manage(Window w, XWindowAttributes *wa); - static void mappingnotify(XEvent *e); - static void maprequest(XEvent *e); -@@ -233,6 +250,7 @@ static Monitor *wintomon(Window w); - static int xerror(Display *dpy, XErrorEvent *ee); - static int xerrordummy(Display *dpy, XErrorEvent *ee); - static int xerrorstart(Display *dpy, XErrorEvent *ee); -+static void xrdb(const Arg *arg); - static void zoom(const Arg *arg); - - /* variables */ -@@ -1019,6 +1037,37 @@ killclient(const Arg *arg) - } - } - -+void -+loadxrdb() -+{ -+ Display *display; -+ char * resm; -+ XrmDatabase xrdb; -+ char *type; -+ XrmValue value; -+ -+ display = XOpenDisplay(NULL); -+ -+ if (display != NULL) { -+ resm = XResourceManagerString(display); -+ -+ if (resm != NULL) { -+ xrdb = XrmGetStringDatabase(resm); -+ -+ if (xrdb != NULL) { -+ XRDB_LOAD_COLOR("dwm.normbordercolor", normbordercolor); -+ XRDB_LOAD_COLOR("dwm.normbgcolor", normbgcolor); -+ XRDB_LOAD_COLOR("dwm.normfgcolor", normfgcolor); -+ XRDB_LOAD_COLOR("dwm.selbordercolor", selbordercolor); -+ XRDB_LOAD_COLOR("dwm.selbgcolor", selbgcolor); -+ XRDB_LOAD_COLOR("dwm.selfgcolor", selfgcolor); -+ } -+ } -+ } -+ -+ XCloseDisplay(display); -+} -+ - void - manage(Window w, XWindowAttributes *wa) - { -@@ -2110,6 +2159,17 @@ xerrorstart(Display *dpy, XErrorEvent *ee) - return -1; - } - -+void -+xrdb(const Arg *arg) -+{ -+ loadxrdb(); -+ int i; -+ for (i = 0; i < LENGTH(colors); i++) -+ scheme[i] = drw_scm_create(drw, colors[i], 3); -+ focus(NULL); -+ arrange(NULL); -+} -+ - void - zoom(const Arg *arg) - { -@@ -2134,6 +2194,8 @@ main(int argc, char *argv[]) - if (!(dpy = XOpenDisplay(NULL))) - die("dwm: cannot open display"); - checkotherwm(); -+ XrmInitialize(); -+ loadxrdb(); - setup(); - #ifdef __OpenBSD__ - if (pledge("stdio rpath proc exec", NULL) == -1) --- -2.38.2 - diff --git a/suckless/dwm/patches/hidevacanttags.diff b/suckless/dwm/patches/hidevacanttags.diff deleted file mode 100644 index 42d9c05..0000000 --- a/suckless/dwm/patches/hidevacanttags.diff +++ /dev/null @@ -1,48 +0,0 @@ -:100644 100644 f1d86b2 0000000 M dwm.c - -diff --git a/dwm.c b/dwm.c -index f1d86b2..d41cc14 100644 ---- a/dwm.c -+++ b/dwm.c -@@ -433,9 +433,15 @@ buttonpress(XEvent *e) - } - if (ev->window == selmon->barwin) { - i = x = 0; -- do -+ unsigned int occ = 0; -+ for(c = m->clients; c; c=c->next) -+ occ |= c->tags == TAGMASK ? 0 : c->tags; -+ do { -+ /* Do not reserve space for vacant tags */ -+ if (!(occ & 1 << i || m->tagset[m->seltags] & 1 << i)) -+ continue; - x += TEXTW(tags[i]); -- while (ev->x >= x && ++i < LENGTH(tags)); -+ } while (ev->x >= x && ++i < LENGTH(tags)); - if (i < LENGTH(tags)) { - click = ClkTagBar; - arg.ui = 1 << i; -@@ -715,19 +721,18 @@ drawbar(Monitor *m) - } - - for (c = m->clients; c; c = c->next) { -- occ |= c->tags; -+ occ |= c->tags == TAGMASK ? 0 : c->tags; - if (c->isurgent) - urg |= c->tags; - } - x = 0; - for (i = 0; i < LENGTH(tags); i++) { -+ /* Do not draw vacant tags */ -+ if(!(occ & 1 << i || m->tagset[m->seltags] & 1 << i)) -+ continue; - 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 = TEXTW(m->ltsymbol); diff --git a/suckless/dwm/readme.dwm.txt b/suckless/dwm/readme.dwm.txt deleted file mode 100644 index 95d4fd0..0000000 --- a/suckless/dwm/readme.dwm.txt +++ /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/suckless/dwm/transient.c b/suckless/dwm/transient.c deleted file mode 100644 index 040adb5..0000000 --- a/suckless/dwm/transient.c +++ /dev/null @@ -1,42 +0,0 @@ -/* cc transient.c -o transient -lX11 */ - -#include -#include -#include -#include - -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/suckless/dwm/util.c b/suckless/dwm/util.c deleted file mode 100644 index 8e26a51..0000000 --- a/suckless/dwm/util.c +++ /dev/null @@ -1,37 +0,0 @@ -/* See LICENSE file for copyright and license details. */ -#include -#include -#include -#include -#include - -#include "util.h" - -void -die(const char *fmt, ...) -{ - va_list ap; - int saved_errno; - - saved_errno = errno; - - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); - - if (fmt[0] && fmt[strlen(fmt)-1] == ':') - fprintf(stderr, " %s", strerror(saved_errno)); - fputc('\n', stderr); - - exit(1); -} - -void * -ecalloc(size_t nmemb, size_t size) -{ - void *p; - - if (!(p = calloc(nmemb, size))) - die("calloc:"); - return p; -} diff --git a/suckless/dwm/util.h b/suckless/dwm/util.h deleted file mode 100644 index c0a50d4..0000000 --- a/suckless/dwm/util.h +++ /dev/null @@ -1,9 +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)) -#define LENGTH(X) (sizeof (X) / sizeof (X)[0]) - -void die(const char *fmt, ...); -void *ecalloc(size_t nmemb, size_t size); diff --git a/suckless/dwm/util.o b/suckless/dwm/util.o deleted file mode 100644 index 5dd48bf05707c29dd79ea9c028b4d6e8fb4493f5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2472 zcmbuAO>7%Q6vy8tE(tWX(+W_eQnW%-u%)uHDTpY1$S5vZkU;@jRlvb)opoc?@tXA* zrGP{b1!)yU>VX3X4jede;J~2=4v4zyp+{~A^-{s9hf1{SjSr>oKRc5QTU$c#q_^+Q z?|tm-%58A?>VXVqQCi^Vq53LO?Iy2#I#DOiD`eUCfqAE zkt=I5tI9W?A$inKuBC$yC$|>{BKbY-oHkRf{jCR75Nwha0^eobjXNri*+3jh$M>c~x?fx8{nyD^pLGt-OiiEXdScyPe#qvp))K~}6+Rvu$8ihE-?_H0ysZ47^941aqJ5618ob3B)M9<|oYPLIi_ zfoylYCVBP6GAsBZAoEzWO)t)RtU}=J_Ubmr;-4&@cE=ER>Lm8i9`P<5$vGS+%QAHn|Mbm%3#S0ccq&fPd z#^gU@<>Qna?y?U-KGaB6JBFL{KwkgsnhZ{{m2qlUjTeWVz?0#+ByS~<0ePqTee&W6 z1Eg2H3VF?FZH+%TV>g9%cW=-t~Oe6uojw`{Xgq+ zIhMluji`oIb>;tyUMD@Y-td$hWP^3Bro)|U5s+nB*JID&nlIEGf-H}+f}8Ir7-Thb z-;}1g#)mz^ik|Zt9GEiQ~q%Q$HUC zN94ZA4DYvnR?+7RUB8ThC1(8%dY2ufX6vv2%lZ!2j@tiq{p&F6g8j#L#oXWQ|EPO& u8qMnoZRmMmAJ8&ekDl4RXGGs?*u}sS-EN2MXKz&fH+udb>|~}+w*C&KO+bzS diff --git a/suckless/dwmblocks b/suckless/dwmblocks deleted file mode 160000 index 8cedd22..0000000 --- a/suckless/dwmblocks +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 8cedd220684064f1433749ed2a19a6184c22cf07 diff --git a/suckless/slstatus/LICENSE b/suckless/slstatus/LICENSE deleted file mode 100644 index 8bee9c8..0000000 --- a/suckless/slstatus/LICENSE +++ /dev/null @@ -1,43 +0,0 @@ -ISC License - -Copyright 2016-2022 Aaron Marcher - -Copyright 2016 Roy Freytag -Copyright 2016 Vincent Loupmon -Copyright 2016 Daniel Walter -Copyright 2016-2018 Ali H. Fardan -Copyright 2016 Jody Leonard -Copyright 2016-2018 Quentin Rameau -Copyright 2016 Mike Coddington -Copyright 2016-2018 Ivan J. -Copyright 2017 Tobias Stoeckmann -Copyright 2017-2018 Laslo Hunhold -Copyright 2018 Darron Anderson -Copyright 2018 Josuah Demangeon -Copyright 2018 Tobias Tschinkowitz -Copyright 2018 David Demelier -Copyright 2018-2012 Michael Buch -Copyright 2018 Ian Remmler -Copyright 2016-2019 Joerg Jung -Copyright 2019 Ryan Kes -Copyright 2019 Cem Keylan -Copyright 2019 Dimitris Papastamos -Copyright 2019-2022 Ingo Feinerer -Copyright 2020 Alexandre Ratchov -Copyright 2020 Mart Lubbers -Copyright 2020 Daniel Moch -Copyright 2022 Nickolas Raymond Kaczynski -Copyright 2022 Patrick Iacob -Copyright 2021-2022 Steven Ward - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/suckless/slstatus/Makefile b/suckless/slstatus/Makefile deleted file mode 100644 index 7a18274..0000000 --- a/suckless/slstatus/Makefile +++ /dev/null @@ -1,69 +0,0 @@ -# See LICENSE file for copyright and license details -# slstatus - suckless status monitor -.POSIX: - -include config.mk - -REQ = util -COM =\ - components/battery\ - components/cat\ - components/cpu\ - components/datetime\ - components/disk\ - components/entropy\ - components/hostname\ - components/ip\ - components/kernel_release\ - components/keyboard_indicators\ - components/keymap\ - components/load_avg\ - components/netspeeds\ - components/num_files\ - components/ram\ - components/run_command\ - components/swap\ - components/temperature\ - components/uptime\ - components/user\ - components/volume\ - components/wifi - -all: slstatus - -$(COM:=.o): config.mk $(REQ:=.h) slstatus.h -slstatus.o: slstatus.c slstatus.h arg.h config.h config.mk $(REQ:=.h) - -.c.o: - $(CC) -o $@ -c $(CPPFLAGS) $(CFLAGS) $< - -config.h: - cp config.def.h $@ - -slstatus: slstatus.o $(COM:=.o) $(REQ:=.o) - $(CC) -o $@ $(LDFLAGS) $(COM:=.o) $(REQ:=.o) slstatus.o $(LDLIBS) - -clean: - rm -f slstatus slstatus.o $(COM:=.o) $(REQ:=.o) slstatus-${VERSION}.tar.gz - -dist: - rm -rf "slstatus-$(VERSION)" - mkdir -p "slstatus-$(VERSION)/components" - cp -R LICENSE Makefile README config.mk config.def.h \ - arg.h slstatus.h slstatus.c $(REQ:=.c) $(REQ:=.h) \ - slstatus.1 "slstatus-$(VERSION)" - cp -R $(COM:=.c) "slstatus-$(VERSION)/components" - tar -cf - "slstatus-$(VERSION)" | gzip -c > "slstatus-$(VERSION).tar.gz" - rm -rf "slstatus-$(VERSION)" - -install: all - mkdir -p "$(DESTDIR)$(PREFIX)/bin" - cp -f slstatus "$(DESTDIR)$(PREFIX)/bin" - chmod 755 "$(DESTDIR)$(PREFIX)/bin/slstatus" - mkdir -p "$(DESTDIR)$(MANPREFIX)/man1" - cp -f slstatus.1 "$(DESTDIR)$(MANPREFIX)/man1" - chmod 644 "$(DESTDIR)$(MANPREFIX)/man1/slstatus.1" - -uninstall: - rm -f "$(DESTDIR)$(PREFIX)/bin/slstatus" - rm -f "$(DESTDIR)$(MANPREFIX)/man1/slstatus.1" diff --git a/suckless/slstatus/arg.h b/suckless/slstatus/arg.h deleted file mode 100644 index 5f1f408..0000000 --- a/suckless/slstatus/arg.h +++ /dev/null @@ -1,33 +0,0 @@ -/* See LICENSE file for copyright and license details. */ -#ifndef ARG_H -#define ARG_H - -extern char *argv0; - -/* int main(int argc, char *argv[]) */ -#define ARGBEGIN for (argv0 = *argv, *argv ? (argc--, argv++) : ((void *)0); \ - *argv && (*argv)[0] == '-' && (*argv)[1]; argc--, argv++) { \ - int i_, argused_; \ - if ((*argv)[1] == '-' && !(*argv)[2]) { \ - argc--, argv++; \ - break; \ - } \ - for (i_ = 1, argused_ = 0; (*argv)[i_]; i_++) { \ - switch ((*argv)[i_]) -#define ARGEND if (argused_) { \ - if ((*argv)[i_ + 1]) { \ - break; \ - } else { \ - argc--, argv++; \ - break; \ - } \ - } \ - } \ - } -#define ARGC() ((*argv)[i_]) -#define ARGF_(x) (((*argv)[i_ + 1]) ? (argused_ = 1, &((*argv)[i_ + 1])) : \ - (*(argv + 1)) ? (argused_ = 1, *(argv + 1)) : (x)) -#define EARGF(x) ARGF_(((x), exit(1), (char *)0)) -#define ARGF() ARGF_((char *)0) - -#endif diff --git a/suckless/slstatus/components/battery.c b/suckless/slstatus/components/battery.c deleted file mode 100644 index d5ef9ea..0000000 --- a/suckless/slstatus/components/battery.c +++ /dev/null @@ -1,247 +0,0 @@ -/* See LICENSE file for copyright and license details. */ -#include -#include - -#include "../slstatus.h" -#include "../util.h" - -#if defined(__linux__) -/* - * https://www.kernel.org/doc/html/latest/power/power_supply_class.html - */ - #include - #include - #include - - #define POWER_SUPPLY_CAPACITY "/sys/class/power_supply/%s/capacity" - #define POWER_SUPPLY_STATUS "/sys/class/power_supply/%s/status" - #define POWER_SUPPLY_CHARGE "/sys/class/power_supply/%s/charge_now" - #define POWER_SUPPLY_ENERGY "/sys/class/power_supply/%s/energy_now" - #define POWER_SUPPLY_CURRENT "/sys/class/power_supply/%s/current_now" - #define POWER_SUPPLY_POWER "/sys/class/power_supply/%s/power_now" - - static const char * - pick(const char *bat, const char *f1, const char *f2, char *path, - size_t length) - { - if (esnprintf(path, length, f1, bat) > 0 && - access(path, R_OK) == 0) - return f1; - - if (esnprintf(path, length, f2, bat) > 0 && - access(path, R_OK) == 0) - return f2; - - return NULL; - } - - const char * - battery_perc(const char *bat) - { - int cap_perc; - char path[PATH_MAX]; - - if (esnprintf(path, sizeof(path), POWER_SUPPLY_CAPACITY, bat) < 0) - return NULL; - if (pscanf(path, "%d", &cap_perc) != 1) - return NULL; - - return bprintf("%d", cap_perc); - } - - const char * - battery_state(const char *bat) - { - static struct { - char *state; - char *symbol; - } map[] = { - { "Charging", "󰚥" }, - { "Discharging", "󰚦" }, - { "Full", "󰚥" }, - { "Not charging", "󰚥"}, - }; - size_t i; - char path[PATH_MAX], state[12]; - - if (esnprintf(path, sizeof(path), POWER_SUPPLY_STATUS, bat) < 0) - return NULL; - if (pscanf(path, "%12[a-zA-Z ]", state) != 1) - return NULL; - - for (i = 0; i < LEN(map); i++) - if (!strcmp(map[i].state, state)) - break; - - return (i == LEN(map)) ? "?" : map[i].symbol; - } - - const char * - battery_remaining(const char *bat) - { - uintmax_t charge_now, current_now, m, h; - double timeleft; - char path[PATH_MAX], state[12]; - - if (esnprintf(path, sizeof(path), POWER_SUPPLY_STATUS, bat) < 0) - return NULL; - if (pscanf(path, "%12[a-zA-Z ]", state) != 1) - return NULL; - - if (!pick(bat, POWER_SUPPLY_CHARGE, POWER_SUPPLY_ENERGY, path, - sizeof(path)) || - pscanf(path, "%ju", &charge_now) < 0) - return NULL; - - if (!strcmp(state, "Discharging")) { - if (!pick(bat, POWER_SUPPLY_CURRENT, POWER_SUPPLY_POWER, path, - sizeof(path)) || - pscanf(path, "%ju", ¤t_now) < 0) - return NULL; - - if (current_now == 0) - return NULL; - - timeleft = (double)charge_now / (double)current_now; - h = timeleft; - m = (timeleft - (double)h) * 60; - - return bprintf("%juh %jum", h, m); - } - - return ""; - } -#elif defined(__OpenBSD__) - #include - #include - #include - #include - - static int - load_apm_power_info(struct apm_power_info *apm_info) - { - int fd; - - fd = open("/dev/apm", O_RDONLY); - if (fd < 0) { - warn("open '/dev/apm':"); - return 0; - } - - memset(apm_info, 0, sizeof(struct apm_power_info)); - if (ioctl(fd, APM_IOC_GETPOWER, apm_info) < 0) { - warn("ioctl 'APM_IOC_GETPOWER':"); - close(fd); - return 0; - } - return close(fd), 1; - } - - const char * - battery_perc(const char *unused) - { - struct apm_power_info apm_info; - - if (load_apm_power_info(&apm_info)) - return bprintf("%d", apm_info.battery_life); - - return NULL; - } - - const char * - battery_state(const char *unused) - { - struct { - unsigned int state; - char *symbol; - } map[] = { - { APM_AC_ON, "+" }, - { APM_AC_OFF, "-" }, - }; - struct apm_power_info apm_info; - size_t i; - - if (load_apm_power_info(&apm_info)) { - for (i = 0; i < LEN(map); i++) - if (map[i].state == apm_info.ac_state) - break; - - return (i == LEN(map)) ? "?" : map[i].symbol; - } - - return NULL; - } - - const char * - battery_remaining(const char *unused) - { - struct apm_power_info apm_info; - unsigned int h, m; - - if (load_apm_power_info(&apm_info)) { - if (apm_info.ac_state != APM_AC_ON) { - h = apm_info.minutes_left / 60; - m = apm_info.minutes_left % 60; - return bprintf("%uh %02um", h, m); - } else { - return ""; - } - } - - return NULL; - } -#elif defined(__FreeBSD__) - #include - - #define BATTERY_LIFE "hw.acpi.battery.life" - #define BATTERY_STATE "hw.acpi.battery.state" - #define BATTERY_TIME "hw.acpi.battery.time" - - const char * - battery_perc(const char *unused) - { - int cap_perc; - size_t len; - - len = sizeof(cap_perc); - if (sysctlbyname(BATTERY_LIFE, &cap_perc, &len, NULL, 0) < 0 || !len) - return NULL; - - return bprintf("%d", cap_perc); - } - - const char * - battery_state(const char *unused) - { - int state; - size_t len; - - len = sizeof(state); - if (sysctlbyname(BATTERY_STATE, &state, &len, NULL, 0) < 0 || !len) - return NULL; - - switch (state) { - case 0: /* FALLTHROUGH */ - case 2: - return "+"; - case 1: - return "-"; - default: - return "?"; - } - } - - const char * - battery_remaining(const char *unused) - { - int rem; - size_t len; - - len = sizeof(rem); - if (sysctlbyname(BATTERY_TIME, &rem, &len, NULL, 0) < 0 || !len - || rem < 0) - return NULL; - - return bprintf("%uh %02um", rem / 60, rem % 60); - } -#endif diff --git a/suckless/slstatus/components/battery.o b/suckless/slstatus/components/battery.o deleted file mode 100644 index 28b2ca745efec5a55610d4ddc360c8d4e32b238d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5208 zcmb_gZERat89sIs>acR{j<#g9o36lN9&2vmw%fwjYBx=D176u!B6a=1y>)JyP{%gc z*IH5ysw&O4tJG*nz^3tI7(q*tNm5>;e@IL3B zW1rqSL7I3apO5D}@5g!1d(XY{iN4I9a45v2gxLM8F_S1`?Xku<#fK@jp2b*tXu!Lk ztfdDByf;j5X~^_`ZF>KF*!12vy=!NPz|s#cfInS3u{l}GcvmvsI~*s9T-dmH=b0Ab zG@!~Gi<=~r@h%IZ8&1Bt-}L@);86Nt`p_%aqIY~a^sssIJ-9Ka*2SrLuidO}gg@?M z*qmwUNN~%i;t^scYi2bck5GsWUz07#+Tz`2^>(O%Fc@#)@xRU8E}ySloN)nNOx8GJ z&isHI8#eFWz^%KjK7R5X(saO&EIpJSyeYcGiqSz6&JV`hd2|=K$>|!8ZeON49AAg! zdk`drLRqXwXI49T=x+{qe=}#k!!q7qg|fTJTzb|l(0SBAN*R~Oeu6X%zr z2VcYN12g*4e|DPF|L{%yW|7L|Dm`)Lg#~zQn};=G!`eZz_6R@fhPC-cjTYc@>pYqI zaHm=Qil0KhKNJGatVtpCGzy`sJX!9_<*jnLt5kf{cCzJ4sg$4W>LAoAS-CNHl64HT zoop3i*|pqCnRO($9k4o&r#tuShuCU-yI?yK zw`lgj&o1~$!%rH1`n4BHb6yYsTuTsIcSdyRpMxGr8zo~E{Y(0qh0sj~xaQ3b^3}pV zSiX4$xt7^%tlmPyu!8fPiRCr?G#Xrtw$LxcK2`@)^%3kha0!2g5BM`LA>Q99@c0cV zV>ky?!Ce77De$ia@OuUB+iNU-N#Kt(AU;Y7{6qln6Zi`O{Hp^0SpfgK!1o1kzlK`b zF9P^}!T(bLKg{Q-s2gR3Pa`b2lIM6UQ$CG2;!um{D=0Y6X8080x6(<<^X4^A*i$R; zpI!lfZUuanaM<4@N{&Axgq>M||El2sMezAEK^Qw?xvuR@8aY-P%N;Xv#X{LFImMFE z&BiUXMy8iHNsP9m*@0#ontRdQho%S37tq{;Ch4niog}9wxoUC;v&)5&Ggfd%n3c=f z<+6+*Te2MrqMWk|BkYKvWV7_z$Q{e(MvrAjtg(EZjJJu+%C3_eFV#WE9=FB{xSUxB z_C|txZxj9gO>b?;{QyaV_(ML-@lVlM^2rnz@KyYW0>{;|mVT1|vcQA(f2HtIbCUnI z!oN+yuPXSb6+9x&5B4`J_;!IK9^B#5{sD!r=Hc54|Kke(F@>+j^Mu03EhOzfqww(| zE%8}}k2_G}zf<^X{9y!65{$o7;K6+EQTS^74=H>#{;a}ZM}A~HBMSZr1wXFfnu4ER z!T!?FDfoH?Kda!kD)^rj`|5rl5HEf#e^TN9Si$j*mwsPX zaD0zS{G7m%f3*(ZQgHPgiN*!T44qrVdCPlN;`kniVDAu#%lAOL57+VA1YZx}cL+QY zz@`1}0RCCQ?+M_NuL~S`6RG8hd=E)n-s?{W`0_qJAHe0k%Z&2mxN9Au-gW$bRE``w zZyByV;WA^`axG>Yq1(}LikN_&H0VC%B#zLC7L9x{XXWd(T-l|oI9D7Wr!Pfj6pF5G z(Dz^`zedIUXrW@@inks5Z1)Y?quCM18n;E%AHCB_6)6sWsiX*l{9V+IKl8bAj2^Xw zx=GPbl}mWYNhX9oo=NzTbtUWNa{>>zVFrvg5m65H6?`AT=10}XcNA=Hqn|3$e|Ny4 zoXWnBlrRqZKiukDOZi>B)$1dFkfN?x{`MhZBsJbLhAGY{m_O7x{Ns*M<$2*>KCg03 z>dPJ#1bzA3N#3l`*Cil&xo_DQ2$y4(IxqB94C5g8yM*C=tUkNoN&N>gQAEZqp&!uz zHiP=QEa-s4p#Jwsw^{z%@lqf;%v(SIcn?W^S-;JELq*4?NESq3Fo*YfP#^F9VC@jZ cBI5b^Jtm3-wnP8zHP@dI@jtKVVi?r_FVAJ@ -#include - -#include "../slstatus.h" -#include "../util.h" - -const char * -cat(const char *path) -{ - char *f; - FILE *fp; - - if (!(fp = fopen(path, "r"))) { - warn("fopen '%s':", path); - return NULL; - } - - f = fgets(buf, sizeof(buf) - 1, fp); - if (fclose(fp) < 0) { - warn("fclose '%s':", path); - return NULL; - } - if (!f) - return NULL; - - if ((f = strrchr(buf, '\n'))) - f[0] = '\0'; - - return buf[0] ? buf : NULL; -} - diff --git a/suckless/slstatus/components/cat.o b/suckless/slstatus/components/cat.o deleted file mode 100644 index b861349cd8c0b33a922d298f79481f4e1fc8ae1c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2128 zcmbu9&ubG=5XUD;Ypd2ZN|j(m_Mo;FyCiLuQm`hiwy8v^KMMXTC5@W~Y?8X!VylQk zsSq&W)&Im(3H~~J?ZuM^!Gnr|V1+v0&6{MiO+a+u<;{HF%)EVX-sJK5#JJz*BM~2s zP|Xrb^uDF0M;$dv8ttL)dyo8zO~*^8z+%^?uf~g;mp{RX7eB;HXB=&jB}P>YL{9T+Kp?!CD7(f+xHMOZ)4Puqx`!#9TF4hnWzfXf*s$I+Vdm_7UXKhK14dY196F&? zWFZ_k$OAbiE=`l4s0_y6?Fe+8M{V8btjpc`sNU{$qKJGCu8?mz=egiq4=BKiY)%HsO&b{B#pesibYB z$ViNZ@e{#MKVap#(A-j*((|TWP)~;LC#@V6Y|BbzEY7);2L$(mxA1$bA~-(;?*ex! zTxT5uf2;{V3CIGDVhTSC$O2#NCHw*)3pm<9_;o-QV@|OMooksIl-> zKon@I%su+cpteu=AgYT>|XGF8ig`{Dd%QhKzl6I1exk7;qD-Q$i z5rfN-%4f6Om}KPgwrOzd^%d-7>aMcqb4$je#f@#*D;$c1W@a{RC9`Jr3;s*dIT}5* z!;>YdY25XCcl_s6?J&VP+Z zKOtv754XtvIGW}`G{e?H$8*wky{zGa;@8XSm -#include -#include - -#include "../slstatus.h" -#include "../util.h" - -#if defined(__linux__) - #define CPU_FREQ "/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq" - - const char * - cpu_freq(const char *unused) - { - uintmax_t freq; - - /* in kHz */ - if (pscanf(CPU_FREQ, "%ju", &freq) != 1) - return NULL; - - return fmt_human(freq * 1000, 1000); - } - - const char * - cpu_perc(const char *unused) - { - static long double a[7]; - long double b[7], sum; - - memcpy(b, a, sizeof(b)); - /* cpu user nice system idle iowait irq softirq */ - if (pscanf("/proc/stat", "%*s %Lf %Lf %Lf %Lf %Lf %Lf %Lf", - &a[0], &a[1], &a[2], &a[3], &a[4], &a[5], &a[6]) - != 7) - return NULL; - - if (b[0] == 0) - return NULL; - - sum = (b[0] + b[1] + b[2] + b[3] + b[4] + b[5] + b[6]) - - (a[0] + a[1] + a[2] + a[3] + a[4] + a[5] + a[6]); - - if (sum == 0) - return NULL; - - return bprintf("%d", (int)(100 * - ((b[0] + b[1] + b[2] + b[5] + b[6]) - - (a[0] + a[1] + a[2] + a[5] + a[6])) / sum)); - } -#elif defined(__OpenBSD__) - #include - #include - #include - - const char * - cpu_freq(const char *unused) - { - int freq, mib[2]; - size_t size; - - mib[0] = CTL_HW; - mib[1] = HW_CPUSPEED; - - size = sizeof(freq); - - /* in MHz */ - if (sysctl(mib, 2, &freq, &size, NULL, 0) < 0) { - warn("sysctl 'HW_CPUSPEED':"); - return NULL; - } - - return fmt_human(freq * 1E6, 1000); - } - - const char * - cpu_perc(const char *unused) - { - int mib[2]; - static uintmax_t a[CPUSTATES]; - uintmax_t b[CPUSTATES], sum; - size_t size; - - mib[0] = CTL_KERN; - mib[1] = KERN_CPTIME; - - size = sizeof(a); - - memcpy(b, a, sizeof(b)); - if (sysctl(mib, 2, &a, &size, NULL, 0) < 0) { - warn("sysctl 'KERN_CPTIME':"); - return NULL; - } - if (b[0] == 0) - return NULL; - - sum = (a[CP_USER] + a[CP_NICE] + a[CP_SYS] + a[CP_INTR] + a[CP_IDLE]) - - (b[CP_USER] + b[CP_NICE] + b[CP_SYS] + b[CP_INTR] + b[CP_IDLE]); - - if (sum == 0) - return NULL; - - return bprintf("%d", 100 * - ((a[CP_USER] + a[CP_NICE] + a[CP_SYS] + - a[CP_INTR]) - - (b[CP_USER] + b[CP_NICE] + b[CP_SYS] + - b[CP_INTR])) / sum); - } -#elif defined(__FreeBSD__) - #include - #include - #include - - const char * - cpu_freq(const char *unused) - { - int freq; - size_t size; - - size = sizeof(freq); - /* in MHz */ - if (sysctlbyname("hw.clockrate", &freq, &size, NULL, 0) < 0 || !size) { - warn("sysctlbyname 'hw.clockrate':"); - return NULL; - } - - return fmt_human(freq * 1E6, 1000); - } - - const char * - cpu_perc(const char *unused) - { - size_t size; - static long a[CPUSTATES]; - long b[CPUSTATES], sum; - - size = sizeof(a); - memcpy(b, a, sizeof(b)); - if (sysctlbyname("kern.cp_time", &a, &size, NULL, 0) < 0 || !size) { - warn("sysctlbyname 'kern.cp_time':"); - return NULL; - } - if (b[0] == 0) - return NULL; - - sum = (a[CP_USER] + a[CP_NICE] + a[CP_SYS] + a[CP_INTR] + a[CP_IDLE]) - - (b[CP_USER] + b[CP_NICE] + b[CP_SYS] + b[CP_INTR] + b[CP_IDLE]); - - if (sum == 0) - return NULL; - - return bprintf("%d", 100 * - ((a[CP_USER] + a[CP_NICE] + a[CP_SYS] + - a[CP_INTR]) - - (b[CP_USER] + b[CP_NICE] + b[CP_SYS] + - b[CP_INTR])) / sum); - } -#endif diff --git a/suckless/slstatus/components/cpu.o b/suckless/slstatus/components/cpu.o deleted file mode 100644 index 8b3d1b15663a246b52c20830c78340280cebfc84..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3168 zcma)7Z%iCj5Py56aJIN$gUQ7z z5JGKGQ$jA`W8)`2^n)?R_|Z>>0#$5H<2Ube;i7(m&@>YLV2laQynS;luaI;u^JeDv zX5PFvJMZ0%{@CjQMPWn=yTo=aLK#~O?&?vlMp+9}*P$bRy zhV~A$=lb+uWXYWSV*~NI<(>P*Hgl{;-#EnB_c(BTD*!(8SM*@ge5H*Cx`+9MIlCHK z;W=(TTEO*6hjAT|t$M~Yc+Tpyp7sFH-mPn9UF)uE9d#{K*MfuQ>_)3M#7gF$u~PIm zvt<5amIjw1OSBnn_MfJf&$c0L<#BafAFgh$SE{FVP+NgD;7;Hu@ZeNq%coy~W9^69 zJ&}cPw|3XFNP1S~LHWnpDvYb;d(|G@1Iu;S@=AFb^3;B>Jg)qNNv9g!;mX6UK;>a& zTA#s4QTo(;AGhy+@^fMejbac;fr z|81#$YrPC#$n#x6-}VoSEbL4=;iUcXSi*KtckN6#kuM^5;*cuXABCNSH9nRdjVFqQ zI0CHwl%uuBQU@^$=L@++*l{hFwI?Cd+GRG-+j~*#7_hT$E~iDhjB`e(mhV0(RNM}0 z0B!}w_855U9Ts402{Gs}PN-|ZyYmX4r(Rc>XOn*$k77)jdYdT|t;+G{rr-iNBYr~6 z;qI8JYJnj&cpB6$fukRLL%pp8uBnSkzxpNcx5|*ZpagzBq6Yhqj;cZ7`h>vH2DZKP z!~_6`_Pv>itG+#OyJ`1`vM*Ip91E#W%1 z8zq#nlYkuaor~8Lu(QD4p7w^kdH~*g0Dc85aKE@;ROVNaDD9c zYiIyXdV=HFJLG@Ehoe8?pZjoZX2KVIIQrvWk-qRmJuls%I}(of2+ z^J^b|#D}j59M6mQhx|3rk?_38MBPFmJV_IVGnsL%5oS1U!INpy3ih~Vxb}q0jHKmS z%ouSTW)yO0pnJrCDQmM)1wr_p$?j_c81yd+I(KfdBvi diff --git a/suckless/slstatus/components/datetime.c b/suckless/slstatus/components/datetime.c deleted file mode 100644 index 5b10daf..0000000 --- a/suckless/slstatus/components/datetime.c +++ /dev/null @@ -1,20 +0,0 @@ -/* See LICENSE file for copyright and license details. */ -#include -#include - -#include "../slstatus.h" -#include "../util.h" - -const char * -datetime(const char *fmt) -{ - time_t t; - - t = time(NULL); - if (!strftime(buf, sizeof(buf), fmt, localtime(&t))) { - warn("strftime: Result string exceeds buffer size"); - return NULL; - } - - return buf; -} diff --git a/suckless/slstatus/components/datetime.o b/suckless/slstatus/components/datetime.o deleted file mode 100644 index 9181ae672c36be74ce6163f4d73ed4f323273efc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1960 zcmb_cO=}Zj5S~q2n`(_wDu}JJhbSrP(x^zOD3MsRLJ_Hoh=sUKHf?A=>h1>Hig+j< zLMim<(PRIFQa^ryC-LIZ3SPvU3U!{%JLz`WT*L>a@60n_*>~pc^U0|jF-;?ZMptRq z5|$|4yQ^n?HA@LPNIwsq{B_4%{hlnDYa^%9>@iz2skqtto!Qw&oZ0$nwt7>({)V`U z*?McXKAY<&+TJfJ>Yds8WWM;=OlG#s^(*lC4z||rrs5^@%#dH*>ublaen>ui?|M$z ztJLfXecE=LRZnN4QlHc9rJ`+@Tz$4#F58aoR#t4Hd@eVkr}K8*Yc%xCMdN}orZ0|< zDisX@d}flRk0pQW9>s{Z!1b^I&~=twzvlbp&NSL<4{0MEQCmCO7B@;@9rQVK$Eh;{D&i+));Me;CJ^ zh~iUS_;eRO(}lm(g{P9`*_g3WBx5Q!*0HJDC|Xr`h{sH_3iQNs>QpGWo>g2Z6z3NT zWvfyp^0$q9V1BrbKRa!VvJQaX$0Gb?kPMzb^|J_{1Ia)|s`LS6Ly{xvef~Q`rajM6NubV~RhmczMT)rq`l`&T#*;>_^Ri&BxxO=6RMN zq(ABhA^qjdvJ?7PFo^YU%GN`? -#include - -#include "../slstatus.h" -#include "../util.h" - -const char * -disk_free(const char *path) -{ - struct statvfs fs; - - if (statvfs(path, &fs) < 0) { - warn("statvfs '%s':", path); - return NULL; - } - - return fmt_human(fs.f_frsize * fs.f_bavail, 1024); -} - -const char * -disk_perc(const char *path) -{ - struct statvfs fs; - - if (statvfs(path, &fs) < 0) { - warn("statvfs '%s':", path); - return NULL; - } - - return bprintf("%d", (int)(100 * - (1 - ((double)fs.f_bavail / (double)fs.f_blocks)))); -} - -const char * -disk_total(const char *path) -{ - struct statvfs fs; - - if (statvfs(path, &fs) < 0) { - warn("statvfs '%s':", path); - return NULL; - } - - return fmt_human(fs.f_frsize * fs.f_blocks, 1024); -} - -const char * -disk_used(const char *path) -{ - struct statvfs fs; - - if (statvfs(path, &fs) < 0) { - warn("statvfs '%s':", path); - return NULL; - } - - return fmt_human(fs.f_frsize * (fs.f_blocks - fs.f_bfree), 1024); -} diff --git a/suckless/slstatus/components/disk.o b/suckless/slstatus/components/disk.o deleted file mode 100644 index edb3cfbdd6cfb41a0401c5a915dfe2cefb93ac49..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3168 zcmcJQO>7%Q6vyADO_M_FHKi3+8=*Zo)X=hu8<46Zz$hu%L#Ysjs$at0*y}oS{ULi( z927yMs8X#EDMv1#ic@b~IU$pBNI4*J>jlISK@Y9DwTSZmv-9v|>jEn3lV)e;H}7Ni z?VH(;j~;t-$g)VpqSvTD6H0V-v_H9*Io z=dFh6(O;l?xx26@+x0p>d8@Btu3)zN+a7OaF`e}6FBj99uW74Z@K)YUw~O9^-O5`y zthBx5TT5rJ|DRx&yp`#6#=G2YkMunI1w`+xFaKvbplk~`^6IE};4>mjOw zlH7*5%^ZJ^hKRagTev|mcDVJ|EwwH+Y*94d&N`6YQAgH??~v6_TKjg4jIOb=!+cDy zRnZ?!B$tP#6KmGcY$EwaVw91?EyoS=Jsy3X>!yyp>Oc9p0(+Jw9(_L-#1HTw!Fz3` zJNE~zZ5eQKvF|85n=Mq8(zeZzXS);`=99fyo>9|n6#46~A!oacxaysmJ;x2-EiNvD zL45Kd92dqQ{o~9LSK_Jf!R*vS^v`SkSCBv!v8(VHey(Y*z6TVFbFGS7AotkR1RhyD zCh<6=mhz=$5Rk5M`oM42s8kK}<@u^#qkNth3YC1JT*;UGxr>oSBWMxCt)+vVcFyP53Gx zOFZsp5q==<7n(!gjQgjdk2Uc>tn-WgT8%cn(8 z3$5@lxrKVQ$~Qc@wR#x1e2>4V4v3y#sLi{LW}VMRxWI<+9+dfj`PD%0?$JAkO_AF8 zO_yT^*=r_`=lV0KH9YolL+*3jOj$z_vt+dW4j#i6H2_IPow^6X<$t9yor%R29*=*J z7vS?z?XzqPpNF`aBJrOxA&(`#^f}F<|3Y86q4yuZo8|qbe@olT{Usijw7nxh_Yzn7 zlgwpos$Tt%`75!}2)DSp*uQN$<+1Er@JBpA{J8yX4X%lz?&J0g%m>xaSJ)KGdG#bh z{ove-z0}X3*f9B27sQfI4(>>}jN9XmiPsJzO6mHY$Hb6$u2CNY?RB6lhAoD1`@aCI CzXsF* diff --git a/suckless/slstatus/components/entropy.c b/suckless/slstatus/components/entropy.c deleted file mode 100644 index 65010b0..0000000 --- a/suckless/slstatus/components/entropy.c +++ /dev/null @@ -1,29 +0,0 @@ -/* See LICENSE file for copyright and license details. */ -#include "../slstatus.h" -#if defined(__linux__) - #include - #include - - #include "../util.h" - - #define ENTROPY_AVAIL "/proc/sys/kernel/random/entropy_avail" - - const char * - entropy(const char *unused) - { - uintmax_t num; - - if (pscanf(ENTROPY_AVAIL, "%ju", &num) != 1) - return NULL; - - return bprintf("%ju", num); - } -#elif defined(__OpenBSD__) | defined(__FreeBSD__) - const char * - entropy(const char *unused) - { - // https://www.unicode.org/charts/PDF/U2200.pdf - /* Unicode Character 'INFINITY' (U+221E) */ - return "\u221E"; - } -#endif diff --git a/suckless/slstatus/components/entropy.o b/suckless/slstatus/components/entropy.o deleted file mode 100644 index 85471743ed2bac674fd86d6737e4c5d250966806..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1824 zcmbuAPiqrF6u{r6sf`%ZC>4aN>>-uMTbYE>H@jcH(sK8W z(I32TCe7Y*#_WC$nb~`gNmR@Wb74R*J%pWi=|^uDo-`rb@Z56NZ~NID+jHz%*0Y?7 zThH1~;JJ-<(RyZW*8mFn{8fFifYfz$V_94gOL}AFoK&ecKpaOJ$25+@-3^EV^ojBI zNY`XwUC~)=F#h$(h6+I-f#DgT$i8YAW4{ZKU)VDmPLILX(8* z#Np>)(%RI7&KwCH>23E5?U8mt`%&ct8poA9;kzND1`cCXZ-C4J{Ne!|WKTpH#9Drd z9tJaL_+`tfLaE_xJ3$qSML)30JH_(WPO%zx5P%N``x5r#&tNFC^0kQ5o|p^Ci5*h- zO@+@Wd{g06i}UD`Q+^sF5q`TKSS1jC;0@<3);zmriNJ0JASza1fhhSt2+t*h+znxX zD7*DKo(TxY4Qzo|?ozmEX+L(F0xx&N_JTHsQbK#HSoN&BJ$i%xQgn=_J4I)sN=_Qw ze_kVBRp!y4v(2dx^*wn=Ey?K~QY`oHq~vEM=iisa@S2s#9Ia3HjB@^Kyn(Tl^D+)q zxc+$+qR#bs&Plcu@%tccJ;FJT=R3I0y6XB(H55JS`w-XY{_eYzX#bEg>vHCa&!6q5 zs8G&md`=cxVMjSf -#include - -#include "../slstatus.h" -#include "../util.h" - -const char * -hostname(const char *unused) -{ - if (gethostname(buf, sizeof(buf)) < 0) { - warn("gethostbyname:"); - return NULL; - } - - return buf; -} diff --git a/suckless/slstatus/components/hostname.o b/suckless/slstatus/components/hostname.o deleted file mode 100644 index 20e1d3388ed7e9eef8888b001cb532dc951dc55f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1680 zcmb_c&ubG=5S~q|tyt4l6be;YFa7|1WNQzlpe%%%2t`EkARcs+ZX2-KO?O{0(SwKL zA%{Z$2QU5=67)atqcWYKZ}aDW+^_GS1ND}siR%4NpW*c1)%zb`edyWlpuT?tOiH_hNAI@+ z-HH<3=!JeeSS6}etE%mLn{+I}fNtGyo^Zg6*)3 z*R6D2?qboTf0|-jyhy0*1AH#2*{!DpF+0L%DUE8BaeusjR$>JBbB$Pi5lMGcb3O1^3V63=>8Cg+K6w&ZF9w`rAeHENs9R#i!M3k- z(AA_ieC?BJBnhcFf`f2Zxulv=yUj0&R2b<%@l&~$XutW?_*>zw>cmkeh;@%sQ7~vd z-i&ec{{n}r;4PpxS$M{gdCD4Mvsh#Yz4Edo+Y6>iPYi#YHF9N6csIaB7Vz@F00-!y z`t3KrKjwv+|C;Y|E^02ZWFh;{XGykYf6<=dD!I5l<2yNC@NA(U-+WEu~o%f qbO48e?+^CL=c8tR_Ds -#include -#include -#include -#if defined(__OpenBSD__) - #include - #include -#elif defined(__FreeBSD__) - #include - #include -#endif - -#include "../slstatus.h" -#include "../util.h" - -static const char * -ip(const char *interface, unsigned short sa_family) -{ - struct ifaddrs *ifaddr, *ifa; - int s; - char host[NI_MAXHOST]; - - if (getifaddrs(&ifaddr) < 0) { - warn("getifaddrs:"); - return NULL; - } - - for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) { - if (!ifa->ifa_addr) - continue; - - s = getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in6), - host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST); - if (!strcmp(ifa->ifa_name, interface) && - (ifa->ifa_addr->sa_family == sa_family)) { - freeifaddrs(ifaddr); - if (s != 0) { - warn("getnameinfo: %s", gai_strerror(s)); - return NULL; - } - return bprintf("%s", host); - } - } - - freeifaddrs(ifaddr); - - return NULL; -} - -const char * -ipv4(const char *interface) -{ - return ip(interface, AF_INET); -} - -const char * -ipv6(const char *interface) -{ - return ip(interface, AF_INET6); -} diff --git a/suckless/slstatus/components/ip.o b/suckless/slstatus/components/ip.o deleted file mode 100644 index e1543a53e1737942f035906ea9696f7725382340..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2592 zcmbuAU1%It6vxkOvh7yWG1@{GQtW_{X2oHR^udQdNgsUBH=hJW%7P#0lRg%L;FDOQ6qSldaXtT;dpDC|_eBqT=brPs z=iGbeo-=nZ&gP$vDGEtZ=qcK@Bqh4KZ&%OyYL-+wNXCoCyy4w4PM`8_&%a<^`b8Ti zDw*vkCQ|HWdY_Lc8JJsdj3@G2?)Z_P5o@*=#uKg1`XO`cN!Xc=k9Qhod(3QYyBE#& zM$&9`-J5ftDjc5oexJ>J`>HaV>0CR?{$i4iMBe+!`^vXoI@9W`cFgunvV8Kf)aoZ@ zn^*KlTEDtSy_-Quu$<|AEmq8Qc8=w}KO@^1*$v+L!EC?hze34;@UZ_*ZakRl(wBJE zm(Lmt##!T)FaEge-oLNKcyl*y{L}6F)*Z06*;=yQO4%xvoaPjPjoa?H;*ZN* zDzw)=%)Sui_2)^sFsh7=>`z=~=Q(CLV#ommPphNv#-`Qe*3hh~y)%4LO}!O2)byMC za_aYq*fZ+&#Ix#;i3RQrfHgI3s3}9$ID|u|)kLuGhCd^5%>;t=HzQ1#eLHMrn11W_ z8yxCWu_)JAi2Lut?0`Q3PHC?M`-;=ZUQCC4JKj4JIh%eiaq12&Hk?Y$EmMJ!RXkTHE}tuut;z~7vo?vxqkJ{+ejupt{oHPM z12F(u@Wo+FaubjRj7zV_*8o|-Q3KL{6OaWQ->c;B1G0eM$xZT)09n9ME0TW<$b$W# zx+MP$kOltX{e0uoz#p|L{l60&{s%*RJH*5LxfSBbm7GTt9Q#3&;tEA_ng6#VT;`wj z=6cn&7P)twpkJ1nW3O1cYhQ3lFIlcd`eL(5x>JV%_l(X(Qmj|2e6f*UtGl+&SJ%US zvW2}=Th$v*yZqJ{rHmykGvWi@y+4#3BE&xlf@ b{?5Y)iI}cO?q;oDye2+~jh<(qMC1Pj- -#include - -#include "../slstatus.h" -#include "../util.h" - -const char * -kernel_release(const char *unused) -{ - struct utsname udata; - - if (uname(&udata) < 0) { - warn("uname:"); - return NULL; - } - - return bprintf("%s", udata.release); -} diff --git a/suckless/slstatus/components/kernel_release.o b/suckless/slstatus/components/kernel_release.o deleted file mode 100644 index 978d5f9747954092bdc31ed1362a7656f5801bc3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1872 zcmbu9L2DCH5P)aX##XJdmZCyM7HOqYeP*>tDOv(Svtp@55cCu_$;OlnSPd-OrZ$6$(e4*fH?bevp zwl}Ykqlwl2deq*0H~AC+bE~aq?2VT?yJXLd>*c~^hp&I2D(_c4r|!+hH1^Jiz;n4=gzQ6wO|l+6g7#OTe=MifHpDtIb@rtyYq&g$4XiZ==H~iKfDFT z+Nd!xGBmt}!6%TDlKAwwk$OFlD5r+W{)$|)ZaTDInNyXs(UJYmN~`KnF!A@r+AtZzQmju z^-OpZ=ya8&57g`i4K=zuB&0Vuyg4uxCF0#$6( z>v*9-d5zFjcxBJ&qhSA@x2l?cqv`r#3sY%9w~{aW_$0bJ_%Fl6Y`T+l#!<i{PKZqmc%KJFZ{4{fUpN!$H7_l*4|18ean*W+l_n+3hfEpF4 ze;^9cmijVgn5AQJ+w7Y$E_pIu$9b`%p`W5o#E!?_#W}j~J$DlQ&!{BJouT`c^A~U* z4O%mvpXNey63AmbAD?R9{?Bnkq|elUdQXxsykBi9RpI*I$w3)GrGLSAKCKz=JtDZn aKjPB{qc>W)8F1+;s diff --git a/suckless/slstatus/components/keyboard_indicators.c b/suckless/slstatus/components/keyboard_indicators.c deleted file mode 100644 index 5f62bb7..0000000 --- a/suckless/slstatus/components/keyboard_indicators.c +++ /dev/null @@ -1,50 +0,0 @@ -/* See LICENSE file for copyright and license details. */ -#include -#include -#include -#include - -#include "../slstatus.h" -#include "../util.h" - -/* - * fmt consists of uppercase or lowercase 'c' for caps lock and/or 'n' for num - * lock, each optionally followed by '?', in the order of indicators desired. - * If followed by '?', the letter with case preserved is included in the output - * if the corresponding indicator is on. Otherwise, the letter is always - * included, lowercase when off and uppercase when on. - */ -const char * -keyboard_indicators(const char *fmt) -{ - Display *dpy; - XKeyboardState state; - size_t fmtlen, i, n; - int togglecase, isset; - char key; - - if (!(dpy = XOpenDisplay(NULL))) { - warn("XOpenDisplay: Failed to open display"); - return NULL; - } - XGetKeyboardControl(dpy, &state); - XCloseDisplay(dpy); - - fmtlen = strnlen(fmt, 4); - for (i = n = 0; i < fmtlen; i++) { - key = tolower(fmt[i]); - if (key != 'c' && key != 'n') - continue; - - togglecase = (i + 1 >= fmtlen || fmt[i + 1] != '?'); - isset = (state.led_mask & (1 << (key == 'n'))); - - if (togglecase) - buf[n++] = isset ? toupper(key) : key; - else if (isset) - buf[n++] = fmt[i]; - } - - buf[n] = 0; - return buf; -} diff --git a/suckless/slstatus/components/keyboard_indicators.o b/suckless/slstatus/components/keyboard_indicators.o deleted file mode 100644 index 7df304bdbb875b6587dd0856d65cdc5e6dab0227..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2448 zcmbuAO>7%Q6vt;1yD`+=m=8fj3tA)>8MUlz2vS-F@Y-&&QC+BLQ_M$Lt?dntve{jB z$4U$bA|*jxjG-KmdgRItZaoD{rR2)72nmjW3PKe(+RD7Qo^dvdeSyF9Ja2yU-puTL z`GYg%xiLW?TmpHK?AJIYBz0)t&j)Uvh~x;zF^K9#z9A{Kl%jrX&+zHO-f%{P~nx0EI2ZAH6Y zdBriT(u(Jpdh4__r>~esU81&R1D5K2PRM+*cv{NL8y2-~DK{-YCub#R=4s~QkSJV` z6j&T={^dmipU_1%4u(Qs0^4sFf_A>Q0y$WJ7-CVvd#@5$@J{>EFQ=g0%M5z-ih?$S$ikSWIkRr}(O_anhgz=;x&XmNgB4!{2LJMN5ASPHR zBMR&~MsD|pHIENDk&gy}_;m+`bA2!rAIuq877W)bDm;tBcwq#;G=je|f;UERX9V9K z!LN?sWYuU@ZQZSFD^`7_rc>MX~+FT}; zqG@{uJFdi|u4Nh)(X<+EIfh1U(_S}R&9rMF)^wZ!^Qc~1)oP7ZZ5d8FOh3?5tiZb!$9WYY2;=Vq1RKHX?^sRQapA#nX$w-Z zL!+TByZV|jn8E*YB*?~34*gvO{pEvS_J%MY3${E1auhsVtNeiU9S0#O!4hy!(B;p{ z6gGnJd?DxWATpF09jK50HU3H9*yn%E&p|E@^( -#include -#include -#include -#include - -#include "../slstatus.h" -#include "../util.h" - -static int -valid_layout_or_variant(char *sym) -{ - size_t i; - /* invalid symbols from xkb rules config */ - static const char *invalid[] = { "evdev", "inet", "pc", "base" }; - - for (i = 0; i < LEN(invalid); i++) - if (!strncmp(sym, invalid[i], strlen(invalid[i]))) - return 0; - - return 1; -} - -static char * -get_layout(char *syms, int grp_num) -{ - char *tok, *layout; - int grp; - - layout = NULL; - tok = strtok(syms, "+:"); - for (grp = 0; tok && grp <= grp_num; tok = strtok(NULL, "+:")) { - if (!valid_layout_or_variant(tok)) { - continue; - } else if (strlen(tok) == 1 && isdigit(tok[0])) { - /* ignore :2, :3, :4 (additional layout groups) */ - continue; - } - layout = tok; - grp++; - } - - return layout; -} - -const char * -keymap(const char *unused) -{ - Display *dpy; - XkbDescRec *desc; - XkbStateRec state; - char *symbols; - const char *layout; - - layout = NULL; - - if (!(dpy = XOpenDisplay(NULL))) { - warn("XOpenDisplay: Failed to open display"); - return NULL; - } - if (!(desc = XkbAllocKeyboard())) { - warn("XkbAllocKeyboard: Failed to allocate keyboard"); - goto end; - } - if (XkbGetNames(dpy, XkbSymbolsNameMask, desc)) { - warn("XkbGetNames: Failed to retrieve key symbols"); - goto end; - } - if (XkbGetState(dpy, XkbUseCoreKbd, &state)) { - warn("XkbGetState: Failed to retrieve keyboard state"); - goto end; - } - if (!(symbols = XGetAtomName(dpy, desc->names->symbols))) { - warn("XGetAtomName: Failed to get atom name"); - goto end; - } - layout = bprintf("%s", get_layout(symbols, state.group)); - XFree(symbols); -end: - XkbFreeKeyboard(desc, XkbSymbolsNameMask, 1); - if (XCloseDisplay(dpy)) - warn("XCloseDisplay: Failed to close display"); - - return layout; -} diff --git a/suckless/slstatus/components/keymap.o b/suckless/slstatus/components/keymap.o deleted file mode 100644 index 5a582c4ab8e61bf2f3727feb5cc3951a8c6df5bf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4048 zcmb`Ke`p*<6vyY9q=_}%#HQ8QXj$|UBDKq1f7olOC7WE6i5|6>MuS?( z+r&hI6=H?uOcj5DfBKJq`Qwj*f?$YE3l$WLh=N56{$ooDRm6%S#P@dRC3D+b1o6S_ z%zozk-ptO-zS}!_DAm6%5@BQ!c95;z5oPS+t!wQbui3*|SquBEW!qo+Rp?*6dcUcGS3%lgXsLHEbyH#w|LBFDGad%NW{ z_}+8pICrl+c}#ywKc+verPOm#wZqI$q|4jTotEDLSZvB%9RPpFn>3K=V37TO^P0)%P35!EtE z*a!sH9jk!BW&Lr}Q4Qc~5jxoR{j3v0_vNj!S>w^N$XB1uoXVL~Y`kbXtdwOLqio{- z|Cs8eG`d+2`=?NNGCkaKpP4J-rzgO^+0p2b62LZlA@NWWqr{LcO_+G)k z5AXwUze!pjZ;ycWLBaD8v?Bm&@!=3Y8p7=m{(K0pgz(ow_}d};oe=(E2>&>Qe;UHS z4B?kTID@2AFiKh$UhpX+Kc3TKOiT57mpHa|;$;_JcH?CaULL^9Ug65*1j(K??BY$? zP)>MqLaWMFtnAp1HGx&$EMis67D_Cg&N?$CGo4987G;@|JzjK1*+{=_Lb994U` zNUH5!&*i)4>N49pp#46VSk|4sI9uA0eTrY5s&=Xkg5s{{=Dr7zsrk^nVd}t@TsI z|5rL^c>WNPKk-^)<4`dS3P$Hwfi{+)KmPXATq<$?uR*_T!S%!6(pvrrG5^ -#include - -#include "../slstatus.h" -#include "../util.h" - -const char * -load_avg(const char *unused) -{ - double avgs[3]; - - if (getloadavg(avgs, 3) < 0) { - warn("getloadavg: Failed to obtain load average"); - return NULL; - } - - return bprintf("%.2f %.2f %.2f", avgs[0], avgs[1], avgs[2]); -} diff --git a/suckless/slstatus/components/load_avg.o b/suckless/slstatus/components/load_avg.o deleted file mode 100644 index 735d51d79cd8a483e2d24a00ea5145a8144eac63..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1904 zcmbu9UuzRV5Wwg9$5vX~Sc()Xb{|rS|JGa;)S?n7wkH%3si04BlU&l!Bo{AhZBy_xy#%-r72?!CUVyx3=1z+%B|=z2^6 z_WQebE--U21}EUx_?h3%*7wXunlCv!H)k_wINPt%Q_l9+Zxs2qy*XjGop-m$35ea^ zoB27OT1ltyxttz0bMO1n9Y_Zu&dy4Ds^nal4C?8@5N>_We5$y*=Bbieugr@@Rjs)t zp*`Uhw5m1)%?P#b`l{l>teh*0&I4d+VPRfmmfVK+JYipzS7cT+ub(p}tqx!SM+(Ov zj-`7Kp%0)Q%OUx2B|aH#EqS(h6ju)dJ~zB&aiAOZqN84#yOAmU7Tk- z8ak2$6Jj4Dqx0T#Cecrs{QGD}h4-J?Q#2?vp8v$;$G -#include - -#include "../slstatus.h" -#include "../util.h" - -#if defined(__linux__) - #include - - #define NET_RX_BYTES "/sys/class/net/%s/statistics/rx_bytes" - #define NET_TX_BYTES "/sys/class/net/%s/statistics/tx_bytes" - - const char * - netspeed_rx(const char *interface) - { - uintmax_t oldrxbytes; - static uintmax_t rxbytes; - extern const unsigned int interval; - char path[PATH_MAX]; - - oldrxbytes = rxbytes; - - if (esnprintf(path, sizeof(path), NET_RX_BYTES, interface) < 0) - return NULL; - if (pscanf(path, "%ju", &rxbytes) != 1) - return NULL; - if (oldrxbytes == 0) - return NULL; - - return fmt_human((rxbytes - oldrxbytes) * 1000 / interval, - 1024); - } - - const char * - netspeed_tx(const char *interface) - { - uintmax_t oldtxbytes; - static uintmax_t txbytes; - extern const unsigned int interval; - char path[PATH_MAX]; - - oldtxbytes = txbytes; - - if (esnprintf(path, sizeof(path), NET_TX_BYTES, interface) < 0) - return NULL; - if (pscanf(path, "%ju", &txbytes) != 1) - return NULL; - if (oldtxbytes == 0) - return NULL; - - return fmt_human((txbytes - oldtxbytes) * 1000 / interval, - 1024); - } -#elif defined(__OpenBSD__) | defined(__FreeBSD__) - #include - #include - #include - #include - #include - - const char * - netspeed_rx(const char *interface) - { - struct ifaddrs *ifal, *ifa; - struct if_data *ifd; - uintmax_t oldrxbytes; - static uintmax_t rxbytes; - extern const unsigned int interval; - int if_ok = 0; - - oldrxbytes = rxbytes; - - if (getifaddrs(&ifal) < 0) { - warn("getifaddrs failed"); - return NULL; - } - rxbytes = 0; - for (ifa = ifal; ifa; ifa = ifa->ifa_next) - if (!strcmp(ifa->ifa_name, interface) && - (ifd = (struct if_data *)ifa->ifa_data)) - rxbytes += ifd->ifi_ibytes, if_ok = 1; - - freeifaddrs(ifal); - if (!if_ok) { - warn("reading 'if_data' failed"); - return NULL; - } - if (oldrxbytes == 0) - return NULL; - - return fmt_human((rxbytes - oldrxbytes) * 1000 / interval, - 1024); - } - - const char * - netspeed_tx(const char *interface) - { - struct ifaddrs *ifal, *ifa; - struct if_data *ifd; - uintmax_t oldtxbytes; - static uintmax_t txbytes; - extern const unsigned int interval; - int if_ok = 0; - - oldtxbytes = txbytes; - - if (getifaddrs(&ifal) < 0) { - warn("getifaddrs failed"); - return NULL; - } - txbytes = 0; - for (ifa = ifal; ifa; ifa = ifa->ifa_next) - if (!strcmp(ifa->ifa_name, interface) && - (ifd = (struct if_data *)ifa->ifa_data)) - txbytes += ifd->ifi_obytes, if_ok = 1; - - freeifaddrs(ifal); - if (!if_ok) { - warn("reading 'if_data' failed"); - return NULL; - } - if (oldtxbytes == 0) - return NULL; - - return fmt_human((txbytes - oldtxbytes) * 1000 / interval, - 1024); - } -#endif diff --git a/suckless/slstatus/components/netspeeds.o b/suckless/slstatus/components/netspeeds.o deleted file mode 100644 index 4afd7aee5a652e07ed8d0ff06409a0ddbdad47d9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2824 zcmdT`--{eY5U#nqn2lb>jU>1sDkI#5i_zKLs1QWL9!GK$IYpER8p397Z`NJ2zntll zT}8bRBOc3v4?c+hfUn{o5C#*X4GGJ@b&K6iiq3S6@|E zPuDc_`SGO_6OKb74jrS>Oi-e)c8=_dHY?=PZu%ZuX!SEZs)=F@AuU=g3*uu~M zT;LK;pZV!wufLcKl47kDCP}dqsp4!>OjM|viE7r8V%)DT4^))U><6p#zf2`eT3lFo z#hY7}57^SwHX z$ocp!a{77a!1T`C*Gzt%@u!S0g+A`)znqwN3l}CA-EX~>azlSJ0XcNW)c9XzjdRP&2?oaDuWy6DvkiWB8~j7YQBTSmlIoEM?$)FiMJtJ4 zqqwiz)Gw1VR*C$j1wE8u9r=%5jr$ZOonGARs5c*rIw{RU51AutU`< ze+RX5)mr0RwH`KGqXept684)qxPR#pe*W3ql35E!Ps>RK2FLtSeuV$7!I8)2pS5sY zox*Pz9C;qIa9tG7vw1!Tt?|071WAFE<#kbczX5sdJ-?Q@A`;9H!-mhov3$=>8X$)X^QZpw%8MIZn z%v!};x*=8^wL)J-eMSCCs6z6WlZ5=ZiwWpuZd||CZMXT-B)`*DkV+~3H#U3~VAlJ#Y+G8@QwL;#~@eK~h=%le`#?0{Vo zg3)=?JYEKuIMFBBFSboBnRpw6o#o;l!FQ9TOMJHe?EZ1jB4;*!%>Z)0Fhxr?zQyRc z^S^8wO5O|3e-}RzFXumQZ7g)#tiNV9jBk2eJh1H9Bff9??^8@H$-cim>>C%KGykoh KSg|m(@&5w1xupvL diff --git a/suckless/slstatus/components/num_files.c b/suckless/slstatus/components/num_files.c deleted file mode 100644 index df0acd1..0000000 --- a/suckless/slstatus/components/num_files.c +++ /dev/null @@ -1,32 +0,0 @@ -/* See LICENSE file for copyright and license details. */ -#include -#include -#include - -#include "../slstatus.h" -#include "../util.h" - -const char * -num_files(const char *path) -{ - struct dirent *dp; - DIR *dir; - int num; - - if (!(dir = opendir(path))) { - warn("opendir '%s':", path); - return NULL; - } - - num = 0; - while ((dp = readdir(dir))) { - if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, "..")) - continue; /* skip self and parent */ - - num++; - } - - closedir(dir); - - return bprintf("%d", num); -} diff --git a/suckless/slstatus/components/num_files.o b/suckless/slstatus/components/num_files.o deleted file mode 100644 index a3471434210ba7e7f6702cc34ff0a9f47ab0f1cd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2192 zcmbu9-Afcv6u{4{Zf<@|n?`LIF+G$k=4D3!AlR z*l5AW{+xvf{1bYJ>LH>CjOZmQuybbaU9ZFLOC7j#&iS2>J99tg=~#L^peP_jf$MPK z2?`Jn9@uf$jDreY@Z;FoUy0dtb&y!%)|mcrcE+guzWteeqw?C=t~ql?<(ucDGhkHb zdeW6Wqw?Nmh&~wA%U-&Nwtgy!t+)GMcSYTNs`6>Us9vL_MZK1|n^^qf6};1HoV(5L z=(UAK3co6rtU`9p*80wu`$m8PV{kqTFp*4-XweC);1r9Reu)jUm{z*d&rR&viX)7J zK6hej76Je@Vl6mG$kuQi#1%I#)=YuJ{t3(_Q65i&vJqB#JKI7#n4Cs-#*F~HBt5Q% ztAR;1@}ecBYR_5|YIG}@Qe%Osb~TE`P$MZdJgSDqI;PcVQq>Y_WYh(`NfSly)e7JD z8--gM>~xo#7{t9jEZv;b+Q@Rsb%M|%L$tkblMW4!pF`a(&Fg+UvH=|a-c&N&gkNpK zN1N~)P54X`4u$pn(#l%SDzgl*bW*3s5Iu(J5j%(jKWboGW)_belpQ;hFF__(EL-F+ zm+ZBIvjUGyy8uUVJ`y}v?wR_t@5yPGdgm*Iw&48|r&__?yMR8O$99PuXp>NXii!N2 z1X29?riWeLfwsucb54C|7X{yz_z{Ue=bZY}84~%M67Q6_#yRz;Q5RO;%sb{XFkD7Y zuL{eyawc=E4F_1(bWC8&EIVfA0r&40)>+BM z9kZQHETx9l>e7mB=B@f0{Fk9&HQhN{8(HGq5$9dRC|8zVbZ8CZGDN$?e?TE#Kzl_d zofVRZr{Dr=;^KeBF}x9mPy6S;h;i!quk||CQqLhAvWWRl$`EZaztC~cV!pgR?rT0S z>V%%exUl6^wGnKPJCCdl$DuQcewf#bdxXdpvHrq;hz6zl>+kXURguWGzdnb&(f)4` zL=pQ;`%nJ^Q7?F-xv6efyg%1;7wJ3w_0-e9_lO|E;T$=V@OE`_9IZz6JN*5h)H6N9 GU;h_5xCyKP diff --git a/suckless/slstatus/components/pixVol.sh b/suckless/slstatus/components/pixVol.sh deleted file mode 100644 index 8f59505..0000000 --- a/suckless/slstatus/components/pixVol.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash - -volume=$(pactl get-sink-volume @DEFAULT_SINK@ | grep -Po '\d+%' | head -n 1 | tr -d '%') -muted=$(pactl get-sink-mute @DEFAULT_SINK@ | awk '{print $2}') - -if [ "$muted" = "yes" ]; then - echo "Muted" -else - echo "${volume}" -fi diff --git a/suckless/slstatus/components/ram.c b/suckless/slstatus/components/ram.c deleted file mode 100644 index 15c4b74..0000000 --- a/suckless/slstatus/components/ram.c +++ /dev/null @@ -1,212 +0,0 @@ -/* See LICENSE file for copyright and license details. */ -#include - -#include "../slstatus.h" -#include "../util.h" - -#if defined(__linux__) - #include - - const char * - ram_free(const char *unused) - { - uintmax_t free; - - if (pscanf("/proc/meminfo", - "MemTotal: %ju kB\n" - "MemFree: %ju kB\n" - "MemAvailable: %ju kB\n", - &free, &free, &free) != 3) - return NULL; - - return fmt_human(free * 1024, 1024); - } - - const char * - ram_perc(const char *unused) - { - uintmax_t total, free, buffers, cached; - int percent; - - if (pscanf("/proc/meminfo", - "MemTotal: %ju kB\n" - "MemFree: %ju kB\n" - "MemAvailable: %ju kB\n" - "Buffers: %ju kB\n" - "Cached: %ju kB\n", - &total, &free, &buffers, &buffers, &cached) != 5) - return NULL; - - if (total == 0) - return NULL; - - percent = 100 * ((total - free) - (buffers + cached)) / total; - return bprintf("%d", percent); - } - - const char * - ram_total(const char *unused) - { - uintmax_t total; - - if (pscanf("/proc/meminfo", "MemTotal: %ju kB\n", &total) - != 1) - return NULL; - - return fmt_human(total * 1024, 1024); - } - - const char * - ram_used(const char *unused) - { - uintmax_t total, free, buffers, cached, used; - - if (pscanf("/proc/meminfo", - "MemTotal: %ju kB\n" - "MemFree: %ju kB\n" - "MemAvailable: %ju kB\n" - "Buffers: %ju kB\n" - "Cached: %ju kB\n", - &total, &free, &buffers, &buffers, &cached) != 5) - return NULL; - - used = (total - free - buffers - cached); - return fmt_human(used * 1024, 1024); - } -#elif defined(__OpenBSD__) - #include - #include - #include - #include - - #define LOG1024 10 - #define pagetok(size, pageshift) (size_t)(size << (pageshift - LOG1024)) - - inline int - load_uvmexp(struct uvmexp *uvmexp) - { - int uvmexp_mib[] = {CTL_VM, VM_UVMEXP}; - size_t size; - - size = sizeof(*uvmexp); - - if (sysctl(uvmexp_mib, 2, uvmexp, &size, NULL, 0) >= 0) - return 1; - - return 0; - } - - const char * - ram_free(const char *unused) - { - struct uvmexp uvmexp; - int free_pages; - - if (!load_uvmexp(&uvmexp)) - return NULL; - - free_pages = uvmexp.npages - uvmexp.active; - return fmt_human(pagetok(free_pages, uvmexp.pageshift) * - 1024, 1024); - } - - const char * - ram_perc(const char *unused) - { - struct uvmexp uvmexp; - int percent; - - if (!load_uvmexp(&uvmexp)) - return NULL; - - percent = uvmexp.active * 100 / uvmexp.npages; - return bprintf("%d", percent); - } - - const char * - ram_total(const char *unused) - { - struct uvmexp uvmexp; - - if (!load_uvmexp(&uvmexp)) - return NULL; - - return fmt_human(pagetok(uvmexp.npages, - uvmexp.pageshift) * 1024, 1024); - } - - const char * - ram_used(const char *unused) - { - struct uvmexp uvmexp; - - if (!load_uvmexp(&uvmexp)) - return NULL; - - return fmt_human(pagetok(uvmexp.active, - uvmexp.pageshift) * 1024, 1024); - } -#elif defined(__FreeBSD__) - #include - #include - #include - #include - - const char * - ram_free(const char *unused) { - struct vmtotal vm_stats; - int mib[] = {CTL_VM, VM_TOTAL}; - size_t len; - - len = sizeof(struct vmtotal); - if (sysctl(mib, 2, &vm_stats, &len, NULL, 0) < 0 - || !len) - return NULL; - - return fmt_human(vm_stats.t_free * getpagesize(), 1024); - } - - const char * - ram_total(const char *unused) { - unsigned int npages; - size_t len; - - len = sizeof(npages); - if (sysctlbyname("vm.stats.vm.v_page_count", - &npages, &len, NULL, 0) < 0 || !len) - return NULL; - - return fmt_human(npages * getpagesize(), 1024); - } - - const char * - ram_perc(const char *unused) { - unsigned int npages; - unsigned int active; - size_t len; - - len = sizeof(npages); - if (sysctlbyname("vm.stats.vm.v_page_count", - &npages, &len, NULL, 0) < 0 || !len) - return NULL; - - if (sysctlbyname("vm.stats.vm.v_active_count", - &active, &len, NULL, 0) < 0 || !len) - return NULL; - - return bprintf("%d", active * 100 / npages); - } - - const char * - ram_used(const char *unused) { - unsigned int active; - size_t len; - - len = sizeof(active); - if (sysctlbyname("vm.stats.vm.v_active_count", - &active, &len, NULL, 0) < 0 || !len) - return NULL; - - return fmt_human(active * getpagesize(), 1024); - } -#endif diff --git a/suckless/slstatus/components/ram.o b/suckless/slstatus/components/ram.o deleted file mode 100644 index 7e34de69a595ab71fb46fd75c1cbac400e367a0b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3128 zcmchYO>7%Q6vxL-Lfp_A6GbSf2<^c^jsn|kn+g*Fa+@}ps4j}CAgDk%YkQ4@y|%H} zRSQKRMI0r zGrRlt>Fjbe5)mvB@vIokmdiU#K zPIkVMbMT`s;e3n1(vKl4y`ud6cIOMHx4XO4klm$ucmG}n6{mA;=bQG_{-^&XN~QXr zDlj9vm#G3>dh-4ejL_rD*)QeXWqN+|Jcd8Hvx(jb^=Y#P|HoTB$DXEy&4sspK_VyP1~ULfI?sPQ^@de_$b2mX;Q+)QVRN z>UGOmu#egERwF&DRoqJmT}F|hHb!mbx#vYxh#uGoH3)Qz+F(7R*7==@h`sYEvV}z6 zI42?(6OqFQ$75H>82k~nBE%*}8MmSv@t8&G0_G$ipp)@TH7=LqYiHu}L_8CHAs&P8 zi&!HmqJ!^CecuM=B=4aM`>w=ez{3Rl9~HNEhOLbZ`67%fLsVg}98}XW@#J1C9@PAF zh(DzH`yqZ1jw<{P9#z>$l207!zoxFyWr1SA1B^M0u4{=C;Uhy8ujIL=MO{*b}{Hn_Q; zNqr88gS*Rd9yYkSA4hXAvkt2UH|vl$xS98Y5#OxCTLw4teq_Wk^L}q|Gw&^fn|UqT zHw4d%#*)?w^G!X+J%%vn`)r;g*7!aPyLHJA+&qmzvp<$uYkF1J4!nzju#0Zs3OnCw z3AXekzru!k4EtA!4?F+w`aedoq5W|Fc#qki&wp5M txZKkD-_gav{}jGqf5gQ`o(>f7 -#include - -#include "../slstatus.h" -#include "../util.h" - -const char * -run_command(const char *cmd) -{ - char *p; - FILE *fp; - - if (!(fp = popen(cmd, "r"))) { - warn("popen '%s':", cmd); - return NULL; - } - - p = fgets(buf, sizeof(buf) - 1, fp); - if (pclose(fp) < 0) { - warn("pclose '%s':", cmd); - return NULL; - } - if (!p) - return NULL; - - if ((p = strrchr(buf, '\n'))) - p[0] = '\0'; - - return buf[0] ? buf : NULL; -} diff --git a/suckless/slstatus/components/run_command.o b/suckless/slstatus/components/run_command.o deleted file mode 100644 index 2a88b6578813a617ae6845eb38005800313bf591..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2144 zcmbu9TWb?h5XWbe##XJ{C{-ervM<_N?2@z}Y!y)` z6#@o)^_%!qg17I`7xBRd!G|gef)(ogH|HdqGzHN=oSd28nVGZamM0gI;{in>DTU5b z&6AYqV@u7BduE(eIzZn$x_=qdiPC8>LwEb7E?m0z_pn{%%jOHEy+W#T%D17cq53iE499Fv8Tiaf6@DTH3V(caQ zaWz~DOsbLRK||G^wHRveYUsQg4LnwR85nA0R1J@+Z6akyhxuFR+xCtD2EisL+u;Rz zJ6D%d`Q8xLU8kd-7vi(8S2w$deD%GxFze%neQZ>eK{Jm1XvRl&;l?g}d>2l3Av>GO zWin=VUQdyp9E;*7hMxidVCDMITw#G07A@BiSBM^%c9tC1wo_@F=h({)!am_{{NAqU z2p|jhq?McG8ru-!F(&ybKo&R-SMqa!EW~0i$u9!3!0{|3zX8ZX9h|D3Y z0gwgW&Q0=FK$iTTEwQdr1y{L@*L)l~Rq4)3#x>_i=RK?RX=&NklBv7avP=5B>6)a^ zIS%P|4i3U&Iv)$piXSTJ*_>}a#zHxrs zE7bhg{21q=<^VUpjnFS-Ac-Dd-#jrr-n%wOW%X6K&(WXW^J`Qv@d`6X{QH}YPI`G-Z1w~IU4 kn2(x`XU~YfiUm!<@kx}cl7nnD%fBnW|4}uvVl?Le0has%eE -#include -#include -#include - -#include "../slstatus.h" -#include "../util.h" - -#if defined(__linux__) - static int - get_swap_info(long *s_total, long *s_free, long *s_cached) - { - FILE *fp; - struct { - const char *name; - const size_t len; - long *var; - } ent[] = { - { "SwapTotal", sizeof("SwapTotal") - 1, s_total }, - { "SwapFree", sizeof("SwapFree") - 1, s_free }, - { "SwapCached", sizeof("SwapCached") - 1, s_cached }, - }; - size_t line_len = 0, i, left; - char *line = NULL; - - /* get number of fields we want to extract */ - for (i = 0, left = 0; i < LEN(ent); i++) - if (ent[i].var) - left++; - - if (!(fp = fopen("/proc/meminfo", "r"))) { - warn("fopen '/proc/meminfo':"); - return 1; - } - - /* read file line by line and extract field information */ - while (left > 0 && getline(&line, &line_len, fp) >= 0) { - for (i = 0; i < LEN(ent); i++) { - if (ent[i].var && - !strncmp(line, ent[i].name, ent[i].len)) { - sscanf(line + ent[i].len + 1, - "%ld kB\n", ent[i].var); - left--; - break; - } - } - } - free(line); - if (ferror(fp)) { - warn("getline '/proc/meminfo':"); - return 1; - } - - fclose(fp); - return 0; - } - - const char * - swap_free(const char *unused) - { - long free; - - if (get_swap_info(NULL, &free, NULL)) - return NULL; - - return fmt_human(free * 1024, 1024); - } - - const char * - swap_perc(const char *unused) - { - long total, free, cached; - - if (get_swap_info(&total, &free, &cached) || total == 0) - return NULL; - - return bprintf("%d", 100 * (total - free - cached) / total); - } - - const char * - swap_total(const char *unused) - { - long total; - - if (get_swap_info(&total, NULL, NULL)) - return NULL; - - return fmt_human(total * 1024, 1024); - } - - const char * - swap_used(const char *unused) - { - long total, free, cached; - - if (get_swap_info(&total, &free, &cached)) - return NULL; - - return fmt_human((total - free - cached) * 1024, 1024); - } -#elif defined(__OpenBSD__) - #include - #include - #include - #include - - static int - getstats(int *total, int *used) - { - struct swapent *sep, *fsep; - int rnswap, nswap, i; - - if ((nswap = swapctl(SWAP_NSWAP, 0, 0)) < 1) { - warn("swaptctl 'SWAP_NSWAP':"); - return 1; - } - if (!(fsep = sep = calloc(nswap, sizeof(*sep)))) { - warn("calloc 'nswap':"); - return 1; - } - if ((rnswap = swapctl(SWAP_STATS, (void *)sep, nswap)) < 0) { - warn("swapctl 'SWAP_STATA':"); - return 1; - } - if (nswap != rnswap) { - warn("getstats: SWAP_STATS != SWAP_NSWAP"); - return 1; - } - - *total = 0; - *used = 0; - - for (i = 0; i < rnswap; i++) { - *total += sep->se_nblks >> 1; - *used += sep->se_inuse >> 1; - } - - free(fsep); - - return 0; - } - - const char * - swap_free(const char *unused) - { - int total, used; - - if (getstats(&total, &used)) - return NULL; - - return fmt_human((total - used) * 1024, 1024); - } - - const char * - swap_perc(const char *unused) - { - int total, used; - - if (getstats(&total, &used)) - return NULL; - - if (total == 0) - return NULL; - - return bprintf("%d", 100 * used / total); - } - - const char * - swap_total(const char *unused) - { - int total, used; - - if (getstats(&total, &used)) - return NULL; - - return fmt_human(total * 1024, 1024); - } - - const char * - swap_used(const char *unused) - { - int total, used; - - if (getstats(&total, &used)) - return NULL; - - return fmt_human(used * 1024, 1024); - } -#elif defined(__FreeBSD__) - #include - #include - #include - #include - #include - - static int getswapinfo(struct kvm_swap *swap_info, size_t size) - { - kvm_t *kd; - - kd = kvm_openfiles(NULL, "/dev/null", NULL, 0, NULL); - if (kd == NULL) { - warn("kvm_openfiles '/dev/null':"); - return 0; - } - - if (kvm_getswapinfo(kd, swap_info, size, 0 /* Unused flags */) < 0) { - warn("kvm_getswapinfo:"); - kvm_close(kd); - return 0; - } - - kvm_close(kd); - return 1; - } - - const char * - swap_free(const char *unused) - { - struct kvm_swap swap_info[1]; - long used, total; - - if (!getswapinfo(swap_info, 1)) - return NULL; - - total = swap_info[0].ksw_total; - used = swap_info[0].ksw_used; - - return fmt_human((total - used) * getpagesize(), 1024); - } - - const char * - swap_perc(const char *unused) - { - struct kvm_swap swap_info[1]; - long used, total; - - if (!getswapinfo(swap_info, 1)) - return NULL; - - total = swap_info[0].ksw_total; - used = swap_info[0].ksw_used; - - return bprintf("%d", used * 100 / total); - } - - const char * - swap_total(const char *unused) - { - struct kvm_swap swap_info[1]; - long total; - - if (!getswapinfo(swap_info, 1)) - return NULL; - - total = swap_info[0].ksw_total; - - return fmt_human(total * getpagesize(), 1024); - } - - const char * - swap_used(const char *unused) - { - struct kvm_swap swap_info[1]; - long used; - - if (!getswapinfo(swap_info, 1)) - return NULL; - - used = swap_info[0].ksw_used; - - return fmt_human(used * getpagesize(), 1024); - } -#endif diff --git a/suckless/slstatus/components/swap.o b/suckless/slstatus/components/swap.o deleted file mode 100644 index dfdca6c4c01bdff827e5ebef17c58fb7c32e4ffc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3928 zcmb`JeTW-H6u>9<(WYN}v9=m%Eh}u>Xmy*kSG_B3N$#%goaCg~ySAb=-6osnynHp; z&}%(WNTV!iR0Qz@1r`4gq)<`t51~X`Yt=u5`>W7@1i?E!r4>c7XybdcGncs~0YM+^ z%$wi7_vUNo%|5+5x~IeAAwoQ47iqQxCFIJorXFT$m?&fgi5!d^h>S%>$M%P=((+G} z30m!19{>Yt4{0e{>qc8@PiaAFTNt|>`E`+6-$FS-_H)+Y&7i8LiNgYX(g@h(9V-CnCz!BOPhm(9#%1@W)FT5H2@KvmpCIo zt&QR~u-G%RvwzRW4$|s!jaI(2Hd6aC-82N9L*b(n^#os8`WpS?PikKZ)#rQmx9B+_ zddB(u4!!T-^O?f=%*43 zCQ}BDc*;zW0@<7|t%W@bE_%#ma+Z)Vkv3*g4>WPLiJP7Ew1$4o0do;6z-Bna6% zIJjL6>@~AiE~kci^{skP&G+5SRf4-reDL78-22cN=^&(ztP>s-)Kz$z?>+3j$O#^@ zu)PXwQ9P#}CZ0*3XU+1(-WS1`0$a=85b`=Y4=BDDItCQ~^PK~VTI(860%y7-O7Pi5 z5v8xZc#m?<)A^J~=^Ipn5hVa7U_E3Sck;f+=1Q30pCt~r`L@a5HrwJQC z60=w`W5rUXjFEL%-Ymq)(R^V%Yb70Gv8=}&N=3+Zcd^;x8F6yWUvSHz9F#bo62apV zUnFr$;)^BzoW$`gia2j_j`?kc#NXu{$AkYR!u~7H(O!}Gw8VQP{vGES2hXyIvxI*S z7ze)t!M92L7KuN|ImW?XE@3|=*{_s%QsS5^gneG(m?s6VNPM-#rzL*7#AhTf+wa5y zf?%~A9uYsvInMVEi5n7^V_oU0F6Q1{oe}= zW4g`%t$&Ee+yb>M!hc+bpo{)R9p)_PvipV)NOf`HCu+PWg)W<3b5DrBblW}x9P^_1 z97T-l+<%_{ycX*(@NrNurrSS^n+kH-spdPUR(+$3 u7cU2pxA?#?_h3GE`(w;jOZ6Tu3W$6B?)Af*+{*tD4jAM~r - -#include "../slstatus.h" -#include "../util.h" - - -#if defined(__linux__) - #include - - const char * - temp(const char *file) - { - uintmax_t temp; - - if (pscanf(file, "%ju", &temp) != 1) - return NULL; - - return bprintf("%ju", temp / 1000); - } -#elif defined(__OpenBSD__) - #include - #include /* before for struct timeval */ - #include - #include - - const char * - temp(const char *unused) - { - int mib[5]; - size_t size; - struct sensor temp; - - mib[0] = CTL_HW; - mib[1] = HW_SENSORS; - mib[2] = 0; /* cpu0 */ - mib[3] = SENSOR_TEMP; - mib[4] = 0; /* temp0 */ - - size = sizeof(temp); - - if (sysctl(mib, 5, &temp, &size, NULL, 0) < 0) { - warn("sysctl 'SENSOR_TEMP':"); - return NULL; - } - - /* kelvin to celsius */ - return bprintf("%d", (int)((float)(temp.value-273150000) / 1E6)); - } -#elif defined(__FreeBSD__) - #include - #include - #include - - #define ACPI_TEMP "hw.acpi.thermal.%s.temperature" - - const char * - temp(const char *zone) - { - char buf[256]; - int temp; - size_t len; - - len = sizeof(temp); - snprintf(buf, sizeof(buf), ACPI_TEMP, zone); - if (sysctlbyname(buf, &temp, &len, NULL, 0) < 0 - || !len) - return NULL; - - /* kelvin to decimal celcius */ - return bprintf("%d.%d", (temp - 2731) / 10, abs((temp - 2731) % 10)); - } -#endif diff --git a/suckless/slstatus/components/temperature.o b/suckless/slstatus/components/temperature.o deleted file mode 100644 index 5663e46b58219426a8512093a4cae8ce80d54a5e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1744 zcmbtT&1(};5T8v`8?mNQdZ^UO9#XBSkF0vA9wZWLRw$+TMT>{HNj9dY`Ec_BtsXq& z6pG;g;lZokf{F((7XJVRPX)ac4}u7BX7eU_S=NgV%+AbjzTTU8`*dmfdc-h*$$%>` zv={|g9UJOtUrj?C4#SVB6TfcR&*liSJD=_L_e9a&iOw(h_O)cp>e`*Jd*trC>3wL; zp)>h<535<9?9Lba=f2%}Z*~2EZxIaMxt)v^?K9JU1v&0J?Do6Fy|?oZTL9Ti=CZkv zb!)O-H?51}f=HQ-#nVa!h+?Az@;GvKs81C3dttt@kjYQ^fppqYqH`V9 z;{7uqb_|*BA0!ijFnr-JI7qkJa6L!1JXaJzEN4Au1bp`={i(~QDT zDxCip1;Yzg0y5bDEc&VDzvf$*OEu3U>%{%(ZaQ&)mT7d7p3;L*f2nLUfO8(p8|Y_U z5B;bcnjVZ@M<2b@kvECfa>;X%d4(>|6~x^SAzL}0HJTF AIsgCw diff --git a/suckless/slstatus/components/uptime.c b/suckless/slstatus/components/uptime.c deleted file mode 100644 index 6227f73..0000000 --- a/suckless/slstatus/components/uptime.c +++ /dev/null @@ -1,34 +0,0 @@ -/* See LICENSE file for copyright and license details. */ -#include -#include -#include - -#include "../slstatus.h" -#include "../util.h" - -#if defined(CLOCK_BOOTTIME) - #define UPTIME_FLAG CLOCK_BOOTTIME -#elif defined(CLOCK_UPTIME) - #define UPTIME_FLAG CLOCK_UPTIME -#else - #define UPTIME_FLAG CLOCK_MONOTONIC -#endif - -const char * -uptime(const char *unused) -{ - char warn_buf[256]; - uintmax_t h, m; - struct timespec uptime; - - if (clock_gettime(UPTIME_FLAG, &uptime) < 0) { - snprintf(warn_buf, sizeof(warn_buf), "clock_gettime %d", UPTIME_FLAG); - warn(warn_buf); - return NULL; - } - - h = uptime.tv_sec / 3600; - m = uptime.tv_sec % 3600 / 60; - - return bprintf("%juh %jum", h, m); -} diff --git a/suckless/slstatus/components/uptime.o b/suckless/slstatus/components/uptime.o deleted file mode 100644 index aa75195b1f02b4d61b4061848b9b0c0eb08f819f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2024 zcmbu9&ubG=5XWcJ)<&&qlnRB4>>-sD^^w&IRa8=H?FvCeQ4xi(O}0&K^TW+nTRlh- z!B7ew^x$8h7r}#<^q@gSJoZ2ETF{Gl5Q|XfyLqqKEZd6?yu6vu%)EK~=Dj=|&zz5F z8Y$7}EVV2}i3*)9J?*J!iqRhW*?Vx~%KL66=F)eaGxO&1@L&>l?QNo;fw|%)qU%U` z+*mwmuG~uWkJgb;MnYFK8xY1~7-%{rCxkR)ck72Bvn+$am0CG?-LiVQiP}h*1-b;UFXsAYn~rp z3DKzC?rUPw?q4QtA+8PdbVr|ZaDw>(>08A-9*aMUWMXe3k(aUfXe=sy+fAs~Nk2Bj z{2e&$fb8;YuOn@qUdi{iQ6lVnpKl#+kIV*m;CzBI#2}21Y{Sv&u=w$9IL%kkPmv>$ z8B5{EkciqEPT6d=RB>iX?o>8cn5BD`Q=-WxfX}t~aZ_&y4EC# zs_Qi8g3=s&&JwP@;F8E&u0>+9S|#C>VIbTP28mp`SmgIWqEvQm!B_sMcSh2lF3pRI zQ?A&KyU3|n&@N=B9II$=?cl!@owIRUarS;mOGDi|YS_Q~CDIe@BY47G4 zx$0f@OMXal^}Z#h4W$I;VErTP$D03|Z*VTwJjTN>sy@EYFRH$p)9i$v@&~cLUk2y_ zuJY7;f&EJNhn@(7A+a}@;T^QyNw!C1{w3D^qRwBjJFFlynEyoPr&XYwgZX&FVf|l| z4N-kY|MAXLzT#oEQR<7VAC+?tGyHo7^RZ^I_l#&we$X`-K9S395&Z9l<*!TlU@Nkz H1oQs_mr~}- diff --git a/suckless/slstatus/components/user.c b/suckless/slstatus/components/user.c deleted file mode 100644 index 3517495..0000000 --- a/suckless/slstatus/components/user.c +++ /dev/null @@ -1,33 +0,0 @@ -/* See LICENSE file for copyright and license details. */ -#include -#include -#include -#include - -#include "../slstatus.h" -#include "../util.h" - -const char * -gid(const char *unused) -{ - return bprintf("%d", getgid()); -} - -const char * -username(const char *unused) -{ - struct passwd *pw; - - if (!(pw = getpwuid(geteuid()))) { - warn("getpwuid '%d':", geteuid()); - return NULL; - } - - return bprintf("%s", pw->pw_name); -} - -const char * -uid(const char *unused) -{ - return bprintf("%d", geteuid()); -} diff --git a/suckless/slstatus/components/user.o b/suckless/slstatus/components/user.o deleted file mode 100644 index f58bb3ace5c136b63c231c8813b74de54ff86550..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2240 zcmb`H-%Aux6vxl_Bh4S1Nl|3T^k5p)ZAXPfs3vUF$U>w-C5l;h)Ft;vvm z_1dd1z57e;p#rUjadmT}Sa64j3d55$R3n<6nwoS+ro(bvskq*_8dF)fI&sdJcqVG& z(Z>U?GkxbCwGh?8T6sWVyFB*%j`qu$IP~ZG7{@}Kr}N}&^*IAQ9i6W^82q&M5Dh@* zGJUr*otljse$DWQU75~Y_X2y9yt~Gq&NFDA!gICJx7~dX2CYqQ5_=?Xr;WzctF3nG zZ;-@D*6oe+5%(!J`cw7wvobru1LteYAcJQ7EOXS6e0?U&E*=nn=>YB@z{i-Q{sYz! z*@rf2VWgHx%}!-8jbif9RI9}T<*QM#9Ixo0a!?AvL+-Uk)6r%Sl~L~yCKmKf2ajL7 zi6rMq=r4VC!q4y;g7_{T!bbpEz`J<}$NNH12R`A~0a@%iw-T)5(ZdoiJ%#w56wjM@ zyH3$?`}uLd5X7UGr2bVv7Mt@|sm125;i!)xGGPqia$gG;m-{4D+b+dHo^>20dQGe- zTn|(nZpEYuK^&0E*J`Aq3Kj_Wlt*g0QY!HegH*W^hl+m*7iw{^{Mf8l%Nwd1RjOeW zZ*wXNhHH;jBJ{+65tpmr8f6eze7d1zDq($~Wo`!78{-S-uvR2$jvvw^md7^K!U+i?~ zm-HfK+p&x6!*`$VVT6Ch#4?wt#w_PA;0YV3Y3KW9qcsUM+Rk5R-t7Lj09j@drT;01 z*_M2{|7Lq5<&D{Y&gdRy=utZ#HSN1+L_f?6<*-PJDc2xJ*=m+wH_!j95t$fv{%<`8 B{qX<* diff --git a/suckless/slstatus/components/volume.c b/suckless/slstatus/components/volume.c deleted file mode 100644 index 6cec556..0000000 --- a/suckless/slstatus/components/volume.c +++ /dev/null @@ -1,219 +0,0 @@ -/* See LICENSE file for copyright and license details. */ -#include -#include -#include -#include -#include - -#include "../slstatus.h" -#include "../util.h" - -#if defined(__OpenBSD__) | defined(__FreeBSD__) - #include - #include - #include - #include - - struct control { - LIST_ENTRY(control) next; - unsigned int addr; - #define CTRL_NONE 0 - #define CTRL_LEVEL 1 - #define CTRL_MUTE 2 - unsigned int type; - unsigned int maxval; - unsigned int val; - }; - - static LIST_HEAD(, control) controls = LIST_HEAD_INITIALIZER(controls); - static struct pollfd *pfds; - static struct sioctl_hdl *hdl; - static int initialized; - - /* - * Call-back to obtain the description of all audio controls. - */ - static void - ondesc(void *unused, struct sioctl_desc *desc, int val) - { - struct control *c, *ctmp; - unsigned int type = CTRL_NONE; - - if (desc == NULL) - return; - - /* Delete existing audio control with the same address. */ - LIST_FOREACH_SAFE(c, &controls, next, ctmp) { - if (desc->addr == c->addr) { - LIST_REMOVE(c, next); - free(c); - break; - } - } - - /* Only match output.level and output.mute audio controls. */ - if (desc->group[0] != 0 || - strcmp(desc->node0.name, "output") != 0) - return; - if (desc->type == SIOCTL_NUM && - strcmp(desc->func, "level") == 0) - type = CTRL_LEVEL; - else if (desc->type == SIOCTL_SW && - strcmp(desc->func, "mute") == 0) - type = CTRL_MUTE; - else - return; - - c = malloc(sizeof(struct control)); - if (c == NULL) { - warn("sndio: failed to allocate audio control\n"); - return; - } - - c->addr = desc->addr; - c->type = type; - c->maxval = desc->maxval; - c->val = val; - LIST_INSERT_HEAD(&controls, c, next); - } - - /* - * Call-back invoked whenever an audio control changes. - */ - static void - onval(void *unused, unsigned int addr, unsigned int val) - { - struct control *c; - - LIST_FOREACH(c, &controls, next) { - if (c->addr == addr) - break; - } - c->val = val; - } - - static void - cleanup(void) - { - struct control *c; - - if (hdl) { - sioctl_close(hdl); - hdl = NULL; - } - - free(pfds); - pfds = NULL; - - while (!LIST_EMPTY(&controls)) { - c = LIST_FIRST(&controls); - LIST_REMOVE(c, next); - free(c); - } - } - - static int - init(void) - { - hdl = sioctl_open(SIO_DEVANY, SIOCTL_READ, 0); - if (hdl == NULL) { - warn("sndio: cannot open device"); - goto failed; - } - - if (!sioctl_ondesc(hdl, ondesc, NULL)) { - warn("sndio: cannot set control description call-back"); - goto failed; - } - - if (!sioctl_onval(hdl, onval, NULL)) { - warn("sndio: cannot set control values call-back"); - goto failed; - } - - pfds = calloc(sioctl_nfds(hdl), sizeof(struct pollfd)); - if (pfds == NULL) { - warn("sndio: cannot allocate pollfd structures"); - goto failed; - } - - return 1; - failed: - cleanup(); - return 0; - } - - const char * - vol_perc(const char *unused) - { - struct control *c; - int n, v, value; - - if (!initialized) - initialized = init(); - - if (hdl == NULL) - return NULL; - - n = sioctl_pollfd(hdl, pfds, POLLIN); - if (n > 0) { - n = poll(pfds, n, 0); - if (n > 0) { - if (sioctl_revents(hdl, pfds) & POLLHUP) { - warn("sndio: disconnected"); - cleanup(); - initialized = 0; - return NULL; - } - } - } - - value = 100; - LIST_FOREACH(c, &controls, next) { - if (c->type == CTRL_MUTE && c->val == 1) - value = 0; - else if (c->type == CTRL_LEVEL) { - v = (c->val * 100 + c->maxval / 2) / c->maxval; - /* For multiple channels return the minimum. */ - if (v < value) - value = v; - } - } - - return bprintf("%d", value); - } -#else - #include - - const char * - vol_perc(const char *card) - { - size_t i; - int v, afd, devmask; - char *vnames[] = SOUND_DEVICE_NAMES; - - if ((afd = open(card, O_RDONLY | O_NONBLOCK)) < 0) { - warn("open '%s':", card); - return NULL; - } - - if (ioctl(afd, (int)SOUND_MIXER_READ_DEVMASK, &devmask) < 0) { - warn("ioctl 'SOUND_MIXER_READ_DEVMASK':"); - close(afd); - return NULL; - } - for (i = 0; i < LEN(vnames); i++) { - if (devmask & (1 << i) && !strcmp("vol", vnames[i])) { - if (ioctl(afd, MIXER_READ(i), &v) < 0) { - warn("ioctl 'MIXER_READ(%ld)':", i); - close(afd); - return NULL; - } - } - } - - close(afd); - - return bprintf("%d", v & 0xff); - } -#endif diff --git a/suckless/slstatus/components/volume.o b/suckless/slstatus/components/volume.o deleted file mode 100644 index e42a5869a465eeb5cadc482c054884dc7048cd77..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3632 zcmds(O>7%g5P-*VlDZHa14T*|gpA}6S5a1WQXmAV?B;I^NhnE!f}j{@y@{>Z-etW> z9YCt97K90wf`qCZI3N&$1BX^f6-cPEC{VcdMo;t_sihS4hFZeRdS0@A*cXnBv~Om< zH}l@xx9?|9j!llYcswA)1BYPO6BNL_XV;E7W(+#P54SrX`71uBRvstz?En_>V{>Zx z?yP$1#uj=hb-lGGjD}i16S|5zT2(7=hXS`hzX(2}e^3;>Q(b#dE#Fit&yp9dI`I0T z^5ya+wQ?-fpOv^rTyg#we6ekbgAk-NV>v3$*`h*qyJt&fH}IzQVgJbh&S z;Elj09N*-U?Ev3fNkjuSse;%c{>fJmV<(+Czo{#vYEUN zxr_!{3RRKn2Efua$Sfr@c`%%kf}&37fKv`aDzg-&Vt|T4Fw+=ori~RFRx>Hx04tfw z7?3ma8QZV`CPqevgW(B1ZyQE1dQcfuB0+QL0GrT?-z|Vo8$J`$bI<}%CFaG4gzO+b zyY(KYUhE|g)cgA|mc;Ys40wtGPj|;2-v$OhgY03a2B4pk$Nhmy%e24i18>|Pe7AMf zA3ohS;ooTSwtM_xL~(!DVSnJT-^WQ!6gAZfe{MIb_BPz{^lswq>a)DiUJuZ#9S{HJ zG-rVE&W3gDTJeyh+TmUoBeR=%RN{{^e@^1P=s(~ZzcXjZBKXw$u1}zIsu3S}Qu9E?y@!qhDdXy3t!q?NC2DA2M-0XL0p zX*m-XOe>SO7a@@-*hy_Up{17-i^)tD``(KW39eh`tKQkJ$%sR1>zBTT;4d<#cv{nf z&oig>-r?d!<`hq>K*XP9PVx7-`1{N$evgZP$XsrJ)5ZO+`13B_>Ege*xVzt9nNz>C zWyCmtbH%&g>z0eV`@O@Q+M&4>?RaUUq0sngoeAFU;`h5anvT@=C+>On#da2)))k3Z zyMoWuFm$mN{AKoo5>K!nmbk`#MB>Zr4@ul)KPGXTeO2No*gq=qx7eSTc!~YjC4Pqe zw8X`F65|r{u)%RfDgG?`C5eB`{(BPtlzq{jX#Wf5n^OE&?0+J0v0lHF_yzXQN&GwZ zzmfR&>{liJGy6f-v_9$C5v8z}vy%&;;F(d=X<=DP zIZ-7Fie}_;cvFIsH*8(O`>@|RaM)kUuPCO4CzWNdaZ`Fav1lc8`pz)^s}aORntS=C zi6J8q=YP$s#R{7=-7mB^WB9mbiw-%IO==v4&Hyrf?^v_-zqW6UB_ zoR0?-l(@(fdYbd4FbK;p!~r5t#J`3HO_lt*BLAoeWG&`T;8irJO*y~F{m+X))^h$E z$QymXt9-$Vbwb~d{)t4s;EnpGuC8$Z=lF%`&T5oT-87o260hGyYRo0_{L$UhDE}6Z LzvRj#Q_lYfhj+x7 diff --git a/suckless/slstatus/components/wifi.c b/suckless/slstatus/components/wifi.c deleted file mode 100644 index 4543d32..0000000 --- a/suckless/slstatus/components/wifi.c +++ /dev/null @@ -1,267 +0,0 @@ -/* See LICENSE file for copyright and license details. */ -#include -#include -#include -#include -#include -#include - -#include "../slstatus.h" -#include "../util.h" - -#define RSSI_TO_PERC(rssi) \ - rssi >= -50 ? 100 : \ - (rssi <= -100 ? 0 : \ - (2 * (rssi + 100))) - -#if defined(__linux__) - #include - #include - - #define NET_OPERSTATE "/sys/class/net/%s/operstate" - - const char * - wifi_perc(const char *interface) - { - int cur; - size_t i; - char *p, *datastart; - char path[PATH_MAX]; - char status[5]; - FILE *fp; - - if (esnprintf(path, sizeof(path), NET_OPERSTATE, interface) < 0) - return NULL; - if (!(fp = fopen(path, "r"))) { - warn("fopen '%s':", path); - return NULL; - } - p = fgets(status, 5, fp); - fclose(fp); - if (!p || strcmp(status, "up\n") != 0) - return NULL; - - if (!(fp = fopen("/proc/net/wireless", "r"))) { - warn("fopen '/proc/net/wireless':"); - return NULL; - } - - for (i = 0; i < 3; i++) - if (!(p = fgets(buf, sizeof(buf) - 1, fp))) - break; - - fclose(fp); - if (i < 2 || !p) - return NULL; - - if (!(datastart = strstr(buf, interface))) - return NULL; - - datastart = (datastart+(strlen(interface)+1)); - sscanf(datastart + 1, " %*d %d %*d %*d\t\t %*d\t " - "%*d\t\t%*d\t\t %*d\t %*d\t\t %*d", &cur); - - /* 70 is the max of /proc/net/wireless */ - return bprintf("%d", (int)((float)cur / 70 * 100)); - } - - const char * - wifi_essid(const char *interface) - { - static char id[IW_ESSID_MAX_SIZE+1]; - int sockfd; - struct iwreq wreq; - - memset(&wreq, 0, sizeof(struct iwreq)); - wreq.u.essid.length = IW_ESSID_MAX_SIZE+1; - if (esnprintf(wreq.ifr_name, sizeof(wreq.ifr_name), "%s", - interface) < 0) - return NULL; - - if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { - warn("socket 'AF_INET':"); - return NULL; - } - wreq.u.essid.pointer = id; - if (ioctl(sockfd,SIOCGIWESSID, &wreq) < 0) { - warn("ioctl 'SIOCGIWESSID':"); - close(sockfd); - return NULL; - } - - close(sockfd); - - if (!strcmp(id, "")) - return NULL; - - return id; - } -#elif defined(__OpenBSD__) - #include - #include - #include - #include /* before for NBBY */ - #include - #include - #include - - static int - load_ieee80211_nodereq(const char *interface, struct ieee80211_nodereq *nr) - { - struct ieee80211_bssid bssid; - int sockfd; - uint8_t zero_bssid[IEEE80211_ADDR_LEN]; - - memset(&bssid, 0, sizeof(bssid)); - memset(nr, 0, sizeof(struct ieee80211_nodereq)); - if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { - warn("socket 'AF_INET':"); - return 0; - } - strlcpy(bssid.i_name, interface, sizeof(bssid.i_name)); - if ((ioctl(sockfd, SIOCG80211BSSID, &bssid)) < 0) { - warn("ioctl 'SIOCG80211BSSID':"); - close(sockfd); - return 0; - } - memset(&zero_bssid, 0, sizeof(zero_bssid)); - if (memcmp(bssid.i_bssid, zero_bssid, - IEEE80211_ADDR_LEN) == 0) { - close(sockfd); - return 0; - } - strlcpy(nr->nr_ifname, interface, sizeof(nr->nr_ifname)); - memcpy(&nr->nr_macaddr, bssid.i_bssid, sizeof(nr->nr_macaddr)); - if ((ioctl(sockfd, SIOCG80211NODE, nr)) < 0 && nr->nr_rssi) { - warn("ioctl 'SIOCG80211NODE':"); - close(sockfd); - return 0; - } - - return close(sockfd), 1; - } - - const char * - wifi_perc(const char *interface) - { - struct ieee80211_nodereq nr; - int q; - - if (load_ieee80211_nodereq(interface, &nr)) { - if (nr.nr_max_rssi) - q = IEEE80211_NODEREQ_RSSI(&nr); - else - q = RSSI_TO_PERC(nr.nr_rssi); - - return bprintf("%d", q); - } - - return NULL; - } - - const char * - wifi_essid(const char *interface) - { - struct ieee80211_nodereq nr; - - if (load_ieee80211_nodereq(interface, &nr)) - return bprintf("%s", nr.nr_nwid); - - return NULL; - } -#elif defined(__FreeBSD__) - #include - #include - - int - load_ieee80211req(int sock, const char *interface, void *data, int type, size_t *len) - { - char warn_buf[256]; - struct ieee80211req ireq; - memset(&ireq, 0, sizeof(ireq)); - ireq.i_type = type; - ireq.i_data = (caddr_t) data; - ireq.i_len = *len; - - strlcpy(ireq.i_name, interface, sizeof(ireq.i_name)); - if (ioctl(sock, SIOCG80211, &ireq) < 0) { - snprintf(warn_buf, sizeof(warn_buf), - "ioctl: 'SIOCG80211': %d", type); - warn(warn_buf); - return 0; - } - - *len = ireq.i_len; - return 1; - } - - const char * - wifi_perc(const char *interface) - { - union { - struct ieee80211req_sta_req sta; - uint8_t buf[24 * 1024]; - } info; - uint8_t bssid[IEEE80211_ADDR_LEN]; - int rssi_dbm; - int sockfd; - size_t len; - const char *fmt; - - if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { - warn("socket 'AF_INET':"); - return NULL; - } - - /* Retreive MAC address of interface */ - len = IEEE80211_ADDR_LEN; - fmt = NULL; - if (load_ieee80211req(sockfd, interface, &bssid, IEEE80211_IOC_BSSID, &len)) - { - /* Retrieve info on station with above BSSID */ - memset(&info, 0, sizeof(info)); - memcpy(info.sta.is_u.macaddr, bssid, sizeof(bssid)); - - len = sizeof(info); - if (load_ieee80211req(sockfd, interface, &info, IEEE80211_IOC_STA_INFO, &len)) { - rssi_dbm = info.sta.info[0].isi_noise + - info.sta.info[0].isi_rssi / 2; - - fmt = bprintf("%d", RSSI_TO_PERC(rssi_dbm)); - } - } - - close(sockfd); - return fmt; - } - - const char * - wifi_essid(const char *interface) - { - char ssid[IEEE80211_NWID_LEN + 1]; - size_t len; - int sockfd; - const char *fmt; - - if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { - warn("socket 'AF_INET':"); - return NULL; - } - - fmt = NULL; - len = sizeof(ssid); - memset(&ssid, 0, len); - if (load_ieee80211req(sockfd, interface, &ssid, IEEE80211_IOC_SSID, &len)) { - if (len < sizeof(ssid)) - len += 1; - else - len = sizeof(ssid); - - ssid[len - 1] = '\0'; - fmt = bprintf("%s", ssid); - } - - close(sockfd); - return fmt; - } -#endif diff --git a/suckless/slstatus/components/wifi.o b/suckless/slstatus/components/wifi.o deleted file mode 100644 index 2c7a79c8577bef351ab88866cd0e14b4318b7d43..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4320 zcmbuBU2IfE6vt=VF0@#0YXK>OdNEsC`PlCAp+JIm`$6x@@}X@p2FkkK?$S-$-DdBt zrG7%%5^l;W4`?*ufhS|4F+A{MV#*377!wmPCO#>~7(qeN^uY+4dj4}~+UcbmA3WLl z`pr3KX3m{G_rB2**-_;2Fex7P6q_AM%9wutY`=kb8(0O?*i^+McS8F@9ijG)Hsk0m zR>_z#QtqSbmTu&hLURJJ+ZZpYsiTo$kNTgVhoHCnL8VlfgWn2t80Oi)X#jO4#8w z!@kY^kd~+7Sm*TgG_74R+D;wA{!Xs#xUU%9&ha&8yJF>ByRY2Hz3MFzN1Uoy(+nbx zJymfKhorE-Alh}mJNDzJcv!oQwM%%MEw96mPU;lx{hgr$q0Z33i~M=D8}^+~O3BRx zO)+|KBew#|18Vlw1@ne|ed*f-zUozsyQK$J6Z~qTh|JHU;?TZ0mLIN~ z*(+zk{LP()^F-~-hW$e@Ke1vQx1i5gDLf4?n`>e_5xF@jI!E}~nRU*vZy4k4zPfwP zI5HW)0WZ=<>dj%ZKHe8I&H8l0s;@EYGXsgNX~nDr%d#X5(t2%;S-Xu54lH8z1KCWR zD-NZyiN1tsN|k$O$V9JM)2-`z4OP5HRaqJDQw>yB<{;Dp0J9qUnas?@dlQyk8`=>K z?`~-)hp9~5>eFl6!h4!p!_T+0wS}9BGIpYovCkV>Yg5xUy{KS7ohxqC^b;i^t?rmNqyDx z=gnY<38FDqXiKC$%U6kMC*AS?*c^i@KJw1QLQXCd{1FL6>%`2<*0{K{j+gmed^I0? zS;)oL3f}4B0m0vKah~kh0vBZrw~G;kK*_U!B+y?-Me<=l66oVANAkA;Nx&bZBKaBW zL%@+MB>xDI1pbkWBtHj80{v<#l3xHMfj)A!OF` z9gqZm)N>Uf;gW!>=c-b;dai)NA0iv+zggic6uwh%?B_m(A5ip>OQoNbqF=6XQ{l+r zQvVf&YYHD#{6DPl(+WpUmwv7*ekv3`rRb~otrQ0$LELmI($7-C(I6j4zEaUw<6o=j zkpUq$Z^`M`Ulo-ZMi_%&= z)89{DQOuvtSP4IUC#~oCMT`%n2mSORNXg6^CPR2n^hA@{SU=uQ|4(!>$JKDZi5rMP za%wPWEUposLxukc?oI<0Rq{v{Bp-+mJ^Tk?D=^O)m|rcp{2l~@eCb-(q4%zj?=|>z z+g}m(xO1xL>VWz|D%jTs7nk;vE-ue6+Xk9P-}&yERX!y)B+n~n5G#mmcTpeq0YF7g z3wvE*=*o3vyH8=N>Zk62h)HQDb(7S=d&3>>ys+OZ6-Dbl&+EkD(`{cV4tVlE?D3w0 zYJ*F!2N#A!#sx#X2ju#A=RoFL8~lt|-w@|OuEjHQ+v6QIU#M;%C?wxF%}ni%A9B}x Q_V0@QAD^*wI&S-a0TQ(ib^rhX diff --git a/suckless/slstatus/config.def.h b/suckless/slstatus/config.def.h deleted file mode 100644 index 70f58da..0000000 --- a/suckless/slstatus/config.def.h +++ /dev/null @@ -1,81 +0,0 @@ -/* See LICENSE file for copyright and license details. */ - -/* interval between updates (in ms) */ -const unsigned int interval = 1000; - -/* text to show if no value can be retrieved */ -static const char unknown_str[] = "n/a"; - -/* maximum output string length */ -#define MAXLEN 2048 - -/* - * function description argument (example) - * - * battery_perc battery percentage battery name (BAT0) - * NULL on OpenBSD/FreeBSD - * battery_remaining battery remaining HH:MM battery name (BAT0) - * NULL on OpenBSD/FreeBSD - * battery_state battery charging state battery name (BAT0) - * NULL on OpenBSD/FreeBSD - * cat read arbitrary file path - * cpu_freq cpu frequency in MHz NULL - * cpu_perc cpu usage in percent NULL - * datetime date and time format string (%F %T) - * disk_free free disk space in GB mountpoint path (/) - * disk_perc disk usage in percent mountpoint path (/) - * disk_total total disk space in GB mountpoint path (/) - * disk_used used disk space in GB mountpoint path (/) - * entropy available entropy NULL - * gid GID of current user NULL - * hostname hostname NULL - * ipv4 IPv4 address interface name (eth0) - * ipv6 IPv6 address interface name (eth0) - * kernel_release `uname -r` NULL - * keyboard_indicators caps/num lock indicators format string (c?n?) - * see keyboard_indicators.c - * keymap layout (variant) of current NULL - * keymap - * load_avg load average NULL - * netspeed_rx receive network speed interface name (wlan0) - * netspeed_tx transfer network speed interface name (wlan0) - * num_files number of files in a directory path - * (/home/foo/Inbox/cur) - * ram_free free memory in GB NULL - * ram_perc memory usage in percent NULL - * ram_total total memory size in GB NULL - * ram_used used memory in GB NULL - * run_command custom shell command command (echo foo) - * swap_free free swap in GB NULL - * swap_perc swap usage in percent NULL - * swap_total total swap size in GB NULL - * swap_used used swap in GB NULL - * temp temperature in degree celsius sensor file - * (/sys/class/thermal/...) - * NULL on OpenBSD - * thermal zone on FreeBSD - * (tz0, tz1, etc.) - * uid UID of current user NULL - * uptime system uptime NULL - * username username of current user NULL - * vol_perc OSS/ALSA volume in percent mixer file (/dev/mixer) - * NULL on OpenBSD/FreeBSD - * wifi_essid WiFi ESSID interface name (wlan0) - * wifi_perc WiFi signal in percent interface name (wlan0) - */ -static const struct arg args[] = { - /* function format argument */ - {battery_state, " %s /", "BAT1"}, - {battery_perc, "  %s% |", "BAT1"}, - {run_command, "  %s% |", "light -G | awk '{print int($1)}'"}, - {run_command, "  %s% |", "pamixer --get-volume"}, - {cpu_perc, "  %s% /", NULL}, - {temp, "  %s󰔄 |", "/sys/class/thermal/thermal_zone3/temp"}, - {ram_used, "  %s |", NULL}, - {run_command, " 󰸗 %s |", "date +'%b %d'"}, - {run_command, " 󱑃 %s |", "date +%H:%M"}, - {disk_perc, "  %s% |", "/home"}, - {wifi_essid, "  %s |", "wlan0"}, - {keymap, "  %s ", NULL}, - -}; diff --git a/suckless/slstatus/config.h b/suckless/slstatus/config.h deleted file mode 100644 index 8ae8a78..0000000 --- a/suckless/slstatus/config.h +++ /dev/null @@ -1,74 +0,0 @@ -/* See LICENSE file for copyright and license details. */ - -/* interval between updates (in ms) */ -const unsigned int interval = 1000; - -/* text to show if no value can be retrieved */ -static const char unknown_str[] = "n/a"; - -/* maximum output string length */ -#define MAXLEN 2048 - -/* - * function description argument (example) - * - * battery_perc battery percentage battery name (BAT0) - * NULL on OpenBSD/FreeBSD - * battery_remaining battery remaining HH:MM battery name (BAT0) - * NULL on OpenBSD/FreeBSD - * battery_state battery charging state battery name (BAT0) - * NULL on OpenBSD/FreeBSD - * cat read arbitrary file path - * cpu_freq cpu frequency in MHz NULL - * cpu_perc cpu usage in percent NULL - * datetime date and time format string (%F %T) - * disk_free free disk space in GB mountpoint path (/) - * disk_perc disk usage in percent mountpoint path (/) - * disk_total total disk space in GB mountpoint path (/) - * disk_used used disk space in GB mountpoint path (/) - * entropy available entropy NULL - * gid GID of current user NULL - * hostname hostname NULL - * ipv4 IPv4 address interface name (eth0) - * ipv6 IPv6 address interface name (eth0) - * kernel_release `uname -r` NULL - * keyboard_indicators caps/num lock indicators format string (c?n?) - * see keyboard_indicators.c - * keymap layout (variant) of current NULL - * keymap - * load_avg load average NULL - * netspeed_rx receive network speed interface name (wlan0) - * netspeed_tx transfer network speed interface name (wlan0) - * num_files number of files in a directory path - * (/home/foo/Inbox/cur) - * ram_free free memory in GB NULL - * ram_perc memory usage in percent NULL - * ram_total total memory size in GB NULL - * ram_used used memory in GB NULL - * run_command custom shell command command (echo foo) - * swap_free free swap in GB NULL - * swap_perc swap usage in percent NULL - * swap_total total swap size in GB NULL - * swap_used used swap in GB NULL - * temp temperature in degree celsius sensor file - * (/sys/class/thermal/...) - * NULL on OpenBSD - * thermal zone on FreeBSD - * (tz0, tz1, etc.) - * uid UID of current user NULL - * uptime system uptime NULL - * username username of current user NULL - * vol_perc OSS/ALSA volume in percent mixer file (/dev/mixer) - * NULL on OpenBSD/FreeBSD - * wifi_essid WiFi ESSID interface name (wlan0) - * wifi_perc WiFi signal in percent interface name (wlan0) - */ -static const struct arg args[] = { - /* function format argument */ - {run_command, "[ %s%]", "amixer get Master | grep -o '[0-9]*%' | head -1"}, - {ram_used, " [ %s] ", NULL}, - {battery_state, "[%s", "BAT1"}, - {battery_perc, " %s%] ", "BAT1"}, - {run_command, "[󱑃 %s] ", "date +%I:%M-%p"}, - -}; diff --git a/suckless/slstatus/config.h~ b/suckless/slstatus/config.h~ deleted file mode 100644 index 81616f0..0000000 --- a/suckless/slstatus/config.h~ +++ /dev/null @@ -1,77 +0,0 @@ -/* See LICENSE file for copyright and license details. */ - -/* interval between updates (in ms) */ -const unsigned int interval = 1000; - -/* text to show if no value can be retrieved */ -static const char unknown_str[] = "n/a"; - -/* maximum output string length */ -#define MAXLEN 2048 - -/* - * function description argument (example) - * - * battery_perc battery percentage battery name (BAT0) - * NULL on OpenBSD/FreeBSD - * battery_remaining battery remaining HH:MM battery name (BAT0) - * NULL on OpenBSD/FreeBSD - * battery_state battery charging state battery name (BAT0) - * NULL on OpenBSD/FreeBSD - * cat read arbitrary file path - * cpu_freq cpu frequency in MHz NULL - * cpu_perc cpu usage in percent NULL - * datetime date and time format string (%F %T) - * disk_free free disk space in GB mountpoint path (/) - * disk_perc disk usage in percent mountpoint path (/) - * disk_total total disk space in GB mountpoint path (/) - * disk_used used disk space in GB mountpoint path (/) - * entropy available entropy NULL - * gid GID of current user NULL - * hostname hostname NULL - * ipv4 IPv4 address interface name (eth0) - * ipv6 IPv6 address interface name (eth0) - * kernel_release `uname -r` NULL - * keyboard_indicators caps/num lock indicators format string (c?n?) - * see keyboard_indicators.c - * keymap layout (variant) of current NULL - * keymap - * load_avg load average NULL - * netspeed_rx receive network speed interface name (wlan0) - * netspeed_tx transfer network speed interface name (wlan0) - * num_files number of files in a directory path - * (/home/foo/Inbox/cur) - * ram_free free memory in GB NULL - * ram_perc memory usage in percent NULL - * ram_total total memory size in GB NULL - * ram_used used memory in GB NULL - * run_command custom shell command command (echo foo) - * swap_free free swap in GB NULL - * swap_perc swap usage in percent NULL - * swap_total total swap size in GB NULL - * swap_used used swap in GB NULL - * temp temperature in degree celsius sensor file - * (/sys/class/thermal/...) - * NULL on OpenBSD - * thermal zone on FreeBSD - * (tz0, tz1, etc.) - * uid UID of current user NULL - * uptime system uptime NULL - * username username of current user NULL - * vol_perc OSS/ALSA volume in percent mixer file (/dev/mixer) - * NULL on OpenBSD/FreeBSD - * wifi_essid WiFi ESSID interface name (wlan0) - * wifi_perc WiFi signal in percent interface name (wlan0) - */ -static const struct arg args[] = { - /* function format argument */ - {battery_state, " [%s", "BAT1"}, - {battery_perc, " %s% ]", "BAT1"}, - {run_command, " [ %s%] ", "pamixer --get-volume"}, - {cpu_perc, " [ %s%] ", NULL}, - {temp, " [ %s󰔄] ", "/sys/class/thermal/thermal_zone3/temp"}, - {ram_used, " [ %s] ", NULL}, - {run_command, " [󰸗 %s] ", "date +'%b %d'"}, - {run_command, " [󱑃 %s] ", "date +%H:%M"}, - -}; diff --git a/suckless/slstatus/config.mk b/suckless/slstatus/config.mk deleted file mode 100644 index 07af883..0000000 --- a/suckless/slstatus/config.mk +++ /dev/null @@ -1,22 +0,0 @@ -# slstatus version -VERSION = 1.0 - -# customize below to fit your system - -# paths -PREFIX = /usr/local -MANPREFIX = $(PREFIX)/share/man - -X11INC = /usr/X11R6/include -X11LIB = /usr/X11R6/lib - -# flags -CPPFLAGS = -I$(X11INC) -D_DEFAULT_SOURCE -DVERSION=\"${VERSION}\" -CFLAGS = -std=c99 -pedantic -Wall -Wextra -Wno-unused-parameter -Os -LDFLAGS = -L$(X11LIB) -s -# OpenBSD: add -lsndio -# FreeBSD: add -lkvm -lsndio -LDLIBS = -lX11 - -# compiler and linker -CC = cc diff --git a/suckless/slstatus/slstatus b/suckless/slstatus/slstatus deleted file mode 100755 index 042803c8a622d96a3546b125edb634737cb61e90..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 31248 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 -#include -#include -#include -#include -#include -#include - -#include "arg.h" -#include "slstatus.h" -#include "util.h" - -struct arg { - const char *(*func)(const char *); - const char *fmt; - const char *args; -}; - -char buf[1024]; -static volatile sig_atomic_t done; -static Display *dpy; - -#include "config.h" - -static void -terminate(const int signo) -{ - if (signo != SIGUSR1) - done = 1; -} - -static void -difftimespec(struct timespec *res, struct timespec *a, struct timespec *b) -{ - res->tv_sec = a->tv_sec - b->tv_sec - (a->tv_nsec < b->tv_nsec); - res->tv_nsec = a->tv_nsec - b->tv_nsec + - (a->tv_nsec < b->tv_nsec) * 1E9; -} - -static void -usage(void) -{ - die("usage: %s [-v] [-s] [-1]", argv0); -} - -int -main(int argc, char *argv[]) -{ - struct sigaction act; - struct timespec start, current, diff, intspec, wait; - size_t i, len; - int sflag, ret; - char status[MAXLEN]; - const char *res; - - sflag = 0; - ARGBEGIN { - case 'v': - die("slstatus-"VERSION); - case '1': - done = 1; - /* FALLTHROUGH */ - case 's': - sflag = 1; - break; - default: - usage(); - } ARGEND - - if (argc) - usage(); - - memset(&act, 0, sizeof(act)); - act.sa_handler = terminate; - sigaction(SIGINT, &act, NULL); - sigaction(SIGTERM, &act, NULL); - act.sa_flags |= SA_RESTART; - sigaction(SIGUSR1, &act, NULL); - - if (!sflag && !(dpy = XOpenDisplay(NULL))) - die("XOpenDisplay: Failed to open display"); - - do { - if (clock_gettime(CLOCK_MONOTONIC, &start) < 0) - die("clock_gettime:"); - - status[0] = '\0'; - for (i = len = 0; i < LEN(args); i++) { - if (!(res = args[i].func(args[i].args))) - res = unknown_str; - - if ((ret = esnprintf(status + len, sizeof(status) - len, - args[i].fmt, res)) < 0) - break; - - len += ret; - } - - if (sflag) { - puts(status); - fflush(stdout); - if (ferror(stdout)) - die("puts:"); - } else { - if (XStoreName(dpy, DefaultRootWindow(dpy), status) < 0) - die("XStoreName: Allocation failed"); - XFlush(dpy); - } - - if (!done) { - if (clock_gettime(CLOCK_MONOTONIC, ¤t) < 0) - die("clock_gettime:"); - difftimespec(&diff, ¤t, &start); - - intspec.tv_sec = interval / 1000; - intspec.tv_nsec = (interval % 1000) * 1E6; - difftimespec(&wait, &intspec, &diff); - - if (wait.tv_sec >= 0 && - nanosleep(&wait, NULL) < 0 && - errno != EINTR) - die("nanosleep:"); - } - } while (!done); - - if (!sflag) { - XStoreName(dpy, DefaultRootWindow(dpy), NULL); - if (XCloseDisplay(dpy) < 0) - die("XCloseDisplay: Failed to close display"); - } - - return 0; -} diff --git a/suckless/slstatus/slstatus.h b/suckless/slstatus/slstatus.h deleted file mode 100644 index 8ef5874..0000000 --- a/suckless/slstatus/slstatus.h +++ /dev/null @@ -1,84 +0,0 @@ -/* See LICENSE file for copyright and license details. */ - -/* battery */ -const char *battery_perc(const char *); -const char *battery_remaining(const char *); -const char *battery_state(const char *); - -/* cat */ -const char *cat(const char *path); - -/* cpu */ -const char *cpu_freq(const char *unused); -const char *cpu_perc(const char *unused); - -/* datetime */ -const char *datetime(const char *fmt); - -/* disk */ -const char *disk_free(const char *path); -const char *disk_perc(const char *path); -const char *disk_total(const char *path); -const char *disk_used(const char *path); - -/* entropy */ -const char *entropy(const char *unused); - -/* hostname */ -const char *hostname(const char *unused); - -/* ip */ -const char *ipv4(const char *interface); -const char *ipv6(const char *interface); - -/* kernel_release */ -const char *kernel_release(const char *unused); - -/* keyboard_indicators */ -const char *keyboard_indicators(const char *fmt); - -/* keymap */ -const char *keymap(const char *unused); - -/* load_avg */ -const char *load_avg(const char *unused); - -/* netspeeds */ -const char *netspeed_rx(const char *interface); -const char *netspeed_tx(const char *interface); - -/* num_files */ -const char *num_files(const char *path); - -/* ram */ -const char *ram_free(const char *unused); -const char *ram_perc(const char *unused); -const char *ram_total(const char *unused); -const char *ram_used(const char *unused); - -/* run_command */ -const char *run_command(const char *cmd); - -/* swap */ -const char *swap_free(const char *unused); -const char *swap_perc(const char *unused); -const char *swap_total(const char *unused); -const char *swap_used(const char *unused); - -/* temperature */ -const char *temp(const char *); - -/* uptime */ -const char *uptime(const char *unused); - -/* user */ -const char *gid(const char *unused); -const char *uid(const char *unused); -const char *username(const char *unused); - -/* volume */ -const char *vol_perc(const char *card); - -/* wifi */ -const char *wifi_essid(const char *interface); -const char *wifi_perc(const char *interface); diff --git a/suckless/slstatus/slstatus.o b/suckless/slstatus/slstatus.o deleted file mode 100644 index d4578255c72ba2e812d1bbffcd201b9efc38405e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6376 zcmc&&U2I%O6`u9)Hke(Te@!mj!6 zx-nncWNmt_8c}rp6)NVmY3WwhY!3%RENki$MyJ+nY9sB(M&V`RD?G}EKbJO=JyT|S zTA%CG`t+%3BcWL-Ed{WauyHmvof8xdTvf%+Ml`#(LfN0TaVCdFV zDyfZ&5G<)DQ|7c`q=DEyoidFwZ9rJlSZieDy;DEXpoh()OrM#WH8L7Bs6C*Y7O2Oy ziHwof+Ed#0kx={I(YEI8fK3{DLTe8*ZRGD~7twcAVxvEnh@rr~_T#V4+f@nO zGPE7d{hiGZv^S?k;-U{lKOY^64h{|EZt~NAz3gR-=W7x?zq7doa>#Q(3@jm*`zOzd z^zy}`Ra3gi=U?^qhTn-5?!#2`d@sX_lcze`vvX$-c@~zfO!SvH6{l{rXB$t=R{Tc`|_8$QmM4~2kX|dEM6E4bnwC>fl#>kQUJVp?k%4CV|e-6^SmI2b+$sF zJ%NyDH@pnhXZ?T?a}$`SpA5VR1xUT9>0Nv$dv~}b^z{s7>$u%Z8!vnU9eD2Dvp8^p zEf(i|k|RfQVIi<2XoYqxdc&)+!ptnspQw)&UKUlQA@&OMVz!682MYW4K*o9Q9QXHJ zjJ2-HD2v5eAO9xIPE)_VK%n z^F4ujzN0F@_x>*8|JDWG`aaM7hPS?XmHXS?1n`9Ss=r<|0p&-b1r}bu>VNp$RsZmL z;Otz&Ad9d2zkQy!p69tGe*H4f4F)vye*-E`6908CNNP`@g)c78wuD!C;dnq3V}X%2 z31z;c%5u!z+Bg>)|6MBKn&^^gfQ96qJesOeKZ;u`yGz|{~^gw>Fi3SYWe;9Q8O-Gin9IP-JM#?ej{n6Qd)R-a91#-r8`=s z%Bp}@4-Zb@{)0mdzQ7`4DirD(JnQuyQIFpciig?uEw%|~fi0fL9%P=`de0qowce+J zjBVWM;Bc@*61#{E_WA0+QqkpWdaAO^rxmKYd@WB_M}48kYofl6`PzQp(+!p1uk>|v z`$AD)3s8XC<*V=V!9=(T_Opupqg1ZGvg`?mW5-c%lsYgg2w#o!Ho!f=_evM)St+u% zF%DXltmZ@D9e`jQ)wCMY-2%r=&lVMb2bdn*hosCZ1#dLscv|;2&_{J;JVLUvS|45%EoD2RV7yM@~_%B@W z3oiI27yK<3{E7>{>VntGJp!sX$QBp;P8Yn*1>XbsW?28~`%z^?;L3ugm8veT!7&C` zznQ5dT-#V8m4sJ%j%AZalc_HzU!TU;9(;xH)q$_Q z_zH*Ej6Rh_=VKw3m@=3-HKC8;<#oetc;l^?8D=t_nMzvY;`+->E0M}tYv!=u*V6GH*CdEkT^8YM+qO#LdBmYd_3P3 zK2P|#? z1CNT+K=_*pemmjQacw1hOufo~gz&eLI0p#7f#44kK8^n{;nVn!68j4g#!fn z65-Q%e4Oyx7SYN0o=ou@UmXIJpCGeGx zDuZLD1vdyhkKyMW3no*R5riLY?c&gu_CzupOlRPavy3$-LmHFuaX7pU+Wr4k*T7M& z2^u3J4fVT7)yecKli}Hf-*jXRv6W#wR6x{v#Jv@L)p}O=Hi^s60xVkwmEtI!?eBzo zjOp}O>#I)ghboMw6j|cE1!Lapz?J_!js}&f%3kR&);5VTCkg8Jh^kV4%8r0iE`Mp6 zzeu&s#Qb3!&ir9NF{X3;T>8yI9TkllpyThba_zr>4T2n!9Yzz|cD9d;5GnK<1CteH z`-+bkieoz13}EPwXCsv*>96)VRj1;q@-e7Df3=S(-eu{pDL|HTIKl^^d3Y2iDWdq7 z^rsl=PVUzL!+pd#e&w(BKlDXW{kAQ}o(BbEI{mp^P|o>t`acK0<>pTuzEG#~g7b&> zLgn8CI!d{=5iiR256KC``Duj5>3<7g&b0>+tH( -#include -#include -#include -#include -#include - -#include "util.h" - -char *argv0; - -static void -verr(const char *fmt, va_list ap) -{ - vfprintf(stderr, fmt, ap); - - if (fmt[0] && fmt[strlen(fmt) - 1] == ':') { - fputc(' ', stderr); - perror(NULL); - } else { - fputc('\n', stderr); - } -} - -void -warn(const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - verr(fmt, ap); - va_end(ap); -} - -void -die(const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - verr(fmt, ap); - va_end(ap); - - exit(1); -} - -static int -evsnprintf(char *str, size_t size, const char *fmt, va_list ap) -{ - int ret; - - ret = vsnprintf(str, size, fmt, ap); - - if (ret < 0) { - warn("vsnprintf:"); - return -1; - } else if ((size_t)ret >= size) { - warn("vsnprintf: Output truncated"); - return -1; - } - - return ret; -} - -int -esnprintf(char *str, size_t size, const char *fmt, ...) -{ - va_list ap; - int ret; - - va_start(ap, fmt); - ret = evsnprintf(str, size, fmt, ap); - va_end(ap); - - return ret; -} - -const char * -bprintf(const char *fmt, ...) -{ - va_list ap; - int ret; - - va_start(ap, fmt); - ret = evsnprintf(buf, sizeof(buf), fmt, ap); - va_end(ap); - - return (ret < 0) ? NULL : buf; -} - -const char * -fmt_human(uintmax_t num, int base) -{ - double scaled; - size_t i, prefixlen; - const char **prefix; - const char *prefix_1000[] = { "", "k", "M", "G", "T", "P", "E", "Z", - "Y" }; - const char *prefix_1024[] = { "", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", - "Zi", "Yi" }; - - switch (base) { - case 1000: - prefix = prefix_1000; - prefixlen = LEN(prefix_1000); - break; - case 1024: - prefix = prefix_1024; - prefixlen = LEN(prefix_1024); - break; - default: - warn("fmt_human: Invalid base"); - return NULL; - } - - scaled = num; - for (i = 0; i < prefixlen && scaled >= base; i++) - scaled /= base; - - return bprintf("%.1f %s", scaled, prefix[i]); -} - -int -pscanf(const char *path, const char *fmt, ...) -{ - FILE *fp; - va_list ap; - int n; - - if (!(fp = fopen(path, "r"))) { - warn("fopen '%s':", path); - return -1; - } - va_start(ap, fmt); - n = vfscanf(fp, fmt, ap); - va_end(ap); - fclose(fp); - - return (n == EOF) ? -1 : n; -} diff --git a/suckless/slstatus/util.h b/suckless/slstatus/util.h deleted file mode 100644 index cf4b027..0000000 --- a/suckless/slstatus/util.h +++ /dev/null @@ -1,16 +0,0 @@ -/* See LICENSE file for copyright and license details. */ -#include - -extern char buf[1024]; - -#define LEN(x) (sizeof(x) / sizeof((x)[0])) - -extern char *argv0; - -void warn(const char *, ...); -void die(const char *, ...); - -int esnprintf(char *str, size_t size, const char *fmt, ...); -const char *bprintf(const char *fmt, ...); -const char *fmt_human(uintmax_t num, int base); -int pscanf(const char *path, const char *fmt, ...); diff --git a/suckless/slstatus/util.o b/suckless/slstatus/util.o deleted file mode 100644 index b5454d1ee1f21b726739ad8f08ae46c353362b57..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5592 zcmdUyZ){sv6~K?3v~}C<*&U-~+8;e>FEnX2FW$1Q&7hMs&LYtv>-Ih9z-Iyk} zd43KlidZ6-iYG5qBtYtiN$kTWhCow345_Q8)ggs35Tb}LWt!9uA(X0vZRv!nY{Q&$ z-?{e7#r}c-!I9p*_x$cT_y0ZDe!6d9Uoa2=B>~t2HBC`~mfLFOZdvSxFc@%HxU0hb zNVp%oPHv+3ZbXzmPX^1B%sc|3^bnPt`-OW&xQ-Q)6{3WtndzoVS7GY~6YD)%ycmg9 zj$I=Mf#nOEu;8gT!uPC-*>^8f4YtxI+##z&xC7R%0k_xc9>9_~U3MN0xA$6u;r0RR zc({GY%7xpXvu4mI-2Q?!FY}*R&&&K3YeD9(S!K*eMX9;94GRKWYl)S`+-d8oRR8=& zvlZfskeKVWOfreQ(Q7q#AYNYmd!-^u=rk&JcuhF#yvfX7q|q)N-tS)8@4k87Tc0;8 z!oA_u&&hTAc6ll+5|_m8x9ly#L$R_nDE_i?Y>DPQc;tU%=4#S%1(pG4et~8sN4sW& z{`1@N4sJ`!nr&G-xHEEFhUB)~E_YVj78>tiT-Qsok^jbtx*L1K^M&{29d*23hh{=o z{^^XZoy@DBR4SG7Iq4tnTN0)E^P;JECkE&BlI-l}t8{VkbbD(c-0xXu5x6U2ZrZ}* zEbr!x7fBmrO?upTadvgN39s#r*;N{&vz_il?P814Y1vTi(4V?)i#fd1*Vj=tDDYfw zSP|jvY5S*tke&aV31Dyb|92t5`V|zJJlabtU}NqNtQb@#e2yG7rnfEdGZ?-SQaEn*mpL?YS zL56nST|V~Y-Y1r@^nW6g`Ap7EXPi_Q)QaYp3r?=!n2ue@B;rnT6jBq;@K|9Yp6N38 zXC~w0=}~heo=-w+G?p@3^8hE|QRs&u7=%7}9FD?)G(4Jy{xl4wVK5DSX?Q#hN7GWxv zZBuo(YMj<9=(Cq=&ect@zGld!TiO0z?n16FGFo$}V}B3x%`&egw9jO}t%hW2yG+-^ z7c@?5NA@|5?__Rk{Bx*BG)8Jq1AeFhKiYr~H{dDcx8ZuKb(Cil*~td>bQbH4^BHa@ z&g(4CDzf9Y^}?7!sWv`?!2&+z_H`=9dhhkcx4w6fpBoci71 z<6rS{+B0Q;#Mch};!=D)HGo3>(%cn)*~k6kxsT5wRo~&WKf_!f|Dw;HimLtJYWxYT zBYDrqH=?fWKV(kr`^P^)0ENawf5w#k40C-vP4pn5kUhmfWxts@+27^kcl+#b@$qdw zd;fTz^l|zyNN7A;@Kg3lf+)oO=SMp6`d zV|_~FPq99u@i^<>(fBCq^BOKEb-lIh{lLl&JktT)kVWf5p{%Kf{iS ztM};sk3baTx0jEplARonN1f!915sHVjXQCO zj^y*GXGtNSSTqLFM0R2Vf8#{1-%C%cKCemzdJpIhc2|j4$Wf3$IY%3ULMrtWA_b+z%U}oQ z#5t@n1-QihzEmY%!PNB6qF%56HhOGO7N~I)>Yw`1`;Rfx`=86>k^GJOH>FlfbbpFJiq)*}4Wq}fj_9^@|H+iMsp`?f z{)1KG74-Q}BBnNV|1tJ&(>m1szmC53_V04U>#yu(a{uUEQ~v7w)a#pE=9M9DEd7R| oPhsUxZ>zrdh+v)`MU<;DttHxY -2012-09-13T07:00:36.081271045+02:00 - diff --git a/suckless/st/LICENSE b/suckless/st/LICENSE deleted file mode 100644 index 3cbf420..0000000 --- a/suckless/st/LICENSE +++ /dev/null @@ -1,34 +0,0 @@ -MIT/X Consortium License - -© 2014-2022 Hiltjo Posthuma -© 2018 Devin J. Pohly -© 2014-2017 Quentin Rameau -© 2009-2012 Aurélien APTEL -© 2008-2017 Anselm R Garbe -© 2012-2017 Roberto E. Vargas Caballero -© 2012-2016 Christoph Lohmann <20h at r-36 dot net> -© 2013 Eon S. Jeon -© 2013 Alexander Sedov -© 2013 Mark Edgar -© 2013-2014 Eric Pruitt -© 2013 Michael Forney -© 2013-2014 Markus Teich -© 2014-2015 Laslo Hunhold - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the "Software"), -to deal in the Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. diff --git a/suckless/st/Makefile b/suckless/st/Makefile deleted file mode 100644 index dfcea0f..0000000 --- a/suckless/st/Makefile +++ /dev/null @@ -1,52 +0,0 @@ -# st - simple terminal -# See LICENSE file for copyright and license details. -.POSIX: - -include config.mk - -SRC = st.c x.c hb.c -OBJ = $(SRC:.c=.o) - -all: st - -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 hb.h -hb.o: st.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 clean dist install uninstall diff --git a/suckless/st/README b/suckless/st/README deleted file mode 100644 index 6a846ed..0000000 --- a/suckless/st/README +++ /dev/null @@ -1,34 +0,0 @@ -st - simple terminal --------------------- -st is a simple terminal emulator for X which sucks less. - - -Requirements ------------- -In order to build st you need the Xlib header files. - - -Installation ------------- -Edit config.mk to match your local setup (st is installed into -the /usr/local namespace by default). - -Afterwards enter the following command to build and install st (if -necessary as root): - - make clean install - - -Running st ----------- -If you did not install st with make clean install, you must compile -the st terminfo entry with the following command: - - tic -sx st.info - -See the man page for additional details. - -Credits -------- -Based on Aurélien APTEL bt source code. - diff --git a/suckless/st/TODO b/suckless/st/TODO deleted file mode 100644 index 5f74cd5..0000000 --- a/suckless/st/TODO +++ /dev/null @@ -1,28 +0,0 @@ -vt emulation ------------- - -* double-height support - -code & interface ----------------- - -* add a simple way to do multiplexing - -drawing -------- -* add diacritics support to xdraws() - * switch to a suckless font drawing library -* make the font cache simpler -* add better support for brightening of the upper colors - -bugs ----- - -* fix shift up/down (shift selection in emacs) -* remove DEC test sequence when appropriate - -misc ----- - - $ grep -nE 'XXX|TODO' st.c - diff --git a/suckless/st/arg.h b/suckless/st/arg.h deleted file mode 100644 index a22e019..0000000 --- a/suckless/st/arg.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copy me if you can. - * by 20h - */ - -#ifndef ARG_H__ -#define ARG_H__ - -extern char *argv0; - -/* use main(int argc, char *argv[]) */ -#define ARGBEGIN for (argv0 = *argv, argv++, argc--;\ - argv[0] && argv[0][0] == '-'\ - && argv[0][1];\ - argc--, argv++) {\ - char argc_;\ - char **argv_;\ - int brk_;\ - if (argv[0][1] == '-' && argv[0][2] == '\0') {\ - argv++;\ - argc--;\ - break;\ - }\ - int i_;\ - for (i_ = 1, brk_ = 0, argv_ = argv;\ - argv[0][i_] && !brk_;\ - i_++) {\ - if (argv_ != argv)\ - break;\ - argc_ = argv[0][i_];\ - switch (argc_) - -#define ARGEND }\ - } - -#define ARGC() argc_ - -#define EARGF(x) ((argv[0][i_+1] == '\0' && argv[1] == NULL)?\ - ((x), abort(), (char *)0) :\ - (brk_ = 1, (argv[0][i_+1] != '\0')?\ - (&argv[0][i_+1]) :\ - (argc--, argv++, argv[0]))) - -#define ARGF() ((argv[0][i_+1] == '\0' && argv[1] == NULL)?\ - (char *)0 :\ - (brk_ = 1, (argv[0][i_+1] != '\0')?\ - (&argv[0][i_+1]) :\ - (argc--, argv++, argv[0]))) - -#endif diff --git a/suckless/st/boxdraw.c b/suckless/st/boxdraw.c deleted file mode 100644 index 28a92d0..0000000 --- a/suckless/st/boxdraw.c +++ /dev/null @@ -1,194 +0,0 @@ -/* - * Copyright 2018 Avi Halachmi (:avih) avihpit@yahoo.com https://github.com/avih - * MIT/X Consortium License - */ - -#include -#include "st.h" -#include "boxdraw_data.h" - -/* Rounded non-negative integers division of n / d */ -#define DIV(n, d) (((n) + (d) / 2) / (d)) - -static Display *xdpy; -static Colormap xcmap; -static XftDraw *xd; -static Visual *xvis; - -static void drawbox(int, int, int, int, XftColor *, XftColor *, ushort); -static void drawboxlines(int, int, int, int, XftColor *, ushort); - -/* public API */ - -void -boxdraw_xinit(Display *dpy, Colormap cmap, XftDraw *draw, Visual *vis) -{ - xdpy = dpy; xcmap = cmap; xd = draw, xvis = vis; -} - -int -isboxdraw(Rune u) -{ - Rune block = u & ~0xff; - return (boxdraw && block == 0x2500 && boxdata[(uint8_t)u]) || - (boxdraw_braille && block == 0x2800); -} - -/* the "index" is actually the entire shape data encoded as ushort */ -ushort -boxdrawindex(const Glyph *g) -{ - if (boxdraw_braille && (g->u & ~0xff) == 0x2800) - return BRL | (uint8_t)g->u; - if (boxdraw_bold && (g->mode & ATTR_BOLD)) - return BDB | boxdata[(uint8_t)g->u]; - return boxdata[(uint8_t)g->u]; -} - -void -drawboxes(int x, int y, int cw, int ch, XftColor *fg, XftColor *bg, - const XftGlyphFontSpec *specs, int len) -{ - for ( ; len-- > 0; x += cw, specs++) - drawbox(x, y, cw, ch, fg, bg, (ushort)specs->glyph); -} - -/* implementation */ - -void -drawbox(int x, int y, int w, int h, XftColor *fg, XftColor *bg, ushort bd) -{ - ushort cat = bd & ~(BDB | 0xff); /* mask out bold and data */ - if (bd & (BDL | BDA)) { - /* lines (light/double/heavy/arcs) */ - drawboxlines(x, y, w, h, fg, bd); - - } else if (cat == BBD) { - /* lower (8-X)/8 block */ - int d = DIV((uint8_t)bd * h, 8); - XftDrawRect(xd, fg, x, y + d, w, h - d); - - } else if (cat == BBU) { - /* upper X/8 block */ - XftDrawRect(xd, fg, x, y, w, DIV((uint8_t)bd * h, 8)); - - } else if (cat == BBL) { - /* left X/8 block */ - XftDrawRect(xd, fg, x, y, DIV((uint8_t)bd * w, 8), h); - - } else if (cat == BBR) { - /* right (8-X)/8 block */ - int d = DIV((uint8_t)bd * w, 8); - XftDrawRect(xd, fg, x + d, y, w - d, h); - - } else if (cat == BBQ) { - /* Quadrants */ - int w2 = DIV(w, 2), h2 = DIV(h, 2); - if (bd & TL) - XftDrawRect(xd, fg, x, y, w2, h2); - if (bd & TR) - XftDrawRect(xd, fg, x + w2, y, w - w2, h2); - if (bd & BL) - XftDrawRect(xd, fg, x, y + h2, w2, h - h2); - if (bd & BR) - XftDrawRect(xd, fg, x + w2, y + h2, w - w2, h - h2); - - } else if (bd & BBS) { - /* Shades - data is 1/2/3 for 25%/50%/75% alpha, respectively */ - int d = (uint8_t)bd; - XftColor xfc; - XRenderColor xrc = { .alpha = 0xffff }; - - xrc.red = DIV(fg->color.red * d + bg->color.red * (4 - d), 4); - xrc.green = DIV(fg->color.green * d + bg->color.green * (4 - d), 4); - xrc.blue = DIV(fg->color.blue * d + bg->color.blue * (4 - d), 4); - - XftColorAllocValue(xdpy, xvis, xcmap, &xrc, &xfc); - XftDrawRect(xd, &xfc, x, y, w, h); - XftColorFree(xdpy, xvis, xcmap, &xfc); - - } else if (cat == BRL) { - /* braille, each data bit corresponds to one dot at 2x4 grid */ - int w1 = DIV(w, 2); - int h1 = DIV(h, 4), h2 = DIV(h, 2), h3 = DIV(3 * h, 4); - - if (bd & 1) XftDrawRect(xd, fg, x, y, w1, h1); - if (bd & 2) XftDrawRect(xd, fg, x, y + h1, w1, h2 - h1); - if (bd & 4) XftDrawRect(xd, fg, x, y + h2, w1, h3 - h2); - if (bd & 8) XftDrawRect(xd, fg, x + w1, y, w - w1, h1); - if (bd & 16) XftDrawRect(xd, fg, x + w1, y + h1, w - w1, h2 - h1); - if (bd & 32) XftDrawRect(xd, fg, x + w1, y + h2, w - w1, h3 - h2); - if (bd & 64) XftDrawRect(xd, fg, x, y + h3, w1, h - h3); - if (bd & 128) XftDrawRect(xd, fg, x + w1, y + h3, w - w1, h - h3); - - } -} - -void -drawboxlines(int x, int y, int w, int h, XftColor *fg, ushort bd) -{ - /* s: stem thickness. width/8 roughly matches underscore thickness. */ - /* We draw bold as 1.5 * normal-stem and at least 1px thicker. */ - /* doubles draw at least 3px, even when w or h < 3. bold needs 6px. */ - int mwh = MIN(w, h); - int base_s = MAX(1, DIV(mwh, 8)); - int bold = (bd & BDB) && mwh >= 6; /* possibly ignore boldness */ - int s = bold ? MAX(base_s + 1, DIV(3 * base_s, 2)) : base_s; - int w2 = DIV(w - s, 2), h2 = DIV(h - s, 2); - /* the s-by-s square (x + w2, y + h2, s, s) is the center texel. */ - /* The base length (per direction till edge) includes this square. */ - - int light = bd & (LL | LU | LR | LD); - int double_ = bd & (DL | DU | DR | DD); - - if (light) { - /* d: additional (negative) length to not-draw the center */ - /* texel - at arcs and avoid drawing inside (some) doubles */ - int arc = bd & BDA; - int multi_light = light & (light - 1); - int multi_double = double_ & (double_ - 1); - /* light crosses double only at DH+LV, DV+LH (ref. shapes) */ - int d = arc || (multi_double && !multi_light) ? -s : 0; - - if (bd & LL) - XftDrawRect(xd, fg, x, y + h2, w2 + s + d, s); - if (bd & LU) - XftDrawRect(xd, fg, x + w2, y, s, h2 + s + d); - if (bd & LR) - XftDrawRect(xd, fg, x + w2 - d, y + h2, w - w2 + d, s); - if (bd & LD) - XftDrawRect(xd, fg, x + w2, y + h2 - d, s, h - h2 + d); - } - - /* double lines - also align with light to form heavy when combined */ - if (double_) { - /* - * going clockwise, for each double-ray: p is additional length - * to the single-ray nearer to the previous direction, and n to - * the next. p and n adjust from the base length to lengths - * which consider other doubles - shorter to avoid intersections - * (p, n), or longer to draw the far-corner texel (n). - */ - int dl = bd & DL, du = bd & DU, dr = bd & DR, dd = bd & DD; - if (dl) { - int p = dd ? -s : 0, n = du ? -s : dd ? s : 0; - XftDrawRect(xd, fg, x, y + h2 + s, w2 + s + p, s); - XftDrawRect(xd, fg, x, y + h2 - s, w2 + s + n, s); - } - if (du) { - int p = dl ? -s : 0, n = dr ? -s : dl ? s : 0; - XftDrawRect(xd, fg, x + w2 - s, y, s, h2 + s + p); - XftDrawRect(xd, fg, x + w2 + s, y, s, h2 + s + n); - } - if (dr) { - int p = du ? -s : 0, n = dd ? -s : du ? s : 0; - XftDrawRect(xd, fg, x + w2 - p, y + h2 - s, w - w2 + p, s); - XftDrawRect(xd, fg, x + w2 - n, y + h2 + s, w - w2 + n, s); - } - if (dd) { - int p = dr ? -s : 0, n = dl ? -s : dr ? s : 0; - XftDrawRect(xd, fg, x + w2 + s, y + h2 - p, s, h - h2 + p); - XftDrawRect(xd, fg, x + w2 - s, y + h2 - n, s, h - h2 + n); - } - } -} diff --git a/suckless/st/boxdraw_data.h b/suckless/st/boxdraw_data.h deleted file mode 100644 index 7890500..0000000 --- a/suckless/st/boxdraw_data.h +++ /dev/null @@ -1,214 +0,0 @@ -/* - * Copyright 2018 Avi Halachmi (:avih) avihpit@yahoo.com https://github.com/avih - * MIT/X Consortium License - */ - -/* - * U+25XX codepoints data - * - * References: - * http://www.unicode.org/charts/PDF/U2500.pdf - * http://www.unicode.org/charts/PDF/U2580.pdf - * - * Test page: - * https://github.com/GNOME/vte/blob/master/doc/boxes.txt - */ - -/* Each shape is encoded as 16-bits. Higher bits are category, lower are data */ -/* Categories (mutually exclusive except BDB): */ -/* For convenience, BDL/BDA/BBS/BDB are 1 bit each, the rest are enums */ -#define BDL (1<<8) /* Box Draw Lines (light/double/heavy) */ -#define BDA (1<<9) /* Box Draw Arc (light) */ - -#define BBD (1<<10) /* Box Block Down (lower) X/8 */ -#define BBL (2<<10) /* Box Block Left X/8 */ -#define BBU (3<<10) /* Box Block Upper X/8 */ -#define BBR (4<<10) /* Box Block Right X/8 */ -#define BBQ (5<<10) /* Box Block Quadrants */ -#define BRL (6<<10) /* Box Braille (data is lower byte of U28XX) */ - -#define BBS (1<<14) /* Box Block Shades */ -#define BDB (1<<15) /* Box Draw is Bold */ - -/* (BDL/BDA) Light/Double/Heavy x Left/Up/Right/Down/Horizontal/Vertical */ -/* Heavy is light+double (literally drawing light+double align to form heavy) */ -#define LL (1<<0) -#define LU (1<<1) -#define LR (1<<2) -#define LD (1<<3) -#define LH (LL+LR) -#define LV (LU+LD) - -#define DL (1<<4) -#define DU (1<<5) -#define DR (1<<6) -#define DD (1<<7) -#define DH (DL+DR) -#define DV (DU+DD) - -#define HL (LL+DL) -#define HU (LU+DU) -#define HR (LR+DR) -#define HD (LD+DD) -#define HH (HL+HR) -#define HV (HU+HD) - -/* (BBQ) Quadrants Top/Bottom x Left/Right */ -#define TL (1<<0) -#define TR (1<<1) -#define BL (1<<2) -#define BR (1<<3) - -/* Data for U+2500 - U+259F except dashes/diagonals */ -static const unsigned short boxdata[256] = { - /* light lines */ - [0x00] = BDL + LH, /* light horizontal */ - [0x02] = BDL + LV, /* light vertical */ - [0x0c] = BDL + LD + LR, /* light down and right */ - [0x10] = BDL + LD + LL, /* light down and left */ - [0x14] = BDL + LU + LR, /* light up and right */ - [0x18] = BDL + LU + LL, /* light up and left */ - [0x1c] = BDL + LV + LR, /* light vertical and right */ - [0x24] = BDL + LV + LL, /* light vertical and left */ - [0x2c] = BDL + LH + LD, /* light horizontal and down */ - [0x34] = BDL + LH + LU, /* light horizontal and up */ - [0x3c] = BDL + LV + LH, /* light vertical and horizontal */ - [0x74] = BDL + LL, /* light left */ - [0x75] = BDL + LU, /* light up */ - [0x76] = BDL + LR, /* light right */ - [0x77] = BDL + LD, /* light down */ - - /* heavy [+light] lines */ - [0x01] = BDL + HH, - [0x03] = BDL + HV, - [0x0d] = BDL + HR + LD, - [0x0e] = BDL + HD + LR, - [0x0f] = BDL + HD + HR, - [0x11] = BDL + HL + LD, - [0x12] = BDL + HD + LL, - [0x13] = BDL + HD + HL, - [0x15] = BDL + HR + LU, - [0x16] = BDL + HU + LR, - [0x17] = BDL + HU + HR, - [0x19] = BDL + HL + LU, - [0x1a] = BDL + HU + LL, - [0x1b] = BDL + HU + HL, - [0x1d] = BDL + HR + LV, - [0x1e] = BDL + HU + LD + LR, - [0x1f] = BDL + HD + LR + LU, - [0x20] = BDL + HV + LR, - [0x21] = BDL + HU + HR + LD, - [0x22] = BDL + HD + HR + LU, - [0x23] = BDL + HV + HR, - [0x25] = BDL + HL + LV, - [0x26] = BDL + HU + LD + LL, - [0x27] = BDL + HD + LU + LL, - [0x28] = BDL + HV + LL, - [0x29] = BDL + HU + HL + LD, - [0x2a] = BDL + HD + HL + LU, - [0x2b] = BDL + HV + HL, - [0x2d] = BDL + HL + LD + LR, - [0x2e] = BDL + HR + LL + LD, - [0x2f] = BDL + HH + LD, - [0x30] = BDL + HD + LH, - [0x31] = BDL + HD + HL + LR, - [0x32] = BDL + HR + HD + LL, - [0x33] = BDL + HH + HD, - [0x35] = BDL + HL + LU + LR, - [0x36] = BDL + HR + LU + LL, - [0x37] = BDL + HH + LU, - [0x38] = BDL + HU + LH, - [0x39] = BDL + HU + HL + LR, - [0x3a] = BDL + HU + HR + LL, - [0x3b] = BDL + HH + HU, - [0x3d] = BDL + HL + LV + LR, - [0x3e] = BDL + HR + LV + LL, - [0x3f] = BDL + HH + LV, - [0x40] = BDL + HU + LH + LD, - [0x41] = BDL + HD + LH + LU, - [0x42] = BDL + HV + LH, - [0x43] = BDL + HU + HL + LD + LR, - [0x44] = BDL + HU + HR + LD + LL, - [0x45] = BDL + HD + HL + LU + LR, - [0x46] = BDL + HD + HR + LU + LL, - [0x47] = BDL + HH + HU + LD, - [0x48] = BDL + HH + HD + LU, - [0x49] = BDL + HV + HL + LR, - [0x4a] = BDL + HV + HR + LL, - [0x4b] = BDL + HV + HH, - [0x78] = BDL + HL, - [0x79] = BDL + HU, - [0x7a] = BDL + HR, - [0x7b] = BDL + HD, - [0x7c] = BDL + HR + LL, - [0x7d] = BDL + HD + LU, - [0x7e] = BDL + HL + LR, - [0x7f] = BDL + HU + LD, - - /* double [+light] lines */ - [0x50] = BDL + DH, - [0x51] = BDL + DV, - [0x52] = BDL + DR + LD, - [0x53] = BDL + DD + LR, - [0x54] = BDL + DR + DD, - [0x55] = BDL + DL + LD, - [0x56] = BDL + DD + LL, - [0x57] = BDL + DL + DD, - [0x58] = BDL + DR + LU, - [0x59] = BDL + DU + LR, - [0x5a] = BDL + DU + DR, - [0x5b] = BDL + DL + LU, - [0x5c] = BDL + DU + LL, - [0x5d] = BDL + DL + DU, - [0x5e] = BDL + DR + LV, - [0x5f] = BDL + DV + LR, - [0x60] = BDL + DV + DR, - [0x61] = BDL + DL + LV, - [0x62] = BDL + DV + LL, - [0x63] = BDL + DV + DL, - [0x64] = BDL + DH + LD, - [0x65] = BDL + DD + LH, - [0x66] = BDL + DD + DH, - [0x67] = BDL + DH + LU, - [0x68] = BDL + DU + LH, - [0x69] = BDL + DH + DU, - [0x6a] = BDL + DH + LV, - [0x6b] = BDL + DV + LH, - [0x6c] = BDL + DH + DV, - - /* (light) arcs */ - [0x6d] = BDA + LD + LR, - [0x6e] = BDA + LD + LL, - [0x6f] = BDA + LU + LL, - [0x70] = BDA + LU + LR, - - /* Lower (Down) X/8 block (data is 8 - X) */ - [0x81] = BBD + 7, [0x82] = BBD + 6, [0x83] = BBD + 5, [0x84] = BBD + 4, - [0x85] = BBD + 3, [0x86] = BBD + 2, [0x87] = BBD + 1, [0x88] = BBD + 0, - - /* Left X/8 block (data is X) */ - [0x89] = BBL + 7, [0x8a] = BBL + 6, [0x8b] = BBL + 5, [0x8c] = BBL + 4, - [0x8d] = BBL + 3, [0x8e] = BBL + 2, [0x8f] = BBL + 1, - - /* upper 1/2 (4/8), 1/8 block (X), right 1/2, 1/8 block (8-X) */ - [0x80] = BBU + 4, [0x94] = BBU + 1, - [0x90] = BBR + 4, [0x95] = BBR + 7, - - /* Quadrants */ - [0x96] = BBQ + BL, - [0x97] = BBQ + BR, - [0x98] = BBQ + TL, - [0x99] = BBQ + TL + BL + BR, - [0x9a] = BBQ + TL + BR, - [0x9b] = BBQ + TL + TR + BL, - [0x9c] = BBQ + TL + TR + BR, - [0x9d] = BBQ + TR, - [0x9e] = BBQ + BL + TR, - [0x9f] = BBQ + BL + TR + BR, - - /* Shades, data is an alpha value in 25% units (1/4, 1/2, 3/4) */ - [0x91] = BBS + 1, [0x92] = BBS + 2, [0x93] = BBS + 3, - - /* U+2504 - U+250B, U+254C - U+254F: unsupported (dashes) */ - /* U+2571 - U+2573: unsupported (diagonals) */ -}; diff --git a/suckless/st/config.def.h b/suckless/st/config.def.h deleted file mode 100644 index e3c30ed..0000000 --- a/suckless/st/config.def.h +++ /dev/null @@ -1,517 +0,0 @@ -/* See LICENSE file for copyright and license details. */ - -/* - * appearance - * - * font: see http://freedesktop.org/software/fontconfig/fontconfig-user.html - */ -static const char *font = "CaskaydiaMonoNerdFontMono-Bold:size=14:style=Bold"; -/* Spare fonts */ - -static char *font2[] = { - "CaskaydiaMonoNerdFontMono-Bold:pixelsize=12:antialias=true:autohint=true"}; -static int borderpx = 6; - -/* How to align the content in the window when the size of the terminal - * doesn't perfectly match the size of the window. The values are percentages. - * 50 means center, 0 means flush left/top, 100 means flush right/bottom. - */ -static int anysize_halign = 50; -static int anysize_valign = 50; - -/* - * 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 */ -/* By default, use the same one as kitty. */ - -char *vtiden = "\033[?62c"; -//char *vtiden = "\x1b[?62;4c"; - -/* Kerning / character bounding-box multipliers */ -static float cwscale = 1; -static float chscale = 1; - -/* - * 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 = 1; -static double maxlatency = 10; - -/* - * blinking timeout (set to 0 to disable blinking) for the terminal blinking - * attribute. - */ -static unsigned int blinktimeout = 100; - -/* - * thickness of underline and bar cursors - */ -static unsigned int cursorthickness = 2; - -/* - * 1: render most of the lines/blocks characters without using the font for - * perfect alignment between cells (U2500 - U259F except dashes/diagonals). - * Bold affects lines thickness if boxdraw_bold is not 0. Italic is ignored. - * 0: disable (render all U25XX glyphs normally from the font). - */ -const int boxdraw = 1; -const int boxdraw_bold = 1; - -/* braille (U28XX): 1: render as adjacent "pixels", 0: use font */ -const int boxdraw_braille = 0; - -/* - * 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"; - -/* - * spaces per tab - * - * When you are changing this value, don't forget to adapt the »it« value in - * the st.info and appropriately install the st.info in the environment where - * you use this st version. - * - * it#$tabspaces, - * - * Secondly make sure your kernel is not expanding tabs. When running `stty - * -a` »tab0« should appear. You can tell the terminal to not expand tabs by - * running following command: - * - * stty tabs - */ -unsigned int tabspaces = 8; - -/* Terminal colors (16 first used in escape sequence) */ -static const char *colorname[] = { - /* 8 normal colors */ - "black", "red3", "green3", "yellow3", "blue2", "magenta3", "cyan3", - "gray90", - - /* 8 bright colors */ - "gray50", "red", "green", "yellow", "#5c5cff", "magenta", "cyan", "white", - - [255] = 0, - - /* more colors can be added after 255 to use with DefaultXX */ - "#cccccc", "#555555", "gray90", /* default foreground colour */ - "black", /* default background colour */ -}; - -/* - * Default colors (colorname index) - * foreground, background, cursor, reverse cursor - */ -unsigned int defaultfg = 258; -unsigned int defaultbg = 259; -unsigned int defaultcs = 256; -static unsigned int defaultrcs = 257; - -/* - * Default shape of cursor - * 2: Block ("█") - * 4: Underline ("_") - * 6: Bar ("|") - * 7: Snowman ("☃") - */ -static unsigned int cursorshape = 2; - -/* - * Default columns and rows numbers - */ - -static unsigned int cols = 80; -static unsigned int rows = 24; - -/* - * Default colour and shape of the mouse cursor - */ -static unsigned int mouseshape = XC_xterm; -static unsigned int mousefg = 7; -static unsigned int mousebg = 0; - -/* - * Color used to display font attributes when fontconfig selected a font which - * doesn't match the ones requested. - */ -static unsigned int defaultattr = 11; - -/* - * Graphics configuration - */ - -/// The template for the cache directory. -const char graphics_cache_dir_template[] = "/tmp/st-images-XXXXXX"; -/// The max size of a single image file, in bytes. -unsigned graphics_max_single_image_file_size = 20 * 1024 * 1024; -/// The max size of the cache, in bytes. -unsigned graphics_total_file_cache_size = 300 * 1024 * 1024; -/// The max ram size of an image or placement, in bytes. -unsigned graphics_max_single_image_ram_size = 100 * 1024 * 1024; -/// The max total size of all images loaded into RAM. -unsigned graphics_max_total_ram_size = 300 * 1024 * 1024; -/// The max total number of image placements and images. -unsigned graphics_max_total_placements = 4096; -/// The ratio by which limits can be exceeded. This is to reduce the frequency -/// of image removal. -double graphics_excess_tolerance_ratio = 0.05; -/// The minimum delay between redraws caused by animations, in milliseconds. -unsigned graphics_animation_min_delay = 20; - -/* - * Force mouse select/shortcuts while mask is active (when MODE_MOUSE is set). - * Note that if you want to use ShiftMask with selmasks, set this to an other - * modifier, set to 0 to not use it. - */ -static uint forcemousemod = ShiftMask; - -/* Internal keyboard shortcuts. */ -#define MODKEY Mod1Mask -#define TERMMOD (ControlMask | ShiftMask) - -/* - * Internal mouse shortcuts. - * Beware that overloading Button1 will disable the selection. - */ -static MouseShortcut mshortcuts[] = { - /* mask button function argument release */ - {TERMMOD, Button3, previewimage, {.s = "feh"}}, - {TERMMOD, Button2, showimageinfo, {}, 1}, - {XK_ANY_MOD, Button2, selpaste, {.i = 0}, 1}, - {ShiftMask, Button4, kscrollup, {.i = 1}}, - {ShiftMask, Button5, kscrolldown, {.i = 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. */ - -static Shortcut shortcuts[] = { - /* mask keysym function argument */ - {TERMMOD, XK_F1, togglegrdebug, {.i = 0}}, - {TERMMOD, XK_F6, dumpgrstate, {.i = 0}}, - {TERMMOD, XK_F7, unloadimages, {.i = 0}}, - {TERMMOD, XK_F8, toggleimages, {.i = 0}}, - {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_C, clipcopy, {.i = 0}}, - {TERMMOD, XK_V, clippaste, {.i = 0}}, - {TERMMOD, XK_Y, selpaste, {.i = 0}}, - {ShiftMask, XK_Page_Up, kscrollup, {.i = -1}}, - {ShiftMask, XK_Page_Down, kscrolldown, {.i = -1}}, - {ShiftMask, XK_Insert, selpaste, {.i = 0}}, - {TERMMOD, XK_Num_Lock, numlock, {.i = 0}}, - {TERMMOD, XK_plus, zoom, {.f = +1}}, - {TERMMOD, XK_underscore, zoom, {.f = -1}}, - {TERMMOD, XK_equal, zoomreset, {0}}, -}; - -/* - * Special keys (change & recompile st.info accordingly) - * - * Mask value: - * * Use XK_ANY_MOD to match the key no matter modifiers state - * * Use XK_NO_MOD to match the key alone (no modifiers) - * appkey value: - * * 0: no value - * * > 0: keypad application mode enabled - * * = 2: term.numlock = 1 - * * < 0: keypad application mode disabled - * appcursor value: - * * 0: no value - * * > 0: cursor application mode enabled - * * < 0: cursor application mode disabled - * - * Be careful with the order of the definitions because st searches in - * this table sequentially, so any XK_ANY_MOD must be in the last - * position for a key. - */ - -/* - * If you want keys other than the X11 function keys (0xFD00 - 0xFFFF) - * to be mapped below, add them to this array. - */ -static KeySym mappedkeys[] = {-1}; - -/* - * State bits to ignore when matching key or button events. By default, - * numlock (Mod2Mask) and keyboard layout (XK_SWITCH_MOD) are ignored. - */ -static uint ignoremod = Mod2Mask | XK_SWITCH_MOD; - -/* - * This is the huge key array which defines all compatibility to the Linux - * world. Please decide about changes wisely. - */ -static Key key[] = { - /* keysym mask string appkey appcursor */ - {XK_KP_Home, ShiftMask, "\033[2J", 0, -1}, - {XK_KP_Home, ShiftMask, "\033[1;2H", 0, +1}, - {XK_KP_Home, XK_ANY_MOD, "\033[H", 0, -1}, - {XK_KP_Home, XK_ANY_MOD, "\033[1~", 0, +1}, - {XK_KP_Up, XK_ANY_MOD, "\033Ox", +1, 0}, - {XK_KP_Up, XK_ANY_MOD, "\033[A", 0, -1}, - {XK_KP_Up, XK_ANY_MOD, "\033OA", 0, +1}, - {XK_KP_Down, XK_ANY_MOD, "\033Or", +1, 0}, - {XK_KP_Down, XK_ANY_MOD, "\033[B", 0, -1}, - {XK_KP_Down, XK_ANY_MOD, "\033OB", 0, +1}, - {XK_KP_Left, XK_ANY_MOD, "\033Ot", +1, 0}, - {XK_KP_Left, XK_ANY_MOD, "\033[D", 0, -1}, - {XK_KP_Left, XK_ANY_MOD, "\033OD", 0, +1}, - {XK_KP_Right, XK_ANY_MOD, "\033Ov", +1, 0}, - {XK_KP_Right, XK_ANY_MOD, "\033[C", 0, -1}, - {XK_KP_Right, XK_ANY_MOD, "\033OC", 0, +1}, - {XK_KP_Prior, ShiftMask, "\033[5;2~", 0, 0}, - {XK_KP_Prior, XK_ANY_MOD, "\033[5~", 0, 0}, - {XK_KP_Begin, XK_ANY_MOD, "\033[E", 0, 0}, - {XK_KP_End, ControlMask, "\033[J", -1, 0}, - {XK_KP_End, ControlMask, "\033[1;5F", +1, 0}, - {XK_KP_End, ShiftMask, "\033[K", -1, 0}, - {XK_KP_End, ShiftMask, "\033[1;2F", +1, 0}, - {XK_KP_End, XK_ANY_MOD, "\033[4~", 0, 0}, - {XK_KP_Next, ShiftMask, "\033[6;2~", 0, 0}, - {XK_KP_Next, XK_ANY_MOD, "\033[6~", 0, 0}, - {XK_KP_Insert, ShiftMask, "\033[2;2~", +1, 0}, - {XK_KP_Insert, ShiftMask, "\033[4l", -1, 0}, - {XK_KP_Insert, ControlMask, "\033[L", -1, 0}, - {XK_KP_Insert, ControlMask, "\033[2;5~", +1, 0}, - {XK_KP_Insert, XK_ANY_MOD, "\033[4h", -1, 0}, - {XK_KP_Insert, XK_ANY_MOD, "\033[2~", +1, 0}, - {XK_KP_Delete, ControlMask, "\033[M", -1, 0}, - {XK_KP_Delete, ControlMask, "\033[3;5~", +1, 0}, - {XK_KP_Delete, ShiftMask, "\033[2K", -1, 0}, - {XK_KP_Delete, ShiftMask, "\033[3;2~", +1, 0}, - {XK_KP_Delete, XK_ANY_MOD, "\033[P", -1, 0}, - {XK_KP_Delete, XK_ANY_MOD, "\033[3~", +1, 0}, - {XK_KP_Multiply, XK_ANY_MOD, "\033Oj", +2, 0}, - {XK_KP_Add, XK_ANY_MOD, "\033Ok", +2, 0}, - {XK_KP_Enter, XK_ANY_MOD, "\033OM", +2, 0}, - {XK_KP_Enter, XK_ANY_MOD, "\r", -1, 0}, - {XK_KP_Subtract, XK_ANY_MOD, "\033Om", +2, 0}, - {XK_KP_Decimal, XK_ANY_MOD, "\033On", +2, 0}, - {XK_KP_Divide, XK_ANY_MOD, "\033Oo", +2, 0}, - {XK_KP_0, XK_ANY_MOD, "\033Op", +2, 0}, - {XK_KP_1, XK_ANY_MOD, "\033Oq", +2, 0}, - {XK_KP_2, XK_ANY_MOD, "\033Or", +2, 0}, - {XK_KP_3, XK_ANY_MOD, "\033Os", +2, 0}, - {XK_KP_4, XK_ANY_MOD, "\033Ot", +2, 0}, - {XK_KP_5, XK_ANY_MOD, "\033Ou", +2, 0}, - {XK_KP_6, XK_ANY_MOD, "\033Ov", +2, 0}, - {XK_KP_7, XK_ANY_MOD, "\033Ow", +2, 0}, - {XK_KP_8, XK_ANY_MOD, "\033Ox", +2, 0}, - {XK_KP_9, XK_ANY_MOD, "\033Oy", +2, 0}, - {XK_Up, ShiftMask, "\033[1;2A", 0, 0}, - {XK_Up, Mod1Mask, "\033[1;3A", 0, 0}, - {XK_Up, ShiftMask | Mod1Mask, "\033[1;4A", 0, 0}, - {XK_Up, ControlMask, "\033[1;5A", 0, 0}, - {XK_Up, ShiftMask | ControlMask, "\033[1;6A", 0, 0}, - {XK_Up, ControlMask | Mod1Mask, "\033[1;7A", 0, 0}, - {XK_Up, ShiftMask | ControlMask | Mod1Mask, "\033[1;8A", 0, 0}, - {XK_Up, XK_ANY_MOD, "\033[A", 0, -1}, - {XK_Up, XK_ANY_MOD, "\033OA", 0, +1}, - {XK_Down, ShiftMask, "\033[1;2B", 0, 0}, - {XK_Down, Mod1Mask, "\033[1;3B", 0, 0}, - {XK_Down, ShiftMask | Mod1Mask, "\033[1;4B", 0, 0}, - {XK_Down, ControlMask, "\033[1;5B", 0, 0}, - {XK_Down, ShiftMask | ControlMask, "\033[1;6B", 0, 0}, - {XK_Down, ControlMask | Mod1Mask, "\033[1;7B", 0, 0}, - {XK_Down, ShiftMask | ControlMask | Mod1Mask, "\033[1;8B", 0, 0}, - {XK_Down, XK_ANY_MOD, "\033[B", 0, -1}, - {XK_Down, XK_ANY_MOD, "\033OB", 0, +1}, - {XK_Left, ShiftMask, "\033[1;2D", 0, 0}, - {XK_Left, Mod1Mask, "\033[1;3D", 0, 0}, - {XK_Left, ShiftMask | Mod1Mask, "\033[1;4D", 0, 0}, - {XK_Left, ControlMask, "\033[1;5D", 0, 0}, - {XK_Left, ShiftMask | ControlMask, "\033[1;6D", 0, 0}, - {XK_Left, ControlMask | Mod1Mask, "\033[1;7D", 0, 0}, - {XK_Left, ShiftMask | ControlMask | Mod1Mask, "\033[1;8D", 0, 0}, - {XK_Left, XK_ANY_MOD, "\033[D", 0, -1}, - {XK_Left, XK_ANY_MOD, "\033OD", 0, +1}, - {XK_Right, ShiftMask, "\033[1;2C", 0, 0}, - {XK_Right, Mod1Mask, "\033[1;3C", 0, 0}, - {XK_Right, ShiftMask | Mod1Mask, "\033[1;4C", 0, 0}, - {XK_Right, ControlMask, "\033[1;5C", 0, 0}, - {XK_Right, ShiftMask | ControlMask, "\033[1;6C", 0, 0}, - {XK_Right, ControlMask | Mod1Mask, "\033[1;7C", 0, 0}, - {XK_Right, ShiftMask | ControlMask | Mod1Mask, "\033[1;8C", 0, 0}, - {XK_Right, XK_ANY_MOD, "\033[C", 0, -1}, - {XK_Right, XK_ANY_MOD, "\033OC", 0, +1}, - {XK_ISO_Left_Tab, ShiftMask, "\033[Z", 0, 0}, - {XK_Return, Mod1Mask, "\033\r", 0, 0}, - {XK_Return, XK_ANY_MOD, "\r", 0, 0}, - {XK_Insert, ShiftMask, "\033[4l", -1, 0}, - {XK_Insert, ShiftMask, "\033[2;2~", +1, 0}, - {XK_Insert, ControlMask, "\033[L", -1, 0}, - {XK_Insert, ControlMask, "\033[2;5~", +1, 0}, - {XK_Insert, XK_ANY_MOD, "\033[4h", -1, 0}, - {XK_Insert, XK_ANY_MOD, "\033[2~", +1, 0}, - {XK_Delete, ControlMask, "\033[M", -1, 0}, - {XK_Delete, ControlMask, "\033[3;5~", +1, 0}, - {XK_Delete, ShiftMask, "\033[2K", -1, 0}, - {XK_Delete, ShiftMask, "\033[3;2~", +1, 0}, - {XK_Delete, XK_ANY_MOD, "\033[P", -1, 0}, - {XK_Delete, XK_ANY_MOD, "\033[3~", +1, 0}, - {XK_BackSpace, XK_NO_MOD, "\177", 0, 0}, - {XK_BackSpace, Mod1Mask, "\033\177", 0, 0}, - {XK_Home, ShiftMask, "\033[2J", 0, -1}, - {XK_Home, ShiftMask, "\033[1;2H", 0, +1}, - {XK_Home, XK_ANY_MOD, "\033[H", 0, -1}, - {XK_Home, XK_ANY_MOD, "\033[1~", 0, +1}, - {XK_End, ControlMask, "\033[J", -1, 0}, - {XK_End, ControlMask, "\033[1;5F", +1, 0}, - {XK_End, ShiftMask, "\033[K", -1, 0}, - {XK_End, ShiftMask, "\033[1;2F", +1, 0}, - {XK_End, XK_ANY_MOD, "\033[4~", 0, 0}, - {XK_Prior, ControlMask, "\033[5;5~", 0, 0}, - {XK_Prior, ShiftMask, "\033[5;2~", 0, 0}, - {XK_Prior, XK_ANY_MOD, "\033[5~", 0, 0}, - {XK_Next, ControlMask, "\033[6;5~", 0, 0}, - {XK_Next, ShiftMask, "\033[6;2~", 0, 0}, - {XK_Next, XK_ANY_MOD, "\033[6~", 0, 0}, - {XK_F1, XK_NO_MOD, "\033OP", 0, 0}, - {XK_F1, /* F13 */ ShiftMask, "\033[1;2P", 0, 0}, - {XK_F1, /* F25 */ ControlMask, "\033[1;5P", 0, 0}, - {XK_F1, /* F37 */ Mod4Mask, "\033[1;6P", 0, 0}, - {XK_F1, /* F49 */ Mod1Mask, "\033[1;3P", 0, 0}, - {XK_F1, /* F61 */ Mod3Mask, "\033[1;4P", 0, 0}, - {XK_F2, XK_NO_MOD, "\033OQ", 0, 0}, - {XK_F2, /* F14 */ ShiftMask, "\033[1;2Q", 0, 0}, - {XK_F2, /* F26 */ ControlMask, "\033[1;5Q", 0, 0}, - {XK_F2, /* F38 */ Mod4Mask, "\033[1;6Q", 0, 0}, - {XK_F2, /* F50 */ Mod1Mask, "\033[1;3Q", 0, 0}, - {XK_F2, /* F62 */ Mod3Mask, "\033[1;4Q", 0, 0}, - {XK_F3, XK_NO_MOD, "\033OR", 0, 0}, - {XK_F3, /* F15 */ ShiftMask, "\033[1;2R", 0, 0}, - {XK_F3, /* F27 */ ControlMask, "\033[1;5R", 0, 0}, - {XK_F3, /* F39 */ Mod4Mask, "\033[1;6R", 0, 0}, - {XK_F3, /* F51 */ Mod1Mask, "\033[1;3R", 0, 0}, - {XK_F3, /* F63 */ Mod3Mask, "\033[1;4R", 0, 0}, - {XK_F4, XK_NO_MOD, "\033OS", 0, 0}, - {XK_F4, /* F16 */ ShiftMask, "\033[1;2S", 0, 0}, - {XK_F4, /* F28 */ ControlMask, "\033[1;5S", 0, 0}, - {XK_F4, /* F40 */ Mod4Mask, "\033[1;6S", 0, 0}, - {XK_F4, /* F52 */ Mod1Mask, "\033[1;3S", 0, 0}, - {XK_F5, XK_NO_MOD, "\033[15~", 0, 0}, - {XK_F5, /* F17 */ ShiftMask, "\033[15;2~", 0, 0}, - {XK_F5, /* F29 */ ControlMask, "\033[15;5~", 0, 0}, - {XK_F5, /* F41 */ Mod4Mask, "\033[15;6~", 0, 0}, - {XK_F5, /* F53 */ Mod1Mask, "\033[15;3~", 0, 0}, - {XK_F6, XK_NO_MOD, "\033[17~", 0, 0}, - {XK_F6, /* F18 */ ShiftMask, "\033[17;2~", 0, 0}, - {XK_F6, /* F30 */ ControlMask, "\033[17;5~", 0, 0}, - {XK_F6, /* F42 */ Mod4Mask, "\033[17;6~", 0, 0}, - {XK_F6, /* F54 */ Mod1Mask, "\033[17;3~", 0, 0}, - {XK_F7, XK_NO_MOD, "\033[18~", 0, 0}, - {XK_F7, /* F19 */ ShiftMask, "\033[18;2~", 0, 0}, - {XK_F7, /* F31 */ ControlMask, "\033[18;5~", 0, 0}, - {XK_F7, /* F43 */ Mod4Mask, "\033[18;6~", 0, 0}, - {XK_F7, /* F55 */ Mod1Mask, "\033[18;3~", 0, 0}, - {XK_F8, XK_NO_MOD, "\033[19~", 0, 0}, - {XK_F8, /* F20 */ ShiftMask, "\033[19;2~", 0, 0}, - {XK_F8, /* F32 */ ControlMask, "\033[19;5~", 0, 0}, - {XK_F8, /* F44 */ Mod4Mask, "\033[19;6~", 0, 0}, - {XK_F8, /* F56 */ Mod1Mask, "\033[19;3~", 0, 0}, - {XK_F9, XK_NO_MOD, "\033[20~", 0, 0}, - {XK_F9, /* F21 */ ShiftMask, "\033[20;2~", 0, 0}, - {XK_F9, /* F33 */ ControlMask, "\033[20;5~", 0, 0}, - {XK_F9, /* F45 */ Mod4Mask, "\033[20;6~", 0, 0}, - {XK_F9, /* F57 */ Mod1Mask, "\033[20;3~", 0, 0}, - {XK_F10, XK_NO_MOD, "\033[21~", 0, 0}, - {XK_F10, /* F22 */ ShiftMask, "\033[21;2~", 0, 0}, - {XK_F10, /* F34 */ ControlMask, "\033[21;5~", 0, 0}, - {XK_F10, /* F46 */ Mod4Mask, "\033[21;6~", 0, 0}, - {XK_F10, /* F58 */ Mod1Mask, "\033[21;3~", 0, 0}, - {XK_F11, XK_NO_MOD, "\033[23~", 0, 0}, - {XK_F11, /* F23 */ ShiftMask, "\033[23;2~", 0, 0}, - {XK_F11, /* F35 */ ControlMask, "\033[23;5~", 0, 0}, - {XK_F11, /* F47 */ Mod4Mask, "\033[23;6~", 0, 0}, - {XK_F11, /* F59 */ Mod1Mask, "\033[23;3~", 0, 0}, - {XK_F12, XK_NO_MOD, "\033[24~", 0, 0}, - {XK_F12, /* F24 */ ShiftMask, "\033[24;2~", 0, 0}, - {XK_F12, /* F36 */ ControlMask, "\033[24;5~", 0, 0}, - {XK_F12, /* F48 */ Mod4Mask, "\033[24;6~", 0, 0}, - {XK_F12, /* F60 */ Mod1Mask, "\033[24;3~", 0, 0}, - {XK_F13, XK_NO_MOD, "\033[1;2P", 0, 0}, - {XK_F14, XK_NO_MOD, "\033[1;2Q", 0, 0}, - {XK_F15, XK_NO_MOD, "\033[1;2R", 0, 0}, - {XK_F16, XK_NO_MOD, "\033[1;2S", 0, 0}, - {XK_F17, XK_NO_MOD, "\033[15;2~", 0, 0}, - {XK_F18, XK_NO_MOD, "\033[17;2~", 0, 0}, - {XK_F19, XK_NO_MOD, "\033[18;2~", 0, 0}, - {XK_F20, XK_NO_MOD, "\033[19;2~", 0, 0}, - {XK_F21, XK_NO_MOD, "\033[20;2~", 0, 0}, - {XK_F22, XK_NO_MOD, "\033[21;2~", 0, 0}, - {XK_F23, XK_NO_MOD, "\033[23;2~", 0, 0}, - {XK_F24, XK_NO_MOD, "\033[24;2~", 0, 0}, - {XK_F25, XK_NO_MOD, "\033[1;5P", 0, 0}, - {XK_F26, XK_NO_MOD, "\033[1;5Q", 0, 0}, - {XK_F27, XK_NO_MOD, "\033[1;5R", 0, 0}, - {XK_F28, XK_NO_MOD, "\033[1;5S", 0, 0}, - {XK_F29, XK_NO_MOD, "\033[15;5~", 0, 0}, - {XK_F30, XK_NO_MOD, "\033[17;5~", 0, 0}, - {XK_F31, XK_NO_MOD, "\033[18;5~", 0, 0}, - {XK_F32, XK_NO_MOD, "\033[19;5~", 0, 0}, - {XK_F33, XK_NO_MOD, "\033[20;5~", 0, 0}, - {XK_F34, XK_NO_MOD, "\033[21;5~", 0, 0}, - {XK_F35, XK_NO_MOD, "\033[23;5~", 0, 0}, -}; - -/* - * Selection types' masks. - * Use the same masks as usual. - * Button1Mask is always unset, to make masks match between ButtonPress. - * ButtonRelease and MotionNotify. - * If no match is found, regular selection is used. - */ -static uint selmasks[] = { - [SEL_RECTANGULAR] = Mod1Mask, -}; - -/* - * Printable characters in ASCII, used to estimate the advance width - * of single wide characters. - */ -static char ascii_printable[] = " !\"#$%&'()*+,-./0123456789:;<=>?" - "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_" - "`abcdefghijklmnopqrstuvwxyz{|}~"; diff --git a/suckless/st/config.h b/suckless/st/config.h deleted file mode 100644 index 7c73a85..0000000 --- a/suckless/st/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 = "monospace:size=12:antialias=true:autohint=true"; -static int borderpx = 4; - -/* - * 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 = 2; -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; - -/* bg opacity */ -float alpha = 0.8; - -/* Background opacity */ -float alpha_def; - -/* Terminal colors (16 first used in escape sequence) */ -static const char *colorname[] = { - /* 8 normal colors */ - "#282828", // black (soft bg) - "#fb4934", // red - "#b8bb26", // green - "#fabd2f", // yellow - "#83a598", // blue - "#d3869b", // magenta - "#8ec07c", // cyan - "#ebdbb2", // white (light fg) - - /* 8 bright colors */ - "#3c3836", // bright black - "#cc241d", // bright red - "#98971a", // bright green - "#d79921", // bright yellow - "#458588", // bright blue - "#b16286", // bright magenta - "#689d6a", // bright cyan - "#f9f5d7", // bright white - - [255] = 0, - "gray90", // default foreground colour - "#000000", // default background colour -}; - -/* - * Default colors (colorname index) - * foreground, background, cursor, reverse cursor - */ -unsigned int defaultfg = 256; -unsigned int defaultbg = 257; -unsigned int defaultcs = 256; -static unsigned int defaultrcs = 257; - -/* - * Default shape of cursor - * 2: Block ("█") - * 4: Underline ("_") - * 6: Bar ("|") - * 7: Snowman ("☃") - */ -static unsigned int cursorshape = 2; - -/* - * Default columns and rows numbers - */ - -static unsigned int cols = 140; -static unsigned int rows = 40; - -/* - * 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_NO_MOD, Button4, kscrollup, {.i = 1} }, - { XK_NO_MOD, Button5, kscrolldown, {.i = 1} }, - { XK_ANY_MOD, Button2, selpaste, {.i = 0}, 1 }, - { ShiftMask, Button4, ttysend, {.s = "\033[5;2~"} }, - { XK_ANY_MOD, Button4, ttysend, {.s = "\031"} }, - { ShiftMask, Button5, ttysend, {.s = "\033[6;2~"} }, - { XK_ANY_MOD, Button5, ttysend, {.s = "\005"} }, -}; - -/* Internal keyboard shortcuts. */ -#define MODKEY Mod1Mask -#define TERMMOD (Mod1Mask|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} }, - { ControlMask, XK_equal, zoom, {.f = +1} }, - { ControlMask, XK_minus, zoom, {.f = -1} }, - { TERMMOD, XK_Home, zoomreset, {.f = 0} }, - { MODKEY, XK_c, clipcopy, {.i = 0} }, - { MODKEY, XK_v, clippaste, {.i = 0} }, - { TERMMOD, XK_Y, selpaste, {.i = 0} }, - { ShiftMask, XK_Insert, selpaste, {.i = 0} }, - { TERMMOD, XK_Num_Lock, numlock, {.i = 0} }, - { MODKEY, XK_k, kscrollup, {.i = 1} }, - { MODKEY, XK_j, 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_F16, 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/suckless/st/config.h.save b/suckless/st/config.h.save deleted file mode 100644 index b25362c..0000000 --- a/suckless/st/config.h.save +++ /dev/null @@ -1,486 +0,0 @@ -/* See LICENSE file for copyright and license details. */ - -/* - * appearance - * - * font: see http://freedesktop.org/software/fontconfig/fontconfig-user.html - */ -static char *font = "Terminus-9: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 = 2; -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; - -/* bg opacity */ -float alpha = 0.8; - -/* Background opacity */ -float alpha_def; - -/* Terminal colors (16 first used in escape sequence) */ -static const char *colorname[] = { - - /* 8 normal colors */ - "#0a0a0a", /* black */ - "#44516d", /* red */ - "#c95d38", /* green */ - "#de9e68", /* yellow */ - "#8b7675", /* blue */ - "#7e5f8c", /* magenta */ - "#8c82c2", /* cyan */ - "#eff7d0", /* white */ - - /* 8 bright colors */ - "#181818", /* black */ - "#7d87a1", /* red */ - "#e9673c", /* green */ - "#e0b18b", /* yellow */ - "#b9a192", /* blue */ - "#9a7ebd", /* magenta */ - "#bccce2", /* cyan */ - "#ffffff", /* white */ - - [255] = 0, - - /* more colors can be added after 255 to use with DefaultXX */ - "#gray90", /* default foreground colour */ - "#black", /* default background colour */ -}; - - -/* - * Default colors (colorname index) - * foreground, background, cursor, reverse cursor - */ -unsigned int defaultfg = 256; -unsigned int defaultbg = 257; -unsigned int defaultcs = 256; -static unsigned int defaultrcs = 257; - -/* - * Default shape of cursor - * 2: Block ("█") - * 4: Underline ("_") - * 6: Bar ("|") - * 7: Snowman ("☃") - */ -static unsigned int cursorshape = 6; - -/* - * 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_NO_MOD, Button4, kscrollup, {.i = 1} }, - { XK_NO_MOD, Button5, kscrolldown, {.i = 1} }, - { XK_ANY_MOD, Button2, selpaste, {.i = 0}, 1 }, - { ShiftMask, Button4, ttysend, {.s = "\033[5;2~"} }, - { XK_ANY_MOD, Button4, ttysend, {.s = "\031"} }, - { ShiftMask, Button5, ttysend, {.s = "\033[6;2~"} }, - { XK_ANY_MOD, Button5, ttysend, {.s = "\005"} }, -}; - -/* Internal keyboard shortcuts. */ -#define MODKEY Mod1Mask -#define TERMMOD (Mod1Mask|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} }, - { ControlMask, XK_j, zoom, {.f = +1} }, - { ControlMask, XK_minus, zoom, {.f = -1} }, - { TERMMOD, XK_Home, zoomreset, {.f = 0} }, - { MODKEY, XK_c, clipcopy, {.i = 0} }, - { MODKEY, XK_v, clippaste, {.i = 0} }, - { TERMMOD, XK_Y, selpaste, {.i = 0} }, - { ShiftMask, XK_Insert, selpaste, {.i = 0} }, - { TERMMOD, XK_Num_Lock, numlock, {.i = 0} }, - { MODKEY, XK_k, kscrollup, {.i = 1} }, - { MODKEY, XK_j, kscrolldown, {.i = 1} }, - { MODKEY, XK_a, chgalpha, {.f = -1} }, - { MODKEY, XK_s, chgalpha, {.f = +1} }, - { MODKEY, XK_d, chgalpha, {.f = 0} }, -}; - -/* - * Special keys (change & recompile st.info accordingly) - * - * Mask value: - * * Use XK_ANY_MOD to match the key no matter modifiers state - * * Use XK_NO_MOD to match the key alone (no modifiers) - * appkey value: - * * 0: no value - * * > 0: keypad application mode enabled - * * = 2: term.numlock = 1 - * * < 0: keypad application mode disabled - * appcursor value: - * * 0: no value - * * > 0: cursor application mode enabled - * * < 0: cursor application mode disabled - * - * Be careful with the order of the definitions because st searches in - * this table sequentially, so any XK_ANY_MOD must be in the last - * position for a key. - */ - -/* - * If you want keys other than the X11 function keys (0xFD00 - 0xFFFF) - * to be mapped below, add them to this array. - */ -static KeySym mappedkeys[] = { -1 }; - -/* - * State bits to ignore when matching key or button events. By default, - * numlock (Mod2Mask) and keyboard layout (XK_SWITCH_MOD) are ignored. - */ -static uint ignoremod = Mod2Mask|XK_SWITCH_MOD; - -/* - * This is the huge key array which defines all compatibility to the Linux - * world. Please decide about changes wisely. - */ -static Key key[] = { - /* keysym mask string appkey appcursor */ - { XK_KP_Home, ShiftMask, "\033[2J", 0, -1}, - { XK_KP_Home, ShiftMask, "\033[1;2H", 0, +1}, - { XK_KP_Home, XK_ANY_MOD, "\033[H", 0, -1}, - { XK_KP_Home, XK_ANY_MOD, "\033[1~", 0, +1}, - { XK_KP_Up, XK_ANY_MOD, "\033Ox", +1, 0}, - { XK_KP_Up, XK_ANY_MOD, "\033[A", 0, -1}, - { XK_KP_Up, XK_ANY_MOD, "\033OA", 0, +1}, - { XK_KP_Down, XK_ANY_MOD, "\033Or", +1, 0}, - { XK_KP_Down, XK_ANY_MOD, "\033[B", 0, -1}, - { XK_KP_Down, XK_ANY_MOD, "\033OB", 0, +1}, - { XK_KP_Left, XK_ANY_MOD, "\033Ot", +1, 0}, - { XK_KP_Left, XK_ANY_MOD, "\033[D", 0, -1}, - { XK_KP_Left, XK_ANY_MOD, "\033OD", 0, +1}, - { XK_KP_Right, XK_ANY_MOD, "\033Ov", +1, 0}, - { XK_KP_Right, XK_ANY_MOD, "\033[C", 0, -1}, - { XK_KP_Right, XK_ANY_MOD, "\033OC", 0, +1}, - { XK_KP_Prior, ShiftMask, "\033[5;2~", 0, 0}, - { XK_KP_Prior, XK_ANY_MOD, "\033[5~", 0, 0}, - { XK_KP_Begin, XK_ANY_MOD, "\033[E", 0, 0}, - { XK_KP_End, ControlMask, "\033[J", -1, 0}, - { XK_KP_End, ControlMask, "\033[1;5F", +1, 0}, - { XK_KP_End, ShiftMask, "\033[K", -1, 0}, - { XK_KP_End, ShiftMask, "\033[1;2F", +1, 0}, - { XK_KP_End, XK_ANY_MOD, "\033[4~", 0, 0}, - { XK_KP_Next, ShiftMask, "\033[6;2~", 0, 0}, - { XK_KP_Next, XK_ANY_MOD, "\033[6~", 0, 0}, - { XK_KP_Insert, ShiftMask, "\033[2;2~", +1, 0}, - { XK_KP_Insert, ShiftMask, "\033[4l", -1, 0}, - { XK_KP_Insert, ControlMask, "\033[L", -1, 0}, - { XK_KP_Insert, ControlMask, "\033[2;5~", +1, 0}, - { XK_KP_Insert, XK_ANY_MOD, "\033[4h", -1, 0}, - { XK_KP_Insert, XK_ANY_MOD, "\033[2~", +1, 0}, - { XK_KP_Delete, ControlMask, "\033[M", -1, 0}, - { XK_KP_Delete, ControlMask, "\033[3;5~", +1, 0}, - { XK_KP_Delete, ShiftMask, "\033[2K", -1, 0}, - { XK_KP_Delete, ShiftMask, "\033[3;2~", +1, 0}, - { XK_KP_Delete, XK_ANY_MOD, "\033[P", -1, 0}, - { XK_KP_Delete, XK_ANY_MOD, "\033[3~", +1, 0}, - { XK_KP_Multiply, XK_ANY_MOD, "\033Oj", +2, 0}, - { XK_KP_Add, XK_ANY_MOD, "\033Ok", +2, 0}, - { XK_KP_Enter, XK_ANY_MOD, "\033OM", +2, 0}, - { XK_KP_Enter, XK_ANY_MOD, "\r", -1, 0}, - { XK_KP_Subtract, XK_ANY_MOD, "\033Om", +2, 0}, - { XK_KP_Decimal, XK_ANY_MOD, "\033On", +2, 0}, - { XK_KP_Divide, XK_ANY_MOD, "\033Oo", +2, 0}, - { XK_KP_0, XK_ANY_MOD, "\033Op", +2, 0}, - { XK_KP_1, XK_ANY_MOD, "\033Oq", +2, 0}, - { XK_KP_2, XK_ANY_MOD, "\033Or", +2, 0}, - { XK_KP_3, XK_ANY_MOD, "\033Os", +2, 0}, - { XK_KP_4, XK_ANY_MOD, "\033Ot", +2, 0}, - { XK_KP_5, XK_ANY_MOD, "\033Ou", +2, 0}, - { XK_KP_6, XK_ANY_MOD, "\033Ov", +2, 0}, - { XK_KP_7, XK_ANY_MOD, "\033Ow", +2, 0}, - { XK_KP_8, XK_ANY_MOD, "\033Ox", +2, 0}, - { XK_KP_9, XK_ANY_MOD, "\033Oy", +2, 0}, - { XK_Up, ShiftMask, "\033[1;2A", 0, 0}, - { XK_Up, Mod1Mask, "\033[1;3A", 0, 0}, - { XK_Up, ShiftMask|Mod1Mask,"\033[1;4A", 0, 0}, - { XK_Up, ControlMask, "\033[1;5A", 0, 0}, - { XK_Up, ShiftMask|ControlMask,"\033[1;6A", 0, 0}, - { XK_Up, ControlMask|Mod1Mask,"\033[1;7A", 0, 0}, - { XK_Up,ShiftMask|ControlMask|Mod1Mask,"\033[1;8A", 0, 0}, - { XK_Up, XK_ANY_MOD, "\033[A", 0, -1}, - { XK_Up, XK_ANY_MOD, "\033OA", 0, +1}, - { XK_Down, ShiftMask, "\033[1;2B", 0, 0}, - { XK_Down, Mod1Mask, "\033[1;3B", 0, 0}, - { XK_Down, ShiftMask|Mod1Mask,"\033[1;4B", 0, 0}, - { XK_Down, ControlMask, "\033[1;5B", 0, 0}, - { XK_Down, ShiftMask|ControlMask,"\033[1;6B", 0, 0}, - { XK_Down, ControlMask|Mod1Mask,"\033[1;7B", 0, 0}, - { XK_Down,ShiftMask|ControlMask|Mod1Mask,"\033[1;8B",0, 0}, - { XK_Down, XK_ANY_MOD, "\033[B", 0, -1}, - { XK_Down, XK_ANY_MOD, "\033OB", 0, +1}, - { XK_Left, ShiftMask, "\033[1;2D", 0, 0}, - { XK_Left, Mod1Mask, "\033[1;3D", 0, 0}, - { XK_Left, ShiftMask|Mod1Mask,"\033[1;4D", 0, 0}, - { XK_Left, ControlMask, "\033[1;5D", 0, 0}, - { XK_Left, ShiftMask|ControlMask,"\033[1;6D", 0, 0}, - { XK_Left, ControlMask|Mod1Mask,"\033[1;7D", 0, 0}, - { XK_Left,ShiftMask|ControlMask|Mod1Mask,"\033[1;8D",0, 0}, - { XK_Left, XK_ANY_MOD, "\033[D", 0, -1}, - { XK_Left, XK_ANY_MOD, "\033OD", 0, +1}, - { XK_Right, ShiftMask, "\033[1;2C", 0, 0}, - { XK_Right, Mod1Mask, "\033[1;3C", 0, 0}, - { XK_Right, ShiftMask|Mod1Mask,"\033[1;4C", 0, 0}, - { XK_Right, ControlMask, "\033[1;5C", 0, 0}, - { XK_Right, ShiftMask|ControlMask,"\033[1;6C", 0, 0}, - { XK_Right, ControlMask|Mod1Mask,"\033[1;7C", 0, 0}, - { XK_Right,ShiftMask|ControlMask|Mod1Mask,"\033[1;8C",0, 0}, - { XK_Right, XK_ANY_MOD, "\033[C", 0, -1}, - { XK_Right, XK_ANY_MOD, "\033OC", 0, +1}, - { XK_ISO_Left_Tab, ShiftMask, "\033[Z", 0, 0}, - { XK_Return, Mod1Mask, "\033\r", 0, 0}, - { XK_Return, XK_ANY_MOD, "\r", 0, 0}, - { XK_Insert, ShiftMask, "\033[4l", -1, 0}, - { XK_Insert, ShiftMask, "\033[2;2~", +1, 0}, - { XK_Insert, ControlMask, "\033[L", -1, 0}, - { XK_Insert, ControlMask, "\033[2;5~", +1, 0}, - { XK_Insert, XK_ANY_MOD, "\033[4h", -1, 0}, - { XK_Insert, XK_ANY_MOD, "\033[2~", +1, 0}, - { XK_Delete, ControlMask, "\033[M", -1, 0}, - { XK_Delete, ControlMask, "\033[3;5~", +1, 0}, - { XK_Delete, ShiftMask, "\033[2K", -1, 0}, - { XK_Delete, ShiftMask, "\033[3;2~", +1, 0}, - { XK_Delete, XK_ANY_MOD, "\033[P", -1, 0}, - { XK_Delete, XK_ANY_MOD, "\033[3~", +1, 0}, - { XK_BackSpace, XK_NO_MOD, "\177", 0, 0}, - { XK_BackSpace, Mod1Mask, "\033\177", 0, 0}, - { XK_Home, ShiftMask, "\033[2J", 0, -1}, - { XK_Home, ShiftMask, "\033[1;2H", 0, +1}, - { XK_Home, XK_ANY_MOD, "\033[H", 0, -1}, - { XK_Home, XK_ANY_MOD, "\033[1~", 0, +1}, - { XK_End, ControlMask, "\033[J", -1, 0}, - { XK_End, ControlMask, "\033[1;5F", +1, 0}, - { XK_End, ShiftMask, "\033[K", -1, 0}, - { XK_End, ShiftMask, "\033[1;2F", +1, 0}, - { XK_End, XK_ANY_MOD, "\033[4~", 0, 0}, - { XK_Prior, ControlMask, "\033[5;5~", 0, 0}, - { XK_Prior, ShiftMask, "\033[5;2~", 0, 0}, - { XK_Prior, XK_ANY_MOD, "\033[5~", 0, 0}, - { XK_Next, ControlMask, "\033[6;5~", 0, 0}, - { XK_Next, ShiftMask, "\033[6;2~", 0, 0}, - { XK_Next, XK_ANY_MOD, "\033[6~", 0, 0}, - { XK_F1, XK_NO_MOD, "\033OP" , 0, 0}, - { XK_F1, /* F13 */ ShiftMask, "\033[1;2P", 0, 0}, - { XK_F1, /* F25 */ ControlMask, "\033[1;5P", 0, 0}, - { XK_F1, /* F37 */ Mod4Mask, "\033[1;6P", 0, 0}, - { XK_F1, /* F49 */ Mod1Mask, "\033[1;3P", 0, 0}, - { XK_F1, /* F61 */ Mod3Mask, "\033[1;4P", 0, 0}, - { XK_F2, XK_NO_MOD, "\033OQ" , 0, 0}, - { XK_F2, /* F14 */ ShiftMask, "\033[1;2Q", 0, 0}, - { XK_F2, /* F26 */ ControlMask, "\033[1;5Q", 0, 0}, - { XK_F2, /* F38 */ Mod4Mask, "\033[1;6Q", 0, 0}, - { XK_F2, /* F50 */ Mod1Mask, "\033[1;3Q", 0, 0}, - { XK_F2, /* F62 */ Mod3Mask, "\033[1;4Q", 0, 0}, - { XK_F3, XK_NO_MOD, "\033OR" , 0, 0}, - { XK_F3, /* F15 */ ShiftMask, "\033[1;2R", 0, 0}, - { XK_F3, /* F27 */ ControlMask, "\033[1;5R", 0, 0}, - { XK_F3, /* F39 */ Mod4Mask, "\033[1;6R", 0, 0}, - { XK_F3, /* F51 */ Mod1Mask, "\033[1;3R", 0, 0}, - { XK_F3, /* F63 */ Mod3Mask, "\033[1;4R", 0, 0}, - { XK_F4, XK_NO_MOD, "\033OS" , 0, 0}, - { XK_F4, /* F16 */ ShiftMask, "\033[1;2S", 0, 0}, - { XK_F4, /* F28 */ ControlMask, "\033[1;5S", 0, 0}, - { XK_F4, /* F40 */ Mod4Mask, "\033[1;6S", 0, 0}, - { XK_F4, /* F52 */ Mod1Mask, "\033[1;3S", 0, 0}, - { XK_F5, XK_NO_MOD, "\033[15~", 0, 0}, - { XK_F5, /* F17 */ ShiftMask, "\033[15;2~", 0, 0}, - { XK_F5, /* F29 */ ControlMask, "\033[15;5~", 0, 0}, - { XK_F5, /* F41 */ Mod4Mask, "\033[15;6~", 0, 0}, - { XK_F5, /* F53 */ Mod1Mask, "\033[15;3~", 0, 0}, - { XK_F6, XK_NO_MOD, "\033[17~", 0, 0}, - { XK_F6, /* F18 */ ShiftMask, "\033[17;2~", 0, 0}, - { XK_F6, /* F30 */ ControlMask, "\033[17;5~", 0, 0}, - { XK_F6, /* F42 */ Mod4Mask, "\033[17;6~", 0, 0}, - { XK_F6, /* F54 */ Mod1Mask, "\033[17;3~", 0, 0}, - { XK_F7, XK_NO_MOD, "\033[18~", 0, 0}, - { XK_F7, /* F19 */ ShiftMask, "\033[18;2~", 0, 0}, - { XK_F7, /* F31 */ ControlMask, "\033[18;5~", 0, 0}, - { XK_F7, /* F43 */ Mod4Mask, "\033[18;6~", 0, 0}, - { XK_F7, /* F55 */ Mod1Mask, "\033[18;3~", 0, 0}, - { XK_F8, XK_NO_MOD, "\033[19~", 0, 0}, - { XK_F8, /* F20 */ ShiftMask, "\033[19;2~", 0, 0}, - { XK_F8, /* F32 */ ControlMask, "\033[19;5~", 0, 0}, - { XK_F8, /* F44 */ Mod4Mask, "\033[19;6~", 0, 0}, - { XK_F8, /* F56 */ Mod1Mask, "\033[19;3~", 0, 0}, - { XK_F9, XK_NO_MOD, "\033[20~", 0, 0}, - { XK_F9, /* F21 */ ShiftMask, "\033[20;2~", 0, 0}, - { XK_F9, /* F33 */ ControlMask, "\033[20;5~", 0, 0}, - { XK_F9, /* F45 */ Mod4Mask, "\033[20;6~", 0, 0}, - { XK_F9, /* F57 */ Mod1Mask, "\033[20;3~", 0, 0}, - { XK_F10, XK_NO_MOD, "\033[21~", 0, 0}, - { XK_F10, /* F22 */ ShiftMask, "\033[21;2~", 0, 0}, - { XK_F10, /* F34 */ ControlMask, "\033[21;5~", 0, 0}, - { XK_F10, /* F46 */ Mod4Mask, "\033[21;6~", 0, 0}, - { XK_F10, /* F58 */ Mod1Mask, "\033[21;3~", 0, 0}, - { XK_F11, XK_NO_MOD, "\033[23~", 0, 0}, - { XK_F11, /* F23 */ ShiftMask, "\033[23;2~", 0, 0}, - { XK_F11, /* F35 */ ControlMask, "\033[23;5~", 0, 0}, - { XK_F11, /* F47 */ Mod4Mask, "\033[23;6~", 0, 0}, - { XK_F11, /* F59 */ Mod1Mask, "\033[23;3~", 0, 0}, - { XK_F12, XK_NO_MOD, "\033[24~", 0, 0}, - { XK_F12, /* F24 */ ShiftMask, "\033[24;2~", 0, 0}, - { XK_F12, /* F36 */ ControlMask, "\033[24;5~", 0, 0}, - { XK_F12, /* F48 */ Mod4Mask, "\033[24;6~", 0, 0}, - { XK_F12, /* F60 */ Mod1Mask, "\033[24;3~", 0, 0}, - { XK_F13, XK_NO_MOD, "\033[1;2P", 0, 0}, - { XK_F14, XK_NO_MOD, "\033[1;2Q", 0, 0}, - { XK_F15, XK_NO_MOD, "\033[1;2R", 0, 0}, - { XK_F16, XK_NO_MOD, "\033[1;2S", 0, 0}, - { XK_F17, XK_NO_MOD, "\033[15;2~", 0, 0}, - { XK_F18, XK_NO_MOD, "\033[17;2~", 0, 0}, - { XK_F19, XK_NO_MOD, "\033[18;2~", 0, 0}, - { XK_F20, XK_NO_MOD, "\033[19;2~", 0, 0}, - { XK_F21, XK_NO_MOD, "\033[20;2~", 0, 0}, - { XK_F22, XK_NO_MOD, "\033[21;2~", 0, 0}, - { XK_F23, XK_NO_MOD, "\033[23;2~", 0, 0}, - { XK_F24, XK_NO_MOD, "\033[24;2~", 0, 0}, - { XK_F25, XK_NO_MOD, "\033[1;5P", 0, 0}, - { XK_F26, XK_NO_MOD, "\033[1;5Q", 0, 0}, - { XK_F27, XK_NO_MOD, "\033[1;5R", 0, 0}, - { XK_F28, XK_NO_MOD, "\033[1;5S", 0, 0}, - { XK_F29, XK_NO_MOD, "\033[15;5~", 0, 0}, - { XK_F30, XK_NO_MOD, "\033[17;5~", 0, 0}, - { XK_F31, XK_NO_MOD, "\033[18;5~", 0, 0}, - { XK_F32, XK_NO_MOD, "\033[19;5~", 0, 0}, - { XK_F33, XK_NO_MOD, "\033[20;5~", 0, 0}, - { XK_F34, XK_NO_MOD, "\033[21;5~", 0, 0}, - { XK_F35, XK_NO_MOD, "\033[23;5~", 0, 0}, -}; - -/* - * Selection types' masks. - * Use the same masks as usual. - * Button1Mask is always unset, to make masks match between ButtonPress. - * ButtonRelease and MotionNotify. - * If no match is found, regular selection is used. - */ -static uint selmasks[] = { - [SEL_RECTANGULAR] = Mod1Mask, -}; - -/* - * Printable characters in ASCII, used to estimate the advance width - * of single wide characters. - */ -static char ascii_printable[] = - " !\"#$%&'()*+,-./0123456789:;<=>?" - "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_" - "`abcdefghijklmnopqrstuvwxyz{|}~"; diff --git a/suckless/st/config.h.save.1 b/suckless/st/config.h.save.1 deleted file mode 100644 index d608c5a..0000000 --- a/suckless/st/config.h.save.1 +++ /dev/null @@ -1,486 +0,0 @@ -/* See LICENSE file for copyright and license details. */ - -/* - * appearance - * - * font: see http://freedesktop.org/software/fontconfig/fontconfig-user.html - */ -static char *font = "Terminus-9: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 = 2; -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; - -/* bg opacity */ -float alpha = 0.8; - -/* Background opacity */ -float alpha_def; - -/* Terminal colors (16 first used in escape sequence) */ -static const char *colorname[] = { - - /* 8 normal colors */ - "#0a0a0a", /* black */ - "#44516d", /* red */ - "#c95d38", /* green */ - "#de9e68", /* yellow */ - "#8b7675", /* blue */ - "#7e5f8c", /* magenta */ - "#8c82c2", /* cyan */ - "#eff7d0", /* white */ - - /* 8 bright colors */ - "#181818", /* black */ - "#7d87a1", /* red */ - "#e9673c", /* green */ - "#e0b18b", /* yellow */ - "#b9a192", /* blue */ - "#9a7ebd", /* magenta */ - "#bccce2", /* cyan */ - "#ffffff", /* white */ - - [255] = 0, - - /* more colors can be added after 255 to use with DefaultXX */ - "gray90", /* default foreground colour */ - "black", /* default background colour */ -}; - - -/* - * Default colors (colorname index) - * foreground, background, cursor, reverse cursor - */ -unsigned int defaultfg = 256; -unsigned int defaultbg = 257; -unsigned int defaultcs = 256; -static unsigned int defaultrcs = 257; - -/* - * Default shape of cursor - * 2: Block ("█") - * 4: Underline ("_") - * 6: Bar ("|") - * 7: Snowman ("☃") - */ -static unsigned int cursorshape = 6; - -/* - * 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_NO_MOD, Button4, kscrollup, {.i = 1} }, - { XK_NO_MOD, Button5, kscrolldown, {.i = 1} }, - { XK_ANY_MOD, Button2, selpaste, {.i = 0}, 1 }, - { ShiftMask, Button4, ttysend, {.s = "\033[5;2~"} }, - { XK_ANY_MOD, Button4, ttysend, {.s = "\031"} }, - { ShiftMask, Button5, ttysend, {.s = "\033[6;2~"} }, - { XK_ANY_MOD, Button5, ttysend, {.s = "\005"} }, -}; - -/* Internal keyboard shortcuts. */ -#define MODKEY Mod1Mask -#define TERMMOD (Mod1Mask|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} }, - { ControlMask, XK_equal, zoom, {.f = +1} }, - { ControlMask, XK_minus, zoom, {.f = -1} }, - { TERMMOD, XK_Home, zoomreset, {.f = 0} }, - { MODKEY, XK_c, clipcopy, {.i = 0} }, - { MODKEY, XK_v, clippaste, {.i = 0} }, - { TERMMOD, XK_Y, selpaste, {.i = 0} }, - { ShiftMask, XK_Insert, selpaste, {.i = 0} }, - { TERMMOD, XK_Num_Lock, numlock, {.i = 0} }, - { ControlMask, XK_k, kscrollup, {.i = 1} }, - { ControlMask, XK_j, kscrolldown, {.i = 1} }, - { MODKEY, XK_a, chgalpha, {.f = -1} }, - { MODKEY, XK_s, chgalpha, {.f = +1} }, - { MODKEY, XK_d, chgalpha, {.f = 0} }, -}; - -/* - * Special keys (change & recompile st.info accordingly) - * - * Mask value: - * * Use XK_ANY_MOD to match the key no matter modifiers state - * * Use XK_NO_MOD to match the key alone (no modifiers) - * appkey value: - * * 0: no value - * * > 0: keypad application mode enabled - * * = 2: term.numlock = 1 - * * < 0: keypad application mode disabled - * appcursor value: - * * 0: no value - * * > 0: cursor application mode enabled - * * < 0: cursor application mode disabled - * - * Be careful with the order of the definitions because st searches in - * this table sequentially, so any XK_ANY_MOD must be in the last - * position for a key. - */ - -/* - * If you want keys other than the X11 function keys (0xFD00 - 0xFFFF) - * to be mapped below, add them to this array. - */ -static KeySym mappedkeys[] = { -1 }; - -/* - * State bits to ignore when matching key or button events. By default, - * numlock (Mod2Mask) and keyboard layout (XK_SWITCH_MOD) are ignored. - */ -static uint ignoremod = Mod2Mask|XK_SWITCH_MOD; - -/* - * This is the huge key array which defines all compatibility to the Linux - * world. Please decide about changes wisely. - */ -static Key key[] = { - /* keysym mask string appkey appcursor */ - { XK_KP_Home, ShiftMask, "\033[2J", 0, -1}, - { XK_KP_Home, ShiftMask, "\033[1;2H", 0, +1}, - { XK_KP_Home, XK_ANY_MOD, "\033[H", 0, -1}, - { XK_KP_Home, XK_ANY_MOD, "\033[1~", 0, +1}, - { XK_KP_Up, XK_ANY_MOD, "\033Ox", +1, 0}, - { XK_KP_Up, XK_ANY_MOD, "\033[A", 0, -1}, - { XK_KP_Up, XK_ANY_MOD, "\033OA", 0, +1}, - { XK_KP_Down, XK_ANY_MOD, "\033Or", +1, 0}, - { XK_KP_Down, XK_ANY_MOD, "\033[B", 0, -1}, - { XK_KP_Down, XK_ANY_MOD, "\033OB", 0, +1}, - { XK_KP_Left, XK_ANY_MOD, "\033Ot", +1, 0}, - { XK_KP_Left, XK_ANY_MOD, "\033[D", 0, -1}, - { XK_KP_Left, XK_ANY_MOD, "\033OD", 0, +1}, - { XK_KP_Right, XK_ANY_MOD, "\033Ov", +1, 0}, - { XK_KP_Right, XK_ANY_MOD, "\033[C", 0, -1}, - { XK_KP_Right, XK_ANY_MOD, "\033OC", 0, +1}, - { XK_KP_Prior, ShiftMask, "\033[5;2~", 0, 0}, - { XK_KP_Prior, XK_ANY_MOD, "\033[5~", 0, 0}, - { XK_KP_Begin, XK_ANY_MOD, "\033[E", 0, 0}, - { XK_KP_End, ControlMask, "\033[J", -1, 0}, - { XK_KP_End, ControlMask, "\033[1;5F", +1, 0}, - { XK_KP_End, ShiftMask, "\033[K", -1, 0}, - { XK_KP_End, ShiftMask, "\033[1;2F", +1, 0}, - { XK_KP_End, XK_ANY_MOD, "\033[4~", 0, 0}, - { XK_KP_Next, ShiftMask, "\033[6;2~", 0, 0}, - { XK_KP_Next, XK_ANY_MOD, "\033[6~", 0, 0}, - { XK_KP_Insert, ShiftMask, "\033[2;2~", +1, 0}, - { XK_KP_Insert, ShiftMask, "\033[4l", -1, 0}, - { XK_KP_Insert, ControlMask, "\033[L", -1, 0}, - { XK_KP_Insert, ControlMask, "\033[2;5~", +1, 0}, - { XK_KP_Insert, XK_ANY_MOD, "\033[4h", -1, 0}, - { XK_KP_Insert, XK_ANY_MOD, "\033[2~", +1, 0}, - { XK_KP_Delete, ControlMask, "\033[M", -1, 0}, - { XK_KP_Delete, ControlMask, "\033[3;5~", +1, 0}, - { XK_KP_Delete, ShiftMask, "\033[2K", -1, 0}, - { XK_KP_Delete, ShiftMask, "\033[3;2~", +1, 0}, - { XK_KP_Delete, XK_ANY_MOD, "\033[P", -1, 0}, - { XK_KP_Delete, XK_ANY_MOD, "\033[3~", +1, 0}, - { XK_KP_Multiply, XK_ANY_MOD, "\033Oj", +2, 0}, - { XK_KP_Add, XK_ANY_MOD, "\033Ok", +2, 0}, - { XK_KP_Enter, XK_ANY_MOD, "\033OM", +2, 0}, - { XK_KP_Enter, XK_ANY_MOD, "\r", -1, 0}, - { XK_KP_Subtract, XK_ANY_MOD, "\033Om", +2, 0}, - { XK_KP_Decimal, XK_ANY_MOD, "\033On", +2, 0}, - { XK_KP_Divide, XK_ANY_MOD, "\033Oo", +2, 0}, - { XK_KP_0, XK_ANY_MOD, "\033Op", +2, 0}, - { XK_KP_1, XK_ANY_MOD, "\033Oq", +2, 0}, - { XK_KP_2, XK_ANY_MOD, "\033Or", +2, 0}, - { XK_KP_3, XK_ANY_MOD, "\033Os", +2, 0}, - { XK_KP_4, XK_ANY_MOD, "\033Ot", +2, 0}, - { XK_KP_5, XK_ANY_MOD, "\033Ou", +2, 0}, - { XK_KP_6, XK_ANY_MOD, "\033Ov", +2, 0}, - { XK_KP_7, XK_ANY_MOD, "\033Ow", +2, 0}, - { XK_KP_8, XK_ANY_MOD, "\033Ox", +2, 0}, - { XK_KP_9, XK_ANY_MOD, "\033Oy", +2, 0}, - { XK_Up, ShiftMask, "\033[1;2A", 0, 0}, - { XK_Up, Mod1Mask, "\033[1;3A", 0, 0}, - { XK_Up, ShiftMask|Mod1Mask,"\033[1;4A", 0, 0}, - { XK_Up, ControlMask, "\033[1;5A", 0, 0}, - { XK_Up, ShiftMask|ControlMask,"\033[1;6A", 0, 0}, - { XK_Up, ControlMask|Mod1Mask,"\033[1;7A", 0, 0}, - { XK_Up,ShiftMask|ControlMask|Mod1Mask,"\033[1;8A", 0, 0}, - { XK_Up, XK_ANY_MOD, "\033[A", 0, -1}, - { XK_Up, XK_ANY_MOD, "\033OA", 0, +1}, - { XK_Down, ShiftMask, "\033[1;2B", 0, 0}, - { XK_Down, Mod1Mask, "\033[1;3B", 0, 0}, - { XK_Down, ShiftMask|Mod1Mask,"\033[1;4B", 0, 0}, - { XK_Down, ControlMask, "\033[1;5B", 0, 0}, - { XK_Down, ShiftMask|ControlMask,"\033[1;6B", 0, 0}, - { XK_Down, ControlMask|Mod1Mask,"\033[1;7B", 0, 0}, - { XK_Down,ShiftMask|ControlMask|Mod1Mask,"\033[1;8B",0, 0}, - { XK_Down, XK_ANY_MOD, "\033[B", 0, -1}, - { XK_Down, XK_ANY_MOD, "\033OB", 0, +1}, - { XK_Left, ShiftMask, "\033[1;2D", 0, 0}, - { XK_Left, Mod1Mask, "\033[1;3D", 0, 0}, - { XK_Left, ShiftMask|Mod1Mask,"\033[1;4D", 0, 0}, - { XK_Left, ControlMask, "\033[1;5D", 0, 0}, - { XK_Left, ShiftMask|ControlMask,"\033[1;6D", 0, 0}, - { XK_Left, ControlMask|Mod1Mask,"\033[1;7D", 0, 0}, - { XK_Left,ShiftMask|ControlMask|Mod1Mask,"\033[1;8D",0, 0}, - { XK_Left, XK_ANY_MOD, "\033[D", 0, -1}, - { XK_Left, XK_ANY_MOD, "\033OD", 0, +1}, - { XK_Right, ShiftMask, "\033[1;2C", 0, 0}, - { XK_Right, Mod1Mask, "\033[1;3C", 0, 0}, - { XK_Right, ShiftMask|Mod1Mask,"\033[1;4C", 0, 0}, - { XK_Right, ControlMask, "\033[1;5C", 0, 0}, - { XK_Right, ShiftMask|ControlMask,"\033[1;6C", 0, 0}, - { XK_Right, ControlMask|Mod1Mask,"\033[1;7C", 0, 0}, - { XK_Right,ShiftMask|ControlMask|Mod1Mask,"\033[1;8C",0, 0}, - { XK_Right, XK_ANY_MOD, "\033[C", 0, -1}, - { XK_Right, XK_ANY_MOD, "\033OC", 0, +1}, - { XK_ISO_Left_Tab, ShiftMask, "\033[Z", 0, 0}, - { XK_Return, Mod1Mask, "\033\r", 0, 0}, - { XK_Return, XK_ANY_MOD, "\r", 0, 0}, - { XK_Insert, ShiftMask, "\033[4l", -1, 0}, - { XK_Insert, ShiftMask, "\033[2;2~", +1, 0}, - { XK_Insert, ControlMask, "\033[L", -1, 0}, - { XK_Insert, ControlMask, "\033[2;5~", +1, 0}, - { XK_Insert, XK_ANY_MOD, "\033[4h", -1, 0}, - { XK_Insert, XK_ANY_MOD, "\033[2~", +1, 0}, - { XK_Delete, ControlMask, "\033[M", -1, 0}, - { XK_Delete, ControlMask, "\033[3;5~", +1, 0}, - { XK_Delete, ShiftMask, "\033[2K", -1, 0}, - { XK_Delete, ShiftMask, "\033[3;2~", +1, 0}, - { XK_Delete, XK_ANY_MOD, "\033[P", -1, 0}, - { XK_Delete, XK_ANY_MOD, "\033[3~", +1, 0}, - { XK_BackSpace, XK_NO_MOD, "\177", 0, 0}, - { XK_BackSpace, Mod1Mask, "\033\177", 0, 0}, - { XK_Home, ShiftMask, "\033[2J", 0, -1}, - { XK_Home, ShiftMask, "\033[1;2H", 0, +1}, - { XK_Home, XK_ANY_MOD, "\033[H", 0, -1}, - { XK_Home, XK_ANY_MOD, "\033[1~", 0, +1}, - { XK_End, ControlMask, "\033[J", -1, 0}, - { XK_End, ControlMask, "\033[1;5F", +1, 0}, - { XK_End, ShiftMask, "\033[K", -1, 0}, - { XK_End, ShiftMask, "\033[1;2F", +1, 0}, - { XK_End, XK_ANY_MOD, "\033[4~", 0, 0}, - { XK_Prior, ControlMask, "\033[5;5~", 0, 0}, - { XK_Prior, ShiftMask, "\033[5;2~", 0, 0}, - { XK_Prior, XK_ANY_MOD, "\033[5~", 0, 0}, - { XK_Next, ControlMask, "\033[6;5~", 0, 0}, - { XK_Next, ShiftMask, "\033[6;2~", 0, 0}, - { XK_Next, XK_ANY_MOD, "\033[6~", 0, 0}, - { XK_F1, XK_NO_MOD, "\033OP" , 0, 0}, - { XK_F1, /* F13 */ ShiftMask, "\033[1;2P", 0, 0}, - { XK_F1, /* F25 */ ControlMask, "\033[1;5P", 0, 0}, - { XK_F1, /* F37 */ Mod4Mask, "\033[1;6P", 0, 0}, - { XK_F1, /* F49 */ Mod1Mask, "\033[1;3P", 0, 0}, - { XK_F1, /* F61 */ Mod3Mask, "\033[1;4P", 0, 0}, - { XK_F2, XK_NO_MOD, "\033OQ" , 0, 0}, - { XK_F2, /* F14 */ ShiftMask, "\033[1;2Q", 0, 0}, - { XK_F2, /* F26 */ ControlMask, "\033[1;5Q", 0, 0}, - { XK_F2, /* F38 */ Mod4Mask, "\033[1;6Q", 0, 0}, - { XK_F2, /* F50 */ Mod1Mask, "\033[1;3Q", 0, 0}, - { XK_F2, /* F62 */ Mod3Mask, "\033[1;4Q", 0, 0}, - { XK_F3, XK_NO_MOD, "\033OR" , 0, 0}, - { XK_F3, /* F15 */ ShiftMask, "\033[1;2R", 0, 0}, - { XK_F3, /* F27 */ ControlMask, "\033[1;5R", 0, 0}, - { XK_F3, /* F39 */ Mod4Mask, "\033[1;6R", 0, 0}, - { XK_F3, /* F51 */ Mod1Mask, "\033[1;3R", 0, 0}, - { XK_F3, /* F63 */ Mod3Mask, "\033[1;4R", 0, 0}, - { XK_F4, XK_NO_MOD, "\033OS" , 0, 0}, - { XK_F4, /* F16 */ ShiftMask, "\033[1;2S", 0, 0}, - { XK_F4, /* F28 */ ControlMask, "\033[1;5S", 0, 0}, - { XK_F4, /* F40 */ Mod4Mask, "\033[1;6S", 0, 0}, - { XK_F4, /* F52 */ Mod1Mask, "\033[1;3S", 0, 0}, - { XK_F5, XK_NO_MOD, "\033[15~", 0, 0}, - { XK_F5, /* F17 */ ShiftMask, "\033[15;2~", 0, 0}, - { XK_F5, /* F29 */ ControlMask, "\033[15;5~", 0, 0}, - { XK_F5, /* F41 */ Mod4Mask, "\033[15;6~", 0, 0}, - { XK_F5, /* F53 */ Mod1Mask, "\033[15;3~", 0, 0}, - { XK_F6, XK_NO_MOD, "\033[17~", 0, 0}, - { XK_F6, /* F18 */ ShiftMask, "\033[17;2~", 0, 0}, - { XK_F6, /* F30 */ ControlMask, "\033[17;5~", 0, 0}, - { XK_F6, /* F42 */ Mod4Mask, "\033[17;6~", 0, 0}, - { XK_F6, /* F54 */ Mod1Mask, "\033[17;3~", 0, 0}, - { XK_F7, XK_NO_MOD, "\033[18~", 0, 0}, - { XK_F7, /* F19 */ ShiftMask, "\033[18;2~", 0, 0}, - { XK_F7, /* F31 */ ControlMask, "\033[18;5~", 0, 0}, - { XK_F7, /* F43 */ Mod4Mask, "\033[18;6~", 0, 0}, - { XK_F7, /* F55 */ Mod1Mask, "\033[18;3~", 0, 0}, - { XK_F8, XK_NO_MOD, "\033[19~", 0, 0}, - { XK_F8, /* F20 */ ShiftMask, "\033[19;2~", 0, 0}, - { XK_F8, /* F32 */ ControlMask, "\033[19;5~", 0, 0}, - { XK_F8, /* F44 */ Mod4Mask, "\033[19;6~", 0, 0}, - { XK_F8, /* F56 */ Mod1Mask, "\033[19;3~", 0, 0}, - { XK_F9, XK_NO_MOD, "\033[20~", 0, 0}, - { XK_F9, /* F21 */ ShiftMask, "\033[20;2~", 0, 0}, - { XK_F9, /* F33 */ ControlMask, "\033[20;5~", 0, 0}, - { XK_F9, /* F45 */ Mod4Mask, "\033[20;6~", 0, 0}, - { XK_F9, /* F57 */ Mod1Mask, "\033[20;3~", 0, 0}, - { XK_F10, XK_NO_MOD, "\033[21~", 0, 0}, - { XK_F10, /* F22 */ ShiftMask, "\033[21;2~", 0, 0}, - { XK_F10, /* F34 */ ControlMask, "\033[21;5~", 0, 0}, - { XK_F10, /* F46 */ Mod4Mask, "\033[21;6~", 0, 0}, - { XK_F10, /* F58 */ Mod1Mask, "\033[21;3~", 0, 0}, - { XK_F11, XK_NO_MOD, "\033[23~", 0, 0}, - { XK_F11, /* F23 */ ShiftMask, "\033[23;2~", 0, 0}, - { XK_F11, /* F35 */ ControlMask, "\033[23;5~", 0, 0}, - { XK_F11, /* F47 */ Mod4Mask, "\033[23;6~", 0, 0}, - { XK_F11, /* F59 */ Mod1Mask, "\033[23;3~", 0, 0}, - { XK_F12, XK_NO_MOD, "\033[24~", 0, 0}, - { XK_F12, /* F24 */ ShiftMask, "\033[24;2~", 0, 0}, - { XK_F12, /* F36 */ ControlMask, "\033[24;5~", 0, 0}, - { XK_F12, /* F48 */ Mod4Mask, "\033[24;6~", 0, 0}, - { XK_F12, /* F60 */ Mod1Mask, "\033[24;3~", 0, 0}, - { XK_F13, XK_NO_MOD, "\033[1;2P", 0, 0}, - { XK_F14, XK_NO_MOD, "\033[1;2Q", 0, 0}, - { XK_F15, XK_NO_MOD, "\033[1;2R", 0, 0}, - { XK_F16, XK_NO_MOD, "\033[1;2S", 0, 0}, - { XK_F17, XK_NO_MOD, "\033[15;2~", 0, 0}, - { XK_F18, XK_NO_MOD, "\033[17;2~", 0, 0}, - { XK_F19, XK_NO_MOD, "\033[18;2~", 0, 0}, - { XK_F20, XK_NO_MOD, "\033[19;2~", 0, 0}, - { XK_F21, XK_NO_MOD, "\033[20;2~", 0, 0}, - { XK_F22, XK_NO_MOD, "\033[21;2~", 0, 0}, - { XK_F23, XK_NO_MOD, "\033[23;2~", 0, 0}, - { XK_F24, XK_NO_MOD, "\033[24;2~", 0, 0}, - { XK_F25, XK_NO_MOD, "\033[1;5P", 0, 0}, - { XK_F26, XK_NO_MOD, "\033[1;5Q", 0, 0}, - { XK_F27, XK_NO_MOD, "\033[1;5R", 0, 0}, - { XK_F28, XK_NO_MOD, "\033[1;5S", 0, 0}, - { XK_F29, XK_NO_MOD, "\033[15;5~", 0, 0}, - { XK_F30, XK_NO_MOD, "\033[17;5~", 0, 0}, - { XK_F31, XK_NO_MOD, "\033[18;5~", 0, 0}, - { XK_F32, XK_NO_MOD, "\033[19;5~", 0, 0}, - { XK_F33, XK_NO_MOD, "\033[20;5~", 0, 0}, - { XK_F34, XK_NO_MOD, "\033[21;5~", 0, 0}, - { XK_F35, XK_NO_MOD, "\033[23;5~", 0, 0}, -}; - -/* - * Selection types' masks. - * Use the same masks as usual. - * Button1Mask is always unset, to make masks match between ButtonPress. - * ButtonRelease and MotionNotify. - * If no match is found, regular selection is used. - */ -static uint selmasks[] = { - [SEL_RECTANGULAR] = Mod1Mask, -}; - -/* - * Printable characters in ASCII, used to estimate the advance width - * of single wide characters. - */ -static char ascii_printable[] = - " !\"#$%&'()*+,-./0123456789:;<=>?" - "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_" - "`abcdefghijklmnopqrstuvwxyz{|}~"; diff --git a/suckless/st/config.h.save.2 b/suckless/st/config.h.save.2 deleted file mode 100644 index 4869423..0000000 --- a/suckless/st/config.h.save.2 +++ /dev/null @@ -1,486 +0,0 @@ -/* See LICENSE file for copyright and license details. */ - -/* - * appearance - * - * font: see http://freedesktop.org/software/fontconfig/fontconfig-user.html - */ -static char *font = "Terminus-9: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 = 2; -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; - -/* bg opacity */ -float alpha = 0.8; - -/* Background opacity */ -float alpha_def; - -/* Terminal colors (16 first used in escape sequence) */ -static const char *colorname[] = { - - /* 8 normal colors */ - "#0a0a0a", /* black */ - "#44516d", /* red */ - "#c95d38", /* green */ - "#de9e68", /* yellow */ - "#8b7675", /* blue */ - "#7e5f8c", /* magenta */ - "#8c82c2", /* cyan */ - "#eff7d0", /* white */ - - /* 8 bright colors */ - "#181818", /* black */ - "#7d87a1", /* red */ - "#e9673c", /* green */ - "#e0b18b", /* yellow */ - "#b9a192", /* blue */ - "#9a7ebd", /* magenta */ - "#bccce2", /* cyan */ - "#ffffff", /* white */ - - [255] = 0, - - /* more colors can be added after 255 to use with DefaultXX */ - "gray90", /* default foreground colour */ - "black", /* default background colour */ -}; - - -/* - * Default colors (colorname index) - * foreground, background, cursor, reverse cursor - */ -unsigned int defaultfg = 256; -unsigned int defaultbg = 257; -unsigned int defaultcs = 256; -static unsigned int defaultrcs = 257; - -/* - * Default shape of cursor - * 2: Block ("█") - * 4: Underline ("_") - * 6: Bar ("|") - * 7: Snowman ("☃") - */ -static unsigned int cursorshape = 6; - -/* - * 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_NO_MOD, Button4, kscrollup, {.i = 1} }, - { XK_NO_MOD, Button5, kscrolldown, {.i = 1} }, - { XK_ANY_MOD, Button2, selpaste, {.i = 0}, 1 }, - { ShiftMask, Button4, ttysend, {.s = "\033[5;2~"} }, - { XK_ANY_MOD, Button4, ttysend, {.s = "\031"} }, - { ShiftMask, Button5, ttysend, {.s = "\033[6;2~"} }, - { XK_ANY_MOD, Button5, ttysend, {.s = "\005"} }, -}; - -/* Internal keyboard shortcuts. */ -#define MODKEY Mod1Mask -#define TERMMOD (Mod1Mask|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} }, - { ControlMask, XK_equal, zoom, {.f = +1} }, - { ControlMask, XK_minus, zoom, {.f = -1} }, - { TERMMOD, XK_Home, zoomreset, {.f = 0} }, - { ControlMask|Shift, XK_c, clipcopy, {.i = 0} }, - { MODKEY, XK_v, clippaste, {.i = 0} }, - { TERMMOD, XK_Y, selpaste, {.i = 0} }, - { ShiftMask, XK_Insert, selpaste, {.i = 0} }, - { TERMMOD, XK_Num_Lock, numlock, {.i = 0} }, - { ControlMask, XK_k, kscrollup, {.i = 1} }, - { ControlMask, XK_j, kscrolldown, {.i = 1} }, - { MODKEY, XK_a, chgalpha, {.f = -1} }, - { MODKEY, XK_s, chgalpha, {.f = +1} }, - { MODKEY, XK_d, chgalpha, {.f = 0} }, -}; - -/* - * Special keys (change & recompile st.info accordingly) - * - * Mask value: - * * Use XK_ANY_MOD to match the key no matter modifiers state - * * Use XK_NO_MOD to match the key alone (no modifiers) - * appkey value: - * * 0: no value - * * > 0: keypad application mode enabled - * * = 2: term.numlock = 1 - * * < 0: keypad application mode disabled - * appcursor value: - * * 0: no value - * * > 0: cursor application mode enabled - * * < 0: cursor application mode disabled - * - * Be careful with the order of the definitions because st searches in - * this table sequentially, so any XK_ANY_MOD must be in the last - * position for a key. - */ - -/* - * If you want keys other than the X11 function keys (0xFD00 - 0xFFFF) - * to be mapped below, add them to this array. - */ -static KeySym mappedkeys[] = { -1 }; - -/* - * State bits to ignore when matching key or button events. By default, - * numlock (Mod2Mask) and keyboard layout (XK_SWITCH_MOD) are ignored. - */ -static uint ignoremod = Mod2Mask|XK_SWITCH_MOD; - -/* - * This is the huge key array which defines all compatibility to the Linux - * world. Please decide about changes wisely. - */ -static Key key[] = { - /* keysym mask string appkey appcursor */ - { XK_KP_Home, ShiftMask, "\033[2J", 0, -1}, - { XK_KP_Home, ShiftMask, "\033[1;2H", 0, +1}, - { XK_KP_Home, XK_ANY_MOD, "\033[H", 0, -1}, - { XK_KP_Home, XK_ANY_MOD, "\033[1~", 0, +1}, - { XK_KP_Up, XK_ANY_MOD, "\033Ox", +1, 0}, - { XK_KP_Up, XK_ANY_MOD, "\033[A", 0, -1}, - { XK_KP_Up, XK_ANY_MOD, "\033OA", 0, +1}, - { XK_KP_Down, XK_ANY_MOD, "\033Or", +1, 0}, - { XK_KP_Down, XK_ANY_MOD, "\033[B", 0, -1}, - { XK_KP_Down, XK_ANY_MOD, "\033OB", 0, +1}, - { XK_KP_Left, XK_ANY_MOD, "\033Ot", +1, 0}, - { XK_KP_Left, XK_ANY_MOD, "\033[D", 0, -1}, - { XK_KP_Left, XK_ANY_MOD, "\033OD", 0, +1}, - { XK_KP_Right, XK_ANY_MOD, "\033Ov", +1, 0}, - { XK_KP_Right, XK_ANY_MOD, "\033[C", 0, -1}, - { XK_KP_Right, XK_ANY_MOD, "\033OC", 0, +1}, - { XK_KP_Prior, ShiftMask, "\033[5;2~", 0, 0}, - { XK_KP_Prior, XK_ANY_MOD, "\033[5~", 0, 0}, - { XK_KP_Begin, XK_ANY_MOD, "\033[E", 0, 0}, - { XK_KP_End, ControlMask, "\033[J", -1, 0}, - { XK_KP_End, ControlMask, "\033[1;5F", +1, 0}, - { XK_KP_End, ShiftMask, "\033[K", -1, 0}, - { XK_KP_End, ShiftMask, "\033[1;2F", +1, 0}, - { XK_KP_End, XK_ANY_MOD, "\033[4~", 0, 0}, - { XK_KP_Next, ShiftMask, "\033[6;2~", 0, 0}, - { XK_KP_Next, XK_ANY_MOD, "\033[6~", 0, 0}, - { XK_KP_Insert, ShiftMask, "\033[2;2~", +1, 0}, - { XK_KP_Insert, ShiftMask, "\033[4l", -1, 0}, - { XK_KP_Insert, ControlMask, "\033[L", -1, 0}, - { XK_KP_Insert, ControlMask, "\033[2;5~", +1, 0}, - { XK_KP_Insert, XK_ANY_MOD, "\033[4h", -1, 0}, - { XK_KP_Insert, XK_ANY_MOD, "\033[2~", +1, 0}, - { XK_KP_Delete, ControlMask, "\033[M", -1, 0}, - { XK_KP_Delete, ControlMask, "\033[3;5~", +1, 0}, - { XK_KP_Delete, ShiftMask, "\033[2K", -1, 0}, - { XK_KP_Delete, ShiftMask, "\033[3;2~", +1, 0}, - { XK_KP_Delete, XK_ANY_MOD, "\033[P", -1, 0}, - { XK_KP_Delete, XK_ANY_MOD, "\033[3~", +1, 0}, - { XK_KP_Multiply, XK_ANY_MOD, "\033Oj", +2, 0}, - { XK_KP_Add, XK_ANY_MOD, "\033Ok", +2, 0}, - { XK_KP_Enter, XK_ANY_MOD, "\033OM", +2, 0}, - { XK_KP_Enter, XK_ANY_MOD, "\r", -1, 0}, - { XK_KP_Subtract, XK_ANY_MOD, "\033Om", +2, 0}, - { XK_KP_Decimal, XK_ANY_MOD, "\033On", +2, 0}, - { XK_KP_Divide, XK_ANY_MOD, "\033Oo", +2, 0}, - { XK_KP_0, XK_ANY_MOD, "\033Op", +2, 0}, - { XK_KP_1, XK_ANY_MOD, "\033Oq", +2, 0}, - { XK_KP_2, XK_ANY_MOD, "\033Or", +2, 0}, - { XK_KP_3, XK_ANY_MOD, "\033Os", +2, 0}, - { XK_KP_4, XK_ANY_MOD, "\033Ot", +2, 0}, - { XK_KP_5, XK_ANY_MOD, "\033Ou", +2, 0}, - { XK_KP_6, XK_ANY_MOD, "\033Ov", +2, 0}, - { XK_KP_7, XK_ANY_MOD, "\033Ow", +2, 0}, - { XK_KP_8, XK_ANY_MOD, "\033Ox", +2, 0}, - { XK_KP_9, XK_ANY_MOD, "\033Oy", +2, 0}, - { XK_Up, ShiftMask, "\033[1;2A", 0, 0}, - { XK_Up, Mod1Mask, "\033[1;3A", 0, 0}, - { XK_Up, ShiftMask|Mod1Mask,"\033[1;4A", 0, 0}, - { XK_Up, ControlMask, "\033[1;5A", 0, 0}, - { XK_Up, ShiftMask|ControlMask,"\033[1;6A", 0, 0}, - { XK_Up, ControlMask|Mod1Mask,"\033[1;7A", 0, 0}, - { XK_Up,ShiftMask|ControlMask|Mod1Mask,"\033[1;8A", 0, 0}, - { XK_Up, XK_ANY_MOD, "\033[A", 0, -1}, - { XK_Up, XK_ANY_MOD, "\033OA", 0, +1}, - { XK_Down, ShiftMask, "\033[1;2B", 0, 0}, - { XK_Down, Mod1Mask, "\033[1;3B", 0, 0}, - { XK_Down, ShiftMask|Mod1Mask,"\033[1;4B", 0, 0}, - { XK_Down, ControlMask, "\033[1;5B", 0, 0}, - { XK_Down, ShiftMask|ControlMask,"\033[1;6B", 0, 0}, - { XK_Down, ControlMask|Mod1Mask,"\033[1;7B", 0, 0}, - { XK_Down,ShiftMask|ControlMask|Mod1Mask,"\033[1;8B",0, 0}, - { XK_Down, XK_ANY_MOD, "\033[B", 0, -1}, - { XK_Down, XK_ANY_MOD, "\033OB", 0, +1}, - { XK_Left, ShiftMask, "\033[1;2D", 0, 0}, - { XK_Left, Mod1Mask, "\033[1;3D", 0, 0}, - { XK_Left, ShiftMask|Mod1Mask,"\033[1;4D", 0, 0}, - { XK_Left, ControlMask, "\033[1;5D", 0, 0}, - { XK_Left, ShiftMask|ControlMask,"\033[1;6D", 0, 0}, - { XK_Left, ControlMask|Mod1Mask,"\033[1;7D", 0, 0}, - { XK_Left,ShiftMask|ControlMask|Mod1Mask,"\033[1;8D",0, 0}, - { XK_Left, XK_ANY_MOD, "\033[D", 0, -1}, - { XK_Left, XK_ANY_MOD, "\033OD", 0, +1}, - { XK_Right, ShiftMask, "\033[1;2C", 0, 0}, - { XK_Right, Mod1Mask, "\033[1;3C", 0, 0}, - { XK_Right, ShiftMask|Mod1Mask,"\033[1;4C", 0, 0}, - { XK_Right, ControlMask, "\033[1;5C", 0, 0}, - { XK_Right, ShiftMask|ControlMask,"\033[1;6C", 0, 0}, - { XK_Right, ControlMask|Mod1Mask,"\033[1;7C", 0, 0}, - { XK_Right,ShiftMask|ControlMask|Mod1Mask,"\033[1;8C",0, 0}, - { XK_Right, XK_ANY_MOD, "\033[C", 0, -1}, - { XK_Right, XK_ANY_MOD, "\033OC", 0, +1}, - { XK_ISO_Left_Tab, ShiftMask, "\033[Z", 0, 0}, - { XK_Return, Mod1Mask, "\033\r", 0, 0}, - { XK_Return, XK_ANY_MOD, "\r", 0, 0}, - { XK_Insert, ShiftMask, "\033[4l", -1, 0}, - { XK_Insert, ShiftMask, "\033[2;2~", +1, 0}, - { XK_Insert, ControlMask, "\033[L", -1, 0}, - { XK_Insert, ControlMask, "\033[2;5~", +1, 0}, - { XK_Insert, XK_ANY_MOD, "\033[4h", -1, 0}, - { XK_Insert, XK_ANY_MOD, "\033[2~", +1, 0}, - { XK_Delete, ControlMask, "\033[M", -1, 0}, - { XK_Delete, ControlMask, "\033[3;5~", +1, 0}, - { XK_Delete, ShiftMask, "\033[2K", -1, 0}, - { XK_Delete, ShiftMask, "\033[3;2~", +1, 0}, - { XK_Delete, XK_ANY_MOD, "\033[P", -1, 0}, - { XK_Delete, XK_ANY_MOD, "\033[3~", +1, 0}, - { XK_BackSpace, XK_NO_MOD, "\177", 0, 0}, - { XK_BackSpace, Mod1Mask, "\033\177", 0, 0}, - { XK_Home, ShiftMask, "\033[2J", 0, -1}, - { XK_Home, ShiftMask, "\033[1;2H", 0, +1}, - { XK_Home, XK_ANY_MOD, "\033[H", 0, -1}, - { XK_Home, XK_ANY_MOD, "\033[1~", 0, +1}, - { XK_End, ControlMask, "\033[J", -1, 0}, - { XK_End, ControlMask, "\033[1;5F", +1, 0}, - { XK_End, ShiftMask, "\033[K", -1, 0}, - { XK_End, ShiftMask, "\033[1;2F", +1, 0}, - { XK_End, XK_ANY_MOD, "\033[4~", 0, 0}, - { XK_Prior, ControlMask, "\033[5;5~", 0, 0}, - { XK_Prior, ShiftMask, "\033[5;2~", 0, 0}, - { XK_Prior, XK_ANY_MOD, "\033[5~", 0, 0}, - { XK_Next, ControlMask, "\033[6;5~", 0, 0}, - { XK_Next, ShiftMask, "\033[6;2~", 0, 0}, - { XK_Next, XK_ANY_MOD, "\033[6~", 0, 0}, - { XK_F1, XK_NO_MOD, "\033OP" , 0, 0}, - { XK_F1, /* F13 */ ShiftMask, "\033[1;2P", 0, 0}, - { XK_F1, /* F25 */ ControlMask, "\033[1;5P", 0, 0}, - { XK_F1, /* F37 */ Mod4Mask, "\033[1;6P", 0, 0}, - { XK_F1, /* F49 */ Mod1Mask, "\033[1;3P", 0, 0}, - { XK_F1, /* F61 */ Mod3Mask, "\033[1;4P", 0, 0}, - { XK_F2, XK_NO_MOD, "\033OQ" , 0, 0}, - { XK_F2, /* F14 */ ShiftMask, "\033[1;2Q", 0, 0}, - { XK_F2, /* F26 */ ControlMask, "\033[1;5Q", 0, 0}, - { XK_F2, /* F38 */ Mod4Mask, "\033[1;6Q", 0, 0}, - { XK_F2, /* F50 */ Mod1Mask, "\033[1;3Q", 0, 0}, - { XK_F2, /* F62 */ Mod3Mask, "\033[1;4Q", 0, 0}, - { XK_F3, XK_NO_MOD, "\033OR" , 0, 0}, - { XK_F3, /* F15 */ ShiftMask, "\033[1;2R", 0, 0}, - { XK_F3, /* F27 */ ControlMask, "\033[1;5R", 0, 0}, - { XK_F3, /* F39 */ Mod4Mask, "\033[1;6R", 0, 0}, - { XK_F3, /* F51 */ Mod1Mask, "\033[1;3R", 0, 0}, - { XK_F3, /* F63 */ Mod3Mask, "\033[1;4R", 0, 0}, - { XK_F4, XK_NO_MOD, "\033OS" , 0, 0}, - { XK_F4, /* F16 */ ShiftMask, "\033[1;2S", 0, 0}, - { XK_F4, /* F28 */ ControlMask, "\033[1;5S", 0, 0}, - { XK_F4, /* F40 */ Mod4Mask, "\033[1;6S", 0, 0}, - { XK_F4, /* F52 */ Mod1Mask, "\033[1;3S", 0, 0}, - { XK_F5, XK_NO_MOD, "\033[15~", 0, 0}, - { XK_F5, /* F17 */ ShiftMask, "\033[15;2~", 0, 0}, - { XK_F5, /* F29 */ ControlMask, "\033[15;5~", 0, 0}, - { XK_F5, /* F41 */ Mod4Mask, "\033[15;6~", 0, 0}, - { XK_F5, /* F53 */ Mod1Mask, "\033[15;3~", 0, 0}, - { XK_F6, XK_NO_MOD, "\033[17~", 0, 0}, - { XK_F6, /* F18 */ ShiftMask, "\033[17;2~", 0, 0}, - { XK_F6, /* F30 */ ControlMask, "\033[17;5~", 0, 0}, - { XK_F6, /* F42 */ Mod4Mask, "\033[17;6~", 0, 0}, - { XK_F6, /* F54 */ Mod1Mask, "\033[17;3~", 0, 0}, - { XK_F7, XK_NO_MOD, "\033[18~", 0, 0}, - { XK_F7, /* F19 */ ShiftMask, "\033[18;2~", 0, 0}, - { XK_F7, /* F31 */ ControlMask, "\033[18;5~", 0, 0}, - { XK_F7, /* F43 */ Mod4Mask, "\033[18;6~", 0, 0}, - { XK_F7, /* F55 */ Mod1Mask, "\033[18;3~", 0, 0}, - { XK_F8, XK_NO_MOD, "\033[19~", 0, 0}, - { XK_F8, /* F20 */ ShiftMask, "\033[19;2~", 0, 0}, - { XK_F8, /* F32 */ ControlMask, "\033[19;5~", 0, 0}, - { XK_F8, /* F44 */ Mod4Mask, "\033[19;6~", 0, 0}, - { XK_F8, /* F56 */ Mod1Mask, "\033[19;3~", 0, 0}, - { XK_F9, XK_NO_MOD, "\033[20~", 0, 0}, - { XK_F9, /* F21 */ ShiftMask, "\033[20;2~", 0, 0}, - { XK_F9, /* F33 */ ControlMask, "\033[20;5~", 0, 0}, - { XK_F9, /* F45 */ Mod4Mask, "\033[20;6~", 0, 0}, - { XK_F9, /* F57 */ Mod1Mask, "\033[20;3~", 0, 0}, - { XK_F10, XK_NO_MOD, "\033[21~", 0, 0}, - { XK_F10, /* F22 */ ShiftMask, "\033[21;2~", 0, 0}, - { XK_F10, /* F34 */ ControlMask, "\033[21;5~", 0, 0}, - { XK_F10, /* F46 */ Mod4Mask, "\033[21;6~", 0, 0}, - { XK_F10, /* F58 */ Mod1Mask, "\033[21;3~", 0, 0}, - { XK_F11, XK_NO_MOD, "\033[23~", 0, 0}, - { XK_F11, /* F23 */ ShiftMask, "\033[23;2~", 0, 0}, - { XK_F11, /* F35 */ ControlMask, "\033[23;5~", 0, 0}, - { XK_F11, /* F47 */ Mod4Mask, "\033[23;6~", 0, 0}, - { XK_F11, /* F59 */ Mod1Mask, "\033[23;3~", 0, 0}, - { XK_F12, XK_NO_MOD, "\033[24~", 0, 0}, - { XK_F12, /* F24 */ ShiftMask, "\033[24;2~", 0, 0}, - { XK_F12, /* F36 */ ControlMask, "\033[24;5~", 0, 0}, - { XK_F12, /* F48 */ Mod4Mask, "\033[24;6~", 0, 0}, - { XK_F12, /* F60 */ Mod1Mask, "\033[24;3~", 0, 0}, - { XK_F13, XK_NO_MOD, "\033[1;2P", 0, 0}, - { XK_F14, XK_NO_MOD, "\033[1;2Q", 0, 0}, - { XK_F15, XK_NO_MOD, "\033[1;2R", 0, 0}, - { XK_F16, XK_NO_MOD, "\033[1;2S", 0, 0}, - { XK_F17, XK_NO_MOD, "\033[15;2~", 0, 0}, - { XK_F18, XK_NO_MOD, "\033[17;2~", 0, 0}, - { XK_F19, XK_NO_MOD, "\033[18;2~", 0, 0}, - { XK_F20, XK_NO_MOD, "\033[19;2~", 0, 0}, - { XK_F21, XK_NO_MOD, "\033[20;2~", 0, 0}, - { XK_F22, XK_NO_MOD, "\033[21;2~", 0, 0}, - { XK_F23, XK_NO_MOD, "\033[23;2~", 0, 0}, - { XK_F24, XK_NO_MOD, "\033[24;2~", 0, 0}, - { XK_F25, XK_NO_MOD, "\033[1;5P", 0, 0}, - { XK_F26, XK_NO_MOD, "\033[1;5Q", 0, 0}, - { XK_F27, XK_NO_MOD, "\033[1;5R", 0, 0}, - { XK_F28, XK_NO_MOD, "\033[1;5S", 0, 0}, - { XK_F29, XK_NO_MOD, "\033[15;5~", 0, 0}, - { XK_F30, XK_NO_MOD, "\033[17;5~", 0, 0}, - { XK_F31, XK_NO_MOD, "\033[18;5~", 0, 0}, - { XK_F32, XK_NO_MOD, "\033[19;5~", 0, 0}, - { XK_F33, XK_NO_MOD, "\033[20;5~", 0, 0}, - { XK_F34, XK_NO_MOD, "\033[21;5~", 0, 0}, - { XK_F35, XK_NO_MOD, "\033[23;5~", 0, 0}, -}; - -/* - * Selection types' masks. - * Use the same masks as usual. - * Button1Mask is always unset, to make masks match between ButtonPress. - * ButtonRelease and MotionNotify. - * If no match is found, regular selection is used. - */ -static uint selmasks[] = { - [SEL_RECTANGULAR] = Mod1Mask, -}; - -/* - * Printable characters in ASCII, used to estimate the advance width - * of single wide characters. - */ -static char ascii_printable[] = - " !\"#$%&'()*+,-./0123456789:;<=>?" - "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_" - "`abcdefghijklmnopqrstuvwxyz{|}~"; diff --git a/suckless/st/config.h.save.3 b/suckless/st/config.h.save.3 deleted file mode 100644 index e2169a7..0000000 --- a/suckless/st/config.h.save.3 +++ /dev/null @@ -1,486 +0,0 @@ -/* See LICENSE file for copyright and license details. */ - -/* - * appearance - * - * font: see http://freedesktop.org/software/fontconfig/fontconfig-user.html - */ -static char *font = "Terminus-9: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 = 2; -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; - -/* bg opacity */ -float alpha = 0.8; - -/* Background opacity */ -float alpha_def; - -/* Terminal colors (16 first used in escape sequence) */ -static const char *colorname[] = { - - /* 8 normal colors */ - "#333e21", /* black */ - "#757849", /* red */ - "#FF432A", /* green */ - "#c83e72", /* yellow */ - "#448C2C", /* blue */ - "#7d5f5f", /* magenta */ - "#bd8c77", /* cyan */ - "#efdceb", /* white */ - - /* 8 bright colors */ - "#686e50", /* black */ - "#A6AA6A", /* red */ - "#fa6d5a", /* green */ - "#d3658e", /* yellow */ - "#80BD6C", /* blue */ - "#B38887", /* magenta */ - "#f0bfaa", /* cyan */ - "#ffffff", /* white */ - - [255] = 0, - - /* more colors can be added after 255 to use with DefaultXX */ - "gray90", /* default foreground colour */ - "black", /* default background colour */ -}; - - -/* - * Default colors (colorname index) - * foreground, background, cursor, reverse cursor - */ -unsigned int defaultfg = 256; -unsigned int defaultbg = 257; -unsigned int defaultcs = 256; -static unsigned int defaultrcs = 257; - -/* - * Default shape of cursor - * 2: Block ("█") - * 4: Underline ("_") - * 6: Bar ("|") - * 7: Snowman ("☃") - */ -static unsigned int cursorshape = 6; - -/* - * 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_NO_MOD, Button4, kscrollup, {.i = 1} }, - { XK_NO_MOD, Button5, kscrolldown, {.i = 1} }, - { XK_ANY_MOD, Button2, selpaste, {.i = 0}, 1 }, - { ShiftMask, Button4, ttysend, {.s = "\033[5;2~"} }, - { XK_ANY_MOD, Button4, ttysend, {.s = "\031"} }, - { ShiftMask, Button5, ttysend, {.s = "\033[6;2~"} }, - { XK_ANY_MOD, Button5, ttysend, {.s = "\005"} }, -}; - -/* Internal keyboard shortcuts. */ -#define MODKEY Mod1Mask -#define TERMMOD (Mod1Mask|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} }, - { ControlMask, XK_equal, zoom, {.f = +1} }, - { ControlMask, XK_minus, zoom, {.f = -1} }, - { TERMMOD, XK_Home, zoomreset, {.f = 0} }, - { MODKEY, XK_c, clipcopy, {.i = 0} }, - { MODKEY, 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_k, kscrollup, {.i = 1} }, - { ShiftMask, XK_j, kscrolldown, {.i = 1} }, - { MODKEY, XK_a, chgalpha, {.f = -1} }, - { MODKEY, XK_s, chgalpha, {.f = +1} }, - { MODKEY, XK_d, chgalpha, {.f = 0} }, -}; - -/* - * Special keys (change & recompile st.info accordingly) - * - * Mask value: - * * Use XK_ANY_MOD to match the key no matter modifiers state - * * Use XK_NO_MOD to match the key alone (no modifiers) - * appkey value: - * * 0: no value - * * > 0: keypad application mode enabled - * * = 2: term.numlock = 1 - * * < 0: keypad application mode disabled - * appcursor value: - * * 0: no value - * * > 0: cursor application mode enabled - * * < 0: cursor application mode disabled - * - * Be careful with the order of the definitions because st searches in - * this table sequentially, so any XK_ANY_MOD must be in the last - * position for a key. - */ - -/* - * If you want keys other than the X11 function keys (0xFD00 - 0xFFFF) - * to be mapped below, add them to this array. - */ -static KeySym mappedkeys[] = { -1 }; - -/* - * State bits to ignore when matching key or button events. By default, - * numlock (Mod2Mask) and keyboard layout (XK_SWITCH_MOD) are ignored. - */ -static uint ignoremod = Mod2Mask|XK_SWITCH_MOD; - -/* - * This is the huge key array which defines all compatibility to the Linux - * world. Please decide about changes wisely. - */ -static Key key[] = { - /* keysym mask string appkey appcursor */ - { XK_KP_Home, ShiftMask, "\033[2J", 0, -1}, - { XK_KP_Home, ShiftMask, "\033[1;2H", 0, +1}, - { XK_KP_Home, XK_ANY_MOD, "\033[H", 0, -1}, - { XK_KP_Home, XK_ANY_MOD, "\033[1~", 0, +1}, - { XK_KP_Up, XK_ANY_MOD, "\033Ox", +1, 0}, - { XK_KP_Up, XK_ANY_MOD, "\033[A", 0, -1}, - { XK_KP_Up, XK_ANY_MOD, "\033OA", 0, +1}, - { XK_KP_Down, XK_ANY_MOD, "\033Or", +1, 0}, - { XK_KP_Down, XK_ANY_MOD, "\033[B", 0, -1}, - { XK_KP_Down, XK_ANY_MOD, "\033OB", 0, +1}, - { XK_KP_Left, XK_ANY_MOD, "\033Ot", +1, 0}, - { XK_KP_Left, XK_ANY_MOD, "\033[D", 0, -1}, - { XK_KP_Left, XK_ANY_MOD, "\033OD", 0, +1}, - { XK_KP_Right, XK_ANY_MOD, "\033Ov", +1, 0}, - { XK_KP_Right, XK_ANY_MOD, "\033[C", 0, -1}, - { XK_KP_Right, XK_ANY_MOD, "\033OC", 0, +1}, - { XK_KP_Prior, ShiftMask, "\033[5;2~", 0, 0}, - { XK_KP_Prior, XK_ANY_MOD, "\033[5~", 0, 0}, - { XK_KP_Begin, XK_ANY_MOD, "\033[E", 0, 0}, - { XK_KP_End, ControlMask, "\033[J", -1, 0}, - { XK_KP_End, ControlMask, "\033[1;5F", +1, 0}, - { XK_KP_End, ShiftMask, "\033[K", -1, 0}, - { XK_KP_End, ShiftMask, "\033[1;2F", +1, 0}, - { XK_KP_End, XK_ANY_MOD, "\033[4~", 0, 0}, - { XK_KP_Next, ShiftMask, "\033[6;2~", 0, 0}, - { XK_KP_Next, XK_ANY_MOD, "\033[6~", 0, 0}, - { XK_KP_Insert, ShiftMask, "\033[2;2~", +1, 0}, - { XK_KP_Insert, ShiftMask, "\033[4l", -1, 0}, - { XK_KP_Insert, ControlMask, "\033[L", -1, 0}, - { XK_KP_Insert, ControlMask, "\033[2;5~", +1, 0}, - { XK_KP_Insert, XK_ANY_MOD, "\033[4h", -1, 0}, - { XK_KP_Insert, XK_ANY_MOD, "\033[2~", +1, 0}, - { XK_KP_Delete, ControlMask, "\033[M", -1, 0}, - { XK_KP_Delete, ControlMask, "\033[3;5~", +1, 0}, - { XK_KP_Delete, ShiftMask, "\033[2K", -1, 0}, - { XK_KP_Delete, ShiftMask, "\033[3;2~", +1, 0}, - { XK_KP_Delete, XK_ANY_MOD, "\033[P", -1, 0}, - { XK_KP_Delete, XK_ANY_MOD, "\033[3~", +1, 0}, - { XK_KP_Multiply, XK_ANY_MOD, "\033Oj", +2, 0}, - { XK_KP_Add, XK_ANY_MOD, "\033Ok", +2, 0}, - { XK_KP_Enter, XK_ANY_MOD, "\033OM", +2, 0}, - { XK_KP_Enter, XK_ANY_MOD, "\r", -1, 0}, - { XK_KP_Subtract, XK_ANY_MOD, "\033Om", +2, 0}, - { XK_KP_Decimal, XK_ANY_MOD, "\033On", +2, 0}, - { XK_KP_Divide, XK_ANY_MOD, "\033Oo", +2, 0}, - { XK_KP_0, XK_ANY_MOD, "\033Op", +2, 0}, - { XK_KP_1, XK_ANY_MOD, "\033Oq", +2, 0}, - { XK_KP_2, XK_ANY_MOD, "\033Or", +2, 0}, - { XK_KP_3, XK_ANY_MOD, "\033Os", +2, 0}, - { XK_KP_4, XK_ANY_MOD, "\033Ot", +2, 0}, - { XK_KP_5, XK_ANY_MOD, "\033Ou", +2, 0}, - { XK_KP_6, XK_ANY_MOD, "\033Ov", +2, 0}, - { XK_KP_7, XK_ANY_MOD, "\033Ow", +2, 0}, - { XK_KP_8, XK_ANY_MOD, "\033Ox", +2, 0}, - { XK_KP_9, XK_ANY_MOD, "\033Oy", +2, 0}, - { XK_Up, ShiftMask, "\033[1;2A", 0, 0}, - { XK_Up, Mod1Mask, "\033[1;3A", 0, 0}, - { XK_Up, ShiftMask|Mod1Mask,"\033[1;4A", 0, 0}, - { XK_Up, ControlMask, "\033[1;5A", 0, 0}, - { XK_Up, ShiftMask|ControlMask,"\033[1;6A", 0, 0}, - { XK_Up, ControlMask|Mod1Mask,"\033[1;7A", 0, 0}, - { XK_Up,ShiftMask|ControlMask|Mod1Mask,"\033[1;8A", 0, 0}, - { XK_Up, XK_ANY_MOD, "\033[A", 0, -1}, - { XK_Up, XK_ANY_MOD, "\033OA", 0, +1}, - { XK_Down, ShiftMask, "\033[1;2B", 0, 0}, - { XK_Down, Mod1Mask, "\033[1;3B", 0, 0}, - { XK_Down, ShiftMask|Mod1Mask,"\033[1;4B", 0, 0}, - { XK_Down, ControlMask, "\033[1;5B", 0, 0}, - { XK_Down, ShiftMask|ControlMask,"\033[1;6B", 0, 0}, - { XK_Down, ControlMask|Mod1Mask,"\033[1;7B", 0, 0}, - { XK_Down,ShiftMask|ControlMask|Mod1Mask,"\033[1;8B",0, 0}, - { XK_Down, XK_ANY_MOD, "\033[B", 0, -1}, - { XK_Down, XK_ANY_MOD, "\033OB", 0, +1}, - { XK_Left, ShiftMask, "\033[1;2D", 0, 0}, - { XK_Left, Mod1Mask, "\033[1;3D", 0, 0}, - { XK_Left, ShiftMask|Mod1Mask,"\033[1;4D", 0, 0}, - { XK_Left, ControlMask, "\033[1;5D", 0, 0}, - { XK_Left, ShiftMask|ControlMask,"\033[1;6D", 0, 0}, - { XK_Left, ControlMask|Mod1Mask,"\033[1;7D", 0, 0}, - { XK_Left,ShiftMask|ControlMask|Mod1Mask,"\033[1;8D",0, 0}, - { XK_Left, XK_ANY_MOD, "\033[D", 0, -1}, - { XK_Left, XK_ANY_MOD, "\033OD", 0, +1}, - { XK_Right, ShiftMask, "\033[1;2C", 0, 0}, - { XK_Right, Mod1Mask, "\033[1;3C", 0, 0}, - { XK_Right, ShiftMask|Mod1Mask,"\033[1;4C", 0, 0}, - { XK_Right, ControlMask, "\033[1;5C", 0, 0}, - { XK_Right, ShiftMask|ControlMask,"\033[1;6C", 0, 0}, - { XK_Right, ControlMask|Mod1Mask,"\033[1;7C", 0, 0}, - { XK_Right,ShiftMask|ControlMask|Mod1Mask,"\033[1;8C",0, 0}, - { XK_Right, XK_ANY_MOD, "\033[C", 0, -1}, - { XK_Right, XK_ANY_MOD, "\033OC", 0, +1}, - { XK_ISO_Left_Tab, ShiftMask, "\033[Z", 0, 0}, - { XK_Return, Mod1Mask, "\033\r", 0, 0}, - { XK_Return, XK_ANY_MOD, "\r", 0, 0}, - { XK_Insert, ShiftMask, "\033[4l", -1, 0}, - { XK_Insert, ShiftMask, "\033[2;2~", +1, 0}, - { XK_Insert, ControlMask, "\033[L", -1, 0}, - { XK_Insert, ControlMask, "\033[2;5~", +1, 0}, - { XK_Insert, XK_ANY_MOD, "\033[4h", -1, 0}, - { XK_Insert, XK_ANY_MOD, "\033[2~", +1, 0}, - { XK_Delete, ControlMask, "\033[M", -1, 0}, - { XK_Delete, ControlMask, "\033[3;5~", +1, 0}, - { XK_Delete, ShiftMask, "\033[2K", -1, 0}, - { XK_Delete, ShiftMask, "\033[3;2~", +1, 0}, - { XK_Delete, XK_ANY_MOD, "\033[P", -1, 0}, - { XK_Delete, XK_ANY_MOD, "\033[3~", +1, 0}, - { XK_BackSpace, XK_NO_MOD, "\177", 0, 0}, - { XK_BackSpace, Mod1Mask, "\033\177", 0, 0}, - { XK_Home, ShiftMask, "\033[2J", 0, -1}, - { XK_Home, ShiftMask, "\033[1;2H", 0, +1}, - { XK_Home, XK_ANY_MOD, "\033[H", 0, -1}, - { XK_Home, XK_ANY_MOD, "\033[1~", 0, +1}, - { XK_End, ControlMask, "\033[J", -1, 0}, - { XK_End, ControlMask, "\033[1;5F", +1, 0}, - { XK_End, ShiftMask, "\033[K", -1, 0}, - { XK_End, ShiftMask, "\033[1;2F", +1, 0}, - { XK_End, XK_ANY_MOD, "\033[4~", 0, 0}, - { XK_Prior, ControlMask, "\033[5;5~", 0, 0}, - { XK_Prior, ShiftMask, "\033[5;2~", 0, 0}, - { XK_Prior, XK_ANY_MOD, "\033[5~", 0, 0}, - { XK_Next, ControlMask, "\033[6;5~", 0, 0}, - { XK_Next, ShiftMask, "\033[6;2~", 0, 0}, - { XK_Next, XK_ANY_MOD, "\033[6~", 0, 0}, - { XK_F1, XK_NO_MOD, "\033OP" , 0, 0}, - { XK_F1, /* F13 */ ShiftMask, "\033[1;2P", 0, 0}, - { XK_F1, /* F25 */ ControlMask, "\033[1;5P", 0, 0}, - { XK_F1, /* F37 */ Mod4Mask, "\033[1;6P", 0, 0}, - { XK_F1, /* F49 */ Mod1Mask, "\033[1;3P", 0, 0}, - { XK_F1, /* F61 */ Mod3Mask, "\033[1;4P", 0, 0}, - { XK_F2, XK_NO_MOD, "\033OQ" , 0, 0}, - { XK_F2, /* F14 */ ShiftMask, "\033[1;2Q", 0, 0}, - { XK_F2, /* F26 */ ControlMask, "\033[1;5Q", 0, 0}, - { XK_F2, /* F38 */ Mod4Mask, "\033[1;6Q", 0, 0}, - { XK_F2, /* F50 */ Mod1Mask, "\033[1;3Q", 0, 0}, - { XK_F2, /* F62 */ Mod3Mask, "\033[1;4Q", 0, 0}, - { XK_F3, XK_NO_MOD, "\033OR" , 0, 0}, - { XK_F3, /* F15 */ ShiftMask, "\033[1;2R", 0, 0}, - { XK_F3, /* F27 */ ControlMask, "\033[1;5R", 0, 0}, - { XK_F3, /* F39 */ Mod4Mask, "\033[1;6R", 0, 0}, - { XK_F3, /* F51 */ Mod1Mask, "\033[1;3R", 0, 0}, - { XK_F3, /* F63 */ Mod3Mask, "\033[1;4R", 0, 0}, - { XK_F4, XK_NO_MOD, "\033OS" , 0, 0}, - { XK_F4, /* F16 */ ShiftMask, "\033[1;2S", 0, 0}, - { XK_F4, /* F28 */ ControlMask, "\033[1;5S", 0, 0}, - { XK_F4, /* F40 */ Mod4Mask, "\033[1;6S", 0, 0}, - { XK_F4, /* F52 */ Mod1Mask, "\033[1;3S", 0, 0}, - { XK_F5, XK_NO_MOD, "\033[15~", 0, 0}, - { XK_F5, /* F17 */ ShiftMask, "\033[15;2~", 0, 0}, - { XK_F5, /* F29 */ ControlMask, "\033[15;5~", 0, 0}, - { XK_F5, /* F41 */ Mod4Mask, "\033[15;6~", 0, 0}, - { XK_F5, /* F53 */ Mod1Mask, "\033[15;3~", 0, 0}, - { XK_F6, XK_NO_MOD, "\033[17~", 0, 0}, - { XK_F6, /* F18 */ ShiftMask, "\033[17;2~", 0, 0}, - { XK_F6, /* F30 */ ControlMask, "\033[17;5~", 0, 0}, - { XK_F6, /* F42 */ Mod4Mask, "\033[17;6~", 0, 0}, - { XK_F6, /* F54 */ Mod1Mask, "\033[17;3~", 0, 0}, - { XK_F7, XK_NO_MOD, "\033[18~", 0, 0}, - { XK_F7, /* F19 */ ShiftMask, "\033[18;2~", 0, 0}, - { XK_F7, /* F31 */ ControlMask, "\033[18;5~", 0, 0}, - { XK_F7, /* F43 */ Mod4Mask, "\033[18;6~", 0, 0}, - { XK_F7, /* F55 */ Mod1Mask, "\033[18;3~", 0, 0}, - { XK_F8, XK_NO_MOD, "\033[19~", 0, 0}, - { XK_F8, /* F20 */ ShiftMask, "\033[19;2~", 0, 0}, - { XK_F8, /* F32 */ ControlMask, "\033[19;5~", 0, 0}, - { XK_F8, /* F44 */ Mod4Mask, "\033[19;6~", 0, 0}, - { XK_F8, /* F56 */ Mod1Mask, "\033[19;3~", 0, 0}, - { XK_F9, XK_NO_MOD, "\033[20~", 0, 0}, - { XK_F9, /* F21 */ ShiftMask, "\033[20;2~", 0, 0}, - { XK_F9, /* F33 */ ControlMask, "\033[20;5~", 0, 0}, - { XK_F9, /* F45 */ Mod4Mask, "\033[20;6~", 0, 0}, - { XK_F9, /* F57 */ Mod1Mask, "\033[20;3~", 0, 0}, - { XK_F10, XK_NO_MOD, "\033[21~", 0, 0}, - { XK_F10, /* F22 */ ShiftMask, "\033[21;2~", 0, 0}, - { XK_F10, /* F34 */ ControlMask, "\033[21;5~", 0, 0}, - { XK_F10, /* F46 */ Mod4Mask, "\033[21;6~", 0, 0}, - { XK_F10, /* F58 */ Mod1Mask, "\033[21;3~", 0, 0}, - { XK_F11, XK_NO_MOD, "\033[23~", 0, 0}, - { XK_F11, /* F23 */ ShiftMask, "\033[23;2~", 0, 0}, - { XK_F11, /* F35 */ ControlMask, "\033[23;5~", 0, 0}, - { XK_F11, /* F47 */ Mod4Mask, "\033[23;6~", 0, 0}, - { XK_F11, /* F59 */ Mod1Mask, "\033[23;3~", 0, 0}, - { XK_F12, XK_NO_MOD, "\033[24~", 0, 0}, - { XK_F12, /* F24 */ ShiftMask, "\033[24;2~", 0, 0}, - { XK_F12, /* F36 */ ControlMask, "\033[24;5~", 0, 0}, - { XK_F12, /* F48 */ Mod4Mask, "\033[24;6~", 0, 0}, - { XK_F12, /* F60 */ Mod1Mask, "\033[24;3~", 0, 0}, - { XK_F13, XK_NO_MOD, "\033[1;2P", 0, 0}, - { XK_F14, XK_NO_MOD, "\033[1;2Q", 0, 0}, - { XK_F15, XK_NO_MOD, "\033[1;2R", 0, 0}, - { XK_F16, XK_NO_MOD, "\033[1;2S", 0, 0}, - { XK_F17, XK_NO_MOD, "\033[15;2~", 0, 0}, - { XK_F18, XK_NO_MOD, "\033[17;2~", 0, 0}, - { XK_F19, XK_NO_MOD, "\033[18;2~", 0, 0}, - { XK_F20, XK_NO_MOD, "\033[19;2~", 0, 0}, - { XK_F21, XK_NO_MOD, "\033[20;2~", 0, 0}, - { XK_F22, XK_NO_MOD, "\033[21;2~", 0, 0}, - { XK_F23, XK_NO_MOD, "\033[23;2~", 0, 0}, - { XK_F24, XK_NO_MOD, "\033[24;2~", 0, 0}, - { XK_F25, XK_NO_MOD, "\033[1;5P", 0, 0}, - { XK_F26, XK_NO_MOD, "\033[1;5Q", 0, 0}, - { XK_F27, XK_NO_MOD, "\033[1;5R", 0, 0}, - { XK_F28, XK_NO_MOD, "\033[1;5S", 0, 0}, - { XK_F29, XK_NO_MOD, "\033[15;5~", 0, 0}, - { XK_F30, XK_NO_MOD, "\033[17;5~", 0, 0}, - { XK_F31, XK_NO_MOD, "\033[18;5~", 0, 0}, - { XK_F32, XK_NO_MOD, "\033[19;5~", 0, 0}, - { XK_F33, XK_NO_MOD, "\033[20;5~", 0, 0}, - { XK_F34, XK_NO_MOD, "\033[21;5~", 0, 0}, - { XK_F35, XK_NO_MOD, "\033[23;5~", 0, 0}, -}; - -/* - * Selection types' masks. - * Use the same masks as usual. - * Button1Mask is always unset, to make masks match between ButtonPress. - * ButtonRelease and MotionNotify. - * If no match is found, regular selection is used. - */ -static uint selmasks[] = { - [SEL_RECTANGULAR] = Mod1Mask, -}; - -/* - * Printable characters in ASCII, used to estimate the advance width - * of single wide characters. - */ -static char ascii_printable[] = - " !\"#$%&'()*+,-./0123456789:;<=>?" - "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_" - "`abcdefghijklmnopqrstuvwxyz{|}~"; diff --git a/suckless/st/config.mk b/suckless/st/config.mk deleted file mode 100644 index b6458af..0000000 --- a/suckless/st/config.mk +++ /dev/null @@ -1,38 +0,0 @@ -# st version -VERSION = 0.9.2 - -# 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` \ - `$(PKG_CONFIG) --cflags harfbuzz` -LIBS = -L$(X11LIB) -lm -lrt -lX11 -lutil -lXft -lXrender \ - `$(PKG_CONFIG) --libs fontconfig` \ - `$(PKG_CONFIG) --libs freetype2` \ - `$(PKG_CONFIG) --libs harfbuzz` - -# 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` -#MANPREFIX = ${PREFIX}/man - -# compiler and linker -# CC = c99 diff --git a/suckless/st/graphics.c b/suckless/st/graphics.c deleted file mode 100644 index 64e6fe0..0000000 --- a/suckless/st/graphics.c +++ /dev/null @@ -1,3812 +0,0 @@ -/* The MIT License - - Copyright (c) 2021-2024 Sergei Grechanik - - 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. -*/ - -//////////////////////////////////////////////////////////////////////////////// -// -// This file implements a subset of the kitty graphics protocol. -// -//////////////////////////////////////////////////////////////////////////////// - -#define _POSIX_C_SOURCE 200809L - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "graphics.h" -#include "khash.h" -#include "kvec.h" - -extern char **environ; - -#define MAX_FILENAME_SIZE 256 -#define MAX_INFO_LEN 256 -#define MAX_IMAGE_RECTS 20 - -/// The type used in this file to represent time. Used both for time differences -/// and absolute times (as milliseconds since an arbitrary point in time, see -/// `initialization_time`). -typedef int64_t Milliseconds; - -enum ScaleMode { - SCALE_MODE_UNSET = 0, - /// Stretch or shrink the image to fill the box, ignoring aspect ratio. - SCALE_MODE_FILL = 1, - /// Preserve aspect ratio and fit to width or to height so that the - /// whole image is visible. - SCALE_MODE_CONTAIN = 2, - /// Do not scale. The image may be cropped if the box is too small. - SCALE_MODE_NONE = 3, - /// Do not scale, unless the box is too small, in which case the image - /// will be shrunk like with `SCALE_MODE_CONTAIN`. - SCALE_MODE_NONE_OR_CONTAIN = 4, -}; - -enum AnimationState { - ANIMATION_STATE_UNSET = 0, - /// The animation is stopped. Display the current frame, but don't - /// advance to the next one. - ANIMATION_STATE_STOPPED = 1, - /// Run the animation to then end, then wait for the next frame. - ANIMATION_STATE_LOADING = 2, - /// Run the animation in a loop. - ANIMATION_STATE_LOOPING = 3, -}; - -/// The status of an image. Each image uploaded to the terminal is cached on -/// disk, then it is loaded to ram when needed. -enum ImageStatus { - STATUS_UNINITIALIZED = 0, - STATUS_UPLOADING = 1, - STATUS_UPLOADING_ERROR = 2, - STATUS_UPLOADING_SUCCESS = 3, - STATUS_RAM_LOADING_ERROR = 4, - STATUS_RAM_LOADING_IN_PROGRESS = 5, - STATUS_RAM_LOADING_SUCCESS = 6, -}; - -const char *image_status_strings[6] = { - "STATUS_UNINITIALIZED", - "STATUS_UPLOADING", - "STATUS_UPLOADING_ERROR", - "STATUS_UPLOADING_SUCCESS", - "STATUS_RAM_LOADING_ERROR", - "STATUS_RAM_LOADING_SUCCESS", -}; - -enum ImageUploadingFailure { - ERROR_OVER_SIZE_LIMIT = 1, - ERROR_CANNOT_OPEN_CACHED_FILE = 2, - ERROR_UNEXPECTED_SIZE = 3, - ERROR_CANNOT_COPY_FILE = 4, -}; - -const char *image_uploading_failure_strings[5] = { - "NO_ERROR", - "ERROR_OVER_SIZE_LIMIT", - "ERROR_CANNOT_OPEN_CACHED_FILE", - "ERROR_UNEXPECTED_SIZE", - "ERROR_CANNOT_COPY_FILE", -}; - -//////////////////////////////////////////////////////////////////////////////// -// -// We use the following structures to represent images and placements: -// -// - Image: this is the main structure representing an image, usually created -// by actions 'a=t', 'a=T`. Each image has an id (image id aka client id, -// specified by 'i='). An image may have multiple frames (ImageFrame) and -// placements (ImagePlacement). -// -// - ImageFrame: represents a single frame of an image, usually created by -// the action 'a=f' (and the first frame is created with the image itself). -// Each frame has an index and also: -// - a file containing the frame data (considered to be "on disk", although -// it's probably in tmpfs), -// - an imlib object containing the fully composed frame (i.e. the frame -// data from the file composed onto the background frame or color). It is -// not ready for display yet, because it needs to be scaled and uploaded -// to the X server. -// -// - ImagePlacement: represents a placement of an image, created by 'a=p' and -// 'a=T'. Each placement has an id (placement id, specified by 'p='). Also -// each placement has an array of pixmaps: one for each frame of the image. -// Each pixmap is a scaled and uploaded image ready to be displayed. -// -// Images are store in the `images` hash table, mapping image ids to Image -// objects (allocated on the heap). -// -// Placements are stored in the `placements` hash table of each Image object, -// mapping placement ids to ImagePlacement objects (also allocated on the heap). -// -// ImageFrames are stored in the `first_frame` field and in the -// `frames_beyond_the_first` array of each Image object. They are stored by -// value, so ImageFrame pointer may be invalidated when frames are -// added/deleted, be careful. -// -//////////////////////////////////////////////////////////////////////////////// - -struct Image; -struct ImageFrame; -struct ImagePlacement; - -KHASH_MAP_INIT_INT(id2image, struct Image *) -KHASH_MAP_INIT_INT(id2placement, struct ImagePlacement *) - -typedef struct ImageFrame { - /// The image this frame belongs to. - struct Image *image; - /// The 1-based index of the frame. Zero if the frame isn't initialized. - int index; - /// The last time when the frame was displayed or otherwise touched. - Milliseconds atime; - /// The background color of the frame in the 0xRRGGBBAA format. - uint32_t background_color; - /// The index of the background frame. Zero to use the color instead. - int background_frame_index; - /// The duration of the frame in milliseconds. - int gap; - /// The expected size of the frame image file (specified with 'S='), - /// used to check if uploading succeeded. - unsigned expected_size; - /// Format specification (see the `f=` key). - int format; - /// Pixel width and height of the non-composed (on-disk) frame data. May - /// differ from the image (i.e. first frame) dimensions. - int data_pix_width, data_pix_height; - /// The offset of the frame relative to the first frame. - int x, y; - /// Compression mode (see the `o=` key). - char compression; - /// The status (see `ImageStatus`). - char status; - /// The reason of uploading failure (see `ImageUploadingFailure`). - char uploading_failure; - /// Whether failures and successes should be reported ('q='). - char quiet; - /// Whether to blend the frame with the background or replace it. - char blend; - /// The file corresponding to the on-disk cache, used when uploading. - FILE *open_file; - /// The size of the corresponding file cached on disk. - unsigned disk_size; - /// The imlib object containing the fully composed frame. It's not - /// scaled for screen display yet. - Imlib_Image imlib_object; -} ImageFrame; - -typedef struct Image { - /// The client id (the one specified with 'i='). Must be nonzero. - uint32_t image_id; - /// The client id specified in the query command (`a=q`). This one must - /// be used to create the response if it's non-zero. - uint32_t query_id; - /// The number specified in the transmission command (`I=`). If - /// non-zero, it may be used to identify the image instead of the - /// image_id, and it also should be mentioned in responses. - uint32_t image_number; - /// The last time when the image was displayed or otherwise touched. - Milliseconds atime; - /// The total duration of the animation in milliseconds. - int total_duration; - /// The total size of cached image files for all frames. - int total_disk_size; - /// The global index of the creation command. Used to decide which image - /// is newer if they have the same image number. - uint64_t global_command_index; - /// The 1-based index of the currently displayed frame. - int current_frame; - /// The state of the animation, see `AnimationState`. - char animation_state; - /// The absolute time that is assumed to be the start of the current - /// frame (in ms since initialization). - Milliseconds current_frame_time; - /// The absolute time of the last redraw (in ms since initialization). - /// Used to check whether it's the first time we draw the image in the - /// current redraw cycle. - Milliseconds last_redraw; - /// The absolute time of the next redraw (in ms since initialization). - /// 0 means no redraw is scheduled. - Milliseconds next_redraw; - /// The unscaled pixel width and height of the image. Usually inherited - /// from the first frame. - int pix_width, pix_height; - /// The first frame. - ImageFrame first_frame; - /// The array of frames beyond the first one. - kvec_t(ImageFrame) frames_beyond_the_first; - /// Image placements. - khash_t(id2placement) *placements; - /// The default placement. - uint32_t default_placement; - /// The initial placement id, specified with the transmission command, - /// used to report success or failure. - uint32_t initial_placement_id; -} Image; - -typedef struct ImagePlacement { - /// The image this placement belongs to. - Image *image; - /// The id of the placement. Must be nonzero. - uint32_t placement_id; - /// The last time when the placement was displayed or otherwise touched. - Milliseconds atime; - /// The 1-based index of the protected pixmap. We protect a pixmap in - /// gr_load_pixmap to avoid unloading it right after it was loaded. - int protected_frame; - /// Whether the placement is used only for Unicode placeholders. - char virtual; - /// The scaling mode (see `ScaleMode`). - char scale_mode; - /// Height and width in cells. - uint16_t rows, cols; - /// Top-left corner of the source rectangle ('x=' and 'y='). - int src_pix_x, src_pix_y; - /// Height and width of the source rectangle (zero if full image). - int src_pix_width, src_pix_height; - /// The image appropriately scaled and uploaded to the X server. This - /// pixmap is premultiplied by alpha. - Pixmap first_pixmap; - /// The array of pixmaps beyond the first one. - kvec_t(Pixmap) pixmaps_beyond_the_first; - /// The dimensions of the cell used to scale the image. If cell - /// dimensions are changed (font change), the image will be rescaled. - uint16_t scaled_cw, scaled_ch; - /// If true, do not move the cursor when displaying this placement - /// (non-virtual placements only). - char do_not_move_cursor; -} ImagePlacement; - -/// A rectangular piece of an image to be drawn. -typedef struct { - uint32_t image_id; - uint32_t placement_id; - /// The position of the rectangle in pixels. - int screen_x_pix, screen_y_pix; - /// The starting row on the screen. - int screen_y_row; - /// The part of the whole image to be drawn, in cells. Starts are - /// zero-based, ends are exclusive. - int img_start_col, img_end_col, img_start_row, img_end_row; - /// The current cell width and height in pixels. - int cw, ch; - /// Whether colors should be inverted. - int reverse; -} ImageRect; - -/// Executes `code` for each frame of an image. Example: -/// -/// foreach_frame(image, frame, { -/// printf("Frame %d\n", frame->index); -/// }); -/// -#define foreach_frame(image, framevar, code) { size_t __i; \ - for (__i = 0; __i <= kv_size((image).frames_beyond_the_first); ++__i) { \ - ImageFrame *framevar = \ - __i == 0 ? &(image).first_frame \ - : &kv_A((image).frames_beyond_the_first, __i - 1); \ - code; \ - } } - -/// Executes `code` for each pixmap of a placement. Example: -/// -/// foreach_pixmap(placement, pixmap, { -/// ... -/// }); -/// -#define foreach_pixmap(placement, pixmapvar, code) { size_t __i; \ - for (__i = 0; __i <= kv_size((placement).pixmaps_beyond_the_first); ++__i) { \ - Pixmap pixmapvar = \ - __i == 0 ? (placement).first_pixmap \ - : kv_A((placement).pixmaps_beyond_the_first, __i - 1); \ - code; \ - } } - - -static Image *gr_find_image(uint32_t image_id); -static void gr_get_frame_filename(ImageFrame *frame, char *out, size_t max_len); -static void gr_delete_image(Image *img); -static void gr_check_limits(); -static char *gr_base64dec(const char *src, size_t *size); -static void sanitize_str(char *str, size_t max_len); -static const char *sanitized_filename(const char *str); - -/// The array of image rectangles to draw. It is reset each frame. -static ImageRect image_rects[MAX_IMAGE_RECTS] = {{0}}; -/// The known images (including the ones being uploaded). -static khash_t(id2image) *images = NULL; -/// The total number of placements in all images. -static unsigned total_placement_count = 0; -/// The total size of all image files stored in the on-disk cache. -static int64_t images_disk_size = 0; -/// The total size of all images and placements loaded into ram. -static int64_t images_ram_size = 0; -/// The id of the last loaded image. -static uint32_t last_image_id = 0; -/// Current cell width and heigh in pixels. -static int current_cw = 0, current_ch = 0; -/// The id of the currently uploaded image (when using direct uploading). -static uint32_t current_upload_image_id = 0; -/// The index of the frame currently being uploaded. -static int current_upload_frame_index = 0; -/// The time when the graphics module was initialized. -static struct timespec initialization_time = {0}; -/// The time when the current frame drawing started, used for debugging fps and -/// to calculate the current frame for animations. -static Milliseconds drawing_start_time; -/// The global index of the current command. -static uint64_t global_command_counter = 0; -/// The next redraw times for each row of the terminal. Used for animations. -/// 0 means no redraw is scheduled. -static kvec_t(Milliseconds) next_redraw_times = {0, 0, NULL}; -/// The number of files loaded in the current redraw cycle. -static int this_redraw_cycle_loaded_files = 0; -/// The number of pixmaps loaded in the current redraw cycle. -static int this_redraw_cycle_loaded_pixmaps = 0; - -/// The directory where the cache files are stored. -static char cache_dir[MAX_FILENAME_SIZE - 16]; - -/// The table used for color inversion. -static unsigned char reverse_table[256]; - -// Declared in the header. -GraphicsDebugMode graphics_debug_mode = GRAPHICS_DEBUG_NONE; -char graphics_display_images = 1; -GraphicsCommandResult graphics_command_result = {0}; -int graphics_next_redraw_delay = INT_MAX; - -// Defined in config.h -extern const char graphics_cache_dir_template[]; -extern unsigned graphics_max_single_image_file_size; -extern unsigned graphics_total_file_cache_size; -extern unsigned graphics_max_single_image_ram_size; -extern unsigned graphics_max_total_ram_size; -extern unsigned graphics_max_total_placements; -extern double graphics_excess_tolerance_ratio; -extern unsigned graphics_animation_min_delay; - - -//////////////////////////////////////////////////////////////////////////////// -// Basic helpers. -//////////////////////////////////////////////////////////////////////////////// - -#define MIN(a, b) ((a) < (b) ? (a) : (b)) -#define MAX(a, b) ((a) < (b) ? (b) : (a)) - -/// Returns the difference between `end` and `start` in milliseconds. -static int64_t gr_timediff_ms(const struct timespec *end, - const struct timespec *start) { - return (end->tv_sec - start->tv_sec) * 1000 + - (end->tv_nsec - start->tv_nsec) / 1000000; -} - -/// Returns the current time in milliseconds since the initialization. -static Milliseconds gr_now_ms() { - struct timespec now; - clock_gettime(CLOCK_MONOTONIC, &now); - return gr_timediff_ms(&now, &initialization_time); -} - -//////////////////////////////////////////////////////////////////////////////// -// Logging. -//////////////////////////////////////////////////////////////////////////////// - -#define GR_LOG(...) \ - do { if(graphics_debug_mode) fprintf(stderr, __VA_ARGS__); } while(0) - -//////////////////////////////////////////////////////////////////////////////// -// Basic image management functions (create, delete, find, etc). -//////////////////////////////////////////////////////////////////////////////// - -/// Returns the 1-based index of the last frame. Note that you may want to use -/// `gr_last_uploaded_frame_index` instead since the last frame may be not -/// fully uploaded yet. -static inline int gr_last_frame_index(Image *img) { - return kv_size(img->frames_beyond_the_first) + 1; -} - -/// Returns the frame with the given index. Returns NULL if the index is out of -/// bounds. The index is 1-based. -static ImageFrame *gr_get_frame(Image *img, int index) { - if (!img) - return NULL; - if (index == 1) - return &img->first_frame; - if (2 <= index && index <= gr_last_frame_index(img)) - return &kv_A(img->frames_beyond_the_first, index - 2); - return NULL; -} - -/// Returns the last frame of the image. Returns NULL if `img` is NULL. -static ImageFrame *gr_get_last_frame(Image *img) { - if (!img) - return NULL; - return gr_get_frame(img, gr_last_frame_index(img)); -} - -/// Returns the 1-based index of the last frame or the second-to-last frame if -/// the last frame is not fully uploaded yet. -static inline int gr_last_uploaded_frame_index(Image *img) { - int last_index = gr_last_frame_index(img); - if (last_index > 1 && - gr_get_frame(img, last_index)->status < STATUS_UPLOADING_SUCCESS) - return last_index - 1; - return last_index; -} - -/// Returns the pixmap for the frame with the given index. Returns 0 if the -/// index is out of bounds. The index is 1-based. -static Pixmap gr_get_frame_pixmap(ImagePlacement *placement, int index) { - if (index == 1) - return placement->first_pixmap; - if (2 <= index && - index <= kv_size(placement->pixmaps_beyond_the_first) + 1) - return kv_A(placement->pixmaps_beyond_the_first, index - 2); - return 0; -} - -/// Sets the pixmap for the frame with the given index. The index is 1-based. -/// The array of pixmaps is resized if needed. -static void gr_set_frame_pixmap(ImagePlacement *placement, int index, - Pixmap pixmap) { - if (index == 1) { - placement->first_pixmap = pixmap; - return; - } - // Resize the array if needed. - size_t old_size = kv_size(placement->pixmaps_beyond_the_first); - if (old_size < index - 1) { - kv_a(Pixmap, placement->pixmaps_beyond_the_first, index - 2); - for (size_t i = old_size; i < index - 1; i++) - kv_A(placement->pixmaps_beyond_the_first, i) = 0; - } - kv_A(placement->pixmaps_beyond_the_first, index - 2) = pixmap; -} - -/// Finds the image corresponding to the client id. Returns NULL if cannot find. -static Image *gr_find_image(uint32_t image_id) { - khiter_t k = kh_get(id2image, images, image_id); - if (k == kh_end(images)) - return NULL; - Image *res = kh_value(images, k); - return res; -} - -/// Finds the newest image corresponding to the image number. Returns NULL if -/// cannot find. -static Image *gr_find_image_by_number(uint32_t image_number) { - if (image_number == 0) - return NULL; - Image *newest_img = NULL; - Image *img = NULL; - kh_foreach_value(images, img, { - if (img->image_number == image_number && - (!newest_img || newest_img->global_command_index < - img->global_command_index)) - newest_img = img; - }); - if (!newest_img) - GR_LOG("Image number %u not found\n", image_number); - else - GR_LOG("Found image number %u, its id is %u\n", image_number, - img->image_id); - return newest_img; -} - -/// Finds the placement corresponding to the id. If the placement id is 0, -/// returns some default placement. -static ImagePlacement *gr_find_placement(Image *img, uint32_t placement_id) { - if (!img) - return NULL; - if (placement_id == 0) { - // Try to get the default placement. - ImagePlacement *dflt = NULL; - if (img->default_placement != 0) - dflt = gr_find_placement(img, img->default_placement); - if (dflt) - return dflt; - // If there is no default placement, return the first one and - // set it as the default. - kh_foreach_value(img->placements, dflt, { - img->default_placement = dflt->placement_id; - return dflt; - }); - // If there are no placements, return NULL. - return NULL; - } - khiter_t k = kh_get(id2placement, img->placements, placement_id); - if (k == kh_end(img->placements)) - return NULL; - ImagePlacement *res = kh_value(img->placements, k); - return res; -} - -/// Finds the placement by image id and placement id. -static ImagePlacement *gr_find_image_and_placement(uint32_t image_id, - uint32_t placement_id) { - return gr_find_placement(gr_find_image(image_id), placement_id); -} - -/// Writes the name of the on-disk cache file to `out`. `max_len` should be the -/// size of `out`. The name will be something like -/// "/tmp/st-images-xxx/img-ID-FRAME". -static void gr_get_frame_filename(ImageFrame *frame, char *out, - size_t max_len) { - snprintf(out, max_len, "%s/img-%.3u-%.3u", cache_dir, - frame->image->image_id, frame->index); -} - -/// Returns the (estimation) of the RAM size used by the frame right now. -static unsigned gr_frame_current_ram_size(ImageFrame *frame) { - if (!frame->imlib_object) - return 0; - return (unsigned)frame->image->pix_width * frame->image->pix_height * 4; -} - -/// Returns the (estimation) of the RAM size used by a single frame pixmap. -static unsigned gr_placement_single_frame_ram_size(ImagePlacement *placement) { - return (unsigned)placement->rows * placement->cols * - placement->scaled_ch * placement->scaled_cw * 4; -} - -/// Returns the (estimation) of the RAM size used by the placemenet right now. -static unsigned gr_placement_current_ram_size(ImagePlacement *placement) { - unsigned single_frame_size = - gr_placement_single_frame_ram_size(placement); - unsigned result = 0; - foreach_pixmap(*placement, pixmap, { - if (pixmap) - result += single_frame_size; - }); - return result; -} - -/// Unload the frame from RAM (i.e. delete the corresponding imlib object). -/// If the on-disk file of the frame is preserved, it can be reloaded later. -static void gr_unload_frame(ImageFrame *frame) { - if (!frame->imlib_object) - return; - - unsigned frame_ram_size = gr_frame_current_ram_size(frame); - images_ram_size -= frame_ram_size; - - imlib_context_set_image(frame->imlib_object); - imlib_free_image_and_decache(); - frame->imlib_object = NULL; - - GR_LOG("After unloading image %u frame %u (atime %ld ms ago) " - "ram: %ld KiB (- %u KiB)\n", - frame->image->image_id, frame->index, - drawing_start_time - frame->atime, images_ram_size / 1024, - frame_ram_size / 1024); -} - -/// Unload all frames of the image. -static void gr_unload_all_frames(Image *img) { - foreach_frame(*img, frame, { - gr_unload_frame(frame); - }); -} - -/// Unload the placement from RAM (i.e. free all of the corresponding pixmaps). -/// If the on-disk files or imlib objects of the corresponding image are -/// preserved, the placement can be reloaded later. -static void gr_unload_placement(ImagePlacement *placement) { - unsigned placement_ram_size = gr_placement_current_ram_size(placement); - images_ram_size -= placement_ram_size; - - Display *disp = imlib_context_get_display(); - foreach_pixmap(*placement, pixmap, { - if (pixmap) - XFreePixmap(disp, pixmap); - }); - - placement->first_pixmap = 0; - placement->pixmaps_beyond_the_first.n = 0; - placement->scaled_ch = placement->scaled_cw = 0; - - GR_LOG("After unloading placement %u/%u (atime %ld ms ago) " - "ram: %ld KiB (- %u KiB)\n", - placement->image->image_id, placement->placement_id, - drawing_start_time - placement->atime, images_ram_size / 1024, - placement_ram_size / 1024); -} - -/// Unload a single pixmap of the placement from RAM. -static void gr_unload_pixmap(ImagePlacement *placement, int frameidx) { - Pixmap pixmap = gr_get_frame_pixmap(placement, frameidx); - if (!pixmap) - return; - - Display *disp = imlib_context_get_display(); - XFreePixmap(disp, pixmap); - gr_set_frame_pixmap(placement, frameidx, 0); - images_ram_size -= gr_placement_single_frame_ram_size(placement); - - GR_LOG("After unloading pixmap %ld of " - "placement %u/%u (atime %ld ms ago) " - "frame %u (atime %ld ms ago) " - "ram: %ld KiB (- %u KiB)\n", - pixmap, placement->image->image_id, placement->placement_id, - drawing_start_time - placement->atime, frameidx, - drawing_start_time - - gr_get_frame(placement->image, frameidx)->atime, - images_ram_size / 1024, - gr_placement_single_frame_ram_size(placement) / 1024); -} - -/// Deletes the on-disk cache file corresponding to the frame. The in-ram image -/// object (if it exists) is not deleted, placements are not unloaded either. -static void gr_delete_imagefile(ImageFrame *frame) { - // It may still be being loaded. Close the file in this case. - if (frame->open_file) { - fclose(frame->open_file); - frame->open_file = NULL; - } - - if (frame->disk_size == 0) - return; - - char filename[MAX_FILENAME_SIZE]; - gr_get_frame_filename(frame, filename, MAX_FILENAME_SIZE); - remove(filename); - - unsigned disk_size = frame->disk_size; - images_disk_size -= disk_size; - frame->image->total_disk_size -= disk_size; - frame->disk_size = 0; - - GR_LOG("After deleting image file %u frame %u (atime %ld ms ago) " - "disk: %ld KiB (- %u KiB)\n", - frame->image->image_id, frame->index, - drawing_start_time - frame->atime, images_disk_size / 1024, - disk_size / 1024); -} - -/// Deletes all on-disk cache files of the image (for each frame). -static void gr_delete_imagefiles(Image *img) { - foreach_frame(*img, frame, { - gr_delete_imagefile(frame); - }); -} - -/// Deletes the given placement: unloads, frees the object, but doesn't change -/// the `placements` hash table. -static void gr_delete_placement_keep_id(ImagePlacement *placement) { - if (!placement) - return; - GR_LOG("Deleting placement %u/%u\n", placement->image->image_id, - placement->placement_id); - gr_unload_placement(placement); - kv_destroy(placement->pixmaps_beyond_the_first); - free(placement); - total_placement_count--; -} - -/// Deletes all placements of `img`. -static void gr_delete_all_placements(Image *img) { - ImagePlacement *placement = NULL; - kh_foreach_value(img->placements, placement, { - gr_delete_placement_keep_id(placement); - }); - kh_clear(id2placement, img->placements); -} - -/// Deletes the given image: unloads, deletes the file, frees the Image object, -/// but doesn't change the `images` hash table. -static void gr_delete_image_keep_id(Image *img) { - if (!img) - return; - GR_LOG("Deleting image %u\n", img->image_id); - foreach_frame(*img, frame, { - gr_delete_imagefile(frame); - gr_unload_frame(frame); - }); - kv_destroy(img->frames_beyond_the_first); - gr_delete_all_placements(img); - kh_destroy(id2placement, img->placements); - free(img); -} - -/// Deletes the given image: unloads, deletes the file, frees the Image object, -/// and also removes it from `images`. -static void gr_delete_image(Image *img) { - if (!img) - return; - uint32_t id = img->image_id; - gr_delete_image_keep_id(img); - khiter_t k = kh_get(id2image, images, id); - kh_del(id2image, images, k); -} - -/// Deletes the given placement: unloads, frees the object, and also removes it -/// from `placements`. -static void gr_delete_placement(ImagePlacement *placement) { - if (!placement) - return; - uint32_t id = placement->placement_id; - Image *img = placement->image; - gr_delete_placement_keep_id(placement); - khiter_t k = kh_get(id2placement, img->placements, id); - kh_del(id2placement, img->placements, k); -} - -/// Deletes all images and clears `images`. -static void gr_delete_all_images() { - Image *img = NULL; - kh_foreach_value(images, img, { - gr_delete_image_keep_id(img); - }); - kh_clear(id2image, images); -} - -/// Update the atime of the image. -static void gr_touch_image(Image *img) { - img->atime = gr_now_ms(); -} - -/// Update the atime of the frame. -static void gr_touch_frame(ImageFrame *frame) { - frame->image->atime = frame->atime = gr_now_ms(); -} - -/// Update the atime of the placement. Touches the images too. -static void gr_touch_placement(ImagePlacement *placement) { - placement->image->atime = placement->atime = gr_now_ms(); -} - -/// Creates a new image with the given id. If an image with that id already -/// exists, it is deleted first. If the provided id is 0, generates a -/// random id. -static Image *gr_new_image(uint32_t id) { - if (id == 0) { - do { - id = rand(); - // Avoid IDs that don't need full 32 bits. - } while ((id & 0xFF000000) == 0 || (id & 0x00FFFF00) == 0 || - gr_find_image(id)); - GR_LOG("Generated random image id %u\n", id); - } - Image *img = gr_find_image(id); - gr_delete_image_keep_id(img); - GR_LOG("Creating image %u\n", id); - img = malloc(sizeof(Image)); - memset(img, 0, sizeof(Image)); - img->placements = kh_init(id2placement); - int ret; - khiter_t k = kh_put(id2image, images, id, &ret); - kh_value(images, k) = img; - img->image_id = id; - gr_touch_image(img); - img->global_command_index = global_command_counter; - return img; -} - -/// Creates a new frame at the end of the frame array. It may be the first frame -/// if there are no frames yet. -static ImageFrame *gr_append_new_frame(Image *img) { - ImageFrame *frame = NULL; - if (img->first_frame.index == 0 && - kv_size(img->frames_beyond_the_first) == 0) { - frame = &img->first_frame; - frame->index = 1; - } else { - frame = kv_pushp(ImageFrame, img->frames_beyond_the_first); - memset(frame, 0, sizeof(ImageFrame)); - frame->index = kv_size(img->frames_beyond_the_first) + 1; - } - frame->image = img; - gr_touch_frame(frame); - GR_LOG("Appending frame %d to image %u\n", frame->index, img->image_id); - return frame; -} - -/// Creates a new placement with the given id. If a placement with that id -/// already exists, it is deleted first. If the provided id is 0, generates a -/// random id. -static ImagePlacement *gr_new_placement(Image *img, uint32_t id) { - if (id == 0) { - do { - // Currently we support only 24-bit IDs. - id = rand() & 0xFFFFFF; - // Avoid IDs that need only one byte. - } while ((id & 0x00FFFF00) == 0 || gr_find_placement(img, id)); - } - ImagePlacement *placement = gr_find_placement(img, id); - gr_delete_placement_keep_id(placement); - GR_LOG("Creating placement %u/%u\n", img->image_id, id); - placement = malloc(sizeof(ImagePlacement)); - memset(placement, 0, sizeof(ImagePlacement)); - total_placement_count++; - int ret; - khiter_t k = kh_put(id2placement, img->placements, id, &ret); - kh_value(img->placements, k) = placement; - placement->image = img; - placement->placement_id = id; - gr_touch_placement(placement); - if (img->default_placement == 0) - img->default_placement = id; - return placement; -} - -static int64_t ceil_div(int64_t a, int64_t b) { - return (a + b - 1) / b; -} - -/// Computes the best number of rows and columns for a placement if it's not -/// specified, and also adjusts the source rectangle size. -static void gr_infer_placement_size_maybe(ImagePlacement *placement) { - // The size of the image. - int image_pix_width = placement->image->pix_width; - int image_pix_height = placement->image->pix_height; - // Negative values are not allowed. Quietly set them to 0. - if (placement->src_pix_x < 0) - placement->src_pix_x = 0; - if (placement->src_pix_y < 0) - placement->src_pix_y = 0; - if (placement->src_pix_width < 0) - placement->src_pix_width = 0; - if (placement->src_pix_height < 0) - placement->src_pix_height = 0; - // If the source rectangle is outside the image, truncate it. - if (placement->src_pix_x > image_pix_width) - placement->src_pix_x = image_pix_width; - if (placement->src_pix_y > image_pix_height) - placement->src_pix_y = image_pix_height; - // If the source rectangle is not specified, use the whole image. If - // it's partially outside the image, truncate it. - if (placement->src_pix_width == 0 || - placement->src_pix_x + placement->src_pix_width > image_pix_width) - placement->src_pix_width = - image_pix_width - placement->src_pix_x; - if (placement->src_pix_height == 0 || - placement->src_pix_y + placement->src_pix_height > image_pix_height) - placement->src_pix_height = - image_pix_height - placement->src_pix_y; - - if (placement->cols != 0 && placement->rows != 0) - return; - if (placement->src_pix_width == 0 || placement->src_pix_height == 0) - return; - if (current_cw == 0 || current_ch == 0) - return; - - // If no size is specified, use the image size. - if (placement->cols == 0 && placement->rows == 0) { - placement->cols = - ceil_div(placement->src_pix_width, current_cw); - placement->rows = - ceil_div(placement->src_pix_height, current_ch); - return; - } - - // Some applications specify only one of the dimensions. - if (placement->scale_mode == SCALE_MODE_CONTAIN) { - // If we preserve aspect ratio and fit to width/height, the most - // logical thing is to find the minimum size of the - // non-specified dimension that allows the image to fit the - // specified dimension. - if (placement->cols == 0) { - placement->cols = ceil_div( - placement->src_pix_width * placement->rows * - current_ch, - placement->src_pix_height * current_cw); - return; - } - if (placement->rows == 0) { - placement->rows = - ceil_div(placement->src_pix_height * - placement->cols * current_cw, - placement->src_pix_width * current_ch); - return; - } - } else { - // Otherwise we stretch the image or preserve the original size. - // In both cases we compute the best number of columns from the - // pixel size and cell size. - // TODO: In the case of stretching it's not the most logical - // thing to do, may need to revisit in the future. - // Currently we switch to SCALE_MODE_CONTAIN when only one - // of the dimensions is specified, so this case shouldn't - // happen in practice. - if (!placement->cols) - placement->cols = - ceil_div(placement->src_pix_width, current_cw); - if (!placement->rows) - placement->rows = - ceil_div(placement->src_pix_height, current_ch); - } -} - -/// Adjusts the current frame index if enough time has passed since the display -/// of the current frame. Also computes the time of the next redraw of this -/// image (`img->next_redraw`). The current time is passed as an argument so -/// that all animations are in sync. -static void gr_update_frame_index(Image *img, Milliseconds now) { - if (img->current_frame == 0) { - img->current_frame_time = now; - img->current_frame = 1; - img->next_redraw = now + MAX(1, img->first_frame.gap); - return; - } - // If the animation is stopped, show the current frame. - if (!img->animation_state || - img->animation_state == ANIMATION_STATE_STOPPED || - img->animation_state == ANIMATION_STATE_UNSET) { - // The next redraw is never (unless the state is changed). - img->next_redraw = 0; - return; - } - int last_uploaded_frame_index = gr_last_uploaded_frame_index(img); - // If we are loading and we reached the last frame, show the last frame. - if (img->animation_state == ANIMATION_STATE_LOADING && - img->current_frame == last_uploaded_frame_index) { - // The next redraw is never (unless the state is changed or - // frames are added). - img->next_redraw = 0; - return; - } - - // Check how many milliseconds passed since the current frame was shown. - int passed_ms = now - img->current_frame_time; - // If the animation is looping and too much time has passes, we can - // make a shortcut. - if (img->animation_state == ANIMATION_STATE_LOOPING && - img->total_duration > 0 && passed_ms >= img->total_duration) { - passed_ms %= img->total_duration; - img->current_frame_time = now - passed_ms; - } - // Find the next frame. - int original_frame_index = img->current_frame; - while (1) { - ImageFrame *frame = gr_get_frame(img, img->current_frame); - if (!frame) { - // The frame doesn't exist, go to the first frame. - img->current_frame = 1; - img->current_frame_time = now; - img->next_redraw = now + MAX(1, img->first_frame.gap); - return; - } - if (frame->gap >= 0 && passed_ms < frame->gap) { - // Not enough time has passed, we are still in the same - // frame, and it's not a gapless frame. - img->next_redraw = - img->current_frame_time + MAX(1, frame->gap); - return; - } - // Otherwise go to the next frame. - passed_ms -= MAX(0, frame->gap); - if (img->current_frame >= last_uploaded_frame_index) { - // It's the last frame, if the animation is loading, - // remain on it. - if (img->animation_state == ANIMATION_STATE_LOADING) { - img->next_redraw = 0; - return; - } - // Otherwise the animation is looping. - img->current_frame = 1; - // TODO: Support finite number of loops. - } else { - img->current_frame++; - } - // Make sure we don't get stuck in an infinite loop. - if (img->current_frame == original_frame_index) { - // We looped through all frames, but haven't reached the - // next frame yet. This may happen if too much time has - // passed since the last redraw or all the frames are - // gapless. Just move on to the next frame. - img->current_frame++; - if (img->current_frame > - last_uploaded_frame_index) - img->current_frame = 1; - img->current_frame_time = now; - img->next_redraw = now + MAX( - 1, gr_get_frame(img, img->current_frame)->gap); - return; - } - // Adjust the start time of the frame. The next redraw time will - // be set in the next iteration. - img->current_frame_time += MAX(0, frame->gap); - } -} - -//////////////////////////////////////////////////////////////////////////////// -// Unloading and deleting images to save resources. -//////////////////////////////////////////////////////////////////////////////// - -/// A helper to compare frames by atime for qsort. -static int gr_cmp_frames_by_atime(const void *a, const void *b) { - ImageFrame *frame_a = *(ImageFrame *const *)a; - ImageFrame *frame_b = *(ImageFrame *const *)b; - if (frame_a->atime == frame_b->atime) - return frame_a->image->global_command_index - - frame_b->image->global_command_index; - return frame_a->atime - frame_b->atime; -} - -/// A helper to compare images by atime for qsort. -static int gr_cmp_images_by_atime(const void *a, const void *b) { - Image *img_a = *(Image *const *)a; - Image *img_b = *(Image *const *)b; - if (img_a->atime == img_b->atime) - return img_a->global_command_index - - img_b->global_command_index; - return img_a->atime - img_b->atime; -} - -/// A helper to compare placements by atime for qsort. -static int gr_cmp_placements_by_atime(const void *a, const void *b) { - ImagePlacement *p_a = *(ImagePlacement **)a; - ImagePlacement *p_b = *(ImagePlacement **)b; - if (p_a->atime == p_b->atime) - return p_a->image->global_command_index - - p_b->image->global_command_index; - return p_a->atime - p_b->atime; -} - -typedef kvec_t(Image *) ImageVec; -typedef kvec_t(ImagePlacement *) ImagePlacementVec; -typedef kvec_t(ImageFrame *) ImageFrameVec; - -/// Returns an array of pointers to all images sorted by atime. -static ImageVec gr_get_images_sorted_by_atime() { - ImageVec vec; - kv_init(vec); - if (kh_size(images) == 0) - return vec; - kv_resize(Image *, vec, kh_size(images)); - Image *img = NULL; - kh_foreach_value(images, img, { kv_push(Image *, vec, img); }); - qsort(vec.a, kv_size(vec), sizeof(Image *), gr_cmp_images_by_atime); - return vec; -} - -/// Returns an array of pointers to all placements sorted by atime. -static ImagePlacementVec gr_get_placements_sorted_by_atime() { - ImagePlacementVec vec; - kv_init(vec); - if (total_placement_count == 0) - return vec; - kv_resize(ImagePlacement *, vec, total_placement_count); - Image *img = NULL; - ImagePlacement *placement = NULL; - kh_foreach_value(images, img, { - kh_foreach_value(img->placements, placement, { - kv_push(ImagePlacement *, vec, placement); - }); - }); - qsort(vec.a, kv_size(vec), sizeof(ImagePlacement *), - gr_cmp_placements_by_atime); - return vec; -} - -/// Returns an array of pointers to all frames sorted by atime. -static ImageFrameVec gr_get_frames_sorted_by_atime() { - ImageFrameVec frames; - kv_init(frames); - Image *img = NULL; - kh_foreach_value(images, img, { - foreach_frame(*img, frame, { - kv_push(ImageFrame *, frames, frame); - }); - }); - qsort(frames.a, kv_size(frames), sizeof(ImageFrame *), - gr_cmp_frames_by_atime); - return frames; -} - -/// An object that can be unloaded from RAM. -typedef struct { - /// Some score, probably based on access time. The lower the score, the - /// more likely that the object should be unloaded. - int64_t score; - union { - ImagePlacement *placement; - ImageFrame *frame; - }; - /// If zero, the object is the imlib object of `frame`, if non-zero, - /// the object is a pixmap of `frameidx`-th frame of `placement`. - int frameidx; -} UnloadableObject; - -typedef kvec_t(UnloadableObject) UnloadableObjectVec; - -/// A helper to compare unloadable objects by score for qsort. -static int gr_cmp_unloadable_objects(const void *a, const void *b) { - UnloadableObject *obj_a = (UnloadableObject *)a; - UnloadableObject *obj_b = (UnloadableObject *)b; - return obj_a->score - obj_b->score; -} - -/// Unloads an unloadable object from RAM. -static void gr_unload_object(UnloadableObject *obj) { - if (obj->frameidx) { - if (obj->placement->protected_frame == obj->frameidx) - return; - gr_unload_pixmap(obj->placement, obj->frameidx); - } else { - gr_unload_frame(obj->frame); - } -} - -/// Returns the recency threshold for an image. Frames that were accessed within -/// this threshold from now are considered recent and may be handled -/// differently because we may need them again very soon. -static Milliseconds gr_recency_threshold(Image *img) { - return img->total_duration * 2 + 1000; -} - -/// Creates an unloadable object for the imlib object of a frame. -static UnloadableObject gr_unloadable_object_for_frame(Milliseconds now, - ImageFrame *frame) { - UnloadableObject obj = {0}; - obj.frameidx = 0; - obj.frame = frame; - Milliseconds atime = frame->atime; - obj.score = atime; - if (atime >= now - gr_recency_threshold(frame->image)) { - // This is a recent frame, probably from an active animation. - // Score it above `now` to prefer unloading non-active frames. - // Randomize the score because it's not very clear in which - // order we want to unload them: reloading a frame may require - // reloading other frames. - obj.score = now + 1000 + rand() % 1000; - } - return obj; -} - -/// Creates an unloadable object for a pixmap. -static UnloadableObject -gr_unloadable_object_for_pixmap(Milliseconds now, ImageFrame *frame, - ImagePlacement *placement) { - UnloadableObject obj = {0}; - obj.frameidx = frame->index; - obj.placement = placement; - obj.score = placement->atime; - // Since we don't store pixmap atimes, use the - // oldest atime of the frame and the placement. - Milliseconds atime = MIN(placement->atime, frame->atime); - obj.score = atime; - if (atime >= now - gr_recency_threshold(frame->image)) { - // This is a recent pixmap, probably from an active animation. - // Score it above `now` to prefer unloading non-active frames. - // Also assign higher scores to frames that are closer to the - // current frame (more likely to be used soon). - int num_frames = gr_last_frame_index(frame->image); - int dist = frame->index - frame->image->current_frame; - if (dist < 0) - dist += num_frames; - obj.score = - now + 1000 + (num_frames - dist) * 1000 / num_frames; - // If the pixmap is much larger than the imlib image, prefer to - // unload the pixmap by adding up to -1000 to the score. If the - // imlib image is larger, add up to +1000. - float imlib_size = gr_frame_current_ram_size(frame); - float pixmap_size = - gr_placement_single_frame_ram_size(placement); - obj.score += - 2000 * (imlib_size / (imlib_size + pixmap_size) - 0.5); - } - return obj; -} - -/// Returns an array of unloadable objects sorted by score. -static UnloadableObjectVec -gr_get_unloadable_objects_sorted_by_score(Milliseconds now) { - UnloadableObjectVec objects; - kv_init(objects); - Image *img = NULL; - ImagePlacement *placement = NULL; - kh_foreach_value(images, img, { - foreach_frame(*img, frame, { - if (!frame->imlib_object) - continue; - kv_push(UnloadableObject, objects, - gr_unloadable_object_for_frame(now, frame)); - int frameidx = frame->index; - kh_foreach_value(img->placements, placement, { - if (!gr_get_frame_pixmap(placement, frameidx)) - continue; - kv_push(UnloadableObject, objects, - gr_unloadable_object_for_pixmap( - now, frame, placement)); - }); - }); - }); - qsort(objects.a, kv_size(objects), sizeof(UnloadableObject), - gr_cmp_unloadable_objects); - return objects; -} - -/// Returns the limit adjusted by the excess tolerance ratio. -static inline unsigned apply_tolerance(unsigned limit) { - return limit + (unsigned)(limit * graphics_excess_tolerance_ratio); -} - -/// Checks RAM and disk cache limits and deletes/unloads some images. -static void gr_check_limits() { - Milliseconds now = gr_now_ms(); - ImageVec images_sorted = {0}; - ImagePlacementVec placements_sorted = {0}; - ImageFrameVec frames_sorted = {0}; - UnloadableObjectVec objects_sorted = {0}; - int images_begin = 0; - int placements_begin = 0; - char changed = 0; - // First reduce the number of images if there are too many. - if (kh_size(images) > apply_tolerance(graphics_max_total_placements)) { - GR_LOG("Too many images: %d\n", kh_size(images)); - changed = 1; - images_sorted = gr_get_images_sorted_by_atime(); - int to_delete = kv_size(images_sorted) - - graphics_max_total_placements; - for (; images_begin < to_delete; images_begin++) - gr_delete_image(images_sorted.a[images_begin]); - } - // Then reduce the number of placements if there are too many. - if (total_placement_count > - apply_tolerance(graphics_max_total_placements)) { - GR_LOG("Too many placements: %d\n", total_placement_count); - changed = 1; - placements_sorted = gr_get_placements_sorted_by_atime(); - int to_delete = kv_size(placements_sorted) - - graphics_max_total_placements; - for (; placements_begin < to_delete; placements_begin++) { - ImagePlacement *placement = - placements_sorted.a[placements_begin]; - if (placement->protected_frame) - break; - gr_delete_placement(placement); - } - } - // Then reduce the size of the image file cache. The files correspond to - // image frames. - if (images_disk_size > - apply_tolerance(graphics_total_file_cache_size)) { - GR_LOG("Too big disk cache: %ld KiB\n", - images_disk_size / 1024); - changed = 1; - frames_sorted = gr_get_frames_sorted_by_atime(); - for (int i = 0; i < kv_size(frames_sorted); i++) { - if (images_disk_size <= graphics_total_file_cache_size) - break; - gr_delete_imagefile(kv_A(frames_sorted, i)); - } - } - // Then unload images from RAM. - if (images_ram_size > apply_tolerance(graphics_max_total_ram_size)) { - changed = 1; - int frames_begin = 0; - GR_LOG("Too much ram: %ld KiB\n", images_ram_size / 1024); - objects_sorted = gr_get_unloadable_objects_sorted_by_score(now); - for (int i = 0; i < kv_size(objects_sorted); i++) { - if (images_ram_size <= graphics_max_total_ram_size) - break; - gr_unload_object(&kv_A(objects_sorted, i)); - } - } - if (changed) { - GR_LOG("After cleaning: ram: %ld KiB disk: %ld KiB " - "img count: %d placement count: %d\n", - images_ram_size / 1024, images_disk_size / 1024, - kh_size(images), total_placement_count); - } - kv_destroy(images_sorted); - kv_destroy(placements_sorted); - kv_destroy(frames_sorted); - kv_destroy(objects_sorted); -} - -/// Unloads all images by user request. -void gr_unload_images_to_reduce_ram() { - Image *img = NULL; - ImagePlacement *placement = NULL; - kh_foreach_value(images, img, { - kh_foreach_value(img->placements, placement, { - if (placement->protected_frame) - continue; - gr_unload_placement(placement); - }); - gr_unload_all_frames(img); - }); -} - -//////////////////////////////////////////////////////////////////////////////// -// Image loading. -//////////////////////////////////////////////////////////////////////////////// - -/// Copies `num_pixels` pixels (not bytes!) from a buffer `from` to an imlib2 -/// image data `to`. The format may be 24 (RGB) or 32 (RGBA), and it's converted -/// to imlib2's representation, which is 0xAARRGGBB (having BGRA memory layout -/// on little-endian architectures). -static inline void gr_copy_pixels(DATA32 *to, unsigned char *from, int format, - size_t num_pixels) { - size_t pixel_size = format == 24 ? 3 : 4; - if (format == 32) { - for (unsigned i = 0; i < num_pixels; ++i) { - unsigned byte_i = i * pixel_size; - to[i] = ((DATA32)from[byte_i + 2]) | - ((DATA32)from[byte_i + 1]) << 8 | - ((DATA32)from[byte_i]) << 16 | - ((DATA32)from[byte_i + 3]) << 24; - } - } else { - for (unsigned i = 0; i < num_pixels; ++i) { - unsigned byte_i = i * pixel_size; - to[i] = ((DATA32)from[byte_i + 2]) | - ((DATA32)from[byte_i + 1]) << 8 | - ((DATA32)from[byte_i]) << 16 | 0xFF000000; - } - } -} - -/// Loads uncompressed RGB or RGBA image data from a file. -static void gr_load_raw_pixel_data_uncompressed(DATA32 *data, FILE *file, - int format, - size_t total_pixels) { - unsigned char chunk[BUFSIZ]; - size_t pixel_size = format == 24 ? 3 : 4; - size_t chunk_size_pix = BUFSIZ / 4; - size_t chunk_size_bytes = chunk_size_pix * pixel_size; - size_t bytes = total_pixels * pixel_size; - for (size_t chunk_start_pix = 0; chunk_start_pix < total_pixels; - chunk_start_pix += chunk_size_pix) { - size_t read_size = fread(chunk, 1, chunk_size_bytes, file); - size_t read_pixels = read_size / pixel_size; - if (chunk_start_pix + read_pixels > total_pixels) - read_pixels = total_pixels - chunk_start_pix; - gr_copy_pixels(data + chunk_start_pix, chunk, format, - read_pixels); - } -} - -#define COMPRESSED_CHUNK_SIZE BUFSIZ -#define DECOMPRESSED_CHUNK_SIZE (BUFSIZ * 4) - -/// Loads compressed RGB or RGBA image data from a file. -static int gr_load_raw_pixel_data_compressed(DATA32 *data, FILE *file, - int format, size_t total_pixels) { - size_t pixel_size = format == 24 ? 3 : 4; - unsigned char compressed_chunk[COMPRESSED_CHUNK_SIZE]; - unsigned char decompressed_chunk[DECOMPRESSED_CHUNK_SIZE]; - - z_stream strm; - strm.zalloc = Z_NULL; - strm.zfree = Z_NULL; - strm.opaque = Z_NULL; - strm.next_out = decompressed_chunk; - strm.avail_out = DECOMPRESSED_CHUNK_SIZE; - strm.avail_in = 0; - strm.next_in = Z_NULL; - int ret = inflateInit(&strm); - if (ret != Z_OK) - return 1; - - int error = 0; - int progress = 0; - size_t total_copied_pixels = 0; - while (1) { - // If we don't have enough data in the input buffer, try to read - // from the file. - if (strm.avail_in <= COMPRESSED_CHUNK_SIZE / 4) { - // Move the existing data to the beginning. - memmove(compressed_chunk, strm.next_in, strm.avail_in); - strm.next_in = compressed_chunk; - // Read more data. - size_t bytes_read = fread( - compressed_chunk + strm.avail_in, 1, - COMPRESSED_CHUNK_SIZE - strm.avail_in, file); - strm.avail_in += bytes_read; - if (bytes_read != 0) - progress = 1; - } - - // Try to inflate the data. - int ret = inflate(&strm, Z_SYNC_FLUSH); - if (ret == Z_MEM_ERROR || ret == Z_DATA_ERROR) { - error = 1; - fprintf(stderr, - "error: could not decompress the image, error " - "%s\n", - ret == Z_MEM_ERROR ? "Z_MEM_ERROR" - : "Z_DATA_ERROR"); - break; - } - - // Copy the data from the output buffer to the image. - size_t full_pixels = - (DECOMPRESSED_CHUNK_SIZE - strm.avail_out) / pixel_size; - // Make sure we don't overflow the image. - if (full_pixels > total_pixels - total_copied_pixels) - full_pixels = total_pixels - total_copied_pixels; - if (full_pixels > 0) { - // Copy pixels. - gr_copy_pixels(data, decompressed_chunk, format, - full_pixels); - data += full_pixels; - total_copied_pixels += full_pixels; - if (total_copied_pixels >= total_pixels) { - // We filled the whole image, there may be some - // data left, but we just truncate it. - break; - } - // Move the remaining data to the beginning. - size_t copied_bytes = full_pixels * pixel_size; - size_t leftover = - (DECOMPRESSED_CHUNK_SIZE - strm.avail_out) - - copied_bytes; - memmove(decompressed_chunk, - decompressed_chunk + copied_bytes, leftover); - strm.next_out -= copied_bytes; - strm.avail_out += copied_bytes; - progress = 1; - } - - // If we haven't made any progress, then we have reached the end - // of both the file and the inflated data. - if (!progress) - break; - progress = 0; - } - - inflateEnd(&strm); - return error; -} - -#undef COMPRESSED_CHUNK_SIZE -#undef DECOMPRESSED_CHUNK_SIZE - -/// Load the image from a file containing raw pixel data (RGB or RGBA), the data -/// may be compressed. -static Imlib_Image gr_load_raw_pixel_data(ImageFrame *frame, - const char *filename) { - size_t total_pixels = frame->data_pix_width * frame->data_pix_height; - if (total_pixels * 4 > graphics_max_single_image_ram_size) { - fprintf(stderr, - "error: image %u frame %u is too big too load: %zu > %u\n", - frame->image->image_id, frame->index, total_pixels * 4, - graphics_max_single_image_ram_size); - return NULL; - } - - FILE* file = fopen(filename, "rb"); - if (!file) { - fprintf(stderr, - "error: could not open image file: %s\n", - sanitized_filename(filename)); - return NULL; - } - - Imlib_Image image = imlib_create_image(frame->data_pix_width, - frame->data_pix_height); - if (!image) { - fprintf(stderr, - "error: could not create an image of size %d x %d\n", - frame->data_pix_width, frame->data_pix_height); - fclose(file); - return NULL; - } - - imlib_context_set_image(image); - imlib_image_set_has_alpha(1); - DATA32* data = imlib_image_get_data(); - - // The default format is 32. - int format = frame->format ? frame->format : 32; - - if (frame->compression == 0) { - gr_load_raw_pixel_data_uncompressed(data, file, format, - total_pixels); - } else { - int ret = gr_load_raw_pixel_data_compressed(data, file, format, - total_pixels); - if (ret != 0) { - imlib_image_put_back_data(data); - imlib_free_image(); - fclose(file); - return NULL; - } - } - - fclose(file); - imlib_image_put_back_data(data); - return image; -} - -/// Loads the unscaled frame into RAM as an imlib object. The frame imlib object -/// is fully composed on top of the background frame. If the frame is already -/// loaded, does nothing. Loading may fail, in which case the status of the -/// frame will be set to STATUS_RAM_LOADING_ERROR. -static void gr_load_imlib_object(ImageFrame *frame) { - if (frame->imlib_object) - return; - - // If the image is uninitialized or uploading has failed, or the file - // has been deleted, we cannot load the image. - if (frame->status < STATUS_UPLOADING_SUCCESS) - return; - if (frame->disk_size == 0) { - if (frame->status != STATUS_RAM_LOADING_ERROR) { - fprintf(stderr, - "error: cached image was deleted: %u frame %u\n", - frame->image->image_id, frame->index); - } - frame->status = STATUS_RAM_LOADING_ERROR; - return; - } - - // Prevent recursive dependences between frames. - if (frame->status == STATUS_RAM_LOADING_IN_PROGRESS) { - fprintf(stderr, - "error: recursive loading of image %u frame %u\n", - frame->image->image_id, frame->index); - frame->status = STATUS_RAM_LOADING_ERROR; - return; - } - frame->status = STATUS_RAM_LOADING_IN_PROGRESS; - - // Load the background frame if needed. Hopefully it's not recursive. - ImageFrame *bg_frame = NULL; - if (frame->background_frame_index) { - bg_frame = gr_get_frame(frame->image, - frame->background_frame_index); - if (!bg_frame) { - fprintf(stderr, - "error: could not find background " - "frame %d for image %u frame %d\n", - frame->background_frame_index, - frame->image->image_id, frame->index); - frame->status = STATUS_RAM_LOADING_ERROR; - return; - } - gr_load_imlib_object(bg_frame); - if (!bg_frame->imlib_object) { - fprintf(stderr, - "error: could not load background frame %d for " - "image %u frame %d\n", - frame->background_frame_index, - frame->image->image_id, frame->index); - frame->status = STATUS_RAM_LOADING_ERROR; - return; - } - } - - // Load the frame data image. - Imlib_Image frame_data_image = NULL; - char filename[MAX_FILENAME_SIZE]; - gr_get_frame_filename(frame, filename, MAX_FILENAME_SIZE); - GR_LOG("Loading image: %s\n", sanitized_filename(filename)); - if (frame->format == 100 || frame->format == 0) - frame_data_image = imlib_load_image(filename); - if (frame->format == 32 || frame->format == 24 || - (!frame_data_image && frame->format == 0)) - frame_data_image = gr_load_raw_pixel_data(frame, filename); - this_redraw_cycle_loaded_files++; - - if (!frame_data_image) { - if (frame->status != STATUS_RAM_LOADING_ERROR) { - fprintf(stderr, "error: could not load image: %s\n", - sanitized_filename(filename)); - } - frame->status = STATUS_RAM_LOADING_ERROR; - return; - } - - imlib_context_set_image(frame_data_image); - int frame_data_width = imlib_image_get_width(); - int frame_data_height = imlib_image_get_height(); - GR_LOG("Successfully loaded, size %d x %d\n", frame_data_width, - frame_data_height); - // If imlib loading succeeded, and it is the first frame, set the - // information about the original image size, unless it's already set. - if (frame->index == 1 && frame->image->pix_width == 0 && - frame->image->pix_height == 0) { - frame->image->pix_width = frame_data_width; - frame->image->pix_height = frame_data_height; - } - - int image_width = frame->image->pix_width; - int image_height = frame->image->pix_height; - - // Compose the image with the background color or frame. - if (frame->background_color != 0 || bg_frame || - image_width != frame_data_width || - image_height != frame_data_height) { - GR_LOG("Composing the frame bg = 0x%08X, bgframe = %d\n", - frame->background_color, frame->background_frame_index); - Imlib_Image composed_image = imlib_create_image( - image_width, image_height); - imlib_context_set_image(composed_image); - imlib_image_set_has_alpha(1); - imlib_context_set_anti_alias(0); - - // Start with the background frame or color. - imlib_context_set_blend(0); - if (bg_frame && bg_frame->imlib_object) { - imlib_blend_image_onto_image( - bg_frame->imlib_object, 1, 0, 0, - image_width, image_height, 0, 0, - image_width, image_height); - } else { - int r = (frame->background_color >> 24) & 0xFF; - int g = (frame->background_color >> 16) & 0xFF; - int b = (frame->background_color >> 8) & 0xFF; - int a = frame->background_color & 0xFF; - imlib_context_set_color(r, g, b, a); - imlib_image_fill_rectangle(0, 0, image_width, - image_height); - } - - // Blend the frame data image onto the background. - imlib_context_set_blend(1); - imlib_blend_image_onto_image( - frame_data_image, 1, 0, 0, frame->data_pix_width, - frame->data_pix_height, frame->x, frame->y, - frame->data_pix_width, frame->data_pix_height); - - // Free the frame data image. - imlib_context_set_image(frame_data_image); - imlib_free_image(); - - frame_data_image = composed_image; - } - - frame->imlib_object = frame_data_image; - - images_ram_size += gr_frame_current_ram_size(frame); - frame->status = STATUS_RAM_LOADING_SUCCESS; - - GR_LOG("After loading image %u frame %d ram: %ld KiB (+ %u KiB)\n", - frame->image->image_id, frame->index, - images_ram_size / 1024, gr_frame_current_ram_size(frame) / 1024); -} - -/// Premultiplies the alpha channel of the image data. The data is an array of -/// pixels such that each pixel is a 32-bit integer in the format 0xAARRGGBB. -static void gr_premultiply_alpha(DATA32 *data, size_t num_pixels) { - for (size_t i = 0; i < num_pixels; ++i) { - DATA32 pixel = data[i]; - unsigned char a = pixel >> 24; - if (a == 0) { - data[i] = 0; - } else if (a != 255) { - unsigned char b = (pixel & 0xFF) * a / 255; - unsigned char g = ((pixel >> 8) & 0xFF) * a / 255; - unsigned char r = ((pixel >> 16) & 0xFF) * a / 255; - data[i] = (a << 24) | (r << 16) | (g << 8) | b; - } - } -} - -/// Creates a pixmap for the frame of an image placement. The pixmap contain the -/// image data correctly scaled and fit to the box defined by the number of -/// rows/columns of the image placement and the provided cell dimensions in -/// pixels. If the placement is already loaded, it will be reloaded only if the -/// cell dimensions have changed. -Pixmap gr_load_pixmap(ImagePlacement *placement, int frameidx, int cw, int ch) { - Image *img = placement->image; - ImageFrame *frame = gr_get_frame(img, frameidx); - - // Update the atime uncoditionally. - gr_touch_placement(placement); - if (frame) - gr_touch_frame(frame); - - // If cw or ch are different, unload all the pixmaps. - if (placement->scaled_cw != cw || placement->scaled_ch != ch) { - gr_unload_placement(placement); - placement->scaled_cw = cw; - placement->scaled_ch = ch; - } - - // If it's already loaded, do nothing. - Pixmap pixmap = gr_get_frame_pixmap(placement, frameidx); - if (pixmap) - return pixmap; - - GR_LOG("Loading placement: %u/%u frame %u\n", img->image_id, - placement->placement_id, frameidx); - - // Load the imlib object for the frame. - if (!frame) { - fprintf(stderr, - "error: could not find frame %u for image %u\n", - frameidx, img->image_id); - return 0; - } - gr_load_imlib_object(frame); - if (!frame->imlib_object) - return 0; - - // Infer the placement size if needed. - gr_infer_placement_size_maybe(placement); - - // Create the scaled image. This is temporary, we will scale it - // appropriately, upload to the X server, and then delete immediately. - int scaled_w = (int)placement->cols * cw; - int scaled_h = (int)placement->rows * ch; - if (scaled_w * scaled_h * 4 > graphics_max_single_image_ram_size) { - fprintf(stderr, - "error: placement %u/%u would be too big to load: %d x " - "%d x 4 > %u\n", - img->image_id, placement->placement_id, scaled_w, - scaled_h, graphics_max_single_image_ram_size); - return 0; - } - Imlib_Image scaled_image = imlib_create_image(scaled_w, scaled_h); - if (!scaled_image) { - fprintf(stderr, - "error: imlib_create_image(%d, %d) returned " - "null\n", - scaled_w, scaled_h); - return 0; - } - imlib_context_set_image(scaled_image); - imlib_image_set_has_alpha(1); - - // First fill the scaled image with the transparent color. - imlib_context_set_blend(0); - imlib_context_set_color(0, 0, 0, 0); - imlib_image_fill_rectangle(0, 0, scaled_w, scaled_h); - imlib_context_set_anti_alias(1); - imlib_context_set_blend(1); - - // The source rectangle. - int src_x = placement->src_pix_x; - int src_y = placement->src_pix_y; - int src_w = placement->src_pix_width; - int src_h = placement->src_pix_height; - // Whether the box is too small to use the true size of the image. - char box_too_small = scaled_w < src_w || scaled_h < src_h; - char mode = placement->scale_mode; - - // Then blend the original image onto the transparent background. - if (src_w <= 0 || src_h <= 0) { - fprintf(stderr, "warning: image of zero size\n"); - } else if (mode == SCALE_MODE_FILL) { - imlib_blend_image_onto_image(frame->imlib_object, 1, src_x, - src_y, src_w, src_h, 0, 0, - scaled_w, scaled_h); - } else if (mode == SCALE_MODE_NONE || - (mode == SCALE_MODE_NONE_OR_CONTAIN && !box_too_small)) { - imlib_blend_image_onto_image(frame->imlib_object, 1, src_x, - src_y, src_w, src_h, 0, 0, src_w, - src_h); - } else { - if (mode != SCALE_MODE_CONTAIN && - mode != SCALE_MODE_NONE_OR_CONTAIN) { - fprintf(stderr, - "warning: unknown scale mode %u, using " - "'contain' instead\n", - mode); - } - int dest_x, dest_y; - int dest_w, dest_h; - if (scaled_w * src_h > src_w * scaled_h) { - // If the box is wider than the original image, fit to - // height. - dest_h = scaled_h; - dest_y = 0; - dest_w = src_w * scaled_h / src_h; - dest_x = (scaled_w - dest_w) / 2; - } else { - // Otherwise, fit to width. - dest_w = scaled_w; - dest_x = 0; - dest_h = src_h * scaled_w / src_w; - dest_y = (scaled_h - dest_h) / 2; - } - imlib_blend_image_onto_image(frame->imlib_object, 1, src_x, - src_y, src_w, src_h, dest_x, - dest_y, dest_w, dest_h); - } - - // XRender needs the alpha channel premultiplied. - DATA32 *data = imlib_image_get_data(); - gr_premultiply_alpha(data, scaled_w * scaled_h); - - // Upload the image to the X server. - Display *disp = imlib_context_get_display(); - Visual *vis = imlib_context_get_visual(); - Colormap cmap = imlib_context_get_colormap(); - Drawable drawable = imlib_context_get_drawable(); - if (!drawable) - drawable = DefaultRootWindow(disp); - pixmap = XCreatePixmap(disp, drawable, scaled_w, scaled_h, 32); - XVisualInfo visinfo; - XMatchVisualInfo(disp, DefaultScreen(disp), 32, TrueColor, &visinfo); - XImage *ximage = XCreateImage(disp, visinfo.visual, 32, ZPixmap, 0, - (char *)data, scaled_w, scaled_h, 32, 0); - GC gc = XCreateGC(disp, pixmap, 0, NULL); - XPutImage(disp, pixmap, gc, ximage, 0, 0, 0, 0, scaled_w, - scaled_h); - XFreeGC(disp, gc); - // XDestroyImage will free the data as well, but it is managed by imlib, - // so set it to NULL. - ximage->data = NULL; - XDestroyImage(ximage); - imlib_image_put_back_data(data); - imlib_free_image(); - - // Assign the pixmap to the frame and increase the ram size. - gr_set_frame_pixmap(placement, frameidx, pixmap); - images_ram_size += gr_placement_single_frame_ram_size(placement); - this_redraw_cycle_loaded_pixmaps++; - - GR_LOG("After loading placement %u/%u frame %d ram: %ld KiB (+ %u " - "KiB)\n", - frame->image->image_id, placement->placement_id, frame->index, - images_ram_size / 1024, - gr_placement_single_frame_ram_size(placement) / 1024); - - // Free up ram if needed, but keep the pixmap we've loaded no matter - // what. - placement->protected_frame = frameidx; - gr_check_limits(); - placement->protected_frame = 0; - - return pixmap; -} - -//////////////////////////////////////////////////////////////////////////////// -// Initialization and deinitialization. -//////////////////////////////////////////////////////////////////////////////// - -/// Creates a temporary directory. -static int gr_create_cache_dir() { - strncpy(cache_dir, graphics_cache_dir_template, sizeof(cache_dir)); - if (!mkdtemp(cache_dir)) { - fprintf(stderr, - "error: could not create temporary dir from template " - "%s\n", - sanitized_filename(cache_dir)); - return 0; - } - fprintf(stderr, "Graphics cache directory: %s\n", cache_dir); - return 1; -} - -/// Checks whether `tmp_dir` exists and recreates it if it doesn't. -static void gr_make_sure_tmpdir_exists() { - struct stat st; - if (stat(cache_dir, &st) == 0 && S_ISDIR(st.st_mode)) - return; - fprintf(stderr, - "error: %s is not a directory, will need to create a new " - "graphics cache directory\n", - sanitized_filename(cache_dir)); - gr_create_cache_dir(); -} - -/// Initialize the graphics module. -void gr_init(Display *disp, Visual *vis, Colormap cm) { - // Set the initialization time. - clock_gettime(CLOCK_MONOTONIC, &initialization_time); - - // Create the temporary dir. - if (!gr_create_cache_dir()) - abort(); - - // Initialize imlib. - imlib_context_set_display(disp); - imlib_context_set_visual(vis); - imlib_context_set_colormap(cm); - imlib_context_set_anti_alias(1); - imlib_context_set_blend(1); - // Imlib2 checks only the file name when caching, which is not enough - // for us since we reuse file names. Disable caching. - imlib_set_cache_size(0); - - // Prepare for color inversion. - for (size_t i = 0; i < 256; ++i) - reverse_table[i] = 255 - i; - - // Create data structures. - images = kh_init(id2image); - kv_init(next_redraw_times); - - atexit(gr_deinit); -} - -/// Deinitialize the graphics module. -void gr_deinit() { - // Remove the cache dir. - remove(cache_dir); - kv_destroy(next_redraw_times); - if (images) { - // Delete all images. - gr_delete_all_images(); - // Destroy the data structures. - kh_destroy(id2image, images); - images = NULL; - } -} - -//////////////////////////////////////////////////////////////////////////////// -// Dumping, debugging, and image preview. -//////////////////////////////////////////////////////////////////////////////// - -/// Returns a string containing a time difference in a human-readable format. -/// Uses a static buffer, so be careful. -static const char *gr_ago(Milliseconds diff) { - static char result[32]; - double seconds = (double)diff / 1000.0; - if (seconds < 1) - snprintf(result, sizeof(result), "%.2f sec ago", seconds); - else if (seconds < 60) - snprintf(result, sizeof(result), "%d sec ago", (int)seconds); - else if (seconds < 3600) - snprintf(result, sizeof(result), "%d min %d sec ago", - (int)(seconds / 60), (int)(seconds) % 60); - else { - snprintf(result, sizeof(result), "%d hr %d min %d sec ago", - (int)(seconds / 3600), (int)(seconds) % 3600 / 60, - (int)(seconds) % 60); - } - return result; -} - -/// Prints to `file` with an indentation of `ind` spaces. -static void fprintf_ind(FILE *file, int ind, const char *format, ...) { - fprintf(file, "%*s", ind, ""); - va_list args; - va_start(args, format); - vfprintf(file, format, args); - va_end(args); -} - -/// Dumps the image info to `file` with an indentation of `ind` spaces. -static void gr_dump_image_info(FILE *file, Image *img, int ind) { - if (!img) { - fprintf_ind(file, ind, "Image is NULL\n"); - return; - } - Milliseconds now = gr_now_ms(); - fprintf_ind(file, ind, "Image %u\n", img->image_id); - ind += 4; - fprintf_ind(file, ind, "number: %u\n", img->image_number); - fprintf_ind(file, ind, "global command index: %lu\n", - img->global_command_index); - fprintf_ind(file, ind, "accessed: %ld %s\n", img->atime, - gr_ago(now - img->atime)); - fprintf_ind(file, ind, "pix size: %ux%u\n", img->pix_width, - img->pix_height); - fprintf_ind(file, ind, "cur frame start time: %ld %s\n", - img->current_frame_time, - gr_ago(now - img->current_frame_time)); - if (img->next_redraw) - fprintf_ind(file, ind, "next redraw: %ld in %ld ms\n", - img->next_redraw, img->next_redraw - now); - fprintf_ind(file, ind, "total disk size: %u KiB\n", - img->total_disk_size / 1024); - fprintf_ind(file, ind, "total duration: %d\n", img->total_duration); - fprintf_ind(file, ind, "frames: %d\n", gr_last_frame_index(img)); - fprintf_ind(file, ind, "cur frame: %d\n", img->current_frame); - fprintf_ind(file, ind, "animation state: %d\n", img->animation_state); - fprintf_ind(file, ind, "default_placement: %u\n", - img->default_placement); -} - -/// Dumps the frame info to `file` with an indentation of `ind` spaces. -static void gr_dump_frame_info(FILE *file, ImageFrame *frame, int ind) { - if (!frame) { - fprintf_ind(file, ind, "Frame is NULL\n"); - return; - } - Milliseconds now = gr_now_ms(); - fprintf_ind(file, ind, "Frame %d\n", frame->index); - ind += 4; - if (frame->index == 0) { - fprintf_ind(file, ind, "NOT INITIALIZED\n"); - return; - } - if (frame->uploading_failure) - fprintf_ind(file, ind, "uploading failure: %s\n", - image_uploading_failure_strings - [frame->uploading_failure]); - fprintf_ind(file, ind, "gap: %d\n", frame->gap); - fprintf_ind(file, ind, "accessed: %ld %s\n", frame->atime, - gr_ago(now - frame->atime)); - fprintf_ind(file, ind, "data pix size: %ux%u\n", frame->data_pix_width, - frame->data_pix_height); - char filename[MAX_FILENAME_SIZE]; - gr_get_frame_filename(frame, filename, MAX_FILENAME_SIZE); - if (access(filename, F_OK) != -1) - fprintf_ind(file, ind, "file: %s\n", - sanitized_filename(filename)); - else - fprintf_ind(file, ind, "not on disk\n"); - fprintf_ind(file, ind, "disk size: %u KiB\n", frame->disk_size / 1024); - if (frame->imlib_object) { - unsigned ram_size = gr_frame_current_ram_size(frame); - fprintf_ind(file, ind, - "loaded into ram, size: %d " - "KiB\n", - ram_size / 1024); - } else { - fprintf_ind(file, ind, "not loaded into ram\n"); - } -} - -/// Dumps the placement info to `file` with an indentation of `ind` spaces. -static void gr_dump_placement_info(FILE *file, ImagePlacement *placement, - int ind) { - if (!placement) { - fprintf_ind(file, ind, "Placement is NULL\n"); - return; - } - Milliseconds now = gr_now_ms(); - fprintf_ind(file, ind, "Placement %u\n", placement->placement_id); - ind += 4; - fprintf_ind(file, ind, "accessed: %ld %s\n", placement->atime, - gr_ago(now - placement->atime)); - fprintf_ind(file, ind, "scale_mode: %u\n", placement->scale_mode); - fprintf_ind(file, ind, "size: %u cols x %u rows\n", placement->cols, - placement->rows); - fprintf_ind(file, ind, "cell size: %ux%u\n", placement->scaled_cw, - placement->scaled_ch); - fprintf_ind(file, ind, "ram per frame: %u KiB\n", - gr_placement_single_frame_ram_size(placement) / 1024); - unsigned ram_size = gr_placement_current_ram_size(placement); - fprintf_ind(file, ind, "ram size: %d KiB\n", ram_size / 1024); -} - -/// Dumps placement pixmaps to `file` with an indentation of `ind` spaces. -static void gr_dump_placement_pixmaps(FILE *file, ImagePlacement *placement, - int ind) { - if (!placement) - return; - int frameidx = 1; - foreach_pixmap(*placement, pixmap, { - fprintf_ind(file, ind, "Frame %d pixmap %lu\n", frameidx, - pixmap); - ++frameidx; - }); -} - -/// Dumps the internal state (images and placements) to stderr. -void gr_dump_state() { - FILE *file = stderr; - int ind = 0; - fprintf_ind(file, ind, "======= Graphics module state dump =======\n"); - fprintf_ind(file, ind, - "sizeof(Image) = %lu sizeof(ImageFrame) = %lu " - "sizeof(ImagePlacement) = %lu\n", - sizeof(Image), sizeof(ImageFrame), sizeof(ImagePlacement)); - fprintf_ind(file, ind, "Image count: %u\n", kh_size(images)); - fprintf_ind(file, ind, "Placement count: %u\n", total_placement_count); - fprintf_ind(file, ind, "Estimated RAM usage: %ld KiB\n", - images_ram_size / 1024); - fprintf_ind(file, ind, "Estimated Disk usage: %ld KiB\n", - images_disk_size / 1024); - - Milliseconds now = gr_now_ms(); - - int64_t images_ram_size_computed = 0; - int64_t images_disk_size_computed = 0; - - Image *img = NULL; - ImagePlacement *placement = NULL; - kh_foreach_value(images, img, { - fprintf_ind(file, ind, "----------------\n"); - gr_dump_image_info(file, img, 0); - int64_t total_disk_size_computed = 0; - int total_duration_computed = 0; - foreach_frame(*img, frame, { - gr_dump_frame_info(file, frame, 4); - if (frame->image != img) - fprintf_ind(file, 8, - "ERROR: WRONG IMAGE POINTER\n"); - total_duration_computed += frame->gap; - images_disk_size_computed += frame->disk_size; - total_disk_size_computed += frame->disk_size; - if (frame->imlib_object) - images_ram_size_computed += - gr_frame_current_ram_size(frame); - }); - if (img->total_disk_size != total_disk_size_computed) { - fprintf_ind(file, ind, - " ERROR: total_disk_size is %u, but " - "computed value is %ld\n", - img->total_disk_size, total_disk_size_computed); - } - if (img->total_duration != total_duration_computed) { - fprintf_ind(file, ind, - " ERROR: total_duration is %d, but computed " - "value is %d\n", - img->total_duration, total_duration_computed); - } - kh_foreach_value(img->placements, placement, { - gr_dump_placement_info(file, placement, 4); - if (placement->image != img) - fprintf_ind(file, 8, - "ERROR: WRONG IMAGE POINTER\n"); - fprintf_ind(file, 8, - "Pixmaps:\n"); - gr_dump_placement_pixmaps(file, placement, 12); - unsigned ram_size = - gr_placement_current_ram_size(placement); - images_ram_size_computed += ram_size; - }); - }); - if (images_ram_size != images_ram_size_computed) { - fprintf_ind(file, ind, - "ERROR: images_ram_size is %ld, but computed value " - "is %ld\n", - images_ram_size, images_ram_size_computed); - } - if (images_disk_size != images_disk_size_computed) { - fprintf_ind(file, ind, - "ERROR: images_disk_size is %ld, but computed value " - "is %ld\n", - images_disk_size, images_disk_size_computed); - } - fprintf_ind(file, ind, "===========================================\n"); -} - -/// Executes `command` with the name of the file corresponding to `image_id` as -/// the argument. Executes xmessage with an error message on failure. -// TODO: Currently we do this for the first frame only. Not sure what to do with -// animations. -void gr_preview_image(uint32_t image_id, const char *exec) { - char command[256]; - size_t len; - Image *img = gr_find_image(image_id); - if (img) { - ImageFrame *frame = &img->first_frame; - char filename[MAX_FILENAME_SIZE]; - gr_get_frame_filename(frame, filename, MAX_FILENAME_SIZE); - if (frame->disk_size == 0) { - len = snprintf(command, 255, - "xmessage 'Image with id=%u is not " - "fully copied to %s'", - image_id, sanitized_filename(filename)); - } else { - len = snprintf(command, 255, "%s %s &", exec, - sanitized_filename(filename)); - } - } else { - len = snprintf(command, 255, - "xmessage 'Cannot find image with id=%u'", - image_id); - } - if (len > 255) { - fprintf(stderr, "error: command too long: %s\n", command); - snprintf(command, 255, "xmessage 'error: command too long'"); - } - if (system(command) != 0) { - fprintf(stderr, "error: could not execute command %s\n", - command); - } -} - -/// Executes ` -e less ` where is the name of a temporary file -/// containing the information about an image and placement, and is -/// specified with `st_executable`. -void gr_show_image_info(uint32_t image_id, uint32_t placement_id, - uint32_t imgcol, uint32_t imgrow, - char is_classic_placeholder, int32_t diacritic_count, - char *st_executable) { - char filename[MAX_FILENAME_SIZE]; - snprintf(filename, sizeof(filename), "%s/info-%u", cache_dir, image_id); - FILE *file = fopen(filename, "w"); - if (!file) { - perror("fopen"); - return; - } - // Basic information about the cell. - fprintf(file, "image_id = %u = 0x%08X\n", image_id, image_id); - fprintf(file, "placement_id = %u = 0x%08X\n", placement_id, placement_id); - fprintf(file, "column = %d, row = %d\n", imgcol, imgrow); - fprintf(file, "classic/unicode placeholder = %s\n", - is_classic_placeholder ? "classic" : "unicode"); - fprintf(file, "original diacritic count = %d\n", diacritic_count); - // Information about the image and the placement. - Image *img = gr_find_image(image_id); - ImagePlacement *placement = gr_find_placement(img, placement_id); - gr_dump_image_info(file, img, 0); - gr_dump_placement_info(file, placement, 0); - if (img) { - fprintf(file, "Frames:\n"); - foreach_frame(*img, frame, { - gr_dump_frame_info(file, frame, 4); - }); - } - if (placement) { - fprintf(file, "Placement pixmaps:\n"); - gr_dump_placement_pixmaps(file, placement, 4); - } - fclose(file); - char *argv[] = {st_executable, "-e", "less", filename, NULL}; - if (posix_spawnp(NULL, st_executable, NULL, NULL, argv, environ) != 0) { - perror("posix_spawnp"); - return; - } -} - -//////////////////////////////////////////////////////////////////////////////// -// Appending and displaying image rectangles. -//////////////////////////////////////////////////////////////////////////////// - -/// Displays debug information in the rectangle using colors col1 and col2. -static void gr_displayinfo(Drawable buf, ImageRect *rect, int col1, int col2, - const char *message) { - int w_pix = (rect->img_end_col - rect->img_start_col) * rect->cw; - int h_pix = (rect->img_end_row - rect->img_start_row) * rect->ch; - Display *disp = imlib_context_get_display(); - GC gc = XCreateGC(disp, buf, 0, NULL); - char info[MAX_INFO_LEN]; - if (rect->placement_id) - snprintf(info, MAX_INFO_LEN, "%s%u/%u [%d:%d)x[%d:%d)", message, - rect->image_id, rect->placement_id, - rect->img_start_col, rect->img_end_col, - rect->img_start_row, rect->img_end_row); - else - snprintf(info, MAX_INFO_LEN, "%s%u [%d:%d)x[%d:%d)", message, - rect->image_id, rect->img_start_col, rect->img_end_col, - rect->img_start_row, rect->img_end_row); - XSetForeground(disp, gc, col1); - XDrawString(disp, buf, gc, rect->screen_x_pix + 4, - rect->screen_y_pix + h_pix - 3, info, strlen(info)); - XSetForeground(disp, gc, col2); - XDrawString(disp, buf, gc, rect->screen_x_pix + 2, - rect->screen_y_pix + h_pix - 5, info, strlen(info)); - XFreeGC(disp, gc); -} - -/// Draws a rectangle (bounding box) for debugging. -static void gr_showrect(Drawable buf, ImageRect *rect) { - int w_pix = (rect->img_end_col - rect->img_start_col) * rect->cw; - int h_pix = (rect->img_end_row - rect->img_start_row) * rect->ch; - Display *disp = imlib_context_get_display(); - GC gc = XCreateGC(disp, buf, 0, NULL); - XSetForeground(disp, gc, 0xFF00FF00); - XDrawRectangle(disp, buf, gc, rect->screen_x_pix, rect->screen_y_pix, - w_pix - 1, h_pix - 1); - XSetForeground(disp, gc, 0xFFFF0000); - XDrawRectangle(disp, buf, gc, rect->screen_x_pix + 1, - rect->screen_y_pix + 1, w_pix - 3, h_pix - 3); - XFreeGC(disp, gc); -} - -/// Updates the next redraw time for the given row. Resizes the -/// next_redraw_times array if needed. -static void gr_update_next_redraw_time(int row, Milliseconds next_redraw) { - if (next_redraw == 0) - return; - if (row >= kv_size(next_redraw_times)) { - size_t old_size = kv_size(next_redraw_times); - kv_a(Milliseconds, next_redraw_times, row); - for (size_t i = old_size; i <= row; ++i) - kv_A(next_redraw_times, i) = 0; - } - Milliseconds old_value = kv_A(next_redraw_times, row); - if (old_value == 0 || old_value > next_redraw) - kv_A(next_redraw_times, row) = next_redraw; -} - -/// Draws the given part of an image. -static void gr_drawimagerect(Drawable buf, ImageRect *rect) { - ImagePlacement *placement = - gr_find_image_and_placement(rect->image_id, rect->placement_id); - // If the image does not exist or image display is switched off, draw - // the bounding box. - if (!placement || !graphics_display_images) { - gr_showrect(buf, rect); - if (graphics_debug_mode == GRAPHICS_DEBUG_LOG_AND_BOXES) - gr_displayinfo(buf, rect, 0xFF000000, 0xFFFFFFFF, ""); - return; - } - - Image *img = placement->image; - - if (img->last_redraw < drawing_start_time) { - // This is the first time we draw this image in this redraw - // cycle. Update the frame index we are going to display. Note - // that currently all image placements are synchronized. - int old_frame = img->current_frame; - gr_update_frame_index(img, drawing_start_time); - img->last_redraw = drawing_start_time; - } - - // Adjust next redraw times for the rows of this image rect. - if (img->next_redraw) { - for (int row = rect->screen_y_row; - row <= rect->screen_y_row + rect->img_end_row - - rect->img_start_row - 1; ++row) { - gr_update_next_redraw_time( - row, img->next_redraw); - } - } - - // Load the frame. - Pixmap pixmap = gr_load_pixmap(placement, img->current_frame, rect->cw, - rect->ch); - - // If the image couldn't be loaded, display the bounding box. - if (!pixmap) { - gr_showrect(buf, rect); - if (graphics_debug_mode == GRAPHICS_DEBUG_LOG_AND_BOXES) - gr_displayinfo(buf, rect, 0xFF000000, 0xFFFFFFFF, ""); - return; - } - - int src_x = rect->img_start_col * rect->cw; - int src_y = rect->img_start_row * rect->ch; - int width = (rect->img_end_col - rect->img_start_col) * rect->cw; - int height = (rect->img_end_row - rect->img_start_row) * rect->ch; - int dst_x = rect->screen_x_pix; - int dst_y = rect->screen_y_pix; - - // Display the image. - Display *disp = imlib_context_get_display(); - Visual *vis = imlib_context_get_visual(); - - // Create an xrender picture for the window. - XRenderPictFormat *win_format = - XRenderFindVisualFormat(disp, vis); - Picture window_pic = - XRenderCreatePicture(disp, buf, win_format, 0, NULL); - - // If needed, invert the image pixmap. Note that this naive approach of - // inverting the pixmap is not entirely correct, because the pixmap is - // premultiplied. But the result is good enough to visually indicate - // selection. - if (rect->reverse) { - unsigned pixmap_w = - (unsigned)placement->cols * placement->scaled_cw; - unsigned pixmap_h = - (unsigned)placement->rows * placement->scaled_ch; - Pixmap invpixmap = - XCreatePixmap(disp, buf, pixmap_w, pixmap_h, 32); - XGCValues gcv = {.function = GXcopyInverted}; - GC gc = XCreateGC(disp, invpixmap, GCFunction, &gcv); - XCopyArea(disp, pixmap, invpixmap, gc, 0, 0, pixmap_w, - pixmap_h, 0, 0); - XFreeGC(disp, gc); - pixmap = invpixmap; - } - - // Create a picture for the image pixmap. - XRenderPictFormat *pic_format = - XRenderFindStandardFormat(disp, PictStandardARGB32); - Picture pixmap_pic = - XRenderCreatePicture(disp, pixmap, pic_format, 0, NULL); - - // Composite the image onto the window. In the reverse mode we ignore - // the alpha channel of the image because the naive inversion above - // seems to invert the alpha channel as well. - int pictop = rect->reverse ? PictOpSrc : PictOpOver; - XRenderComposite(disp, pictop, pixmap_pic, 0, window_pic, - src_x, src_y, src_x, src_y, dst_x, dst_y, width, - height); - - // Free resources - XRenderFreePicture(disp, pixmap_pic); - XRenderFreePicture(disp, window_pic); - if (rect->reverse) - XFreePixmap(disp, pixmap); - - // In debug mode always draw bounding boxes and print info. - if (graphics_debug_mode == GRAPHICS_DEBUG_LOG_AND_BOXES) { - gr_showrect(buf, rect); - gr_displayinfo(buf, rect, 0xFF000000, 0xFFFFFFFF, ""); - } -} - -/// Removes the given image rectangle. -static void gr_freerect(ImageRect *rect) { memset(rect, 0, sizeof(ImageRect)); } - -/// Returns the bottom coordinate of the rect. -static int gr_getrectbottom(ImageRect *rect) { - return rect->screen_y_pix + - (rect->img_end_row - rect->img_start_row) * rect->ch; -} - -/// Prepare for image drawing. `cw` and `ch` are dimensions of the cell. -void gr_start_drawing(Drawable buf, int cw, int ch) { - current_cw = cw; - current_ch = ch; - this_redraw_cycle_loaded_files = 0; - this_redraw_cycle_loaded_pixmaps = 0; - drawing_start_time = gr_now_ms(); - imlib_context_set_drawable(buf); -} - -/// Finish image drawing. This functions will draw all the rectangles left to -/// draw. -void gr_finish_drawing(Drawable buf) { - // Draw and then delete all known image rectangles. - for (size_t i = 0; i < MAX_IMAGE_RECTS; ++i) { - ImageRect *rect = &image_rects[i]; - if (!rect->image_id) - continue; - gr_drawimagerect(buf, rect); - gr_freerect(rect); - } - - // Compute the delay until the next redraw as the minimum of the next - // redraw delays for all rows. - Milliseconds drawing_end_time = gr_now_ms(); - graphics_next_redraw_delay = INT_MAX; - for (int row = 0; row < kv_size(next_redraw_times); ++row) { - Milliseconds row_next_redraw = kv_A(next_redraw_times, row); - if (row_next_redraw > 0) { - int delay = MAX(graphics_animation_min_delay, - row_next_redraw - drawing_end_time); - graphics_next_redraw_delay = - MIN(graphics_next_redraw_delay, delay); - } - } - - // In debug mode display additional info. - if (graphics_debug_mode) { - int milliseconds = drawing_end_time - drawing_start_time; - - Display *disp = imlib_context_get_display(); - GC gc = XCreateGC(disp, buf, 0, NULL); - const char *debug_mode_str = - graphics_debug_mode == GRAPHICS_DEBUG_LOG_AND_BOXES - ? "(boxes shown) " - : ""; - int redraw_delay = graphics_next_redraw_delay == INT_MAX - ? -1 - : graphics_next_redraw_delay; - char info[MAX_INFO_LEN]; - snprintf(info, MAX_INFO_LEN, - "%sRender time: %d ms ram %ld K disk %ld K count " - "%d cell %dx%d delay %d", - debug_mode_str, milliseconds, images_ram_size / 1024, - images_disk_size / 1024, kh_size(images), current_cw, - current_ch, redraw_delay); - XSetForeground(disp, gc, 0xFF000000); - XFillRectangle(disp, buf, gc, 0, 0, 600, 16); - XSetForeground(disp, gc, 0xFFFFFFFF); - XDrawString(disp, buf, gc, 0, 14, info, strlen(info)); - XFreeGC(disp, gc); - - if (milliseconds > 0) { - fprintf(stderr, "%s (loaded %d files, %d pixmaps)\n", - info, this_redraw_cycle_loaded_files, - this_redraw_cycle_loaded_pixmaps); - } - } - - // Check the limits in case we have used too much ram for placements. - gr_check_limits(); -} - -// Add an image rectangle to the list of rectangles to draw. -void gr_append_imagerect(Drawable buf, uint32_t image_id, uint32_t placement_id, - int img_start_col, int img_end_col, int img_start_row, - int img_end_row, int x_col, int y_row, int x_pix, - int y_pix, int cw, int ch, int reverse) { - current_cw = cw; - current_ch = ch; - - ImageRect new_rect; - new_rect.image_id = image_id; - new_rect.placement_id = placement_id; - new_rect.img_start_col = img_start_col; - new_rect.img_end_col = img_end_col; - new_rect.img_start_row = img_start_row; - new_rect.img_end_row = img_end_row; - new_rect.screen_y_row = y_row; - new_rect.screen_x_pix = x_pix; - new_rect.screen_y_pix = y_pix; - new_rect.ch = ch; - new_rect.cw = cw; - new_rect.reverse = reverse; - - // Display some red text in debug mode. - if (graphics_debug_mode == GRAPHICS_DEBUG_LOG_AND_BOXES) - gr_displayinfo(buf, &new_rect, 0xFF000000, 0xFFFF0000, "? "); - - // If it's the empty image (image_id=0) or an empty rectangle, do - // nothing. - if (image_id == 0 || img_end_col - img_start_col <= 0 || - img_end_row - img_start_row <= 0) - return; - // Try to find a rect to merge with. - ImageRect *free_rect = NULL; - for (size_t i = 0; i < MAX_IMAGE_RECTS; ++i) { - ImageRect *rect = &image_rects[i]; - if (rect->image_id == 0) { - if (!free_rect) - free_rect = rect; - continue; - } - if (rect->image_id != image_id || - rect->placement_id != placement_id || rect->cw != cw || - rect->ch != ch || rect->reverse != reverse) - continue; - // We only support the case when the new stripe is added to the - // bottom of an existing rectangle and they are perfectly - // aligned. - if (rect->img_end_row == img_start_row && - gr_getrectbottom(rect) == y_pix) { - if (rect->img_start_col == img_start_col && - rect->img_end_col == img_end_col && - rect->screen_x_pix == x_pix) { - rect->img_end_row = img_end_row; - return; - } - } - } - // If we haven't merged the new rect with any existing rect, and there - // is no free rect, we have to render one of the existing rects. - if (!free_rect) { - for (size_t i = 0; i < MAX_IMAGE_RECTS; ++i) { - ImageRect *rect = &image_rects[i]; - if (!free_rect || gr_getrectbottom(free_rect) > - gr_getrectbottom(rect)) - free_rect = rect; - } - gr_drawimagerect(buf, free_rect); - gr_freerect(free_rect); - } - // Start a new rectangle in `free_rect`. - *free_rect = new_rect; -} - -/// Mark rows containing animations as dirty if it's time to redraw them. Must -/// be called right after `gr_start_drawing`. -void gr_mark_dirty_animations(int *dirty, int rows) { - if (rows < kv_size(next_redraw_times)) - kv_size(next_redraw_times) = rows; - if (rows * 2 < kv_max(next_redraw_times)) - kv_resize(Milliseconds, next_redraw_times, rows); - for (int i = 0; i < MIN(rows, kv_size(next_redraw_times)); ++i) { - if (dirty[i]) { - kv_A(next_redraw_times, i) = 0; - continue; - } - Milliseconds next_update = kv_A(next_redraw_times, i); - if (next_update > 0 && next_update <= drawing_start_time) { - dirty[i] = 1; - kv_A(next_redraw_times, i) = 0; - } - } -} - -//////////////////////////////////////////////////////////////////////////////// -// Command parsing and handling. -//////////////////////////////////////////////////////////////////////////////// - -/// A parsed kitty graphics protocol command. -typedef struct { - /// The command itself, without the 'G'. - char *command; - /// The payload (after ';'). - char *payload; - /// 'a=', may be 't', 'q', 'f', 'T', 'p', 'd', 'a'. - char action; - /// 'q=', 1 to suppress OK response, 2 to suppress errors too. - int quiet; - /// 'f=', use 24 or 32 for raw pixel data, 100 to autodetect with - /// imlib2. If 'f=0', will try to load with imlib2, then fallback to - /// 32-bit pixel data. - int format; - /// 'o=', may be 'z' for RFC 1950 ZLIB. - int compression; - /// 't=', may be 'f', 't' or 'd'. - char transmission_medium; - /// 'd=' - char delete_specifier; - /// 's=', 'v=', if 'a=t' or 'a=T', used only when 'f=24' or 'f=32'. - /// When 'a=f', this is the size of the frame rectangle when composed on - /// top of another frame. - int frame_pix_width, frame_pix_height; - /// 'x=', 'y=' - top-left corner of the source rectangle. - int src_pix_x, src_pix_y; - /// 'w=', 'h=' - width and height of the source rectangle. - int src_pix_width, src_pix_height; - /// 'r=', 'c=' - int rows, columns; - /// 'i=' - uint32_t image_id; - /// 'I=' - uint32_t image_number; - /// 'p=' - uint32_t placement_id; - /// 'm=', may be 0 or 1. - int more; - /// True if either 'm=0' or 'm=1' is specified. - char is_data_transmission; - /// True if turns out that this command is a continuation of a data - /// transmission and not the first one for this image. Populated by - /// `gr_handle_transmit_command`. - char is_direct_transmission_continuation; - /// 'S=', used to check the size of uploaded data. - int size; - /// 'U=', whether it's a virtual placement for Unicode placeholders. - int virtual; - /// 'C=', if true, do not move the cursor when displaying this placement - /// (non-virtual placements only). - char do_not_move_cursor; - // --------------------------------------------------------------------- - // Animation-related fields. Their keys often overlap with keys of other - // commands, so these make sense only if the action is 'a=f' (frame - // transmission) or 'a=a' (animation control). - // - // 'x=' and 'y=', the relative position of the frame image when it's - // composed on top of another frame. - int frame_dst_pix_x, frame_dst_pix_y; - /// 'X=', 'X=1' to replace colors instead of alpha blending on top of - /// the background color or frame. - char replace_instead_of_blending; - /// 'Y=', the background color in the 0xRRGGBBAA format (still - /// transmitted as a decimal number). - uint32_t background_color; - /// (Only for 'a=f'). 'c=', the 1-based index of the background frame. - int background_frame; - /// (Only for 'a=a'). 'c=', sets the index of the current frame. - int current_frame; - /// 'r=', the 1-based index of the frame to edit. - int edit_frame; - /// 'z=', the duration of the frame. Zero if not specified, negative if - /// the frame is gapless (i.e. skipped). - int gap; - /// (Only for 'a=a'). 's=', if non-zero, sets the state of the - /// animation, 1 to stop, 2 to run in loading mode, 3 to loop. - int animation_state; - /// (Only for 'a=a'). 'v=', if non-zero, sets the number of times the - /// animation will loop. 1 to loop infinitely, N to loop N-1 times. - int loops; -} GraphicsCommand; - -/// Replaces all non-printed characters in `str` with '?' and truncates the -/// string to `max_size`, maybe inserting ellipsis at the end. -static void sanitize_str(char *str, size_t max_size) { - assert(max_size >= 4); - for (size_t i = 0; i < max_size; ++i) { - unsigned c = str[i]; - if (c == '\0') - return; - if (c >= 128 || !isprint(c)) - str[i] = '?'; - } - str[max_size - 1] = '\0'; - str[max_size - 2] = '.'; - str[max_size - 3] = '.'; - str[max_size - 4] = '.'; -} - -/// A non-destructive version of `sanitize_str`. Uses a static buffer, so be -/// careful. -static const char *sanitized_filename(const char *str) { - static char buf[MAX_FILENAME_SIZE]; - strncpy(buf, str, sizeof(buf)); - sanitize_str(buf, sizeof(buf)); - return buf; -} - -/// Creates a response to the current command in `graphics_command_result`. -static void gr_createresponse(uint32_t image_id, uint32_t image_number, - uint32_t placement_id, const char *msg) { - if (!image_id && !image_number && !placement_id) { - // Nobody expects the response in this case, so just print it to - // stderr. - fprintf(stderr, - "error: No image id or image number or placement_id, " - "but still there is a response: %s\n", - msg); - return; - } - char *buf = graphics_command_result.response; - size_t maxlen = MAX_GRAPHICS_RESPONSE_LEN; - size_t written; - written = snprintf(buf, maxlen, "\033_G"); - buf += written; - maxlen -= written; - if (image_id) { - written = snprintf(buf, maxlen, "i=%u,", image_id); - buf += written; - maxlen -= written; - } - if (image_number) { - written = snprintf(buf, maxlen, "I=%u,", image_number); - buf += written; - maxlen -= written; - } - if (placement_id) { - written = snprintf(buf, maxlen, "p=%u,", placement_id); - buf += written; - maxlen -= written; - } - buf[-1] = ';'; - written = snprintf(buf, maxlen, "%s\033\\", msg); - buf += written; - maxlen -= written; - buf[-2] = '\033'; - buf[-1] = '\\'; -} - -/// Creates the 'OK' response to the current command, unless suppressed or a -/// non-final data transmission. -static void gr_reportsuccess_cmd(GraphicsCommand *cmd) { - if (cmd->quiet < 1 && !cmd->more) - gr_createresponse(cmd->image_id, cmd->image_number, - cmd->placement_id, "OK"); -} - -/// Creates the 'OK' response to the current command (unless suppressed). -static void gr_reportsuccess_frame(ImageFrame *frame) { - uint32_t id = frame->image->query_id ? frame->image->query_id - : frame->image->image_id; - if (frame->quiet < 1) - gr_createresponse(id, frame->image->image_number, - frame->image->initial_placement_id, "OK"); -} - -/// Creates an error response to the current command (unless suppressed). -static void gr_reporterror_cmd(GraphicsCommand *cmd, const char *format, ...) { - char errmsg[MAX_GRAPHICS_RESPONSE_LEN]; - graphics_command_result.error = 1; - va_list args; - va_start(args, format); - vsnprintf(errmsg, MAX_GRAPHICS_RESPONSE_LEN, format, args); - va_end(args); - - fprintf(stderr, "%s in command: %s\n", errmsg, cmd->command); - if (cmd->quiet < 2) - gr_createresponse(cmd->image_id, cmd->image_number, - cmd->placement_id, errmsg); -} - -/// Creates an error response to the current command (unless suppressed). -static void gr_reporterror_frame(ImageFrame *frame, const char *format, ...) { - char errmsg[MAX_GRAPHICS_RESPONSE_LEN]; - graphics_command_result.error = 1; - va_list args; - va_start(args, format); - vsnprintf(errmsg, MAX_GRAPHICS_RESPONSE_LEN, format, args); - va_end(args); - - if (!frame) { - fprintf(stderr, "%s\n", errmsg); - gr_createresponse(0, 0, 0, errmsg); - } else { - uint32_t id = frame->image->query_id ? frame->image->query_id - : frame->image->image_id; - fprintf(stderr, "%s id=%u\n", errmsg, id); - if (frame->quiet < 2) - gr_createresponse(id, frame->image->image_number, - frame->image->initial_placement_id, - errmsg); - } -} - -/// Loads an image and creates a success/failure response. Returns `frame`, or -/// NULL if it's a query action and the image was deleted. -static ImageFrame *gr_loadimage_and_report(ImageFrame *frame) { - gr_load_imlib_object(frame); - if (!frame->imlib_object) { - gr_reporterror_frame(frame, "EBADF: could not load image"); - } else { - gr_reportsuccess_frame(frame); - } - // If it was a query action, discard the image. - if (frame->image->query_id) { - gr_delete_image(frame->image); - return NULL; - } - return frame; -} - -/// Creates an appropriate uploading failure response to the current command. -static void gr_reportuploaderror(ImageFrame *frame) { - switch (frame->uploading_failure) { - case 0: - return; - case ERROR_CANNOT_OPEN_CACHED_FILE: - gr_reporterror_frame(frame, - "EIO: could not create a file for image"); - break; - case ERROR_OVER_SIZE_LIMIT: - gr_reporterror_frame( - frame, - "EFBIG: the size of the uploaded image exceeded " - "the image size limit %u", - graphics_max_single_image_file_size); - break; - case ERROR_UNEXPECTED_SIZE: - gr_reporterror_frame(frame, - "EINVAL: the size of the uploaded image %u " - "doesn't match the expected size %u", - frame->disk_size, frame->expected_size); - break; - }; -} - -/// Displays a non-virtual placement. This functions records the information in -/// `graphics_command_result`, the placeholder itself is created by the terminal -/// after handling the current command in the graphics module. -static void gr_display_nonvirtual_placement(ImagePlacement *placement) { - if (placement->virtual) - return; - if (placement->image->first_frame.status < STATUS_RAM_LOADING_SUCCESS) - return; - // Infer the placement size if needed. - gr_infer_placement_size_maybe(placement); - // Populate the information about the placeholder which will be created - // by the terminal. - graphics_command_result.create_placeholder = 1; - graphics_command_result.placeholder.image_id = placement->image->image_id; - graphics_command_result.placeholder.placement_id = placement->placement_id; - graphics_command_result.placeholder.columns = placement->cols; - graphics_command_result.placeholder.rows = placement->rows; - graphics_command_result.placeholder.do_not_move_cursor = - placement->do_not_move_cursor; - GR_LOG("Creating a placeholder for %u/%u %d x %d\n", - placement->image->image_id, placement->placement_id, - placement->cols, placement->rows); -} - -/// Marks the rows that are occupied by the image as dirty. -static void gr_schedule_image_redraw(Image *img) { - if (!img) - return; - gr_schedule_image_redraw_by_id(img->image_id); -} - -/// Appends data from `payload` to the frame `frame` when using direct -/// transmission. Note that we report errors only for the final command -/// (`!more`) to avoid spamming the client. If the frame is not specified, use -/// the image id and frame index we are currently uploading. -static void gr_append_data(ImageFrame *frame, const char *payload, int more) { - if (!frame) { - Image *img = gr_find_image(current_upload_image_id); - frame = gr_get_frame(img, current_upload_frame_index); - GR_LOG("Appending data to image %u frame %d\n", - current_upload_image_id, current_upload_frame_index); - if (!img) - GR_LOG("ERROR: this image doesn't exist\n"); - if (!frame) - GR_LOG("ERROR: this frame doesn't exist\n"); - } - if (!more) { - current_upload_image_id = 0; - current_upload_frame_index = 0; - } - if (!frame) { - if (!more) - gr_reporterror_frame(NULL, "ENOENT: could not find the " - "image to append data to"); - return; - } - if (frame->status != STATUS_UPLOADING) { - if (!more) - gr_reportuploaderror(frame); - return; - } - - // Decode the data. - size_t data_size = 0; - char *data = gr_base64dec(payload, &data_size); - - GR_LOG("appending %u + %zu = %zu bytes\n", frame->disk_size, data_size, - frame->disk_size + data_size); - - // Do not append this data if the image exceeds the size limit. - if (frame->disk_size + data_size > - graphics_max_single_image_file_size || - frame->expected_size > graphics_max_single_image_file_size) { - free(data); - gr_delete_imagefile(frame); - frame->uploading_failure = ERROR_OVER_SIZE_LIMIT; - if (!more) - gr_reportuploaderror(frame); - return; - } - - // If there is no open file corresponding to the image, create it. - if (!frame->open_file) { - gr_make_sure_tmpdir_exists(); - char filename[MAX_FILENAME_SIZE]; - gr_get_frame_filename(frame, filename, MAX_FILENAME_SIZE); - FILE *file = fopen(filename, frame->disk_size ? "a" : "w"); - if (!file) { - frame->status = STATUS_UPLOADING_ERROR; - frame->uploading_failure = ERROR_CANNOT_OPEN_CACHED_FILE; - if (!more) - gr_reportuploaderror(frame); - return; - } - frame->open_file = file; - } - - // Write data to the file and update disk size variables. - fwrite(data, 1, data_size, frame->open_file); - free(data); - frame->disk_size += data_size; - frame->image->total_disk_size += data_size; - images_disk_size += data_size; - gr_touch_frame(frame); - - if (more) { - current_upload_image_id = frame->image->image_id; - current_upload_frame_index = frame->index; - } else { - current_upload_image_id = 0; - current_upload_frame_index = 0; - // Close the file. - if (frame->open_file) { - fclose(frame->open_file); - frame->open_file = NULL; - } - frame->status = STATUS_UPLOADING_SUCCESS; - uint32_t placement_id = frame->image->default_placement; - if (frame->expected_size && - frame->expected_size != frame->disk_size) { - // Report failure if the uploaded image size doesn't - // match the expected size. - frame->status = STATUS_UPLOADING_ERROR; - frame->uploading_failure = ERROR_UNEXPECTED_SIZE; - gr_reportuploaderror(frame); - } else { - // Make sure to redraw all existing image instances. - gr_schedule_image_redraw(frame->image); - // Try to load the image into ram and report the result. - frame = gr_loadimage_and_report(frame); - // If there is a non-virtual image placement, we may - // need to display it. - if (frame && frame->index == 1) { - Image *img = frame->image; - ImagePlacement *placement = NULL; - kh_foreach_value(img->placements, placement, { - gr_display_nonvirtual_placement(placement); - }); - } - } - } - - // Check whether we need to delete old images. - gr_check_limits(); -} - -/// Finds the image either by id or by number specified in the command and sets -/// the image_id of `cmd` if the image was found. -static Image *gr_find_image_for_command(GraphicsCommand *cmd) { - if (cmd->image_id) - return gr_find_image(cmd->image_id); - Image *img = NULL; - // If the image number is not specified, we can't find the image, unless - // it's a put command, in which case we will try the last image. - if (cmd->image_number == 0 && cmd->action == 'p') - img = gr_find_image(last_image_id); - else - img = gr_find_image_by_number(cmd->image_number); - if (img) - cmd->image_id = img->image_id; - return img; -} - -/// Creates a new image or a new frame in an existing image (depending on the -/// command's action) and initializes its parameters from the command. -static ImageFrame *gr_new_image_or_frame_from_command(GraphicsCommand *cmd) { - if (cmd->format != 0 && cmd->format != 32 && cmd->format != 24 && - cmd->compression != 0) { - gr_reporterror_cmd(cmd, "EINVAL: compression is supported only " - "for raw pixel data (f=32 or f=24)"); - // Even though we report an error, we still create an image. - } - - Image *img = NULL; - if (cmd->action == 'f') { - // If it's a frame transmission action, there must be an - // existing image. - img = gr_find_image_for_command(cmd); - if (!img) { - gr_reporterror_cmd(cmd, "ENOENT: image not found"); - return NULL; - } - } else { - // Otherwise create a new image object. If the action is `q`, - // we'll use random id instead of the one specified in the - // command. - uint32_t image_id = cmd->action == 'q' ? 0 : cmd->image_id; - img = gr_new_image(image_id); - if (!img) - return NULL; - if (cmd->action == 'q') - img->query_id = cmd->image_id; - else if (!cmd->image_id) - cmd->image_id = img->image_id; - // Set the image number. - img->image_number = cmd->image_number; - } - - ImageFrame *frame = gr_append_new_frame(img); - // Initialize the frame. - frame->expected_size = cmd->size; - frame->format = cmd->format; - frame->compression = cmd->compression; - frame->background_color = cmd->background_color; - frame->background_frame_index = cmd->background_frame; - frame->gap = cmd->gap; - img->total_duration += frame->gap; - frame->blend = !cmd->replace_instead_of_blending; - frame->data_pix_width = cmd->frame_pix_width; - frame->data_pix_height = cmd->frame_pix_height; - if (cmd->action == 'f') { - frame->x = cmd->frame_dst_pix_x; - frame->y = cmd->frame_dst_pix_y; - } - // We save the quietness information in the frame because for direct - // transmission subsequent transmission command won't contain this info. - frame->quiet = cmd->quiet; - return frame; -} - -/// Removes a file if it actually looks like a temporary file. -static void gr_delete_tmp_file(const char *filename) { - if (strstr(filename, "tty-graphics-protocol") == NULL) - return; - if (strstr(filename, "/tmp/") != filename) { - const char *tmpdir = getenv("TMPDIR"); - if (!tmpdir || !tmpdir[0] || - strstr(filename, tmpdir) != filename) - return; - } - unlink(filename); -} - -/// Handles a data transmission command. -static ImageFrame *gr_handle_transmit_command(GraphicsCommand *cmd) { - // The default is direct transmission. - if (!cmd->transmission_medium) - cmd->transmission_medium = 'd'; - - // If neither id, nor image number is specified, and the transmission - // medium is 'd' (or unspecified), and there is an active direct upload, - // this is a continuation of the upload. - if (current_upload_image_id != 0 && cmd->image_id == 0 && - cmd->image_number == 0 && cmd->transmission_medium == 'd') { - cmd->image_id = current_upload_image_id; - GR_LOG("No images id is specified, continuing uploading %u\n", - cmd->image_id); - } - - ImageFrame *frame = NULL; - if (cmd->transmission_medium == 'f' || - cmd->transmission_medium == 't') { - // File transmission. - // Create a new image or a new frame of an existing image. - frame = gr_new_image_or_frame_from_command(cmd); - if (!frame) - return NULL; - last_image_id = frame->image->image_id; - // Decode the filename. - char *original_filename = gr_base64dec(cmd->payload, NULL); - GR_LOG("Copying image %s\n", - sanitized_filename(original_filename)); - // Stat the file and check that it's a regular file and not too - // big. - struct stat st; - int stat_res = stat(original_filename, &st); - const char *stat_error = NULL; - if (stat_res) - stat_error = strerror(errno); - else if (!S_ISREG(st.st_mode)) - stat_error = "Not a regular file"; - else if (st.st_size == 0) - stat_error = "The size of the file is zero"; - else if (st.st_size > graphics_max_single_image_file_size) - stat_error = "The file is too large"; - if (stat_error) { - gr_reporterror_cmd(cmd, - "EBADF: %s", stat_error); - fprintf(stderr, "Could not load the file %s\n", - sanitized_filename(original_filename)); - frame->status = STATUS_UPLOADING_ERROR; - frame->uploading_failure = ERROR_CANNOT_COPY_FILE; - } else { - gr_make_sure_tmpdir_exists(); - // Build the filename for the cached copy of the file. - char cache_filename[MAX_FILENAME_SIZE]; - gr_get_frame_filename(frame, cache_filename, - MAX_FILENAME_SIZE); - // We will create a symlink to the original file, and - // then copy the file to the temporary cache dir. We do - // this symlink trick mostly to be able to use cp for - // copying, and avoid escaping file name characters when - // calling system at the same time. - char tmp_filename_symlink[MAX_FILENAME_SIZE + 4] = {0}; - strcat(tmp_filename_symlink, cache_filename); - strcat(tmp_filename_symlink, ".sym"); - char command[MAX_FILENAME_SIZE + 256]; - size_t len = - snprintf(command, MAX_FILENAME_SIZE + 255, - "cp '%s' '%s'", tmp_filename_symlink, - cache_filename); - if (len > MAX_FILENAME_SIZE + 255 || - symlink(original_filename, tmp_filename_symlink) || - system(command) != 0) { - gr_reporterror_cmd(cmd, - "EBADF: could not copy the " - "image to the cache dir"); - fprintf(stderr, - "Could not copy the image " - "%s (symlink %s) to %s", - sanitized_filename(original_filename), - tmp_filename_symlink, cache_filename); - frame->status = STATUS_UPLOADING_ERROR; - frame->uploading_failure = ERROR_CANNOT_COPY_FILE; - } else { - // Get the file size of the copied file. - frame->status = STATUS_UPLOADING_SUCCESS; - frame->disk_size = st.st_size; - frame->image->total_disk_size += st.st_size; - images_disk_size += frame->disk_size; - if (frame->expected_size && - frame->expected_size != frame->disk_size) { - // The file has unexpected size. - frame->status = STATUS_UPLOADING_ERROR; - frame->uploading_failure = - ERROR_UNEXPECTED_SIZE; - gr_reportuploaderror(frame); - } else { - // Everything seems fine, try to load - // and redraw existing instances. - gr_schedule_image_redraw(frame->image); - frame = gr_loadimage_and_report(frame); - } - } - // Delete the symlink. - unlink(tmp_filename_symlink); - // Delete the original file if it's temporary. - if (cmd->transmission_medium == 't') - gr_delete_tmp_file(original_filename); - } - free(original_filename); - gr_check_limits(); - } else if (cmd->transmission_medium == 'd') { - // Direct transmission (default if 't' is not specified). - frame = gr_get_last_frame(gr_find_image_for_command(cmd)); - if (frame && frame->status == STATUS_UPLOADING) { - // This is a continuation of the previous transmission. - cmd->is_direct_transmission_continuation = 1; - gr_append_data(frame, cmd->payload, cmd->more); - return frame; - } - // If no action is specified, it's not the first transmission - // command. If we couldn't find the image, something went wrong - // and we should just drop this command. - if (cmd->action == 0) - return NULL; - // Otherwise create a new image or frame structure. - frame = gr_new_image_or_frame_from_command(cmd); - if (!frame) - return NULL; - last_image_id = frame->image->image_id; - frame->status = STATUS_UPLOADING; - // Start appending data. - gr_append_data(frame, cmd->payload, cmd->more); - } else { - gr_reporterror_cmd( - cmd, - "EINVAL: transmission medium '%c' is not supported", - cmd->transmission_medium); - return NULL; - } - - return frame; -} - -/// Handles the 'put' command by creating a placement. -static void gr_handle_put_command(GraphicsCommand *cmd) { - if (cmd->image_id == 0 && cmd->image_number == 0) { - gr_reporterror_cmd(cmd, - "EINVAL: neither image id nor image number " - "are specified or both are zero"); - return; - } - - // Find the image with the id or number. - Image *img = gr_find_image_for_command(cmd); - if (!img) { - gr_reporterror_cmd(cmd, "ENOENT: image not found"); - return; - } - - // Create a placement. If a placement with the same id already exists, - // it will be deleted. If the id is zero, a random id will be generated. - ImagePlacement *placement = gr_new_placement(img, cmd->placement_id); - placement->virtual = cmd->virtual; - placement->src_pix_x = cmd->src_pix_x; - placement->src_pix_y = cmd->src_pix_y; - placement->src_pix_width = cmd->src_pix_width; - placement->src_pix_height = cmd->src_pix_height; - placement->cols = cmd->columns; - placement->rows = cmd->rows; - placement->do_not_move_cursor = cmd->do_not_move_cursor; - - if (placement->virtual) { - placement->scale_mode = SCALE_MODE_CONTAIN; - } else if (placement->cols && placement->rows) { - // For classic placements the default is to stretch the image if - // both cols and rows are specified. - placement->scale_mode = SCALE_MODE_FILL; - } else if (placement->cols || placement->rows) { - // But if only one of them is specified, the default is to - // contain. - placement->scale_mode = SCALE_MODE_CONTAIN; - } else { - // If none of them are specified, the default is to use the - // original size. - placement->scale_mode = SCALE_MODE_NONE; - } - - // Display the placement unless it's virtual. - gr_display_nonvirtual_placement(placement); - - // Report success. - gr_reportsuccess_cmd(cmd); -} - -/// Information about what to delete. -typedef struct DeletionData { - uint32_t image_id; - uint32_t placement_id; - /// If true, delete the image object if there are no more placements. - char delete_image_if_no_ref; -} DeletionData; - -/// The callback called for each cell to perform deletion. -static int gr_deletion_callback(void *data, uint32_t image_id, - uint32_t placement_id, int col, - int row, char is_classic) { - DeletionData *del_data = data; - // Leave unicode placeholders alone. - if (!is_classic) - return 0; - if (del_data->image_id && del_data->image_id != image_id) - return 0; - if (del_data->placement_id && del_data->placement_id != placement_id) - return 0; - Image *img = gr_find_image(image_id); - // If the image is already deleted, just erase the placeholder. - if (!img) - return 1; - // Delete the placement. - if (placement_id) - gr_delete_placement(gr_find_placement(img, placement_id)); - // Delete the image if image deletion is requested (uppercase delete - // specifier) and there are no more placements. - if (del_data->delete_image_if_no_ref && kh_size(img->placements) == 0) - gr_delete_image(img); - return 1; -} - -/// Handles the delete command. -static void gr_handle_delete_command(GraphicsCommand *cmd) { - DeletionData del_data = {0}; - del_data.delete_image_if_no_ref = isupper(cmd->delete_specifier) != 0; - char d = tolower(cmd->delete_specifier); - - if (d == 'n') { - d = 'i'; - Image *img = gr_find_image_by_number(cmd->image_number); - if (!img) - return; - del_data.image_id = img->image_id; - } - - if (!d || d == 'a') { - // Delete all visible placements. - gr_for_each_image_cell(gr_deletion_callback, &del_data); - } else if (d == 'i') { - // Delete the specified image by image id and maybe placement - // id. - if (!del_data.image_id) - del_data.image_id = cmd->image_id; - if (!del_data.image_id) { - fprintf(stderr, - "ERROR: image id is not specified in the " - "delete command\n"); - return; - } - del_data.placement_id = cmd->placement_id; - // NOTE: It's not very clear whether we should delete the image - // even if there are no _visible_ placements to delete. We do - // this because otherwise there is no way to delete an image - // with virtual placements in one command. - if (!del_data.placement_id && del_data.delete_image_if_no_ref) - gr_delete_image(gr_find_image(cmd->image_id)); - gr_for_each_image_cell(gr_deletion_callback, &del_data); - } else { - fprintf(stderr, - "WARNING: unsupported value of the d key: '%c'. The " - "command is ignored.\n", - cmd->delete_specifier); - } -} - -static void gr_handle_animation_control_command(GraphicsCommand *cmd) { - if (cmd->image_id == 0 && cmd->image_number == 0) { - gr_reporterror_cmd(cmd, - "EINVAL: neither image id nor image number " - "are specified or both are zero"); - return; - } - - // Find the image with the id or number. - Image *img = gr_find_image_for_command(cmd); - if (!img) { - gr_reporterror_cmd(cmd, "ENOENT: image not found"); - return; - } - - // Find the frame to edit, if requested. - ImageFrame *frame = NULL; - if (cmd->edit_frame) - frame = gr_get_frame(img, cmd->edit_frame); - if (cmd->edit_frame || cmd->gap) { - if (!frame) { - gr_reporterror_cmd(cmd, "ENOENT: frame %d not found", - cmd->edit_frame); - return; - } - if (cmd->gap) { - img->total_duration -= frame->gap; - frame->gap = cmd->gap; - img->total_duration += frame->gap; - } - } - - // Set animation-related parameters of the image. - if (cmd->current_frame) - img->current_frame = cmd->current_frame; - if (cmd->animation_state) { - if (cmd->animation_state == 1) { - img->animation_state = ANIMATION_STATE_STOPPED; - } else if (cmd->animation_state == 2) { - img->animation_state = ANIMATION_STATE_LOADING; - } else if (cmd->animation_state == 3) { - img->animation_state = ANIMATION_STATE_LOOPING; - } else { - gr_reporterror_cmd( - cmd, "EINVAL: invalid animation state: %d", - cmd->animation_state); - } - } - // TODO: Set the number of loops to cmd->loops - - // Make sure we redraw all instances of the image. - gr_schedule_image_redraw(img); -} - -/// Handles a command. -static void gr_handle_command(GraphicsCommand *cmd) { - if (!cmd->image_id && !cmd->image_number) { - // If there is no image id or image number, nobody expects a - // response, so set quiet to 2. - cmd->quiet = 2; - } - ImageFrame *frame = NULL; - switch (cmd->action) { - case 0: - // If no action is specified, it may be a data transmission - // command if 'm=' is specified. - if (cmd->is_data_transmission) { - gr_handle_transmit_command(cmd); - break; - } - gr_reporterror_cmd(cmd, "EINVAL: no action specified"); - break; - case 't': - case 'q': - case 'f': - // Transmit data. 'q' means query, which is basically the same - // as transmit, but the image is discarded, and the id is fake. - // 'f' appends a frame to an existing image. - gr_handle_transmit_command(cmd); - break; - case 'p': - // Display (put) the image. - gr_handle_put_command(cmd); - break; - case 'T': - // Transmit and display. - frame = gr_handle_transmit_command(cmd); - if (frame && !cmd->is_direct_transmission_continuation) { - gr_handle_put_command(cmd); - if (cmd->placement_id) - frame->image->initial_placement_id = - cmd->placement_id; - } - break; - case 'd': - gr_handle_delete_command(cmd); - break; - case 'a': - gr_handle_animation_control_command(cmd); - break; - default: - gr_reporterror_cmd(cmd, "EINVAL: unsupported action: %c", - cmd->action); - return; - } -} - -/// A partially parsed key-value pair. -typedef struct KeyAndValue { - char *key_start; - char *val_start; - unsigned key_len, val_len; -} KeyAndValue; - -/// Parses the value of a key and assigns it to the appropriate field of `cmd`. -static void gr_set_keyvalue(GraphicsCommand *cmd, KeyAndValue *kv) { - char *key_start = kv->key_start; - char *key_end = key_start + kv->key_len; - char *value_start = kv->val_start; - char *value_end = value_start + kv->val_len; - // Currently all keys are one-character. - if (key_end - key_start != 1) { - gr_reporterror_cmd(cmd, "EINVAL: unknown key of length %ld: %s", - key_end - key_start, key_start); - return; - } - long num = 0; - if (*key_start == 'a' || *key_start == 't' || *key_start == 'd' || - *key_start == 'o') { - // Some keys have one-character values. - if (value_end - value_start != 1) { - gr_reporterror_cmd( - cmd, - "EINVAL: value of 'a', 't' or 'd' must be a " - "single char: %s", - key_start); - return; - } - } else { - // All the other keys have integer values. - char *num_end = NULL; - num = strtol(value_start, &num_end, 10); - if (num_end != value_end) { - gr_reporterror_cmd( - cmd, "EINVAL: could not parse number value: %s", - key_start); - return; - } - } - switch (*key_start) { - case 'a': - cmd->action = *value_start; - break; - case 't': - cmd->transmission_medium = *value_start; - break; - case 'd': - cmd->delete_specifier = *value_start; - break; - case 'q': - cmd->quiet = num; - break; - case 'f': - cmd->format = num; - if (num != 0 && num != 24 && num != 32 && num != 100) { - gr_reporterror_cmd( - cmd, - "EINVAL: unsupported format specification: %s", - key_start); - } - break; - case 'o': - cmd->compression = *value_start; - if (cmd->compression != 'z') { - gr_reporterror_cmd(cmd, - "EINVAL: unsupported compression " - "specification: %s", - key_start); - } - break; - case 's': - if (cmd->action == 'a') - cmd->animation_state = num; - else - cmd->frame_pix_width = num; - break; - case 'v': - if (cmd->action == 'a') - cmd->loops = num; - else - cmd->frame_pix_height = num; - break; - case 'i': - cmd->image_id = num; - break; - case 'I': - cmd->image_number = num; - break; - case 'p': - cmd->placement_id = num; - break; - case 'x': - cmd->src_pix_x = num; - cmd->frame_dst_pix_x = num; - break; - case 'y': - if (cmd->action == 'f') - cmd->frame_dst_pix_y = num; - else - cmd->src_pix_y = num; - break; - case 'w': - cmd->src_pix_width = num; - break; - case 'h': - cmd->src_pix_height = num; - break; - case 'c': - if (cmd->action == 'f') - cmd->background_frame = num; - else if (cmd->action == 'a') - cmd->current_frame = num; - else - cmd->columns = num; - break; - case 'r': - if (cmd->action == 'f' || cmd->action == 'a') - cmd->edit_frame = num; - else - cmd->rows = num; - break; - case 'm': - cmd->is_data_transmission = 1; - cmd->more = num; - break; - case 'S': - cmd->size = num; - break; - case 'U': - cmd->virtual = num; - break; - case 'X': - if (cmd->action == 'f') - cmd->replace_instead_of_blending = num; - else - break; /*ignore*/ - break; - case 'Y': - if (cmd->action == 'f') - cmd->background_color = num; - else - break; /*ignore*/ - break; - case 'z': - if (cmd->action == 'f' || cmd->action == 'a') - cmd->gap = num; - else - break; /*ignore*/ - break; - case 'C': - cmd->do_not_move_cursor = num; - break; - default: - gr_reporterror_cmd(cmd, "EINVAL: unsupported key: %s", - key_start); - return; - } -} - -/// Parse and execute a graphics command. `buf` must start with 'G' and contain -/// at least `len + 1` characters. Returns 1 on success. -int gr_parse_command(char *buf, size_t len) { - if (buf[0] != 'G') - return 0; - - memset(&graphics_command_result, 0, sizeof(GraphicsCommandResult)); - - global_command_counter++; - GR_LOG("### Command %lu: %.80s\n", global_command_counter, buf); - - // Eat the 'G'. - ++buf; - --len; - - GraphicsCommand cmd = {.command = buf}; - // The state of parsing. 'k' to parse key, 'v' to parse value, 'p' to - // parse the payload. - char state = 'k'; - // An array of partially parsed key-value pairs. - KeyAndValue key_vals[32]; - unsigned key_vals_count = 0; - char *key_start = buf; - char *key_end = NULL; - char *val_start = NULL; - char *val_end = NULL; - char *c = buf; - while (c - buf < len + 1) { - if (state == 'k') { - switch (*c) { - case ',': - case ';': - case '\0': - state = *c == ',' ? 'k' : 'p'; - key_end = c; - gr_reporterror_cmd( - &cmd, "EINVAL: key without value: %s ", - key_start); - break; - case '=': - key_end = c; - state = 'v'; - val_start = c + 1; - break; - default: - break; - } - } else if (state == 'v') { - switch (*c) { - case ',': - case ';': - case '\0': - state = *c == ',' ? 'k' : 'p'; - val_end = c; - if (key_vals_count >= - sizeof(key_vals) / sizeof(*key_vals)) { - gr_reporterror_cmd(&cmd, - "EINVAL: too many " - "key-value pairs"); - break; - } - key_vals[key_vals_count].key_start = key_start; - key_vals[key_vals_count].val_start = val_start; - key_vals[key_vals_count].key_len = - key_end - key_start; - key_vals[key_vals_count].val_len = - val_end - val_start; - ++key_vals_count; - key_start = c + 1; - break; - default: - break; - } - } else if (state == 'p') { - cmd.payload = c; - // break out of the loop, we don't check the payload - break; - } - ++c; - } - - // Set the action key ('a=') first because we need it to disambiguate - // some keys. Also set 'i=' and 'I=' for better error reporting. - for (unsigned i = 0; i < key_vals_count; ++i) { - if (key_vals[i].key_len == 1) { - char *start = key_vals[i].key_start; - if (*start == 'a' || *start == 'i' || *start == 'I') { - gr_set_keyvalue(&cmd, &key_vals[i]); - break; - } - } - } - // Set the rest of the keys. - for (unsigned i = 0; i < key_vals_count; ++i) - gr_set_keyvalue(&cmd, &key_vals[i]); - - if (!cmd.payload) - cmd.payload = buf + len; - - if (cmd.payload && cmd.payload[0]) - GR_LOG(" payload size: %ld\n", strlen(cmd.payload)); - - if (!graphics_command_result.error) - gr_handle_command(&cmd); - - if (graphics_debug_mode) { - fprintf(stderr, "Response: "); - for (const char *resp = graphics_command_result.response; - *resp != '\0'; ++resp) { - if (isprint(*resp)) - fprintf(stderr, "%c", *resp); - else - fprintf(stderr, "(0x%x)", *resp); - } - fprintf(stderr, "\n"); - } - - // Make sure that we suppress response if needed. Usually cmd.quiet is - // taken into account when creating the response, but it's not very - // reliable in the current implementation. - if (cmd.quiet) { - if (!graphics_command_result.error || cmd.quiet >= 2) - graphics_command_result.response[0] = '\0'; - } - - return 1; -} - -//////////////////////////////////////////////////////////////////////////////// -// base64 decoding part is basically copied from st.c -//////////////////////////////////////////////////////////////////////////////// - -static const char gr_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}; - -static char gr_base64_getc(const char **src) { - while (**src && !isprint(**src)) - (*src)++; - return **src ? *((*src)++) : '='; /* emulate padding if string ends */ -} - -char *gr_base64dec(const char *src, size_t *size) { - size_t in_len = strlen(src); - char *result, *dst; - - result = dst = malloc((in_len + 3) / 4 * 3 + 1); - while (*src) { - int a = gr_base64_digits[(unsigned char)gr_base64_getc(&src)]; - int b = gr_base64_digits[(unsigned char)gr_base64_getc(&src)]; - int c = gr_base64_digits[(unsigned char)gr_base64_getc(&src)]; - int d = gr_base64_digits[(unsigned char)gr_base64_getc(&src)]; - - 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'; - if (size) { - *size = dst - result; - } - return result; -} diff --git a/suckless/st/graphics.h b/suckless/st/graphics.h deleted file mode 100644 index 2e75dea..0000000 --- a/suckless/st/graphics.h +++ /dev/null @@ -1,107 +0,0 @@ - -#include -#include -#include - -/// Initialize the graphics module. -void gr_init(Display *disp, Visual *vis, Colormap cm); -/// Deinitialize the graphics module. -void gr_deinit(); - -/// Add an image rectangle to a list if rectangles to draw. This function may -/// actually draw some rectangles, or it may wait till more rectangles are -/// appended. Must be called between `gr_start_drawing` and `gr_finish_drawing`. -/// - `img_start_col..img_end_col` and `img_start_row..img_end_row` define the -/// part of the image to draw (row/col indices are zero-based, ends are -/// excluded). -/// - `x_col` and `y_row` are the coordinates of the top-left corner of the -/// image in the terminal grid. -/// - `x_pix` and `y_pix` are the same but in pixels. -/// - `reverse` indicates whether colors should be inverted. -void gr_append_imagerect(Drawable buf, uint32_t image_id, uint32_t placement_id, - int img_start_col, int img_end_col, int img_start_row, - int img_end_row, int x_col, int y_row, int x_pix, - int y_pix, int cw, int ch, int reverse); -/// Prepare for image drawing. `cw` and `ch` are dimensions of the cell. -void gr_start_drawing(Drawable buf, int cw, int ch); -/// Finish image drawing. This functions will draw all the rectangles left to -/// draw. -void gr_finish_drawing(Drawable buf); -/// Mark rows containing animations as dirty if it's time to redraw them. Must -/// be called right after `gr_start_drawing`. -void gr_mark_dirty_animations(int *dirty, int rows); - -/// Parse and execute a graphics command. `buf` must start with 'G' and contain -/// at least `len + 1` characters (including '\0'). Returns 1 on success. -/// Additional informations is returned through `graphics_command_result`. -int gr_parse_command(char *buf, size_t len); - -/// Executes `command` with the name of the file corresponding to `image_id` as -/// the argument. Executes xmessage with an error message on failure. -void gr_preview_image(uint32_t image_id, const char *command); - -/// Executes ` -e less ` where is the name of a temporary file -/// containing the information about an image and placement, and is -/// specified with `st_executable`. -void gr_show_image_info(uint32_t image_id, uint32_t placement_id, - uint32_t imgcol, uint32_t imgrow, - char is_classic_placeholder, int32_t diacritic_count, - char *st_executable); - -/// Dumps the internal state (images and placements) to stderr. -void gr_dump_state(); - -/// Unloads images to reduce RAM usage. -void gr_unload_images_to_reduce_ram(); - -/// Executes `callback` for each image cell. `callback` may return 1 to erase -/// the cell or 0 to keep it. This function is implemented in `st.c`. -void gr_for_each_image_cell(int (*callback)(void *data, uint32_t image_id, - uint32_t placement_id, int col, - int row, char is_classic), - void *data); - -/// Marks all the rows containing the image with `image_id` as dirty. -void gr_schedule_image_redraw_by_id(uint32_t image_id); - -typedef enum { - GRAPHICS_DEBUG_NONE = 0, - GRAPHICS_DEBUG_LOG = 1, - GRAPHICS_DEBUG_LOG_AND_BOXES = 2, -} GraphicsDebugMode; - -/// Print additional information, draw bounding bounding boxes, etc. -extern GraphicsDebugMode graphics_debug_mode; - -/// Whether to display images or just draw bounding boxes. -extern char graphics_display_images; - -/// The time in milliseconds until the next redraw to update animations. -/// INT_MAX means no redraw is needed. Populated by `gr_finish_drawing`. -extern int graphics_next_redraw_delay; - -#define MAX_GRAPHICS_RESPONSE_LEN 256 - -/// A structure representing the result of a graphics command. -typedef struct { - /// Indicates if the terminal needs to be redrawn. - char redraw; - /// The response of the command that should be sent back to the client - /// (may be empty if the quiet flag is set). - char response[MAX_GRAPHICS_RESPONSE_LEN]; - /// Whether there was an error executing this command (not very useful, - /// the response must be sent back anyway). - char error; - /// Whether the terminal has to create a placeholder for a non-virtual - /// placement. - char create_placeholder; - /// The placeholder that needs to be created. - struct { - uint32_t rows, columns; - uint32_t image_id, placement_id; - char do_not_move_cursor; - } placeholder; -} GraphicsCommandResult; - -/// The result of a graphics command. -extern GraphicsCommandResult graphics_command_result; diff --git a/suckless/st/hb.c b/suckless/st/hb.c deleted file mode 100644 index 2bb334c..0000000 --- a/suckless/st/hb.c +++ /dev/null @@ -1,125 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -#include "st.h" -#include "hb.h" - -#define FEATURE(c1,c2,c3,c4) { .tag = HB_TAG(c1,c2,c3,c4), .value = 1, .start = HB_FEATURE_GLOBAL_START, .end = HB_FEATURE_GLOBAL_END } -#define BUFFER_STEP 256 - -hb_font_t *hbfindfont(XftFont *match); - -typedef struct { - XftFont *match; - hb_font_t *font; -} HbFontMatch; - -typedef struct { - size_t capacity; - HbFontMatch *fonts; -} HbFontCache; - -static HbFontCache hbfontcache = { 0, NULL }; - -typedef struct { - size_t capacity; - Rune *runes; -} RuneBuffer; - -static RuneBuffer hbrunebuffer = { 0, NULL }; - -/* - * Poplulate the array with a list of font features, wrapped in FEATURE macro, - * e. g. - * FEATURE('c', 'a', 'l', 't'), FEATURE('d', 'l', 'i', 'g') - */ -hb_feature_t features[] = {0}; - -void -hbunloadfonts() -{ - for (int i = 0; i < hbfontcache.capacity; i++) { - hb_font_destroy(hbfontcache.fonts[i].font); - XftUnlockFace(hbfontcache.fonts[i].match); - } - - if (hbfontcache.fonts != NULL) { - free(hbfontcache.fonts); - hbfontcache.fonts = NULL; - } - hbfontcache.capacity = 0; -} - -hb_font_t * -hbfindfont(XftFont *match) -{ - for (int i = 0; i < hbfontcache.capacity; i++) { - if (hbfontcache.fonts[i].match == match) - return hbfontcache.fonts[i].font; - } - - /* Font not found in cache, caching it now. */ - hbfontcache.fonts = realloc(hbfontcache.fonts, sizeof(HbFontMatch) * (hbfontcache.capacity + 1)); - FT_Face face = XftLockFace(match); - hb_font_t *font = hb_ft_font_create(face, NULL); - if (font == NULL) - die("Failed to load Harfbuzz font."); - - hbfontcache.fonts[hbfontcache.capacity].match = match; - hbfontcache.fonts[hbfontcache.capacity].font = font; - hbfontcache.capacity += 1; - - return font; -} - -void hbtransform(HbTransformData *data, XftFont *xfont, const Glyph *glyphs, int start, int length) { - ushort mode = USHRT_MAX; - unsigned int glyph_count; - int rune_idx, glyph_idx, end = start + length; - - hb_font_t *font = hbfindfont(xfont); - if (font == NULL) - return; - - hb_buffer_t *buffer = hb_buffer_create(); - hb_buffer_set_direction(buffer, HB_DIRECTION_LTR); - hb_buffer_set_cluster_level(buffer, HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS); - - /* Resize the buffer if required length is larger. */ - if (hbrunebuffer.capacity < length) { - hbrunebuffer.capacity = (length / BUFFER_STEP + 1) * BUFFER_STEP; - hbrunebuffer.runes = realloc(hbrunebuffer.runes, hbrunebuffer.capacity * sizeof(Rune)); - } - - /* Fill buffer with codepoints. */ - for (rune_idx = 0, glyph_idx = start; glyph_idx < end; glyph_idx++, rune_idx++) { - hbrunebuffer.runes[rune_idx] = glyphs[glyph_idx].u; - mode = glyphs[glyph_idx].mode; - if (mode & ATTR_WDUMMY) - hbrunebuffer.runes[rune_idx] = 0x0020; - } - hb_buffer_add_codepoints(buffer, hbrunebuffer.runes, length, 0, length); - - /* Shape the segment. */ - hb_shape(font, buffer, features, sizeof(features)/sizeof(hb_feature_t)); - - /* Get new glyph info. */ - hb_glyph_info_t *info = hb_buffer_get_glyph_infos(buffer, &glyph_count); - hb_glyph_position_t *pos = hb_buffer_get_glyph_positions(buffer, &glyph_count); - - /* Fill the output. */ - data->buffer = buffer; - data->glyphs = info; - data->positions = pos; - data->count = glyph_count; -} - -void hbcleanup(HbTransformData *data) { - hb_buffer_destroy(data->buffer); - memset(data, 0, sizeof(HbTransformData)); -} diff --git a/suckless/st/hb.h b/suckless/st/hb.h deleted file mode 100644 index 3b0ef44..0000000 --- a/suckless/st/hb.h +++ /dev/null @@ -1,14 +0,0 @@ -#include -#include -#include - -typedef struct { - hb_buffer_t *buffer; - hb_glyph_info_t *glyphs; - hb_glyph_position_t *positions; - unsigned int count; -} HbTransformData; - -void hbunloadfonts(); -void hbtransform(HbTransformData *, XftFont *, const Glyph *, int, int); -void hbcleanup(HbTransformData *); diff --git a/suckless/st/hb.o b/suckless/st/hb.o deleted file mode 100644 index 34d5bbe58d498ad6527bebec41ab53ed8850776d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4304 zcmbtWU2GIp6u#3gu<|pz#lI>FlUTL>uuw&%AlT_2w@E=13KFc#c6XMoY==N@_)x=)^D_MG$G@1Aq+ zxpVK%8y(%9HJZjqG`5tDdxSE!a>lsbBFq-1vl;BK$n2{PRO5^9$06q^FN+v_Xv~fJqelc=OjOL$q44_NQ6;zc z4=;-f`OsJH5}EWM)Y zF7FEgba{vNhXm<}@b}}sc6-12?BrqIEEW}c^BCafaA=;{eB|}6<;k&b?{7ZxbBJrl zWmCO#-P%>LD(%>Q1K8s|El0h&%Po^ak&f@ZI?=<@NQgHdFP=8NGy8zbymP$#6dIIz zAJ)N#MSr@z)7{<`zoOx6Lx_79h{nB9#ar%Ku&~~6m)8+3w>N}LucMxW5l->P{9Y6} z^tFC{ulcgsYrbN}M~8>TAkon8k*>pg*zg{Ft$Fe?_e3$U!!;A^@Yze($HqiCxCyH` zzE{r)KOOm_5~-_=)U`#|k22Po=+9ay!?lg9ok$rx;iUVD+qM~LJLkq2Th`XL$Y@+< zGTU>))apb`f{@7O9=^2E*QBS8tZd;A(&y z62?72nF$Z#6?+8OhAR9_ z72K_Y@2rBq1vutijSUA8`wjX%cqUrc?kf0!D)^68@JoQ#Df>mau2tbrhWdyDlpA7H z!IxISp9dV*`vV+E6!A`iURQX1oa#TM#8KaqqgD9dDg1ksyr&c# z&nVSnfQ^E~k|KQdd?CJFpp3av6QBNvDgm7CYZfaE4!DUv(5~a_3|WqqO~hPltIJ}k zgqvWozCwY;92*^^H^rJ*ENKr6z-JqaJ9gf3+(DR%0j*3t z?IZ>)S=&*f_Ws&=)QSK z;*tiQFHZ*niOXX^H1;@H7&Ay;D1rGmn7$GG&u#)3W8!y{Dl~t#3W81fNw-KWm}ia5 zZ@{=JG>>!_43e$#wgeX>2ZP*ofKP!ZuuW{MoWD{H3O4nh;LTuQ%;5Yl<^1DBlsY&+ z3;0C)pO*)JgPe!^kN&2; exit 1" INT - -cols="" -rows="" -file="" -tty="/dev/tty" -uploading_method="auto" -cell_size="" -scale=1 -max_cols="" -max_rows="" -speed="" - -# Parse the command line. -while [ $# -gt 0 ]; do - case "$1" in - -c|--columns|--cols) - cols="$2" - shift 2 - ;; - -r|--rows|-l|--lines) - rows="$2" - shift 2 - ;; - -s|--scale) - scale="$2" - shift 2 - ;; - -h|--help) - echo "$short_help" - exit 0 - ;; - -m|--upload-method|--uploading-method) - uploading_method="$2" - shift 2 - ;; - --cell-size) - cell_size="$2" - shift 2 - ;; - --max-cols) - max_cols="$2" - shift 2 - ;; - --max-rows) - max_rows="$2" - shift 2 - ;; - --speed) - speed="$2" - shift 2 - ;; - --) - file="$2" - shift 2 - ;; - -*) - echo "Unknown option: $1" >&2 - exit 1 - ;; - *) - if [ -n "$file" ]; then - echo "Multiple image files are not supported: $file and $1" >&2 - exit 1 - fi - file="$1" - shift - ;; - esac -done - -file="$(realpath "$file")" - -##################################################################### -# Adjust the terminal state -##################################################################### - -stty_orig="$(stty -g < "$tty")" -stty -echo < "$tty" -# Disable ctrl-z. Pressing ctrl-z during image uploading may cause some -# horrible issues otherwise. -stty susp undef < "$tty" -stty -icanon < "$tty" - -restore_echo() { - [ -n "$stty_orig" ] || return - stty $stty_orig < "$tty" -} - -trap restore_echo EXIT TERM - -##################################################################### -# Detect imagemagick -##################################################################### - -# If there is the 'magick' command, use it instead of separate 'convert' and -# 'identify' commands. -if command -v magick > /dev/null; then - identify="magick identify" - convert="magick" -else - identify="identify" - convert="convert" -fi - -##################################################################### -# Detect tmux -##################################################################### - -# Check if we are inside tmux. -inside_tmux="" -if [ -n "$TMUX" ]; then - case "$TERM" in - *tmux*|*screen*) - inside_tmux=1 - ;; - esac -fi - -##################################################################### -# Compute the number of rows and columns -##################################################################### - -is_pos_int() { - if [ -z "$1" ]; then - return 1 # false - fi - if [ -z "$(printf '%s' "$1" | tr -d '[:digit:]')" ]; then - if [ "$1" -gt 0 ]; then - return 0 # true - fi - fi - return 1 # false -} - -if [ -n "$cols" ] || [ -n "$rows" ]; then - if [ -n "$max_cols" ] || [ -n "$max_rows" ]; then - echo "You can't specify both max-cols/rows and cols/rows" >&2 - exit 1 - fi -fi -# Get the max number of cols and rows. -[ -n "$max_cols" ] || max_cols="$(tput cols)" -[ -n "$max_rows" ] || max_rows="$(tput lines)" -if [ "$max_rows" -gt 255 ]; then - max_rows=255 -fi - -python_ioctl_command="import array, fcntl, termios -buf = array.array('H', [0, 0, 0, 0]) -fcntl.ioctl(0, termios.TIOCGWINSZ, buf) -print(int(buf[2]/buf[1]), int(buf[3]/buf[0]))" - -# Get the cell size in pixels if either cols or rows are not specified. -if [ -z "$cols" ] || [ -z "$rows" ]; then - cell_width="" - cell_height="" - # If the cell size is specified, use it. - if [ -n "$cell_size" ]; then - cell_width="${cell_size%x*}" - cell_height="${cell_size#*x}" - if ! is_pos_int "$cell_height" || ! is_pos_int "$cell_width"; then - echo "Invalid cell size: $cell_size" >&2 - exit 1 - fi - fi - # Otherwise try to use TIOCGWINSZ ioctl via python. - if [ -z "$cell_width" ] || [ -z "$cell_height" ]; then - cell_size_ioctl="$(python3 -c "$python_ioctl_command" < "$tty" 2> /dev/null)" - cell_width="${cell_size_ioctl% *}" - cell_height="${cell_size_ioctl#* }" - if ! is_pos_int "$cell_height" || ! is_pos_int "$cell_width"; then - cell_width="" - cell_height="" - fi - fi - # If it didn't work, try to use csi XTWINOPS. - if [ -z "$cell_width" ] || [ -z "$cell_height" ]; then - if [ -n "$inside_tmux" ]; then - printf '\ePtmux;\e\e[16t\e\\' >> "$tty" - else - printf '\e[16t' >> "$tty" - fi - # The expected response will look like ^[[6;;t - term_response="" - while true; do - char=$(dd bs=1 count=1 <"$tty" 2>/dev/null) - if [ "$char" = "t" ]; then - break - fi - term_response="$term_response$char" - done - cell_height="$(printf '%s' "$term_response" | cut -d ';' -f 2)" - cell_width="$(printf '%s' "$term_response" | cut -d ';' -f 3)" - if ! is_pos_int "$cell_height" || ! is_pos_int "$cell_width"; then - cell_width=8 - cell_height=16 - fi - fi -fi - -# Compute a formula with bc and round to the nearest integer. -bc_round() { - LC_NUMERIC=C printf '%.0f' "$(printf '%s\n' "scale=2;($1) + 0.5" | bc)" -} - -# Compute the number of rows and columns of the image. -if [ -z "$cols" ] || [ -z "$rows" ]; then - # Get the size of the image and its resolution. If it's an animation, use - # the first frame. - format_output="$($identify -format '%w %h\n' "$file" | head -1)" - img_width="$(printf '%s' "$format_output" | cut -d ' ' -f 1)" - img_height="$(printf '%s' "$format_output" | cut -d ' ' -f 2)" - if ! is_pos_int "$img_width" || ! is_pos_int "$img_height"; then - echo "Couldn't get image size from identify: $format_output" >&2 - echo >&2 - exit 1 - fi - opt_cols_expr="(${scale}*${img_width}/${cell_width})" - opt_rows_expr="(${scale}*${img_height}/${cell_height})" - if [ -z "$cols" ] && [ -z "$rows" ]; then - # If columns and rows are not specified, compute the optimal values - # using the information about rows and columns per inch. - cols="$(bc_round "$opt_cols_expr")" - rows="$(bc_round "$opt_rows_expr")" - # Make sure that automatically computed rows and columns are within some - # sane limits - if [ "$cols" -gt "$max_cols" ]; then - rows="$(bc_round "$rows * $max_cols / $cols")" - cols="$max_cols" - fi - if [ "$rows" -gt "$max_rows" ]; then - cols="$(bc_round "$cols * $max_rows / $rows")" - rows="$max_rows" - fi - elif [ -z "$cols" ]; then - # If only one dimension is specified, compute the other one to match the - # aspect ratio as close as possible. - cols="$(bc_round "${opt_cols_expr}*${rows}/${opt_rows_expr}")" - elif [ -z "$rows" ]; then - rows="$(bc_round "${opt_rows_expr}*${cols}/${opt_cols_expr}")" - fi - - if [ "$cols" -lt 1 ]; then - cols=1 - fi - if [ "$rows" -lt 1 ]; then - rows=1 - fi -fi - -##################################################################### -# Generate an image id -##################################################################### - -image_id="" -while [ -z "$image_id" ]; do - image_id="$(shuf -i 16777217-4294967295 -n 1)" - # Check that the id requires 24-bit fg colors. - if [ "$(expr \( "$image_id" / 256 \) % 65536)" -eq 0 ]; then - image_id="" - fi -done - -##################################################################### -# Uploading the image -##################################################################### - -# Choose the uploading method -if [ "$uploading_method" = "auto" ]; then - if [ -n "$SSH_CLIENT" ] || [ -n "$SSH_TTY" ] || [ -n "$SSH_CONNECTION" ]; then - uploading_method="direct" - else - uploading_method="file" - fi -fi - -# Functions to emit the start and the end of a graphics command. -if [ -n "$inside_tmux" ]; then - # If we are in tmux we have to wrap the command in Ptmux. - graphics_command_start='\ePtmux;\e\e_G' - graphics_command_end='\e\e\\\e\\' -else - graphics_command_start='\e_G' - graphics_command_end='\e\\' -fi - -start_gr_command() { - printf "$graphics_command_start" >> "$tty" -} -end_gr_command() { - printf "$graphics_command_end" >> "$tty" -} - -# Send a graphics command with the correct start and end -gr_command() { - start_gr_command - printf '%s' "$1" >> "$tty" - end_gr_command -} - -# Send an uploading command. Usage: gr_upload -# Where is a part of command that specifies the action, it will be -# repeated for every chunk (if the method is direct), and is the rest -# of the command that specifies the image parameters. and -# must not include the transmission method or ';'. -# Example: -# gr_upload "a=T,q=2" "U=1,i=${image_id},f=100,c=${cols},r=${rows}" "$file" -gr_upload() { - arg_action="$1" - arg_command="$2" - arg_file="$3" - if [ "$uploading_method" = "file" ]; then - # base64-encode the filename - encoded_filename=$(printf '%s' "$arg_file" | base64 -w0) - gr_command "${arg_action},${arg_command},t=f;${encoded_filename}" - fi - if [ "$uploading_method" = "direct" ]; then - # Create a temporary directory to store the chunked image. - chunkdir="$(mktemp -d)" - if [ ! "$chunkdir" ] || [ ! -d "$chunkdir" ]; then - echo "Can't create a temp dir" >&2 - exit 1 - fi - # base64-encode the file and split it into chunks. The size of each - # graphics command shouldn't be more than 4096, so we set the size of an - # encoded chunk to be 3968, slightly less than that. - chunk_size=3968 - cat "$arg_file" | base64 -w0 | split -b "$chunk_size" - "$chunkdir/chunk_" - - # Issue a command indicating that we want to start data transmission for - # a new image. - gr_command "${arg_action},${arg_command},t=d,m=1" - - # Transmit chunks. - for chunk in "$chunkdir/chunk_"*; do - start_gr_command - printf '%s' "${arg_action},i=${image_id},m=1;" >> "$tty" - cat "$chunk" >> "$tty" - end_gr_command - rm "$chunk" - done - - # Tell the terminal that we are done. - gr_command "${arg_action},i=$image_id,m=0" - - # Remove the temporary directory. - rmdir "$chunkdir" - fi -} - -delayed_frame_dir_cleanup() { - arg_frame_dir="$1" - sleep 2 - if [ -n "$arg_frame_dir" ]; then - for frame in "$arg_frame_dir"/frame_*.png; do - rm "$frame" - done - rmdir "$arg_frame_dir" - fi -} - -upload_image_and_print_placeholder() { - # Check if the file is an animation. - frame_count=$($identify -format '%n\n' "$file" | head -n 1) - if [ "$frame_count" -gt 1 ]; then - # The file is an animation, decompose into frames and upload each frame. - frame_dir="$(mktemp -d)" - frame_dir="$HOME/temp/frames${frame_dir}" - mkdir -p "$frame_dir" - if [ ! "$frame_dir" ] || [ ! -d "$frame_dir" ]; then - echo "Can't create a temp dir for frames" >&2 - exit 1 - fi - - # Decompose the animation into separate frames. - $convert "$file" -coalesce "$frame_dir/frame_%06d.png" - - # Get all frame delays at once, in centiseconds, as a space-separated - # string. - delays=$($identify -format "%T " "$file") - - frame_number=1 - for frame in "$frame_dir"/frame_*.png; do - # Read the delay for the current frame and convert it from - # centiseconds to milliseconds. - delay=$(printf '%s' "$delays" | cut -d ' ' -f "$frame_number") - delay=$((delay * 10)) - # If the delay is 0, set it to 100ms. - if [ "$delay" -eq 0 ]; then - delay=100 - fi - - if [ -n "$speed" ]; then - delay=$(bc_round "$delay / $speed") - fi - - if [ "$frame_number" -eq 1 ]; then - # Upload the first frame with a=T - gr_upload "q=2,a=T" "f=100,U=1,i=${image_id},c=${cols},r=${rows}" "$frame" - # Set the delay for the first frame and also play the animation - # in loading mode (s=2). - gr_command "a=a,v=1,s=2,r=${frame_number},z=${delay},i=${image_id}" - # Print the placeholder after the first frame to reduce the wait - # time. - print_placeholder - else - # Upload subsequent frames with a=f - gr_upload "q=2,a=f" "f=100,i=${image_id},z=${delay}" "$frame" - fi - - frame_number=$((frame_number + 1)) - done - - # Play the animation in loop mode (s=3). - gr_command "a=a,v=1,s=3,i=${image_id}" - - # Remove the temporary directory, but do it in the background with a - # delay to avoid removing files before they are loaded by the terminal. - delayed_frame_dir_cleanup "$frame_dir" 2> /dev/null & - else - # The file is not an animation, upload it directly - gr_upload "q=2,a=T" "U=1,i=${image_id},f=100,c=${cols},r=${rows}" "$file" - # Print the placeholder - print_placeholder - fi -} - -##################################################################### -# Printing the image placeholder -##################################################################### - -print_placeholder() { - # Each line starts with the escape sequence to set the foreground color to - # the image id. - blue="$(expr "$image_id" % 256 )" - green="$(expr \( "$image_id" / 256 \) % 256 )" - red="$(expr \( "$image_id" / 65536 \) % 256 )" - line_start="$(printf "\e[38;2;%d;%d;%dm" "$red" "$green" "$blue")" - line_end="$(printf "\e[39;m")" - - id4th="$(expr \( "$image_id" / 16777216 \) % 256 )" - eval "id_diacritic=\$d${id4th}" - - # Reset the brush state, mostly to reset the underline color. - printf "\e[0m" - - # Fill the output with characters representing the image - for y in $(seq 0 "$(expr "$rows" - 1)"); do - eval "row_diacritic=\$d${y}" - printf '%s' "$line_start" - for x in $(seq 0 "$(expr "$cols" - 1)"); do - eval "col_diacritic=\$d${x}" - # Note that when $x is out of bounds, the column diacritic will - # be empty, meaning that the column should be guessed by the - # terminal. - if [ "$x" -ge "$num_diacritics" ]; then - printf '%s' "${placeholder}${row_diacritic}" - else - printf '%s' "${placeholder}${row_diacritic}${col_diacritic}${id_diacritic}" - fi - done - printf '%s\n' "$line_end" - done - - printf "\e[0m" -} - -d0="̅" -d1="̍" -d2="̎" -d3="̐" -d4="̒" -d5="̽" -d6="̾" -d7="̿" -d8="͆" -d9="͊" -d10="͋" -d11="͌" -d12="͐" -d13="͑" -d14="͒" -d15="͗" -d16="͛" -d17="ͣ" -d18="ͤ" -d19="ͥ" -d20="ͦ" -d21="ͧ" -d22="ͨ" -d23="ͩ" -d24="ͪ" -d25="ͫ" -d26="ͬ" -d27="ͭ" -d28="ͮ" -d29="ͯ" -d30="҃" -d31="҄" -d32="҅" -d33="҆" -d34="҇" -d35="֒" -d36="֓" -d37="֔" -d38="֕" -d39="֗" -d40="֘" -d41="֙" -d42="֜" -d43="֝" -d44="֞" -d45="֟" -d46="֠" -d47="֡" -d48="֨" -d49="֩" -d50="֫" -d51="֬" -d52="֯" -d53="ׄ" -d54="ؐ" -d55="ؑ" -d56="ؒ" -d57="ؓ" -d58="ؔ" -d59="ؕ" -d60="ؖ" -d61="ؗ" -d62="ٗ" -d63="٘" -d64="ٙ" -d65="ٚ" -d66="ٛ" -d67="ٝ" -d68="ٞ" -d69="ۖ" -d70="ۗ" -d71="ۘ" -d72="ۙ" -d73="ۚ" -d74="ۛ" -d75="ۜ" -d76="۟" -d77="۠" -d78="ۡ" -d79="ۢ" -d80="ۤ" -d81="ۧ" -d82="ۨ" -d83="۫" -d84="۬" -d85="ܰ" -d86="ܲ" -d87="ܳ" -d88="ܵ" -d89="ܶ" -d90="ܺ" -d91="ܽ" -d92="ܿ" -d93="݀" -d94="݁" -d95="݃" -d96="݅" -d97="݇" -d98="݉" -d99="݊" -d100="߫" -d101="߬" -d102="߭" -d103="߮" -d104="߯" -d105="߰" -d106="߱" -d107="߳" -d108="ࠖ" -d109="ࠗ" -d110="࠘" -d111="࠙" -d112="ࠛ" -d113="ࠜ" -d114="ࠝ" -d115="ࠞ" -d116="ࠟ" -d117="ࠠ" -d118="ࠡ" -d119="ࠢ" -d120="ࠣ" -d121="ࠥ" -d122="ࠦ" -d123="ࠧ" -d124="ࠩ" -d125="ࠪ" -d126="ࠫ" -d127="ࠬ" -d128="࠭" -d129="॑" -d130="॓" -d131="॔" -d132="ྂ" -d133="ྃ" -d134="྆" -d135="྇" -d136="፝" -d137="፞" -d138="፟" -d139="៝" -d140="᤺" -d141="ᨗ" -d142="᩵" -d143="᩶" -d144="᩷" -d145="᩸" -d146="᩹" -d147="᩺" -d148="᩻" -d149="᩼" -d150="᭫" -d151="᭭" -d152="᭮" -d153="᭯" -d154="᭰" -d155="᭱" -d156="᭲" -d157="᭳" -d158="᳐" -d159="᳑" -d160="᳒" -d161="᳚" -d162="᳛" -d163="᳠" -d164="᷀" -d165="᷁" -d166="᷃" -d167="᷄" -d168="᷅" -d169="᷆" -d170="᷇" -d171="᷈" -d172="᷉" -d173="᷋" -d174="᷌" -d175="᷑" -d176="᷒" -d177="ᷓ" -d178="ᷔ" -d179="ᷕ" -d180="ᷖ" -d181="ᷗ" -d182="ᷘ" -d183="ᷙ" -d184="ᷚ" -d185="ᷛ" -d186="ᷜ" -d187="ᷝ" -d188="ᷞ" -d189="ᷟ" -d190="ᷠ" -d191="ᷡ" -d192="ᷢ" -d193="ᷣ" -d194="ᷤ" -d195="ᷥ" -d196="ᷦ" -d197="᷾" -d198="⃐" -d199="⃑" -d200="⃔" -d201="⃕" -d202="⃖" -d203="⃗" -d204="⃛" -d205="⃜" -d206="⃡" -d207="⃧" -d208="⃩" -d209="⃰" -d210="⳯" -d211="⳰" -d212="⳱" -d213="ⷠ" -d214="ⷡ" -d215="ⷢ" -d216="ⷣ" -d217="ⷤ" -d218="ⷥ" -d219="ⷦ" -d220="ⷧ" -d221="ⷨ" -d222="ⷩ" -d223="ⷪ" -d224="ⷫ" -d225="ⷬ" -d226="ⷭ" -d227="ⷮ" -d228="ⷯ" -d229="ⷰ" -d230="ⷱ" -d231="ⷲ" -d232="ⷳ" -d233="ⷴ" -d234="ⷵ" -d235="ⷶ" -d236="ⷷ" -d237="ⷸ" -d238="ⷹ" -d239="ⷺ" -d240="ⷻ" -d241="ⷼ" -d242="ⷽ" -d243="ⷾ" -d244="ⷿ" -d245="꙯" -d246="꙼" -d247="꙽" -d248="꛰" -d249="꛱" -d250="꣠" -d251="꣡" -d252="꣢" -d253="꣣" -d254="꣤" -d255="꣥" -d256="꣦" -d257="꣧" -d258="꣨" -d259="꣩" -d260="꣪" -d261="꣫" -d262="꣬" -d263="꣭" -d264="꣮" -d265="꣯" -d266="꣰" -d267="꣱" -d268="ꪰ" -d269="ꪲ" -d270="ꪳ" -d271="ꪷ" -d272="ꪸ" -d273="ꪾ" -d274="꪿" -d275="꫁" -d276="︠" -d277="︡" -d278="︢" -d279="︣" -d280="︤" -d281="︥" -d282="︦" -d283="𐨏" -d284="𐨸" -d285="𝆅" -d286="𝆆" -d287="𝆇" -d288="𝆈" -d289="𝆉" -d290="𝆪" -d291="𝆫" -d292="𝆬" -d293="𝆭" -d294="𝉂" -d295="𝉃" -d296="𝉄" - -num_diacritics="297" - -placeholder="􎻮" - -##################################################################### -# Upload the image and print the placeholder -##################################################################### - -upload_image_and_print_placeholder diff --git a/suckless/st/khash.h b/suckless/st/khash.h deleted file mode 100644 index f75f347..0000000 --- a/suckless/st/khash.h +++ /dev/null @@ -1,627 +0,0 @@ -/* The MIT License - - Copyright (c) 2008, 2009, 2011 by Attractive Chaos - - 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. -*/ - -/* - An example: - -#include "khash.h" -KHASH_MAP_INIT_INT(32, char) -int main() { - int ret, is_missing; - khiter_t k; - khash_t(32) *h = kh_init(32); - k = kh_put(32, h, 5, &ret); - kh_value(h, k) = 10; - k = kh_get(32, h, 10); - is_missing = (k == kh_end(h)); - k = kh_get(32, h, 5); - kh_del(32, h, k); - for (k = kh_begin(h); k != kh_end(h); ++k) - if (kh_exist(h, k)) kh_value(h, k) = 1; - kh_destroy(32, h); - return 0; -} -*/ - -/* - 2013-05-02 (0.2.8): - - * Use quadratic probing. When the capacity is power of 2, stepping function - i*(i+1)/2 guarantees to traverse each bucket. It is better than double - hashing on cache performance and is more robust than linear probing. - - In theory, double hashing should be more robust than quadratic probing. - However, my implementation is probably not for large hash tables, because - the second hash function is closely tied to the first hash function, - which reduce the effectiveness of double hashing. - - Reference: http://research.cs.vt.edu/AVresearch/hashing/quadratic.php - - 2011-12-29 (0.2.7): - - * Minor code clean up; no actual effect. - - 2011-09-16 (0.2.6): - - * The capacity is a power of 2. This seems to dramatically improve the - speed for simple keys. Thank Zilong Tan for the suggestion. Reference: - - - http://code.google.com/p/ulib/ - - http://nothings.org/computer/judy/ - - * Allow to optionally use linear probing which usually has better - performance for random input. Double hashing is still the default as it - is more robust to certain non-random input. - - * Added Wang's integer hash function (not used by default). This hash - function is more robust to certain non-random input. - - 2011-02-14 (0.2.5): - - * Allow to declare global functions. - - 2009-09-26 (0.2.4): - - * Improve portability - - 2008-09-19 (0.2.3): - - * Corrected the example - * Improved interfaces - - 2008-09-11 (0.2.2): - - * Improved speed a little in kh_put() - - 2008-09-10 (0.2.1): - - * Added kh_clear() - * Fixed a compiling error - - 2008-09-02 (0.2.0): - - * Changed to token concatenation which increases flexibility. - - 2008-08-31 (0.1.2): - - * Fixed a bug in kh_get(), which has not been tested previously. - - 2008-08-31 (0.1.1): - - * Added destructor -*/ - - -#ifndef __AC_KHASH_H -#define __AC_KHASH_H - -/*! - @header - - Generic hash table library. - */ - -#define AC_VERSION_KHASH_H "0.2.8" - -#include -#include -#include - -/* compiler specific configuration */ - -#if UINT_MAX == 0xffffffffu -typedef unsigned int khint32_t; -#elif ULONG_MAX == 0xffffffffu -typedef unsigned long khint32_t; -#endif - -#if ULONG_MAX == ULLONG_MAX -typedef unsigned long khint64_t; -#else -typedef unsigned long long khint64_t; -#endif - -#ifndef kh_inline -#ifdef _MSC_VER -#define kh_inline __inline -#else -#define kh_inline inline -#endif -#endif /* kh_inline */ - -#ifndef klib_unused -#if (defined __clang__ && __clang_major__ >= 3) || (defined __GNUC__ && __GNUC__ >= 3) -#define klib_unused __attribute__ ((__unused__)) -#else -#define klib_unused -#endif -#endif /* klib_unused */ - -typedef khint32_t khint_t; -typedef khint_t khiter_t; - -#define __ac_isempty(flag, i) ((flag[i>>4]>>((i&0xfU)<<1))&2) -#define __ac_isdel(flag, i) ((flag[i>>4]>>((i&0xfU)<<1))&1) -#define __ac_iseither(flag, i) ((flag[i>>4]>>((i&0xfU)<<1))&3) -#define __ac_set_isdel_false(flag, i) (flag[i>>4]&=~(1ul<<((i&0xfU)<<1))) -#define __ac_set_isempty_false(flag, i) (flag[i>>4]&=~(2ul<<((i&0xfU)<<1))) -#define __ac_set_isboth_false(flag, i) (flag[i>>4]&=~(3ul<<((i&0xfU)<<1))) -#define __ac_set_isdel_true(flag, i) (flag[i>>4]|=1ul<<((i&0xfU)<<1)) - -#define __ac_fsize(m) ((m) < 16? 1 : (m)>>4) - -#ifndef kroundup32 -#define kroundup32(x) (--(x), (x)|=(x)>>1, (x)|=(x)>>2, (x)|=(x)>>4, (x)|=(x)>>8, (x)|=(x)>>16, ++(x)) -#endif - -#ifndef kcalloc -#define kcalloc(N,Z) calloc(N,Z) -#endif -#ifndef kmalloc -#define kmalloc(Z) malloc(Z) -#endif -#ifndef krealloc -#define krealloc(P,Z) realloc(P,Z) -#endif -#ifndef kfree -#define kfree(P) free(P) -#endif - -static const double __ac_HASH_UPPER = 0.77; - -#define __KHASH_TYPE(name, khkey_t, khval_t) \ - typedef struct kh_##name##_s { \ - khint_t n_buckets, size, n_occupied, upper_bound; \ - khint32_t *flags; \ - khkey_t *keys; \ - khval_t *vals; \ - } kh_##name##_t; - -#define __KHASH_PROTOTYPES(name, khkey_t, khval_t) \ - extern kh_##name##_t *kh_init_##name(void); \ - extern void kh_destroy_##name(kh_##name##_t *h); \ - extern void kh_clear_##name(kh_##name##_t *h); \ - extern khint_t kh_get_##name(const kh_##name##_t *h, khkey_t key); \ - extern int kh_resize_##name(kh_##name##_t *h, khint_t new_n_buckets); \ - extern khint_t kh_put_##name(kh_##name##_t *h, khkey_t key, int *ret); \ - extern void kh_del_##name(kh_##name##_t *h, khint_t x); - -#define __KHASH_IMPL(name, SCOPE, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) \ - SCOPE kh_##name##_t *kh_init_##name(void) { \ - return (kh_##name##_t*)kcalloc(1, sizeof(kh_##name##_t)); \ - } \ - SCOPE void kh_destroy_##name(kh_##name##_t *h) \ - { \ - if (h) { \ - kfree((void *)h->keys); kfree(h->flags); \ - kfree((void *)h->vals); \ - kfree(h); \ - } \ - } \ - SCOPE void kh_clear_##name(kh_##name##_t *h) \ - { \ - if (h && h->flags) { \ - memset(h->flags, 0xaa, __ac_fsize(h->n_buckets) * sizeof(khint32_t)); \ - h->size = h->n_occupied = 0; \ - } \ - } \ - SCOPE khint_t kh_get_##name(const kh_##name##_t *h, khkey_t key) \ - { \ - if (h->n_buckets) { \ - khint_t k, i, last, mask, step = 0; \ - mask = h->n_buckets - 1; \ - k = __hash_func(key); i = k & mask; \ - last = i; \ - while (!__ac_isempty(h->flags, i) && (__ac_isdel(h->flags, i) || !__hash_equal(h->keys[i], key))) { \ - i = (i + (++step)) & mask; \ - if (i == last) return h->n_buckets; \ - } \ - return __ac_iseither(h->flags, i)? h->n_buckets : i; \ - } else return 0; \ - } \ - SCOPE int kh_resize_##name(kh_##name##_t *h, khint_t new_n_buckets) \ - { /* This function uses 0.25*n_buckets bytes of working space instead of [sizeof(key_t+val_t)+.25]*n_buckets. */ \ - khint32_t *new_flags = 0; \ - khint_t j = 1; \ - { \ - kroundup32(new_n_buckets); \ - if (new_n_buckets < 4) new_n_buckets = 4; \ - if (h->size >= (khint_t)(new_n_buckets * __ac_HASH_UPPER + 0.5)) j = 0; /* requested size is too small */ \ - else { /* hash table size to be changed (shrink or expand); rehash */ \ - new_flags = (khint32_t*)kmalloc(__ac_fsize(new_n_buckets) * sizeof(khint32_t)); \ - if (!new_flags) return -1; \ - memset(new_flags, 0xaa, __ac_fsize(new_n_buckets) * sizeof(khint32_t)); \ - if (h->n_buckets < new_n_buckets) { /* expand */ \ - khkey_t *new_keys = (khkey_t*)krealloc((void *)h->keys, new_n_buckets * sizeof(khkey_t)); \ - if (!new_keys) { kfree(new_flags); return -1; } \ - h->keys = new_keys; \ - if (kh_is_map) { \ - khval_t *new_vals = (khval_t*)krealloc((void *)h->vals, new_n_buckets * sizeof(khval_t)); \ - if (!new_vals) { kfree(new_flags); return -1; } \ - h->vals = new_vals; \ - } \ - } /* otherwise shrink */ \ - } \ - } \ - if (j) { /* rehashing is needed */ \ - for (j = 0; j != h->n_buckets; ++j) { \ - if (__ac_iseither(h->flags, j) == 0) { \ - khkey_t key = h->keys[j]; \ - khval_t val; \ - khint_t new_mask; \ - new_mask = new_n_buckets - 1; \ - if (kh_is_map) val = h->vals[j]; \ - __ac_set_isdel_true(h->flags, j); \ - while (1) { /* kick-out process; sort of like in Cuckoo hashing */ \ - khint_t k, i, step = 0; \ - k = __hash_func(key); \ - i = k & new_mask; \ - while (!__ac_isempty(new_flags, i)) i = (i + (++step)) & new_mask; \ - __ac_set_isempty_false(new_flags, i); \ - if (i < h->n_buckets && __ac_iseither(h->flags, i) == 0) { /* kick out the existing element */ \ - { khkey_t tmp = h->keys[i]; h->keys[i] = key; key = tmp; } \ - if (kh_is_map) { khval_t tmp = h->vals[i]; h->vals[i] = val; val = tmp; } \ - __ac_set_isdel_true(h->flags, i); /* mark it as deleted in the old hash table */ \ - } else { /* write the element and jump out of the loop */ \ - h->keys[i] = key; \ - if (kh_is_map) h->vals[i] = val; \ - break; \ - } \ - } \ - } \ - } \ - if (h->n_buckets > new_n_buckets) { /* shrink the hash table */ \ - h->keys = (khkey_t*)krealloc((void *)h->keys, new_n_buckets * sizeof(khkey_t)); \ - if (kh_is_map) h->vals = (khval_t*)krealloc((void *)h->vals, new_n_buckets * sizeof(khval_t)); \ - } \ - kfree(h->flags); /* free the working space */ \ - h->flags = new_flags; \ - h->n_buckets = new_n_buckets; \ - h->n_occupied = h->size; \ - h->upper_bound = (khint_t)(h->n_buckets * __ac_HASH_UPPER + 0.5); \ - } \ - return 0; \ - } \ - SCOPE khint_t kh_put_##name(kh_##name##_t *h, khkey_t key, int *ret) \ - { \ - khint_t x; \ - if (h->n_occupied >= h->upper_bound) { /* update the hash table */ \ - if (h->n_buckets > (h->size<<1)) { \ - if (kh_resize_##name(h, h->n_buckets - 1) < 0) { /* clear "deleted" elements */ \ - *ret = -1; return h->n_buckets; \ - } \ - } else if (kh_resize_##name(h, h->n_buckets + 1) < 0) { /* expand the hash table */ \ - *ret = -1; return h->n_buckets; \ - } \ - } /* TODO: to implement automatically shrinking; resize() already support shrinking */ \ - { \ - khint_t k, i, site, last, mask = h->n_buckets - 1, step = 0; \ - x = site = h->n_buckets; k = __hash_func(key); i = k & mask; \ - if (__ac_isempty(h->flags, i)) x = i; /* for speed up */ \ - else { \ - last = i; \ - while (!__ac_isempty(h->flags, i) && (__ac_isdel(h->flags, i) || !__hash_equal(h->keys[i], key))) { \ - if (__ac_isdel(h->flags, i)) site = i; \ - i = (i + (++step)) & mask; \ - if (i == last) { x = site; break; } \ - } \ - if (x == h->n_buckets) { \ - if (__ac_isempty(h->flags, i) && site != h->n_buckets) x = site; \ - else x = i; \ - } \ - } \ - } \ - if (__ac_isempty(h->flags, x)) { /* not present at all */ \ - h->keys[x] = key; \ - __ac_set_isboth_false(h->flags, x); \ - ++h->size; ++h->n_occupied; \ - *ret = 1; \ - } else if (__ac_isdel(h->flags, x)) { /* deleted */ \ - h->keys[x] = key; \ - __ac_set_isboth_false(h->flags, x); \ - ++h->size; \ - *ret = 2; \ - } else *ret = 0; /* Don't touch h->keys[x] if present and not deleted */ \ - return x; \ - } \ - SCOPE void kh_del_##name(kh_##name##_t *h, khint_t x) \ - { \ - if (x != h->n_buckets && !__ac_iseither(h->flags, x)) { \ - __ac_set_isdel_true(h->flags, x); \ - --h->size; \ - } \ - } - -#define KHASH_DECLARE(name, khkey_t, khval_t) \ - __KHASH_TYPE(name, khkey_t, khval_t) \ - __KHASH_PROTOTYPES(name, khkey_t, khval_t) - -#define KHASH_INIT2(name, SCOPE, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) \ - __KHASH_TYPE(name, khkey_t, khval_t) \ - __KHASH_IMPL(name, SCOPE, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) - -#define KHASH_INIT(name, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) \ - KHASH_INIT2(name, static kh_inline klib_unused, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) - -/* --- BEGIN OF HASH FUNCTIONS --- */ - -/*! @function - @abstract Integer hash function - @param key The integer [khint32_t] - @return The hash value [khint_t] - */ -#define kh_int_hash_func(key) (khint32_t)(key) -/*! @function - @abstract Integer comparison function - */ -#define kh_int_hash_equal(a, b) ((a) == (b)) -/*! @function - @abstract 64-bit integer hash function - @param key The integer [khint64_t] - @return The hash value [khint_t] - */ -#define kh_int64_hash_func(key) (khint32_t)((key)>>33^(key)^(key)<<11) -/*! @function - @abstract 64-bit integer comparison function - */ -#define kh_int64_hash_equal(a, b) ((a) == (b)) -/*! @function - @abstract const char* hash function - @param s Pointer to a null terminated string - @return The hash value - */ -static kh_inline khint_t __ac_X31_hash_string(const char *s) -{ - khint_t h = (khint_t)*s; - if (h) for (++s ; *s; ++s) h = (h << 5) - h + (khint_t)*s; - return h; -} -/*! @function - @abstract Another interface to const char* hash function - @param key Pointer to a null terminated string [const char*] - @return The hash value [khint_t] - */ -#define kh_str_hash_func(key) __ac_X31_hash_string(key) -/*! @function - @abstract Const char* comparison function - */ -#define kh_str_hash_equal(a, b) (strcmp(a, b) == 0) - -static kh_inline khint_t __ac_Wang_hash(khint_t key) -{ - key += ~(key << 15); - key ^= (key >> 10); - key += (key << 3); - key ^= (key >> 6); - key += ~(key << 11); - key ^= (key >> 16); - return key; -} -#define kh_int_hash_func2(key) __ac_Wang_hash((khint_t)key) - -/* --- END OF HASH FUNCTIONS --- */ - -/* Other convenient macros... */ - -/*! - @abstract Type of the hash table. - @param name Name of the hash table [symbol] - */ -#define khash_t(name) kh_##name##_t - -/*! @function - @abstract Initiate a hash table. - @param name Name of the hash table [symbol] - @return Pointer to the hash table [khash_t(name)*] - */ -#define kh_init(name) kh_init_##name() - -/*! @function - @abstract Destroy a hash table. - @param name Name of the hash table [symbol] - @param h Pointer to the hash table [khash_t(name)*] - */ -#define kh_destroy(name, h) kh_destroy_##name(h) - -/*! @function - @abstract Reset a hash table without deallocating memory. - @param name Name of the hash table [symbol] - @param h Pointer to the hash table [khash_t(name)*] - */ -#define kh_clear(name, h) kh_clear_##name(h) - -/*! @function - @abstract Resize a hash table. - @param name Name of the hash table [symbol] - @param h Pointer to the hash table [khash_t(name)*] - @param s New size [khint_t] - */ -#define kh_resize(name, h, s) kh_resize_##name(h, s) - -/*! @function - @abstract Insert a key to the hash table. - @param name Name of the hash table [symbol] - @param h Pointer to the hash table [khash_t(name)*] - @param k Key [type of keys] - @param r Extra return code: -1 if the operation failed; - 0 if the key is present in the hash table; - 1 if the bucket is empty (never used); 2 if the element in - the bucket has been deleted [int*] - @return Iterator to the inserted element [khint_t] - */ -#define kh_put(name, h, k, r) kh_put_##name(h, k, r) - -/*! @function - @abstract Retrieve a key from the hash table. - @param name Name of the hash table [symbol] - @param h Pointer to the hash table [khash_t(name)*] - @param k Key [type of keys] - @return Iterator to the found element, or kh_end(h) if the element is absent [khint_t] - */ -#define kh_get(name, h, k) kh_get_##name(h, k) - -/*! @function - @abstract Remove a key from the hash table. - @param name Name of the hash table [symbol] - @param h Pointer to the hash table [khash_t(name)*] - @param k Iterator to the element to be deleted [khint_t] - */ -#define kh_del(name, h, k) kh_del_##name(h, k) - -/*! @function - @abstract Test whether a bucket contains data. - @param h Pointer to the hash table [khash_t(name)*] - @param x Iterator to the bucket [khint_t] - @return 1 if containing data; 0 otherwise [int] - */ -#define kh_exist(h, x) (!__ac_iseither((h)->flags, (x))) - -/*! @function - @abstract Get key given an iterator - @param h Pointer to the hash table [khash_t(name)*] - @param x Iterator to the bucket [khint_t] - @return Key [type of keys] - */ -#define kh_key(h, x) ((h)->keys[x]) - -/*! @function - @abstract Get value given an iterator - @param h Pointer to the hash table [khash_t(name)*] - @param x Iterator to the bucket [khint_t] - @return Value [type of values] - @discussion For hash sets, calling this results in segfault. - */ -#define kh_val(h, x) ((h)->vals[x]) - -/*! @function - @abstract Alias of kh_val() - */ -#define kh_value(h, x) ((h)->vals[x]) - -/*! @function - @abstract Get the start iterator - @param h Pointer to the hash table [khash_t(name)*] - @return The start iterator [khint_t] - */ -#define kh_begin(h) (khint_t)(0) - -/*! @function - @abstract Get the end iterator - @param h Pointer to the hash table [khash_t(name)*] - @return The end iterator [khint_t] - */ -#define kh_end(h) ((h)->n_buckets) - -/*! @function - @abstract Get the number of elements in the hash table - @param h Pointer to the hash table [khash_t(name)*] - @return Number of elements in the hash table [khint_t] - */ -#define kh_size(h) ((h)->size) - -/*! @function - @abstract Get the number of buckets in the hash table - @param h Pointer to the hash table [khash_t(name)*] - @return Number of buckets in the hash table [khint_t] - */ -#define kh_n_buckets(h) ((h)->n_buckets) - -/*! @function - @abstract Iterate over the entries in the hash table - @param h Pointer to the hash table [khash_t(name)*] - @param kvar Variable to which key will be assigned - @param vvar Variable to which value will be assigned - @param code Block of code to execute - */ -#define kh_foreach(h, kvar, vvar, code) { khint_t __i; \ - for (__i = kh_begin(h); __i != kh_end(h); ++__i) { \ - if (!kh_exist(h,__i)) continue; \ - (kvar) = kh_key(h,__i); \ - (vvar) = kh_val(h,__i); \ - code; \ - } } - -/*! @function - @abstract Iterate over the values in the hash table - @param h Pointer to the hash table [khash_t(name)*] - @param vvar Variable to which value will be assigned - @param code Block of code to execute - */ -#define kh_foreach_value(h, vvar, code) { khint_t __i; \ - for (__i = kh_begin(h); __i != kh_end(h); ++__i) { \ - if (!kh_exist(h,__i)) continue; \ - (vvar) = kh_val(h,__i); \ - code; \ - } } - -/* More convenient interfaces */ - -/*! @function - @abstract Instantiate a hash set containing integer keys - @param name Name of the hash table [symbol] - */ -#define KHASH_SET_INIT_INT(name) \ - KHASH_INIT(name, khint32_t, char, 0, kh_int_hash_func, kh_int_hash_equal) - -/*! @function - @abstract Instantiate a hash map containing integer keys - @param name Name of the hash table [symbol] - @param khval_t Type of values [type] - */ -#define KHASH_MAP_INIT_INT(name, khval_t) \ - KHASH_INIT(name, khint32_t, khval_t, 1, kh_int_hash_func, kh_int_hash_equal) - -/*! @function - @abstract Instantiate a hash set containing 64-bit integer keys - @param name Name of the hash table [symbol] - */ -#define KHASH_SET_INIT_INT64(name) \ - KHASH_INIT(name, khint64_t, char, 0, kh_int64_hash_func, kh_int64_hash_equal) - -/*! @function - @abstract Instantiate a hash map containing 64-bit integer keys - @param name Name of the hash table [symbol] - @param khval_t Type of values [type] - */ -#define KHASH_MAP_INIT_INT64(name, khval_t) \ - KHASH_INIT(name, khint64_t, khval_t, 1, kh_int64_hash_func, kh_int64_hash_equal) - -typedef const char *kh_cstr_t; -/*! @function - @abstract Instantiate a hash map containing const char* keys - @param name Name of the hash table [symbol] - */ -#define KHASH_SET_INIT_STR(name) \ - KHASH_INIT(name, kh_cstr_t, char, 0, kh_str_hash_func, kh_str_hash_equal) - -/*! @function - @abstract Instantiate a hash map containing const char* keys - @param name Name of the hash table [symbol] - @param khval_t Type of values [type] - */ -#define KHASH_MAP_INIT_STR(name, khval_t) \ - KHASH_INIT(name, kh_cstr_t, khval_t, 1, kh_str_hash_func, kh_str_hash_equal) - -#endif /* __AC_KHASH_H */ diff --git a/suckless/st/kvec.h b/suckless/st/kvec.h deleted file mode 100644 index 10f1c5b..0000000 --- a/suckless/st/kvec.h +++ /dev/null @@ -1,90 +0,0 @@ -/* The MIT License - - Copyright (c) 2008, by Attractive Chaos - - 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. -*/ - -/* - An example: - -#include "kvec.h" -int main() { - kvec_t(int) array; - kv_init(array); - kv_push(int, array, 10); // append - kv_a(int, array, 20) = 5; // dynamic - kv_A(array, 20) = 4; // static - kv_destroy(array); - return 0; -} -*/ - -/* - 2008-09-22 (0.1.0): - - * The initial version. - -*/ - -#ifndef AC_KVEC_H -#define AC_KVEC_H - -#include - -#define kv_roundup32(x) (--(x), (x)|=(x)>>1, (x)|=(x)>>2, (x)|=(x)>>4, (x)|=(x)>>8, (x)|=(x)>>16, ++(x)) - -#define kvec_t(type) struct { size_t n, m; type *a; } -#define kv_init(v) ((v).n = (v).m = 0, (v).a = 0) -#define kv_destroy(v) free((v).a) -#define kv_A(v, i) ((v).a[(i)]) -#define kv_pop(v) ((v).a[--(v).n]) -#define kv_size(v) ((v).n) -#define kv_max(v) ((v).m) - -#define kv_resize(type, v, s) ((v).m = (s), (v).a = (type*)realloc((v).a, sizeof(type) * (v).m)) - -#define kv_copy(type, v1, v0) do { \ - if ((v1).m < (v0).n) kv_resize(type, v1, (v0).n); \ - (v1).n = (v0).n; \ - memcpy((v1).a, (v0).a, sizeof(type) * (v0).n); \ - } while (0) \ - -#define kv_push(type, v, x) do { \ - if ((v).n == (v).m) { \ - (v).m = (v).m? (v).m<<1 : 2; \ - (v).a = (type*)realloc((v).a, sizeof(type) * (v).m); \ - } \ - (v).a[(v).n++] = (x); \ - } while (0) - -#define kv_pushp(type, v) ((((v).n == (v).m)? \ - ((v).m = ((v).m? (v).m<<1 : 2), \ - (v).a = (type*)realloc((v).a, sizeof(type) * (v).m), 0) \ - : 0), ((v).a + ((v).n++))) - -#define kv_a(type, v, i) (((v).m <= (size_t)(i)? \ - ((v).m = (v).n = (i) + 1, kv_roundup32((v).m), \ - (v).a = (type*)realloc((v).a, sizeof(type) * (v).m), 0) \ - : (v).n <= (size_t)(i)? (v).n = (i) + 1 \ - : 0), (v).a[(i)]) - -#endif diff --git a/suckless/st/rowcolumn_diacritics_helpers.c b/suckless/st/rowcolumn_diacritics_helpers.c deleted file mode 100644 index 829c0fc..0000000 --- a/suckless/st/rowcolumn_diacritics_helpers.c +++ /dev/null @@ -1,391 +0,0 @@ -#include - -uint16_t diacritic_to_num(uint32_t code) -{ - switch (code) { - case 0x305: - return code - 0x305 + 1; - case 0x30d: - case 0x30e: - return code - 0x30d + 2; - case 0x310: - return code - 0x310 + 4; - case 0x312: - return code - 0x312 + 5; - case 0x33d: - case 0x33e: - case 0x33f: - return code - 0x33d + 6; - case 0x346: - return code - 0x346 + 9; - case 0x34a: - case 0x34b: - case 0x34c: - return code - 0x34a + 10; - case 0x350: - case 0x351: - case 0x352: - return code - 0x350 + 13; - case 0x357: - return code - 0x357 + 16; - case 0x35b: - return code - 0x35b + 17; - case 0x363: - case 0x364: - case 0x365: - case 0x366: - case 0x367: - case 0x368: - case 0x369: - case 0x36a: - case 0x36b: - case 0x36c: - case 0x36d: - case 0x36e: - case 0x36f: - return code - 0x363 + 18; - case 0x483: - case 0x484: - case 0x485: - case 0x486: - case 0x487: - return code - 0x483 + 31; - case 0x592: - case 0x593: - case 0x594: - case 0x595: - return code - 0x592 + 36; - case 0x597: - case 0x598: - case 0x599: - return code - 0x597 + 40; - case 0x59c: - case 0x59d: - case 0x59e: - case 0x59f: - case 0x5a0: - case 0x5a1: - return code - 0x59c + 43; - case 0x5a8: - case 0x5a9: - return code - 0x5a8 + 49; - case 0x5ab: - case 0x5ac: - return code - 0x5ab + 51; - case 0x5af: - return code - 0x5af + 53; - case 0x5c4: - return code - 0x5c4 + 54; - case 0x610: - case 0x611: - case 0x612: - case 0x613: - case 0x614: - case 0x615: - case 0x616: - case 0x617: - return code - 0x610 + 55; - case 0x657: - case 0x658: - case 0x659: - case 0x65a: - case 0x65b: - return code - 0x657 + 63; - case 0x65d: - case 0x65e: - return code - 0x65d + 68; - case 0x6d6: - case 0x6d7: - case 0x6d8: - case 0x6d9: - case 0x6da: - case 0x6db: - case 0x6dc: - return code - 0x6d6 + 70; - case 0x6df: - case 0x6e0: - case 0x6e1: - case 0x6e2: - return code - 0x6df + 77; - case 0x6e4: - return code - 0x6e4 + 81; - case 0x6e7: - case 0x6e8: - return code - 0x6e7 + 82; - case 0x6eb: - case 0x6ec: - return code - 0x6eb + 84; - case 0x730: - return code - 0x730 + 86; - case 0x732: - case 0x733: - return code - 0x732 + 87; - case 0x735: - case 0x736: - return code - 0x735 + 89; - case 0x73a: - return code - 0x73a + 91; - case 0x73d: - return code - 0x73d + 92; - case 0x73f: - case 0x740: - case 0x741: - return code - 0x73f + 93; - case 0x743: - return code - 0x743 + 96; - case 0x745: - return code - 0x745 + 97; - case 0x747: - return code - 0x747 + 98; - case 0x749: - case 0x74a: - return code - 0x749 + 99; - case 0x7eb: - case 0x7ec: - case 0x7ed: - case 0x7ee: - case 0x7ef: - case 0x7f0: - case 0x7f1: - return code - 0x7eb + 101; - case 0x7f3: - return code - 0x7f3 + 108; - case 0x816: - case 0x817: - case 0x818: - case 0x819: - return code - 0x816 + 109; - case 0x81b: - case 0x81c: - case 0x81d: - case 0x81e: - case 0x81f: - case 0x820: - case 0x821: - case 0x822: - case 0x823: - return code - 0x81b + 113; - case 0x825: - case 0x826: - case 0x827: - return code - 0x825 + 122; - case 0x829: - case 0x82a: - case 0x82b: - case 0x82c: - case 0x82d: - return code - 0x829 + 125; - case 0x951: - return code - 0x951 + 130; - case 0x953: - case 0x954: - return code - 0x953 + 131; - case 0xf82: - case 0xf83: - return code - 0xf82 + 133; - case 0xf86: - case 0xf87: - return code - 0xf86 + 135; - case 0x135d: - case 0x135e: - case 0x135f: - return code - 0x135d + 137; - case 0x17dd: - return code - 0x17dd + 140; - case 0x193a: - return code - 0x193a + 141; - case 0x1a17: - return code - 0x1a17 + 142; - case 0x1a75: - case 0x1a76: - case 0x1a77: - case 0x1a78: - case 0x1a79: - case 0x1a7a: - case 0x1a7b: - case 0x1a7c: - return code - 0x1a75 + 143; - case 0x1b6b: - return code - 0x1b6b + 151; - case 0x1b6d: - case 0x1b6e: - case 0x1b6f: - case 0x1b70: - case 0x1b71: - case 0x1b72: - case 0x1b73: - return code - 0x1b6d + 152; - case 0x1cd0: - case 0x1cd1: - case 0x1cd2: - return code - 0x1cd0 + 159; - case 0x1cda: - case 0x1cdb: - return code - 0x1cda + 162; - case 0x1ce0: - return code - 0x1ce0 + 164; - case 0x1dc0: - case 0x1dc1: - return code - 0x1dc0 + 165; - case 0x1dc3: - case 0x1dc4: - case 0x1dc5: - case 0x1dc6: - case 0x1dc7: - case 0x1dc8: - case 0x1dc9: - return code - 0x1dc3 + 167; - case 0x1dcb: - case 0x1dcc: - return code - 0x1dcb + 174; - case 0x1dd1: - case 0x1dd2: - case 0x1dd3: - case 0x1dd4: - case 0x1dd5: - case 0x1dd6: - case 0x1dd7: - case 0x1dd8: - case 0x1dd9: - case 0x1dda: - case 0x1ddb: - case 0x1ddc: - case 0x1ddd: - case 0x1dde: - case 0x1ddf: - case 0x1de0: - case 0x1de1: - case 0x1de2: - case 0x1de3: - case 0x1de4: - case 0x1de5: - case 0x1de6: - return code - 0x1dd1 + 176; - case 0x1dfe: - return code - 0x1dfe + 198; - case 0x20d0: - case 0x20d1: - return code - 0x20d0 + 199; - case 0x20d4: - case 0x20d5: - case 0x20d6: - case 0x20d7: - return code - 0x20d4 + 201; - case 0x20db: - case 0x20dc: - return code - 0x20db + 205; - case 0x20e1: - return code - 0x20e1 + 207; - case 0x20e7: - return code - 0x20e7 + 208; - case 0x20e9: - return code - 0x20e9 + 209; - case 0x20f0: - return code - 0x20f0 + 210; - case 0x2cef: - case 0x2cf0: - case 0x2cf1: - return code - 0x2cef + 211; - case 0x2de0: - case 0x2de1: - case 0x2de2: - case 0x2de3: - case 0x2de4: - case 0x2de5: - case 0x2de6: - case 0x2de7: - case 0x2de8: - case 0x2de9: - case 0x2dea: - case 0x2deb: - case 0x2dec: - case 0x2ded: - case 0x2dee: - case 0x2def: - case 0x2df0: - case 0x2df1: - case 0x2df2: - case 0x2df3: - case 0x2df4: - case 0x2df5: - case 0x2df6: - case 0x2df7: - case 0x2df8: - case 0x2df9: - case 0x2dfa: - case 0x2dfb: - case 0x2dfc: - case 0x2dfd: - case 0x2dfe: - case 0x2dff: - return code - 0x2de0 + 214; - case 0xa66f: - return code - 0xa66f + 246; - case 0xa67c: - case 0xa67d: - return code - 0xa67c + 247; - case 0xa6f0: - case 0xa6f1: - return code - 0xa6f0 + 249; - case 0xa8e0: - case 0xa8e1: - case 0xa8e2: - case 0xa8e3: - case 0xa8e4: - case 0xa8e5: - case 0xa8e6: - case 0xa8e7: - case 0xa8e8: - case 0xa8e9: - case 0xa8ea: - case 0xa8eb: - case 0xa8ec: - case 0xa8ed: - case 0xa8ee: - case 0xa8ef: - case 0xa8f0: - case 0xa8f1: - return code - 0xa8e0 + 251; - case 0xaab0: - return code - 0xaab0 + 269; - case 0xaab2: - case 0xaab3: - return code - 0xaab2 + 270; - case 0xaab7: - case 0xaab8: - return code - 0xaab7 + 272; - case 0xaabe: - case 0xaabf: - return code - 0xaabe + 274; - case 0xaac1: - return code - 0xaac1 + 276; - case 0xfe20: - case 0xfe21: - case 0xfe22: - case 0xfe23: - case 0xfe24: - case 0xfe25: - case 0xfe26: - return code - 0xfe20 + 277; - case 0x10a0f: - return code - 0x10a0f + 284; - case 0x10a38: - return code - 0x10a38 + 285; - case 0x1d185: - case 0x1d186: - case 0x1d187: - case 0x1d188: - case 0x1d189: - return code - 0x1d185 + 286; - case 0x1d1aa: - case 0x1d1ab: - case 0x1d1ac: - case 0x1d1ad: - return code - 0x1d1aa + 291; - case 0x1d242: - case 0x1d243: - case 0x1d244: - return code - 0x1d242 + 295; - } - return 0; -} diff --git a/suckless/st/st b/suckless/st/st deleted file mode 100755 index a80dd985cbbea0f505eab8cb3f49ffb6478b898d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 120544 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 == -1.0f && alpha >= 0.1f) -+ alpha -= 0.1f; -+ else if (arg->f == 1.0f && alpha < 1.0f) -+ alpha += 0.1f; -+ else if (arg->f == 0.0f) -+ alpha = alpha_def; -+ else -+ return; -+ -+ dc.col[defaultbg].color.alpha = (unsigned short)(0xFFFF * alpha); -+ /* Required to remove artifacting from borderpx */ -+ cresize(0, 0); -+ redraw(); -+} -+ - void - xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, int y) - { -@@ -2038,6 +2077,9 @@ main(int argc, char *argv[]) - case 'a': - allowaltscreen = 0; - break; -+ case 'A': -+ opt_alpha = EARGF(usage()); -+ break; - case 'c': - opt_class = EARGF(usage()); - break; diff --git a/suckless/st/st.1 b/suckless/st/st.1 deleted file mode 100644 index ef8c956..0000000 --- a/suckless/st/st.1 +++ /dev/null @@ -1,177 +0,0 @@ -.TH ST 1 st\-VERSION -.SH NAME -st \- simple terminal (bread's build) -.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 [=][{xX}][{+-}{+-}]. 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/suckless/st/st.c b/suckless/st/st.c deleted file mode 100644 index 367a3bb..0000000 --- a/suckless/st/st.c +++ /dev/null @@ -1,2799 +0,0 @@ -/* See LICENSE for license details. */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "st.h" -#include "win.h" - -#if defined(__linux) - #include -#elif defined(__OpenBSD__) || defined(__NetBSD__) || defined(__APPLE__) - #include -#elif defined(__FreeBSD__) || defined(__DragonFly__) - #include -#endif - -/* Arbitrary sizes */ -#define UTF_INVALID 0xFFFD -#define UTF_SIZ 4 -#define ESC_BUF_SIZ (128*UTF_SIZ) -#define ESC_ARG_SIZ 16 -#define STR_BUF_SIZ ESC_BUF_SIZ -#define STR_ARG_SIZ ESC_ARG_SIZ - -/* macros */ -#define IS_SET(flag) ((term.mode & (flag)) != 0) -#define ISCONTROLC0(c) (BETWEEN(c, 0, 0x1f) || (c) == 0x7f) -#define ISCONTROLC1(c) (BETWEEN(c, 0x80, 0x9f)) -#define ISCONTROL(c) (ISCONTROLC0(c) || ISCONTROLC1(c)) -#define ISDELIM(u) (u && wcschr(worddelimiters, u)) - -#define TSCREEN term.screen[IS_SET(MODE_ALTSCREEN)] -#define TLINEOFFSET(y) (((y) + TSCREEN.cur - TSCREEN.off + TSCREEN.size) % TSCREEN.size) -#define TLINE(y) (TSCREEN.buffer[TLINEOFFSET(y)]) - -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; - -/* Screen lines */ -typedef struct { - Line* buffer; /* ring buffer */ - int size; /* size of buffer */ - int cur; /* start of active screen */ - int off; /* scrollback line offset */ - TCursor sc; /* saved cursor */ -} LineBuffer; - -/* Internal representation of the screen */ -typedef struct { - int row; /* nb row */ - int col; /* nb col */ - LineBuffer screen[2]; /* screen and alternate screen */ - int linelen; /* allocated line length */ - 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 '[' [[ [] [;]] []] */ -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 [[ [] [;]] ] 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 void osc_color_response(int, int, int); -static int eschandle(uchar); -static void strdump(void); -static void strhandle(void); -static void strparse(void); -static void strreset(void); - -static void tprinter(char *, size_t); -static void tdumpsel(void); -static void tdumpline(int); -static void tdump(void); -static void tclearregion(int, int, int, int); -static void tcursor(int); -static void tdeletechar(int); -static void tdeleteline(int); -static void tinsertblank(int); -static void tinsertblankline(int); -static int tlinelen(int); -static void tmoveto(int, int); -static void tmoveato(int, int); -static void tnewline(int); -static void tputtab(int); -static void tputc(Rune); -static void treset(void); -static void tscrollup(int, int); -static void tscrolldown(int, int); -static void tsetattr(const int *, int); -static void tsetchar(Rune, const Glyph *, int, int); -static void tsetdirt(int, int); -static void tsetscroll(int, int); -static void tswapscreen(void); -static void tsetmode(int, int, const int *, int); -static int twrite(const char *, int, int); -static void tfulldirt(void); -static void tcontrolcode(uchar ); -static void tdectest(char ); -static void tdefutf8(char); -static int32_t tdefcolor(const int *, int *, int); -static void tdeftran(char); -static void tstrsequence(uchar); - -static void drawregion(int, int, int, int); -static void clearline(Line, Glyph, int, int); -static Line ensureline(Line); - -static void selnormalize(void); -static void selscroll(int, int); -static void selsnap(int *, int *, int); - -static size_t utf8decode(const char *, Rune *, size_t); -static Rune utf8decodebyte(char, size_t *); -static char utf8encodebyte(Rune, size_t); -static size_t utf8validate(Rune *, size_t); - -static char *base64dec(const char *); -static char base64dec_getc(const char **); - -static ssize_t xwrite(int, const char *, size_t); - -/* Globals */ -static Term term; -static Selection sel; -static CSIEscape csiescseq; -static STREscape strescseq; -static int iofd = 1; -static int cmdfd; -static pid_t pid; - -static const uchar utfbyte[UTF_SIZ + 1] = {0x80, 0, 0xC0, 0xE0, 0xF0}; -static const uchar utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8}; -static const Rune utfmin[UTF_SIZ + 1] = { 0, 0, 0x80, 0x800, 0x10000}; -static const Rune utfmax[UTF_SIZ + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF}; - -ssize_t -xwrite(int fd, const char *s, size_t len) -{ - size_t aux = len; - ssize_t r; - - while (len > 0) { - r = write(fd, s, len); - if (r < 0) - return r; - len -= r; - s += r; - } - - return aux; -} - -void * -xmalloc(size_t len) -{ - void *p; - - if (!(p = malloc(len))) - die("malloc: %s\n", strerror(errno)); - - return p; -} - -void * -xrealloc(void *p, size_t len) -{ - if ((p = realloc(p, len)) == NULL) - die("realloc: %s\n", strerror(errno)); - - return p; -} - -char * -xstrdup(const char *s) -{ - char *p; - - if ((p = strdup(s)) == NULL) - die("strdup: %s\n", strerror(errno)); - - return p; -} - -size_t -utf8decode(const char *c, Rune *u, size_t clen) -{ - size_t i, j, len, type; - Rune udecoded; - - *u = UTF_INVALID; - if (!clen) - return 0; - udecoded = utf8decodebyte(c[0], &len); - if (!BETWEEN(len, 1, UTF_SIZ)) - return 1; - for (i = 1, j = 1; i < clen && j < len; ++i, ++j) { - udecoded = (udecoded << 6) | utf8decodebyte(c[i], &type); - if (type != 0) - return j; - } - if (j < len) - return 0; - *u = udecoded; - utf8validate(u, len); - - return len; -} - -Rune -utf8decodebyte(char c, size_t *i) -{ - for (*i = 0; *i < LEN(utfmask); ++(*i)) - if (((uchar)c & utfmask[*i]) == utfbyte[*i]) - return (uchar)c & ~utfmask[*i]; - - return 0; -} - -size_t -utf8encode(Rune u, char *c) -{ - size_t len, i; - - len = utf8validate(&u, 0); - if (len > UTF_SIZ) - return 0; - - for (i = len - 1; i != 0; --i) { - c[i] = utf8encodebyte(u, 0); - u >>= 6; - } - c[0] = utf8encodebyte(u, len); - - return len; -} - -char -utf8encodebyte(Rune u, size_t i) -{ - return utfbyte[i] | (u & ~utfmask[i]); -} - -size_t -utf8validate(Rune *u, size_t i) -{ - if (!BETWEEN(*u, utfmin[i], utfmax[i]) || BETWEEN(*u, 0xD800, 0xDFFF)) - *u = UTF_INVALID; - for (i = 1; *u > utfmax[i]; ++i) - ; - - return i; -} - -char -base64dec_getc(const char **src) -{ - while (**src && !isprint((unsigned char)**src)) - (*src)++; - return **src ? *((*src)++) : '='; /* emulate padding if string ends */ -} - -char * -base64dec(const char *src) -{ - size_t in_len = strlen(src); - char *result, *dst; - static const char base64_digits[256] = { - [43] = 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 - }; - - 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; - Line line = TLINE(y); - - if (line[i - 1].mode & ATTR_WRAP) - return i; - - while (i > 0 && line[i - 1].u == ' ') - --i; - - return i; -} - -void -selstart(int col, int row, int snap) -{ - selclear(); - sel.mode = SEL_EMPTY; - sel.type = SEL_REGULAR; - sel.alt = IS_SET(MODE_ALTSCREEN); - sel.snap = snap; - sel.oe.x = sel.ob.x = col; - sel.oe.y = sel.ob.y = row; - selnormalize(); - - if (sel.snap != 0) - sel.mode = SEL_READY; - tsetdirt(sel.nb.y, sel.ne.y); -} - -void -selextend(int col, int row, int type, int done) -{ - int oldey, oldex, oldsby, oldsey, oldtype; - - if (sel.mode == SEL_IDLE) - return; - if (done && sel.mode == SEL_EMPTY) { - selclear(); - return; - } - - oldey = sel.oe.y; - oldex = sel.oe.x; - oldsby = sel.nb.y; - oldsey = sel.ne.y; - oldtype = sel.type; - - sel.oe.x = col; - sel.oe.y = row; - selnormalize(); - sel.type = type; - - if (oldey != sel.oe.y || oldex != sel.oe.x || oldtype != sel.type || sel.mode == SEL_EMPTY) - tsetdirt(MIN(sel.nb.y, oldsby), MAX(sel.ne.y, oldsey)); - - sel.mode = done ? SEL_IDLE : SEL_READY; -} - -void -selnormalize(void) -{ - int i; - - if (sel.type == SEL_REGULAR && sel.ob.y != sel.oe.y) { - sel.nb.x = sel.ob.y < sel.oe.y ? sel.ob.x : sel.oe.x; - sel.ne.x = sel.ob.y < sel.oe.y ? sel.oe.x : sel.ob.x; - } else { - sel.nb.x = MIN(sel.ob.x, sel.oe.x); - sel.ne.x = MAX(sel.ob.x, sel.oe.x); - } - sel.nb.y = MIN(sel.ob.y, sel.oe.y); - sel.ne.y = MAX(sel.ob.y, sel.oe.y); - - selsnap(&sel.nb.x, &sel.nb.y, -1); - selsnap(&sel.ne.x, &sel.ne.y, +1); - - /* expand selection over line breaks */ - if (sel.type == SEL_RECTANGULAR) - return; - i = tlinelen(sel.nb.y); - if (i < sel.nb.x) - sel.nb.x = i; - if (tlinelen(sel.ne.y) <= sel.ne.x) - sel.ne.x = term.col - 1; -} - -int -selected(int x, int y) -{ - if (sel.mode == SEL_EMPTY || sel.ob.x == -1 || - sel.alt != IS_SET(MODE_ALTSCREEN)) - return 0; - - if (sel.type == SEL_RECTANGULAR) - return BETWEEN(y, sel.nb.y, sel.ne.y) - && BETWEEN(x, sel.nb.x, sel.ne.x); - - return BETWEEN(y, sel.nb.y, sel.ne.y) - && (y != sel.nb.y || x >= sel.nb.x) - && (y != sel.ne.y || x <= sel.ne.x); -} - -void -selsnap(int *x, int *y, int direction) -{ - int newx, newy, xt, yt; - int delim, prevdelim; - const Glyph *gp, *prevgp; - - switch (sel.snap) { - case SNAP_WORD: - /* - * Snap around if the word wraps around at the end or - * beginning of a line. - */ - prevgp = &TLINE(*y)[*x]; - prevdelim = ISDELIM(prevgp->u); - for (;;) { - newx = *x + direction; - newy = *y; - if (!BETWEEN(newx, 0, term.col - 1)) { - newy += direction; - newx = (newx + term.col) % term.col; - if (!BETWEEN(newy, 0, term.row - 1)) - break; - - if (direction > 0) - yt = *y, xt = *x; - else - yt = newy, xt = newx; - if (!(TLINE(yt)[xt].mode & ATTR_WRAP)) - break; - } - - if (newx >= tlinelen(newy)) - break; - - gp = &TLINE(newy)[newx]; - delim = ISDELIM(gp->u); - if (!(gp->mode & ATTR_WDUMMY) && (delim != prevdelim - || (delim && gp->u != prevgp->u))) - break; - - *x = newx; - *y = newy; - prevgp = gp; - prevdelim = delim; - } - break; - case SNAP_LINE: - /* - * Snap around if the the previous line or the current one - * has set ATTR_WRAP at its end. Then the whole next or - * previous line will be selected. - */ - *x = (direction < 0) ? 0 : term.col - 1; - if (direction < 0) { - for (; *y > 0; *y += direction) { - if (!(TLINE(*y-1)[term.col-1].mode - & ATTR_WRAP)) { - break; - } - } - } else if (direction > 0) { - for (; *y < term.row-1; *y += direction) { - if (!(TLINE(*y)[term.col-1].mode - & ATTR_WRAP)) { - break; - } - } - } - break; - } -} - -char * -getsel(void) -{ - char *str, *ptr; - int y, bufsize, lastx, linelen; - const Glyph *gp, *last; - - if (sel.ob.x == -1) - return NULL; - - bufsize = (term.col+1) * (sel.ne.y-sel.nb.y+1) * UTF_SIZ; - ptr = str = xmalloc(bufsize); - - /* append every set & selected glyph to the selection */ - for (y = sel.nb.y; y <= sel.ne.y; y++) { - if ((linelen = tlinelen(y)) == 0) { - *ptr++ = '\n'; - continue; - } - - if (sel.type == SEL_RECTANGULAR) { - gp = &TLINE(y)[sel.nb.x]; - lastx = sel.ne.x; - } else { - gp = &TLINE(y)[sel.nb.y == y ? sel.nb.x : 0]; - lastx = (sel.ne.y == y) ? sel.ne.x : term.col-1; - } - last = &TLINE(y)[MIN(lastx, linelen-1)]; - while (last >= gp && last->u == ' ') - --last; - - for ( ; gp <= last; ++gp) { - if (gp->mode & ATTR_WDUMMY) - continue; - - ptr += utf8encode(gp->u, ptr); - } - - /* - * Copy and pasting of line endings is inconsistent - * in the inconsistent terminal and GUI world. - * The best solution seems like to produce '\n' when - * something is copied from st and convert '\n' to - * '\r', when something to be pasted is received by - * st. - * FIXME: Fix the computer world. - */ - if ((y < sel.ne.y || lastx >= linelen) && - (!(last->mode & ATTR_WRAP) || sel.type == SEL_RECTANGULAR)) - *ptr++ = '\n'; - } - *ptr = 0; - return str; -} - -void -selclear(void) -{ - if (sel.ob.x == -1) - return; - sel.mode = SEL_IDLE; - sel.ob.x = -1; - tsetdirt(sel.nb.y, sel.ne.y); -} - -void -die(const char *errstr, ...) -{ - va_list ap; - - va_start(ap, errstr); - vfprintf(stderr, errstr, ap); - va_end(ap); - exit(1); -} - -void -execsh(char *cmd, char **args) -{ - char *sh, *prog, *arg; - const struct passwd *pw; - - errno = 0; - if ((pw = getpwuid(getuid())) == NULL) { - if (errno) - die("getpwuid: %s\n", strerror(errno)); - else - die("who are you?\n"); - } - - if ((sh = getenv("SHELL")) == NULL) - sh = (pw->pw_shell[0]) ? pw->pw_shell : cmd; - - if (args) { - prog = args[0]; - arg = NULL; - } else if (scroll) { - prog = scroll; - arg = utmp ? utmp : sh; - } else if (utmp) { - prog = utmp; - arg = NULL; - } else { - prog = sh; - arg = NULL; - } - DEFAULT(args, ((char *[]) {prog, arg, NULL})); - - unsetenv("COLUMNS"); - unsetenv("LINES"); - unsetenv("TERMCAP"); - setenv("LOGNAME", pw->pw_name, 1); - setenv("USER", pw->pw_name, 1); - setenv("SHELL", sh, 1); - setenv("HOME", pw->pw_dir, 1); - setenv("TERM", termname, 1); - - signal(SIGCHLD, SIG_DFL); - signal(SIGHUP, SIG_DFL); - signal(SIGINT, SIG_DFL); - signal(SIGQUIT, SIG_DFL); - signal(SIGTERM, SIG_DFL); - signal(SIGALRM, SIG_DFL); - - execvp(prog, args); - _exit(1); -} - -void -sigchld(int a) -{ - int stat; - pid_t p; - - if ((p = waitpid(pid, &stat, WNOHANG)) < 0) - die("waiting for pid %hd failed: %s\n", pid, strerror(errno)); - - if (pid != p) - return; - - if (WIFEXITED(stat) && WEXITSTATUS(stat)) - die("child exited with status %d\n", WEXITSTATUS(stat)); - else if (WIFSIGNALED(stat)) - die("child terminated due to signal %d\n", WTERMSIG(stat)); - _exit(0); -} - -void -stty(char **args) -{ - char cmd[_POSIX_ARG_MAX], **p, *q, *s; - size_t n, siz; - - if ((n = strlen(stty_args)) > sizeof(cmd)-1) - die("incorrect stty parameters\n"); - memcpy(cmd, stty_args, n); - q = cmd + n; - siz = sizeof(cmd) - n; - for (p = args; p && (s = *p); ++p) { - if ((n = strlen(s)) > siz-1) - die("stty parameter length too long\n"); - *q++ = ' '; - memcpy(q, s, n); - q += n; - siz -= n + 1; - } - *q = '\0'; - if (system(cmd) != 0) - perror("Couldn't call stty"); -} - -int -ttynew(const char *line, char *cmd, const char *out, char **args) -{ - int m, s; - - if (out) { - term.mode |= MODE_PRINT; - iofd = (!strcmp(out, "-")) ? - 1 : open(out, O_WRONLY | O_CREAT, 0666); - if (iofd < 0) { - fprintf(stderr, "Error opening %s:%s\n", - out, strerror(errno)); - } - } - - if (line) { - if ((cmdfd = open(line, O_RDWR)) < 0) - die("open line '%s' failed: %s\n", - line, strerror(errno)); - dup2(cmdfd, 0); - stty(args); - return cmdfd; - } - - /* seems to work fine on linux, openbsd and freebsd */ - if (openpty(&m, &s, NULL, NULL, NULL) < 0) - die("openpty failed: %s\n", strerror(errno)); - - switch (pid = fork()) { - case -1: - die("fork failed: %s\n", strerror(errno)); - break; - case 0: - close(iofd); - close(m); - setsid(); /* create a new process group */ - dup2(s, 0); - dup2(s, 1); - dup2(s, 2); - if (ioctl(s, TIOCSCTTY, NULL) < 0) - die("ioctl TIOCSCTTY failed: %s\n", strerror(errno)); - if (s > 2) - close(s); -#ifdef __OpenBSD__ - if (pledge("stdio getpw proc exec", NULL) == -1) - die("pledge\n"); -#endif - execsh(cmd, args); - break; - default: -#ifdef __OpenBSD__ - if (pledge("stdio rpath tty proc", NULL) == -1) - die("pledge\n"); -#endif - close(s); - cmdfd = m; - signal(SIGCHLD, sigchld); - break; - } - return cmdfd; -} - -size_t -ttyread(void) -{ - static char buf[BUFSIZ]; - static int buflen = 0; - int ret, written; - - /* append read bytes to unprocessed bytes */ - ret = read(cmdfd, buf+buflen, LEN(buf)-buflen); - - switch (ret) { - case 0: - exit(0); - case -1: - die("couldn't read from shell: %s\n", strerror(errno)); - default: - buflen += ret; - written = twrite(buf, buflen, 0); - buflen -= written; - /* keep any incomplete UTF-8 byte sequence for the next call */ - if (buflen > 0) - memmove(buf, buf + written, buflen); - return ret; - } -} - -void -ttywrite(const char *s, size_t n, int may_echo) -{ - const char *next; - - 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(void) -{ - /* Send SIGHUP to shell */ - kill(pid, SIGHUP); -} - -int -tattrset(int attr) -{ - int i, j; - int y = TLINEOFFSET(0); - - for (i = 0; i < term.row-1; i++) { - Line line = TSCREEN.buffer[y]; - for (j = 0; j < term.col-1; j++) { - if (line[j].mode & attr) - return 1; - } - y = (y+1) % TSCREEN.size; - } - - 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; - int y = TLINEOFFSET(0); - - for (i = 0; i < term.row-1; i++) { - Line line = TSCREEN.buffer[y]; - for (j = 0; j < term.col-1; j++) { - if (line[j].mode & attr) { - tsetdirt(i, i); - break; - } - } - y = (y+1) % TSCREEN.size; - } -} - -void -tfulldirt(void) -{ - tsetdirt(0, term.row-1); -} - -void -tcursor(int mode) -{ - if (mode == CURSOR_SAVE) { - TSCREEN.sc = term.c; - } else if (mode == CURSOR_LOAD) { - term.c = TSCREEN.sc; - tmoveto(term.c.x, term.c.y); - } -} - -void -treset(void) -{ - int i, j; - Glyph g = (Glyph){ .fg = defaultfg, .bg = defaultbg}; - - 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++) { - term.screen[i].sc = (TCursor){{ - .fg = defaultfg, - .bg = defaultbg - }}; - term.screen[i].cur = 0; - term.screen[i].off = 0; - for (j = 0; j < term.row; ++j) { - if (term.col != term.linelen) - term.screen[i].buffer[j] = xrealloc(term.screen[i].buffer[j], term.col * sizeof(Glyph)); - clearline(term.screen[i].buffer[j], g, 0, term.col); - } - for (j = term.row; j < term.screen[i].size; ++j) { - free(term.screen[i].buffer[j]); - term.screen[i].buffer[j] = NULL; - } - } - tcursor(CURSOR_LOAD); - term.linelen = term.col; - tfulldirt(); -} - -void -tnew(int col, int row) -{ - int i; - term = (Term){0}; - term.screen[0].buffer = xmalloc(HISTSIZE * sizeof(Line)); - term.screen[0].size = HISTSIZE; - term.screen[1].buffer = NULL; - for (i = 0; i < HISTSIZE; ++i) term.screen[0].buffer[i] = NULL; - - tresize(col, row); - treset(); -} - -void -tswapscreen(void) -{ - term.mode ^= MODE_ALTSCREEN; - tfulldirt(); -} - -void -kscrollup(const Arg *a) -{ - int n = a->i; - - if (IS_SET(MODE_ALTSCREEN)) - return; - - if (n < 0) n = (-n) * term.row; - if (n > TSCREEN.size - term.row - TSCREEN.off) n = TSCREEN.size - term.row - TSCREEN.off; - while (!TLINE(-n)) --n; - TSCREEN.off += n; - selscroll(0, n); - tfulldirt(); -} - -void -kscrolldown(const Arg *a) -{ - - int n = a->i; - - if (IS_SET(MODE_ALTSCREEN)) - return; - - if (n < 0) n = (-n) * term.row; - if (n > TSCREEN.off) n = TSCREEN.off; - TSCREEN.off -= n; - selscroll(0, -n); - tfulldirt(); -} - -void -tscrolldown(int orig, int n) -{ - int i; - Line temp; - - LIMIT(n, 0, term.bot-orig+1); - - /* Ensure that lines are allocated */ - for (i = -n; i < 0; i++) { - TLINE(i) = ensureline(TLINE(i)); - } - - /* Shift non-scrolling areas in ring buffer */ - for (i = term.bot+1; i < term.row; i++) { - temp = TLINE(i); - TLINE(i) = TLINE(i-n); - TLINE(i-n) = temp; - } - for (i = 0; i < orig; i++) { - temp = TLINE(i); - TLINE(i) = TLINE(i-n); - TLINE(i-n) = temp; - } - - /* Scroll buffer */ - TSCREEN.cur = (TSCREEN.cur + TSCREEN.size - n) % TSCREEN.size; - /* Clear lines that have entered the view */ - tclearregion(0, orig, term.linelen-1, orig+n-1); - /* Redraw portion of the screen that has scrolled */ - tsetdirt(orig+n-1, term.bot); - selscroll(orig, n); -} - -void -tscrollup(int orig, int n) -{ - int i; - Line temp; - - LIMIT(n, 0, term.bot-orig+1); - - /* Ensure that lines are allocated */ - for (i = term.row; i < term.row + n; i++) { - TLINE(i) = ensureline(TLINE(i)); - } - - /* Shift non-scrolling areas in ring buffer */ - for (i = orig-1; i >= 0; i--) { - temp = TLINE(i); - TLINE(i) = TLINE(i+n); - TLINE(i+n) = temp; - } - for (i = term.row-1; i >term.bot; i--) { - temp = TLINE(i); - TLINE(i) = TLINE(i+n); - TLINE(i+n) = temp; - } - - /* Scroll buffer */ - TSCREEN.cur = (TSCREEN.cur + n) % TSCREEN.size; - /* Clear lines that have entered the view */ - tclearregion(0, term.bot-n+1, term.linelen-1, term.bot); - /* Redraw portion of the screen that has scrolled */ - tsetdirt(orig, term.bot-n+1); - selscroll(orig, -n); -} - -void -selscroll(int orig, int n) -{ - if (sel.ob.x == -1 || sel.alt != IS_SET(MODE_ALTSCREEN)) - return; - - if (BETWEEN(sel.nb.y, orig, term.bot) != BETWEEN(sel.ne.y, orig, term.bot)) { - selclear(); - } else if (BETWEEN(sel.nb.y, orig, term.bot)) { - sel.ob.y += n; - sel.oe.y += n; - if (sel.ob.y < term.top || sel.ob.y > term.bot || - sel.oe.y < term.top || sel.oe.y > term.bot) { - selclear(); - } else { - selnormalize(); - } - } -} - -void -tnewline(int first_col) -{ - int y = term.c.y; - - if (y == term.bot) { - tscrollup(term.top, 1); - } else { - y++; - } - tmoveto(first_col ? 0 : term.c.x, y); -} - -void -csiparse(void) -{ - char *p = csiescseq.buf, *np; - long int v; - int sep = ';'; /* colon or semi-colon, but not both */ - - 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 (sep == ';' && *p == ':') - sep = ':'; /* allow override to colon once */ - if (*p != sep || csiescseq.narg == ESC_ARG_SIZ) - break; - p++; - } - csiescseq.mode[0] = *p++; - csiescseq.mode[1] = (p < csiescseq.buf+csiescseq.len) ? *p : '\0'; -} - -/* for absolute user moves, when decom is set */ -void -tmoveato(int x, int y) -{ - tmoveto(x, y + ((term.c.state & CURSOR_ORIGIN) ? term.top: 0)); -} - -void -tmoveto(int x, int y) -{ - int miny, maxy; - - if (term.c.state & CURSOR_ORIGIN) { - miny = term.top; - maxy = term.bot; - } else { - miny = 0; - maxy = term.row - 1; - } - term.c.state &= ~CURSOR_WRAPNEXT; - term.c.x = LIMIT(x, 0, term.col-1); - term.c.y = LIMIT(y, miny, maxy); -} - -void -tsetchar(Rune u, const Glyph *attr, int x, int y) -{ - static const char *vt100_0[62] = { /* 0x41 - 0x7e */ - "↑", "↓", "→", "←", "█", "▚", "☃", /* A - G */ - 0, 0, 0, 0, 0, 0, 0, 0, /* H - O */ - 0, 0, 0, 0, 0, 0, 0, 0, /* P - W */ - 0, 0, 0, 0, 0, 0, 0, " ", /* X - _ */ - "◆", "▒", "␉", "␌", "␍", "␊", "°", "±", /* ` - g */ - "␤", "␋", "┘", "┐", "┌", "└", "┼", "⎺", /* h - o */ - "⎻", "─", "⎼", "⎽", "├", "┤", "┴", "┬", /* p - w */ - "│", "≤", "≥", "π", "≠", "£", "·", /* x - ~ */ - }; - Line line = TLINE(y); - - /* - * 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 (line[x].mode & ATTR_WIDE) { - if (x+1 < term.col) { - line[x+1].u = ' '; - line[x+1].mode &= ~ATTR_WDUMMY; - } - } else if (line[x].mode & ATTR_WDUMMY) { - line[x-1].u = ' '; - line[x-1].mode &= ~ATTR_WIDE; - } - - term.dirty[y] = 1; - line[x] = *attr; - line[x].u = u; -} - -void -tclearregion(int x1, int y1, int x2, int y2) -{ - int x, y, L, S, 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.linelen-1); - LIMIT(x2, 0, term.linelen-1); - LIMIT(y1, 0, term.row-1); - LIMIT(y2, 0, term.row-1); - - L = TLINEOFFSET(y1); - for (y = y1; y <= y2; y++) { - term.dirty[y] = 1; - for (x = x1; x <= x2; x++) { - gp = &TSCREEN.buffer[L][x]; - if (selected(x, y)) - selclear(); - gp->fg = term.c.attr.fg; - gp->bg = term.c.attr.bg; - gp->mode = 0; - gp->u = ' '; - } - L = (L + 1) % TSCREEN.size; - } -} - -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 = TLINE(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 = TLINE(term.c.y); - - memmove(&line[dst], &line[src], size * sizeof(Glyph)); - tclearregion(src, term.c.y, dst - 1, term.c.y); -} - -void -tinsertblankline(int n) -{ - if (BETWEEN(term.c.y, term.top, term.bot)) - tscrolldown(term.c.y, n); -} - -void -tdeleteline(int n) -{ - if (BETWEEN(term.c.y, term.top, term.bot)) - tscrollup(term.c.y, n); -} - -int32_t -tdefcolor(const int *attr, int *npar, int l) -{ - int32_t idx = -1; - uint r, g, b; - - switch (attr[*npar + 1]) { - case 2: /* direct color in RGB space */ - if (*npar + 4 >= l) { - fprintf(stderr, - "erresc(38): Incorrect number of parameters (%d)\n", - *npar); - break; - } - r = attr[*npar + 2]; - g = attr[*npar + 3]; - b = attr[*npar + 4]; - *npar += 4; - if (!BETWEEN(r, 0, 255) || !BETWEEN(g, 0, 255) || !BETWEEN(b, 0, 255)) - fprintf(stderr, "erresc: bad rgb color (%u,%u,%u)\n", - r, g, b); - else - idx = TRUECOLOR(r, g, b); - break; - case 5: /* indexed color */ - if (*npar + 2 >= l) { - fprintf(stderr, - "erresc(38): Incorrect number of parameters (%d)\n", - *npar); - break; - } - *npar += 2; - if (!BETWEEN(attr[*npar], 0, 255)) - fprintf(stderr, "erresc: bad fgcolor %d\n", attr[*npar]); - else - idx = attr[*npar]; - break; - case 0: /* implemented defined (only foreground) */ - case 1: /* transparent */ - case 3: /* direct color in CMY space */ - case 4: /* direct color in CMYK space */ - default: - fprintf(stderr, - "erresc(38): gfx attr %d unknown\n", attr[*npar]); - break; - } - - return idx; -} - -void -tsetattr(const int *attr, int l) -{ - int i; - int32_t idx; - - for (i = 0; i < l; i++) { - switch (attr[i]) { - case 0: - term.c.attr.mode &= ~( - ATTR_BOLD | - ATTR_FAINT | - ATTR_ITALIC | - ATTR_UNDERLINE | - ATTR_BLINK | - ATTR_REVERSE | - ATTR_INVISIBLE | - ATTR_STRUCK ); - term.c.attr.fg = defaultfg; - term.c.attr.bg = defaultbg; - break; - case 1: - term.c.attr.mode |= ATTR_BOLD; - break; - case 2: - term.c.attr.mode |= ATTR_FAINT; - break; - case 3: - term.c.attr.mode |= ATTR_ITALIC; - break; - case 4: - term.c.attr.mode |= ATTR_UNDERLINE; - break; - case 5: /* slow blink */ - /* FALLTHROUGH */ - case 6: /* rapid blink */ - term.c.attr.mode |= ATTR_BLINK; - break; - case 7: - term.c.attr.mode |= ATTR_REVERSE; - break; - case 8: - term.c.attr.mode |= ATTR_INVISIBLE; - break; - case 9: - term.c.attr.mode |= ATTR_STRUCK; - break; - case 22: - term.c.attr.mode &= ~(ATTR_BOLD | ATTR_FAINT); - break; - case 23: - term.c.attr.mode &= ~ATTR_ITALIC; - break; - case 24: - term.c.attr.mode &= ~ATTR_UNDERLINE; - break; - case 25: - term.c.attr.mode &= ~ATTR_BLINK; - break; - case 27: - term.c.attr.mode &= ~ATTR_REVERSE; - break; - case 28: - term.c.attr.mode &= ~ATTR_INVISIBLE; - break; - case 29: - term.c.attr.mode &= ~ATTR_STRUCK; - break; - case 38: - if ((idx = tdefcolor(attr, &i, l)) >= 0) - term.c.attr.fg = idx; - break; - case 39: - term.c.attr.fg = defaultfg; - break; - case 48: - if ((idx = tdefcolor(attr, &i, l)) >= 0) - term.c.attr.bg = idx; - break; - case 49: - term.c.attr.bg = defaultbg; - break; - default: - if (BETWEEN(attr[i], 30, 37)) { - term.c.attr.fg = attr[i] - 30; - } else if (BETWEEN(attr[i], 40, 47)) { - term.c.attr.bg = attr[i] - 40; - } else if (BETWEEN(attr[i], 90, 97)) { - term.c.attr.fg = attr[i] - 90 + 8; - } else if (BETWEEN(attr[i], 100, 107)) { - term.c.attr.bg = attr[i] - 100 + 8; - } else { - fprintf(stderr, - "erresc(default): gfx attr %d unknown\n", - attr[i]); - csidump(); - } - break; - } - } -} - -void -tsetscroll(int t, int b) -{ - int temp; - - LIMIT(t, 0, term.row-1); - LIMIT(b, 0, term.row-1); - if (t > b) { - temp = t; - t = b; - b = temp; - } - term.top = t; - term.bot = b; -} - -void -tsetmode(int priv, int set, const int *args, int narg) -{ - int alt; const int *lim; - - for (lim = args + narg; args < lim; ++args) { - if (priv) { - switch (*args) { - case 1: /* DECCKM -- Cursor key */ - xsetmode(set, MODE_APPCURSOR); - break; - case 5: /* DECSCNM -- Reverse video */ - xsetmode(set, MODE_REVERSE); - break; - case 6: /* DECOM -- Origin */ - MODBIT(term.c.state, set, CURSOR_ORIGIN); - tmoveato(0, 0); - break; - case 7: /* DECAWM -- Auto wrap */ - MODBIT(term.mode, set, MODE_WRAP); - break; - case 0: /* Error (IGNORED) */ - case 2: /* DECANM -- ANSI/VT52 (IGNORED) */ - case 3: /* DECCOLM -- Column (IGNORED) */ - case 4: /* DECSCLM -- Scroll (IGNORED) */ - case 8: /* DECARM -- Auto repeat (IGNORED) */ - case 18: /* DECPFF -- Printer feed (IGNORED) */ - case 19: /* DECPEX -- Printer extent (IGNORED) */ - case 42: /* DECNRCM -- National characters (IGNORED) */ - case 12: /* att610 -- Start blinking cursor (IGNORED) */ - break; - case 25: /* DECTCEM -- Text Cursor Enable Mode */ - xsetmode(!set, MODE_HIDE); - break; - case 9: /* X10 mouse compatibility mode */ - xsetpointermotion(0); - xsetmode(0, MODE_MOUSE); - xsetmode(set, MODE_MOUSEX10); - break; - case 1000: /* 1000: report button press */ - xsetpointermotion(0); - xsetmode(0, MODE_MOUSE); - xsetmode(set, MODE_MOUSEBTN); - break; - case 1002: /* 1002: report motion on button press */ - xsetpointermotion(0); - xsetmode(0, MODE_MOUSE); - xsetmode(set, MODE_MOUSEMOTION); - break; - case 1003: /* 1003: enable all mouse motions */ - xsetpointermotion(set); - xsetmode(0, MODE_MOUSE); - xsetmode(set, MODE_MOUSEMANY); - break; - case 1004: /* 1004: send focus events to tty */ - xsetmode(set, MODE_FOCUS); - break; - case 1006: /* 1006: extended reporting mode */ - xsetmode(set, MODE_MOUSESGR); - break; - case 1034: - xsetmode(set, MODE_8BIT); - break; - case 1049: /* swap screen & set/restore cursor as xterm */ - if (!allowaltscreen) - break; - tcursor((set) ? CURSOR_SAVE : CURSOR_LOAD); - /* FALLTHROUGH */ - case 47: /* swap screen */ - case 1047: - if (!allowaltscreen) - break; - alt = IS_SET(MODE_ALTSCREEN); - if (alt) { - tclearregion(0, 0, term.col-1, - term.row-1); - } - if (set ^ alt) /* set is always 1 or 0 */ - tswapscreen(); - if (*args != 1049) - break; - /* FALLTHROUGH */ - case 1048: - tcursor((set) ? CURSOR_SAVE : CURSOR_LOAD); - break; - case 2004: /* 2004: bracketed paste mode */ - xsetmode(set, MODE_BRCKTPASTE); - break; - /* Not implemented mouse modes. See comments there. */ - case 1001: /* mouse highlight mode; can hang the - terminal by design when implemented. */ - case 1005: /* UTF-8 mouse mode; will confuse - applications not supporting UTF-8 - and luit. */ - case 1015: /* urxvt mangled mouse mode; incompatible - and can be mistaken for other control - codes. */ - break; - default: - fprintf(stderr, - "erresc: unknown private set/reset mode %d\n", - *args); - break; - } - } else { - switch (*args) { - case 0: /* Error (IGNORED) */ - break; - case 2: - xsetmode(set, MODE_KBDLOCK); - break; - case 4: /* IRM -- Insertion-replacement */ - MODBIT(term.mode, set, MODE_INSERT); - break; - case 12: /* SRM -- Send/Receive */ - MODBIT(term.mode, !set, MODE_ECHO); - break; - case 20: /* LNM -- Linefeed/new line */ - MODBIT(term.mode, set, MODE_CRLF); - break; - default: - fprintf(stderr, - "erresc: unknown set/reset mode %d\n", - *args); - break; - } - } - } -} - -void -csihandle(void) -{ - char buf[40]; - int len; - - switch (csiescseq.mode[0]) { - default: - unknown: - fprintf(stderr, "erresc: unknown csi "); - csidump(); - /* die(""); */ - break; - case '@': /* ICH -- Insert blank char */ - DEFAULT(csiescseq.arg[0], 1); - tinsertblank(csiescseq.arg[0]); - break; - case 'A': /* CUU -- Cursor Up */ - DEFAULT(csiescseq.arg[0], 1); - tmoveto(term.c.x, term.c.y-csiescseq.arg[0]); - break; - case 'B': /* CUD -- Cursor Down */ - case 'e': /* VPR --Cursor 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 more times */ - LIMIT(csiescseq.arg[0], 1, 65535); - if (term.lastc) - while (csiescseq.arg[0]-- > 0) - tputc(term.lastc); - break; - case 'C': /* CUF -- Cursor Forward */ - case 'a': /* HPR -- Cursor Forward */ - DEFAULT(csiescseq.arg[0], 1); - tmoveto(term.c.x+csiescseq.arg[0], term.c.y); - break; - case 'D': /* CUB -- Cursor Backward */ - DEFAULT(csiescseq.arg[0], 1); - tmoveto(term.c.x-csiescseq.arg[0], term.c.y); - break; - case 'E': /* CNL -- Cursor Down and first col */ - DEFAULT(csiescseq.arg[0], 1); - tmoveto(0, term.c.y+csiescseq.arg[0]); - break; - case 'F': /* CPL -- Cursor 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 */ - case '`': /* HPA */ - DEFAULT(csiescseq.arg[0], 1); - tmoveto(csiescseq.arg[0]-1, term.c.y); - break; - case 'H': /* CUP -- Move to */ - 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 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 line up */ - if (csiescseq.priv) break; - DEFAULT(csiescseq.arg[0], 1); - tscrollup(term.top, csiescseq.arg[0]); - break; - case 'T': /* SD -- Scroll line down */ - DEFAULT(csiescseq.arg[0], 1); - tscrolldown(term.top, csiescseq.arg[0]); - break; - case 'L': /* IL -- Insert 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 lines */ - DEFAULT(csiescseq.arg[0], 1); - tdeleteline(csiescseq.arg[0]); - break; - case 'X': /* ECH -- Erase 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 char */ - DEFAULT(csiescseq.arg[0], 1); - tdeletechar(csiescseq.arg[0]); - break; - case 'Z': /* CBT -- Cursor Backward Tabulation tab stops */ - DEFAULT(csiescseq.arg[0], 1); - tputtab(-csiescseq.arg[0]); - break; - case 'd': /* VPA -- Move to */ - 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 */ - switch (csiescseq.arg[0]) { - case 5: /* Status Report "OK" `0n` */ - ttywrite("\033[0n", sizeof("\033[0n") - 1, 0); - break; - case 6: /* Report Cursor Position (CPR) ";R" */ - len = snprintf(buf, sizeof(buf), "\033[%i;%iR", - term.c.y+1, term.c.x+1); - ttywrite(buf, len, 0); - break; - default: - goto unknown; - } - 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 -osc_color_response(int num, int index, int is_osc4) -{ - int n; - char buf[32]; - unsigned char r, g, b; - - if (xgetcolor(is_osc4 ? num : index, &r, &g, &b)) { - fprintf(stderr, "erresc: failed to fetch %s color %d\n", - is_osc4 ? "osc4" : "osc", - is_osc4 ? num : index); - return; - } - - n = snprintf(buf, sizeof buf, "\033]%s%d;rgb:%02x%02x/%02x%02x/%02x%02x\007", - is_osc4 ? "4;" : "", num, r, r, g, g, b, b); - if (n < 0 || n >= sizeof(buf)) { - fprintf(stderr, "error: %s while printing %s response\n", - n < 0 ? "snprintf failed" : "truncation occurred", - is_osc4 ? "osc4" : "osc"); - } else { - ttywrite(buf, n, 1); - } -} - -void -strhandle(void) -{ - char *p = NULL, *dec; - int j, narg, par; - const struct { int idx; char *str; } osc_table[] = { - { defaultfg, "foreground" }, - { defaultbg, "background" }, - { defaultcs, "cursor" } - }; - - term.esc &= ~(ESC_STR_END|ESC_STR); - strparse(); - par = (narg = strescseq.narg) ? atoi(strescseq.args[0]) : 0; - - switch (strescseq.type) { - case ']': /* OSC -- Operating System Command */ - switch (par) { - case 0: - if (narg > 1) { - xsettitle(strescseq.args[1]); - xseticontitle(strescseq.args[1]); - } - return; - case 1: - if (narg > 1) - xseticontitle(strescseq.args[1]); - return; - case 2: - if (narg > 1) - xsettitle(strescseq.args[1]); - return; - case 52: - if (narg > 2 && allowwindowops) { - dec = base64dec(strescseq.args[2]); - if (dec) { - xsetsel(dec); - xclipcopy(); - } else { - fprintf(stderr, "erresc: invalid base64\n"); - } - } - return; - case 10: - case 11: - case 12: - if (narg < 2) - break; - p = strescseq.args[1]; - if ((j = par - 10) < 0 || j >= LEN(osc_table)) - break; /* shouldn't be possible */ - - if (!strcmp(p, "?")) { - osc_color_response(par, osc_table[j].idx, 0); - } else if (xsetcolorname(osc_table[j].idx, p)) { - fprintf(stderr, "erresc: invalid %s color: %s\n", - osc_table[j].str, p); - } else { - tfulldirt(); - } - return; - case 4: /* color set */ - if (narg < 3) - break; - p = strescseq.args[2]; - /* FALLTHROUGH */ - case 104: /* color reset */ - j = (narg > 1) ? atoi(strescseq.args[1]) : -1; - - if (p && !strcmp(p, "?")) { - osc_color_response(j, 0, 1); - } else if (xsetcolorname(j, p)) { - if (par == 104 && narg <= 1) { - xloadcols(); - 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 - */ - tfulldirt(); - } - return; - } - break; - case 'k': /* old title set compatibility */ - xsettitle(strescseq.args[0]); - return; - case 'P': /* DCS -- Device Control String */ - case '_': /* APC -- Application Program Command */ - case '^': /* PM -- Privacy Message */ - return; - } - - fprintf(stderr, "erresc: unknown str "); - strdump(); -} - -void -strparse(void) -{ - int c; - char *p = strescseq.buf; - - strescseq.narg = 0; - strescseq.buf[strescseq.len] = '\0'; - - if (*p == '\0') - return; - - while (strescseq.narg < STR_ARG_SIZ) { - strescseq.args[strescseq.narg++] = p; - while ((c = *p) != ';' && c != '\0') - ++p; - if (c == '\0') - return; - *p++ = '\0'; - } -} - -void -strdump(void) -{ - size_t i; - uint c; - - fprintf(stderr, "ESC%c", strescseq.type); - for (i = 0; i < strescseq.len; i++) { - c = strescseq.buf[i] & 0xff; - if (c == '\0') { - putc('\n', stderr); - return; - } else if (isprint(c)) { - putc(c, stderr); - } else if (c == '\n') { - fprintf(stderr, "(\\n)"); - } else if (c == '\r') { - fprintf(stderr, "(\\r)"); - } else if (c == 0x1b) { - fprintf(stderr, "(\\e)"); - } else { - fprintf(stderr, "(%02x)", c); - } - } - fprintf(stderr, "ESC\\\n"); -} - -void -strreset(void) -{ - strescseq = (STREscape){ - .buf = xrealloc(strescseq.buf, STR_BUF_SIZ), - .siz = STR_BUF_SIZ, - }; -} - -void -sendbreak(const Arg *arg) -{ - if (tcsendbreak(cmdfd, 0)) - perror("Error sending break"); -} - -void -tprinter(char *s, size_t len) -{ - if (iofd != -1 && xwrite(iofd, s, len) < 0) { - perror("Error writing to output file"); - close(iofd); - iofd = -1; - } -} - -void -toggleprinter(const Arg *arg) -{ - term.mode ^= MODE_PRINT; -} - -void -printscreen(const Arg *arg) -{ - tdump(); -} - -void -printsel(const Arg *arg) -{ - tdumpsel(); -} - -void -tdumpsel(void) -{ - char *ptr; - - if ((ptr = getsel())) { - tprinter(ptr, strlen(ptr)); - free(ptr); - } -} - -void -tdumpline(int n) -{ - char buf[UTF_SIZ]; - const Glyph *bp, *end; - - bp = &TLINE(n)[0]; - end = &bp[MIN(tlinelen(n), term.col) - 1]; - if (bp != end || bp->u != ' ') { - for ( ; bp <= end; ++bp) - tprinter(buf, utf8encode(bp->u, buf)); - } - tprinter("\n", 1); -} - -void -tdump(void) -{ - int i; - - for (i = 0; i < term.row; ++i) - tdumpline(i); -} - -void -tputtab(int n) -{ - uint x = term.c.x; - - if (n > 0) { - while (x < term.col && n--) - for (++x; x < term.col && !term.tabs[x]; ++x) - /* nothing */ ; - } else if (n < 0) { - while (x > 0 && n++) - for (--x; x > 0 && !term.tabs[x]; --x) - /* nothing */ ; - } - term.c.x = LIMIT(x, 0, term.col-1); -} - -void -tdefutf8(char ascii) -{ - if (ascii == 'G') - term.mode |= MODE_UTF8; - else if (ascii == '@') - term.mode &= ~MODE_UTF8; -} - -void -tdeftran(char ascii) -{ - static char cs[] = "0B"; - static int vcs[] = {CS_GRAPHIC0, CS_USA}; - char *p; - - if ((p = strchr(cs, ascii)) == NULL) { - fprintf(stderr, "esc unhandled charset: ESC ( %c\n", ascii); - } else { - term.trantbl[term.icharset] = vcs[p - cs]; - } -} - -void -tdectest(char c) -{ - int x, y; - - if (c == '8') { /* DEC screen alignment test. */ - for (x = 0; x < term.col; ++x) { - for (y = 0; y < term.row; ++y) - tsetchar('E', &term.c.attr, x, y); - } - } -} - -void -tstrsequence(uchar c) -{ - switch (c) { - case 0x90: /* DCS -- Device Control String */ - c = 'P'; - break; - case 0x9f: /* APC -- Application Program Command */ - c = '_'; - break; - case 0x9e: /* PM -- Privacy Message */ - c = '^'; - break; - case 0x9d: /* OSC -- Operating System Command */ - c = ']'; - break; - } - strreset(); - strescseq.type = c; - term.esc |= ESC_STR; -} - -void -tcontrolcode(uchar ascii) -{ - switch (ascii) { - case '\t': /* HT */ - tputtab(1); - return; - case '\b': /* BS */ - tmoveto(term.c.x-1, term.c.y); - return; - case '\r': /* CR */ - tmoveto(0, term.c.y); - return; - case '\f': /* LF */ - case '\v': /* VT */ - case '\n': /* LF */ - /* go to first col if the mode is set */ - tnewline(IS_SET(MODE_CRLF)); - return; - case '\a': /* BEL */ - if (term.esc & ESC_STR_END) { - /* backwards compatibility to xterm */ - strhandle(); - } else { - xbell(); - } - break; - case '\033': /* ESC */ - csireset(); - term.esc &= ~(ESC_CSI|ESC_ALTCHARSET|ESC_TEST); - term.esc |= ESC_START; - return; - case '\016': /* SO (LS1 -- Locking shift 1) */ - case '\017': /* SI (LS0 -- Locking shift 0) */ - term.charset = 1 - (ascii - '\016'); - return; - case '\032': /* SUB */ - tsetchar('?', &term.c.attr, term.c.x, term.c.y); - /* FALLTHROUGH */ - case '\030': /* CAN */ - csireset(); - break; - case '\005': /* ENQ (IGNORED) */ - case '\000': /* NUL (IGNORED) */ - case '\021': /* XON (IGNORED) */ - case '\023': /* XOFF (IGNORED) */ - case 0177: /* DEL (IGNORED) */ - return; - case 0x80: /* TODO: PAD */ - case 0x81: /* TODO: HOP */ - case 0x82: /* TODO: BPH */ - case 0x83: /* TODO: NBH */ - case 0x84: /* TODO: IND */ - break; - case 0x85: /* NEL -- Next line */ - tnewline(1); /* always go to first col */ - break; - case 0x86: /* TODO: SSA */ - case 0x87: /* TODO: ESA */ - break; - case 0x88: /* HTS -- Horizontal tab stop */ - term.tabs[term.c.x] = 1; - break; - case 0x89: /* TODO: HTJ */ - case 0x8a: /* TODO: VTS */ - case 0x8b: /* TODO: PLD */ - case 0x8c: /* TODO: PLU */ - case 0x8d: /* TODO: RI */ - case 0x8e: /* TODO: SS2 */ - case 0x8f: /* TODO: SS3 */ - case 0x91: /* TODO: PU1 */ - case 0x92: /* TODO: PU2 */ - case 0x93: /* TODO: STS */ - case 0x94: /* TODO: CCH */ - case 0x95: /* TODO: MW */ - case 0x96: /* TODO: SPA */ - case 0x97: /* TODO: EPA */ - case 0x98: /* TODO: SOS */ - case 0x99: /* TODO: SGCI */ - break; - case 0x9a: /* DECID -- Identify Terminal */ - ttywrite(vtiden, strlen(vtiden), 0); - break; - case 0x9b: /* TODO: CSI */ - case 0x9c: /* TODO: ST */ - break; - case 0x90: /* DCS -- Device Control String */ - case 0x9d: /* OSC -- Operating System Command */ - case 0x9e: /* PM -- Privacy Message */ - case 0x9f: /* APC -- Application Program Command */ - tstrsequence(ascii); - return; - } - /* only CAN, SUB, \a and C1 chars interrupt a sequence */ - term.esc &= ~(ESC_STR_END|ESC_STR); -} - -/* - * returns 1 when the sequence is finished and it hasn't to read - * more characters for this sequence, otherwise 0 - */ -int -eschandle(uchar ascii) -{ - switch (ascii) { - case '[': - term.esc |= ESC_CSI; - return 0; - case '#': - term.esc |= ESC_TEST; - return 0; - case '%': - term.esc |= ESC_UTF8; - return 0; - case 'P': /* DCS -- Device Control String */ - case '_': /* APC -- Application Program Command */ - case '^': /* PM -- Privacy Message */ - case ']': /* OSC -- Operating System Command */ - case 'k': /* old title set compatibility */ - tstrsequence(ascii); - return 0; - case 'n': /* LS2 -- Locking shift 2 */ - case 'o': /* LS3 -- Locking shift 3 */ - term.charset = 2 + (ascii - 'n'); - break; - case '(': /* GZD4 -- set primary charset G0 */ - case ')': /* G1D4 -- set secondary charset G1 */ - case '*': /* G2D4 -- set tertiary charset G2 */ - case '+': /* G3D4 -- set quaternary charset G3 */ - term.icharset = ascii - '('; - term.esc |= ESC_ALTCHARSET; - return 0; - case 'D': /* IND -- Linefeed */ - if (term.c.y == term.bot) { - tscrollup(term.top, 1); - } else { - tmoveto(term.c.x, term.c.y+1); - } - break; - case 'E': /* NEL -- Next line */ - tnewline(1); /* always go to first col */ - break; - case 'H': /* HTS -- Horizontal tab stop */ - term.tabs[term.c.x] = 1; - break; - case 'M': /* RI -- Reverse index */ - if (term.c.y == term.top) { - tscrolldown(term.top, 1); - } else { - tmoveto(term.c.x, term.c.y-1); - } - break; - case 'Z': /* DECID -- Identify Terminal */ - ttywrite(vtiden, strlen(vtiden), 0); - break; - case 'c': /* RIS -- Reset to initial state */ - treset(); - resettitle(); - xloadcols(); - xsetmode(0, MODE_HIDE); - 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) { - /* in UTF-8 mode ignore handling C1 control characters */ - if (IS_SET(MODE_UTF8) && ISCONTROLC1(u)) - return; - 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 = &TLINE(term.c.y)[term.c.x]; - if (IS_SET(MODE_WRAP) && (term.c.state & CURSOR_WRAPNEXT)) { - gp->mode |= ATTR_WRAP; - tnewline(1); - gp = &TLINE(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)); - gp->mode &= ~ATTR_WIDE; - } - - if (term.c.x+width > term.col) { - if (IS_SET(MODE_WRAP)) - tnewline(1); - else - tmoveto(term.col - width, term.c.y); - gp = &TLINE(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) { - if (gp[1].mode == ATTR_WIDE && term.c.x+2 < term.col) { - gp[2].u = ' '; - gp[2].mode &= ~ATTR_WDUMMY; - } - 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; - - if (TSCREEN.off) { - TSCREEN.off = 0; - tfulldirt(); - } - - 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 -clearline(Line line, Glyph g, int x, int xend) -{ - int i; - g.mode = 0; - g.u = ' '; - for (i = x; i < xend; ++i) { - line[i] = g; - } -} - -Line -ensureline(Line line) -{ - if (!line) { - line = xmalloc(term.linelen * sizeof(Glyph)); - } - return line; -} - -void -tresize(int col, int row) -{ - int i, j; - int minrow = MIN(row, term.row); - int mincol = MIN(col, term.col); - int linelen = MAX(col, term.linelen); - int *bp; - - if (col < 1 || row < 1 || row > HISTSIZE) { - fprintf(stderr, - "tresize: error resizing to %dx%d\n", col, row); - return; - } - - /* Shift buffer to keep the cursor where we expect it */ - if (row <= term.c.y) { - term.screen[0].cur = (term.screen[0].cur - row + term.c.y + 1) % term.screen[0].size; - } - - /* Resize and clear line buffers as needed */ - if (linelen > term.linelen) { - for (i = 0; i < term.screen[0].size; ++i) { - if (term.screen[0].buffer[i]) { - term.screen[0].buffer[i] = xrealloc(term.screen[0].buffer[i], linelen * sizeof(Glyph)); - clearline(term.screen[0].buffer[i], term.c.attr, term.linelen, linelen); - } - } - for (i = 0; i < minrow; ++i) { - term.screen[1].buffer[i] = xrealloc(term.screen[1].buffer[i], linelen * sizeof(Glyph)); - clearline(term.screen[1].buffer[i], term.c.attr, term.linelen, linelen); - } - } - /* Allocate all visible lines for regular line buffer */ - for (j = term.screen[0].cur, i = 0; i < row; ++i, j = (j + 1) % term.screen[0].size) - { - if (!term.screen[0].buffer[j]) { - term.screen[0].buffer[j] = xmalloc(linelen * sizeof(Glyph)); - } - if (i >= term.row) { - clearline(term.screen[0].buffer[j], term.c.attr, 0, linelen); - } - } - /* Resize alt screen */ - term.screen[1].cur = 0; - term.screen[1].size = row; - for (i = row; i < term.row; ++i) { - free(term.screen[1].buffer[i]); - } - term.screen[1].buffer = xrealloc(term.screen[1].buffer, row * sizeof(Line)); - for (i = term.row; i < row; ++i) { - term.screen[1].buffer[i] = xmalloc(linelen * sizeof(Glyph)); - clearline(term.screen[1].buffer[i], term.c.attr, 0, linelen); - } - - /* resize to new height */ - term.dirty = xrealloc(term.dirty, row * sizeof(*term.dirty)); - term.tabs = xrealloc(term.tabs, col * sizeof(*term.tabs)); - - /* fix tabstops */ - 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; - term.linelen = linelen; - /* reset scrolling region */ - tsetscroll(0, row-1); - /* make use of the LIMIT in tmoveto */ - tmoveto(term.c.x, term.c.y); - tfulldirt(); -} - -void -resettitle(void) -{ - xsettitle(NULL); -} - -void -drawregion(int x1, int y1, int x2, int y2) -{ - int y, L; - - L = TLINEOFFSET(y1); - for (y = y1; y < y2; y++) { - if (term.dirty[y]) { - term.dirty[y] = 0; - xdrawline(TSCREEN.buffer[L], x1, y, x2); - } - L = (L + 1) % TSCREEN.size; - } -} - -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 (TLINE(term.ocy)[term.ocx].mode & ATTR_WDUMMY) - term.ocx--; - if (TLINE(term.c.y)[cx].mode & ATTR_WDUMMY) - cx--; - - drawregion(0, 0, term.col, term.row); - if (TSCREEN.off == 0) - xdrawcursor(cx, term.c.y, TLINE(term.c.y)[cx], - term.ocx, term.ocy, TLINE(term.ocy)[term.ocx], - TLINE(term.ocy), term.col); - - 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/suckless/st/st.h b/suckless/st/st.h deleted file mode 100644 index 4649646..0000000 --- a/suckless/st/st.h +++ /dev/null @@ -1,130 +0,0 @@ -/* See LICENSE for license details. */ - -#include -#include - -/* 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 & (~ATTR_WRAP)) != ((b).mode & (~ATTR_WRAP)) || \ - (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)) -#define HISTSIZE 2000 - -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 printscreen(const Arg *); -void printsel(const Arg *); -void sendbreak(const Arg *); -void toggleprinter(const Arg *); - -int tattrset(int); -void tnew(int, int); -void tresize(int, int); -void tsetdirtattr(int); -void ttyhangup(void); -int ttynew(const char *, char *, const char *, char **); -size_t ttyread(void); -void ttyresize(int, int); -void ttywrite(const char *, size_t, int); - -void resettitle(void); - -void selclear(void); -void selinit(void); -void selstart(int, int, int); -void selextend(int, int, int, int); -int selected(int, int); -char *getsel(void); - -size_t utf8encode(Rune, char *); - -void *xmalloc(size_t); -void *xrealloc(void *, size_t); -char *xstrdup(const char *); - -/* config.h globals */ -extern char *utmp; -extern char *scroll; -extern char *stty_args; -extern char *vtiden; -extern wchar_t *worddelimiters; -extern int allowaltscreen; -extern int allowwindowops; -extern char *termname; -extern unsigned int tabspaces; -extern unsigned int defaultfg; -extern unsigned int defaultbg; -extern unsigned int defaultcs; -extern float alpha; -extern float alpha_def; diff --git a/suckless/st/st.info b/suckless/st/st.info deleted file mode 100644 index efab2cf..0000000 --- a/suckless/st/st.info +++ /dev/null @@ -1,243 +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, - BE=\E[?2004h, - BD=\E[?2004l, - PS=\E[200~, - PE=\E[201~, -# 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/suckless/st/st.o b/suckless/st/st.o deleted file mode 100644 index 53e6ffd9fad3efc75afbabe6c45b3b8780e7e9d6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 82832 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 diff --git a/suckless/st/win.h b/suckless/st/win.h deleted file mode 100644 index 94679e4..0000000 --- a/suckless/st/win.h +++ /dev/null @@ -1,41 +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, Line, int); -void xdrawline(Line, int, int, int); -void xfinishdraw(void); -void xloadcols(void); -int xsetcolorname(int, const char *); -int xgetcolor(int, unsigned char *, unsigned char *, unsigned char *); -void xseticontitle(char *); -void xsettitle(char *); -int xsetcursor(int); -void xsetmode(int, unsigned int); -void xsetpointermotion(int); -void xsetsel(char *); -int xstartdraw(void); -void xximspot(int, int); diff --git a/suckless/st/x.c b/suckless/st/x.c deleted file mode 100644 index 0cb35e8..0000000 --- a/suckless/st/x.c +++ /dev/null @@ -1,2319 +0,0 @@ -/* See LICENSE for license details. */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -char *argv0; -#include "arg.h" -#include "st.h" -#include "win.h" -#include "hb.h" - -/* types used in config.h */ -typedef struct { - uint mod; - KeySym keysym; - void (*func)(const Arg *); - const Arg arg; -} Shortcut; - -typedef struct { - uint mod; - uint button; - void (*func)(const Arg *); - const Arg arg; - uint release; -} MouseShortcut; - -typedef struct { - KeySym k; - uint mask; - char *s; - /* three-valued logic variables: 0 indifferent, 1 on, -1 off */ - signed char appkey; /* application keypad */ - signed char appcursor; /* application cursor */ -} Key; - -/* X modifiers */ -#define XK_ANY_MOD UINT_MAX -#define XK_NO_MOD 0 -#define XK_SWITCH_MOD (1<<13|1<<14) - -/* function definitions used in config.h */ -static void clipcopy(const Arg *); -static void clippaste(const Arg *); -static void numlock(const Arg *); -static void selpaste(const Arg *); -static void zoom(const Arg *); -static void zoomabs(const Arg *); -static void zoomreset(const Arg *); -static void ttysend(const Arg *); -static void chgalpha(const Arg *); -void kscrollup(const Arg *); -void kscrolldown(const Arg *); - -/* config.h for applying patches and the configuration. */ -#include "config.h" - -/* XEMBED messages */ -#define XEMBED_FOCUS_IN 4 -#define XEMBED_FOCUS_OUT 5 - -/* macros */ -#define IS_SET(flag) ((win.mode & (flag)) != 0) -#define TRUERED(x) (((x) & 0xff0000) >> 8) -#define TRUEGREEN(x) (((x) & 0xff00)) -#define TRUEBLUE(x) (((x) & 0xff) << 8) - -typedef XftDraw *Draw; -typedef XftColor Color; -typedef XftGlyphFontSpec GlyphFontSpec; - -/* Purely graphic info */ -typedef struct { - int tw, th; /* tty width and height */ - int w, h; /* window width and height */ - int ch; /* char height */ - int cw; /* char width */ - int mode; /* window state/mode flags */ - int cursor; /* cursor style */ -} TermWindow; - -typedef struct { - Display *dpy; - Colormap cmap; - Window win; - Drawable buf; - GlyphFontSpec *specbuf; /* font spec buffer used for rendering */ - Atom xembed, wmdeletewin, netwmname, netwmiconname, netwmpid; - struct { - XIM xim; - XIC xic; - XPoint spot; - XVaNestedList spotlist; - } ime; - Draw draw; - Visual *vis; - XSetWindowAttributes attrs; - int scr; - int isfixed; /* is fixed geometry? */ - int depth; /* bit depth */ - 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 void xresetfontsettings(ushort mode, Font **font, int *frcflags); -static int xmakeglyphfontspecs(XftGlyphFontSpec *, const Glyph *, int, int, int); -static void xdrawglyphfontspecs(const XftGlyphFontSpec *, Glyph, int, int, int, int); -static void xdrawglyph(Glyph, int, int); -static void xclear(int, int, int, int); -static int xgeommasktogravity(int); -static int ximopen(Display *); -static void ximinstantiate(Display *, XPointer, XPointer); -static void ximdestroy(XIM, XPointer, XPointer); -static int xicdestroy(XIC, XPointer, XPointer); -static void xinit(int, int); -static void cresize(int, int); -static void xresize(int, int); -static void xhints(void); -static int xloadcolor(int, const char *, Color *); -static int xloadfont(Font *, FcPattern *); -static void xloadfonts(const char *, double); -static void xunloadfont(Font *); -static void xunloadfonts(void); -static void xsetenv(void); -static void xseturgency(int); -static int evcol(XEvent *); -static int evrow(XEvent *); - -static void expose(XEvent *); -static void visibility(XEvent *); -static void unmap(XEvent *); -static void kpress(XEvent *); -static void cmessage(XEvent *); -static void resize(XEvent *); -static void focus(XEvent *); -static uint buttonmask(uint); -static int mouseaction(XEvent *, uint); -static void brelease(XEvent *); -static void bpress(XEvent *); -static void bmotion(XEvent *); -static void propnotify(XEvent *); -static void selnotify(XEvent *); -static void selclear_(XEvent *); -static void selrequest(XEvent *); -static void setsel(char *, Time); -static void mousesel(XEvent *, int); -static void mousereport(XEvent *); -static char *kmap(KeySym, uint); -static int match(uint, uint); - -static void run(void); -static void usage(void); - -static void (*handler[LASTEvent])(XEvent *) = { - [KeyPress] = kpress, - [ClientMessage] = cmessage, - [ConfigureNotify] = resize, - [VisibilityNotify] = visibility, - [UnmapNotify] = unmap, - [Expose] = expose, - [FocusIn] = focus, - [FocusOut] = focus, - [MotionNotify] = bmotion, - [ButtonPress] = bpress, - [ButtonRelease] = brelease, -/* - * Uncomment if you want the selection to disappear when you select something - * different in another window. - */ -/* [SelectionClear] = selclear_, */ - [SelectionNotify] = selnotify, -/* - * PropertyNotify is only turned on when there is some INCR transfer happening - * for the selection retrieval. - */ - [PropertyNotify] = propnotify, - [SelectionRequest] = selrequest, -}; - -/* Globals */ -static DC dc; -static XWindow xw; -static XSelection xsel; -static TermWindow win; - -/* Font Ring Cache */ -enum { - FRC_NORMAL, - FRC_ITALIC, - FRC_BOLD, - FRC_ITALICBOLD -}; - -typedef struct { - XftFont *font; - int flags; - Rune unicodep; -} Fontcache; - -/* Fontcache is an array now. A new font will be appended to the array. */ -static Fontcache *frc = NULL; -static int frclen = 0; -static int frccap = 0; -static char *usedfont = NULL; -static double usedfontsize = 0; -static double defaultfontsize = 0; - -static char *opt_alpha = NULL; -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 uint buttons; /* bit field of pressed buttons */ - -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, btn, code; - int x = evcol(e), y = evrow(e); - int state = e->xbutton.state; - char buf[40]; - static int ox, oy; - - if (e->type == MotionNotify) { - if (x == ox && y == oy) - return; - if (!IS_SET(MODE_MOUSEMOTION) && !IS_SET(MODE_MOUSEMANY)) - return; - /* MODE_MOUSEMOTION: no reporting if no button is pressed */ - if (IS_SET(MODE_MOUSEMOTION) && buttons == 0) - return; - /* Set btn to lowest-numbered pressed button, or 12 if no - * buttons are pressed. */ - for (btn = 1; btn <= 11 && !(buttons & (1<<(btn-1))); btn++) - ; - code = 32; - } else { - btn = e->xbutton.button; - /* Only buttons 1 through 11 can be encoded */ - if (btn < 1 || btn > 11) - return; - if (e->type == ButtonRelease) { - /* MODE_MOUSEX10: no button release reporting */ - if (IS_SET(MODE_MOUSEX10)) - return; - /* Don't send release events for the scroll wheel */ - if (btn == 4 || btn == 5) - return; - } - code = 0; - } - - ox = x; - oy = y; - - /* Encode btn into code. If no button is pressed for a motion event in - * MODE_MOUSEMANY, then encode it as a release. */ - if ((!IS_SET(MODE_MOUSESGR) && e->type == ButtonRelease) || btn == 12) - code += 3; - else if (btn >= 8) - code += 128 + btn - 8; - else if (btn >= 4) - code += 64 + btn - 4; - else - code += btn - 1; - - if (!IS_SET(MODE_MOUSEX10)) { - code += ((state & ShiftMask ) ? 4 : 0) - + ((state & Mod1Mask ) ? 8 : 0) /* meta key: alt */ - + ((state & ControlMask) ? 16 : 0); - } - - if (IS_SET(MODE_MOUSESGR)) { - len = snprintf(buf, sizeof(buf), "\033[<%d;%d;%d%c", - code, x+1, y+1, - e->type == ButtonRelease ? 'm' : 'M'); - } else if (x < 223 && y < 223) { - len = snprintf(buf, sizeof(buf), "\033[M%c%c%c", - 32+code, 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 Buttonmask for Button - it's set on release */ - uint state = e->xbutton.state & ~buttonmask(e->xbutton.button); - - for (ms = mshortcuts; ms < mshortcuts + LEN(mshortcuts); ms++) { - if (ms->release == release && - ms->button == e->xbutton.button && - (match(ms->mod, state) || /* exact or forced */ - match(ms->mod, state & ~forcemousemod))) { - ms->func(&(ms->arg)); - return 1; - } - } - - return 0; -} - -void -bpress(XEvent *e) -{ - int btn = e->xbutton.button; - struct timespec now; - int snap; - - if (1 <= btn && btn <= 11) - buttons |= 1 << (btn-1); - - if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forcemousemod)) { - mousereport(e); - return; - } - - if (mouseaction(e, 0)) - return; - - if (btn == Button1) { - /* - * If the user clicks below predefined timeouts specific - * snapping behaviour is exposed. - */ - clock_gettime(CLOCK_MONOTONIC, &now); - if (TIMEDIFF(now, xsel.tclick2) <= tripleclicktimeout) { - snap = SNAP_LINE; - } else if (TIMEDIFF(now, xsel.tclick1) <= doubleclicktimeout) { - snap = SNAP_WORD; - } else { - snap = 0; - } - xsel.tclick2 = xsel.tclick1; - xsel.tclick1 = now; - - selstart(evcol(e), evrow(e), snap); - } -} - -void -propnotify(XEvent *e) -{ - XPropertyEvent *xpev; - Atom clipboard = XInternAtom(xw.dpy, "CLIPBOARD", 0); - - xpev = &e->xproperty; - if (xpev->state == PropertyNewValue && - (xpev->atom == XA_PRIMARY || - xpev->atom == clipboard)) { - selnotify(e); - } -} - -void -selnotify(XEvent *e) -{ - ulong nitems, ofs, rem; - int format; - uchar *data, *last, *repl; - Atom type, incratom, property = None; - - incratom = XInternAtom(xw.dpy, "INCR", 0); - - ofs = 0; - if (e->type == SelectionNotify) - property = e->xselection.property; - else if (e->type == PropertyNotify) - property = e->xproperty.atom; - - if (property == None) - return; - - do { - if (XGetWindowProperty(xw.dpy, xw.win, property, ofs, - BUFSIZ/4, False, AnyPropertyType, - &type, &format, &nitems, &rem, - &data)) { - fprintf(stderr, "Clipboard allocation failed\n"); - return; - } - - if (e->type == PropertyNotify && nitems == 0 && rem == 0) { - /* - * If there is some PropertyNotify with no data, then - * this is the signal of the selection owner that all - * data has been transferred. We won't need to receive - * PropertyNotify events anymore. - */ - MODBIT(xw.attrs.event_mask, 0, PropertyChangeMask); - XChangeWindowAttributes(xw.dpy, xw.win, CWEventMask, - &xw.attrs); - } - - if (type == incratom) { - /* - * Activate the PropertyNotify events so we receive - * when the selection owner does send us the next - * chunk of data. - */ - MODBIT(xw.attrs.event_mask, 1, PropertyChangeMask); - XChangeWindowAttributes(xw.dpy, xw.win, CWEventMask, - &xw.attrs); - - /* - * Deleting the property is the transfer start signal. - */ - XDeleteProperty(xw.dpy, xw.win, (int)property); - continue; - } - - /* - * As seen in getsel: - * Line endings are inconsistent in the terminal and GUI world - * copy and pasting. When receiving some selection data, - * replace all '\n' with '\r'. - * FIXME: Fix the computer world. - */ - repl = data; - last = data + nitems * format / 8; - while ((repl = memchr(repl, '\n', last - repl))) { - *repl++ = '\r'; - } - - if (IS_SET(MODE_BRCKTPASTE) && ofs == 0) - ttywrite("\033[200~", 6, 0); - ttywrite((char *)data, nitems * format / 8, 1); - if (IS_SET(MODE_BRCKTPASTE) && rem == 0) - ttywrite("\033[201~", 6, 0); - XFree(data); - /* number of 32-bit chunks returned */ - ofs += nitems * format / 32; - } while (rem > 0); - - /* - * Deleting the property again tells the selection owner to send the - * next data chunk in the property. - */ - XDeleteProperty(xw.dpy, xw.win, (int)property); -} - -void -xclipcopy(void) -{ - clipcopy(NULL); -} - -void -selclear_(XEvent *e) -{ - selclear(); -} - -void -selrequest(XEvent *e) -{ - XSelectionRequestEvent *xsre; - XSelectionEvent xev; - Atom xa_targets, string, clipboard; - char *seltext; - - xsre = (XSelectionRequestEvent *) e; - xev.type = SelectionNotify; - xev.requestor = xsre->requestor; - xev.selection = xsre->selection; - xev.target = xsre->target; - xev.time = xsre->time; - if (xsre->property == None) - xsre->property = xsre->target; - - /* reject */ - xev.property = None; - - xa_targets = XInternAtom(xw.dpy, "TARGETS", 0); - if (xsre->target == xa_targets) { - /* respond with the supported type */ - string = xsel.xtarget; - XChangeProperty(xsre->display, xsre->requestor, xsre->property, - XA_ATOM, 32, PropModeReplace, - (uchar *) &string, 1); - xev.property = xsre->property; - } else if (xsre->target == xsel.xtarget || xsre->target == XA_STRING) { - /* - * xith XA_STRING non ascii characters may be incorrect in the - * requestor. It is not our problem, use utf8. - */ - clipboard = XInternAtom(xw.dpy, "CLIPBOARD", 0); - if (xsre->selection == XA_PRIMARY) { - seltext = xsel.primary; - } else if (xsre->selection == clipboard) { - seltext = xsel.clipboard; - } else { - fprintf(stderr, - "Unhandled clipboard selection 0x%lx\n", - xsre->selection); - return; - } - if (seltext != NULL) { - XChangeProperty(xsre->display, xsre->requestor, - xsre->property, xsre->target, - 8, PropModeReplace, - (uchar *)seltext, strlen(seltext)); - xev.property = xsre->property; - } - } - - /* all done, send a notification to the listener */ - if (!XSendEvent(xsre->display, xsre->requestor, 1, 0, (XEvent *) &xev)) - fprintf(stderr, "Error sending SelectionNotify event\n"); -} - -void -setsel(char *str, Time t) -{ - if (!str) - return; - - free(xsel.primary); - xsel.primary = str; - - XSetSelectionOwner(xw.dpy, XA_PRIMARY, xw.win, t); - if (XGetSelectionOwner(xw.dpy, XA_PRIMARY) != xw.win) - selclear(); -} - -void -xsetsel(char *str) -{ - setsel(str, CurrentTime); -} - -void -brelease(XEvent *e) -{ - int btn = e->xbutton.button; - - if (1 <= btn && btn <= 11) - buttons &= ~(1 << (btn-1)); - - if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forcemousemod)) { - mousereport(e); - return; - } - - if (mouseaction(e, 1)) - return; - if (btn == 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, - xw.depth); - XftDrawChange(xw.draw, xw.buf); - xclear(0, 0, win.w, win.h); - - /* resize to new width */ - xw.specbuf = xrealloc(xw.specbuf, col * sizeof(GlyphFontSpec) * 4); -} - -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); - } - - /* set alpha value of bg color */ - if (opt_alpha) - alpha = strtof(opt_alpha, NULL); - dc.col[defaultbg].color.alpha = (unsigned short)(0xffff * alpha); - dc.col[defaultbg].pixel &= 0x00FFFFFF; - dc.col[defaultbg].pixel |= (unsigned char)(0xff * alpha) << 24; - loaded = 1; -} - -int -xgetcolor(int x, unsigned char *r, unsigned char *g, unsigned char *b) -{ - if (!BETWEEN(x, 0, dc.collen - 1)) - return 1; - - *r = dc.col[x].color.red >> 8; - *g = dc.col[x].color.green >> 8; - *b = dc.col[x].color.blue >> 8; - - return 0; -} - -int -xsetcolorname(int x, const char *name) -{ - Color ncolor; - - if (!BETWEEN(x, 0, dc.collen - 1)) - return 1; - - if (!xloadcolor(x, name, &ncolor)) - return 1; - - XftColorFree(xw.dpy, xw.vis, xw.cmap, &dc.col[x]); - dc.col[x] = ncolor; - - return 0; -} - -/* - * Absolute coordinates. - */ -void -xclear(int x1, int y1, int x2, int y2) -{ - XftDrawRect(xw.draw, - &dc.col[IS_SET(MODE_REVERSE)? defaultfg : defaultbg], - x1, y1, x2-x1, y2-y1); -} - -void -xhints(void) -{ - XClassHint class = {opt_name ? opt_name : termname, - opt_class ? opt_class : termname}; - XWMHints wm = {.flags = InputHint, .input = 1}; - XSizeHints *sizeh; - - sizeh = XAllocSizeHints(); - - sizeh->flags = PSize | PResizeInc | PBaseSize | PMinSize; - sizeh->height = win.h; - sizeh->width = win.w; - sizeh->height_inc = win.ch; - sizeh->width_inc = win.cw; - sizeh->base_height = 2 * borderpx; - sizeh->base_width = 2 * borderpx; - sizeh->min_height = win.ch + 2 * borderpx; - sizeh->min_width = win.cw + 2 * borderpx; - if (xw.isfixed) { - sizeh->flags |= PMaxSize; - sizeh->min_width = sizeh->max_width = win.w; - sizeh->min_height = sizeh->max_height = win.h; - } - if (xw.gm & (XValue|YValue)) { - sizeh->flags |= USPosition | PWinGravity; - sizeh->x = xw.l; - sizeh->y = xw.t; - sizeh->win_gravity = xgeommasktogravity(xw.gm); - } - - XSetWMProperties(xw.dpy, xw.win, NULL, NULL, NULL, 0, sizeh, &wm, - &class); - XFree(sizeh); -} - -int -xgeommasktogravity(int mask) -{ - switch (mask & (XNegative|YNegative)) { - case 0: - return NorthWestGravity; - case XNegative: - return NorthEastGravity; - case YNegative: - return SouthWestGravity; - } - - return SouthEastGravity; -} - -int -xloadfont(Font *f, FcPattern *pattern) -{ - FcPattern *configured; - FcPattern *match; - FcResult result; - XGlyphInfo extents; - int wantattr, haveattr; - - /* - * Manually configure instead of calling XftMatchFont - * so that we can use the configured pattern for - * "missing glyph" lookups. - */ - configured = FcPatternDuplicate(pattern); - if (!configured) - return 1; - - FcConfigSubstitute(NULL, configured, FcMatchPattern); - XftDefaultSubstitute(xw.dpy, xw.scr, configured); - - match = FcFontMatch(NULL, configured, &result); - if (!match) { - FcPatternDestroy(configured); - return 1; - } - - if (!(f->match = XftFontOpenPattern(xw.dpy, match))) { - FcPatternDestroy(configured); - FcPatternDestroy(match); - return 1; - } - - if ((XftPatternGetInteger(pattern, "slant", 0, &wantattr) == - XftResultMatch)) { - /* - * Check if xft was unable to find a font with the appropriate - * slant but gave us one anyway. Try to mitigate. - */ - if ((XftPatternGetInteger(f->match->pattern, "slant", 0, - &haveattr) != XftResultMatch) || haveattr < wantattr) { - f->badslant = 1; - fputs("font slant does not match\n", stderr); - } - } - - if ((XftPatternGetInteger(pattern, "weight", 0, &wantattr) == - XftResultMatch)) { - if ((XftPatternGetInteger(f->match->pattern, "weight", 0, - &haveattr) != XftResultMatch) || haveattr != wantattr) { - f->badweight = 1; - fputs("font weight does not match\n", stderr); - } - } - - XftTextExtentsUtf8(xw.dpy, f->match, - (const FcChar8 *) ascii_printable, - strlen(ascii_printable), &extents); - - f->set = NULL; - f->pattern = configured; - - f->ascent = f->match->ascent; - f->descent = f->match->descent; - f->lbearing = 0; - f->rbearing = f->match->max_advance_width; - - f->height = f->ascent + f->descent; - f->width = DIVCEIL(extents.xOff, strlen(ascii_printable)); - - return 0; -} - -void -xloadfonts(const char *fontstr, double fontsize) -{ - FcPattern *pattern; - double fontval; - - if (fontstr[0] == '-') - pattern = XftXlfdParse(fontstr, False, False); - else - pattern = FcNameParse((const FcChar8 *)fontstr); - - if (!pattern) - die("can't open font %s\n", fontstr); - - if (fontsize > 1) { - FcPatternDel(pattern, FC_PIXEL_SIZE); - FcPatternDel(pattern, FC_SIZE); - FcPatternAddDouble(pattern, FC_PIXEL_SIZE, (double)fontsize); - usedfontsize = fontsize; - } else { - if (FcPatternGetDouble(pattern, FC_PIXEL_SIZE, 0, &fontval) == - FcResultMatch) { - usedfontsize = fontval; - } else if (FcPatternGetDouble(pattern, FC_SIZE, 0, &fontval) == - FcResultMatch) { - usedfontsize = -1; - } else { - /* - * Default font size is 12, if none given. This is to - * have a known usedfontsize value. - */ - FcPatternAddDouble(pattern, FC_PIXEL_SIZE, 12); - usedfontsize = 12; - } - defaultfontsize = usedfontsize; - } - - if (xloadfont(&dc.font, pattern)) - die("can't open font %s\n", fontstr); - - if (usedfontsize < 0) { - FcPatternGetDouble(dc.font.match->pattern, - FC_PIXEL_SIZE, 0, &fontval); - usedfontsize = fontval; - if (fontsize == 0) - defaultfontsize = fontval; - } - - /* Setting character width and height. */ - win.cw = ceilf(dc.font.width * cwscale); - win.ch = ceilf(dc.font.height * chscale); - - FcPatternDel(pattern, FC_SLANT); - FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ITALIC); - if (xloadfont(&dc.ifont, pattern)) - die("can't open font %s\n", fontstr); - - FcPatternDel(pattern, FC_WEIGHT); - FcPatternAddInteger(pattern, FC_WEIGHT, FC_WEIGHT_BOLD); - if (xloadfont(&dc.ibfont, pattern)) - die("can't open font %s\n", fontstr); - - FcPatternDel(pattern, FC_SLANT); - FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ROMAN); - if (xloadfont(&dc.bfont, pattern)) - die("can't open font %s\n", fontstr); - - FcPatternDestroy(pattern); -} - -void -xunloadfont(Font *f) -{ - XftFontClose(xw.dpy, f->match); - FcPatternDestroy(f->pattern); - if (f->set) - FcFontSetDestroy(f->set); -} - -void -xunloadfonts(void) -{ - /* Clear Harfbuzz font cache. */ - hbunloadfonts(); - - /* 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, root; - pid_t thispid = getpid(); - XColor xmousefg, xmousebg; - XWindowAttributes attr; - XVisualInfo vis; - - if (!(xw.dpy = XOpenDisplay(NULL))) - die("can't open display\n"); - xw.scr = XDefaultScreen(xw.dpy); - - if (!(opt_embed && (parent = strtol(opt_embed, NULL, 0)))) { - parent = XRootWindow(xw.dpy, xw.scr); - xw.depth = 32; - } else { - XGetWindowAttributes(xw.dpy, parent, &attr); - xw.depth = attr.depth; - } - - XMatchVisualInfo(xw.dpy, xw.scr, xw.depth, TrueColor, &vis); - xw.vis = vis.visual; - - /* font */ - if (!FcInit()) - die("could not init fontconfig.\n"); - - usedfont = (opt_font == NULL)? font : opt_font; - xloadfonts(usedfont, 0); - - /* Backup default alpha value */ - alpha_def = alpha; - - /* colors */ - xw.cmap = XCreateColormap(xw.dpy, parent, xw.vis, None); - 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; - - root = XRootWindow(xw.dpy, xw.scr); - xw.win = XCreateWindow(xw.dpy, root, xw.l, xw.t, - win.w, win.h, 0, xw.depth, InputOutput, - xw.vis, CWBackPixel | CWBorderPixel | CWBitGravity - | CWEventMask | CWColormap, &xw.attrs); - if (parent != root) - XReparentWindow(xw.dpy, xw.win, parent, xw.l, xw.t); - - memset(&gcvalues, 0, sizeof(gcvalues)); - gcvalues.graphics_exposures = False; - xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h, xw.depth); - dc.gc = XCreateGC(xw.dpy, xw.buf, GCGraphicsExposures, &gcvalues); - 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) * 4); - - /* Xft rendering context */ - xw.draw = XftDrawCreate(xw.dpy, xw.buf, xw.vis, xw.cmap); - - /* input methods */ - if (!ximopen(xw.dpy)) { - XRegisterIMInstantiateCallback(xw.dpy, NULL, NULL, NULL, - ximinstantiate, NULL); - } - - /* white cursor, black outline */ - cursor = XCreateFontCursor(xw.dpy, mouseshape); - XDefineCursor(xw.dpy, xw.win, cursor); - - if (XParseColor(xw.dpy, xw.cmap, colorname[mousefg], &xmousefg) == 0) { - xmousefg.red = 0xffff; - xmousefg.green = 0xffff; - xmousefg.blue = 0xffff; - } - - if (XParseColor(xw.dpy, xw.cmap, colorname[mousebg], &xmousebg) == 0) { - xmousebg.red = 0x0000; - xmousebg.green = 0x0000; - xmousebg.blue = 0x0000; - } - - XRecolorCursor(xw.dpy, cursor, &xmousefg, &xmousebg); - - xw.xembed = XInternAtom(xw.dpy, "_XEMBED", False); - xw.wmdeletewin = XInternAtom(xw.dpy, "WM_DELETE_WINDOW", False); - xw.netwmname = XInternAtom(xw.dpy, "_NET_WM_NAME", False); - xw.netwmiconname = XInternAtom(xw.dpy, "_NET_WM_ICON_NAME", False); - XSetWMProtocols(xw.dpy, xw.win, &xw.wmdeletewin, 1); - - xw.netwmpid = XInternAtom(xw.dpy, "_NET_WM_PID", False); - XChangeProperty(xw.dpy, xw.win, xw.netwmpid, XA_CARDINAL, 32, - PropModeReplace, (uchar *)&thispid, 1); - - win.mode = MODE_NUMLOCK; - resettitle(); - xhints(); - XMapWindow(xw.dpy, xw.win); - XSync(xw.dpy, False); - - clock_gettime(CLOCK_MONOTONIC, &xsel.tclick1); - clock_gettime(CLOCK_MONOTONIC, &xsel.tclick2); - xsel.primary = NULL; - xsel.clipboard = NULL; - xsel.xtarget = XInternAtom(xw.dpy, "UTF8_STRING", 0); - if (xsel.xtarget == None) - xsel.xtarget = XA_STRING; -} - -void -xresetfontsettings(ushort mode, Font **font, int *frcflags) -{ - *font = &dc.font; - 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; - } -} - -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, length = 0, start = 0, numspecs = 0; - float cluster_xp = xp, cluster_yp = yp; - HbTransformData shaped = { 0 }; - - /* Initial values. */ - mode = prevmode = glyphs[0].mode & ~ATTR_WRAP; - xresetfontsettings(mode, &font, &frcflags); - - for (i = 0, xp = winx, yp = winy + font->ascent; i < len; ++i) { - mode = glyphs[i].mode & ~ATTR_WRAP; - - /* Skip dummy wide-character spacing. */ - if (mode & ATTR_WDUMMY && i < (len - 1)) - continue; - - if ( - prevmode != mode - || ATTRCMP(glyphs[start], glyphs[i]) - || selected(x + i, y) != selected(x + start, y) - || i == (len - 1) - ) { - /* Handle 1-character wide segments and end of line */ - length = i - start; - if (i == start) { - length = 1; - } else if (i == (len - 1)) { - length = (i - start + 1); - } - - /* Shape the segment. */ - hbtransform(&shaped, font->match, glyphs, start, length); - runewidth = win.cw * ((glyphs[start].mode & ATTR_WIDE) ? 2.0f : 1.0f); - cluster_xp = xp; cluster_yp = yp; - for (int code_idx = 0; code_idx < shaped.count; code_idx++) { - int idx = shaped.glyphs[code_idx].cluster; - - if (glyphs[start + idx].mode & ATTR_WDUMMY) - continue; - - /* Advance the drawing cursor if we've moved to a new cluster */ - if (code_idx > 0 && idx != shaped.glyphs[code_idx - 1].cluster) { - xp += runewidth; - cluster_xp = xp; - cluster_yp = yp; - runewidth = win.cw * ((glyphs[start + idx].mode & ATTR_WIDE) ? 2.0f : 1.0f); - } - - if (shaped.glyphs[code_idx].codepoint != 0) { - /* If symbol is found, put it into the specs. */ - specs[numspecs].font = font->match; - specs[numspecs].glyph = shaped.glyphs[code_idx].codepoint; - specs[numspecs].x = cluster_xp + (short)(shaped.positions[code_idx].x_offset / 64.); - specs[numspecs].y = cluster_yp - (short)(shaped.positions[code_idx].y_offset / 64.); - cluster_xp += shaped.positions[code_idx].x_advance / 64.; - cluster_yp += shaped.positions[code_idx].y_advance / 64.; - numspecs++; - } else { - /* If it's not found, try to fetch it through the font cache. */ - rune = glyphs[start + idx].u; - 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; - numspecs++; - } - } - - /* Cleanup and get ready for next segment. */ - hbcleanup(&shaped); - start = i; - - /* Determine font for glyph if different from previous glyph. */ - if (prevmode != mode) { - prevmode = mode; - xresetfontsettings(mode, &font, &frcflags); - yp = winy + font->ascent; - } - } - } - - return numspecs; -} - -void -chgalpha(const Arg *arg) -{ - if (arg->f == -1.0f && alpha >= 0.1f) - alpha -= 0.1f; - else if (arg->f == 1.0f && alpha < 1.0f) - alpha += 0.1f; - else if (arg->f == 0.0f) - alpha = alpha_def; - else - return; - - dc.col[defaultbg].color.alpha = (unsigned short)(0xFFFF * alpha); - /* Required to remove artifacting from borderpx */ - cresize(0, 0); - redraw(); -} - -void -xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, int y, int charlen) -{ - 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 * chscale + 1, - width, 1); - } - - if (base.mode & ATTR_STRUCK) { - XftDrawRect(xw.draw, fg, winx, winy + 2 * dc.font.ascent * chscale / 3, - width, 1); - } - - /* Reset clip to none. */ - XftDrawSetClip(xw.draw, 0); -} - -void -xdrawglyph(Glyph g, int x, int y) -{ - int numspecs; - XftGlyphFontSpec *specs = xw.specbuf; - - numspecs = xmakeglyphfontspecs(specs, &g, 1, x, y); - xdrawglyphfontspecs(specs, g, numspecs, x, y, (g.mode & ATTR_WIDE) ? 2 : 1); -} - -void -xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og, Line line, int len) -{ - Color drawcol; - - /* remove the old cursor */ - if (selected(ox, oy)) - og.mode ^= ATTR_REVERSE; - - /* Redraw the line where cursor was previously. - * It will restore the ligatures broken by the cursor. */ - xdrawline(line, 0, oy, len); - - if (IS_SET(MODE_HIDE)) - return; - - /* - * Select the right color for the right mode. - */ - g.mode &= ATTR_BOLD|ATTR_ITALIC|ATTR_UNDERLINE|ATTR_STRUCK|ATTR_WIDE; - - if (IS_SET(MODE_REVERSE)) { - g.mode |= ATTR_REVERSE; - g.bg = defaultfg; - if (selected(cx, cy)) { - drawcol = dc.col[defaultcs]; - g.fg = defaultrcs; - } else { - drawcol = dc.col[defaultrcs]; - g.fg = defaultcs; - } - } else { - if (selected(cx, cy)) { - g.fg = defaultfg; - g.bg = defaultrcs; - } else { - g.fg = defaultbg; - g.bg = defaultcs; - } - drawcol = dc.col[g.bg]; - } - - /* draw the new one */ - if (IS_SET(MODE_FOCUSED)) { - switch (win.cursor) { - case 7: /* st extension */ - g.u = 0x2603; /* snowman (U+2603) */ - /* FALLTHROUGH */ - case 0: /* Blinking Block */ - case 1: /* Blinking Block (Default) */ - case 2: /* Steady Block */ - xdrawglyph(g, cx, cy); - break; - case 3: /* Blinking Underline */ - case 4: /* Steady Underline */ - XftDrawRect(xw.draw, &drawcol, - borderpx + cx * win.cw, - borderpx + (cy + 1) * win.ch - \ - cursorthickness, - win.cw, cursorthickness); - break; - case 5: /* Blinking bar */ - case 6: /* Steady bar */ - XftDrawRect(xw.draw, &drawcol, - borderpx + cx * win.cw, - borderpx + cy * win.ch, - cursorthickness, win.ch); - break; - } - } else { - XftDrawRect(xw.draw, &drawcol, - borderpx + cx * win.cw, - borderpx + cy * win.ch, - win.cw - 1, 1); - XftDrawRect(xw.draw, &drawcol, - borderpx + cx * win.cw, - borderpx + cy * win.ch, - 1, win.ch - 1); - XftDrawRect(xw.draw, &drawcol, - borderpx + (cx + 1) * win.cw - 1, - borderpx + cy * win.ch, - 1, win.ch - 1); - XftDrawRect(xw.draw, &drawcol, - borderpx + cx * win.cw, - borderpx + (cy + 1) * win.ch - 1, - win.cw, 1); - } -} - -void -xsetenv(void) -{ - char buf[sizeof(long) * 8 + 1]; - - snprintf(buf, sizeof(buf), "%lu", xw.win); - setenv("WINDOWID", buf, 1); -} - -void -xseticontitle(char *p) -{ - XTextProperty prop; - DEFAULT(p, opt_title); - - if (p[0] == '\0') - p = opt_title; - - if (Xutf8TextListToTextProperty(xw.dpy, &p, 1, XUTF8StringStyle, - &prop) != Success) - return; - XSetWMIconName(xw.dpy, xw.win, &prop); - XSetTextProperty(xw.dpy, xw.win, &prop, xw.netwmiconname); - XFree(prop.value); -} - -void -xsettitle(char *p) -{ - XTextProperty prop; - DEFAULT(p, opt_title); - - if (p[0] == '\0') - p = opt_title; - - if (Xutf8TextListToTextProperty(xw.dpy, &p, 1, XUTF8StringStyle, - &prop) != Success) - return; - XSetWMName(xw.dpy, xw.win, &prop); - XSetTextProperty(xw.dpy, xw.win, &prop, xw.netwmname); - XFree(prop.value); -} - -int -xstartdraw(void) -{ - return IS_SET(MODE_VISIBLE); -} - -void -xdrawline(Line line, int x1, int y1, int x2) -{ - int i, x, ox, numspecs; - Glyph base, new; - XftGlyphFontSpec *specs = xw.specbuf; - - i = ox = 0; - for (x = x1; x < x2; x++) { - new = line[x]; - if (new.mode == ATTR_WDUMMY) - continue; - if (selected(x, y1)) - new.mode ^= ATTR_REVERSE; - if ((i > 0) && ATTRCMP(base, new)) { - numspecs = xmakeglyphfontspecs(specs, &line[ox], x - ox, ox, y1); - xdrawglyphfontspecs(specs, base, numspecs, ox, y1, x - ox); - i = 0; - } - if (i == 0) { - ox = x; - base = new; - } - i++; - } - if (i > 0) { - numspecs = xmakeglyphfontspecs(specs, &line[ox], x2 - ox, ox, y1); - xdrawglyphfontspecs(specs, base, numspecs, ox, y1, x2 - ox); - } -} - -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 = NoSymbol; - 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); - if (status == XBufferOverflow) - return; - } 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; - } -} - - -#define XRESOURCE_LOAD_META(NAME) \ - if(!XrmGetResource(xrdb, "st." NAME, "st." NAME, &type, &ret)) \ - XrmGetResource(xrdb, "*." NAME, "*." NAME, &type, &ret); \ - if (ret.addr != NULL && !strncmp("String", type, 64)) - -#define XRESOURCE_LOAD_STRING(NAME, DST) \ - XRESOURCE_LOAD_META(NAME) \ - DST = ret.addr; - -#define XRESOURCE_LOAD_CHAR(NAME, DST) \ - XRESOURCE_LOAD_META(NAME) \ - DST = ret.addr[0]; - -#define XRESOURCE_LOAD_INTEGER(NAME, DST) \ - XRESOURCE_LOAD_META(NAME) \ - DST = strtoul(ret.addr, NULL, 10); - -#define XRESOURCE_LOAD_FLOAT(NAME, DST) \ - XRESOURCE_LOAD_META(NAME) \ - DST = strtof(ret.addr, NULL); - -void -xrdb_load(void) -{ - /* XXX */ - char *xrm; - char *type; - XrmDatabase xrdb; - XrmValue ret; - Display *dpy; - - if(!(dpy = XOpenDisplay(NULL))) - die("Can't open display\n"); - - XrmInitialize(); - xrm = XResourceManagerString(dpy); - - if (xrm != NULL) { - xrdb = XrmGetStringDatabase(xrm); - - /* handling colors here without macros to do via loop. */ - int i = 0; - char loadValue[12] = ""; - for (i = 0; i < 256; i++) - { - sprintf(loadValue, "%s%d", "st.color", i); - - if(!XrmGetResource(xrdb, loadValue, loadValue, &type, &ret)) - { - sprintf(loadValue, "%s%d", "*.color", i); - if (!XrmGetResource(xrdb, loadValue, loadValue, &type, &ret)) - /* reset if not found (unless in range for defaults). */ - if (i > 15) - colorname[i] = NULL; - } - - if (ret.addr != NULL && !strncmp("String", type, 64)) - colorname[i] = ret.addr; - } - - XRESOURCE_LOAD_STRING("foreground", colorname[defaultfg]); - XRESOURCE_LOAD_STRING("background", colorname[defaultbg]); - XRESOURCE_LOAD_STRING("cursorColor", colorname[defaultcs]) - else { - // this looks confusing because we are chaining off of the if - // in the macro. probably we should be wrapping everything blocks - // so this isn't possible... - defaultcs = defaultfg; - } - XRESOURCE_LOAD_STRING("reverse-cursor", colorname[defaultrcs]) - else { - // see above. - defaultrcs = defaultbg; - } - - XRESOURCE_LOAD_STRING("font", font); - XRESOURCE_LOAD_STRING("termname", termname); - - XRESOURCE_LOAD_INTEGER("blinktimeout", blinktimeout); - XRESOURCE_LOAD_INTEGER("bellvolume", bellvolume); - XRESOURCE_LOAD_INTEGER("borderpx", borderpx); - XRESOURCE_LOAD_INTEGER("cursorshape", cursorshape); - - XRESOURCE_LOAD_FLOAT("cwscale", cwscale); - XRESOURCE_LOAD_FLOAT("chscale", chscale); - } - XFlush(dpy); -} - -void -reload(int sig) -{ - xrdb_load(); - - /* colors, fonts */ - xloadcols(); - xunloadfonts(); - xloadfonts(font, 0); - - /* pretend the window just got resized */ - cresize(win.w, win.h); - - redraw(); - - /* triggers re-render if we're visible. */ - ttywrite("\033[O", 3, 1); - - signal(SIGUSR1, reload); -} - - -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 'A': - opt_alpha = EARGF(usage()); - 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(""); - xrdb_load(); - signal(SIGUSR1, reload); - cols = MAX(cols, 1); - rows = MAX(rows, 1); - tnew(cols, rows); - xinit(cols, rows); - xsetenv(); - selinit(); - run(); - - return 0; -} diff --git a/suckless/st/x.o b/suckless/st/x.o deleted file mode 100644 index cde21ef7b41cff1efc6dedba8cfc10b96cf57026..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 86904 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 SZ2!E+r9*sHpSA}nR{jgbXT|dX