From 50aa3cfaa0a47a33e5fdb9f1694a76fe62837936 Mon Sep 17 00:00:00 2001 From: kerem Date: Mon, 2 Jan 2023 14:48:17 +0100 Subject: [PATCH] added custom version of demenu need to write the setup script for it --- linuxSetup/common.sh | 3 +- linuxSetup/new/1 | 0 linuxSetup/new/2] | 0 linuxSetup/new/install.sh | 51 + linuxSetup/programs/demnu_custom | 1 - linuxSetup/programs/dmenu/Makefile | 64 ++ linuxSetup/programs/dmenu/arg.h | 49 + linuxSetup/programs/dmenu/config.def.h | 40 + linuxSetup/programs/dmenu/config.def.h.orig | 33 + linuxSetup/programs/dmenu/config.def.h.rej | 10 + linuxSetup/programs/dmenu/config.h | 41 + linuxSetup/programs/dmenu/config.mk | 32 + linuxSetup/programs/dmenu/dmenu | Bin 0 -> 48472 bytes .../dmenu/dmenu-alpha-20210605-1a13d04.diff | 267 +++++ .../dmenu/dmenu-alpha-20210605-1a13d04.diff.1 | 267 +++++ .../programs/dmenu/dmenu-border-4.9.diff | 25 + .../programs/dmenu/dmenu-center-5.2.diff | 104 ++ .../dmenu/dmenu-dracula-20211128-d78ff08.diff | 27 + .../programs/dmenu/dmenu-highlight-4.9.diff | 94 ++ .../programs/dmenu/dmenu-lineheight-5.2.diff | 106 ++ .../dmenu/dmenu-numbers-20220512-28fb3e2.diff | 89 ++ linuxSetup/programs/dmenu/dmenu.1 | 202 ++++ linuxSetup/programs/dmenu/dmenu.1.orig | 197 ++++ linuxSetup/programs/dmenu/dmenu.c | 939 ++++++++++++++++++ linuxSetup/programs/dmenu/dmenu.c.orig | 887 +++++++++++++++++ linuxSetup/programs/dmenu/dmenu.c.rej | 28 + linuxSetup/programs/dmenu/dmenu_path | 13 + linuxSetup/programs/dmenu/dmenu_run | 2 + linuxSetup/programs/dmenu/drw.c | 452 +++++++++ linuxSetup/programs/dmenu/drw.c.orig | 450 +++++++++ linuxSetup/programs/dmenu/drw.h | 61 ++ linuxSetup/programs/dmenu/drw.h.orig | 58 ++ linuxSetup/programs/dmenu/patch.sh | 9 + linuxSetup/programs/dmenu/stest | Bin 0 -> 21544 bytes linuxSetup/programs/dmenu/stest.1 | 90 ++ linuxSetup/programs/dmenu/stest.c | 109 ++ linuxSetup/programs/dmenu/util.c | 36 + linuxSetup/programs/dmenu/util.h | 8 + .../raspberry/programs/vim/_vimrc.forWindows | 155 --- linuxSetup/raspberry/programs/vim/init.vim | 144 --- linuxSetup/raspberry/programs/vim/instVim.sh | 68 -- 41 files changed, 4841 insertions(+), 370 deletions(-) create mode 100644 linuxSetup/new/1 create mode 100644 linuxSetup/new/2] create mode 100755 linuxSetup/new/install.sh delete mode 160000 linuxSetup/programs/demnu_custom create mode 100644 linuxSetup/programs/dmenu/Makefile create mode 100644 linuxSetup/programs/dmenu/arg.h create mode 100644 linuxSetup/programs/dmenu/config.def.h create mode 100644 linuxSetup/programs/dmenu/config.def.h.orig create mode 100644 linuxSetup/programs/dmenu/config.def.h.rej create mode 100644 linuxSetup/programs/dmenu/config.h create mode 100644 linuxSetup/programs/dmenu/config.mk create mode 100755 linuxSetup/programs/dmenu/dmenu create mode 100644 linuxSetup/programs/dmenu/dmenu-alpha-20210605-1a13d04.diff create mode 100644 linuxSetup/programs/dmenu/dmenu-alpha-20210605-1a13d04.diff.1 create mode 100644 linuxSetup/programs/dmenu/dmenu-border-4.9.diff create mode 100644 linuxSetup/programs/dmenu/dmenu-center-5.2.diff create mode 100644 linuxSetup/programs/dmenu/dmenu-dracula-20211128-d78ff08.diff create mode 100644 linuxSetup/programs/dmenu/dmenu-highlight-4.9.diff create mode 100644 linuxSetup/programs/dmenu/dmenu-lineheight-5.2.diff create mode 100644 linuxSetup/programs/dmenu/dmenu-numbers-20220512-28fb3e2.diff create mode 100644 linuxSetup/programs/dmenu/dmenu.1 create mode 100644 linuxSetup/programs/dmenu/dmenu.1.orig create mode 100644 linuxSetup/programs/dmenu/dmenu.c create mode 100644 linuxSetup/programs/dmenu/dmenu.c.orig create mode 100644 linuxSetup/programs/dmenu/dmenu.c.rej create mode 100755 linuxSetup/programs/dmenu/dmenu_path create mode 100755 linuxSetup/programs/dmenu/dmenu_run create mode 100644 linuxSetup/programs/dmenu/drw.c create mode 100644 linuxSetup/programs/dmenu/drw.c.orig create mode 100644 linuxSetup/programs/dmenu/drw.h create mode 100644 linuxSetup/programs/dmenu/drw.h.orig create mode 100755 linuxSetup/programs/dmenu/patch.sh create mode 100755 linuxSetup/programs/dmenu/stest create mode 100644 linuxSetup/programs/dmenu/stest.1 create mode 100644 linuxSetup/programs/dmenu/stest.c create mode 100644 linuxSetup/programs/dmenu/util.c create mode 100644 linuxSetup/programs/dmenu/util.h delete mode 100755 linuxSetup/raspberry/programs/vim/_vimrc.forWindows delete mode 100755 linuxSetup/raspberry/programs/vim/init.vim delete mode 100755 linuxSetup/raspberry/programs/vim/instVim.sh diff --git a/linuxSetup/common.sh b/linuxSetup/common.sh index 1e505ff..54f3053 100755 --- a/linuxSetup/common.sh +++ b/linuxSetup/common.sh @@ -6,6 +6,7 @@ tmux \ git \ fish \ mc \ +wget \ sudo \ unzip \ dmenu \ @@ -36,5 +37,3 @@ elif [[ $system == *"debian"* ]] fi echo $system - - diff --git a/linuxSetup/new/1 b/linuxSetup/new/1 new file mode 100644 index 0000000..e69de29 diff --git a/linuxSetup/new/2] b/linuxSetup/new/2] new file mode 100644 index 0000000..e69de29 diff --git a/linuxSetup/new/install.sh b/linuxSetup/new/install.sh new file mode 100755 index 0000000..d01edb7 --- /dev/null +++ b/linuxSetup/new/install.sh @@ -0,0 +1,51 @@ +#!/bin/bash + +common_programs_list=(\ +htop \ +tmux \ +git \ +fish \ +mc \ +wget \ +sudo \ +unzip \ +dmenu \ +cmake \ +make \ +gcc \ +python3 \ +pulseaudio \ +pulseaudio-alsa \ +alsa \ +alsa-utils \ +exa) + +os_list=(Debian Arch Raspberry) +os_list_count=${#os_list[@]} +answer=$(($os_list_count + 1)) +main_dir=$PWD +common_programs=$( IFS=$'\n'; echo "${common_programs_list[*]}" ) + +echo "###########################################" +echo "# Wellcome to my Linux instalation Script #" +echo "###########################################" + +echo "Please Select your OS" +for i in "${!os_list[@]}"; +do + echo "[$(($i + 1))] ${os_list[$i]}" +done + +echo $answer + +while (( answer > 3 )) +do + read -p "Select your os or ( $(($os_list_count + 1)) to quit ) " answer +done + +#Checks if the goven progrramm exists. +if ! command -v foo &> /dev/null +then + echo " could not be found" + exit +fi diff --git a/linuxSetup/programs/demnu_custom b/linuxSetup/programs/demnu_custom deleted file mode 160000 index ba1a347..0000000 --- a/linuxSetup/programs/demnu_custom +++ /dev/null @@ -1 +0,0 @@ -Subproject commit ba1a347dcaba055f824161007dfee60db3ea785b diff --git a/linuxSetup/programs/dmenu/Makefile b/linuxSetup/programs/dmenu/Makefile new file mode 100644 index 0000000..a03a95c --- /dev/null +++ b/linuxSetup/programs/dmenu/Makefile @@ -0,0 +1,64 @@ +# dmenu - dynamic menu +# See LICENSE file for copyright and license details. + +include config.mk + +SRC = drw.c dmenu.c stest.c util.c +OBJ = $(SRC:.c=.o) + +all: options dmenu stest + +options: + @echo dmenu build options: + @echo "CFLAGS = $(CFLAGS)" + @echo "LDFLAGS = $(LDFLAGS)" + @echo "CC = $(CC)" + +.c.o: + $(CC) -c $(CFLAGS) $< + +config.h: + cp config.def.h $@ + +$(OBJ): arg.h config.h config.mk drw.h + +dmenu: dmenu.o drw.o util.o + $(CC) -o $@ dmenu.o drw.o util.o $(LDFLAGS) + +stest: stest.o + $(CC) -o $@ stest.o $(LDFLAGS) + +clean: + rm -f dmenu stest $(OBJ) dmenu-$(VERSION).tar.gz + +dist: clean + mkdir -p dmenu-$(VERSION) + cp LICENSE Makefile README arg.h config.def.h config.mk dmenu.1\ + drw.h util.h dmenu_path dmenu_run stest.1 $(SRC)\ + dmenu-$(VERSION) + tar -cf dmenu-$(VERSION).tar dmenu-$(VERSION) + gzip dmenu-$(VERSION).tar + rm -rf dmenu-$(VERSION) + +install: all + mkdir -p $(DESTDIR)$(PREFIX)/bin + cp -f dmenu dmenu_path dmenu_run stest $(DESTDIR)$(PREFIX)/bin + chmod 755 $(DESTDIR)$(PREFIX)/bin/dmenu + chmod 755 $(DESTDIR)$(PREFIX)/bin/dmenu_path + chmod 755 $(DESTDIR)$(PREFIX)/bin/dmenu_run + chmod 755 $(DESTDIR)$(PREFIX)/bin/stest + mkdir -p $(DESTDIR)$(MANPREFIX)/man1 + sed "s/VERSION/$(VERSION)/g" < dmenu.1 > $(DESTDIR)$(MANPREFIX)/man1/dmenu.1 + sed "s/VERSION/$(VERSION)/g" < stest.1 > $(DESTDIR)$(MANPREFIX)/man1/stest.1 + chmod 644 $(DESTDIR)$(MANPREFIX)/man1/dmenu.1 + chmod 644 $(DESTDIR)$(MANPREFIX)/man1/stest.1 + +uninstall: + rm -f $(DESTDIR)$(PREFIX)/bin/dmenu\ + $(DESTDIR)$(PREFIX)/bin/dmenu_path\ + $(DESTDIR)$(PREFIX)/bin/dmenu_run\ + $(DESTDIR)$(PREFIX)/bin/stest\ + $(DESTDIR)$(MANPREFIX)/man1/dmenu.1\ + $(DESTDIR)$(MANPREFIX)/man1/stest.1 + +.PHONY: all options clean dist install uninstall diff --git a/linuxSetup/programs/dmenu/arg.h b/linuxSetup/programs/dmenu/arg.h new file mode 100644 index 0000000..e94e02b --- /dev/null +++ b/linuxSetup/programs/dmenu/arg.h @@ -0,0 +1,49 @@ +/* + * Copy me if you can. + * by 20h + */ + +#ifndef ARG_H__ +#define ARG_H__ + +extern char *argv0; + +/* use main(int argc, char *argv[]) */ +#define ARGBEGIN for (argv0 = *argv, argv++, argc--;\ + argv[0] && argv[0][0] == '-'\ + && argv[0][1];\ + argc--, argv++) {\ + char argc_;\ + char **argv_;\ + int brk_;\ + if (argv[0][1] == '-' && argv[0][2] == '\0') {\ + argv++;\ + argc--;\ + break;\ + }\ + for (brk_ = 0, argv[0]++, argv_ = argv;\ + argv[0][0] && !brk_;\ + argv[0]++) {\ + if (argv_ != argv)\ + break;\ + argc_ = argv[0][0];\ + switch (argc_) + +#define ARGEND }\ + } + +#define ARGC() argc_ + +#define EARGF(x) ((argv[0][1] == '\0' && argv[1] == NULL)?\ + ((x), abort(), (char *)0) :\ + (brk_ = 1, (argv[0][1] != '\0')?\ + (&argv[0][1]) :\ + (argc--, argv++, argv[0]))) + +#define ARGF() ((argv[0][1] == '\0' && argv[1] == NULL)?\ + (char *)0 :\ + (brk_ = 1, (argv[0][1] != '\0')?\ + (&argv[0][1]) :\ + (argc--, argv++, argv[0]))) + +#endif diff --git a/linuxSetup/programs/dmenu/config.def.h b/linuxSetup/programs/dmenu/config.def.h new file mode 100644 index 0000000..1d558ef --- /dev/null +++ b/linuxSetup/programs/dmenu/config.def.h @@ -0,0 +1,40 @@ +/* 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 */ +static int centered = 0; /* -c option; centers dmenu on screen */ +static int min_width = 500; /* minimum width when centered */ +/* -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" }, + [SchemeSelHighlight] = { "#ffc978", "#005577" }, + [SchemeNormHighlight] = { "#ffc978", "#222222" }, + [SchemeOut] = { "#000000", "#00ffff" }, +}; + +static const unsigned int alphas[SchemeLast][2] = { + [SchemeNorm] = { OPAQUE, alpha }, + [SchemeSel] = { OPAQUE, alpha }, + [SchemeOut] = { OPAQUE, alpha }, +}; + +/* -l option; if nonzero, dmenu uses vertical list with given number of lines */ +static unsigned int lines = 0; +/* -h option; minimum height of a menu line */ +static unsigned int lineheight = 0; +static unsigned int min_lineheight = 8; + +/* + * Characters not considered part of a word while deleting words + * for example: " /?\"&[]" + */ +static const char worddelimiters[] = " "; + +/* Size of the window border */ +static const unsigned int border_width = 5; diff --git a/linuxSetup/programs/dmenu/config.def.h.orig b/linuxSetup/programs/dmenu/config.def.h.orig new file mode 100644 index 0000000..2bcf3ef --- /dev/null +++ b/linuxSetup/programs/dmenu/config.def.h.orig @@ -0,0 +1,33 @@ +/* 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 */ +static int centered = 0; /* -c option; centers dmenu on screen */ +static int min_width = 500; /* minimum width when centered */ +/* -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" }, + [SchemeSelHighlight] = { "#ffc978", "#005577" }, + [SchemeNormHighlight] = { "#ffc978", "#222222" }, + [SchemeOut] = { "#000000", "#00ffff" }, +}; +/* -l option; if nonzero, dmenu uses vertical list with given number of lines */ +static unsigned int lines = 0; +/* -h option; minimum height of a menu line */ +static unsigned int lineheight = 0; +static unsigned int min_lineheight = 8; + +/* + * Characters not considered part of a word while deleting words + * for example: " /?\"&[]" + */ +static const char worddelimiters[] = " "; + +/* Size of the window border */ +static const unsigned int border_width = 5; diff --git a/linuxSetup/programs/dmenu/config.def.h.rej b/linuxSetup/programs/dmenu/config.def.h.rej new file mode 100644 index 0000000..a9e0cab --- /dev/null +++ b/linuxSetup/programs/dmenu/config.def.h.rej @@ -0,0 +1,10 @@ +--- config.def.h ++++ config.def.h +@@ -2,6 +2,7 @@ + /* Default settings; can be overriden by command line. */ + + static int topbar = 1; /* -b option; if 0, dmenu appears at bottom */ ++static const unsigned int alpha = 0xf0; + /* -fn option overrides fonts[0]; default X11 font or font set */ + static const char *fonts[] = { + "monospace:size=10" diff --git a/linuxSetup/programs/dmenu/config.h b/linuxSetup/programs/dmenu/config.h new file mode 100644 index 0000000..715bdb0 --- /dev/null +++ b/linuxSetup/programs/dmenu/config.h @@ -0,0 +1,41 @@ +/* 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 */ +static const unsigned int alpha = 0xf0; +/* -fn option overrides fonts[0]; default X11 font or font set */ +static const char *fonts[] = { + //"monospace:size=24" + "xft:Ubuntu:weight=bold:pixelsize=26:antialias=true:hinting=true" +}; +static const char *prompt = NULL; /* -p option; prompt to the left of input field */ + +static const unsigned int alphas[SchemeLast][2] = { + [SchemeNorm] = { OPAQUE, alpha }, + [SchemeSel] = { OPAQUE, alpha }, + [SchemeOut] = { OPAQUE, alpha }, +}; + + +static const char *colors[SchemeLast][2] = { + /* fg bg */ + [SchemeNorm] = { "#F7774C", "#002b36" }, + [SchemeSel] = { "#F7774C", "#073642"}, + [SchemeOut] = { "#000000", "#00ffff" }, + [SchemeSelHighlight] = { "#ffc978", "#005577" }, + [SchemeNormHighlight] = { "#ffc978", "#222222" }, +}; + +/* -l option; if nonzero, dmenu uses vertical list with given number of lines */ +static unsigned int lines = 20; + +static const unsigned int border_width = 5; +static unsigned int lineheight = 32; +static unsigned int min_lineheight = 8; +static int centered = 1; /* -c option; centers dmenu on screen */ +static int min_width = 1000; +/* + * Characters not considered part of a word while deleting words + * for example: " /?\"&[]" + */ +static const char worddelimiters[] = " "; diff --git a/linuxSetup/programs/dmenu/config.mk b/linuxSetup/programs/dmenu/config.mk new file mode 100644 index 0000000..a2bcfa4 --- /dev/null +++ b/linuxSetup/programs/dmenu/config.mk @@ -0,0 +1,32 @@ +# dmenu version +VERSION = 5.2 + +# 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 -lXrender $(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/linuxSetup/programs/dmenu/dmenu b/linuxSetup/programs/dmenu/dmenu new file mode 100755 index 0000000000000000000000000000000000000000..1a1188ed901d1b4df77a3a53be27b90b96209090 GIT binary patch literal 48472 zcmeIbd3;;d)i!!0OSUsf&P2=*qJRT7#7P|DU?&KySaxJ^5)(U#8G<9rax9Q7*OC&4 zG8pUxPKDdFPzrr%oA#x2phMc1mr_P&APHp(fkH|OgrRVR8Nw6-6!bmMKKt0m!g}v_ z@BQa~_s0R9wb!%PUVH7e=Y39&udS-BwpuKTab+pzD&*!Z(vb=ok$;a2fK(`D$^_hJ zDFsS4c$>iV_zImMR=*BfN77u0XMr+ZJ_DoBlXO@ys9_-~(`CBmovgGZHLMp4Sn(BqACbQjazDAT3W zdD5Q-HT+2%`74wDOs5ry<5eNX^>4u?A8-NoHy3yT*n zm=lf6nJ-MBUGwl`H7;GgO0o7R1H_E<7R4g?F~E3PC2z!2b_#xUJJWwT{gvI{e`0R+ zuawIk%DeBO)^YPfA5eznU>eHsBF3L_(R@FClo9^1xRf4dhl_aYDt})2hY6z_5gu_B zBH^SFh|YWp4Wr>JGvK)>$Y}DHXORCcvKdW&eg=EGGvF^}$hRW{erE=I8sXH@?3oTb zUAjv~+@H%JKPCg-kiq`G4EPtwZ8UohXV71fp}g%G^jBxVXJ_!wUozm;8SK0+1CDGJ z7k=s2-!hde1MbLR|GEr**quQShoRB@Y|9|upF#g~8SE*@pl3Gnb)`E2{H_do$}-?* zX3+l=;HQkD|KAz({3ZjwC_}w>LHB5WyDx*DM>6=WJcIqWX3+C&2Knh3@TLs->J0XO zJA<8$40`U(fS;Vf{`WKBFJ!Ri<_!K%X3%qW275lrP_92_!2gj!PhAH5%?x%vkwO2s z4D!ci(En@(J!%H|B^mTTltI2YgZ^z9>gE0n_{kaay(5GEeHrw;nE`(`gMNR8_Hb#$(lyKs>56R)@mSU9}Zy).)m(MXrlSkr-&9iCXE-H5FVb?bR_`I|2YZfcJB zyIMq!t3%PaKU~w%8c`bSM;ZWo)`U7*A{#xiSXZby9t*;%A+WA1(i!ZEA^-Y#XJ@1< z7Ojm0{4`E4*V0NORD)1;SCBE`NHjQPH?pe?`=e1`h$UR<4@HA|e!93}@~V#Yy3smp zl(90>u>twl2g7hnDAFO!uMKqs&DO$)VUydI2fJg^p~zg%Y)PaGH3{1yotr$U5vB3M zc(7|zgD|*$Q%8V`nTMzwkxO+171|Yvcff_LiJE0f<1&AzC;=dmzAl1N3B970%>|=p z+M8=5kt^bz_3&)RdXzrc0V}HEZoNW~MY|tfL3z6T?S7%MJ^-6KqDpnZ8*KH*!?F5! zb2Ju;p<;m5`D3EeTUwSxBH>}c8}AH<0%&M}D%<>B^tvz!{BnPLu+HBV6>*V{*3kM9 zDy6tL7>#vBHVvouw6rkFl*f?7uoW_~(%2enpxe7+Xvoo3vDPv|Y|nbx&4@G%@l0LS zjoyVO*NPs2w#~LfMsyfYI2;k?8_EnLr8KKW+F~dm!~z@qGJh=4rl4qn&P_^(zatV2 z2ZNnTw4)PM5^F_FOQ=IZ8}CAwYGQ{DT+tM0yP~Pp9||k2Y#+hyP)unLwzo$%1gR+& zxk4vll5nsC=>oA$ox!H&CfG|5|C4ku64k(BDC>hUY%qgLD2h7Vr1)cz5E5eZ8IZ$B zyC0Uo9@ruh2mH}spuKZQdkka9#$cDo137m4n_5F1{&46@SOwjBzeKKqwk`#IlzFyd zpb01&T4iC$MyZ=>X&)&pXe=q=es`e=cZo(yzC`e{aSj2ksHT8uMne#)gW>s<4=}V) zSz24Oq_S!LoU;}T1&2dt4Po==lyWS_9(u%o*hAw#-mT(paOqNJIkQaGP%1rzp~;Zf zsS#%z%Eyq)lDUt}PtU=yh_ZJ44Ag?%`T`sh80Qi9eE(K#)9uQ+5}OhVP2i5cM)H#d zpQY4GK7K+7M+jDBEqGqWxrH%Lxfbhqk326j@cr^UYv1*Hyn!3Mk~Xh7o26VDK273z zX}BSupN7wn@~$-ebcq+H;d3QEFAYCi;$><0c@nQk!wq>~8opG@*QMbrB!1tudbxRa zf{GZr22A*gL#U$cGvTM1@cky-IMQSEK@)zSN&c`2Uu(j(>vaap8>PgAA2H#RP53%l zE;bLp3GXrCvZ#7&k4|zxn1^xY_UIwvRs#gh>(LqFS$a_1^LuoLIF?F7m#aq)5|>R@ z0EH%;zBaCTJ$i`p{25nSj~*gsv|S<>6MmZsKhA`2GvU)r_^(ZPz6sxM!jCuM_nGh$O!$BaKgopeGvPclGp_wTdWhwf zNAm(WXu@acBI177gu6_*X2NHh@FOPt6cc{Tgr91{mFskd_7s@#ToXRagy)&?(@l83 z2`@C^E)!m4!V69KnI?Rm37>7k%S?E&39m5Wb4<9;gwHkMbtatW)yCCm!si+wU|1EhN`E7##1$izNlUoJl027y$qK=Dk>}DcIZyDHlOIpsCHQ9YT>2;T1b;DkF8z{<;8&98k}rAW zD*&_3C(or`^045SkmnLFxnJ;$$a86z91#3`@?5efw+sFZ@>9rf6Z|RUxwK1e75oY0 zxui?>2!0ZIF6EM)f*(tsOSt4Z!CT35>6WY${O9Q2ZCtV?D+K=`d2V5n^927k`IE@I z1pgX&F4>ZKf`5_x$>bHmA0R)2{E;tN{=boTkv}Z>o#bbd-!J(4$)7@gK=6Mi&m~xL zyWoFIo=dOfHo^abJeOR_t%CnCd2X$eJ%axMc`m(@or3=kc`mt<>jZy2c`mh*b%MW= zJhx!U3c+`g=aMTqPwGr{&m}~%6TD}QXLVJ{ zQO_!m`lYAA^B@P_RrNmgBj0uJXc%={dzoKt{wd?QTzi7qsu z~+lri_O&|*=BslLQjXXa{b@2dSn zERT|bVL@T$-*v$mx?m2t`#GhQ?{_ZQsoEc4l6k{PUZZ)x7@_+)v<=n%Qwrt`3qDA} zO}gMjU&4E4E=o~DyI&LD7LNQeg&NX?c2mSY60rWOoLH z1~*9GFQSA7Tj7-<2^S?Aq{K;-*pnu4^kPWNml9uLu+i>JlL(_wgL!Bxvk+S{pzXwn zI5@6K{r6zD=V3TR@uYSquSboRq|kQWTnrU|f}vPnuy#uAFae40qUsPD+Ta*%$!D}O z_F73w%Rvy1+e#rM7!S$YD7hAy_!85*i6`7il0ffaWTx7$BD3RgjxVcM6Ao(2^Qpzv zLPIJ(2I2V#4^AyPP;ykuL5|Q*KXAeG8Vs7kaQ`g@`i|IEA{e?GM!XRBu6@ zufORXfj2}eA5k!<6fc@)e;CwnY z;XY)5tC*i^C$Al+$NdQ5#MHHoBI15B6B@`QmcmP=GYM4W_6}G@H|)RAqS`Geq4SUE zk|M7G9|}9G=UgS`(zamA{;Lg!s(TXlJxF@{r=KOJK7>Hg&VJi`)qXF6a9AZtxqX4) z+-?x(=4Uu)^~VZkYwe$~B|HjGJNq6WnsA>0k=p*2g2LMVaKXG<^|e~{J?#^CH!=N> zYZPVkp-m^Cs};=iEw;Y}<6{eay~ixh&G%x-I9Ry&(t_E}oA~mIA+rlI@o6Q8lGg$3 zbzcD$%BCaWA7tGlY3y~j!Ix`cPk}FSDHQiN6qGGfKd4ocFeicZwf)|L3ZMG2_LS%& z&drZvy{czWZf}NwbMxZ@aSPv~8Q0MQBzX6j=u|hb^%3(X!UeP0C70Q}iCYR91$0wE z18B+7l0)9a9R-&nTxHo=WqI6N{+{!u9w_d0-@^&Xsd9kYoN{jdZ`w{XJr|!4 z^i>k|86S+DU5B};p|-!apn|raqm{xAY${wR=~anX!AXg$3S2aTSvC~R_V!m>y!|UI z-tuR!zO+Vt!uiNVuk(?MtiIkI<2}wtyahJPesB4J$GKvl{6lB$^F{mbhXsn$w-d1q z1=(K9i{A3TA^I6l`4?Vi?JM4*7d;P9#N+fmiw1;I#FpAM_%mPNP{Mu?v#sxnL*spx zLDu^X5Ywu$g3q#Fk0Sh4%Tg3KZ`VxF<_egVrtWY)QlDG?w`&Tt69l*#;QeOVECHWK z*`3ZuDsx3QQl~BgP_!Sd6X{V5bhVQZJN8WbbVTTIwt!uOb1Bm6uH~{yKP{`o8w~hnS{6LIPC83StR&BZ+JT+Tc+!E^r{5Cvdm_ER=T=R>TSW zQ&@-41$}fuWgcB{Erdq6V77p{B2jn9CL_EsMc{S7M|j~&C$*GQd?y+mTbOi22{7RZ zx&TpZXlL4|0fiTUq5M@P1HEo97e`(S#U~7j9f40MBUPgOti(j=I}k1r;S(j1m*CU`coaPWzN3MpfKxkUGg~) z^wC1BPdS})q6*U;vVZ?2m zZB%`v{%Zw%R|`-dws&$q&ei^ea;du#-h#&7V^(J$-;D0nvN+k?uo@c?^ut&-{)Q-!aow>F%0+laPs2Z!qL^| zo*+`+&e(+gRF=NqeG>_t60^fYe|RsII@%}fusJtxB(!uYyNq@xVvy>;FNAn`Ujd&f zIye6e2MXG05O@R@DT6QeK3I^42*hkg47$}=X!j=UIUsDraC(di67IDintC#pzn4G~ ziZ7Llk3o~OubPTaz)Y1qhtcj_QI?Bfxt2h)aNc{1?(c+h)K+J8ZZ1bD*}QUnfsc}W z^$bp{ac)Urz3S`L&IdQwdBX?f`X^k;g;&6KozJo_b-1?Q{T<|-j3C>MMLze1BBKxJ zV0XO;zb(STb$vI$nB;G%#(k@Z+$SP$6X6{QC;J(R@qtxCUC9R8FM$&YRGNSkf%yP> zUdwg%6)~pw*iv|pYGoo;Z_;5(M6;4#n)0D@lJA%R)_n4i383}8uYG~m$rdKgaSZhh zl>MVgb|rzI5=hw3u7e%@Q@K0dW3yt2Kvj!P04nlCfLM5Z`m*+`X+XnB(ff2t`z33l z-yMRJJnQToCPMOn7_XnYT<(c4pj|X%?UhL=(Z579(wb2vW1Tl}{{UBfSqv2c+x0%n{?uW^ zhjnz>72FNUI$KTPViT~6Kn;OnwhE}scHU6NTJE3v{0Nn9HWKINsVIH&=S<-K8Gwzm zeeRnWvE|=F3C95_ndH3T9rFECe?L+Q8H2y@`rlT$93o)5bZcI5Zkxw(9a2F5$bi{gs>8O2r3ecOjKa^ zXYXMU1NDo8cOv3D1hqLj%;5$bjSn1FNh6WppM>~=kYv+ora3A-4Mk$nfqsCEsfO}@m04@k;= zdCtw;_aPDS8fl>Iqm<#3A~$2DS8RhHZ!sQr2) zA=g!VEAny2k(i#-PZ`%g^=S}RY3w+?It$rk;V0@o4U)a?-8?u$KjCscVV`TL93#}g zsWj~0w0N=o1V*a%aUjmk8Zp)G0HbxH2PR)2kg&fCFNs8V3XS;>r)E&_70sIz?a(ch zyzEn75Z%lE3FJSzQw$z|&x4w+Le13gQcd|SVzzK@ZiFt+Ds<2_fYCEc9s}cU2IINU zg7&bATaZR9VfqR>VR+q2ty)8FSXH4hc(}*%`8FSlo&E4wVf8E8(zg+f1s7`E?kjqE za2zc>g%)xZ_KNli`ZuQwpSJcbOf*l7fo0EPM~L}Lye#AFdlVcD+5`8&lovp>KSMP6 zdx7gGaV@?x^`kjw-;a>7R>EAl#_?fG)mMz!Ui<1zq&b!AyYgMm&F^9Tkvtt7wnNTG zJT`2JzGdY`Xg_v3JH6%D{M7Cr-U>M%xeyzn5546tBKp~?@~5htwI6tkKJ+|{+_({X z9vh+ZW7pW!z3NA)J=|L*k7r(})Xi5juU4)huiMRY#QWel<&w3YOFe5nmwB3YIcIQ> zfXc!1qLO!O)Mqa9sjvBZ-#Aj&fJHk-$9}gTT{<;2QKcv!x6U!-fq&qGQ~K?1lawEe z;rPd14Iz4aOzN<6Mi2EO13@9bL&%rjPg3-iPd(z>@!om99mleKmOZ{_zKTtOf(cSV zZt8HWbB1>~J?-mp{~l?T_*tvasozE46HqbF;~Y6P^&lWE0Au&q`ygmpyKC6q zU9H1mKJTKwe#&^^WZaIVjC?7CM6klS^i_23?R z1E%ltH2f9qSb5liTUE&$II8V^r>+I(uJVu;2QgfKb18!TbnZuYC+vS>!4vKukYIgm z!(uR>)#1YVmYqw(leBEKO)QVpsdftC{6gL3EpI8XU9;Mkz`EJJ8nE`QH_$@6b1m_* z*52-ul~{={F*#8=1$C7uE!OjxBa%;j1a497f5Kh6>R%|TYX1qsgJW=phclpx!T;n& zvl;5(&mSO0iI>40A0Xrl*satdPTsE95QQyD1q=%#GEoPyiaK@b8cM2m9|_j8zM-BF zvukIfo1kmfv90a$tj57M8WjA*eZV`e5uVB~8Q^9pujD9l|IcbD6Mj=;1-U$lj3roC1@s!isQfOA9Igkix6jBWK4_~7V? zx}B&JZ(*vZY-~IWqcrkdAG#9U+AiY-KFbB z%Tr&3*LS>z+8dvju&-m|EkEdUF5RWt>&d_=`DUjahjD<%B}NC_CE874x;M~rdfl(W z5m^0s3-T(KIN@e&9pX(7@L+;FTRhlx`yhc~5`!Zo|H_+w@EEw^Fv5D>-JsW9XP$N? z@Q~S}e`)s%x%~*1AA}b#kqu{6ePVhRIyVOQG0s0u-;MaeDALS802|s$6d*DEw_v=9 z;{PDYD&7jBErL3T9Ya!xoeVK=qO=P!9;`;E>yd{L>CGy=6ewgi2Vvr)-lC7Rukvw< zF}(_~w`kB?^m@@?(JnL<8-S8`(GfnP(#;2AGkV?YE8*^hy%~){6r+*i5M*7#W&}aIqrXkU7A`#Xe zs=c2w~01{YH{aL363SPmU>(J=ry+K z(l=m(uN)YM6Zd=IN*=o(^99a-U&ok)K6F(8?kNT8nRSlnOp}Al8PN54vj$!;m7sKLZKJqeI-dB*1cwv0Gdkd{f zxX%W0-ZIcTkmb7#JMNv@olcej7NN=xAX1ya9Q#XGh*ij5?PRj@_;&$1Mor>sl>WWc z)F(YiD9%otef&B?4W_jk^_B0Sn%vJU0bjKD#@d4M%L1t-du(Nhjw{;7$DwwoE=D%r zK@>WVx4*#3gzA)nB{z;Q)Ak=urNmj7&vMZFow7X;w-w-A%B#Lsgz5alYoiH!o?eo6 zr_jH5aG4)BjyQ5ERxw||<#$Yg`m zsX#AR>b>xNo~M7o6u|jKd-^w|w0Gc~#*5j>&xT=G=Xh^CCrdk1gx}{r%!Oc0(e9e^ z-BBDMm7aj@cS$O_mwU_pbF$#45rIYtU$bSVQok<&!uVR-ap? zeu8I~U!XDO`^u;9qq7t4O@frJ1c^=Q{dPXE(q&-c+>0$hK>Pay_Md+sc)6m!CtR62 z%bTzt0&+VvoDE8MCgD+!xahN)B9ZNlds5A&(eQIVZXQ0-#LyY*5%x4)%vDZ( zPni;14s{!aI`>wJjS*#;00o!h=v^;M>B)#e2IGLTJnO;Ysm6ps(2@fzQ5n_|Ydve# zUA^w(&r{%=iI@TYh-i*j`#|Gk5!j1>r|4zm_$7p(hH>kq-GFEiiwk;?PwmwJ}^vj+DeYQik*m_m)EwGf8nqm;yxD+?ZxOhyn-t=JS7 zBKCG@@brgsQbkXC%RhA0*no_<^pp6j*%!FVSR_p)nUvTCcNW`g6I8=DVTXgtx zp{T#ks=Yc6agCmf;M{v5CZssV*-9Q8#Ntluxnj1|j=_&0aVI3OFs1vQzFznriy6$8 z1FpdjYWrvHY2wiF@M8)cGPM%(eXaVIw(SrWOzs_Sps{kyU=>2gyT0<`IS4uX?y6UTZG^c{3i_3fg6XndE%muSx$dLJy8}!IyC^=3?ie5sE za?sUIVJsIo@6{yE&6>InVnxq;i@qw_qg{?YnEG<9`f14lG|N+Pap9gJS%Slc6vc^r4hw&*t9?&Z4X z)6a?qLC0$<^j!`ePazfsUsbfri-GYZbbNGe_TOSeU}zkJCW9d^QToX_LfdhGweO9g zM{m{@8=2k)7U?J_Mr7nBa+)D5cfSN2uF0}rO2v;RrqeFXD$F=@`ci^P4<4zz?}4ED za>)TE>*R@mLeJHw!_Sb*paHwIpKoWbC(+KY@{}IGq+RLL`<{D{+Fb z5yAVF9${$|VePyBV5__8B?Ze}&GRCd-Y@L&cd>R(xPL*Vn^Q5Y3~V#7jCZjwjKyPS zEgyn|FKH7gpKx2LXl;&AdNRUzK7Io_0%G#OHD0ndSq8z>UhJxizYC-u50STku5@nx zA)9%x`#f+;>nfTT7i#mPJF zO#UN1`6cG$ztxk+yO8|(#Ynyn8I(gp+bR{$)K4=mW@6R;XUL#O-3@{R#jJ|Hqw%MZ zVGdFNzGWDWxj6S-Ak|OSl}y!@v_ougKMK!Dt6`N-pRX?DBc{@x#Y${WRmr>6&U;&m zm8!lsVy9@IK+6*6y;IKgC6vVYtxL+sZ;RV&QjZS4h?*IEvg8ov*@OC2i0KBCsTUb| zR@e5I?#AprwCTaBr_7bM%qaw*ZxIW%<;aE`6;xt?c5~_SZY-FX&KGDr7)LFrw#N`I z-*xr;)Gl@UqX^@fr*FsWn6F>fPG-fb_Foa@rUw|D`EQ)mX%;S(684)Ag&ay!=c}_1 z*Q9o9U$BX(j}G2ilB!bQ;#02Ns?BeRP53&hNt9{FUZ4ni4BM;w@suJcA!=bAoicg0jG+)T*>k1 zRII%sbc1)1g%ZP}&i+qkrt;;Ls$850s>RO&s8vgMgDjKMj|@rwK}5FY)d=ZYwfL6; zm~|@%l>LZAwexL3kZ*x#&$4}E#l}`;Ua{TDD!OiW8DR5@P3*@pVg3+l(F?xBG|89E zH2d=qw;c4jd7ihi9(gT>#Qh4A`-*lh@1O0e?O%|^`S;KT{pXy9Il$+v*@Yibwv_|$)Vbmt{&QNqvRRektNzKH3>uws|`89du>{~{lL=%4Tzi03=DJde85 zGxKj%i>6GBkNI@}%wx`b2XJhc+Ue{4+#Y`!8LP+P$!98dx>#o>uFWT7*V>ymSd@wn3vS**}lZaGIfoOJMJ;Q z#I?EF7}5K<(f)R>SACWCRu*cN!h*^&`gxaW2`tv+JdivAofAr&eG?f_zkokbr_XyH z0*h_xGQ3rI{SgFf6047KgW3h3G7EOrT&;!Xa_xX|rbgWx$2&9byizFYFZ~mS8|(;Q zLqkaZClrXoU#3xnp?aD)+LZg11tP(3^aOum%RvUU>Q|cm0H&}Iheh`T9K9+r!#-RH zW%?*yjCr5uW2}g}d>pnRMsbcCmJq|0mdzDqVvWs{HBH4X8%qe>>XAV=()r+OkTw@a zKaAuxz3=5FbJ%CqE9wTV9Isdzn$b?NzhPw@C)=A#!!swndBw3b+@-@C%S4TA6wZlO zur%5UqDg+cPJ75m(2c^u^PUE{9NSqqca`&&o%Ol<<4Z+-V>a?7*33giyVS?2utwEt z)mOE3(4-$_y$QeEi-o#&CYBLCY(aOto<9rf72g=N(zT+Ci#o4SpVue2-ghu0A7yU6 zpIMx@?nGvF*orehUyb^yPks7fo@3(O9Bn^!V%(g^^NsgBiSd7^Nlba4-Fe5GHeU*d zk(df_R;!gE$J+9LvDN2xJqMpb`R=^oGi55b`P7Yd!gCDyjE1QGo!hZ`G@uGdIs2|h z-gr&S$4w)$-r!L`#%Y09eY8q_8f`CIoRwtx5@>-egg3SIN;!l5AYI?QNAWIUV9K4IJJy%;;pDD9@SRBIV3xQSAweGA*_DQqxw@Ynt6*( zE{<5lHdo(zcXJ-t4#%Ry&K~n2SJ?AdceKhjbUfYWRR_lG8?!%F$GtBgR6?trMwzJN}hj3m5v9 zI3GTzOcPJ!#^AUdZ!{_Kl{KloROGAaP1$1hW#ym6|Aq%0Yf+f<7th{zRVkP}$y{6L z>))&t!e8zb_6_%anSwdaYHe`pLk#Ns_rcs{>SuzlO+@ReO3-RCm%IvZc`(W0gm#4w zF9PObkM32G6JCSDW>T1^9m4dVu#d$nIKm>YMJu-zbS;N(YzV_83lg>hZxKUf0P{f4 z8Jt^#{Un`pFY#^$ z7h8eO&VGgU1zIN_j@ti%vn0{@D_HNy;2fy+YJbO@3m0F+W|5Ee_%t8AQ>XNU3 z)vXjw3I|)xzPo{Wdfvhl>7R?(LtGbQ{S8BxsUNcmyOO8!c%C`$K(4QRfBZe|$lq|L@E)26_BSnU9z$c2P654c!w<)CS&Qais>1V=+4*1 zB2_I0%Kp+K#MWR-gx%4jPvMPzDCc_P1i+Y`w4Xo0hh|uc;`O9|v26hR5>&2R_`)-q zVT1Np6clX{&x&Y!p7t2hQMN>wgQIT@(D8A4RVSxnkP<^h0Ge=UipCbt$IiZBHuHA> z3a5OiQf)JI4mJ+2KeU7>f^4mCVx5RJ{GJjlm8$bS@En#Twt^bsLRD{KCV@}T*(*=fVGg@dQ=S%&@1fNFmjZ13UoeCq6-?1jmtv{uwC zP69-&o&?<(o!I`JRki}vR>0g7Cly!@iU}Ldq75_36fqxQ0euw;f*GaTG!u$>f!i32 z^RXG6y-q-Xe@r|U#@Xh9)hK@tUuM99X;;a>u3hyd1M0J!>SUTznC3)Gbv{yEd=c$19`o?Y01{5e!W>HgF~B{Xi)z*uvn62(4!_`~;z6e`aWzJQH?=$V zB4ZW%GqGw${L$F)n6+_4i0L7*P{v~ukcHaSS83P1bC?YWlMF^?ET?v*?b3t%BZJuuah4iMiETbWg#6;2$j54?1FQ#j_Wz zaz86#ZrF(T6&!&C8y%ikaP-HFKaUUgSVGV#^JKJ3`vk?pIRqNo14td4jV?`tbG7h3 zl$Qf*&sABeMe)gxxR6H628vdH9$VqqN3d2_w2z=cUo3yNCzZNTt4Bki_xO)3ZpXS< zJA%RL;$1`kKD5{P7okY}&Gn53zVW~}9{9!s|HpfP-%<aQ%WuWaN^z@F98iiw zN<8XcA6(=Tk*-UMn_EL0)`Esz{Qg~(!8TW0Ftolc#&D;rvn$fxDZ;HCE`DB)aJvg1 z*bK!YU2Dg>%-1Ew9nG!)Kc`8lj@IFD)PzS(_(s>p5I=AkYFVokhn34(2dGQe^&>-*0{*k5pn4s)pJGlZ(oizoPlp*cDP#PmpKEGc(?_^F&Dn@ z=L)tr2V3w-!Symz7e4kUKdZUOHLrVCxLbi<7BULUnX);EZ2T?3mN~jRmCD+hx+N<- zE4|99hU&7W`i7M?%axe3DTz zLaIKtDI8QzZ7sup^OaNQm(BN|wNN>A;rz4b`xhvu&J!1DD=x^j2FlMagPgdCmzJJ= zw$j}iTePY<-Vuv0+9>MM-5d$GEb0t(2g6Z(lh8eX;Ua%WEQAjf`lIexS3J0=4PRV@ zX9V;0?$nMGj7}`(`7?(N?0=$u?A{sw47T>8$vuJi*KtDgF@ARBQ-t3l{K#JbdMSR) z^SAghJ;OK3@a>YC_3n|__mG}A^M4W8c5Drd-z(t91OEqPh)qYBr$YO{Uybv-`|w-y zTq^Zl{H*wW2L1)aUjuz*C`YE>d64ttcL#opk**8BHxYgbzXy=sNY{q2%j9P4*A=ch z)2T^B1jVN?XS?K3!KNvitE&~g)YXAcYc6t~J}Y|qSY@POC%-VNOH#-ci?}-VkChto zvfaC)oxwn;HN*x#Qib?tCB9**cWIG}GH1>lCDsPTA$(L*S0Czd5efJMxVOgv4|O5k zNWU(J4_uMDdkek7G@ zz$sb`_1^-%9Y@V~g5C+r_x}#y5d9s{L7cVE#vb(6gOCS(8}usBad_Ovf0|T`$BWN_ zJ^}h~(Cz=k@n;rxCodr$^f2D=S%4F+FkTD06f}r8sro?w0{S3mGu|7_g&l8#PRYj0 zt8b-Jg`mqoy`Wim{qiQz3qT(P-I|0veD^!h0?>bgR)C)Ob}AJH9RU3u=-)sGK%WDB z4)p3lY=7aazkuRZeP!-DsnoAQZ}<@T;h_3HP#@@rpq-#+eS|&&x)St3&#7=rl@rb3}y}Ah-a(!#JkgigGHBylO}O`Oa}0 zb9Wz7PkN)^>R+YomZ>w??-b84l_UQq_{z1#R_Q40wJ&v4bUS>o z>D!_N@TBf&h%-$c(*K(2ZF+iX8}jM5Eg5MWDr~Kz@dC%XfTPjls0%t8mpRroI~tdu zyvrSpUdKACPjFW{8rL}10ba0ty30fo>syY-^BwD;1?f=+RrtwgcAhM#I09n}U9x`!ePr%2l$x_$cRt-0OxM`@lJn`v>G!Qcm~^zPyQT zc?;WRuifjI2QR^Q!(Q@1G=_8^A>G}uN3Xvc)?dw#kC1Mt{*F{+U1J@!Na8zo1JJb+ zV^W{A!Q9?_Y;Q~1H>~wzMQtG;y|${xrS+2sk$ybt>^6+2-R%63`&zq#E@{{Kj&0dl zS7$kXoxRGjJ-Zup36Wn~5n2OeiQ_)}2D0mkS}0cqv|6Gb$3DdF&u&DlwH1*UBQgT& zp?Fs=Ld$?Ghj=xV)Ii(=@fyaSVR4jIf4%K;aC!pv{|)bMa*p7YkKbWnM}QR*sCMM_ zTK&7&S-oKYjW`Q@cQ4~adC}I*{Ycb94f~N7?Q4sp3_x0^!EvYJ#W)z@o1fIPlw+Eg zV;b63uPrVb3u7jlW|FB;82du_pel!*l#JYi5O;`*V=fz{l=QjwO@)3SX8`nI@?4q&4FX(CJ zQLJj*O5k4~-Pqzsf$0ky=F=kBBHE2;Bk1p95-F^5%)7*qS1DYou&(Dp_H4*@OB-cf zLz?qfg|*EzeO(2ab&$Un@{K54dYOiOC&%jT7R+GxS$vKGODCwuvE7pOJu5<0KrRAZ z0%VnxSYt@IG7Jx5{yvQS*I-RiLVFt=d8lQy%L_z1C?J-LuPh;6lwGuuiyiqG=`IlM z_WYstQV6*#A?INlw1JyAhst?-lhMWz#dg>L+3!Ji24#gm>vac$WxI?a{=0}5X>oU;Hk;y?K+6`=^v;dsexm3cBFZu@!hy9B(9 zGmwxJ#2ZKA;=Y&{Ug{rl$z+NqAGGkukXMB?fO}?M*yf9CnxsdhA_L!!f2GRHu)9Jk z!Xp528TsQSNKqa`6fZ*wew|E@7wH6V)YB2k{}}&dk{8}w6Y+TW@c$E+@pt6Yjalf@ zk!nd-OWG>w21&O_daI;&NqVoOdnA2c(l;eNDrxpiMO?>8dYYsQC9RfpwWO_*Zjf|~ zq_;|Xm!$Vfx<}IIC4E!UqmpKyBJ-E@G)WgqS}o~nNn0h|An6uKZsCh0;+t0i46X{)3g zB;6wEt&-j)sjd~zfv(p>77!PH91j>qKb22n!HjY_n{{xSqy|4j@~2BWSJJa3Jui)4 zD)|+XF0HIwVsYuhVq$wL8aIt8zB(#)vgi zM30|f&lG=-NWXkI-leC%1BJO}qPc{>%<0d$4I>lDtw-&!FOYWbbEX$fR9#L7goN{ux zIeZ|QWy$_85c^8pET>I7nc`OatswRUZkEE6W-da`^WMt1y;p&A&AJT9|4io1jRzoN+4%1QrdomkcBrZU--{CjmGjH0a$pm{x`81 zEDv8Vw(w?sjM!pg&l2O!`VwyAvT0S$C;ZH0_5&zK&Zp9-TZXS;G|nL5w%+FNtj<_D5p8S@~6g zob!q8BF3BbNn%rxkL?9wyjfo*#ubfikQi^)Pl#>6&6Xm@n{^CIZei6~Co^;hL(>`B z&d})$?PjQip@R%9W{7UJRxw0(SXVH#jUj#+)p8F*0fzQ5)Xva98QRFu5r(c~$cCFW zft$SqSkB3!U61QUF1DN*te|ZAKWC=%hX_OJzd&-nJ?WPSPtMDE$^Ieu@gLy!%2*Ms zhV(0@AkQ{*4@Smu69sZA{i3 z!Yqj3qYq**tYyYxR4YP=quL?-tmP25OdE$U11PBQbs)I1^wG(-fDE4`aWuV-3MSGT z06rue9!L$5n<>I3Qw$OR2oa>rn>Nuh$(iLi(J{+08DqC~j*{g#?|6a`w>Xt?GjnUO z)U}?ikYp7ob5l+Ggf5YP?7^GsjRrp%B_mf~aGn1qP4HnsMTcylEJ^ zrCpd_@+Mn^3gkl#6QzA3TQsDhEM)xTX}UP$IMrQ}H9pp6#a|}2TnS++?_#3S zl=GXn;;(#d1l^1uTlg*b-Gkq5{2s?oWIWc3kmY5vZ{n8qF>hJ0(KZG*yvKx`rsI}P zxg1Vlx$_ZX?q`6Gn!AO$>&0RRQN%4EQ~mEcWFAsl#0?HnTu6;8>pV+sZQMQAioerr z0d6dRvJNPg3o!avESEv*|Bm0!W;Wsmb;jx_>vU+Nqk$PKq^vU~HfPS<=%#2(uroTh zyKG_8!Uc2j_r<$nbLy43&GAsUW$t?Z!R)!wu7C^$qHzT)NtdVIg+HBLj1bl|=#|5^qufASg3$m`Jqz9Wy3a&d zWDNB!{+M5SeJFzw?r#YzO-mw?up+HxB^ebSjC3F;{(1TTsmRM}mafF-G)FqPdw!`X zgQzPutICoRxkqsoxBKyj;@xPL#S0gJi^V&F?)AZrU{@&MDqim@UNPTQj6X*2Uf&T% zs^V7Avhw0k2jAfb+Yu@5495@%b_ar;u~4KV3I@$Pa7A$-?2on;V;adB&Bh!&2TWh@*mZjZDC!|o9NaRFXVFAjDG1A4;{JqR^Gcd-VHb}?KR zXyikU@vQj@-YWi9Qy_{C=U*RfY7UuV%OL1)4mHL6>xYwvI%Hp3F1nGd;o*2cD~xSQ zX{uR)jt?(1#iPL%yab&-js&`5Aq*pvo+E4WSS87FaD zrNnJItW1;m_O$kSvc$X7?BTH!^>n7;JOW~Q?^vqmcayY-D^KEuJ{|Z> z;$ERAPx&~Y17f#;V7-)|S)=1Cr9Ah-)DxAscqbci%|Z{_xwPLXS4iU9(#q8-@O9E@X_oK zNJ==b%E64@Ui{G{$tz4PvYlqM?N%>twPj9}Drsrvq&qU=xX^$cQn$REdYmFV296GvHkr z@M|*QH)p{A8-AFCc59q~oF>b@ErUD{D=Gg4j~sAarxRso2Km1OcS#vDapa8dhc`0l z`6L65GYDmp)u|Y(N+XY4;;^%_QAbK-1dsJc^Z(oo_>v6x>I`^W20WSpzb*s*y$txz z1nyAAEYk~guPoPZGsxec0pAPUCDWS8>lx&aWx&Uy{or&?QP$~NASSL8MZ1!WiJX}M zFVBEqkO6PZfb;!`(dxH51Acu5{D;6@CcBN`AA#qMGHyJWLC=#J@IwN3DCJzJ<1)ti z*Cn2_T*t*TCj^gX(Br`R?G#;f#JvdkXnrWmfG-ueL;uU&&@@kKtCRQ^IpG`cpj zW{|%m1Kyqizb*rQO9uR>8SuL^;P(sMp}a5sIYZjN7kD1pPkKE*n?cVT8Su9=;8rxq z(c0Ve40v${yh7j(rB=>&e1Cw~g&E|7Qa+0PzHQU2K@U{zk|>9a2fmbA7+sMxs=~NOP3e_ z78$|2h+D^hZ8HB|20e=Dymt8TnaA8X-xS~C0qqEO<5MghK_w9HiblGWZpLp2MdSW3 zzK_ur40b3jotu=dNF;`n=+0Q15@`2#D)?Yfi#TjmLa|^wp4;$4J_Xn{lRZUgPy-iKv@WiUA$|pgeccs#_w06Z3JlI=NU0q+* z(A3~rQd#!58PSP-G=Kqa2v)dypqmKKJT#+AVic(NMbfm$sZdv&A> z`9rWy|3-~Bh}w*7QW{Zd@QMGzc(7|zz3328Lvc0AR;hQJ#%dN(+$9q2=)~7%VyzWR zYipKNHt|KkQl+sqCK81s(V!`>cxN~ifTipsP0;|VRT!>>qA+ID2n|h5>(O}hhrn=3 zusakR5#PAdABqO$*PTTD3ZO;{DH%ViL>Oij*VU{eX ztf)$U#EYX#;|hFF%PT*p)l}243=dX~R^PC!l5M_0e7I*r>nKj9)!|^r2&>bcpEcI& zAMlFSMlb-O;#y;D7FFHoSW%@F15jW@^2X{=7(K3P19}PiNH91uR(Huzlc|h!Zt|c8 z>A$ZVg3^py7W7a&7M73q=}6sgOE?sv!J^dBpy3m?6FQ32s9NdErltU&hBY-eg(Jg- zI1Ak;(2WO}p$>e1>&i6ykr~>5aJ_iaidGy7hgYIi_&e6aHzE(VZqYa~PGi`_qjNF( zk8}h3z*2NOwvXZTjmt4;>zj!=I>~crgsJT@i9@S(Ghx)Pb?B10r_K*&;+^$kaN^p+EFcHq1~$j;7*LMQSSS|9+#n{Gx==U!eRaSaZ1u;(F;hGSoUauZdBOu2;YKLO;NBG( znO{>-yptjaVwp?hGJmI-PFi$}(ISljTOaZC#*CiKx0d9b)b0-r54~rhp$Y#rhyf(T zNsrB~jvrvd(hJkSSXd0tg>r&MpI4MQ(M|0!e={iBhoEgnNYqBBGDp0QfHzU*V7aKz zS;LTcqpBFMF6oeGNlh`|zL-OCEV0^@IW3zykcCdMTof^w6r*@WWdzfNxUOK>&jd1r zcU_b@ToWmC#K1L&ODV)fgdgVw+vMVjFLn%ZdJ26NrHB+p7>ezD%Y!Xa(ZT7qAPimgBFaC z9)8|$z%^;M{f+HO`3*nC~SV#lHbF%0D2}8?;ag;uua`>Gu19;(gbl@*Dqd z&Y=9J9WR!Vem2tQ6T}t5k69Y|8~+Z^pvJ$uqbx7#FkjyS!++yuq&NOun?d(TVZ(ky z&Y;&Ip8saf;EjJbXHa=O@iqGm8~DB{eQKmP{@tEID`bR`e|q_UB-1aE3XOjUXi%Pm z@nZUE_@$@+IWYRf(66|_@N$W}c=1*b>G$;dzXPy2z00M`8B}~TP=~}lPlgT3V8W>G~NFHlIacqE9<17r1#_e-h8>t48jlKNBfQR z#`8^s@)daVm7f1&h%~3qU9U?Ul;3zXUumqu_fH)7$!<6FyxREpt?BXxZ_rne)@e#_ zJRdixAqNq08N5LUfwJuw`5Vt`4LVOchW(e9kF+lF%11Fkea7m2CMu-|yDVw~UA6^u-f zo_>PNKfRnr`t-9y+RDqI$I0|MI(+Z!)x$@IArUhCZosoLq+i#kOWcyy{*8Q%^d%Y6 zf2`^feE-CJrLoF+8PeaL&{MsbmLQE)E|BTd{TJoHitEa>4rin{=;{pV-~GOx{#-*) zXNUZ5z^yX9j2>z&MCU&sUSR3HQKE)|8aUW+MX_{ h-w$(O#WjHQQuCFb|3pNNmVVox^;8?u5~Q)p{{mUT(bxb0 literal 0 HcmV?d00001 diff --git a/linuxSetup/programs/dmenu/dmenu-alpha-20210605-1a13d04.diff b/linuxSetup/programs/dmenu/dmenu-alpha-20210605-1a13d04.diff new file mode 100644 index 0000000..51679f7 --- /dev/null +++ b/linuxSetup/programs/dmenu/dmenu-alpha-20210605-1a13d04.diff @@ -0,0 +1,267 @@ +diff --git a/config.def.h b/config.def.h +index 1edb647..697d511 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -2,6 +2,7 @@ + /* Default settings; can be overriden by command line. */ + + static int topbar = 1; /* -b option; if 0, dmenu appears at bottom */ ++static const unsigned int alpha = 0xf0; + /* -fn option overrides fonts[0]; default X11 font or font set */ + static const char *fonts[] = { + "monospace:size=10" +@@ -13,6 +14,13 @@ static const char *colors[SchemeLast][2] = { + [SchemeSel] = { "#eeeeee", "#005577" }, + [SchemeOut] = { "#000000", "#00ffff" }, + }; ++ ++static const unsigned int alphas[SchemeLast][2] = { ++ [SchemeNorm] = { OPAQUE, alpha }, ++ [SchemeSel] = { OPAQUE, alpha }, ++ [SchemeOut] = { OPAQUE, alpha }, ++}; ++ + /* -l option; if nonzero, dmenu uses vertical list with given number of lines */ + static unsigned int lines = 0; + +diff --git a/dmenu.c b/dmenu.c +index 65f25ce..3e56e1a 100644 +--- a/dmenu.c ++++ b/dmenu.c +@@ -10,6 +10,7 @@ + + #include + #include ++#include + #include + #ifdef XINERAMA + #include +@@ -25,6 +26,8 @@ + #define LENGTH(X) (sizeof X / sizeof X[0]) + #define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad) + ++#define OPAQUE 0xffU ++ + /* enums */ + enum { SchemeNorm, SchemeSel, SchemeOut, SchemeLast }; /* color schemes */ + +@@ -53,10 +56,16 @@ static XIC xic; + static Drw *drw; + static Clr *scheme[SchemeLast]; + ++static int useargb = 0; ++static Visual *visual; ++static int depth; ++static Colormap cmap; ++ + #include "config.h" + + static int (*fstrncmp)(const char *, const char *, size_t) = strncmp; + static char *(*fstrstr)(const char *, const char *) = strstr; ++static void xinitvisual(); + + static void + appenditem(struct item *item, struct item **list, struct item **last) +@@ -602,7 +611,7 @@ setup(void) + #endif + /* init appearance */ + for (j = 0; j < SchemeLast; j++) +- scheme[j] = drw_scm_create(drw, colors[j], 2); ++ scheme[j] = drw_scm_create(drw, colors[j], alphas[i], 2); + + clip = XInternAtom(dpy, "CLIPBOARD", False); + utf8 = XInternAtom(dpy, "UTF8_STRING", False); +@@ -640,6 +649,7 @@ setup(void) + x = info[i].x_org; + y = info[i].y_org + (topbar ? 0 : info[i].height - mh); + mw = info[i].width; ++ + XFree(info); + } else + #endif +@@ -657,11 +667,13 @@ setup(void) + + /* create menu window */ + swa.override_redirect = True; +- swa.background_pixel = scheme[SchemeNorm][ColBg].pixel; ++ swa.background_pixel = 0; ++ swa.border_pixel = 0; ++ swa.colormap = cmap; + swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask; +- win = XCreateWindow(dpy, parentwin, x, y, mw, mh, 0, +- CopyFromParent, CopyFromParent, CopyFromParent, +- CWOverrideRedirect | CWBackPixel | CWEventMask, &swa); ++ win = XCreateWindow(dpy, parentwin, x, y, mw, mh, border_width, ++ depth, CopyFromParent, visual, ++ CWOverrideRedirect | CWBackPixel | CWBorderPixel | CWColormap | CWEventMask, &swa); + XSetClassHint(dpy, win, &ch); + + +@@ -747,7 +759,8 @@ main(int argc, char *argv[]) + 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); ++ xinitvisual(); ++ drw = drw_create(dpy, screen, root, wa.width, wa.height, visual, depth, cmap); + if (!drw_fontset_create(drw, fonts, LENGTH(fonts))) + die("no fonts could be loaded."); + lrpad = drw->fonts->h; +@@ -769,3 +782,40 @@ main(int argc, char *argv[]) + + return 1; /* unreachable */ + } ++ ++ 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/drw.c b/drw.c +index 4cdbcbe..fe3aadd 100644 +--- a/drw.c ++++ b/drw.c +@@ -61,7 +61,7 @@ utf8decode(const char *c, long *u, size_t clen) + } + + Drw * +-drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h) ++drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h, Visual *visual, unsigned int depth, Colormap cmap) + { + Drw *drw = ecalloc(1, sizeof(Drw)); + +@@ -70,8 +70,11 @@ drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h + 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); ++ drw->visual = visual; ++ drw->depth = depth; ++ drw->cmap = cmap; ++ drw->drawable = XCreatePixmap(dpy, root, w, h, depth); ++ drw->gc = XCreateGC(dpy, drw->drawable, 0, NULL); + XSetLineAttributes(dpy, drw->gc, 1, LineSolid, CapButt, JoinMiter); + + return drw; +@@ -87,7 +90,7 @@ drw_resize(Drw *drw, unsigned int w, unsigned int h) + 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)); ++ drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, drw->depth); + } + + void +@@ -194,21 +197,22 @@ drw_fontset_free(Fnt *font) + } + + void +-drw_clr_create(Drw *drw, Clr *dest, const char *clrname) ++drw_clr_create(Drw *drw, Clr *dest, const char *clrname, unsigned int alpha) + { + if (!drw || !dest || !clrname) + return; + +- if (!XftColorAllocName(drw->dpy, DefaultVisual(drw->dpy, drw->screen), +- DefaultColormap(drw->dpy, drw->screen), ++ if (!XftColorAllocName(drw->dpy, drw->visual, drw->cmap, + clrname, dest)) + die("error, cannot allocate color '%s'", clrname); ++ ++ dest->pixel = (dest->pixel & 0x00ffffffU) | (alpha << 24); + } + + /* 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, const char *clrnames[], const unsigned int alphas[], size_t clrcount) + { + size_t i; + Clr *ret; +@@ -218,7 +222,7 @@ drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount) + return NULL; + + for (i = 0; i < clrcount; i++) +- drw_clr_create(drw, &ret[i], clrnames[i]); ++ drw_clr_create(drw, &ret[i], clrnames[i], alphas[i]); + return ret; + } + +@@ -274,9 +278,7 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp + } else { + XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].pixel); + XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h); +- d = XftDrawCreate(drw->dpy, drw->drawable, +- DefaultVisual(drw->dpy, drw->screen), +- DefaultColormap(drw->dpy, drw->screen)); ++ d = XftDrawCreate(drw->dpy, drw->drawable, drw->visual, drw->cmap); + x += lpad; + w -= lpad; + } +diff --git a/drw.h b/drw.h +index 4c67419..f6fa5cd 100644 +--- a/drw.h ++++ b/drw.h +@@ -20,6 +20,9 @@ typedef struct { + Display *dpy; + int screen; + Window root; ++ Visual *visual; ++ unsigned int depth; ++ Colormap cmap; + Drawable drawable; + GC gc; + Clr *scheme; +@@ -27,7 +30,7 @@ typedef struct { + } Drw; + + /* Drawable abstraction */ +-Drw *drw_create(Display *dpy, int screen, Window win, unsigned int w, unsigned int h); ++Drw *drw_create(Display *dpy, int screen, Window win, unsigned int w, unsigned int h, Visual*, unsigned int, Colormap); + void drw_resize(Drw *drw, unsigned int w, unsigned int h); + void drw_free(Drw *drw); + +@@ -38,8 +41,8 @@ unsigned int drw_fontset_getwidth(Drw *drw, const char *text); + void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h); + + /* Colorscheme abstraction */ +-void drw_clr_create(Drw *drw, Clr *dest, const char *clrname); +-Clr *drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount); ++void drw_clr_create(Drw *drw, Clr *dest, const char *clrname, unsigned int alpha); ++Clr *drw_scm_create(Drw *drw, const char *clrnames[], const unsigned int alphas[], size_t clrcount); + + /* Cursor abstraction */ + Cur *drw_cur_create(Drw *drw, int shape); diff --git a/linuxSetup/programs/dmenu/dmenu-alpha-20210605-1a13d04.diff.1 b/linuxSetup/programs/dmenu/dmenu-alpha-20210605-1a13d04.diff.1 new file mode 100644 index 0000000..51679f7 --- /dev/null +++ b/linuxSetup/programs/dmenu/dmenu-alpha-20210605-1a13d04.diff.1 @@ -0,0 +1,267 @@ +diff --git a/config.def.h b/config.def.h +index 1edb647..697d511 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -2,6 +2,7 @@ + /* Default settings; can be overriden by command line. */ + + static int topbar = 1; /* -b option; if 0, dmenu appears at bottom */ ++static const unsigned int alpha = 0xf0; + /* -fn option overrides fonts[0]; default X11 font or font set */ + static const char *fonts[] = { + "monospace:size=10" +@@ -13,6 +14,13 @@ static const char *colors[SchemeLast][2] = { + [SchemeSel] = { "#eeeeee", "#005577" }, + [SchemeOut] = { "#000000", "#00ffff" }, + }; ++ ++static const unsigned int alphas[SchemeLast][2] = { ++ [SchemeNorm] = { OPAQUE, alpha }, ++ [SchemeSel] = { OPAQUE, alpha }, ++ [SchemeOut] = { OPAQUE, alpha }, ++}; ++ + /* -l option; if nonzero, dmenu uses vertical list with given number of lines */ + static unsigned int lines = 0; + +diff --git a/dmenu.c b/dmenu.c +index 65f25ce..3e56e1a 100644 +--- a/dmenu.c ++++ b/dmenu.c +@@ -10,6 +10,7 @@ + + #include + #include ++#include + #include + #ifdef XINERAMA + #include +@@ -25,6 +26,8 @@ + #define LENGTH(X) (sizeof X / sizeof X[0]) + #define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad) + ++#define OPAQUE 0xffU ++ + /* enums */ + enum { SchemeNorm, SchemeSel, SchemeOut, SchemeLast }; /* color schemes */ + +@@ -53,10 +56,16 @@ static XIC xic; + static Drw *drw; + static Clr *scheme[SchemeLast]; + ++static int useargb = 0; ++static Visual *visual; ++static int depth; ++static Colormap cmap; ++ + #include "config.h" + + static int (*fstrncmp)(const char *, const char *, size_t) = strncmp; + static char *(*fstrstr)(const char *, const char *) = strstr; ++static void xinitvisual(); + + static void + appenditem(struct item *item, struct item **list, struct item **last) +@@ -602,7 +611,7 @@ setup(void) + #endif + /* init appearance */ + for (j = 0; j < SchemeLast; j++) +- scheme[j] = drw_scm_create(drw, colors[j], 2); ++ scheme[j] = drw_scm_create(drw, colors[j], alphas[i], 2); + + clip = XInternAtom(dpy, "CLIPBOARD", False); + utf8 = XInternAtom(dpy, "UTF8_STRING", False); +@@ -640,6 +649,7 @@ setup(void) + x = info[i].x_org; + y = info[i].y_org + (topbar ? 0 : info[i].height - mh); + mw = info[i].width; ++ + XFree(info); + } else + #endif +@@ -657,11 +667,13 @@ setup(void) + + /* create menu window */ + swa.override_redirect = True; +- swa.background_pixel = scheme[SchemeNorm][ColBg].pixel; ++ swa.background_pixel = 0; ++ swa.border_pixel = 0; ++ swa.colormap = cmap; + swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask; +- win = XCreateWindow(dpy, parentwin, x, y, mw, mh, 0, +- CopyFromParent, CopyFromParent, CopyFromParent, +- CWOverrideRedirect | CWBackPixel | CWEventMask, &swa); ++ win = XCreateWindow(dpy, parentwin, x, y, mw, mh, border_width, ++ depth, CopyFromParent, visual, ++ CWOverrideRedirect | CWBackPixel | CWBorderPixel | CWColormap | CWEventMask, &swa); + XSetClassHint(dpy, win, &ch); + + +@@ -747,7 +759,8 @@ main(int argc, char *argv[]) + 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); ++ xinitvisual(); ++ drw = drw_create(dpy, screen, root, wa.width, wa.height, visual, depth, cmap); + if (!drw_fontset_create(drw, fonts, LENGTH(fonts))) + die("no fonts could be loaded."); + lrpad = drw->fonts->h; +@@ -769,3 +782,40 @@ main(int argc, char *argv[]) + + return 1; /* unreachable */ + } ++ ++ 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/drw.c b/drw.c +index 4cdbcbe..fe3aadd 100644 +--- a/drw.c ++++ b/drw.c +@@ -61,7 +61,7 @@ utf8decode(const char *c, long *u, size_t clen) + } + + Drw * +-drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h) ++drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h, Visual *visual, unsigned int depth, Colormap cmap) + { + Drw *drw = ecalloc(1, sizeof(Drw)); + +@@ -70,8 +70,11 @@ drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h + 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); ++ drw->visual = visual; ++ drw->depth = depth; ++ drw->cmap = cmap; ++ drw->drawable = XCreatePixmap(dpy, root, w, h, depth); ++ drw->gc = XCreateGC(dpy, drw->drawable, 0, NULL); + XSetLineAttributes(dpy, drw->gc, 1, LineSolid, CapButt, JoinMiter); + + return drw; +@@ -87,7 +90,7 @@ drw_resize(Drw *drw, unsigned int w, unsigned int h) + 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)); ++ drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, drw->depth); + } + + void +@@ -194,21 +197,22 @@ drw_fontset_free(Fnt *font) + } + + void +-drw_clr_create(Drw *drw, Clr *dest, const char *clrname) ++drw_clr_create(Drw *drw, Clr *dest, const char *clrname, unsigned int alpha) + { + if (!drw || !dest || !clrname) + return; + +- if (!XftColorAllocName(drw->dpy, DefaultVisual(drw->dpy, drw->screen), +- DefaultColormap(drw->dpy, drw->screen), ++ if (!XftColorAllocName(drw->dpy, drw->visual, drw->cmap, + clrname, dest)) + die("error, cannot allocate color '%s'", clrname); ++ ++ dest->pixel = (dest->pixel & 0x00ffffffU) | (alpha << 24); + } + + /* 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, const char *clrnames[], const unsigned int alphas[], size_t clrcount) + { + size_t i; + Clr *ret; +@@ -218,7 +222,7 @@ drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount) + return NULL; + + for (i = 0; i < clrcount; i++) +- drw_clr_create(drw, &ret[i], clrnames[i]); ++ drw_clr_create(drw, &ret[i], clrnames[i], alphas[i]); + return ret; + } + +@@ -274,9 +278,7 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp + } else { + XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].pixel); + XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h); +- d = XftDrawCreate(drw->dpy, drw->drawable, +- DefaultVisual(drw->dpy, drw->screen), +- DefaultColormap(drw->dpy, drw->screen)); ++ d = XftDrawCreate(drw->dpy, drw->drawable, drw->visual, drw->cmap); + x += lpad; + w -= lpad; + } +diff --git a/drw.h b/drw.h +index 4c67419..f6fa5cd 100644 +--- a/drw.h ++++ b/drw.h +@@ -20,6 +20,9 @@ typedef struct { + Display *dpy; + int screen; + Window root; ++ Visual *visual; ++ unsigned int depth; ++ Colormap cmap; + Drawable drawable; + GC gc; + Clr *scheme; +@@ -27,7 +30,7 @@ typedef struct { + } Drw; + + /* Drawable abstraction */ +-Drw *drw_create(Display *dpy, int screen, Window win, unsigned int w, unsigned int h); ++Drw *drw_create(Display *dpy, int screen, Window win, unsigned int w, unsigned int h, Visual*, unsigned int, Colormap); + void drw_resize(Drw *drw, unsigned int w, unsigned int h); + void drw_free(Drw *drw); + +@@ -38,8 +41,8 @@ unsigned int drw_fontset_getwidth(Drw *drw, const char *text); + void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h); + + /* Colorscheme abstraction */ +-void drw_clr_create(Drw *drw, Clr *dest, const char *clrname); +-Clr *drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount); ++void drw_clr_create(Drw *drw, Clr *dest, const char *clrname, unsigned int alpha); ++Clr *drw_scm_create(Drw *drw, const char *clrnames[], const unsigned int alphas[], size_t clrcount); + + /* Cursor abstraction */ + Cur *drw_cur_create(Drw *drw, int shape); diff --git a/linuxSetup/programs/dmenu/dmenu-border-4.9.diff b/linuxSetup/programs/dmenu/dmenu-border-4.9.diff new file mode 100644 index 0000000..89b4437 --- /dev/null +++ b/linuxSetup/programs/dmenu/dmenu-border-4.9.diff @@ -0,0 +1,25 @@ +diff -up dmenu-4.9-b/config.def.h dmenu-4.9-a/config.def.h +--- dmenu-4.9-b/config.def.h 2019-02-02 13:55:02.000000000 +0100 ++++ dmenu-4.9-a/config.def.h 2019-05-19 02:10:12.740040403 +0200 +@@ -21,3 +21,6 @@ static unsigned int lines = 0; + * for example: " /?\"&[]" + */ + static const char worddelimiters[] = " "; ++ ++/* Size of the window border */ ++static const unsigned int border_width = 5; +diff -up dmenu-4.9-b/dmenu.c dmenu-4.9-a/dmenu.c +--- dmenu-4.9-b/dmenu.c 2019-02-02 13:55:02.000000000 +0100 ++++ dmenu-4.9-a/dmenu.c 2019-05-19 02:11:20.966710117 +0200 +@@ -654,9 +654,10 @@ setup(void) + swa.override_redirect = True; + swa.background_pixel = scheme[SchemeNorm][ColBg].pixel; + swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask; +- win = XCreateWindow(dpy, parentwin, x, y, mw, mh, 0, ++ win = XCreateWindow(dpy, parentwin, x, y, mw, mh, border_width, + CopyFromParent, CopyFromParent, CopyFromParent, + CWOverrideRedirect | CWBackPixel | CWEventMask, &swa); ++ XSetWindowBorder(dpy, win, scheme[SchemeSel][ColBg].pixel); + XSetClassHint(dpy, win, &ch); + + /* open input methods */ diff --git a/linuxSetup/programs/dmenu/dmenu-center-5.2.diff b/linuxSetup/programs/dmenu/dmenu-center-5.2.diff new file mode 100644 index 0000000..9401dc5 --- /dev/null +++ b/linuxSetup/programs/dmenu/dmenu-center-5.2.diff @@ -0,0 +1,104 @@ +diff --git a/config.def.h b/config.def.h +index 1edb647..88ef264 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -2,6 +2,8 @@ + /* Default settings; can be overriden by command line. */ + + static int topbar = 1; /* -b option; if 0, dmenu appears at bottom */ ++static int centered = 0; /* -c option; centers dmenu on screen */ ++static int min_width = 500; /* minimum width when centered */ + /* -fn option overrides fonts[0]; default X11 font or font set */ + static const char *fonts[] = { + "monospace:size=10" +diff --git a/dmenu.1 b/dmenu.1 +index 323f93c..c036baa 100644 +--- a/dmenu.1 ++++ b/dmenu.1 +@@ -40,6 +40,9 @@ which lists programs in the user's $PATH and runs the result in their $SHELL. + .B \-b + dmenu appears at the bottom of the screen. + .TP ++.B \-c ++dmenu appears centered on the screen. ++.TP + .B \-f + dmenu grabs the keyboard before reading stdin if not reading from a tty. This + is faster, but will lock up X until stdin reaches end\-of\-file. +diff --git a/dmenu.c b/dmenu.c +index 27b7a30..427fb04 100644 +--- a/dmenu.c ++++ b/dmenu.c +@@ -96,6 +96,15 @@ calcoffsets(void) + break; + } + ++static int ++max_textw(void) ++{ ++ int len = 0; ++ for (struct item *item = items; item && item->text; item++) ++ len = MAX(TEXTW(item->text), len); ++ return len; ++} ++ + static void + cleanup(void) + { +@@ -636,6 +645,7 @@ setup(void) + bh = drw->fonts->h + 2; + lines = MAX(lines, 0); + mh = (lines + 1) * bh; ++ promptw = (prompt && *prompt) ? TEXTW(prompt) - lrpad / 4 : 0; + #ifdef XINERAMA + i = 0; + if (parentwin == root && (info = XineramaQueryScreens(dpy, &n))) { +@@ -662,9 +672,16 @@ setup(void) + 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; ++ if (centered) { ++ mw = MIN(MAX(max_textw() + promptw, min_width), info[i].width); ++ x = info[i].x_org + ((info[i].width - mw) / 2); ++ y = info[i].y_org + ((info[i].height - mh) / 2); ++ } else { ++ x = info[i].x_org; ++ y = info[i].y_org + (topbar ? 0 : info[i].height - mh); ++ mw = info[i].width; ++ } ++ + XFree(info); + } else + #endif +@@ -672,9 +689,16 @@ setup(void) + 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; ++ ++ if (centered) { ++ mw = MIN(MAX(max_textw() + promptw, min_width), wa.width); ++ x = (wa.width - mw) / 2; ++ y = (wa.height - mh) / 2; ++ } else { ++ 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 */ +@@ -733,6 +757,8 @@ main(int argc, char *argv[]) + topbar = 0; + else if (!strcmp(argv[i], "-f")) /* grabs keyboard before reading stdin */ + fast = 1; ++ else if (!strcmp(argv[i], "-c")) /* centers dmenu on screen */ ++ centered = 1; + else if (!strcmp(argv[i], "-i")) { /* case-insensitive item matching */ + fstrncmp = strncasecmp; + fstrstr = cistrstr; diff --git a/linuxSetup/programs/dmenu/dmenu-dracula-20211128-d78ff08.diff b/linuxSetup/programs/dmenu/dmenu-dracula-20211128-d78ff08.diff new file mode 100644 index 0000000..7059652 --- /dev/null +++ b/linuxSetup/programs/dmenu/dmenu-dracula-20211128-d78ff08.diff @@ -0,0 +1,27 @@ +From f16313b64965d74e6cbb30fa41d53aaf09b9ad49 Mon Sep 17 00:00:00 2001 +From: David Lima +Date: Sun, 28 Nov 2021 17:02:43 -0300 +Subject: [PATCH] apply dracula theme to dmenu + +--- + config.def.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/config.def.h b/config.def.h +index 1edb647..e688388 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -9,8 +9,8 @@ static const char *fonts[] = { + 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" }, ++ [SchemeNorm] = { "#f8f8f2", "#282a36" }, ++ [SchemeSel] = { "#f8f8f2", "#6272a4" }, + [SchemeOut] = { "#000000", "#00ffff" }, + }; + /* -l option; if nonzero, dmenu uses vertical list with given number of lines */ +-- +2.34.1 + diff --git a/linuxSetup/programs/dmenu/dmenu-highlight-4.9.diff b/linuxSetup/programs/dmenu/dmenu-highlight-4.9.diff new file mode 100644 index 0000000..8eb784b --- /dev/null +++ b/linuxSetup/programs/dmenu/dmenu-highlight-4.9.diff @@ -0,0 +1,94 @@ +From a06d0d3d7bbb3c0f5bad44934dbbf1e88e7d9558 Mon Sep 17 00:00:00 2001 +From: Miles Alan +Date: Sat, 4 Jul 2020 11:49:04 -0500 +Subject: [PATCH] Highlight matched text in a different color scheme + +--- + config.def.h | 2 ++ + dmenu.c | 43 +++++++++++++++++++++++++++++++++++++++++-- + 2 files changed, 43 insertions(+), 2 deletions(-) + +diff --git a/config.def.h b/config.def.h +index 1edb647..64eab2a 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -11,6 +11,8 @@ static const char *colors[SchemeLast][2] = { + /* fg bg */ + [SchemeNorm] = { "#bbbbbb", "#222222" }, + [SchemeSel] = { "#eeeeee", "#005577" }, ++ [SchemeSelHighlight] = { "#ffc978", "#005577" }, ++ [SchemeNormHighlight] = { "#ffc978", "#222222" }, + [SchemeOut] = { "#000000", "#00ffff" }, + }; + /* -l option; if nonzero, dmenu uses vertical list with given number of lines */ +diff --git a/dmenu.c b/dmenu.c +index 6b8f51b..d5e1991 100644 +--- a/dmenu.c ++++ b/dmenu.c +@@ -26,7 +26,7 @@ + #define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad) + + /* enums */ +-enum { SchemeNorm, SchemeSel, SchemeOut, SchemeLast }; /* color schemes */ ++enum { SchemeNorm, SchemeSel, SchemeOut, SchemeNormHighlight, SchemeSelHighlight, SchemeLast }; /* color schemes */ + + struct item { + char *text; +@@ -113,6 +113,43 @@ cistrstr(const char *s, const char *sub) + return NULL; + } + ++static void ++drawhighlights(struct item *item, int x, int y, int maxw) ++{ ++ char restorechar, tokens[sizeof text], *highlight, *token; ++ int indentx, highlightlen; ++ ++ drw_setscheme(drw, scheme[item == sel ? SchemeSelHighlight : SchemeNormHighlight]); ++ strcpy(tokens, text); ++ for (token = strtok(tokens, " "); token; token = strtok(NULL, " ")) { ++ highlight = fstrstr(item->text, token); ++ while (highlight) { ++ // Move item str end, calc width for highlight indent, & restore ++ highlightlen = highlight - item->text; ++ restorechar = *highlight; ++ item->text[highlightlen] = '\0'; ++ indentx = TEXTW(item->text); ++ item->text[highlightlen] = restorechar; ++ ++ // Move highlight str end, draw highlight, & restore ++ restorechar = highlight[strlen(token)]; ++ highlight[strlen(token)] = '\0'; ++ if (indentx - (lrpad / 2) - 1 < maxw) ++ drw_text( ++ drw, ++ x + indentx - (lrpad / 2) - 1, ++ y, ++ MIN(maxw - indentx, TEXTW(highlight) - lrpad), ++ bh, 0, highlight, 0 ++ ); ++ highlight[strlen(token)] = restorechar; ++ ++ if (strlen(highlight) - strlen(token) < strlen(token)) break; ++ highlight = fstrstr(highlight + strlen(token), token); ++ } ++ } ++} ++ + static int + drawitem(struct item *item, int x, int y, int w) + { +@@ -123,7 +160,9 @@ drawitem(struct item *item, int x, int y, int w) + else + drw_setscheme(drw, scheme[SchemeNorm]); + +- return drw_text(drw, x, y, w, bh, lrpad / 2, item->text, 0); ++ int r = drw_text(drw, x, y, w, bh, lrpad / 2, item->text, 0); ++ drawhighlights(item, x, y, w); ++ return r; + } + + static void +-- +2.23.1 + diff --git a/linuxSetup/programs/dmenu/dmenu-lineheight-5.2.diff b/linuxSetup/programs/dmenu/dmenu-lineheight-5.2.diff new file mode 100644 index 0000000..a5e8468 --- /dev/null +++ b/linuxSetup/programs/dmenu/dmenu-lineheight-5.2.diff @@ -0,0 +1,106 @@ +From ba103e38ea4ab07f9a3ee90627714b9bea17c329 Mon Sep 17 00:00:00 2001 +From: pskry +Date: Sun, 8 Nov 2020 22:04:22 +0100 +Subject: [PATCH] Add an option which defines the lineheight + +Despite both the panel and dmenu using the same font (a Terminus 12), +dmenu is shorter and the panel is visible from under the dmenu bar. +The appearance can be even more distracting when using similar colors +for background and selections. With the option added by this patch, +dmenu can be launched with a '-h 24', thus completely covering the panel. +--- + config.def.h | 3 +++ + dmenu.1 | 5 +++++ + dmenu.c | 11 ++++++++--- + 3 files changed, 16 insertions(+), 3 deletions(-) + +diff --git a/config.def.h b/config.def.h +index 1edb647..4394dec 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -15,6 +15,9 @@ static const char *colors[SchemeLast][2] = { + }; + /* -l option; if nonzero, dmenu uses vertical list with given number of lines */ + static unsigned int lines = 0; ++/* -h option; minimum height of a menu line */ ++static unsigned int lineheight = 0; ++static unsigned int min_lineheight = 8; + + /* + * Characters not considered part of a word while deleting words +diff --git a/dmenu.1 b/dmenu.1 +index 323f93c..f2a82b4 100644 +--- a/dmenu.1 ++++ b/dmenu.1 +@@ -6,6 +6,8 @@ dmenu \- dynamic menu + .RB [ \-bfiv ] + .RB [ \-l + .IR lines ] ++.RB [ \-h ++.IR height ] + .RB [ \-m + .IR monitor ] + .RB [ \-p +@@ -50,6 +52,9 @@ dmenu matches menu items case insensitively. + .BI \-l " lines" + dmenu lists items vertically, with the given number of lines. + .TP ++.BI \-h " height" ++dmenu uses a menu line of at least 'height' pixels tall, but no less than 8. ++.TP + .BI \-m " monitor" + dmenu is displayed on the monitor number supplied. Monitor numbers are starting + from 0. +diff --git a/dmenu.c b/dmenu.c +index e7be8af..82b204b 100644 +--- a/dmenu.c ++++ b/dmenu.c +@@ -148,7 +148,7 @@ drawmenu(void) + { + unsigned int curpos; + struct item *item; +- int x = 0, y = 0, w; ++ int x = 0, y = 0, fh = drw->fonts->h, w; + + drw_setscheme(drw, scheme[SchemeNorm]); + drw_rect(drw, 0, 0, mw, mh, 1, 1); +@@ -165,7 +165,7 @@ drawmenu(void) + 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); ++ drw_rect(drw, x + curpos, 2 + (bh - fh) / 2, 2, fh - 4, 1, 0); + } + + if (lines > 0) { +@@ -630,6 +630,7 @@ setup(void) + + /* calculate menu geometry */ + bh = drw->fonts->h + 2; ++ bh = MAX(bh,lineheight); /* make a menu line AT LEAST 'lineheight' tall */ + lines = MAX(lines, 0); + mh = (lines + 1) * bh; + #ifdef XINERAMA +@@ -710,7 +711,7 @@ setup(void) + static void + usage(void) + { +- die("usage: dmenu [-bfiv] [-l lines] [-p prompt] [-fn font] [-m monitor]\n" ++ die("usage: dmenu [-bfiv] [-l lines] [-h height] [-p prompt] [-fn font] [-m monitor]\n" + " [-nb color] [-nf color] [-sb color] [-sf color] [-w windowid]"); + } + +@@ -737,6 +738,10 @@ main(int argc, char *argv[]) + /* 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], "-h")) { /* minimum height of one menu line */ ++ lineheight = atoi(argv[++i]); ++ lineheight = MAX(lineheight, min_lineheight); ++ } + else if (!strcmp(argv[i], "-m")) + mon = atoi(argv[++i]); + else if (!strcmp(argv[i], "-p")) /* adds prompt to left of input field */ +-- +2.38.1 + diff --git a/linuxSetup/programs/dmenu/dmenu-numbers-20220512-28fb3e2.diff b/linuxSetup/programs/dmenu/dmenu-numbers-20220512-28fb3e2.diff new file mode 100644 index 0000000..9a0fc3c --- /dev/null +++ b/linuxSetup/programs/dmenu/dmenu-numbers-20220512-28fb3e2.diff @@ -0,0 +1,89 @@ +From c4cd209c2e322563750d09a3b64194d11cc12a10 Mon Sep 17 00:00:00 2001 +From: Ehsan Ghorbannezhad +Date: Thu, 12 May 2022 22:32:47 +0430 +Subject: [PATCH] the numbers patch, updated to fix segfault in some conditions + +--- + dmenu.c | 27 ++++++++++++++++++++++++--- + 1 file changed, 24 insertions(+), 3 deletions(-) + +diff --git a/dmenu.c b/dmenu.c +index 571bc35..70004e7 100644 +--- a/dmenu.c ++++ b/dmenu.c +@@ -24,6 +24,8 @@ + * MAX(0, MIN((y)+(h),(r).y_org+(r).height) - MAX((y),(r).y_org))) + #define LENGTH(X) (sizeof X / sizeof X[0]) + #define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad) ++#define NUMBERSMAXDIGITS 100 ++#define NUMBERSBUFSIZE (NUMBERSMAXDIGITS * 2) + 1 + + /* enums */ + enum { SchemeNorm, SchemeSel, SchemeOut, SchemeLast }; /* color schemes */ +@@ -34,6 +36,7 @@ struct item { + int out; + }; + ++static char numbers[NUMBERSBUFSIZE] = ""; + static char text[BUFSIZ] = ""; + static char *embed; + static int bh, mw, mh; +@@ -86,7 +89,7 @@ calcoffsets(void) + if (lines > 0) + n = lines * bh; + else +- n = mw - (promptw + inputw + TEXTW("<") + TEXTW(">")); ++ n = mw - (promptw + inputw + TEXTW("<") + TEXTW(">") + TEXTW(numbers)); + /* 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) +@@ -143,6 +146,21 @@ drawitem(struct item *item, int x, int y, int w) + return drw_text(drw, x, y, w, bh, lrpad / 2, item->text, 0); + } + ++static void ++recalculatenumbers() ++{ ++ unsigned int numer = 0, denom = 0; ++ struct item *item; ++ if (matchend) { ++ numer++; ++ for (item = matchend; item && item->left; item = item->left) ++ numer++; ++ } ++ for (item = items; item && item->text; item++) ++ denom++; ++ snprintf(numbers, NUMBERSBUFSIZE, "%d/%d", numer, denom); ++} ++ + static void + drawmenu(void) + { +@@ -168,6 +186,7 @@ drawmenu(void) + drw_rect(drw, x + curpos, 2, 2, bh - 4, 1, 0); + } + ++ recalculatenumbers(); + if (lines > 0) { + /* draw vertical list */ + for (item = curr; item != next; item = item->right) +@@ -182,13 +201,15 @@ drawmenu(void) + } + x += w; + for (item = curr; item != next; item = item->right) +- x = drawitem(item, x, 0, textw_clamp(item->text, mw - x - TEXTW(">"))); ++ x = drawitem(item, x, 0, textw_clamp(item->text, mw - x - TEXTW(">") - TEXTW(numbers))); + if (next) { + w = TEXTW(">"); + drw_setscheme(drw, scheme[SchemeNorm]); +- drw_text(drw, mw - w, 0, w, bh, lrpad / 2, ">", 0); ++ drw_text(drw, mw - w - TEXTW(numbers), 0, w, bh, lrpad / 2, ">", 0); + } + } ++ drw_setscheme(drw, scheme[SchemeNorm]); ++ drw_text(drw, mw - TEXTW(numbers), 0, TEXTW(numbers), bh, lrpad / 2, numbers, 0); + drw_map(drw, win, 0, 0, mw, mh); + } + +-- +2.36.1 diff --git a/linuxSetup/programs/dmenu/dmenu.1 b/linuxSetup/programs/dmenu/dmenu.1 new file mode 100644 index 0000000..c80cd20 --- /dev/null +++ b/linuxSetup/programs/dmenu/dmenu.1 @@ -0,0 +1,202 @@ +.TH DMENU 1 dmenu\-VERSION +.SH NAME +dmenu \- dynamic menu +.SH SYNOPSIS +.B dmenu +.RB [ \-bfiv ] +.RB [ \-l +.IR lines ] +.RB [ \-h +.IR height ] +.RB [ \-m +.IR monitor ] +.RB [ \-p +.IR prompt ] +.RB [ \-fn +.IR font ] +.RB [ \-nb +.IR color ] +.RB [ \-nf +.IR color ] +.RB [ \-sb +.IR color ] +.RB [ \-sf +.IR color ] +.RB [ \-w +.IR windowid ] +.P +.BR dmenu_run " ..." +.SH DESCRIPTION +.B dmenu +is a dynamic menu for X, which reads a list of newline\-separated items from +stdin. When the user selects an item and presses Return, their choice is printed +to stdout and dmenu terminates. Entering text will narrow the items to those +matching the tokens in the input. +.P +.B dmenu_run +is a script used by +.IR dwm (1) +which lists programs in the user's $PATH and runs the result in their $SHELL. +.SH OPTIONS +.TP +.B \-b +dmenu appears at the bottom of the screen. +.TP +.B \-c +dmenu appears centered on the screen. +.TP +.B \-f +dmenu grabs the keyboard before reading stdin if not reading from a tty. This +is faster, but will lock up X until stdin reaches end\-of\-file. +.TP +.B \-i +dmenu matches menu items case insensitively. +.TP +.BI \-l " lines" +dmenu lists items vertically, with the given number of lines. +.TP +.BI \-h " height" +dmenu uses a menu line of at least 'height' pixels tall, but no less than 8. +.TP +.BI \-m " monitor" +dmenu is displayed on the monitor number supplied. Monitor numbers are starting +from 0. +.TP +.BI \-p " prompt" +defines the prompt to be displayed to the left of the input field. +.TP +.BI \-fn " font" +defines the font or font set used. +.TP +.BI \-nb " color" +defines the normal background color. +.IR #RGB , +.IR #RRGGBB , +and X color names are supported. +.TP +.BI \-nf " color" +defines the normal foreground color. +.TP +.BI \-sb " color" +defines the selected background color. +.TP +.BI \-sf " color" +defines the selected foreground color. +.TP +.B \-v +prints version information to stdout, then exits. +.TP +.BI \-w " windowid" +embed into windowid. +.SH USAGE +dmenu is completely controlled by the keyboard. Items are selected using the +arrow keys, page up, page down, home, and end. +.TP +.B Tab +Copy the selected item to the input field. +.TP +.B Return +Confirm selection. Prints the selected item to stdout and exits, returning +success. +.TP +.B Ctrl-Return +Confirm selection. Prints the selected item to stdout and continues. +.TP +.B Shift\-Return +Confirm input. Prints the input text to stdout and exits, returning success. +.TP +.B Escape +Exit without selecting an item, returning failure. +.TP +.B Ctrl-Left +Move cursor to the start of the current word +.TP +.B Ctrl-Right +Move cursor to the end of the current word +.TP +.B C\-a +Home +.TP +.B C\-b +Left +.TP +.B C\-c +Escape +.TP +.B C\-d +Delete +.TP +.B C\-e +End +.TP +.B C\-f +Right +.TP +.B C\-g +Escape +.TP +.B C\-h +Backspace +.TP +.B C\-i +Tab +.TP +.B C\-j +Return +.TP +.B C\-J +Shift-Return +.TP +.B C\-k +Delete line right +.TP +.B C\-m +Return +.TP +.B C\-M +Shift-Return +.TP +.B C\-n +Down +.TP +.B C\-p +Up +.TP +.B C\-u +Delete line left +.TP +.B C\-w +Delete word left +.TP +.B C\-y +Paste from primary X selection +.TP +.B C\-Y +Paste from X clipboard +.TP +.B M\-b +Move cursor to the start of the current word +.TP +.B M\-f +Move cursor to the end of the current word +.TP +.B M\-g +Home +.TP +.B M\-G +End +.TP +.B M\-h +Up +.TP +.B M\-j +Page down +.TP +.B M\-k +Page up +.TP +.B M\-l +Down +.SH SEE ALSO +.IR dwm (1), +.IR stest (1) diff --git a/linuxSetup/programs/dmenu/dmenu.1.orig b/linuxSetup/programs/dmenu/dmenu.1.orig new file mode 100644 index 0000000..c036baa --- /dev/null +++ b/linuxSetup/programs/dmenu/dmenu.1.orig @@ -0,0 +1,197 @@ +.TH DMENU 1 dmenu\-VERSION +.SH NAME +dmenu \- dynamic menu +.SH SYNOPSIS +.B dmenu +.RB [ \-bfiv ] +.RB [ \-l +.IR lines ] +.RB [ \-m +.IR monitor ] +.RB [ \-p +.IR prompt ] +.RB [ \-fn +.IR font ] +.RB [ \-nb +.IR color ] +.RB [ \-nf +.IR color ] +.RB [ \-sb +.IR color ] +.RB [ \-sf +.IR color ] +.RB [ \-w +.IR windowid ] +.P +.BR dmenu_run " ..." +.SH DESCRIPTION +.B dmenu +is a dynamic menu for X, which reads a list of newline\-separated items from +stdin. When the user selects an item and presses Return, their choice is printed +to stdout and dmenu terminates. Entering text will narrow the items to those +matching the tokens in the input. +.P +.B dmenu_run +is a script used by +.IR dwm (1) +which lists programs in the user's $PATH and runs the result in their $SHELL. +.SH OPTIONS +.TP +.B \-b +dmenu appears at the bottom of the screen. +.TP +.B \-c +dmenu appears centered on the screen. +.TP +.B \-f +dmenu grabs the keyboard before reading stdin if not reading from a tty. This +is faster, but will lock up X until stdin reaches end\-of\-file. +.TP +.B \-i +dmenu matches menu items case insensitively. +.TP +.BI \-l " lines" +dmenu lists items vertically, with the given number of lines. +.TP +.BI \-m " monitor" +dmenu is displayed on the monitor number supplied. Monitor numbers are starting +from 0. +.TP +.BI \-p " prompt" +defines the prompt to be displayed to the left of the input field. +.TP +.BI \-fn " font" +defines the font or font set used. +.TP +.BI \-nb " color" +defines the normal background color. +.IR #RGB , +.IR #RRGGBB , +and X color names are supported. +.TP +.BI \-nf " color" +defines the normal foreground color. +.TP +.BI \-sb " color" +defines the selected background color. +.TP +.BI \-sf " color" +defines the selected foreground color. +.TP +.B \-v +prints version information to stdout, then exits. +.TP +.BI \-w " windowid" +embed into windowid. +.SH USAGE +dmenu is completely controlled by the keyboard. Items are selected using the +arrow keys, page up, page down, home, and end. +.TP +.B Tab +Copy the selected item to the input field. +.TP +.B Return +Confirm selection. Prints the selected item to stdout and exits, returning +success. +.TP +.B Ctrl-Return +Confirm selection. Prints the selected item to stdout and continues. +.TP +.B Shift\-Return +Confirm input. Prints the input text to stdout and exits, returning success. +.TP +.B Escape +Exit without selecting an item, returning failure. +.TP +.B Ctrl-Left +Move cursor to the start of the current word +.TP +.B Ctrl-Right +Move cursor to the end of the current word +.TP +.B C\-a +Home +.TP +.B C\-b +Left +.TP +.B C\-c +Escape +.TP +.B C\-d +Delete +.TP +.B C\-e +End +.TP +.B C\-f +Right +.TP +.B C\-g +Escape +.TP +.B C\-h +Backspace +.TP +.B C\-i +Tab +.TP +.B C\-j +Return +.TP +.B C\-J +Shift-Return +.TP +.B C\-k +Delete line right +.TP +.B C\-m +Return +.TP +.B C\-M +Shift-Return +.TP +.B C\-n +Down +.TP +.B C\-p +Up +.TP +.B C\-u +Delete line left +.TP +.B C\-w +Delete word left +.TP +.B C\-y +Paste from primary X selection +.TP +.B C\-Y +Paste from X clipboard +.TP +.B M\-b +Move cursor to the start of the current word +.TP +.B M\-f +Move cursor to the end of the current word +.TP +.B M\-g +Home +.TP +.B M\-G +End +.TP +.B M\-h +Up +.TP +.B M\-j +Page down +.TP +.B M\-k +Page up +.TP +.B M\-l +Down +.SH SEE ALSO +.IR dwm (1), +.IR stest (1) diff --git a/linuxSetup/programs/dmenu/dmenu.c b/linuxSetup/programs/dmenu/dmenu.c new file mode 100644 index 0000000..38a486e --- /dev/null +++ b/linuxSetup/programs/dmenu/dmenu.c @@ -0,0 +1,939 @@ +/* See LICENSE file for copyright and license details. */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#ifdef XINERAMA +#include +#endif +#include + +#include "drw.h" +#include "util.h" + +/* macros */ +#define INTERSECT(x,y,w,h,r) (MAX(0, MIN((x)+(w),(r).x_org+(r).width) - MAX((x),(r).x_org)) \ + * MAX(0, MIN((y)+(h),(r).y_org+(r).height) - MAX((y),(r).y_org))) +#define LENGTH(X) (sizeof X / sizeof X[0]) +#define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad) +#define NUMBERSMAXDIGITS 100 +#define NUMBERSBUFSIZE (NUMBERSMAXDIGITS * 2) + 1 + +#define OPAQUE 0xffU + +/* enums */ +enum { SchemeNorm, SchemeSel, SchemeOut, SchemeNormHighlight, SchemeSelHighlight, SchemeLast }; /* color schemes */ + +struct item { + char *text; + struct item *left, *right; + int out; +}; + +static char numbers[NUMBERSBUFSIZE] = ""; +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]; + +static int useargb = 0; +static Visual *visual; +static int depth; +static Colormap cmap; + +#include "config.h" + +static int (*fstrncmp)(const char *, const char *, size_t) = strncmp; +static char *(*fstrstr)(const char *, const char *) = strstr; +static void xinitvisual(); + +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(">") + TEXTW(numbers)); + /* 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 int +max_textw(void) +{ + int len = 0; + for (struct item *item = items; item && item->text; item++) + len = MAX(TEXTW(item->text), len); + return len; +} + +static void +cleanup(void) +{ + size_t i; + + XUngrabKey(dpy, AnyKey, AnyModifier, root); + 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 void +drawhighlights(struct item *item, int x, int y, int maxw) +{ + char restorechar, tokens[sizeof text], *highlight, *token; + int indentx, highlightlen; + + drw_setscheme(drw, scheme[item == sel ? SchemeSelHighlight : SchemeNormHighlight]); + strcpy(tokens, text); + for (token = strtok(tokens, " "); token; token = strtok(NULL, " ")) { + highlight = fstrstr(item->text, token); + while (highlight) { + // Move item str end, calc width for highlight indent, & restore + highlightlen = highlight - item->text; + restorechar = *highlight; + item->text[highlightlen] = '\0'; + indentx = TEXTW(item->text); + item->text[highlightlen] = restorechar; + + // Move highlight str end, draw highlight, & restore + restorechar = highlight[strlen(token)]; + highlight[strlen(token)] = '\0'; + if (indentx - (lrpad / 2) - 1 < maxw) + drw_text( + drw, + x + indentx - (lrpad / 2) - 1, + y, + MIN(maxw - indentx, TEXTW(highlight) - lrpad), + bh, 0, highlight, 0 + ); + highlight[strlen(token)] = restorechar; + + if (strlen(highlight) - strlen(token) < strlen(token)) break; + highlight = fstrstr(highlight + strlen(token), token); + } + } +} + +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]); + + int r = drw_text(drw, x, y, w, bh, lrpad / 2, item->text, 0); + drawhighlights(item, x, y, w); + return r; +} + +static void +recalculatenumbers() +{ + unsigned int numer = 0, denom = 0; + struct item *item; + if (matchend) { + numer++; + for (item = matchend; item && item->left; item = item->left) + numer++; + } + for (item = items; item && item->text; item++) + denom++; + snprintf(numbers, NUMBERSBUFSIZE, "%d/%d", numer, denom); +} + +static void +drawmenu(void) +{ + unsigned int curpos; + struct item *item; + int x = 0, y = 0, fh = drw->fonts->h, 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 + (bh - fh) / 2, 2, fh - 4, 1, 0); + } + + recalculatenumbers(); + 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(">") - TEXTW(numbers))); + if (next) { + w = TEXTW(">"); + drw_setscheme(drw, scheme[SchemeNorm]); + drw_text(drw, mw - w - TEXTW(numbers), 0, w, bh, lrpad / 2, ">", 0); + } + } + drw_setscheme(drw, scheme[SchemeNorm]); + drw_text(drw, mw - TEXTW(numbers), 0, TEXTW(numbers), bh, lrpad / 2, numbers, 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, junk, itemsiz = 0; + ssize_t len; + + /* read each line from stdin and add it to the item list */ + for (i = 0; (len = getline(&line, &junk, 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'; + items[i].text = line; + items[i].out = 0; + line = NULL; /* next call of getline() allocates a new line */ + } + 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], alphas[i], 2); + + clip = XInternAtom(dpy, "CLIPBOARD", False); + utf8 = XInternAtom(dpy, "UTF8_STRING", False); + + /* calculate menu geometry */ + bh = drw->fonts->h + 2; + bh = MAX(bh,lineheight); /* make a menu line AT LEAST 'lineheight' tall */ + lines = MAX(lines, 0); + mh = (lines + 1) * bh; + promptw = (prompt && *prompt) ? TEXTW(prompt) - lrpad / 4 : 0; +#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; + + if (centered) { + mw = MIN(MAX(max_textw() + promptw, min_width), info[i].width); + x = info[i].x_org + ((info[i].width - mw) / 2); + y = info[i].y_org + ((info[i].height - mh) / 2); + } else { + 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); + + if (centered) { + mw = MIN(MAX(max_textw() + promptw, min_width), wa.width); + x = (wa.width - mw) / 2; + y = (wa.height - mh) / 2; + } else { + 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 = 0; + swa.border_pixel = 0; + swa.colormap = cmap; + swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask; + win = XCreateWindow(dpy, parentwin, x, y, mw, mh, border_width, + depth, CopyFromParent, visual, + CWOverrideRedirect | CWBackPixel | CWBorderPixel | CWColormap | + CWEventMask, &swa); + XSetWindowBorder(dpy, win, scheme[SchemeSel][ColBg].pixel); + XSetClassHint(dpy, win, &ch); + + + /* input methods */ + if ((xim = XOpenIM(dpy, NULL, NULL, NULL)) == NULL) + die("XOpenIM failed: could not open input device"); + + xic = XCreateIC(xim, XNInputStyle, XIMPreeditNothing | XIMStatusNothing, + XNClientWindow, win, XNFocusWindow, win, NULL); + + XMapRaised(dpy, win); + if (embed) { + XSelectInput(dpy, parentwin, FocusChangeMask | SubstructureNotifyMask); + if (XQueryTree(dpy, parentwin, &dw, &w, &dws, &du) && dws) { + for (i = 0; i < du && dws[i] != win; ++i) + XSelectInput(dpy, dws[i], FocusChangeMask); + XFree(dws); + } + grabfocus(); + } + drw_resize(drw, mw, mh); + drawmenu(); +} + +static void +usage(void) +{ + die("usage: dmenu [-bfiv] [-l lines] [-h height] [-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], "-c")) /* centers dmenu on screen */ + centered = 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], "-h")) { /* minimum height of one menu line */ + lineheight = atoi(argv[++i]); + lineheight = MAX(lineheight, min_lineheight); + } + 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); + xinitvisual(); + + xinitvisual(); + drw = drw_create(dpy, screen, root, wa.width, wa.height, visual, depth, cmap); + 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 */ +} + + 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/linuxSetup/programs/dmenu/dmenu.c.orig b/linuxSetup/programs/dmenu/dmenu.c.orig new file mode 100644 index 0000000..2ef2fde --- /dev/null +++ b/linuxSetup/programs/dmenu/dmenu.c.orig @@ -0,0 +1,887 @@ +/* See LICENSE file for copyright and license details. */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#ifdef XINERAMA +#include +#endif +#include + +#include "drw.h" +#include "util.h" + +/* macros */ +#define INTERSECT(x,y,w,h,r) (MAX(0, MIN((x)+(w),(r).x_org+(r).width) - MAX((x),(r).x_org)) \ + * MAX(0, MIN((y)+(h),(r).y_org+(r).height) - MAX((y),(r).y_org))) +#define LENGTH(X) (sizeof X / sizeof X[0]) +#define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad) +#define NUMBERSMAXDIGITS 100 +#define NUMBERSBUFSIZE (NUMBERSMAXDIGITS * 2) + 1 + +/* enums */ +enum { SchemeNorm, SchemeSel, SchemeOut, SchemeNormHighlight, SchemeSelHighlight, SchemeLast }; /* color schemes */ + +struct item { + char *text; + struct item *left, *right; + int out; +}; + +static char numbers[NUMBERSBUFSIZE] = ""; +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(">") + TEXTW(numbers)); + /* 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 int +max_textw(void) +{ + int len = 0; + for (struct item *item = items; item && item->text; item++) + len = MAX(TEXTW(item->text), len); + return len; +} + +static void +cleanup(void) +{ + size_t i; + + XUngrabKey(dpy, AnyKey, AnyModifier, root); + 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 void +drawhighlights(struct item *item, int x, int y, int maxw) +{ + char restorechar, tokens[sizeof text], *highlight, *token; + int indentx, highlightlen; + + drw_setscheme(drw, scheme[item == sel ? SchemeSelHighlight : SchemeNormHighlight]); + strcpy(tokens, text); + for (token = strtok(tokens, " "); token; token = strtok(NULL, " ")) { + highlight = fstrstr(item->text, token); + while (highlight) { + // Move item str end, calc width for highlight indent, & restore + highlightlen = highlight - item->text; + restorechar = *highlight; + item->text[highlightlen] = '\0'; + indentx = TEXTW(item->text); + item->text[highlightlen] = restorechar; + + // Move highlight str end, draw highlight, & restore + restorechar = highlight[strlen(token)]; + highlight[strlen(token)] = '\0'; + if (indentx - (lrpad / 2) - 1 < maxw) + drw_text( + drw, + x + indentx - (lrpad / 2) - 1, + y, + MIN(maxw - indentx, TEXTW(highlight) - lrpad), + bh, 0, highlight, 0 + ); + highlight[strlen(token)] = restorechar; + + if (strlen(highlight) - strlen(token) < strlen(token)) break; + highlight = fstrstr(highlight + strlen(token), token); + } + } +} + +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]); + + int r = drw_text(drw, x, y, w, bh, lrpad / 2, item->text, 0); + drawhighlights(item, x, y, w); + return r; +} + +static void +recalculatenumbers() +{ + unsigned int numer = 0, denom = 0; + struct item *item; + if (matchend) { + numer++; + for (item = matchend; item && item->left; item = item->left) + numer++; + } + for (item = items; item && item->text; item++) + denom++; + snprintf(numbers, NUMBERSBUFSIZE, "%d/%d", numer, denom); +} + +static void +drawmenu(void) +{ + unsigned int curpos; + struct item *item; + int x = 0, y = 0, fh = drw->fonts->h, 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 + (bh - fh) / 2, 2, fh - 4, 1, 0); + } + + recalculatenumbers(); + 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(">") - TEXTW(numbers))); + if (next) { + w = TEXTW(">"); + drw_setscheme(drw, scheme[SchemeNorm]); + drw_text(drw, mw - w - TEXTW(numbers), 0, w, bh, lrpad / 2, ">", 0); + } + } + drw_setscheme(drw, scheme[SchemeNorm]); + drw_text(drw, mw - TEXTW(numbers), 0, TEXTW(numbers), bh, lrpad / 2, numbers, 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, junk, itemsiz = 0; + ssize_t len; + + /* read each line from stdin and add it to the item list */ + for (i = 0; (len = getline(&line, &junk, 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'; + items[i].text = line; + items[i].out = 0; + line = NULL; /* next call of getline() allocates a new line */ + } + 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; + bh = MAX(bh,lineheight); /* make a menu line AT LEAST 'lineheight' tall */ + lines = MAX(lines, 0); + mh = (lines + 1) * bh; + promptw = (prompt && *prompt) ? TEXTW(prompt) - lrpad / 4 : 0; +#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; + + if (centered) { + mw = MIN(MAX(max_textw() + promptw, min_width), info[i].width); + x = info[i].x_org + ((info[i].width - mw) / 2); + y = info[i].y_org + ((info[i].height - mh) / 2); + } else { + 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); + + if (centered) { + mw = MIN(MAX(max_textw() + promptw, min_width), wa.width); + x = (wa.width - mw) / 2; + y = (wa.height - mh) / 2; + } else { + 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, parentwin, x, y, mw, mh, border_width, + CopyFromParent, CopyFromParent, CopyFromParent, + CWOverrideRedirect | CWBackPixel | CWEventMask, &swa); + XSetWindowBorder(dpy, win, scheme[SchemeSel][ColBg].pixel); + XSetClassHint(dpy, win, &ch); + + + /* input methods */ + if ((xim = XOpenIM(dpy, NULL, NULL, NULL)) == NULL) + die("XOpenIM failed: could not open input device"); + + xic = XCreateIC(xim, XNInputStyle, XIMPreeditNothing | XIMStatusNothing, + XNClientWindow, win, XNFocusWindow, win, NULL); + + XMapRaised(dpy, win); + if (embed) { + XSelectInput(dpy, parentwin, FocusChangeMask | SubstructureNotifyMask); + if (XQueryTree(dpy, parentwin, &dw, &w, &dws, &du) && dws) { + for (i = 0; i < du && dws[i] != win; ++i) + XSelectInput(dpy, dws[i], FocusChangeMask); + XFree(dws); + } + grabfocus(); + } + drw_resize(drw, mw, mh); + drawmenu(); +} + +static void +usage(void) +{ + die("usage: dmenu [-bfiv] [-l lines] [-h height] [-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], "-c")) /* centers dmenu on screen */ + centered = 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], "-h")) { /* minimum height of one menu line */ + lineheight = atoi(argv[++i]); + lineheight = MAX(lineheight, min_lineheight); + } + 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/linuxSetup/programs/dmenu/dmenu.c.rej b/linuxSetup/programs/dmenu/dmenu.c.rej new file mode 100644 index 0000000..ceea03e --- /dev/null +++ b/linuxSetup/programs/dmenu/dmenu.c.rej @@ -0,0 +1,28 @@ +--- dmenu.c ++++ dmenu.c +@@ -649,6 +658,7 @@ setup(void) + x = info[i].x_org; + y = info[i].y_org + (topbar ? 0 : info[i].height - mh); + mw = info[i].width; ++ + XFree(info); + } else + #endif +@@ -666,11 +676,13 @@ setup(void) + + /* create menu window */ + swa.override_redirect = True; +- swa.background_pixel = scheme[SchemeNorm][ColBg].pixel; ++ swa.background_pixel = 0; ++ swa.border_pixel = 0; ++ swa.colormap = cmap; + swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask; +- win = XCreateWindow(dpy, parentwin, x, y, mw, mh, 0, +- CopyFromParent, CopyFromParent, CopyFromParent, +- CWOverrideRedirect | CWBackPixel | CWEventMask, &swa); ++ win = XCreateWindow(dpy, parentwin, x, y, mw, mh, border_width, ++ depth, CopyFromParent, visual, ++ CWOverrideRedirect | CWBackPixel | CWBorderPixel | CWColormap | CWEventMask, &swa); + XSetClassHint(dpy, win, &ch); + + diff --git a/linuxSetup/programs/dmenu/dmenu_path b/linuxSetup/programs/dmenu/dmenu_path new file mode 100755 index 0000000..3a7cda7 --- /dev/null +++ b/linuxSetup/programs/dmenu/dmenu_path @@ -0,0 +1,13 @@ +#!/bin/sh + +cachedir="${XDG_CACHE_HOME:-"$HOME/.cache"}" +cache="$cachedir/dmenu_run" + +[ ! -e "$cachedir" ] && mkdir -p "$cachedir" + +IFS=: +if stest -dqr -n "$cache" $PATH; then + stest -flx $PATH | sort -u | tee "$cache" +else + cat "$cache" +fi diff --git a/linuxSetup/programs/dmenu/dmenu_run b/linuxSetup/programs/dmenu/dmenu_run new file mode 100755 index 0000000..834ede5 --- /dev/null +++ b/linuxSetup/programs/dmenu/dmenu_run @@ -0,0 +1,2 @@ +#!/bin/sh +dmenu_path | dmenu "$@" | ${SHELL:-"/bin/sh"} & diff --git a/linuxSetup/programs/dmenu/drw.c b/linuxSetup/programs/dmenu/drw.c new file mode 100644 index 0000000..42700e5 --- /dev/null +++ b/linuxSetup/programs/dmenu/drw.c @@ -0,0 +1,452 @@ +/* See LICENSE file for copyright and license details. */ +#include +#include +#include +#include +#include + +#include "drw.h" +#include "util.h" + +#define UTF_INVALID 0xFFFD +#define UTF_SIZ 4 + +static const unsigned char utfbyte[UTF_SIZ + 1] = {0x80, 0, 0xC0, 0xE0, 0xF0}; +static const unsigned char utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8}; +static const long utfmin[UTF_SIZ + 1] = { 0, 0, 0x80, 0x800, 0x10000}; +static const long utfmax[UTF_SIZ + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF}; + +static long +utf8decodebyte(const char c, size_t *i) +{ + for (*i = 0; *i < (UTF_SIZ + 1); ++(*i)) + if (((unsigned char)c & utfmask[*i]) == utfbyte[*i]) + return (unsigned char)c & ~utfmask[*i]; + return 0; +} + +static size_t +utf8validate(long *u, size_t i) +{ + if (!BETWEEN(*u, utfmin[i], utfmax[i]) || BETWEEN(*u, 0xD800, 0xDFFF)) + *u = UTF_INVALID; + for (i = 1; *u > utfmax[i]; ++i) + ; + return i; +} + +static size_t +utf8decode(const char *c, long *u, size_t clen) +{ + size_t i, j, len, type; + long udecoded; + + *u = UTF_INVALID; + if (!clen) + return 0; + udecoded = utf8decodebyte(c[0], &len); + if (!BETWEEN(len, 1, UTF_SIZ)) + return 1; + for (i = 1, j = 1; i < clen && j < len; ++i, ++j) { + udecoded = (udecoded << 6) | utf8decodebyte(c[i], &type); + if (type) + return j; + } + if (j < len) + return 0; + *u = udecoded; + utf8validate(u, len); + + return len; +} + +Drw * +drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h, Visual *visual, unsigned int depth, Colormap cmap) +{ + Drw *drw = ecalloc(1, sizeof(Drw)); + + drw->dpy = dpy; + drw->screen = screen; + drw->root = root; + drw->w = w; + drw->h = h; + drw->visual = visual; + drw->depth = depth; + drw->cmap = cmap; + drw->drawable = XCreatePixmap(dpy, root, w, h, depth); + drw->gc = XCreateGC(dpy, drw->drawable, 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, drw->depth); +} + +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, unsigned int alpha) +{ + if (!drw || !dest || !clrname) + return; + + if (!XftColorAllocName(drw->dpy, drw->visual, drw->cmap, + clrname, dest)) + die("error, cannot allocate color '%s'", clrname); + + dest->pixel = (dest->pixel & 0x00ffffffU) | (alpha << 24); +} + +/* 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[], const unsigned int alphas[], 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], alphas[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 i, ty, ellipsis_x = 0; + unsigned int tmpw, ew, ellipsis_w = 0, ellipsis_len; + XftDraw *d = NULL; + Fnt *usedfont, *curfont, *nextfont; + int utf8strlen, utf8charlen, render = x || y || w || h; + long utf8codepoint = 0; + const char *utf8str; + FcCharSet *fccharset; + FcPattern *fcpattern; + FcPattern *match; + XftResult result; + int charexists = 0, overflow = 0; + /* keep track of a couple codepoints for which we have no match. */ + enum { nomatches_len = 64 }; + static struct { long codepoint[nomatches_len]; unsigned int idx; } nomatches; + static unsigned int ellipsis_width = 0; + + 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); + d = XftDrawCreate(drw->dpy, drw->drawable, drw->visual, drw->cmap); + x += lpad; + w -= lpad; + } + + usedfont = drw->fonts; + if (!ellipsis_width && render) + ellipsis_width = drw_fontset_getwidth(drw, "..."); + while (1) { + ew = ellipsis_len = utf8strlen = 0; + utf8str = text; + nextfont = NULL; + while (*text) { + utf8charlen = utf8decode(text, &utf8codepoint, UTF_SIZ); + for (curfont = drw->fonts; curfont; curfont = curfont->next) { + charexists = charexists || XftCharExists(drw->dpy, curfont->xfont, utf8codepoint); + if (charexists) { + 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) { + utf8strlen += utf8charlen; + text += utf8charlen; + ew += tmpw; + } else { + nextfont = curfont; + } + break; + } + } + + if (overflow || !charexists || nextfont) + 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 (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; + + for (i = 0; i < nomatches_len; ++i) { + /* avoid calling XftFontMatch if we know we won't find a match */ + if (utf8codepoint == nomatches.codepoint[i]) + 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.codepoint[++nomatches.idx % nomatches_len] = 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/linuxSetup/programs/dmenu/drw.c.orig b/linuxSetup/programs/dmenu/drw.c.orig new file mode 100644 index 0000000..a58a2b4 --- /dev/null +++ b/linuxSetup/programs/dmenu/drw.c.orig @@ -0,0 +1,450 @@ +/* See LICENSE file for copyright and license details. */ +#include +#include +#include +#include +#include + +#include "drw.h" +#include "util.h" + +#define UTF_INVALID 0xFFFD +#define UTF_SIZ 4 + +static const unsigned char utfbyte[UTF_SIZ + 1] = {0x80, 0, 0xC0, 0xE0, 0xF0}; +static const unsigned char utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8}; +static const long utfmin[UTF_SIZ + 1] = { 0, 0, 0x80, 0x800, 0x10000}; +static const long utfmax[UTF_SIZ + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF}; + +static long +utf8decodebyte(const char c, size_t *i) +{ + for (*i = 0; *i < (UTF_SIZ + 1); ++(*i)) + if (((unsigned char)c & utfmask[*i]) == utfbyte[*i]) + return (unsigned char)c & ~utfmask[*i]; + return 0; +} + +static size_t +utf8validate(long *u, size_t i) +{ + if (!BETWEEN(*u, utfmin[i], utfmax[i]) || BETWEEN(*u, 0xD800, 0xDFFF)) + *u = UTF_INVALID; + for (i = 1; *u > utfmax[i]; ++i) + ; + return i; +} + +static size_t +utf8decode(const char *c, long *u, size_t clen) +{ + size_t i, j, len, type; + long udecoded; + + *u = UTF_INVALID; + if (!clen) + return 0; + udecoded = utf8decodebyte(c[0], &len); + if (!BETWEEN(len, 1, UTF_SIZ)) + return 1; + for (i = 1, j = 1; i < clen && j < len; ++i, ++j) { + udecoded = (udecoded << 6) | utf8decodebyte(c[i], &type); + if (type) + return j; + } + if (j < len) + return 0; + *u = udecoded; + utf8validate(u, len); + + return len; +} + +Drw * +drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h) +{ + Drw *drw = ecalloc(1, sizeof(Drw)); + + drw->dpy = dpy; + drw->screen = screen; + drw->root = root; + drw->w = w; + drw->h = h; + drw->drawable = XCreatePixmap(dpy, root, w, h, DefaultDepth(dpy, screen)); + drw->gc = XCreateGC(dpy, root, 0, NULL); + XSetLineAttributes(dpy, drw->gc, 1, LineSolid, CapButt, JoinMiter); + + return drw; +} + +void +drw_resize(Drw *drw, unsigned int w, unsigned int h) +{ + if (!drw) + return; + + drw->w = w; + drw->h = h; + if (drw->drawable) + XFreePixmap(drw->dpy, drw->drawable); + drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, DefaultDepth(drw->dpy, drw->screen)); +} + +void +drw_free(Drw *drw) +{ + XFreePixmap(drw->dpy, drw->drawable); + XFreeGC(drw->dpy, drw->gc); + drw_fontset_free(drw->fonts); + free(drw); +} + +/* This function is an implementation detail. Library users should use + * drw_fontset_create instead. + */ +static Fnt * +xfont_create(Drw *drw, const char *fontname, FcPattern *fontpattern) +{ + Fnt *font; + XftFont *xfont = NULL; + FcPattern *pattern = NULL; + + if (fontname) { + /* Using the pattern found at font->xfont->pattern does not yield the + * same substitution results as using the pattern returned by + * FcNameParse; using the latter results in the desired fallback + * behaviour whereas the former just results in missing-character + * rectangles being drawn, at least with some fonts. */ + if (!(xfont = XftFontOpenName(drw->dpy, drw->screen, fontname))) { + fprintf(stderr, "error, cannot load font from name: '%s'\n", fontname); + return NULL; + } + if (!(pattern = FcNameParse((FcChar8 *) fontname))) { + fprintf(stderr, "error, cannot parse font name to pattern: '%s'\n", fontname); + XftFontClose(drw->dpy, xfont); + return NULL; + } + } else if (fontpattern) { + if (!(xfont = XftFontOpenPattern(drw->dpy, fontpattern))) { + fprintf(stderr, "error, cannot load font from pattern.\n"); + return NULL; + } + } else { + die("no font specified."); + } + + 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 i, ty, ellipsis_x = 0; + unsigned int tmpw, ew, ellipsis_w = 0, ellipsis_len; + XftDraw *d = NULL; + Fnt *usedfont, *curfont, *nextfont; + int utf8strlen, utf8charlen, render = x || y || w || h; + long utf8codepoint = 0; + const char *utf8str; + FcCharSet *fccharset; + FcPattern *fcpattern; + FcPattern *match; + XftResult result; + int charexists = 0, overflow = 0; + /* keep track of a couple codepoints for which we have no match. */ + enum { nomatches_len = 64 }; + static struct { long codepoint[nomatches_len]; unsigned int idx; } nomatches; + static unsigned int ellipsis_width = 0; + + 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); + 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, "..."); + while (1) { + ew = ellipsis_len = utf8strlen = 0; + utf8str = text; + nextfont = NULL; + while (*text) { + utf8charlen = utf8decode(text, &utf8codepoint, UTF_SIZ); + for (curfont = drw->fonts; curfont; curfont = curfont->next) { + charexists = charexists || XftCharExists(drw->dpy, curfont->xfont, utf8codepoint); + if (charexists) { + 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) { + utf8strlen += utf8charlen; + text += utf8charlen; + ew += tmpw; + } else { + nextfont = curfont; + } + break; + } + } + + if (overflow || !charexists || nextfont) + 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 (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; + + for (i = 0; i < nomatches_len; ++i) { + /* avoid calling XftFontMatch if we know we won't find a match */ + if (utf8codepoint == nomatches.codepoint[i]) + 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.codepoint[++nomatches.idx % nomatches_len] = 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/linuxSetup/programs/dmenu/drw.h b/linuxSetup/programs/dmenu/drw.h new file mode 100644 index 0000000..48f2f93 --- /dev/null +++ b/linuxSetup/programs/dmenu/drw.h @@ -0,0 +1,61 @@ +/* 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; + Visual *visual; + unsigned int depth; + Colormap cmap; + 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, Visual*, unsigned int, Colormap); +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, unsigned int alpha); +Clr *drw_scm_create(Drw *drw, const char *clrnames[], const unsigned int alphas[], 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/linuxSetup/programs/dmenu/drw.h.orig b/linuxSetup/programs/dmenu/drw.h.orig new file mode 100644 index 0000000..fd7631b --- /dev/null +++ b/linuxSetup/programs/dmenu/drw.h.orig @@ -0,0 +1,58 @@ +/* See LICENSE file for copyright and license details. */ + +typedef struct { + Cursor cursor; +} Cur; + +typedef struct Fnt { + Display *dpy; + unsigned int h; + XftFont *xfont; + FcPattern *pattern; + struct Fnt *next; +} Fnt; + +enum { ColFg, ColBg }; /* Clr scheme index */ +typedef XftColor Clr; + +typedef struct { + unsigned int w, h; + Display *dpy; + int screen; + Window root; + Drawable drawable; + GC gc; + Clr *scheme; + Fnt *fonts; +} Drw; + +/* Drawable abstraction */ +Drw *drw_create(Display *dpy, int screen, Window win, unsigned int w, unsigned int h); +void drw_resize(Drw *drw, unsigned int w, unsigned int h); +void drw_free(Drw *drw); + +/* Fnt abstraction */ +Fnt *drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount); +void drw_fontset_free(Fnt* set); +unsigned int drw_fontset_getwidth(Drw *drw, const char *text); +unsigned int drw_fontset_getwidth_clamp(Drw *drw, const char *text, unsigned int n); +void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h); + +/* Colorscheme abstraction */ +void drw_clr_create(Drw *drw, Clr *dest, const char *clrname); +Clr *drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount); + +/* Cursor abstraction */ +Cur *drw_cur_create(Drw *drw, int shape); +void drw_cur_free(Drw *drw, Cur *cursor); + +/* Drawing context manipulation */ +void drw_setfontset(Drw *drw, Fnt *set); +void drw_setscheme(Drw *drw, Clr *scm); + +/* Drawing functions */ +void drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert); +int drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert); + +/* Map functions */ +void drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h); diff --git a/linuxSetup/programs/dmenu/patch.sh b/linuxSetup/programs/dmenu/patch.sh new file mode 100755 index 0000000..783a5d8 --- /dev/null +++ b/linuxSetup/programs/dmenu/patch.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +patch -p1 < dmenu-border-4.9.diff +patch -p1 < dmenu-center-5.2.diff +patch -p1 < dmenu-highlight-4.9.diff +patch -p1 < dmenu-lineheight-5.2.diff +sudo make install + + diff --git a/linuxSetup/programs/dmenu/stest b/linuxSetup/programs/dmenu/stest new file mode 100755 index 0000000000000000000000000000000000000000..36f0b2c6bcd350f0cd679fe1d6d6a29dd45cd3d6 GIT binary patch literal 21544 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 literal 0 HcmV?d00001 diff --git a/linuxSetup/programs/dmenu/stest.1 b/linuxSetup/programs/dmenu/stest.1 new file mode 100644 index 0000000..2667d8a --- /dev/null +++ b/linuxSetup/programs/dmenu/stest.1 @@ -0,0 +1,90 @@ +.TH STEST 1 dmenu\-VERSION +.SH NAME +stest \- filter a list of files by properties +.SH SYNOPSIS +.B stest +.RB [ -abcdefghlpqrsuwx ] +.RB [ -n +.IR file ] +.RB [ -o +.IR file ] +.RI [ file ...] +.SH DESCRIPTION +.B stest +takes a list of files and filters by the files' properties, analogous to +.IR test (1). +Files which pass all tests are printed to stdout. If no files are given, stest +reads files from stdin. +.SH OPTIONS +.TP +.B \-a +Test hidden files. +.TP +.B \-b +Test that files are block specials. +.TP +.B \-c +Test that files are character specials. +.TP +.B \-d +Test that files are directories. +.TP +.B \-e +Test that files exist. +.TP +.B \-f +Test that files are regular files. +.TP +.B \-g +Test that files have their set-group-ID flag set. +.TP +.B \-h +Test that files are symbolic links. +.TP +.B \-l +Test the contents of a directory given as an argument. +.TP +.BI \-n " file" +Test that files are newer than +.IR file . +.TP +.BI \-o " file" +Test that files are older than +.IR file . +.TP +.B \-p +Test that files are named pipes. +.TP +.B \-q +No files are printed, only the exit status is returned. +.TP +.B \-r +Test that files are readable. +.TP +.B \-s +Test that files are not empty. +.TP +.B \-u +Test that files have their set-user-ID flag set. +.TP +.B \-v +Invert the sense of tests, only failing files pass. +.TP +.B \-w +Test that files are writable. +.TP +.B \-x +Test that files are executable. +.SH EXIT STATUS +.TP +.B 0 +At least one file passed all tests. +.TP +.B 1 +No files passed all tests. +.TP +.B 2 +An error occurred. +.SH SEE ALSO +.IR dmenu (1), +.IR test (1) diff --git a/linuxSetup/programs/dmenu/stest.c b/linuxSetup/programs/dmenu/stest.c new file mode 100644 index 0000000..e27d3a5 --- /dev/null +++ b/linuxSetup/programs/dmenu/stest.c @@ -0,0 +1,109 @@ +/* See LICENSE file for copyright and license details. */ +#include + +#include +#include +#include +#include +#include +#include + +#include "arg.h" +char *argv0; + +#define FLAG(x) (flag[(x)-'a']) + +static void test(const char *, const char *); +static void usage(void); + +static int match = 0; +static int flag[26]; +static struct stat old, new; + +static void +test(const char *path, const char *name) +{ + struct stat st, ln; + + if ((!stat(path, &st) && (FLAG('a') || name[0] != '.') /* hidden files */ + && (!FLAG('b') || S_ISBLK(st.st_mode)) /* block special */ + && (!FLAG('c') || S_ISCHR(st.st_mode)) /* character special */ + && (!FLAG('d') || S_ISDIR(st.st_mode)) /* directory */ + && (!FLAG('e') || access(path, F_OK) == 0) /* exists */ + && (!FLAG('f') || S_ISREG(st.st_mode)) /* regular file */ + && (!FLAG('g') || st.st_mode & S_ISGID) /* set-group-id flag */ + && (!FLAG('h') || (!lstat(path, &ln) && S_ISLNK(ln.st_mode))) /* symbolic link */ + && (!FLAG('n') || st.st_mtime > new.st_mtime) /* newer than file */ + && (!FLAG('o') || st.st_mtime < old.st_mtime) /* older than file */ + && (!FLAG('p') || S_ISFIFO(st.st_mode)) /* named pipe */ + && (!FLAG('r') || access(path, R_OK) == 0) /* readable */ + && (!FLAG('s') || st.st_size > 0) /* not empty */ + && (!FLAG('u') || st.st_mode & S_ISUID) /* set-user-id flag */ + && (!FLAG('w') || access(path, W_OK) == 0) /* writable */ + && (!FLAG('x') || access(path, X_OK) == 0)) != FLAG('v')) { /* executable */ + if (FLAG('q')) + exit(0); + match = 1; + puts(name); + } +} + +static void +usage(void) +{ + fprintf(stderr, "usage: %s [-abcdefghlpqrsuvwx] " + "[-n file] [-o file] [file...]\n", argv0); + exit(2); /* like test(1) return > 1 on error */ +} + +int +main(int argc, char *argv[]) +{ + struct dirent *d; + char path[PATH_MAX], *line = NULL, *file; + size_t linesiz = 0; + ssize_t n; + DIR *dir; + int r; + + ARGBEGIN { + case 'n': /* newer than file */ + case 'o': /* older than file */ + file = EARGF(usage()); + if (!(FLAG(ARGC()) = !stat(file, (ARGC() == 'n' ? &new : &old)))) + perror(file); + break; + default: + /* miscellaneous operators */ + if (strchr("abcdefghlpqrsuvwx", ARGC())) + FLAG(ARGC()) = 1; + else + usage(); /* unknown flag */ + } ARGEND; + + if (!argc) { + /* read list from stdin */ + while ((n = getline(&line, &linesiz, stdin)) > 0) { + if (line[n - 1] == '\n') + line[n - 1] = '\0'; + test(line, line); + } + free(line); + } else { + for (; argc; argc--, argv++) { + if (FLAG('l') && (dir = opendir(*argv))) { + /* test directory contents */ + while ((d = readdir(dir))) { + r = snprintf(path, sizeof path, "%s/%s", + *argv, d->d_name); + if (r >= 0 && (size_t)r < sizeof path) + test(path, d->d_name); + } + closedir(dir); + } else { + test(*argv, *argv); + } + } + } + return match ? 0 : 1; +} diff --git a/linuxSetup/programs/dmenu/util.c b/linuxSetup/programs/dmenu/util.c new file mode 100644 index 0000000..96b82c9 --- /dev/null +++ b/linuxSetup/programs/dmenu/util.c @@ -0,0 +1,36 @@ +/* See LICENSE file for copyright and license details. */ +#include +#include +#include +#include + +#include "util.h" + +void +die(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + + if (fmt[0] && fmt[strlen(fmt)-1] == ':') { + fputc(' ', stderr); + perror(NULL); + } else { + fputc('\n', stderr); + } + + exit(1); +} + +void * +ecalloc(size_t nmemb, size_t size) +{ + void *p; + + if (!(p = calloc(nmemb, size))) + die("calloc:"); + return p; +} diff --git a/linuxSetup/programs/dmenu/util.h b/linuxSetup/programs/dmenu/util.h new file mode 100644 index 0000000..f633b51 --- /dev/null +++ b/linuxSetup/programs/dmenu/util.h @@ -0,0 +1,8 @@ +/* See LICENSE file for copyright and license details. */ + +#define MAX(A, B) ((A) > (B) ? (A) : (B)) +#define MIN(A, B) ((A) < (B) ? (A) : (B)) +#define BETWEEN(X, A, B) ((A) <= (X) && (X) <= (B)) + +void die(const char *fmt, ...); +void *ecalloc(size_t nmemb, size_t size); diff --git a/linuxSetup/raspberry/programs/vim/_vimrc.forWindows b/linuxSetup/raspberry/programs/vim/_vimrc.forWindows deleted file mode 100755 index 241ebe4..0000000 --- a/linuxSetup/raspberry/programs/vim/_vimrc.forWindows +++ /dev/null @@ -1,155 +0,0 @@ -" Vim with all enhancements -source $VIMRUNTIME/vimrc_example.vim - -" Mouse behavior (the Unix way) -behave xterm - -" Use the internal diff if available. -" Otherwise use the special 'diffexpr' for Windows. -if &diffopt !~# 'internal' - set diffexpr=MyDiff() -endif -function MyDiff() - let opt = '-a --binary ' - if &diffopt =~ 'icase' | let opt = opt . '-i ' | endif - if &diffopt =~ 'iwhite' | let opt = opt . '-b ' | endif - let arg1 = v:fname_in - if arg1 =~ ' ' | let arg1 = '"' . arg1 . '"' | endif - let arg1 = substitute(arg1, '!', '\!', 'g') - let arg2 = v:fname_new - if arg2 =~ ' ' | let arg2 = '"' . arg2 . '"' | endif - let arg2 = substitute(arg2, '!', '\!', 'g') - let arg3 = v:fname_out - if arg3 =~ ' ' | let arg3 = '"' . arg3 . '"' | endif - let arg3 = substitute(arg3, '!', '\!', 'g') - if $VIMRUNTIME =~ ' ' - if &sh =~ '\ ' . arg3 - if exists('l:shxq_sav') - let &shellxquote=l:shxq_sav - endif -endfunction - - -language en_US.utf8 - - - - -"BASICS-------------------------------------------------------------- -set exrc ""You can get some cuntomizations if therre is a vimrc on the local eare that you are it wiil use it. -set guicursor= ""Bi cursor for oldstyle lovers. -set relativenumber ""Show the line beofre and ofetr starting from your line -set noerrorbells ""No sound effects. -set tabstop=4 ""TabSize of 4 -set shiftwidth=4 ""Indentation fo 4 -set softtabstop=4 ""Enabeling it will remplace tabs by spaces in insert mode -set noexpandtab ""Enabeling it will remplace tabs by spaces -set smartindent ""will try it's best to indent for you. -set nowrap ""Will continue to go right when line is too long -set incsearch ""incremental searching as i am typing the words will be highligted. -set number ""Self explanatory -set scrolloff=8 ""Will start to scroll down wehn there is still 8 Lines before end of page. -:autocmd InsertEnter,InsertLeave * set cul! - -"Backup and Undo -set noswapfile ""No swap file. they are anoying -set nobackup ""Nobackup because we will do a undo dir -set undodir=~/vimfiles/undodir -set undofile - -packadd termdebug -let g:termdebug_wide=1 - -filetype plugin indent on -syntax enable - -"PLUGINS------------------------------------------------------------- -call plug#begin('~/vimfiles/pluggin/') -Plug 'gruvbox-community/gruvbox' -Plug 'arcticicestudio/nord-vim' -Plug 'vim-utils/vim-man' -Plug 'mbbill/undotree' -call plug#end() -"-------------------------------------------------------------------- - -"VISUALS------------------------------------------------------------- -set colorcolumn=100 -highlight ColorColumn ctermbg=0 guibg=lightgrey -set signcolumn=yes -colorscheme gruvbox -"https://vi.stackexchange.com/questions/27599/colorscheme-displayed-wrongly-with-neovim -let g:gruvbox_termcolors=16 -set termguicolors -set background=dark - - -"REMAPS-------------------------------------------------------------- -let mapleader=" " -"Ease of window jumg intead of ^wj etc.. -map h :wincmd h -map j :wincmd j -map k :wincmd k -map l :wincmd l -map u :UndotreeShow -map db :Termdebug :vertical resize 30 -noremap ts :Step -noremap to :Over -noremap tn :Next -noremap tc :Cont -map pv :Sex! :vertical resize 30 -map ,/ :s/^/\/\// -map ,{ :s/);/)\r{\r\t\r}\r/g -"-------------------------------------------------------------------- - -"FILE BROWSING------------------------------------------------------- -let g:netrw_banner=0 " disable annoying banner -let g:netrw_browse_split=4 " open in prior window -let g:netrw_altv=1 " open splits to the right -let g:netrw_liststyle=3 " tree view - - " NOW WE CAN: - " - :edit a folder to open a file browser - " - /v/t to open in an h-split/v-split/tab - " - check |netrw-browse-maps| for more mappings -"PLUGINS------------------------------------------------------------- -"-------------------------------------------------------------------- - -"SNIPPETS------------------------------------------------------------ -" Command Read template move cursor -nnoremap ,html :-1read $HOME/.vim/.skeleton.html3jwf>a - -" NOW WE CAN: -" - Take over the world! -" (with much fewer keystrokes) -"-------------------------------------------------------------------- - -"BUILD INTEGRATION--------------------------------------------------- -" Steal Mr. Bradley's formatter & add it to our spec_helper -" http://philipbradley.net/rspec-into-vim-with-quickfix -" Configure the `make` command to run RSpec -set makeprg=bundle\ exec\ rspec\ -f\ QuickfixFormatter - - " NOW WE CAN: - " - Run :make to run RSpec - " - :cl to list errors - " - :cc# to jump to error by number - " - :cn and :cp to navigate forward and back -"-------------------------------------------------------------------- - - - - - diff --git a/linuxSetup/raspberry/programs/vim/init.vim b/linuxSetup/raspberry/programs/vim/init.vim deleted file mode 100755 index ec455ef..0000000 --- a/linuxSetup/raspberry/programs/vim/init.vim +++ /dev/null @@ -1,144 +0,0 @@ -"BASICS-------------------------------------------------------------- -set exrc ""You can get some cuntomizations if therre is a vimrc on the local eare that you are it wiil use it. -set guicursor= ""Bi cursor for oldstyle lovers. -set relativenumber ""Show the line beofre and ofetr starting from your line -set noerrorbells ""No sound effects. -set tabstop=4 ""TabSize of 4 -set shiftwidth=4 ""Indentation fo 4 -set softtabstop=4 ""Enabeling it will remplace tabs by spaces in insert mode -set noexpandtab ""Enabeling it will remplace tabs by spaces -set smartindent ""will try it's best to indent for you. -set nowrap ""Will continue to go right when line is too long -set incsearch ""incremental searching as i am typing the words will be highligted. -set number ""Self explanatory -set scrolloff=8 ""Will start to scroll down wehn there is still 8 Lines before end of page. - -"Backup and Undo -set noswapfile ""No swap file. they are anoying -set nobackup ""Nobackup because we will do a undo dir -set undodir=~/.vim/undodir -set undofile - -packadd termdebug -let g:termdebug_wide=1 - -filetype plugin indent on -syntax enable - -:autocmd InsertEnter,InsertLeave * set cul! -"-------------------------------------------------------------------- - -"PLUGINS------------------------------------------------------------- -call plug#begin('~/.vim/plugged') -Plug 'gruvbox-community/gruvbox' -Plug 'arcticicestudio/nord-vim' -Plug 'vim-utils/vim-man' -Plug 'mbbill/undotree' -Plug 'gyim/vim-boxdraw' -Plug 'vim-airline/vim-airline' -""Plug 'theprimeagen/vim-be-good' -call plug#end() -"-------------------------------------------------------------------- - -"VISUALS------------------------------------------------------------- -set colorcolumn=100 -highlight ColorColumn ctermbg=0 guibg=lightgrey -set signcolumn=yes - -colorscheme gruvbox -set background=dark -highlight Normal guibg=blue - -" lightline -"" set noshowmode -""let g:lightline = { 'colorscheme': 'nord' } -"-------------------------------------------------------------------- - -"REMAPS-------------------------------------------------------------- -let mapleader=" " -"Ease of window jumg intead of ^wj etc.. -map h :wincmd h -map j :wincmd j -map k :wincmd k -map l :wincmd l -map u :UndotreeShow -map db :Termdebug :vertical resize 30 -noremap ts :Step -noremap to :Over -noremap tn :Next -noremap tc :Cont -map pv :Sex! :vertical resize 30 -map ,/ :s/^/\/\// -map ,{ :s/);/)\r{\r\t\r}\r/g -map ra ebvey :%s/0/ -"-------------------------------------------------------------------- - -"WILDMENU FOR FUZZY FILE SEARCH-------------------------------------- -filetype plugin on "plugins(included with vim) for netrw -set path+=** - -set wildmenu "Display all matching files when we tab complete - " NOW WE CAN: - " Type :find - " - Hit tab to :find by partial match - " - Use * to make it fuzzy - " - Opened files will be buffered try it out - " - :b lets you autocomplete any open buffer -"-------------------------------------------------------------------- - -"TAG JUMPING--------------------------------------------------------- -" Create the `tags` file (need to install ctags first) -command! MakeTags !ctags -R . - " NOW WE CAN: - " - Use ^] to jump to tag under cursor - " - Use g^] for ambiguous tags - " - Use ^t to jump back up the tag stack - " THINGS TO CONSIDER: - " - This doesn't help if you want a visual list of tags - " AUTOCOMPLETE: - " The good stuff is documented in |ins-completion| - " HIGHLIGHTS: - " - ^x^n for JUST this file - " - ^x^f for filenames (works with our path trick!) - " - ^x^] for tags only - " - ^n for anything specified by the 'complete' option - " NOW WE CAN: - " - Use ^n and ^p to go back and forth in the suggestion list -"-------------------------------------------------------------------- - -"FILE BROWSING------------------------------------------------------- -let g:netrw_banner=0 " disable annoying banner -let g:netrw_browse_split=4 " open in prior window -let g:netrw_altv=1 " open splits to the right -let g:netrw_liststyle=3 " tree view -let g:netrw_list_hide=netrw_gitignore#Hide() -let g:netrw_list_hide.=',\(^\|\s\s\)\zs\.\S\+' - - " NOW WE CAN: - " - :edit a folder to open a file browser - " - /v/t to open in an h-split/v-split/tab - " - check |netrw-browse-maps| for more mappings -"PLUGINS------------------------------------------------------------- -"-------------------------------------------------------------------- - -"SNIPPETS------------------------------------------------------------ -" Command Read template move cursor -nnoremap ,html :-1read $HOME/.vim/.skeleton.html3jwf>a - -" NOW WE CAN: -" - Take over the world! -" (with much fewer keystrokes) -"-------------------------------------------------------------------- - -"BUILD INTEGRATION--------------------------------------------------- -" Steal Mr. Bradley's formatter & add it to our spec_helper -" http://philipbradley.net/rspec-into-vim-with-quickfix -" Configure the `make` command to run RSpec -set makeprg=bundle\ exec\ rspec\ -f\ QuickfixFormatter - - " NOW WE CAN: - " - Run :make to run RSpec - " - :cl to list errors - " - :cc# to jump to error by number - " - :cn and :cp to navigate forward and back -"-------------------------------------------------------------------- diff --git a/linuxSetup/raspberry/programs/vim/instVim.sh b/linuxSetup/raspberry/programs/vim/instVim.sh deleted file mode 100755 index f9415ea..0000000 --- a/linuxSetup/raspberry/programs/vim/instVim.sh +++ /dev/null @@ -1,68 +0,0 @@ -#!/bin/bash - -VIMVER="vim" - -DOTCONFIG="/home/$USER/.config" -LOCALVIMRC="init.vim" - -VIMRC="/home/$USER/.vimrc" -VIMDIR="/home/$USER/" - -NVIMRC="/home/$USER/.config/nvim/init.vim" -NVIMDIR="/home/$USER/.config/nvim/" - -CURDATE=$(date +%m%d%Y%H%M%S) - -#sudo apt install -y exuberant-ctags -#sudo apt install -y curl - -echo $CURDATE - -if [[ $VIMVER = "neovim" ]] -then - echo Installing NEOVIM - sudo apt install -y neovim - curl -fLo ~/.var/app/io.neovim.nvim/data/nvim/site/autoload/plug.vim --create-dirs https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim - - if [ -d "$DOTCONFIG" ]; - then - echo "$DOTCONFIG existst and will not be created" - else - mkdir $DOTCONFIG - fi - - if [ -d "$NVIMDIR" ]; - then - echo "$NVIMDIR existst and will not be created" - else - mkdir $NVIMDIR - fi - - if [ -f $NVIMRC ]; - then - echo Backing the old config file with the current date - cp $NVIMRC "$NVIMRC"."$CURDATE" - cp $LOCALVIMRC $NVIMDIR - else - cp $LOCALVIMRC $NVIMDIR - fi - -else - echo Installing VIM - sudo apt install -y vim - curl -fLo ~/.vim/autoload/plug.vim --create-dirs https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim - - if [ -f $VIMRC ]; - then - echo Backing the old config file with the current date - cp $VIMRC "$VIMRC"."$CURDATE" - cp $LOCALVIMRC $VIMDIR - cd $VIMDIR - mv $LOCALVIMRC .vimrc - else - cp $LOCALVIMRC $VIMDIR - cd $VIMDIR - mv $LOCALVIMRC .vimrc - fi -fi -