From c98e13a0220b57ac841bdab1153cf7915d150d2d Mon Sep 17 00:00:00 2001 From: Arkenys <87391814+Arkenys@users.noreply.github.com> Date: Wed, 2 Mar 2022 19:33:51 +0000 Subject: [PATCH] Add files via upload --- dwm/LICENSE | 37 + dwm/Makefile | 51 ++ dwm/README | 48 + dwm/config.def.h | 116 +++ dwm/config.h | 114 +++ dwm/config.h.save | 116 +++ dwm/config.mk | 38 + dwm/drw.c | 436 +++++++++ dwm/drw.h | 57 ++ dwm/drw.o | Bin 0 -> 10536 bytes dwm/dwm | Bin 0 -> 61712 bytes dwm/dwm.1 | 176 ++++ dwm/dwm.c | 2155 +++++++++++++++++++++++++++++++++++++++++++++ dwm/dwm.o | Bin 0 -> 56992 bytes dwm/dwm.png | Bin 0 -> 373 bytes dwm/transient.c | 42 + dwm/util.c | 35 + dwm/util.h | 8 + dwm/util.o | Bin 0 -> 2216 bytes 19 files changed, 3429 insertions(+) create mode 100644 dwm/LICENSE create mode 100644 dwm/Makefile create mode 100644 dwm/README create mode 100644 dwm/config.def.h create mode 100644 dwm/config.h.save create mode 100644 dwm/config.mk create mode 100644 dwm/drw.c create mode 100644 dwm/drw.h create mode 100644 dwm/drw.o create mode 100644 dwm/dwm create mode 100644 dwm/dwm.1 create mode 100644 dwm/dwm.c create mode 100644 dwm/dwm.o create mode 100644 dwm/dwm.png create mode 100644 dwm/transient.c create mode 100644 dwm/util.c create mode 100644 dwm/util.h create mode 100644 dwm/util.o diff --git a/dwm/LICENSE b/dwm/LICENSE new file mode 100644 index 0000000..d221f09 --- /dev/null +++ b/dwm/LICENSE @@ -0,0 +1,37 @@ +MIT/X Consortium License + +© 2006-2019 Anselm R Garbe <anselm@garbe.ca> +© 2006-2009 Jukka Salmi <jukka at salmi dot ch> +© 2006-2007 Sander van Dijk <a dot h dot vandijk at gmail dot com> +© 2007-2011 Peter Hartlich <sgkkr at hartlich dot com> +© 2007-2009 Szabolcs Nagy <nszabolcs at gmail dot com> +© 2007-2009 Christof Musik <christof at sendfax dot de> +© 2007-2009 Premysl Hruby <dfenze at gmail dot com> +© 2007-2008 Enno Gottox Boland <gottox at s01 dot de> +© 2008 Martin Hurton <martin dot hurton at gmail dot com> +© 2008 Neale Pickett <neale dot woozle dot org> +© 2009 Mate Nagy <mnagy at port70 dot net> +© 2010-2016 Hiltjo Posthuma <hiltjo@codemadness.org> +© 2010-2012 Connor Lane Smith <cls@lubutu.com> +© 2011 Christoph Lohmann <20h@r-36.net> +© 2015-2016 Quentin Rameau <quinq@fifth.space> +© 2015-2016 Eric Pruitt <eric.pruitt@gmail.com> +© 2016-2017 Markus Teich <markus.teich@stusta.mhn.de> + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/dwm/Makefile b/dwm/Makefile new file mode 100644 index 0000000..77bcbc0 --- /dev/null +++ b/dwm/Makefile @@ -0,0 +1,51 @@ +# dwm - dynamic window manager +# See LICENSE file for copyright and license details. + +include config.mk + +SRC = drw.c dwm.c util.c +OBJ = ${SRC:.c=.o} + +all: options dwm + +options: + @echo dwm build options: + @echo "CFLAGS = ${CFLAGS}" + @echo "LDFLAGS = ${LDFLAGS}" + @echo "CC = ${CC}" + +.c.o: + ${CC} -c ${CFLAGS} $< + +${OBJ}: config.h config.mk + +config.h: + cp config.def.h $@ + +dwm: ${OBJ} + ${CC} -o $@ ${OBJ} ${LDFLAGS} + +clean: + rm -f dwm ${OBJ} dwm-${VERSION}.tar.gz + +dist: clean + mkdir -p dwm-${VERSION} + cp -R LICENSE Makefile README config.def.h config.mk\ + dwm.1 drw.h util.h ${SRC} dwm.png transient.c dwm-${VERSION} + tar -cf dwm-${VERSION}.tar dwm-${VERSION} + gzip dwm-${VERSION}.tar + rm -rf dwm-${VERSION} + +install: all + mkdir -p ${DESTDIR}${PREFIX}/bin + cp -f dwm ${DESTDIR}${PREFIX}/bin + chmod 755 ${DESTDIR}${PREFIX}/bin/dwm + mkdir -p ${DESTDIR}${MANPREFIX}/man1 + sed "s/VERSION/${VERSION}/g" < dwm.1 > ${DESTDIR}${MANPREFIX}/man1/dwm.1 + chmod 644 ${DESTDIR}${MANPREFIX}/man1/dwm.1 + +uninstall: + rm -f ${DESTDIR}${PREFIX}/bin/dwm\ + ${DESTDIR}${MANPREFIX}/man1/dwm.1 + +.PHONY: all options clean dist install uninstall diff --git a/dwm/README b/dwm/README new file mode 100644 index 0000000..95d4fd0 --- /dev/null +++ b/dwm/README @@ -0,0 +1,48 @@ +dwm - dynamic window manager +============================ +dwm is an extremely fast, small, and dynamic window manager for X. + + +Requirements +------------ +In order to build dwm you need the Xlib header files. + + +Installation +------------ +Edit config.mk to match your local setup (dwm is installed into +the /usr/local namespace by default). + +Afterwards enter the following command to build and install dwm (if +necessary as root): + + make clean install + + +Running dwm +----------- +Add the following line to your .xinitrc to start dwm using startx: + + exec dwm + +In order to connect dwm to a specific display, make sure that +the DISPLAY environment variable is set correctly, e.g.: + + DISPLAY=foo.bar:1 exec dwm + +(This will start dwm on display :1 of the host foo.bar.) + +In order to display status info in the bar, you can do something +like this in your .xinitrc: + + while xsetroot -name "`date` `uptime | sed 's/.*,//'`" + do + sleep 1 + done & + exec dwm + + +Configuration +------------- +The configuration of dwm is done by creating a custom config.h +and (re)compiling the source code. diff --git a/dwm/config.def.h b/dwm/config.def.h new file mode 100644 index 0000000..a2ac963 --- /dev/null +++ b/dwm/config.def.h @@ -0,0 +1,116 @@ +/* See LICENSE file for copyright and license details. */ + +/* appearance */ +static const unsigned int borderpx = 1; /* border pixel of windows */ +static const unsigned int snap = 32; /* snap pixel */ +static const int showbar = 1; /* 0 means no bar */ +static const int topbar = 1; /* 0 means bottom bar */ +static const char *fonts[] = { "monospace:size=10" }; +static const char dmenufont[] = "monospace:size=10"; +static const char col_gray1[] = "#222222"; +static const char col_gray2[] = "#444444"; +static const char col_gray3[] = "#bbbbbb"; +static const char col_gray4[] = "#eeeeee"; +static const char col_cyan[] = "#005577"; +static const char *colors[][3] = { + /* fg bg border */ + [SchemeNorm] = { col_gray3, col_gray1, col_gray2 }, + [SchemeSel] = { col_gray4, col_cyan, col_cyan }, +}; + +/* tagging */ +static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; + +static const Rule rules[] = { + /* xprop(1): + * WM_CLASS(STRING) = instance, class + * WM_NAME(STRING) = title + */ + /* class instance title tags mask isfloating monitor */ + { "Gimp", NULL, NULL, 0, 1, -1 }, + { "Firefox", NULL, NULL, 1 << 8, 0, -1 }, +}; + +/* layout(s) */ +static const float mfact = 0.55; /* factor of master area size [0.05..0.95] */ +static const int nmaster = 1; /* number of clients in master area */ +static const int resizehints = 1; /* 1 means respect size hints in tiled resizals */ +static const int lockfullscreen = 1; /* 1 will force focus on the fullscreen window */ + +static const Layout layouts[] = { + /* symbol arrange function */ + { "[]=", tile }, /* first entry is default */ + { "><>", NULL }, /* no layout function means floating behavior */ + { "[M]", monocle }, +}; + +/* key definitions */ +#define MODKEY Mod1Mask +#define TAGKEYS(KEY,TAG) \ + { MODKEY, KEY, view, {.ui = 1 << TAG} }, \ + { MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG} }, \ + { MODKEY|ShiftMask, KEY, tag, {.ui = 1 << TAG} }, \ + { MODKEY|ControlMask|ShiftMask, KEY, toggletag, {.ui = 1 << TAG} }, + +/* helper for spawning shell commands in the pre dwm-5.0 fashion */ +#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } } + +/* commands */ +static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */ +static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL }; +static const char *termcmd[] = { "st", NULL }; + +static Key keys[] = { + /* modifier key function argument */ + { MODKEY, XK_p, spawn, {.v = dmenucmd } }, + { MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } }, + { MODKEY, XK_b, togglebar, {0} }, + { MODKEY, XK_j, focusstack, {.i = +1 } }, + { MODKEY, XK_k, focusstack, {.i = -1 } }, + { MODKEY, XK_i, incnmaster, {.i = +1 } }, + { MODKEY, XK_d, incnmaster, {.i = -1 } }, + { MODKEY, XK_h, setmfact, {.f = -0.05} }, + { MODKEY, XK_l, setmfact, {.f = +0.05} }, + { MODKEY, XK_Return, zoom, {0} }, + { MODKEY, XK_Tab, view, {0} }, + { MODKEY|ShiftMask, XK_c, killclient, {0} }, + { MODKEY, XK_t, setlayout, {.v = &layouts[0]} }, + { MODKEY, XK_f, setlayout, {.v = &layouts[1]} }, + { MODKEY, XK_m, setlayout, {.v = &layouts[2]} }, + { MODKEY, XK_space, setlayout, {0} }, + { MODKEY|ShiftMask, XK_space, togglefloating, {0} }, + { MODKEY, XK_0, view, {.ui = ~0 } }, + { MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } }, + { MODKEY, XK_comma, focusmon, {.i = -1 } }, + { MODKEY, XK_period, focusmon, {.i = +1 } }, + { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } }, + { MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } }, + TAGKEYS( XK_1, 0) + TAGKEYS( XK_2, 1) + TAGKEYS( XK_3, 2) + TAGKEYS( XK_4, 3) + TAGKEYS( XK_5, 4) + TAGKEYS( XK_6, 5) + TAGKEYS( XK_7, 6) + TAGKEYS( XK_8, 7) + TAGKEYS( XK_9, 8) + { MODKEY|ShiftMask, XK_q, quit, {0} }, +}; + +/* button definitions */ +/* click can be ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */ +static Button buttons[] = { + /* click event mask button function argument */ + { ClkLtSymbol, 0, Button1, setlayout, {0} }, + { ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} }, + { ClkWinTitle, 0, Button2, zoom, {0} }, + { ClkStatusText, 0, Button2, spawn, {.v = termcmd } }, + { ClkClientWin, MODKEY, Button1, movemouse, {0} }, + { ClkClientWin, MODKEY, Button2, togglefloating, {0} }, + { ClkClientWin, MODKEY, Button3, resizemouse, {0} }, + { ClkTagBar, 0, Button1, view, {0} }, + { ClkTagBar, 0, Button3, toggleview, {0} }, + { ClkTagBar, MODKEY, Button1, tag, {0} }, + { ClkTagBar, MODKEY, Button3, toggletag, {0} }, +}; + diff --git a/dwm/config.h b/dwm/config.h index 8b13789..166d500 100644 --- a/dwm/config.h +++ b/dwm/config.h @@ -1 +1,115 @@ +/* See LICENSE file for copyright and license details. */ + +/* appearance */ +static const unsigned int borderpx = 2; /* border pixel of windows */ +static const unsigned int snap = 32; /* snap pixel */ +static const int showbar = 1; /* 0 means no bar */ +static const int topbar = 1; /* 0 means bottom bar */ +static const char *fonts[] = { "monospace:size=10" }; +static const char dmenufont[] = "monospace:size=10"; +static const char col_gray1[] = "#222222"; +static const char col_gray2[] = "#444444"; +static const char col_gray3[] = "#bbbbbb"; +static const char col_gray4[] = "#eeeeee"; +static const char col_cyan[] = "#005577"; +static const char *colors[][3] = { + /* fg bg border */ + [SchemeNorm] = { col_gray3, col_gray1, col_gray2 }, + [SchemeSel] = { col_gray4, col_cyan, col_cyan }, +}; + +/* tagging */ +static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; + +static const Rule rules[] = { + /* xprop(1): + * WM_CLASS(STRING) = instance, class + * WM_NAME(STRING) = title + */ + /* class instance title tags mask isfloating monitor */ + { "Gimp", NULL, NULL, 0, 1, -1 }, +}; + +/* layout(s) */ +static const float mfact = 0.55; /* factor of master area size [0.05..0.95] */ +static const int nmaster = 1; /* number of clients in master area */ +static const int resizehints = 0; /* 1 means respect size hints in tiled resizals */ +static const int lockfullscreen = 1; /* 1 will force focus on the fullscreen window */ + +static const Layout layouts[] = { + /* symbol arrange function */ + { "[]=", tile }, /* first entry is default */ + { "><>", NULL }, /* no layout function means floating behavior */ + { "[M]", monocle }, +}; + +/* key definitions */ +#define MODKEY Mod4Mask +#define TAGKEYS(KEY,TAG) \ + { MODKEY, KEY, view, {.ui = 1 << TAG} }, \ + { MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG} }, \ + { MODKEY|ShiftMask, KEY, tag, {.ui = 1 << TAG} }, \ + { MODKEY|ControlMask|ShiftMask, KEY, toggletag, {.ui = 1 << TAG} }, + +/* helper for spawning shell commands in the pre dwm-5.0 fashion */ +#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } } + +/* commands */ +static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */ +static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL }; +static const char *termcmd[] = { "st", NULL }; + +static Key keys[] = { + /* modifier key function argument */ + { MODKEY, XK_d, spawn, {.v = dmenucmd } }, + { MODKEY, XK_Return, spawn, {.v = termcmd } }, + { MODKEY, XK_b, togglebar, {0} }, + { MODKEY, XK_j, focusstack, {.i = +1 } }, + { MODKEY, XK_k, focusstack, {.i = -1 } }, + { MODKEY, XK_i, incnmaster, {.i = +1 } }, + { MODKEY|ShiftMask, XK_d, incnmaster, {.i = -1 } }, + { MODKEY, XK_h, setmfact, {.f = -0.05} }, + { MODKEY, XK_l, setmfact, {.f = +0.05} }, + { MODKEY, XK_Return, zoom, {0} }, + { MODKEY, XK_Tab, view, {0} }, + { MODKEY|ShiftMask, XK_q, killclient, {0} }, + { MODKEY, XK_t, setlayout, {.v = &layouts[0]} }, + { MODKEY, XK_f, setlayout, {.v = &layouts[1]} }, + { MODKEY, XK_m, setlayout, {.v = &layouts[2]} }, + { MODKEY, XK_space, setlayout, {0} }, + { MODKEY|ShiftMask, XK_space, togglefloating, {0} }, + { MODKEY, XK_0, view, {.ui = ~0 } }, + { MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } }, + { MODKEY, XK_comma, focusmon, {.i = -1 } }, + { MODKEY, XK_period, focusmon, {.i = +1 } }, + { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } }, + { MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } }, + TAGKEYS( 0x26, 0) + TAGKEYS( 0xe9, 1) + TAGKEYS( 0x22, 2) + TAGKEYS( 0x27, 3) + TAGKEYS( 0x28, 4) + TAGKEYS( 0x2d, 5) + TAGKEYS( 0xe8, 6) + TAGKEYS( 0x5f, 7) + TAGKEYS( 0xe7, 8) + { MODKEY|ShiftMask, XK_e, quit, {0} }, +}; + +/* button definitions */ +/* click can be ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */ +static Button buttons[] = { + /* click event mask button function argument */ + { ClkLtSymbol, 0, Button1, setlayout, {0} }, + { ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} }, + { ClkWinTitle, 0, Button2, zoom, {0} }, + { ClkStatusText, 0, Button2, spawn, {.v = termcmd } }, + { ClkClientWin, MODKEY, Button1, movemouse, {0} }, + { ClkClientWin, MODKEY, Button2, togglefloating, {0} }, + { ClkClientWin, MODKEY, Button3, resizemouse, {0} }, + { ClkTagBar, 0, Button1, view, {0} }, + { ClkTagBar, 0, Button3, toggleview, {0} }, + { ClkTagBar, MODKEY, Button1, tag, {0} }, + { ClkTagBar, MODKEY, Button3, toggletag, {0} }, +}; diff --git a/dwm/config.h.save b/dwm/config.h.save new file mode 100644 index 0000000..f1dc083 --- /dev/null +++ b/dwm/config.h.save @@ -0,0 +1,116 @@ +/* See LICENSE file for copyright and license details. */ + +/* appearance */ +static const unsigned int borderpx = 2; /* border pixel of windows */ +static const unsigned int snap = 32; /* snap pixel */ +static const int showbar = 1; /* 0 means no bar */ +static const int topbar = 1; /* 0 means bottom bar */ +static const char *fonts[] = { "monospace:size=10" }; +static const char dmenufont[] = "monospace:size=10"; +static const char col_gray1[] = "#222222"; +static const char col_gray2[] = "#444444"; +static const char col_gray3[] = "#bbbbbb"; +static const char col_gray4[] = "#eeeeee"; +static const char col_cyan[] = "#005577"; +static const char *colors[][3] = { + /* fg bg border */ + [SchemeNorm] = { col_gray3, col_gray1, col_gray2 }, + [SchemeSel] = { col_gray4, col_cyan, col_cyan }, +}; + +/* tagging */ +static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; + +static const Rule rules[] = { + /* xprop(1): + * WM_CLASS(STRING) = instance, class + * WM_NAME(STRING) = title + */ + /* class instance title tags mask isfloating monitor */ + { "Gimp", NULL, NULL, 0, 1, -1 }, + { "Firefox", NULL, NULL, 1 << 8, 0, -1 }, +}; + +/* layout(s) */ +static const float mfact = 0.55; /* factor of master area size [0.05..0.95] */ +static const int nmaster = 1; /* number of clients in master area */ +static const int resizehints = 1; /* 1 means respect size hints in tiled resizals */ +static const int lockfullscreen = 1; /* 1 will force focus on the fullscreen window */ + +static const Layout layouts[] = { + /* symbol arrange function */ + { "[]=", tile }, /* first entry is default */ + { "><>", NULL }, /* no layout function means floating behavior */ + { "[M]", monocle }, +}; + +/* key definitions */ +#define MODKEY Mod4Mask +#define TAGKEYS(KEY,TAG) \ + { MODKEY, KEY, view, {.ui = 1 << TAG} }, \ + { MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG} }, \ + { MODKEY|ShiftMask, KEY, tag, {.ui = 1 << TAG} }, \ + { MODKEY|ControlMask|ShiftMask, KEY, toggletag, {.ui = 1 << TAG} }, + +/* helper for spawning shell commands in the pre dwm-5.0 fashion */ +#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } } + +/* commands */ +static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */ +static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL }; +static const char *termcmd[] = { "st", NULL }; + +static Key keys[] = { + /* modifier key function argument */ + { MODKEY, XK_p, spawn, {.v = dmenucmd } }, + { MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } }, + { MODKEY, XK_b, togglebar, {0} }, + { MODKEY, XK_j, focusstack, {.i = +1 } }, + { MODKEY, XK_k, focusstack, {.i = -1 } }, + { MODKEY, XK_i, incnmaster, {.i = +1 } }, + { MODKEY,Shif XK_d, incnmaster, {.i = -1 } }, + { MODKEY, XK_h, setmfact, {.f = -0.05} }, + { MODKEY, XK_l, setmfact, {.f = +0.05} }, + { MODKEY, XK_Return, zoom, {0} }, + { MODKEY, XK_Tab, view, {0} }, + { MODKEY|ShiftMask, XK_c, killclient, {0} }, + { MODKEY, XK_t, setlayout, {.v = &layouts[0]} }, + { MODKEY, XK_f, setlayout, {.v = &layouts[1]} }, + { MODKEY, XK_m, setlayout, {.v = &layouts[2]} }, + { MODKEY, XK_space, setlayout, {0} }, + { MODKEY|ShiftMask, XK_space, togglefloating, {0} }, + { MODKEY, XK_0, view, {.ui = ~0 } }, + { MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } }, + { MODKEY, XK_comma, focusmon, {.i = -1 } }, + { MODKEY, XK_period, focusmon, {.i = +1 } }, + { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } }, + { MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } }, + TAGKEYS( 0x26, 0) + TAGKEYS( 0xe9, 1) + TAGKEYS( 0x22, 2) + TAGKEYS( 0x27, 3) + TAGKEYS( 0x28, 4) + TAGKEYS( 0x2d, 5) + TAGKEYS( 0xe8, 6) + TAGKEYS( 0x5f, 7) + TAGKEYS( 0xe7, 8) + { MODKEY|ShiftMask, XK_q, quit, {0} }, +}; + +/* button definitions */ +/* click can be ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */ +static Button buttons[] = { + /* click event mask button function argument */ + { ClkLtSymbol, 0, Button1, setlayout, {0} }, + { ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} }, + { ClkWinTitle, 0, Button2, zoom, {0} }, + { ClkStatusText, 0, Button2, spawn, {.v = termcmd } }, + { ClkClientWin, MODKEY, Button1, movemouse, {0} }, + { ClkClientWin, MODKEY, Button2, togglefloating, {0} }, + { ClkClientWin, MODKEY, Button3, resizemouse, {0} }, + { ClkTagBar, 0, Button1, view, {0} }, + { ClkTagBar, 0, Button3, toggleview, {0} }, + { ClkTagBar, MODKEY, Button1, tag, {0} }, + { ClkTagBar, MODKEY, Button3, toggletag, {0} }, +}; + diff --git a/dwm/config.mk b/dwm/config.mk new file mode 100644 index 0000000..b6eb7e0 --- /dev/null +++ b/dwm/config.mk @@ -0,0 +1,38 @@ +# dwm version +VERSION = 6.3 + +# Customize below to fit your system + +# paths +PREFIX = /usr/local +MANPREFIX = ${PREFIX}/share/man + +X11INC = /usr/X11R6/include +X11LIB = /usr/X11R6/lib + +# Xinerama, comment if you don't want it +XINERAMALIBS = -lXinerama +XINERAMAFLAGS = -DXINERAMA + +# freetype +FREETYPELIBS = -lfontconfig -lXft +FREETYPEINC = /usr/include/freetype2 +# OpenBSD (uncomment) +#FREETYPEINC = ${X11INC}/freetype2 + +# includes and libs +INCS = -I${X11INC} -I${FREETYPEINC} +LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} + +# flags +CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=200809L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} +#CFLAGS = -g -std=c99 -pedantic -Wall -O0 ${INCS} ${CPPFLAGS} +CFLAGS = -std=c99 -pedantic -Wall -Wno-deprecated-declarations -Os ${INCS} ${CPPFLAGS} +LDFLAGS = ${LIBS} + +# Solaris +#CFLAGS = -fast ${INCS} -DVERSION=\"${VERSION}\" +#LDFLAGS = ${LIBS} + +# compiler and linker +CC = cc diff --git a/dwm/drw.c b/dwm/drw.c new file mode 100644 index 0000000..4cdbcbe --- /dev/null +++ b/dwm/drw.c @@ -0,0 +1,436 @@ +/* See LICENSE file for copyright and license details. */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <X11/Xlib.h> +#include <X11/Xft/Xft.h> + +#include "drw.h" +#include "util.h" + +#define UTF_INVALID 0xFFFD +#define UTF_SIZ 4 + +static const unsigned char utfbyte[UTF_SIZ + 1] = {0x80, 0, 0xC0, 0xE0, 0xF0}; +static const unsigned char utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8}; +static const long utfmin[UTF_SIZ + 1] = { 0, 0, 0x80, 0x800, 0x10000}; +static const long utfmax[UTF_SIZ + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF}; + +static long +utf8decodebyte(const char c, size_t *i) +{ + for (*i = 0; *i < (UTF_SIZ + 1); ++(*i)) + if (((unsigned char)c & utfmask[*i]) == utfbyte[*i]) + return (unsigned char)c & ~utfmask[*i]; + return 0; +} + +static size_t +utf8validate(long *u, size_t i) +{ + if (!BETWEEN(*u, utfmin[i], utfmax[i]) || BETWEEN(*u, 0xD800, 0xDFFF)) + *u = UTF_INVALID; + for (i = 1; *u > utfmax[i]; ++i) + ; + return i; +} + +static size_t +utf8decode(const char *c, long *u, size_t clen) +{ + size_t i, j, len, type; + long udecoded; + + *u = UTF_INVALID; + if (!clen) + return 0; + udecoded = utf8decodebyte(c[0], &len); + if (!BETWEEN(len, 1, UTF_SIZ)) + return 1; + for (i = 1, j = 1; i < clen && j < len; ++i, ++j) { + udecoded = (udecoded << 6) | utf8decodebyte(c[i], &type); + if (type) + return j; + } + if (j < len) + return 0; + *u = udecoded; + utf8validate(u, len); + + return len; +} + +Drw * +drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h) +{ + Drw *drw = ecalloc(1, sizeof(Drw)); + + drw->dpy = dpy; + drw->screen = screen; + drw->root = root; + drw->w = w; + drw->h = h; + drw->drawable = XCreatePixmap(dpy, root, w, h, DefaultDepth(dpy, screen)); + drw->gc = XCreateGC(dpy, root, 0, NULL); + XSetLineAttributes(dpy, drw->gc, 1, LineSolid, CapButt, JoinMiter); + + return drw; +} + +void +drw_resize(Drw *drw, unsigned int w, unsigned int h) +{ + if (!drw) + return; + + drw->w = w; + drw->h = h; + if (drw->drawable) + XFreePixmap(drw->dpy, drw->drawable); + drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, DefaultDepth(drw->dpy, drw->screen)); +} + +void +drw_free(Drw *drw) +{ + XFreePixmap(drw->dpy, drw->drawable); + XFreeGC(drw->dpy, drw->gc); + drw_fontset_free(drw->fonts); + free(drw); +} + +/* This function is an implementation detail. Library users should use + * drw_fontset_create instead. + */ +static Fnt * +xfont_create(Drw *drw, const char *fontname, FcPattern *fontpattern) +{ + Fnt *font; + XftFont *xfont = NULL; + FcPattern *pattern = NULL; + + if (fontname) { + /* Using the pattern found at font->xfont->pattern does not yield the + * same substitution results as using the pattern returned by + * FcNameParse; using the latter results in the desired fallback + * behaviour whereas the former just results in missing-character + * rectangles being drawn, at least with some fonts. */ + if (!(xfont = XftFontOpenName(drw->dpy, drw->screen, fontname))) { + fprintf(stderr, "error, cannot load font from name: '%s'\n", fontname); + return NULL; + } + if (!(pattern = FcNameParse((FcChar8 *) fontname))) { + fprintf(stderr, "error, cannot parse font name to pattern: '%s'\n", fontname); + XftFontClose(drw->dpy, xfont); + return NULL; + } + } else if (fontpattern) { + if (!(xfont = XftFontOpenPattern(drw->dpy, fontpattern))) { + fprintf(stderr, "error, cannot load font from pattern.\n"); + return NULL; + } + } else { + die("no font specified."); + } + + /* Do not allow using color fonts. This is a workaround for a BadLength + * error from Xft with color glyphs. Modelled on the Xterm workaround. See + * https://bugzilla.redhat.com/show_bug.cgi?id=1498269 + * https://lists.suckless.org/dev/1701/30932.html + * https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=916349 + * and lots more all over the internet. + */ + FcBool iscol; + if(FcPatternGetBool(xfont->pattern, FC_COLOR, 0, &iscol) == FcResultMatch && iscol) { + XftFontClose(drw->dpy, xfont); + return NULL; + } + + font = ecalloc(1, sizeof(Fnt)); + font->xfont = xfont; + font->pattern = pattern; + font->h = xfont->ascent + xfont->descent; + font->dpy = drw->dpy; + + return font; +} + +static void +xfont_free(Fnt *font) +{ + if (!font) + return; + if (font->pattern) + FcPatternDestroy(font->pattern); + XftFontClose(font->dpy, font->xfont); + free(font); +} + +Fnt* +drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount) +{ + Fnt *cur, *ret = NULL; + size_t i; + + if (!drw || !fonts) + return NULL; + + for (i = 1; i <= fontcount; i++) { + if ((cur = xfont_create(drw, fonts[fontcount - i], NULL))) { + cur->next = ret; + ret = cur; + } + } + return (drw->fonts = ret); +} + +void +drw_fontset_free(Fnt *font) +{ + if (font) { + drw_fontset_free(font->next); + xfont_free(font); + } +} + +void +drw_clr_create(Drw *drw, Clr *dest, const char *clrname) +{ + if (!drw || !dest || !clrname) + return; + + if (!XftColorAllocName(drw->dpy, DefaultVisual(drw->dpy, drw->screen), + DefaultColormap(drw->dpy, drw->screen), + clrname, dest)) + die("error, cannot allocate color '%s'", clrname); +} + +/* Wrapper to create color schemes. The caller has to call free(3) on the + * returned color scheme when done using it. */ +Clr * +drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount) +{ + size_t i; + Clr *ret; + + /* need at least two colors for a scheme */ + if (!drw || !clrnames || clrcount < 2 || !(ret = ecalloc(clrcount, sizeof(XftColor)))) + return NULL; + + for (i = 0; i < clrcount; i++) + drw_clr_create(drw, &ret[i], clrnames[i]); + return ret; +} + +void +drw_setfontset(Drw *drw, Fnt *set) +{ + if (drw) + drw->fonts = set; +} + +void +drw_setscheme(Drw *drw, Clr *scm) +{ + if (drw) + drw->scheme = scm; +} + +void +drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert) +{ + if (!drw || !drw->scheme) + return; + XSetForeground(drw->dpy, drw->gc, invert ? drw->scheme[ColBg].pixel : drw->scheme[ColFg].pixel); + if (filled) + XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h); + else + XDrawRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w - 1, h - 1); +} + +int +drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert) +{ + char buf[1024]; + int ty; + unsigned int ew; + XftDraw *d = NULL; + Fnt *usedfont, *curfont, *nextfont; + size_t i, len; + int utf8strlen, utf8charlen, render = x || y || w || h; + long utf8codepoint = 0; + const char *utf8str; + FcCharSet *fccharset; + FcPattern *fcpattern; + FcPattern *match; + XftResult result; + int charexists = 0; + + if (!drw || (render && !drw->scheme) || !text || !drw->fonts) + return 0; + + if (!render) { + w = ~w; + } else { + XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].pixel); + XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h); + d = XftDrawCreate(drw->dpy, drw->drawable, + DefaultVisual(drw->dpy, drw->screen), + DefaultColormap(drw->dpy, drw->screen)); + x += lpad; + w -= lpad; + } + + usedfont = drw->fonts; + while (1) { + utf8strlen = 0; + utf8str = text; + nextfont = NULL; + while (*text) { + utf8charlen = utf8decode(text, &utf8codepoint, UTF_SIZ); + for (curfont = drw->fonts; curfont; curfont = curfont->next) { + charexists = charexists || XftCharExists(drw->dpy, curfont->xfont, utf8codepoint); + if (charexists) { + if (curfont == usedfont) { + utf8strlen += utf8charlen; + text += utf8charlen; + } else { + nextfont = curfont; + } + break; + } + } + + if (!charexists || nextfont) + break; + else + charexists = 0; + } + + if (utf8strlen) { + drw_font_getexts(usedfont, utf8str, utf8strlen, &ew, NULL); + /* shorten text if necessary */ + for (len = MIN(utf8strlen, sizeof(buf) - 1); len && ew > w; len--) + drw_font_getexts(usedfont, utf8str, len, &ew, NULL); + + if (len) { + memcpy(buf, utf8str, len); + buf[len] = '\0'; + if (len < utf8strlen) + for (i = len; i && i > len - 3; buf[--i] = '.') + ; /* NOP */ + + if (render) { + ty = y + (h - usedfont->h) / 2 + usedfont->xfont->ascent; + XftDrawStringUtf8(d, &drw->scheme[invert ? ColBg : ColFg], + usedfont->xfont, x, ty, (XftChar8 *)buf, len); + } + x += ew; + w -= ew; + } + } + + if (!*text) { + break; + } else if (nextfont) { + charexists = 0; + usedfont = nextfont; + } else { + /* Regardless of whether or not a fallback font is found, the + * character must be drawn. */ + charexists = 1; + + fccharset = FcCharSetCreate(); + FcCharSetAddChar(fccharset, utf8codepoint); + + if (!drw->fonts->pattern) { + /* Refer to the comment in xfont_create for more information. */ + die("the first font in the cache must be loaded from a font string."); + } + + fcpattern = FcPatternDuplicate(drw->fonts->pattern); + FcPatternAddCharSet(fcpattern, FC_CHARSET, fccharset); + FcPatternAddBool(fcpattern, FC_SCALABLE, FcTrue); + FcPatternAddBool(fcpattern, FC_COLOR, FcFalse); + + FcConfigSubstitute(NULL, fcpattern, FcMatchPattern); + FcDefaultSubstitute(fcpattern); + match = XftFontMatch(drw->dpy, drw->screen, fcpattern, &result); + + FcCharSetDestroy(fccharset); + FcPatternDestroy(fcpattern); + + if (match) { + usedfont = xfont_create(drw, NULL, match); + if (usedfont && XftCharExists(drw->dpy, usedfont->xfont, utf8codepoint)) { + for (curfont = drw->fonts; curfont->next; curfont = curfont->next) + ; /* NOP */ + curfont->next = usedfont; + } else { + xfont_free(usedfont); + usedfont = drw->fonts; + } + } + } + } + if (d) + XftDrawDestroy(d); + + return x + (render ? w : 0); +} + +void +drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h) +{ + if (!drw) + return; + + XCopyArea(drw->dpy, drw->drawable, win, drw->gc, x, y, w, h, x, y); + XSync(drw->dpy, False); +} + +unsigned int +drw_fontset_getwidth(Drw *drw, const char *text) +{ + if (!drw || !drw->fonts || !text) + return 0; + return drw_text(drw, 0, 0, 0, 0, 0, text, 0); +} + +void +drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h) +{ + XGlyphInfo ext; + + if (!font || !text) + return; + + XftTextExtentsUtf8(font->dpy, font->xfont, (XftChar8 *)text, len, &ext); + if (w) + *w = ext.xOff; + if (h) + *h = font->h; +} + +Cur * +drw_cur_create(Drw *drw, int shape) +{ + Cur *cur; + + if (!drw || !(cur = ecalloc(1, sizeof(Cur)))) + return NULL; + + cur->cursor = XCreateFontCursor(drw->dpy, shape); + + return cur; +} + +void +drw_cur_free(Drw *drw, Cur *cursor) +{ + if (!cursor) + return; + + XFreeCursor(drw->dpy, cursor->cursor); + free(cursor); +} diff --git a/dwm/drw.h b/dwm/drw.h new file mode 100644 index 0000000..4bcd5ad --- /dev/null +++ b/dwm/drw.h @@ -0,0 +1,57 @@ +/* See LICENSE file for copyright and license details. */ + +typedef struct { + Cursor cursor; +} Cur; + +typedef struct Fnt { + Display *dpy; + unsigned int h; + XftFont *xfont; + FcPattern *pattern; + struct Fnt *next; +} Fnt; + +enum { ColFg, ColBg, ColBorder }; /* Clr scheme index */ +typedef XftColor Clr; + +typedef struct { + unsigned int w, h; + Display *dpy; + int screen; + Window root; + Drawable drawable; + GC gc; + Clr *scheme; + Fnt *fonts; +} Drw; + +/* Drawable abstraction */ +Drw *drw_create(Display *dpy, int screen, Window win, unsigned int w, unsigned int h); +void drw_resize(Drw *drw, unsigned int w, unsigned int h); +void drw_free(Drw *drw); + +/* Fnt abstraction */ +Fnt *drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount); +void drw_fontset_free(Fnt* set); +unsigned int drw_fontset_getwidth(Drw *drw, const char *text); +void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h); + +/* Colorscheme abstraction */ +void drw_clr_create(Drw *drw, Clr *dest, const char *clrname); +Clr *drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount); + +/* Cursor abstraction */ +Cur *drw_cur_create(Drw *drw, int shape); +void drw_cur_free(Drw *drw, Cur *cursor); + +/* Drawing context manipulation */ +void drw_setfontset(Drw *drw, Fnt *set); +void drw_setscheme(Drw *drw, Clr *scm); + +/* Drawing functions */ +void drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert); +int drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert); + +/* Map functions */ +void drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h); diff --git a/dwm/drw.o b/dwm/drw.o new file mode 100644 index 0000000000000000000000000000000000000000..769ec788f1a0bd7c34ebe2f1e6bd6ac9069cf045 GIT binary patch literal 10536 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 literal 0 HcmV?d00001 diff --git a/dwm/dwm b/dwm/dwm new file mode 100644 index 0000000000000000000000000000000000000000..476b18d562357e15a8d9fc847f599a67f474f0ce GIT binary patch literal 61712 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� zQv;(xL%@s-%nT>NZ3jquV#~y7Y@m_&*HAH$%uHSe24;qDP=2XYCMReVl7Stf9yT5g zYgaTt2WoFX$EjiB22k+_XyR)oL(F-BCSDi}5&wWDz5%M9VGl$eX8snaI0u^eqacVn z1vK#;Q1u#U;=7>Y2590IlOX0;po#B+s&_yW-v<@<KodUz6%RlYKLizzKodU#6;D7D zKL!<_fF{nA265*CG;yU0i1-FH@qOhG@f~R5&QS3aXySKLA?hEXi3esv#5thz46t}n zftn+LCjOxeqFw<_d~H2M+yG5{Q3*uc0!`dB2_l|=CcdW-BHn=}u9yuGpMWO*ARQup z;xL4UxgW;=fF`bz15qb%1VY2q!^9=f#9`^x08RWm)V~2};$L$i=0>22A2<UMFF+Ib z0}VJbFfdF&6JG=M?*=q+*+z&t7tqAzsvzPY(8SZB;V*C$A`kQLOV9)XXc`PnTn(x| z08Je3FEsH7Fn^(m!_-%xiNnHS0-CryG~70ziN`|ybpeO?2Q=}&u=qWO>R*_+0h;(s zsQLgL;st2puy~(<CJqb#4QS$NP=8%O6Nja@8))LNa`pq7I86NyG;vrtD{vguzcBR@ zXyWknj3y3KAAlwfONRw$;xPYCKof_hs|{%49@P-{UBDs!0Zsf>14O;R2?z~Kw=i)7 zG;x@F0?@=^>AwI?9OljmXyUN+zX44gX8r{<ahUlZ(8OWp3!FrCKg@gsG;x^u0ched z^9#_#VdhUj6Nj0<0Zklc{slB~nE4;j#9`(OoWkLLG;x^u0ched^9#_#VdhUj6NkGW zO&n(a1vGJ(`5(~4Vde{*#^HW6ahUl5XyP#Q3(&-2=1)Kqhr1t59A^FnG;x^uAJD{M z<_kc}S6KRonQwq54l_RhO&n%^0h&0>{0V5{F!MK{iTC+H!Vy+}!`#yWZO_2!0ho9< zRQv^+Ia8tHAJD`vK<nurXyP-V>KV|+!33b|2RP8g=Rnm9poud;)k~m>FMz67KokD} z71ux$Ujh|3Kofre6}LbWUjY?&Kofrf6;D7DhuNEfCJu9d0h;&^s5upA;xO|Y(8OWx z?7$&D0Zse_)cgbcA@L7dV*p*c0v0%dB#u09cL7NpG?xfg%)r2K14-NvCdk0R@Bm31 z+5`m4!p1*A>nv)(A`n6XG%(J<0PfC!=4K(H3=9fL;-G#KOk4v=oEatvYX2aKBd@El zKoSSp4b$R)Bn}D-n79X$IJAoemI^=;hvf~BL<EvJY>fy=JON3Z3nT!=8A#&XP%#iy zfF#ZX5`f|gBynD-7>H^>66XU6Kye3>I6qVjL`^^v2dzZ`iGlD8Byr?<#|22@!XSlE zyaGuawC)8e%&-ATTofkAz`(ErNn8v``~Z@;IFk4YBykBO@e4@e(4|^n*&9gWQeY7X z@c>C&8X^QHUm%GiFQEB=Bo11;0anbw!0-b}Tn;7(q7Q-yNV=7WFu^1Tk~s1@0|6v) zMX*W;A%P^W3=sm83P|EAU=awRfh4X95dxD2NaAW>5eQ*{B(4q-0+S9%;u>HP2;qSw zt_cwWlL1KLT3`_f5rHJG4G{v92}t6)U=awBfh4X65dxD1NaFfn5eQL%Bo11q1rcRn zXh0H&tmJ~obRdZvLxjNO1SD}2un2^hfg}zZiGqkSFf2e4H-iZ>Ffgn@5;sQ@-+&}; zfh4{IN!$`i`~Z@;6_WS~Bynpb@e4@eHb~+(ki>0~#2+Au+aZa+KoW;84F$`7KoW-z z6@kTnAc;GIMWDnX2n{MDoghpw$$=#93>JY90!ZSpHHaV?2_$h>kN^}bAc=$Kz@fqn z8c5>qFhNlHk0kDaByNEu?ujJsfF$mPB<_JE?u{fKfFurWLV;x?ki>n#A`l`0N!$-2 z1ST_(#Qnh{5TXD{JOCmDCM%G{1HmE?q5(-9I>ZK+=s*&O4&i~tCm@N3fJGq03?%VT zh!B`ufFurDI|CL3rGF&xaF`$i1H%R+ap)3Uu<Q;b@kp=;ggAgC9t9BslP8eGqroB& z;sTO*3`7V_-arzM1&ct42T0;^5Fs%60!cg`ECL}uAc-eHguvtvB=JPB2$X=fb3y4J zIs^um;6M^j28%!l0VHwI+9HT31A_#TICN+aETw=X4jobii)$c>Lx;@3;s!|K8DJ3z zVSywL9U=rvI3S5<fkhyM2a-5+=n5<mfFuqbY5|K!Ac;eVNWkI=NaA^55eSiiB%Tiu z0+R(u;ssz42vLC~UIY;WlMP7Xpfzh?K?Vkf4kU5t5Exi$0+M(sSOh}MKoW-ziGn2- zAc;eVP{HCWki?-wx?u5vCO-4a{qksj!{O1*y0M>u!K3v+3Df@z9?eIf3G%<`qkaa4 z|Ef>=85sEG9T@(rg81N+^76s||NsB1-s)#y$N)9LUtR$7FM;@=ruWMOVE!o(AJpW2 zxdF^S1mc65+AkM?`MW@TP!s#*1TcRSh!1L7zia^WSAqDT?DDbz%wGiJgPPJW6Ttjg zAU>!G{W1W|p9JEAn$9mB!2B){AJk-iX#nOof%u@N@=FCUzY4?$HIZKmfcZrrKB#H@ zk^#)m0`Wmj;+G%(f&7~U;)9yPFCT#UQ6N63OZ4&rm>&e<gPO!I4}kezAU>!m{Bi@B z?*!t5n!qm?fcaJ+KB(#Yasrrd1mc65ye}KTd@T?k)YN@h0Ol)!_@E~4%LFiA3d9FB zZC?g}`9dH*s7d?M0nFzD@j*@5mj+-y6NnFL!oE}h^MCa*Fl2z5t}g|^{7)c0sLA@0 z0nC2|;)9y1FF*VR`Tr4!4{D;md;sR(0`Wmj)0Y>({7WD{s4MvL0GNLY#0ND|Uv2>N z4}tigrs>NCVE!%;AJim$IRVVy1mc65qAwf3{8b=6s0sSA0L)(m;)9x=FB8E0Ss*^B z$@ww>%%23}gPNKz9l-o95FgaUd}#pYH-Y$|F6m1JFuw}K2Q@Wc3V``VAU>#x`H}(5 z&jRs5P0N=b{($_S1mc65lrJBE`B5M~s4M&O0+=5J;)9x&FAsqEULZcGN%?XEnC}GQ zgPM{r7l8RzAU>!G`Eml7Zv^6lnvO3Uz<ezbAJk-gSpeoMf%u@N;>!duUkbzrH4$G1 zfcZioKB#H<(gDop0`Wmj!j}eMJ`;!!Y6`wo0P}zKGB9L-nt(3_!2C}jKB(#Uk^#(r z1>%F6d@n!z2KoOHh!1M&y?g-X-vaSLO}v*E!2C-fKB#H;@&K5B3d9FB>0WLC^ACae zpr+i*1z`Rz5FgZpdpQBj-vr`=nr<%}!2DGpKB&p|vH;9q1mc65YA+MO{8=DAsEPJ6 z0L-5R;)9xIFCD=AE)XBoBztK9<~M=(pr+VM1u(w~#0NFOUJ8KuMIb(?>GhHU%+CVx zK~1igAAW)Sp9JEAnp!U(fca4%KB$TH@&cG21mc65Rxb~L`CcGCs7dv51DNjw;)9w} zFBgFMRv<p83H5RUm~RB)gPKk+8^C-m5FgZJdRYMGD}nf+rqas<FkcG92Q`si27viO zAU>#R^wI&$=K}FTO`?|uU_KLw4{8d%Q~>jT^)N7GfSN!r1;G4IAU>$+^O6C~e+A-$ znmjK*`~>;`5r_|J>b!ga=HCMGK~0>O7r^{WAU>#R^YQ?ge+tA0HECXM0P_!l_@JiD z%LQQmE)XBogn2mu%-;m!gPJZc8^HWkAU>$c^0ENTUj*WVDxjAMVE!x+AJjy7835)_ z0`Wmjla~%)eiw)jYLdJ(0P~wbd{9&5r2?2=1>%F6ATI^L{2~w^)bx1C0On_b_@E}o z%MU+5{!aq&K~0U955W8=5Fa#T_3{Fk9|Yoqnj9|={P_RhG2AiCG1M_6G}xo@O$8$Z zLyAW?iz=x2^5|?)0o9v^2b%vgmCAZ_mvMOX+OCdbV0hvF_y2#7UfW4g3=FLYO4(lX z{y$&B=h16BF^Yk~@W6{we+CARUftXX1_s0b9-Z%AZ2$NFzenqVQc;g?)6-KylD1_a zbMF8C|Nk}Ti-=$U|F<3}d1Uzih3>Ea|2;Zcr%eM_^`$%>y|x)3l}cbEZHq-27+!FK zOzXBSn#RDe3$&Qgqmxx`Is=18a{B`Y1_qCV57<4J+h2f~-30<Kxc~hB@6m1RGL3=3 z@Y@Sr5U<zP9%RlzkT1GzwIDLWfByeB{QqLVC<B8>x2-710Z;=wk9D%%1o4qg4iM<} zkZ|dCkn!jgJu#Jmp_6yhGzJEjPS)kq7#Lo3a56CL0<}3jdQDGFVPNp+JnqrSx??H> z!;4HVgx8iuf&$YIWFzZrP`GqESadsZbh3s`V_;}Lz|_ea3Nr1K3`m7-<5UI)!%H5$ zrkx;d$snI}+vdOo8zLDPJUfrP@P>$oz{E=<LDsWg0okn&k+Xowt%1lL0Lg*;@6l~5 z1C#TE$gKg%eg6#(Lk5_f14M2HNbWX7?#UFW<IEv)Iv~0I5V;dDIW36Xizy5YFBU`O z*1+VXA#ztha_tbg2{1Wch};2?TsB0m1SZD?kpr3Y!XF|R0h42g$jt!hGlt07z~uf% zfWxH+Bqt7$Q-I0+gUD5Y<bH!vWVh{~$qWqpK(&HLCu;^s{Dc5FQl5asK@Db)PFB#^ z_=^n?@iQQCP%Y}w$qE|NelbIUfngu0S-2n6_Vnmvy)>DD;f1p=*pzvb85nkf+Mpi2 zrdg9f4m<48$qJfVcwx^8R#AhbA_1&|*`r&w3}l8ZNJXbJhexlh8Hk@M%fRqro(V{s zsqSP32E&tvmjXPxZ5<~wFgWf6rAo&gATo;q1YfNB_W!>}^AQDC!;?Ef&7>?wk8aV} z$sk7@bKC)HNCkUz+p>TKSg%fEV0e)M3X)#diZBL-EM|{xQH9A23;`b9raLAvFt{3? z^yz%)(QSKq5(9(d4v>dmSb)?+Z1Ct7Wtz;u0J6h$;v@zJu#E^?=7Ego1S#)jJv51d zA&b+aTXg3ni1CRK<9CAE<{sU)MPLg+?t5|lCn$Z2UI2wlx2YwFYCfXi(QWGoV)n+U zDERc&s7UzqmZ)&N@B;a_o7EX4)p>Ilg9kXESU}uvTUjv0;BnkVC8LBPiUCvzb}%q7 zyjTKqRCkC<hDW#Qjfo&FwjU=lFuYjv{r~?Lep;ZC?uDlrsA%(15%BH&;nVraquX>H zMCI{`3=BTKJ}N9Ab3sjGh8H5>GLOH7g%K2HPdvI^R3u!iQ&d=ri(NaPdUV@P25IfQ z<<)KS;>GnJ-~uwFd5_8r25`aVq9Rf13X=2aw#@{Y-udZ;;!lvOQa!L)%{3}DOkUkK zFG_{Me2>n1Al?fzI|hc=+%K$D7#KX7e=wIka{Pbfb)&1{6OZm1m<uvNE&yBo-lN-= z3*^mEhzq<RW_8<soxs50)A<SHf)^_xa`^4tXA8FXkTSBp-5#y~OITlYd;&$E?ZOG5 zBHE`{x1)}M;YIVe|Non9FSIf+FqB&F0QGcyI{$lg=BOxmbh@ZWfI<>fOEJ9oVGW86 zR__T64BY`P9-VV8fTrd>x@8?FFfhEf@abKmvH~1twhmxNKYO9^6&z5jJd#_$Ql8x| zN5MVIexJ_g|1Z4m@aT>%@MyhVBIMCsodI&=JHu};zM3&Gyng4=&3hBn5AC-7)DNnE z8bEG-A@&*UgYzJn*8e5!FE;TrFuZ<ic-x~__ZCR7yW}pYTG<9-|3CcV6b~pEelwRo z^XQfZ_iMYYUo?UZspfc50cMzHf)sb#g8GLqu7ZVZ%la7@UMyt+dDs@z4>bJtBKj-X z>Xd#^MhDk9`#_odg)&6k2W*JwTrg!S2h#5eF$>g>d(jJKLn`_d4{b=zU&8vr6r{WH z2&h3|cpy5~F~%|0G0rjm@B~nQ-0-bu=fyaW&PN{2Pd)^MxEdZXJn7MEyYc(~|Nlj` z8yFbAr0Ma?LlzEs^x9tR1!W6XP&?bh@<)lNM>p%cdT=FJ!ukIJzdR_q7!E^ek6zn_ zVD+Y;cC&}(Kab829tYpqdmQ}1?7?`<<Kn*(5sz-xtxy9v{y#|Lmv>=+>j$~7!8W%S zlx&PcJ(_JNffhn}bUrQN_2{-OYi3~hFWOMg!0;mZ|NsBTSY3J<7#L#@Biws94Z#MD zCxFa*ng0L(|IVL=mwb9zzXX7?GViAV1_sA276Hf3Lyn54T&+X|OS!*a@aPm%{K3EN zz+sR7hdi2pv6kNPIL-zdIxswN7}Ut}?EDfM?9ut#qxp>lQaj5<g~RZGN9(texbAWR zkM4R7pUy`wE`wsG^C+m<B<s;_JEaGd;U0PPn!fV`H?lT={r~^vc?OW^^B2#){{Qa@ zQJn12ZJQ2P{0gGD?d$*lud_WmuX(gyD$xX4;cEEyMZgzOV+(ABu1B}2VGk&tY@hov zFuZX6^#A|s62k)?y|({A{6(&yG{>R}D!ll)J-TZpKrInaiPmfS0i<9GBu|Mq*Ql^C zln8iqS95rDzB7FL;`h7%|6gnE1Lf8I;Dj0A#=y`W%EBDV&>6tt(H+d;)0rXR(JA23 znIYiOc@$K_a3CkeRiM(L`G|x^=L<+eJPgW_8lfJYe?7YEB|se37ozV#xuBN8qq|h# zMF)t}`9Aig{)hkn4?Bjtb{=;ObL>3l80y)1)iDI56YP{=kK}v%Kt08P7rR{<7+gAk zx^#Z>>3rwWnZe=F`QEehNN0qA$HB+!9?Ww=?MaYBUAmnuTsjS0IxARSFnsy{AFTYn z;YrU<7ZnA=OD}pp{{Iiog&v*nT_M669-YS^HLl^w7k57V{~zVk`2gY-aGnDBAk;C` z5#%<<&M%+@(rNC|U9Qj>&H_pmoS^u6p$tk7pioVA7I5i&>C*Ygqq|rFskQ6U?O^dD z7o@7wSs@yfV-FvOx9wa1m$-q<as;Km&Z|DXCf6MIf}+FK@QJ78+j3>k?y?_-mpnS} zzX%33i(3zru={i-D0p@r@%(?(v-usz>l;3u$ri7fT@9Z^`*c2l775_E5Ces%M|Zu# zi+BG)De8Uf%gBHK{~v}3mn(qXpA3q|?othp?plr)Y45?&W$|J!OhXGO&RV~PdURgp zpK`#X^%DP-LmU@Moj`$O>(lMe;gRev;Mw`Xqw^)m&z{VUkQh1d(H#)r(Ouy1;?sL@ zsV?Br`Oc%)HqnQHA@=2KCkBRCa43Kb4hH2rkJfJ>3z~m1@=pWV;OW`<7i5W}XXiJM z&iDI3BWEwxI77-O9mCrmo%cMuMeg}@zW4Zl*yG?c7EtxW;lX(9g)hkMmUqDkw*1Cx zCc^_B%||4nV?jkFI9ymfI?FBKEQ7<)z7{B+LxY36LsT3*TL1I6G=Xa;cLPw=v>qra zbL{-$*m=&S^Qdd*`PNG%Y#!YK0<W1px&=JCi#0$Q>&5f8|NpzT{`cq(2J=0-ixo=b zI&)MUTsuEHM!R;th<53G2#q1f_?IW%{{R2~tZT2|f7i|zE}aiSDjlN`DexuxyZ`?q z5PYzct%5x}KlyaWYk-{94T;3SAjd$*&XYc!Hyr~UJ1_WjUV8E74Jan7IY2E)!*9_q z&%6U=xsXs$SSz5EaT1_1?th7cXXi&yO0@6*6?UD!J-Y2ZJJ0xZ9__s7)9a$b<I{QS zMf&^y|9xAZlyLIzcTo{>>|{~#XnkA4*6qyE>B;~KZwcfAq7#&KnvW=eJOB&h5ZBH# zp`B+zdC8;kO$NBeY*7InrqCIpqR}0qqS0BRqTtf$qN3x{y+>sQNI|EI3J2#WBsaIH zM6iI0g#(-?I4|(Gq_cnuUT~BZfYdiv8!+&<q_QwD9CuMs0c9po3aC-xVBl}@hbXXM z;BNu#Xl<@hQDG<*1T|VfB`Cx9tDQM2EU#+~4}hZ)60M+QdGG;?2eY$*N4LNWCUD4t zVz^krvGb*4K(~vEiHqh_Pznfe>2^`E==M=Dc=7r*Gy;;HK?y_wlsn-4UylHf?f{1u z)8GI9@4}d(VgO3J8l5>RB94)cQDDn`x{EFNryekT>uPx017v%ri;4j#h&e!Q!cG?z z0T4%kf1iaz%YXhBHbzh#QKI7U;?0l$|9!e^R6IO7k9zjH{|B`u%QGQ`ibrpWN`SBB z`x14qW{-nU*_`<I*=W4j{^S3D56+_=%{3|k45c36qUA43=@pM&)?!Zv1}{sUAN8gl zy{u|bPK|~~Z!3ew|NkDg|JfNBcKrR%z~I5}_TshZUJ%m}T#Ucw@a=pL=KFMKTXeqi zZGBtf>e_m{M9vYkTb#ky@?EK^4`YprfGgu4h>)w{+t*5--KF4qsxw5z;>DAf|NlF7 z9&SBQddjyuSD`yZ#p3lgm(Cl_9~he-F#5K><)3=U)$lgQ1^$-T|Nj36m4k0xTc7Z^ zfX*HA=q^#=0Ch1OTn!JnbUyOw{OQyA{l(Wm|NlES{`toY>UaHTW?*pT_dDa8e6rg` z#lhM|g{4djtkI?Ol&j$Zh#sF#9~Fxid;WmJ)<?y{^Z&`xi!a+i1w?O%N`!Cn6R-}S z&XXRU*FP_DI_AO?!Qg9orcBJI^OR?==U)%Yi^W_X|4$ur5sA<%{RmEXC61omVFKMg zDmtJP?x^j@0W!qk;!9>O59VTn0LMU3Vgj}QHC%dG7`uH`3_zWgj28+o{{N4P>~>M% zV02MY&~#B@0Y_&8C{^o$`z^OYVJ!p}^##?NE-D-^_y7I>|Apy`|NlGRId;DH=sfP( zdGtl<Gf*mZw(w}KkYFeUjTJp|1LdX{p0=Qdg|mf6cZI}@`_DiX>MM_4Q)YMYXog4U z@fTiiVKr*6=@&OhdnfGG|No!{h-nE_z!fau)A`Ks|BIckL8d%^q4?(i|L$UN6#H~O z^62$Zad~0;5+wKDxAQ9~D{#E%eFfq_e{uCG$bBIy93HKgO1UA4<fY30|NjlYf$Bv2 zZ?N`NiIzuq0oY8J&R;LqJqOh}C1M`k&K4e>hdjC+6hIBOFFu`F3a@wibiRKP@EsJD z*%q%?gA%<2LkSlspe0@`dH(;u;Q?^`@VmOGuynepuynhqC@{OIu)G$56qUT7as|}i zdkGmVnF214QarRpzyow8tS|ar{{QdMcm!0wfl5D6&Ept<7@}L#qq*LKp+p{3*h&Ss z8lD8V)3X>1FNGO?dvOKSpKU%OaoF&{;lqw0u7*!SgF)4xwnyjh&adEn1s<(<vCsw* z6RihI_(4Ta=erjto`6DwMFrZ7ISjHvGSs8<E2yIP=r((C{Ry-gu<qIa|A#%g+Z({e zMnHr|w?hP^572s`M8KnWLIFsky8%SKe&*5L4q|w8G9C8lo(|U2?Udos>y?45rvua} z@#t;<QD8kFhDRr(hh<elsg4IoN9%zSd5`W6kO|#|4&6Q*J(N2F7#SE!Ibr(lcyu}? z9QNq^0h&<MXx<S4D!xlV(jXVSe(BLY0j%50p*y6@LwN#7cge%U$60Nllct9qJ5Tv^ z%U*3{U<h{U<q`Mj=Dpa+z+iaWk@1s9>&cSP?m&ZXM+=v3M-#>iE|w=8`TY-C{^Iw! zu6bb>C`$P~4s{3GxG)}avApES?|;eB@`DS%&oLLxLykK@@{ar-7x>p7vOHYN+IiTs z^R!2|XTj@bKAktB4|lt(bo=Wx*9S0ki<&kuFm$?`bo$$rD0Y{JXkK*eJkaTH)B3HH z#if^p!==+*ruAD16XS(Wcay{4Z*_*t9QNoIRc{0}Z!VQ6dUQKQfI>jX!*WLlBLhQ; zpa(QEUV3x~6}-M>cmR|@0z7(cSzW;Sb*3c)L-UFMQHS}r`6)E~Wae+_VqjnZH>$rn z26Trhq&5EH(BhwRAg%Eir<Vi&lw+J9KteolCYKC?sR(Cs+JTr393M)}8lL?IX?7~n z@$CG=zb#bJquX|BJ;-*CUemSC3=A)}zxe+@(xda8Pv`Sk$C&@B@{J4(QHBR%9b-VQ z4f5zU1&ws?2TgjuI1S3#{||u6oJGzcQ(j!P0Cn1%&qEsOFHSxMW#am`5r;jxS$P^5 z7$EJ|@B$CZAElxmouWVL85mxRdvtpgcv!wH;qvG_0m|g>U+a2w1{8R7msWUm+dcvH zDf2<;9>Tu@;>&~hppMA0$Dj-$q6!+8=jRUCH-UkH0i4HPI9Y-!RMW3H3=AINegh~W zdh9%VhQ}Vv>a7#-==2cq=nU}i=nM$(=-dG6E_-zD0F6p{9A}7*wPo-)?f@ERV~9E& z-0kkN3)F)3=$>;Ntgzeog(s-&?L6+$?aTp+Yv$<x526oyG{4F4>E_i1h3loApq+O} z4IdYk2*U#&-R&IU+_@c;GCVsU9A{AhP5XihP6Lnbb^%6ES?r@C0TQt2ZubE5&wGFx zRv<#7(?!Jr)Zzing@Kw#pgAdq7pFmC((R%Wf!u^U1`=#Ok^$*5G`}%Gaf}AUC7s(r z?&&m9@#qFSsWU`{rPD`+1JsJ+>1+p`h|=B8!^ptUIUPjq0?i3`w#zUwFhCsJ*$;BE zN9V)NcF-AQ-R&Zbpw=Cj>TCx!;2@sx=(ZKBV_*QaeO}}~07cyU7iS@J4*zOFDd)v= zP;_>?sAwSjfeGRVgV@8ZCqo@OFM(q-xO+Y*T=@M?xwal~;rBZPEev}_q+MH2mIS+W z^H$X{FgRL%tQBzSo)2=MOXoR9#>+06_guPpqv{wKTrDqx<v^}=?L6hkc-d9+mP@aU zp{wCZN5;$Uy)puh{2m`c;`|;LUkAH%M;N$tdsw(K-gLD5SkDVLmGLsjOb?Up2pbp1 z(=L{m>v_A^gG^<-s`=Wn^H#5nA>(C7%iE6pzMny+x-i~yw7lrb?|ZRZ^lUB2kr!O} zeGXY(<o7w%ydPX*mWqLf+`3yJLvGC#91Q%ee?hI4?&%ufwA1bY3ghniAf8KizYa*y z@=ytzi{?#N%@d#b1=>L;!|{h-;@3Y^7WSE6pr3`2fq`HDRGH^zeyy9I9r?8`@M}E& z%pdoNU;km5*k}I8Q=j>xPJZH#;1zUYVEDwZbMm#^Xa2a${Q4KlL_hOK9{$W9b>I_! z1nVb928K^A{5l6bEDx1JE$p6ez{tSRdb@<Z^Tf>Wzcnv*&o_YxaJqCJnECy;qvi!i z#?#&XAZK^CTQGurecF-V_p~eHL6`1!7f`Fm@}Mif@4?msC9IYQ`Tb9Hx7&b>I8egw zXnDYe-~WImIGvVCxmbeJVX2@cIN_CYx>$nKS_xOQOXsCn@N|B3EI7#<o(vB1=ynH} z#mca{r^ul@WD~URY5v6sEt#8d{(pU=^<;^NN3ZBdI|hb*;OyS{{zcJUP!py$;)NP$ zG`#aLD6i{vH-nO2x37gq=Y3bhlP=w^Hr=5nj0d_)4KxorY94q2T9e?>y&GKX9gT>N zg?FGlJO6|lz6EvTBs{w7BVK?e4?Q5J3V3wy0BQJt^u?|p|Np;!-TIclMG6#F-7YF3 zmM@BBTn*p09w?ClMW2g`#b-zUNEa1>&p!M*FJ7~{cIT*A9CuLxEpcIRHT>^t_|2pB zHh;@a1_p-iZjf^wyF*k&9J^gqY#h65R7@PZOH>RPPg;kl@Ra$xXnwGK<=Xk0-~Fni z=4ntC=)7Qf$wk{mg~##x2ghC!JCDx$nkQU3Z#s4!cv1A{|NrjEATzt0K`FhLCBTL8 zgQK;Jij51u(}&jqE}B0KFFAI;fEnQ09iw95s`=WnSH#|h@g2x~&C|#xg4QHpnD_%` z;tyz0zE}hr3w2T9@#sAKQVuju02vv84WoKAztQmQ`~m6;ciXP4M45GUQ33UodqY4y zFVoyg&^*k=0FPc56%jBg5fJdA9aJiTXE;JsKwV*Yd$8_4crHf+oTxmS-w2?Tqo7en zOIxW*28L2iP#2BGqx1QT!vCP!uSBA|M1`f>Mg=@S1TMN>NPYkR|FxM%H|viIP;=ox z36F<mMn#E=N4G=4>-Qd=?_YpMe8J6L*0W$GmrB?@x|=`^Cy(wB70@Ui++|Phfn6pL z3myms4-ZIqbla}2K=V6?;ei(x_d!nLZ}|u+ExK(xL1y=ssIVBmePMeG)bu>+(ao9+ z5^X(D!U1y5|D&%zdnDJWu<Qe+D#P0^UK@fcr&osmJv)zB)~K-5d3z)u_UJt5(Rt3} z|4C4TRn{Z>BacgW6pIhzGZ)J^meMCK-9a2KmSG&Fw_b~SWFO%1=;r!=*oX0fM<++O z7e}WD$N%FV&4+kiulE5B?Y(_*@#g>koiQpbmaqAHKm)NZ-7%mZlI+QHP_=SH^M#A$ zi#lm=+MW#diF1KR>jD0jSs+g5;nz=nK~qAmhL>Co-?~~}=I?t8Dmg(};R&co#lPRs zk$=A@lOzBBKo&>-{f=yomal3>EQ=LN`7OOwO1Uh9HA-16opnmITsng#JUZ_~I^Uhe z2A#zUo!%y$-YT8J7M;Nwoz6C$&N?rSfX4K@qYE7WAM$KI$n(0}$C6dFoPnW~-KUe6 zryLYu$NwLG@%`KX|CV=4l6|^)|Ccc^_;#M~Z9P!J=h^K5a()S`XXk;}Z#}y!B0$}R zJ<v8g#A?q@hlm%BU;h91>~@Us>Ffumgidgy-m}{=!?Uw8!lSbt)L!@Otju`5%ct}C zi|$*Xv8=bH-i8NWc7p<-*|r_DV6l|v#TC#@T_<a08K{eBTU5rt&@Jjy&cM*k>Qv6a zU>OebzPnDzvCeRd&Tx%RcbiUkofr2&gWBD!E)Y$+AgYs9uZ)4=#S75vcPFb-83V%( zP}}OY{EH%p4dP`C437VgzO?%H|No0Pu$Xhf>$ez*SpE(;5rf9~VjN=+hwcO|V*@Rm z0L{vIbjzMEMM=#qDxgLhXb`<dMZu#t2Qq5~YNs%KUhUD#Y7T1q9d}VlU}*r4A%V(N z22g8?14IabQ_ezgkW^PN@VA2IG(5U(t4cv@9a!DV7#Ki<(cRuMNJBo|!3Lojj9efo zUdb{BhW`Z)9^Izur3?&N4BZYE0a*+$x^95#30q^3G0jH|JUWkgbUIgfbh8?QM7jlD zoV*QEPz-9-@|7|$ywC(!EX5Tby`cVax9!go28I_VU{j(CUWS26w{D16k()!GZ-Kj} zppc1<Jq+rt@V7XEMnb>~PFxM&g4djY=R!0*x^3r_Ffe#n%C>^2Zg&fp?gWm~0FQ3g zDIkGf-BPgI3|_2%1#+8h9!RwF-3y_Qpf0{e7K5wd$xxTx3?`RuR;5z#N`!7(&k_a( z7tMDroiATJd;R}^yko?17Zp%#$>7oL3}S=I3h=z2LN~aB#~Gr+)4U@Flr~COIKc%l zq-T12CuseqOXmYnUj6p{qsMU;&;mh*ouFl)p!(yuOXq{{A00c7I5r<)^5_;(@#tku zN@QRF53zf6+wLo7VDRZ?x!}`z%m*}k`6BYe|NmV)D$J}oCE%7ON4K-XWze+mlwt;k z&R5DI%^n`ztka7b82G0i;@@`3qub=di%l>8|L<nC0(q<R+fL9j0+(*ED{bS785m}M z|LLgs%J7n7kPm1e!KE`qMaD6}rJGf-gn^;kM@7Q1^WclSum1m!jBCwN;VE%-H9YBI zDJxtIN-QBNBBh{Fj08}tf!EdWr1A<-m)DVh>cLQtZrguFpd#&;bFYcHV~}g-1DDQ+ zFZ5pi{~r<M@t;M-g}Fq9!=u?og_FPaKcu02wg^;j-P;Rt<cpm5|Nk?yHWh=j@#Z21 zhE5ihPS!FopB2RS=r(w9^##atvBjX2>eBhmrJFSptiZOZh=Cz^X19-u!1uqPus--g z;?@8Ej!}-$j-AIqvoV@4K#c-ctzrfS$Ihetz3U)ZCV|1Dn>7^Vj&57KA_j(%Y{N?) zma@u43=I5J4uJzS5p3tnB8Z(Y{}(5?bhADJ`}NyQk8WG`A_fMSrHesBE#1xujuDQL zu<-(Sm+p=bMg|5@xP-fQKFDHl>3rzY`Rla;$VbdC{{M%pw=lfq()lgWrJJ=4Z1zjg z@(0^hg$xWYUOop0Vs~)`C@+InYPfXsCO{nBSqPdWKB9pb*?F1#;{X4{!5-bRsUW%5 z+a-LU(W&{Mf~`Bc;Pu<+!{8BbP#pr=@9oju3@U=V101?tCU__}gQB#gs(UgAs87@l z>Lht|ZwB@5Ji2X_LC)d349Z?mO)ehD4f_(#=H1{ne~E7MZqT|ghEkR8ZcvA%dosu* zP-^PD-@O@RwhN@S_2M&l&Sy5Lzz5HvdUWpwv0sG$M>Na8CLp_|R|K?JWl8}9Lv;3~ ze=n;q{r?|*7&2|z_~r)#S_uo91u{JFVh(r(k25Iw^0(Y&U|@hoQK?RMu!~3cl*{1G zaB~$0Ly43}w{yjD7Zn9iKKB5vwTR9DmA4YFy*#=%Ktn^cfPvw~gG>MacRPcE;V?vd z1qVavL62_R@A;r^phs_vipGoESO5Qi9R>><K96p&cRgBfm%e^|1#1M{K?M4`d{8!d zxeK&h@de{0aNvVo04gM2Z}#Z6?E$N}1#acPIDZAyFe-iF(cPi~@;GvN+k6#V-hu)M z)QS&rgw8d0ZU+@;&@Qt_x2<(P1H+4DSHKJMN^C*1N}WeNIxjRl`RCgDq=XH`Jj3V# zo@aq1jm}pd-L|YCT?N<w|Bv?Qd>`u=^YY4t|NlV=6B09l2=i~}F)+MvgPNc2(Ji_u z59G(A9^DKcmQe|%s{Feia1_foJo$$RhUH)-uRylG;J*I<|7%{4gFiT$A24<{gB)*o z;F~K0V+p6>f#zBc2L34rI-3)~ZK(HA(XlVRE`TSmASu83O#;Fx0eL8i1v0A9`4C)> zy*PXU9G0A*5eg2_@Cj%Xn*-FE?L650NTBf{sACFh&z7ioyygPUoAZH&%@sU4H-kE} zuem*rH-i`q3=9k_97@2F1|FT8K^;u6B!~f)RDeiocyw+Cbtu7-AO=VhWG*|XouL4- z<0MFB2xv-WGN=OzRtaK&RIX?!(fZ7<<)dQpnP1CA#pW}A+(9tk<ukuvGsv-EaR-q2 zYu@8v5s*Iq@B`h=AnQQNK%MK>10{0Z&Couph(~ub$OaEfup0g;2l%%g=xhcRYM}5y z8KhAJ6%Nfu5~2?~hIn-T1NDtSr(-i1p7d-!^WUTSje$qEXiYA-l)svT7W5jRW{`^t z2ROJv?gDpa6p%<6Fxw#@=takQa5KxG^+2f@Xw+PQ0W@aLQNrTFzfJu`)HzT#K^uH& z1?8RQBL+U54;*7ay`P_;o~wmVx4Q;P7f1s%(Q^F74{$T05Y*r1Z`lq`OGh2P9TO<w z>vnYLYz1`~U)})~k`q8hUh5^$@>kZE*$fQb6`<na2fR4oZ_Nkk?%oS7XX6zdz8zyM z5$|pVm4cnEpr&58qXFZMPOyMWx4VkNw_{8t65Xw!BD1qq24sh$i3{U_POyl>w__|N zqTQ{aLb0<IR6=z-T6BWB4&RP(fTTd(*v?k)XqBT)XDf&cQQz&a(R#_HyBB1&BmdOH zy&{s1j0YVpFV^Y1w%jh!>YfVnmg6o^mE6k`Fw^n-FUQV<ohLwy&Vw$RCwo~WA@1z< z*Xf2Bycgt5r(O|8#^aXP>-0e8XhO{aw?81}{OmjqHs)vNLCv2|y)2BKFwZcT@HsR* z<0<6;^%gt9GnK92kb>4ot>7A|w7VB%Pxn-i(>=Pkf=WP_?p~1BTp)h)=(cUnVqkdT zcmDtX*KQ!gY+nEW|JtV8(ZQoT(7>bHHYE$(juP<bcJ%P*6jAZ$4zvK5>fMe39-R+8 zIzv=AK#Mz$f!1lfn05w~hHUk-K;`%gi3=beT8c6T2{s?G02ij95#eBu&d(l=Z@_De zAp?*e-L`KtQPO#f$_)n45Ho19i3e292)tN*5nRr&x*9%tT?0zT0v^dODm=Xb{~bGz zfG1V{pYX7hIbQnKaSy0Q>I_lgc~N#6)G2yWataz6pqX(AQ0u^>o0TgIoWqJU!F>h^ z(2`Bia4Xoi4#!<oJU~k#Jvw7l0zi2Uv=E=+MHnbYbwgZ-Txo#9)1&bS$WJbiH7SQf zoA-kXR|b#HzomYNvXmv0fx+-3WMJR~C<peof}#o3k`Z;tge=fJkO5lD2w6qy(QSJ% z1GEAZ<eC>|pfWnjquVq!6I2<zkA1lU+)fmongQbf@aV2e0CgvYJi7Zq#(G$KD3q{* zH&j8!3p_gi27C0%>culK1o3Yx4*{*kTHL@64vEYR28I_;&VdI8d@Qp$O4YhWSu+_J zx|xk#1Da1UeZQo5sNvDyQhtwaX8}<Amd&HLS^~6*?6885<>S)R5ul395jym>4-^TY z#af}khPQ)2>mM^17>=`U0Ilc;Ed;#{@;qp5#@Ei9u7*z>FF);eWpJ^4P-eux{;)@P zD965f&?I%Y?WJ@E1{cN$od;aHY?xkrIrsm+qs8%3c9%}w3{b%QKl1w6|HI9{IZC%g zcyzvpI03XC=;h2)|Nlc5?s)X-TE{Uk1pD+Z1$(yn4aS-ZpWYl5ju(#q|NjSfYIiY! zS0s8Ie4yyj&8wFV4k33C1)BWrW_^<m$tTSxm^xilL|(+40;T;@4v%hI#dHRS7e43y z|8F@^V(V)7jepyX?obA2?vSkv0iE|iG0l4~je)`Q|1n6b)}!0@T^cBgK_T`c`5b7n z*t7W`OX*3E=A#NemQPEUf$9*@02O>);ayP1gRa#8%~pbI?HA%F|Nn2U)?h4Ui+;)U zAJpE1`M>jTaOY<aEZ%<M{}1Y8kM3Sjk}>=S@w07I8gyMIDEo7Cv;Im$^>Nm@|NmQW zm+EIRKy`xVMZaY+IPL`X2f^Xz(QPY|2I>@KF}(0T3$Bb5JbGmVqCso_z*GIJL3yOv znx)jv)$mDoFiUqa2SmTC;Q?oEk!4v7p8t<P&G+cGJ(dbFEsOERZ)ga3HveHMJ?ha6 zN`tRUw_t?S=F<>+VF?2?Z<n6Rz|i`?PROU*sld1OK&ie@H*0h%1H)@Ik8akWR8SB4 zLMfkT=K;`|7-){_%WEDO&+<a)7oW}phe4CVrBZ?5<yzN3C35F+aGr>I8S&x&|A@nf zLqQo)7P7i7<HZ{Ag0lB77J;VGKvP*o;PDmRCn=yY!MC6};o6KBZ6H<MxdpG^cy#NY zgi7&&%IPeSK9J1YSa4i-w}bi)t>5@tKsT_o9^h}a1XZBDte-);AmwTnqpRV`0FQ3b z^C=7r;N{+s72+P<wzVmsft=I-|93ZoYG#kl`^TF>27;2{aj+1G)!Cc^s#w8e-^alu zsKwFQ>;tk2+9&eR=q^y`4p4FFcF=jz`V=&w*ljD9!oUy*ZI?#Bd~gg@bn~}N2X!c+ zP6LfJfSm+NKB9Ulp!5$a;yk)-A0~tH57=!W>peQ}cTWaa@SDNyfNoHA4sk8SH6RbT zbT@;ma<J1n!5yhia2Ki*?Cef(2g{`sJb3-$K4^xidpD>8jfjeV8T=2FQ^Gtte}W@Z z<q@P!Uk=)A((S0>Va?i~%)n4;>(R|REg6(H934v7Jggl(N<%!l9WB5Gok#Nz#u8D( zZywD*m`ZsKzcud%g(d@NE;jO|52%c`W=#Z{qUh1h`XUKrN<~76Nb`PByPTnv8*E6_ zOVBc6@bu|Xkdp2SaABSfHLNraI$KmC)4U(lvScU~KHd)UJt!PJx@{*UF)+L~3Frn- zm$(|9gh+xSvKu^e(hZ(aae++Oy_g3M1>5K(28O7Y{(nIW3_5=VdUV@*CNVH{hr57M zv!+Kk2WS>vvGbaTb<cNDa}BilNTA!@1=Qje_2`^(93=RfyZIAiCs<GE1H{~E3s@4= zhvz*B%7qmPpdCCVY*8=o|M~wv;-%hO(5&DOP)3RN=(fF(2(h?(%5{*T9^h`K(`SAG zhR^&0yiMw$39S=l?4S7~+y!2<eCCfi_=#UYG)kR;;WK~Ki8Oxwi{&C|{QA5B>I@9! zT%Y*`-34Bj{rUg@uxIBFk8az-M9_eiV>bh%yGXaYNb3Q9k3*gAA}@pg{QnQ?DhGn( z4}eG5rX1*W4|s9={{R2o;RfCQG9KOK6)xc6G+u6S%-Gr_GBCVgKL#rFZ6y*xLC6Ch zJz(Wd1XUG~n5zr)=r&yiQpxxolm$w&J-Tg~K>XUn;GJJD?*IS)qVWXSlvfGhM$}@E zOgHP11duVdSHYA+0<=f{A`}#k-M0H6YL|oT@3q|tGQ}EV%8~?-TjGv_i=beSUe?EP zpq9aJ4@-8?4hGho1O|p~2Z`nb1|6(BLKzrdD4zhkEYzc$H3MWBXeyw)Lg2;fL;wH3 zC_4ml8nZ{Yg-7SH7cXEuTfcblY&&=tLbrh7ffu<T+k0&fC^Im;P&@(N0e0#TC|iNz zwji|gtKm1$h>Byti!9KrS~n{T$S(Mx$vcpF-3%Vx0SYgKj{N`M`nJT}quX>lSlISL zJfh7s<tWHSqM~5!rqdt_*2gn2L`KKH+<q9+g*^<O7x6&pu~--$0JY;F<Cd+LO4$t$ zyj;q_z;KL-!K3pdWK_BHpGUWC63EQX%O0JtUQ9m>3Y(Ivpw5#4L&;eXtsq}20_wm@ z?D`KX&N}bEFg*7E|7&-TZd(nI&R!oCNQ)J;VXy5F$bbs1<{A|qhB{@B?i|o;R4D^! z;zZP=^FG*&7au@=>U{sA;^_bX$C^RLf;(ywFSZ|m*Ucd+7RU>h?j8Z<rz0NVdCzX! zK2Rk0>Q0YmVAu!RLJe~KkAEP$OZh!|O%0V87(kWCcaW}b+l)BSn%<2s|NjpKrB9Gv z&>Halpz0r_b00*fh)4Hcs1VrD7t8+r|KCu{z)&jS(fJ;<BTpG*&Y~m#|Hp#XL1=h% ziyn;wH(eq13`+QeCgVCm<D1|>{u|4{fQXLHi&;#dnK^-g7a^dO8--DezXj!r<|7*5 zF7qc?uNgGl09udr1k!1?T^@_li*Qka_Le0;R)H6c27s)Q2mn(mVA3HVi{(Y!0dR1F zddfnez6E$SJcm!W`U{i&p!DW~x<nx!;u>f#*)hbU+cYPZfdMkO)(sBF7s251{N3OH z>^9Af1+V^kVf+98e;-R#Kalr3kCyU+%YD$;qXuY2r=_lMECWL+7or9RwOT-_89crZ znm|Tvw}NIOt!*d7Fff#=c{EpRsF%uvf(|re2x%(vw}LLlf~=>0dFk)}|IO7FjQlO2 zLkM43gXSl|n;rODc7f7zx3h*v^AC-ZG>_&VE+wKK%|Db&lR)Vv;qCwbFV4RD|NnJx z^ImX;Q|blnQF(OR8peQ9*P|CN4}%h1iGfGAjmnFAplOTN1N>9L10k&-O`zp{;QsxK zhu{AHe+}--_Je8wh`s71oF3M!G9bT5fh`5CpN9+xcv$8ql(N3~4_biJ&8i5p&(c`~ z(i^S=Rj#15mB{_EeFwquDG?nDT7w<z(JfjM&A?D130*bf(fPaE!=c-y!$Y|p)N?M? z@aT@p0PR$ghmABsrNKkJpyh7h(a6_#U>z(~56k<dl2FAS)~uo+<GnpPS$U!v7+yOW zetW?T8cA)vU3%N2+w^@DxG?94MwDY`Kq;<U)HfO=V|osv;5lfE?x%hK|G!Rc-VJUU zlyE^7PL_aMnD<}kfTxSV1Iv)4(;blE(K#738tl;-k@12D+^S?<1~G3sn1T#Hb~|u@ zi`UKjKy~i@7cn0}37a(rq@*(<A^PRp7hnNzkU+Ob0;t+I=oas81O-szBhbBKmKRFo z3@?Nk{_g|}zE}tjdRxgT1_sB7mporVO^9w&t|$hEZvJjJhsK8>O&-k$1iC}oI4n<< z$QYgqH~ilj(#G*34Wjj4Bv|XkFJP^#$0I=vBX<q{R?s|fXz*@O+a<6&+`?LP4#-q@ zn^JDW+m@`|QK0#p!=0jSQ49>7tTmuud;8%3f6g2HEuaf|x<yk#%1zV3ezENU?eo2N z_W%DElfVm(Wb;AxwB9ZW_vp@!04<4EZ{7=Tua$^)duwzDt9W$2?=Dtw>2}t6u?dur zyVru|6klKI_Lk`mHt>K>Gq`l~{so!TZL0^e;pbjZ07e(QUSjzFMeE=H|Dz25N5{VW z@)=qwIfgiPet?XCG`}(M>0S<MfTEO<8iog6h+X^t|Ap%{(743`{#MXTZg)GRy={9U z0@4F}VZR&PdRTS+|Nj@x;DiJo>j90=blWb9U|;~RU3>9k7sx^2UY$p`ZC3=SeF5&5 zy;uj<1TNhTzr6sR9{}3_2v+bS2$Vp2ZBsyoKLeM3w*C<e3@^Aq-s^n-LTL}UdS3!= z?uae{ZSn0k<poo=Y9NJ%dqCFea)E?e-<J4$bjL=3@|J@~Z!@Sk1oePLb0R>Cxj|!S zpdGL0!cn%cdUV^~2?uTI-v9r9gh%&mP~b<s-t7VE|EvK`b}s-=h@h3qCqWKuK4Jha zGs8T<&3TO%q1PbId4=Xm0dVV+-=iD6M$_<H<V&}opq0r{FBAWP+Do9$oW=_ks0Kcd z&g0-b7WL8zEDdTI`gFT1l(IF~hcK0L`dG7yg)=aeCWiWS9uE$D@ftL904`5K3t(q} zV)r%2i(Q~u-%iky$d6&5)P18w+@rf90c`S%d*C^8+3R7TO`V{GDCl9GolwFZ1s=%& zA8Y|yO9axr8m!x0p)@SGyW9t{yrjF{<HZipGy&L-tDzt}4wq<vTJOpp-K;fX3=Ckq zK$gD9`v!_Tk51XtFb0Mf4?$~}J7pJ!GB89RMp>`~8uZ0p+dyY*Upxj);kO<r(FUz$ z>Sh%MyY5Db49FU=eJ_|`cKrl3GfP2sb+f(=Wnl2^22JBzS5%bR8@@HX?bB;p?+g+( z0qv5#15(_4>HmMw@+Jpn)+u2O42*{zE${L-fp?$&KkCu^m$UTZ%T=I3q>3y5|L+BD z3<UMnS`U<HzTgGhW7`_az_6DEq=XCHaklLV1vUQnffC${1E74-D|^xlR3|_4=>-o$ zSZbHrdvtpXfXY2H(4wgjOJ|N!oo-g9Fb0P1U=~N?5S4)D6HMPPC|+3cw^X?GZ7FAS zwFHAt=l2p8@Icr__#njVu+Ep@Q6$5+mmhSpsJx!YEPEd0B2aneXnD7&(W9I7Q3$B$ zw|xzwdQCz8HhkM1Vez8vB50O(PACI|Cdl6o{PT`BA7y&!4Q@}kfL8-S>h==W7uP^O zL0b~l&DsGnvO6FF)J0S2W>*Cj!zI#zhW|U8K!y2>m!P&rw{2nw14G=)(D&f7mp3?s zfuUQxyU+nr)?0^c^e9pD==>1g{DHC4(V_KH2}@^4qle-D7poxJl|mR8B3_C?w6lsJ z?Bs8`2AVkB1ujwfTR{g-H`_DR>3ekV0%c_I#-AQ=djq^Sy&JkVd^*T&rO6)M`$4K+ z-vF&~H~jBmc?h(;8gmW02fynN59lK6TOO_dOEqEZ{h;Q7mm(mk0*&L`0d+^L171A; z4l1H-<AXt+r5B(MKXe_AJhX)Xo9cx$56;0HbqACa4TC}R$rS|*CC0(s_Al0enlRwZ zCjgSLJPeu{tw=EZ_JRR4n$s!!GYGV+J^E$QcTk52JPzyG`DNb(M#u_j@cLy?hQr!l z0X1<MUZjBbId`rAm7X4*haJ0FR6IKGcQ%8@Lpqy5qy3-+%hK5l8Yby%22BEh1UNdI zL1QJI&7f%zkN{67c$5S(3<44m@aaua5r7Qnym$|CZntex5U6hlTB6eV?uF<saGOp8 z)F|e7!Fdr<mP*2cx&aht9-WgxW!+2A$!DN(b&!5Y&knR*q}x^yB+v<Nvw+&+kRI4^ z7Zq@W9MaSU4PYDxx3xg57xmlz|M%(6QIP;`i*fbnHLVZ@t*Uze;@UQd12iGpK-tNo zn{`1TXbkN@iEwj;#DCB}KghZ|u#KR-BL$m5v0bAg0E&Iq7m1re!(L#QcY|FH&LE}i z-A)eOE=?YgwUeD-*K~t}&ZWB>6vn+GoF3iXAg{XgvIuk+Ds)$BxH2AO{O)M^vyRh6 z^LXcOkh1Pd6_;*D9hdHIP&_bC22H;>GX8L6yy$9qu#U@7^MVT`in_t;2Q07g`+VvI zk5yS$%9JWNg69HfI)4Ar9caM#!SX^4FLR)U<%L?dZrlDq28M2M^!ju@1lRE%o$nw6 zb4&~j43<CmeU5u{+b#%TV1QTwnw|&Aym-3_6a=h&0pK#H9z=D%15G7^dfW@PK$?UG zpy=(q|3Vv-5IXO_`1BAWo(Q75Z9N0P4T~fOP|x<yR#43e>bcB(`Tsv`+Fleo=I7CE zD;>bV@Z#B~|NmcWg1XHdkhNl^Jcb9FcY_D7_@^G|1dlIvHiLQxtp`dE!P?W^rhENi z%>zhR(xcn<ls~kM;L#lr;n6u6R7!Y&o4*ktF1QKYEh+-`T0{oCtr75oaXTo!!BHa` z8o<B+i5RF$UAntL5#$1iX~>$11b+sG7uuje=?3@TAoZEl$N&GMJi1x6{23S`JuJbg ztCSm5-x+>;Aqw7z3m#JR=!{Qz@gKa(#a0Y-+zuo!yvW)Ds(WALfC3k^Q4G1i!nYON zU-1AnT|f)sJbHDt{TLWPLna=buL3=~%Ry_qPJlLu3vUDGNTp`m20zf|d`XY)YK<59 zpwac#1Ervr!@KC%m(zbk8l4{9tW|yt-~%1Hr$ASigBEY(1bcKxB!F6Fu;nPF;U3); z5iblu!|IlYOC>>aF0f^|(jZaDqGbb6oEL%y)gc4G$g$BG5%Ho2+%yA+MD)uaFTh2f zhvjxqwkb&lZEgaGCdg+2FYbej&igNvPXGV^A`mp<>+0aqxf-O_@PD^Us|O?(dUU%+ zcyu;HBHT5@qcax71xI*iY{m<zPq3zTCumuZM>lJ`FKC&VM}lwb$r2@xZq|Cx=`hWp z5?dso+y2F`=b+7M=c7D2kG)L%587u7UP}jFNZ0rVv>?Qz+ZJ@93{vA9GUo@{&5@tr z0a~Yho{510+H2r%J;cPo@M6K8|NkK~);mGRju~EZ>D~$|0zA5H`Fugi8B|<BHn4-{ zkUY9s`F$A}!aTZ7&-;L;HU1l9F}z^e08R-Cpb`BXCI*IX@FY5P*V#9p?x~<UAP_X@ z@wR&^DCK%|+ivgy&8OJTv|?ajJoNum5Hon9+o$u={}Z5viU&b?AH2%hwhgQ@MMYwt zPlEsh=y-$@kYuupibV4do)W2guI3+XCGsypx9&Fo5Gmno{vpoa3R;2T)A`)-zsT{I zpiy>@ZqTG?=M5jt7aq+&1o+$dL9+y4hq`pTsKo3972+P<TS4*IE5ZQUq@wMj!l8M= zrQ6Sd-{YXG<_AzI*qgx!-lFBg?{UDRoAr`61A{B$%kB!7?f?VF{|7v}_dwPMbk}n@ zT3+Pu0Ud<F9AM#Sd9l8x+s~vsz{G{|pykDyeC7Zf%Zv3Hu%U@~P-{TGdnzdGySIY! zy-VjykIwgy*|rzU&i?=ZI@YE0mG)Fnz1Vr-`wf1NL(M-F>P1~T4{3t~6(Lw>Z1^9% zG3G_ui~s*Y-sAD;W>xcs<|(8d8zsFk2ef#0-fgZ?kznO-?f3^u6CRA9t`{T{p-~uQ zcoH6eAH1+f9LGjbp>2E73)J2?qG0&##j>?vk^Nqv>hKX{F%#1UP=QeT0y5Fx4fYfy z;dSrjU}Ru;F$**{Ysp#!GN$uzi6m(7uJhQ7bnro49-Xq0UJMK`u7WmyW0~150j0;r zBcMzHDV#u4tMI-8__Q;SoJY5<kQd6}8%BnyMb0n<pbV3L^Z)<uxga-!^2$<Be1Vp# zGJ2tA7SIfl=^9T425`3e4_c+L&l8kkUR+;;$SiV9pk_;niik&Vjf%jFN9RGI!r#Kq z1R9Y1=F_WNWe%?Unms|8r3Rh_e!VDM|NlQ|Edg>CP<UC)$iRTe0-$SzeLDX;{tr3I z@DfyAfwpW1_;mj8(fk0(1I~;f<5_t;85p`lR3f^4RAOAZ3k(=<X@{r?xG+A{_E8aW z>HMyFz4PDqd;A{XoBzqznRf35C5`T_po9q8Yvj_)Qs>I}(XrP=z_Ih1OXqpb?+E4f zY_6IIT|3Wp2bgqT*F2Aqs54*=u<70kGRm>@0wh`W+7!8T9_lsW*ZkCZ4P@b`&Qs0* z<m*{oIuB|7>h^GfCRUH`mJ{H~mTm`*(pXR%S)scZ;vDeO6&LVn4$!QVed_=J*HJE= zAGN`&V>(ZOvd%$J))DEvs106xf)J}S1da8m@VwA{`u~4-hzcm*ymMz@==K0D{ef5t z+UZo%4|Pgun{VeoXubi>$$50!UULU!oEPg?{r`_MdG7{|o?Eg`c4uJlKuX>npsxLY zk51VtcLs(R-$3JMSd#ZtP=>-t-k{nEwnU|~M8yKM>czpM(?`VvwCXs(r_)CzqUAt| z6~Cs7N&>&8k4gc*<`flBF!F28Q2}jA<kwuHvVehsfnRft$_6mKMFn(I0KeuQ70`{r zNHq&&l)BsY7wBl1&U+rcEh^wKThP))@X{C1khKA5$u+1iaNI>j1av4VXi{F`McAtU z{~N3sJi1NyxH2%5=y-JA2d!b@c(HdCsGulO;b^E~{%=((ydN~T`XYQ4xCzp*?*ISS zT>C+1=e}@R_5VM(2l7H{<^TVIFH}GQ(s}@VVxR~Q1H%i@VYpF;89?Xvc!16ihMyP= zD&$A;Xb6mkz-S1JhQMeDjE2Bq4gp36CI;}0&pHapiFtYXB?>wDi75)8o0}EVit=+6 z@)C1XtrXN%i`BW%6c&JP@P?=aDN-oOS15qo4vt+tn!!-DdRz>7`4Cfz3sRFa(=t<2 z^ca#smu;ij2flMUu_RRiED3fJLrF%eLRw}~aS6nP%sd5<NOEFwMyf(?X>o}{QYzR( zsVNZOBtp~`mlS2@rRy;yXMp@r!cd%?n3I^413HBoEwcXq2aiiKfKE9CNr8?@0@L8- z7z_+Bd5{<}7}OX9s{=LKzzk6DpMl{(!-Ee$8W;{d_>fYbYo(BwmtT^RTBJ~(nU|7Z zu8^CUmzbVfq>x#xkeE}HnwV0lP*j?imzkH&09KxsSdy5d0FFm1g`(8L($wM-1<;-H zwyG&Q5OElniy=8NPrXDTGq1QLF(*eM*wfwF!^cG-BQY-}C$-3mAzC#h7Gx?2TPZ-U z3Rh4qW>5g#{GFNt64o`-GiGql%q?KhEn_GxPE1d=Qb;M!RfyIti)AQJECM;qN+B;_ z0dmE;LUCz9L4HvQ7f7!aES=>Sq~<B4WEL0XBv!(bK(Rt{erZk$BG&X6LPOjv;)6qi zJpJ4m!hPcdg8W1Lo&9}+K^zxXAJ-7q_;61@7yodOK!~HaYrLDkb7(L_yq{}GyrXl7 zXBb=oSSUC&AizH;#MK3&BHTCL&(YTv&It~241w~XDn0$&<HLR9ojqKgy-}6LyM_Ar z1Um=0y86K-Aa02di41_667CCiA6P8j#naKp-yNdd*~in>FC^Z_GdP5yxP&1kH#M&` zzNj>hK{uB{H!Y7rH!q1nH!qDrw>XJGw>S-a7KxpW9YeHlEQ29~5rYYXDT5h<IfDg* zB|~n0UVd>wVsffgab{Jjt)T%pZ80z?8yJ|Hnwv8yr-A{4auOIYD4T!*gR&7AKvgqf zF(;`gKRXq49y(kN1H%LRSu;UkrF|M0yt8LuXs}NP=TIvKMrmg20A>aT(4p*SX8-@+ z!py+Hv-to2B_a$AHmm>t&tYa@FkSQi{~BfnhSD|v{~usxU^uY$|NlSC3=Hqq{{Jt* z!obkK?*IP;76yh_>;C_rz{0@bv;P18Gb{`Y8SDT5f5F1QFk}7y|17Kw3?J72|F6Qz zz>u=x|Nj_P28O&1|Nj@TGB8wZ`2W9!m4QKV<NyDESQ!`+H~#;x!N$OFXXF3>5o`<$ z54QdPe}avHL2|1a1W7y`Ec|1ZMMz>vTF|9=y928PAk|Nr-3XJFvm@&A7eI|GB& zj{pA)*cljHcl`g~!p^|3f5-p-3)mSL{_Xhxe+xSUgWk^n|4*<pFc|Lq|Njn1-Om62 zzpyhf+~4{CzX1mWgCuB1j)Q@rVb}lv85|4@w|4#i-@w7Zz_R=Q{{<Wj46}Ft|G$HS zfgxef|Nl2Q7#RBY{r}Ix$-p4H|Nnm-P6mdi1ONY5a56AFKJfql0!{{ox`Y4!9{?Rp zedPcDKb#B<#Yg}Dcj01S*ni^x{})^g40lfa|IfnBz_9t`|Nko73=EG?{r?}p&A{M$ z`v3n9ZU%;Hr~m)o!_C0pc=rGQ2iyz{56}Mp59-$$T=@Urfro)X_TvBlB|Hoa9T)%q zpTonzu<qjj{~LH17$h$J|NnxAfno8b|Njkm85nvl|NmdZ%fPVs^8f#Hco`VBUHSk2 z4=)45-z)$B3-B>8$X)&a-++&Sq2lWQ{{egq3}>(X|386`fg$4h|NmR~7#J>G|Ns9C z9|MEyjsO4O@G&r~yz&1(13v@9=^Ow5i|{ir2;KbuUx%N8Vd2gH|9$uw7*uZk|DVCn zz%c99|Nl$)85r7b|Nno6pMl}f?f?H@@G~&*-1+~XLx6#y<j(*9Isyy~?05hFPY_^W z$hiCee~$nI!_s^I{~r)wV7PSu|NlDz3=F~#{{R0Xz`)@5;QxOfK?VkW(42-K1H+t0 z|NplLGB8|t^#A_~K?a8RkN*EZA;`dx_4xmP79j?PbC3W3R}f-gnELep{~RF(hEq@f z|8EguVBmcA|Nk5z28J)s{{P=1#K2(o{Qv(OLJSO%umAs75N2Rl{QCd@5Mc%e%{Tx5 zR|qpOOndYH{}N#ahLdmp|KB6b!0-!nl%NO$!_80s|Lce{FkAvn3y3l>h(L26V^t6X zV}$^tG!HumXr>S(4!X?c#Pa|DL6@d5xUhpOEYSXG(DCRFGyeZ~U}s=p;1h7;lkno_ zF6U@qu$QvdGFAcI(ZT>y47v=WamD}tprcwr)_^V-0iC3@cE$hy-k|EqiBF)H$%#** zhuMWsp^e3nPotUDozH>UkdaTrg-^kePr`{$z=;o3rGX~z)-W(I>{<E$Kj;z_1~)!| zHm0OwAW6{i?x1b6=T`pz588Ln;KV1;&*aJ{(Z}q{r_jsd%BRu8>d0r%#^%Xq(ai42 z=fITDXW_zU;K--p#HZi{vj%i|3uq`xebxW}po=XS+(GVhg}Seq1!N?|L5_#doMm7D z`3JNKFKE^O|DcO0K=$^5{L{<q#HY{$@=qJc-exu?f3Sz(HZd@O{8Pioz)-R3|9?<8 zL;Mo}_76yI22>7Q-a3N(ng#MI14!)_Mh1qSRsTUJ;WIF}faI8bx%fC-xgGg9Kyh=0 zk%8gJs{jAN_f0wR2|(TC2nu5tP#C-LIWQ&gX*ePUF(|%xKvQ?C|NjRK)PUj(B&NW` z!0>GqLJVZ42@?aun^ph+uLLOqhqV(ZtesH9+7T4ij(iSGkzC-wc0mnnSMDG#J_|>T zNC5c)i!kUM;x$YR46>`C>B)^xpqVL{Pr?xtff^os2Elv+&WFKa1d7KSObiT$tN;H8 zUk~oYC(y&>$S2Xp?8v9k%mVU$9@y`W;N%6mw1b10fuUwKr0fU9V?QV!`#|y7%i;t| zKQ5s3;|%hX7vBO-rbB!yIDPmwa56dZt>ARxTfoW8!31V);Eds0!RZJRS<Z;fgACv} ztYBtf5ZLhlKj?xVh7djhFFpxpJ_T>E`$2x4!OXy*xZ(eQ&;>al_w+Eiz};U0@-;MH zfYQSeW(Ee64gddx4$gw4qhN440!0rf4xcbHFc@$6{~we#U}8U*85n{${QnQS5Cta2 z!@|I@6y_!d25=r$U}0c5wBi4MZjd4dNV+v)VPM#~;s5_CkeD|p9+>h#4hPv4z{0>F zz7gtfs2M3N3=B>i|NjT4WvEyM3j;&k#{ZzxH9@9;%b^|?1_s}a|Nn!^9tKA~fgnB( za2{L2!oc9U@&Er>AeH{`xOC-HV9Md*lW;%AC*X93kHd}I5fq4^fN?wqy6zcd&I1+( zhUFXo|F;6^b>tJM;Nt*?{|^=hhLaor{|8+F!{7nVLjmAC!~iK1C0H341UCKu54!LM z<QAp~J`PY=8?Z7k1a12NA9N8ENW7UTm5YzV36%A~eh6S?V2IiD|37H&34;q?0n;Ri zz6@3dhTEI||33<KM;ntnp99lwJ^@EQ4p4k|ure?-Z2tdW50nR;LGJP7lW1mU7GvV# z6L5iKZjf3~`MZUcfuU*Z|Ns4Pv)n*x9r+ZPTEI!ek&gp(c-tLT28Neg|NjR~CV<iq zo;2;k7r^X}Be^nw>;$!On704_54w<t!G+Htm(RkD&%uq)!;vq*lg}U$6#t;`31DMj zu-^Xv|7^J1-1!ukCW8G5DlZGz7#Ox~|Ns9K$e)PvA6zzp%YPR>2j-njsD%>)0|Tgx zU&F@0;Iixge{E3R0WK54{&wfvz{u3ew}a7@?*OA0-w8%fz6*>ld^Z@K_#Q9@fFzS) zp~Aob8YKV1#=xMy`~QC*X3#P0pt=HQ`Q^@+z~sc2;lfvtz?b2~m%#L#FT;ngAcQZ& zkuM>SFC&1jzz57`3gzO<2;wUUhA8vp%W&f>NC9&~`7&Jj3Ou+&z*>F5%H#Mf91rsu zI3DBEa5}@M;B=Nx!s#5JfYW(UI7%=uFw9_QU^u_`|9{X0YLIjm4Uz(<T~NF5!ruS? zuS3JQnThEP7axZQC=r6v(iL_FhW35`|AXdHL3-OjWnVM17vBUXW<^FsSb)m|4hDwq z{r~@iE;a(C5#(})DVU2-!UbGJf=XoxNNLHy0LsS}91IM5_y7Oj33UV14i`QJrV1{Y z6);_nd>o+pfE*462B8E0|7SzvubIi6uYfs`5u7*}Am&csU|@(m`2RmBo*?cC<8#R6 z^Kjz}aN~<`<4bS@g<pXupF=U9fGZ^L9N}PKIC}8^e}7P#0;dZXP<{ZVX=f&wTcGBD z;9y{QarpoLw;*>T>ID~2z2L>yz{GTgPr(JO2h#2UrF|7n28M-4{{IJE_5=yfd_D;e zK7}N(I!KufD*Jpm85o`%`44F?F)%QI!Z(4Ff#KT`MEFA6JK*#Vu8TeR448sYlRGG_ z&){TW&^Y@4KWITNC>)@9*8^0?g6ku2dj?#`I`cU&rGcwhwDt_B40yoFz>t0P|9{YN z#~^c{Z2?64#DmYEna!IofT@fx!i6s(nJ>bTFCYV4ErY98XcG*Sw{^G}7&wmo{|~w} z5EKs0O#a{^(~*yZ0o2y>;bLI;fAs%<VNm=c+8qeHTtIfY@dYr2@J0CXC4_*oM}a3_ zKmlJwFkgZbjEiYIq%K;+#lW!X*#G~aOWQ!v2XfN^E(V6D$Nv8ZZKnpc*Mi_Kg4DAQ zxEL6o9Yd7kZA`IX6=i%J44}*E7`Pc26psJ@9}04_Bd9LR1f_Werb18@3wVGP2l7dH z@hLFXg5%o}EClj1C`~(XGccH*fX0&}p8%+}!{N#esuVz}p953}rEoJa%sKJ@Kj^w4 zhI&4MVrU&y!_C0(=fwa2;QK#a_ym~J;6{V%-Z|V141p*A{|8-a2J$Z`jcwp&U|4wa z|9@~J8(LQ#;bvf1e-aulAU8Nd>YO{=3=H>9LhFe@J^`jOg!!N{<`1afcIyBCW{}}v zzcV$03K>v2Ey2UUu;tW$&`DwpkT!)YC{Kav+$d1~KFlZJcnnf4fyxC(J`Tsj#~2vE zbwvmd1H-#h|Np;%nhP%*5||!Cf{>2`WPc401H-1%|Nn#I0i16^u>y&=89WROmrnox z54vy<l-Amqn4Dm)2Zj3%9tMU#r~m&4Z|`>DGpL2uN1&!7s4@bTQFnM47#z<0|34Yz z4sc$N;B!a=mnDv{vc!oGRF>q!%Mt-z28Q`(p!FPBj|aTn#S{c~J-A>1nQz0(z;NZv z|Npkov;+00JD))fD2TwtnkzTcJFqTCh@T6185r)K{r_JVq{ju6-k4Pw`8dFBhaO%A zhIgR-<{<Z`@(F}N#h36hFo>W3{~vVOB10mdKnS#5w1=00!Rq|~{|`axgFtNtM^GHO z@hLFv;^LEV#uZ1P`2E4lz;OTk|NprlcYyr~ZeN1SK^MLNra#~u8qXKu!55H;)K&(C zy$K%!gTO^-d(x3lAO##T&R`OhFF^S+f{%eg;Uct6>c}S$4wr@Wn=1Gi800TP+viar zw}Z=UP#eY<RO{e!J1E_N`uA}cq4~lO6oyP8p!5eS?=J8$Ff6<H|Nn8Qzo6wNxNib3 zH^J?AaJdPpA6DaP^MLZL3_k+{=<pQKC7KLTd;+1+_%PvTV6eLkZR5u93B*FhLE{Li zm;e8N4T=w@4SWK=ka{nLpMk;R%K!hM%PSfDLGI1wIt<A>9FB(}ZJQ2$28OUJ|Nkq4 z7Lg;`MV_EOn<u2tR=^y}%va&a*TBf+%U9vSSHKjGT5o{T<OO~P2E!Z3`Njj3CfxZH zKuu*AXqt3{B}oQQe6k2IFu33N{~vT-J;<NUOiU@r4g|F+Gz1`HD4+`s8N5L81#X{$ z>U$qVQiHUeLj)KYUfuZrA9Oh>Lp+}VsD=bBrpgguU|_xZ|Gy!q-G$a~1jh}cPIKp5 zz{Hfpw}Q!&Zv&GP-wq}xz5`62d<&T3_*O8*@oix8K@wx`W8_=G6oMog0Mg!ot@j10 zr$FN}>u&%5e;?FdAi^D<d@Gnj`8F{5@$F#pgt~*-l?j{i3?P4o2r@7v^!@*@4;r{2 zWc~(b=IhLSJD5ZH4lq0MonUt2yTI(pw}IJ<ZwGTA-vQ<rz7xzId>5FL`8F{7@a<p@ z<~zU~3Kc8n+rZ51&dg`w46d({$1*_q<c=T%!_vF||NjJ~M{xP>#rJ^`5=TD-85o-G z{r?ZT;1^WBhJy-zkh)Pk8Uk2CpaD9FX8@(wfGbr7hC<K{v<wUk8=!oc)-6!}qac_F zD!l_LzY9uROoGVof%5l3=>t&u5R^UwrH?^rh%Uk;6KtRZs#FQw7=v;c7#Q|J?+0*( z(lD7jSmy3Pa)F>p2oQq+R)L!L0dzJhlG?Sfi9e{=BGAAZ0|SF8cpwofh=<w(x)~Oa zJWNUv+-YH8cmN*gfQd4I&K(1DdO=5FG9dUf(fF&-_<Pa#C!u`M87yD}L6r~#0|V&d za}eJFbd)Ls0|U66VPIgmup1=GzyP{99K-?@ksum$A}ff#0hI@}AwYbX{MUc~L3iac zfaY{S;-F1fAbJDn26YAo2B<R_K;v2<ao89p4?Bp*0BYug8K80z#1I7$NElQlfw`bn za}1z!^}#%b6HtRd?E#Po)HnukABcg0VF###$iTn=6aN8~fVuksG+;mnk%IKY?En2A z;vWVE2C&k9Q2q|6{{K)us2Ky&_W{b^13Jo|fq~&Cl-~rB9E5nmUhIxCgQgERC>;i+ z)1Y)2lx~C4)1dS+D7_6zAA{1@p!72+{S8X9fd^I@7{s8o8k9DJ(r!>X3`(a#=`twY z2BoJ#>19xQ8<ai<rLRHhXHfbZlx73n)Xu=bAO@w?ptKp3c7xJkP&y4tmqF<^C_N2I zFN4zCp!6{)eGN)KgVNuiG#j|_#lRp2rPZLc8I*Q|(qT|K4N8|m={6`m4N5PA(%Yc) zF(`cvN<V|r-=H)bXz&B%e<-a6rOlwU8<Y-%(rHk-3`(~_>1j}U8I;}zrH?`BYf$<b zl>P>#*}#o<1_m)Gtp=sdptKv54ujHZP`V6Cw?XM?P<k1Z-Ug+QLFsEy`Wck|2Bq1| zAn9KWN~=L>Gbrr_rNf|f8k8=B(rr+B8kAlJrME%pV^I1Ulzs-Kzd>m>bEy4LS`A8@ zL1{NA9R{T#sxiqEpj~#*u`^g%1X2ZK!)O)IBnn6ZiecigauqJW2ciHb4r+pfM82cd zhcIy%{T1BtU|=`^8rWxGU;uTKKur;tJ$|5uH^?9;hRMV9uYuNsP-(b+m^)+}VKS&R z%zQcUWCyAohzHZ34z0gIVla&CzL%9SQ3MT=hv`>C(+`pZsf3OF!2JIJ>VKF#FLb>S zOdb|KFnL&WLLM4^ATvQ2CJ!F>Wnf^4h58TXUzj{B*kJOY3w@FG!<s>Vq45vX?+8)^ zI`kJx!{pKRgU4?e7#L<k^`AZC1Fkt>_Ctk{<!wPm!sKE8M^8U6c}{5fpvND~eXwR! z8jkRRMGGwbK7h7QVCKV`l`#1aX!0;)Ve$;n^bgYy>VJd$1D6MJK-UOBX_!2E`i1F- zR(A|A|G~l+=0BJ`Ed9acVfsOHr68+3z!RmQb!Y#<AqJBN&$WX#PebL=;}@p?6?6d_ z%zT*rF#Rxjn0}b~;I#z|3~=|u<UwQLAa}v!VfhOt4>KPo5Az>P-W8;ofq?-g56fRL zd6@m+ad9O3VdVwPewaMWewaMWewaMWewaMWewaMWewaMWe%LrJEdD^{7Rc!^`(g4h z`(g4h`(g4h`(g4h`(g4h`(g4h`$4BSf$W3X4{nS?=i5NyFnO5$FnO5$FnO5$FnO5$ zFnO5$FnO5$ps^*8Juv%0W85G<%>OWXnEfz$nEfz$nEfz$nEfz$nEfz$nEkpS%aGz9 zmfv9Z!{lN1!{lN1!{lN1!{lN1!{lN1!{lN1gEq5)oB;DbOdMuEOde)GOde)GOde)G zOde)GOde)GOddwZgDgk#KQtSI=UYKiFnO5$FnO5$FnO5$FnO5$FnO5$FnO5$&q0<T z*$?ZO!u$`DhuII4huII4huII4huII4huII4hv|oP@B2VoXrXQaQ5^)v7rLSHQ=#+) zXgg^JlrJy^WC{br94Maw%3lEGe}K|Up!5SMy#h+VfYK0CFiDtxn7Kco>S6j|=E3L_ zP<eM}XDbB_cfU|g1w%tUBRyFCfN29n1XNzKFnk2p2@nwo3F_7|GO#erfi_@Z=^E5M z#ikxKkBv=S8Qj<AV>s*$F&El=X8^6QU}E57_zo3^)w7`HEl4~T8eh=v76T|ffy80) z2wSfLN(YP#k_=a%@dGRWe4+Nvgqj0w{xF1t$3mnSD$YUN11qoMpyCZ^;>l2Rgh2)} zFff4E>o71dfY!M&GDtB*fKHZzwpT$W7DLqsLDj>;AJqH>xxWc24h>cY(EKk*ycH@A z8;1a`F9C_qgo=aL#xO82%!9hq18OhK{h+m4Aoa$eP5cZD4B+)J3=9k#q3+3rio=G9 zK+P18`zN6J7c@KqGUp0ZJ$QW#0|Ub;u)U%Tu=WwmUzecf>-mFx&j5~B5DRqI1IU~R zs5r<!AaPKB1&P0hii6k7FfcGkae>BU_!zc;ZzE)20I!o_U|{$HwpWTF0qS2^{C<au z$DoP-g1QGbE(u;k0}^9|m=7Dz1h1I^jq5<guZ4hI$G`wy|H8n)AjAk7Gm~N{Knovn zsCx5Ih<flk7zPFg(7`Ame_eu#gV(<>Fff4DvVg?rfDinJ@Ig8qnIPt;pt;`+YVQK5 zy|D2l&>SSl9MF+wApPLAEexO??htc2pz2}i0kq~96u&dj#66+rH$d%$m6!ftaZv^Z zP{IJU2SJuFFff3Q)&Q9k096kQ|0u9}DTWX<@i=Js2**MU0F?_MRytJN04fe%+XBi* zP;qup1_bp(K?M>60|V$Z29STvp%o0QAJYU?zYr=8UZ29izyMm)3R15Hy0U|TfdRY* zg@J)#0aX1|XvBiooiH#ktc1E>0qTBO`L+S79yU%3UUS00z;F;M-U98gf!CKXFfg2k ziWfpF8d!e{v_=yYZU>;@51P9Kg#+mJ0+2gl<Ib@5>l3IsuyJgdf0@DQM3TV)no&T< zjf2ej40XQ))cvq{c?&fs2U?(l$`_D&(3wpjd%r`)VeM89CP==3jUPjYCmF<`;@_bK z26)W}D4#;z^8i}jg3j9pnXd#@&jsx;!q#wTL&ag^>ELx73=9lLQ1K$DdRRGQ1r<L7 z6$h`|0HsH$IBdKd=C3fQIIRB!8}?6yio^O{;58Tw3=H{Daaey88l4OkP;pp47S^tA zhKj@b*D!zeLd9YIN?18F11b*duY=cKfXZ!HxIz2(p!x$8Zp)$Ku=WM4|F8jSP6c!a z1#Ef&beaz+9^XO5!D}!;<L*%PxAH-zGC<b8FfcIOg^G(oEd;N(U|?W)3AR^&K?&M! zfsJo}fT~Y`s)zO8*_a{e<OEb4+T37}go;N)JKE4}#-Ifihs|Sv$}f=1HbKq*Sp?!S zFo4%dfX*6%s)x1XVC^?&s5q>B2wo$>z`)=K6^G5MfY(ScFfhbH#halK4qpGjz`&3W z6^G5!z}g|jP;uBi4tR|%0|P@NR2(*61nnL(^g_j9^GUGuGm9Bg4j(uR@fWNdUI0}O zn~wsoTL9HBpgM_xj{(-Mg$^q+ctX{~`U|l3258R<DBfY?G~hJ|3=9n0q3U7%d+-_r z1_p)%sCXCD;ox-#3=H7;6_7cw`6*a>I1P3G1E~9<(>e?npyt5FU%+b!7#J9?Ld9#L z4Sv`-$X%#7Y&-xuT+9GkqYSbaHVy|~Bf!AG@BwVEC_@9Z-T~F4pb!Mj^MKUD#{Ix^ z`Jgak0fn<9!vv^1Vd2aH6;FVQ!`dhOU~wsi3}`tFQ!fP;mxPZu!upL$U~vHkSo>ZG z<QN791|6t4tUV4h#|$bCYp=t^9iZZ{_Bl-46DkgC$HT;fq2jQ1K1@881vD0l***td zEe{Hx1F!@Fb!Qd}B%gjj6R(Ae!{&FP${8ku?UiC!0Sz~3^~*3HEH1(To3DeZKL#}i zHeU=AzXVn<44?mliGRf5{_jw8IzbJ41_p5Z9;Anj6%@Y$3>~0zR~Z->VDo@{Q1M<g zaWPhie@{Zq0q;9uU|>*&ii<!q1Z<p24{A;V)EwCOfhkm60ZrV76?^#OiWg_FIYJCu zKn-$`hmbI~{!t*<gMthp&~g~2JOyly1Oo%8K@JmSU|^^Mi;FR!&%dqbU|>*SkYqRj zt(Re1npqhbU}+d82BN3n5MPQzd>0P!GdRRA;Sj%vL;MvE@&7o)h1jtBYcpsKG6NsO z1Zet)wXfuHs5inP?t()+6fDli-~t`MfQ=ugfW<)}i;8P-h<D%+pT!1>M^rOFyp=fA z@4+E{7KiwK9O7?4;!OMuu=#wDogn-PB+kIcU;^!@!}{aw?AXI!42QTT4sk0S;yyUU zBXNkQ;1DmuAr5LsW6Kv4aHwAe7UyGdf|e)XeP|2}3|qnCppZhvCvk{hW5*u9pKz#W z=U`wE1g#bZodSe3&L9R(=csmqcxpJrO>l_2;SdkUA)baqya0zdXs;@^aGne<uRtzF z#cMf0Yr!$gv0XUKKaE5D4i53xIK+Q~#rYUYK?6!i^${Z{D4p{$*f~So37c;d;bdTd z^${R45K<qk9>PW@?Qn?u;t-F*A)Wyi=VRCdbq}naQwSA51TB}K%UT%f!Q#j+fw0?g zh)=~Kz8r`6HXPyyafqMeWMB|vl4O_xZErwa!@zJ0te%g-zzre-+M^9(JqC+|Sg80L z4slK{i21O2ZI~`GE=W8+hUQ=J{!a!521T$qOcjDQ#v$$i7UyF)0}W?bHSY-)N9c#K zB5{bP;1DmsA>NEbd@2s{l{myV;}8e!v%r>5&x6(TF)V?W|FHhi9WGElmBNTe&>nJZ z=KKVk0}B-d4cd%~O+6PkD83NtU@TD_;s!XxZE=YE;t)>&i}NuofaWjQI<-QmxEi!$ z1Y7S`2^HT8EjOUuEru?zILy@udNvO6bvVTL;}AcOLmadxA6t07!=av$2YWb!_Vi;j zM}r3v?+u_+=Mdgv(8XbnB@S_49OBV9#Pe{7*W(cH#v#4{EY8QU1Dbzf<>Y#(_#0@v zLx*b__VIw~UnzzK(DDk_FS`g<j}!n<<`W#^UvP;3#Uakei#=YXaENQ;5O=^K9)d$W z1&4SQ4)I=IP<p^D&!^x}zX*r;S{&k^akPtegVpmfq(aLjXmg+86j&S@8A#L(9O7Sb zh%@kk!k>>pw;f^#c#S=%{RI|>h#`}pGb^y=7a1JtHNfJ03<=QnS>U|{3=9mqAaN!h z$Yx0-3yeYHNPHO68;5ud4snLWq)gqs{E}3?WQO?o#H7sllEid|%)HDJy=2faJ0LQ( zBr!RIAq7komn0@<GvuXKl$2!Vq^2+wmS&bPz|IgVN=+^)$<NKtV<=9|0a3a6dBqH+ z1u2OosY!`N1^LAcNf`{~nRzAo$vK&+c_j=L;IoEON^^57q3q(4#3GnDRHz~+Gl`)% zGd(#YCxsz7Cp9szv;bs!N<k$<a#3nxNh*k!lUSKwT2joASX7jlmkt(6&d*EBOfM}; zWhhDo9cKfzw78t1I0Jk_O>#~u1IQl?>8T|}`S~RUB}EJ%8sbKfsSwAfr{?D({87x1 zTv}9|U&N47lvtjW2%^gwic3-}N*GEK(~B8$iV6}_7?N_zVG4>FiZk-dGcr@a4grT? zacW6vQ939HAU2feW@P4-zyb^8SO`BowWPQtu_TqDJU6i<KbHaSCFto)48^H=DXC>3 zgNjp2((;o_iy87#OTcQuyv#g??9|GFqSRuT;d!OGIr+)ixrxQu4CzIQN!h8D#SFQL z1qGRT>3R7jnQ4_^;iS@%5>WJ|WEMf<G_|52zc>{Zz6>DiN^^3GlZ#SQ^B5pOo10n; zI>m{hBtJbpCp9f6Kd}UKwp4Ly2_$wvnsU<;lS>#f^OEy&6N^hyi=c`@;h3G7lLIk` zp|~KiJP&e|QF3kygaM9^Jg~1o5e5qIf};Eaz2yA7;u0{+02)c4AS;FWw<NP9CzSzu z{7`Xf3B(4Fl2pCS;-W-71CVK;5CfY56@o?!_}r|L%7Rn|kYs96NhLIhAYKGz76_{> zGqoHMJ5WWXd5{yg7(k2ys9;KJaY<1=%$(G`lGGxoOm2QjW<KcfG*BGm=I7}dFhF7f z5`AEwLoy(k2?~$g!~$4KC{NTgWT?u|&jqImkYq_>I*5WK{@nc1;#3Cc@mvhK`DLjP z5zrBB#gK#2iW$mtlQUA2v&%E{7)nx$a^XP_QUp>HpI($$X$WT-gIURyiFsfKNYVt( zGGa(BDk&~0O-ln8B1Ng`nV|TNFUgHh&dJY9EoO+1Psxu@&&f|p%!yAa$uBC7Pb{rq zNY2kK$Vn|pP0=&Jt|C4yGcPk9l+P>UQ}arSDjCv>5_41IA;n01JQ6P+RFa`6O(`nZ zOJ*o7NwY{v1)Xe`R9TV=;)1h7X-OKGUjg!OJfv)4fN;`^QX%Rx^B~GA7)nbrbHK%> zTacr#YrLzUOME;-e7w6~XuPXOJVemLC5R#3-N)a_(I?*D%`Mn9BtFE^$;UOGA>Jj@ z&(YV@nZYgDIU}(sIJLwvB?ZJ{a7zw=oPXy6Nhu5wnR%&2iMfe^rKv@g!Qc#6%n;!W zF8bW^^Gci{#ZiPC$c+)c`DLl$;B?CX7J<qZ=M@xX=9Q#5xchiIIma968R?mV@?&vk z3W`ufS_#<998hLQIHj~8Co>sT5G8{oP<1%N%2}wjDMjV+#mTv_0E`GqO)E+*&hSpH zOv+CzO7Vr1H4G8%MTtqlsYPX}MGO({sU_jQe)&bYi8&tNk}y6Vlz8L8^+9|*1LOcX z6nj%EGD}bdB7##(oI%cW$uH0I%}+^XhzLr|EQW;!INdOS90!Wt;?$D(^wg5_%#@N0 zhKSHSP*E6=p9#v25Z8c%FrX;E0F>(?LFt>H0y<c*C^xZyAtJ5Br6{pH7<>d^Xi1s{ z#6NH&ASQaJRx&`Gl~`O1@)#`Mpg{$Xd`N6EMC2xgq*j!`tPRNr@q98t$GR1j!vhqe zI5-oOQJ@Az_!p$+xj>J>i}wuijZaC1Ww{VvXHbR<0Uu3RmWCxA#C!V37nh`D=Eav5 zr=~DO1Vc{REB47xPRvOK`4yBhT`Mw+ONtrN3Q9|oQ34*6IZy<kfdfy#&iMtEjzy`7 z3=uA=pu7$9A473TQBG<eie9keu{u3IJ|(dv5t1app$hT4Q+`njGzo!13vPA<)Ov_2 zh6qT~fCdpL8Gxb@M8lE;G{eWoCs!nb5=&xEW>qSR+dxt2mS2>bUX)*&m%<R?mYI_i zl$u<Un3oO;rqI0H!~&Rg?x4g7i*>LypzH}^6sMLHCugMQrb1GcyE82P!7>9V3kQLl zEHJ}BNe#&&ztoBnS8%Nl&91(QCCM2K@$n(P&d`DgWD%%}1O;(%NfCxOd@}P=9ZO1z zGLuS6AZ2lJemtal0Ot`%tpSegVpPqJIXU^|VB3qKDw9hXBAh`Lhi_tWHduxs!WShZ z!hJ!BzZlev%S+5bH7~8i8FWl1$k=4R#N1Sd^2E%N0`y`DlIB5S6`Y!rnq1<US5R64 zP6c3=8@TBM@^o@(Q9LL?GQ`Ix6&FKO3%nq6Oi6Ld&(C3q2(HXa2DuXM;NaA}6o}j7 zL7I}Y<C8P8<3XoY!kufv5D}hOQ~=N8kfIWl^T6&dE-6aREr6>A6|f)&!IBr)QK^vA z4Z#5ik^q%KsTC!~h-v_uYC-XqTu_N(T7-9MC8*L0$@fmJEUwIjq#sBT1TG|CHHBxf zV{%DmSt=;MrDf)&LhAsC-Ka*Um4GshYeh+FUP&>u97`>Mm2|MOIzAPY+&w|1W1b_Z zAzEBgl!xIwa0P`WbfEPa1IYcwmAPQ&gZu$0GM&IJO{78>DOrNT57g4k&nqcTEdhsG za!wJfAS^CPNi9N6+HT2^+9<d*skkJwq_iXzlr%v-0z|n0s&`-ovujaNevt>{&{9Zn z24q%%3Wl`&qHNTVa!)M@DN4*M2K8Lr@{2$Tn!zpEB{eOvG^YgFK5$(YP?TSipPZjl z460-y2biK5R{-w%pa{jMg332o4FPorC?kPuu@qP-0Szxu(16l9wA6wYxsYta5FekD znUoAl$3-Raxrv#GBG%Z1Ap#svA>iUDGZmbNVENMxoC5<u$JsJOcxUG1I72#WAR`#S zttnV=LP{p2sDfuP_tX+_7J~~w8#ckIB@7ID#g(}wiAfB4#U(`$Is?W6*S!S{df@J8 zdS0m>tjUcelvJ9TlcJlM0u^#}^3(;j!Sz7OGZKq481zyq^FTQROqUcffMv>3i;6Sz z^H4bPMGSgHsX2)tg-}*OP6>k^sKv;j2QE4FKn+a>y`p?@wCJT~K%15sDMbu$9z+ME zjmZGk0b_%7fvnIg$_G0uF*h@rK`%YO1Wf3GZ3C%c&`T;VX3$H{&&>t(<6vERifGV& zThQD+Z2gb~bb%?1hK*ywECH#7u|YIwoi1n%5KO-XR6mS{POpQMf-!6y49sC*U;wS# zMb-~G{|+PvqoLbqK|){*TdxM@FfcH9g4SY!)^|V!VC#-yG;DnyR2sa$3&sY~pmn|9 z{{IIp?*ehb>s&w#*nVQzdLP(6Vs!U|)-8e76vO-vT7Lr452JU0B%y8ug&j;kY<(tZ zxf&?QVESSEmSHq(pEAfy5C)k6qG1@cd<wKD7^WY#4;V&+*0qAv!rTv22czp47#RK` z`5(5=7)Hb54-`iryJ7AJnF+$Zps_8a@Q3YlhS9Kn&M^C7`eFVDt?vcJDRg=TzHb_~ ze;T&W8l)ej2VFmCJ{9CHkUYpe;6unj4Cn+GD1C#tFbuK_#s<-I!0Uk#`@|KX`d~Ep zEK`s|D2A=~fziv+^uxyGVDx?Hx@4$!(2OjM38vSg>4(ju!)Vxkd9Y$=Si{&LdNWi% zEIt{a^Sv-S1kJ<f`2n;o4HSMb{jl{Ua2k|2K^8$VnsE%ETQ!mOuK-0T0|Nt$7C;-^ zgvB4!IEKrhqhc8t7+}`G&H=cv8lnPSJ&X^d?}IM2LDCOfcXWeD{jZ_n2ebbHC_oq( z7#=|N9{_m{;uJ869)3TdXAHpf!`9a<07WcleK#~<LHP${0L<O6^uq{VkBjjCf&Cy= z3=9X>LulAKBM1+AC;;qm0Fd2i`WayBen7YVfX?55ISgt5%zhXRx-t#qMVK<!I-mof zgvG$Xa07Ng0aQP_|3w)gZi4Aw0G;oc0p6|2!0-U-f2elwxk4~Dh?au7ADZnzLSPKj zkCuF3%g#|~G%LXRH$d$NAI{0ZzyMlL4q7S&^Eaq00VxD|59W3dABK0_gs=+uAT*2w ag%ykqq6LxC9*7Ua8qf_^%4izUxC{Vrg<%;0 literal 0 HcmV?d00001 diff --git a/dwm/dwm.1 b/dwm/dwm.1 new file mode 100644 index 0000000..ddc8321 --- /dev/null +++ b/dwm/dwm.1 @@ -0,0 +1,176 @@ +.TH DWM 1 dwm\-VERSION +.SH NAME +dwm \- dynamic window manager +.SH SYNOPSIS +.B dwm +.RB [ \-v ] +.SH DESCRIPTION +dwm is a dynamic window manager for X. It manages windows in tiled, monocle +and floating layouts. Either layout can be applied dynamically, optimising the +environment for the application in use and the task performed. +.P +In tiled layouts windows are managed in a master and stacking area. The master +area on the left contains one window by default, and the stacking area on the +right contains all other windows. The number of master area windows can be +adjusted from zero to an arbitrary number. In monocle layout all windows are +maximised to the screen size. In floating layout windows can be resized and +moved freely. Dialog windows are always managed floating, regardless of the +layout applied. +.P +Windows are grouped by tags. Each window can be tagged with one or multiple +tags. Selecting certain tags displays all windows with these tags. +.P +Each screen contains a small status bar which displays all available tags, the +layout, the title of the focused window, and the text read from the root window +name property, if the screen is focused. A floating window is indicated with an +empty square and a maximised floating window is indicated with a filled square +before the windows title. The selected tags are indicated with a different +color. The tags of the focused window are indicated with a filled square in the +top left corner. The tags which are applied to one or more windows are +indicated with an empty square in the top left corner. +.P +dwm draws a small border around windows to indicate the focus state. +.SH OPTIONS +.TP +.B \-v +prints version information to stderr, then exits. +.SH USAGE +.SS Status bar +.TP +.B X root window name +is read and displayed in the status text area. It can be set with the +.BR xsetroot (1) +command. +.TP +.B Button1 +click on a tag label to display all windows with that tag, click on the layout +label toggles between tiled and floating layout. +.TP +.B Button3 +click on a tag label adds/removes all windows with that tag to/from the view. +.TP +.B Mod1\-Button1 +click on a tag label applies that tag to the focused window. +.TP +.B Mod1\-Button3 +click on a tag label adds/removes that tag to/from the focused window. +.SS Keyboard commands +.TP +.B Mod1\-Shift\-Return +Start +.BR st(1). +.TP +.B Mod1\-p +Spawn +.BR dmenu(1) +for launching other programs. +.TP +.B Mod1\-, +Focus previous screen, if any. +.TP +.B Mod1\-. +Focus next screen, if any. +.TP +.B Mod1\-Shift\-, +Send focused window to previous screen, if any. +.TP +.B Mod1\-Shift\-. +Send focused window to next screen, if any. +.TP +.B Mod1\-b +Toggles bar on and off. +.TP +.B Mod1\-t +Sets tiled layout. +.TP +.B Mod1\-f +Sets floating layout. +.TP +.B Mod1\-m +Sets monocle layout. +.TP +.B Mod1\-space +Toggles between current and previous layout. +.TP +.B Mod1\-j +Focus next window. +.TP +.B Mod1\-k +Focus previous window. +.TP +.B Mod1\-i +Increase number of windows in master area. +.TP +.B Mod1\-d +Decrease number of windows in master area. +.TP +.B Mod1\-l +Increase master area size. +.TP +.B Mod1\-h +Decrease master area size. +.TP +.B Mod1\-Return +Zooms/cycles focused window to/from master area (tiled layouts only). +.TP +.B Mod1\-Shift\-c +Close focused window. +.TP +.B Mod1\-Shift\-space +Toggle focused window between tiled and floating state. +.TP +.B Mod1\-Tab +Toggles to the previously selected tags. +.TP +.B Mod1\-Shift\-[1..n] +Apply nth tag to focused window. +.TP +.B Mod1\-Shift\-0 +Apply all tags to focused window. +.TP +.B Mod1\-Control\-Shift\-[1..n] +Add/remove nth tag to/from focused window. +.TP +.B Mod1\-[1..n] +View all windows with nth tag. +.TP +.B Mod1\-0 +View all windows with any tag. +.TP +.B Mod1\-Control\-[1..n] +Add/remove all windows with nth tag to/from the view. +.TP +.B Mod1\-Shift\-q +Quit dwm. +.SS Mouse commands +.TP +.B Mod1\-Button1 +Move focused window while dragging. Tiled windows will be toggled to the floating state. +.TP +.B Mod1\-Button2 +Toggles focused window between floating and tiled state. +.TP +.B Mod1\-Button3 +Resize focused window while dragging. Tiled windows will be toggled to the floating state. +.SH CUSTOMIZATION +dwm is customized by creating a custom config.h and (re)compiling the source +code. This keeps it fast, secure and simple. +.SH SEE ALSO +.BR dmenu (1), +.BR st (1) +.SH ISSUES +Java applications which use the XToolkit/XAWT backend may draw grey windows +only. The XToolkit/XAWT backend breaks ICCCM-compliance in recent JDK 1.5 and early +JDK 1.6 versions, because it assumes a reparenting window manager. Possible workarounds +are using JDK 1.4 (which doesn't contain the XToolkit/XAWT backend) or setting the +environment variable +.BR AWT_TOOLKIT=MToolkit +(to use the older Motif backend instead) or running +.B xprop -root -f _NET_WM_NAME 32a -set _NET_WM_NAME LG3D +or +.B wmname LG3D +(to pretend that a non-reparenting window manager is running that the +XToolkit/XAWT backend can recognize) or when using OpenJDK setting the environment variable +.BR _JAVA_AWT_WM_NONREPARENTING=1 . +.SH BUGS +Send all bug reports with a patch to hackers@suckless.org. diff --git a/dwm/dwm.c b/dwm/dwm.c new file mode 100644 index 0000000..a96f33c --- /dev/null +++ b/dwm/dwm.c @@ -0,0 +1,2155 @@ +/* See LICENSE file for copyright and license details. + * + * dynamic window manager is designed like any other X client as well. It is + * driven through handling X events. In contrast to other X clients, a window + * manager selects for SubstructureRedirectMask on the root window, to receive + * events about window (dis-)appearance. Only one X connection at a time is + * allowed to select for this event mask. + * + * The event handlers of dwm are organized in an array which is accessed + * whenever a new event has been fetched. This allows event dispatching + * in O(1) time. + * + * Each child of the root window is called a client, except windows which have + * set the override_redirect flag. Clients are organized in a linked client + * list on each monitor, the focus history is remembered through a stack list + * on each monitor. Each client contains a bit array to indicate the tags of a + * client. + * + * Keys and tagging rules are organized as arrays and defined in config.h. + * + * To understand everything else, start reading main(). + */ +#include <errno.h> +#include <locale.h> +#include <signal.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <X11/cursorfont.h> +#include <X11/keysym.h> +#include <X11/Xatom.h> +#include <X11/Xlib.h> +#include <X11/Xproto.h> +#include <X11/Xutil.h> +#ifdef XINERAMA +#include <X11/extensions/Xinerama.h> +#endif /* XINERAMA */ +#include <X11/Xft/Xft.h> + +#include "drw.h" +#include "util.h" + +/* macros */ +#define BUTTONMASK (ButtonPressMask|ButtonReleaseMask) +#define CLEANMASK(mask) (mask & ~(numlockmask|LockMask) & (ShiftMask|ControlMask|Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask)) +#define INTERSECT(x,y,w,h,m) (MAX(0, MIN((x)+(w),(m)->wx+(m)->ww) - MAX((x),(m)->wx)) \ + * MAX(0, MIN((y)+(h),(m)->wy+(m)->wh) - MAX((y),(m)->wy))) +#define ISVISIBLE(C) ((C->tags & C->mon->tagset[C->mon->seltags])) +#define LENGTH(X) (sizeof X / sizeof X[0]) +#define MOUSEMASK (BUTTONMASK|PointerMotionMask) +#define WIDTH(X) ((X)->w + 2 * (X)->bw) +#define HEIGHT(X) ((X)->h + 2 * (X)->bw) +#define TAGMASK ((1 << LENGTH(tags)) - 1) +#define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad) + +/* enums */ +enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */ +enum { SchemeNorm, SchemeSel }; /* color schemes */ +enum { NetSupported, NetWMName, NetWMState, NetWMCheck, + NetWMFullscreen, NetActiveWindow, NetWMWindowType, + NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */ +enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */ +enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, + ClkClientWin, ClkRootWin, ClkLast }; /* clicks */ + +typedef union { + int i; + unsigned int ui; + float f; + const void *v; +} Arg; + +typedef struct { + unsigned int click; + unsigned int mask; + unsigned int button; + void (*func)(const Arg *arg); + const Arg arg; +} Button; + +typedef struct Monitor Monitor; +typedef struct Client Client; +struct Client { + char name[256]; + float mina, maxa; + int x, y, w, h; + int oldx, oldy, oldw, oldh; + int basew, baseh, incw, inch, maxw, maxh, minw, minh; + int bw, oldbw; + unsigned int tags; + int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen; + Client *next; + Client *snext; + Monitor *mon; + Window win; +}; + +typedef struct { + unsigned int mod; + KeySym keysym; + void (*func)(const Arg *); + const Arg arg; +} Key; + +typedef struct { + const char *symbol; + void (*arrange)(Monitor *); +} Layout; + +struct Monitor { + char ltsymbol[16]; + float mfact; + int nmaster; + int num; + int by; /* bar geometry */ + int mx, my, mw, mh; /* screen size */ + int wx, wy, ww, wh; /* window area */ + unsigned int seltags; + unsigned int sellt; + unsigned int tagset[2]; + int showbar; + int topbar; + Client *clients; + Client *sel; + Client *stack; + Monitor *next; + Window barwin; + const Layout *lt[2]; +}; + +typedef struct { + const char *class; + const char *instance; + const char *title; + unsigned int tags; + int isfloating; + int monitor; +} Rule; + +/* function declarations */ +static void applyrules(Client *c); +static int applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact); +static void arrange(Monitor *m); +static void arrangemon(Monitor *m); +static void attach(Client *c); +static void attachstack(Client *c); +static void buttonpress(XEvent *e); +static void checkotherwm(void); +static void cleanup(void); +static void cleanupmon(Monitor *mon); +static void clientmessage(XEvent *e); +static void configure(Client *c); +static void configurenotify(XEvent *e); +static void configurerequest(XEvent *e); +static Monitor *createmon(void); +static void destroynotify(XEvent *e); +static void detach(Client *c); +static void detachstack(Client *c); +static Monitor *dirtomon(int dir); +static void drawbar(Monitor *m); +static void drawbars(void); +static void enternotify(XEvent *e); +static void expose(XEvent *e); +static void focus(Client *c); +static void focusin(XEvent *e); +static void focusmon(const Arg *arg); +static void focusstack(const Arg *arg); +static Atom getatomprop(Client *c, Atom prop); +static int getrootptr(int *x, int *y); +static long getstate(Window w); +static int gettextprop(Window w, Atom atom, char *text, unsigned int size); +static void grabbuttons(Client *c, int focused); +static void grabkeys(void); +static void incnmaster(const Arg *arg); +static void keypress(XEvent *e); +static void killclient(const Arg *arg); +static void manage(Window w, XWindowAttributes *wa); +static void mappingnotify(XEvent *e); +static void maprequest(XEvent *e); +static void monocle(Monitor *m); +static void motionnotify(XEvent *e); +static void movemouse(const Arg *arg); +static Client *nexttiled(Client *c); +static void pop(Client *); +static void propertynotify(XEvent *e); +static void quit(const Arg *arg); +static Monitor *recttomon(int x, int y, int w, int h); +static void resize(Client *c, int x, int y, int w, int h, int interact); +static void resizeclient(Client *c, int x, int y, int w, int h); +static void resizemouse(const Arg *arg); +static void restack(Monitor *m); +static void run(void); +static void scan(void); +static int sendevent(Client *c, Atom proto); +static void sendmon(Client *c, Monitor *m); +static void setclientstate(Client *c, long state); +static void setfocus(Client *c); +static void setfullscreen(Client *c, int fullscreen); +static void setlayout(const Arg *arg); +static void setmfact(const Arg *arg); +static void setup(void); +static void seturgent(Client *c, int urg); +static void showhide(Client *c); +static void sigchld(int unused); +static void spawn(const Arg *arg); +static void tag(const Arg *arg); +static void tagmon(const Arg *arg); +static void tile(Monitor *); +static void togglebar(const Arg *arg); +static void togglefloating(const Arg *arg); +static void toggletag(const Arg *arg); +static void toggleview(const Arg *arg); +static void unfocus(Client *c, int setfocus); +static void unmanage(Client *c, int destroyed); +static void unmapnotify(XEvent *e); +static void updatebarpos(Monitor *m); +static void updatebars(void); +static void updateclientlist(void); +static int updategeom(void); +static void updatenumlockmask(void); +static void updatesizehints(Client *c); +static void updatestatus(void); +static void updatetitle(Client *c); +static void updatewindowtype(Client *c); +static void updatewmhints(Client *c); +static void view(const Arg *arg); +static Client *wintoclient(Window w); +static Monitor *wintomon(Window w); +static int xerror(Display *dpy, XErrorEvent *ee); +static int xerrordummy(Display *dpy, XErrorEvent *ee); +static int xerrorstart(Display *dpy, XErrorEvent *ee); +static void zoom(const Arg *arg); + +/* variables */ +static const char broken[] = "broken"; +static char stext[256]; +static int screen; +static int sw, sh; /* X display screen geometry width, height */ +static int bh, blw = 0; /* bar geometry */ +static int lrpad; /* sum of left and right padding for text */ +static int (*xerrorxlib)(Display *, XErrorEvent *); +static unsigned int numlockmask = 0; +static void (*handler[LASTEvent]) (XEvent *) = { + [ButtonPress] = buttonpress, + [ClientMessage] = clientmessage, + [ConfigureRequest] = configurerequest, + [ConfigureNotify] = configurenotify, + [DestroyNotify] = destroynotify, + [EnterNotify] = enternotify, + [Expose] = expose, + [FocusIn] = focusin, + [KeyPress] = keypress, + [MappingNotify] = mappingnotify, + [MapRequest] = maprequest, + [MotionNotify] = motionnotify, + [PropertyNotify] = propertynotify, + [UnmapNotify] = unmapnotify +}; +static Atom wmatom[WMLast], netatom[NetLast]; +static int running = 1; +static Cur *cursor[CurLast]; +static Clr **scheme; +static Display *dpy; +static Drw *drw; +static Monitor *mons, *selmon; +static Window root, wmcheckwin; + +/* configuration, allows nested code to access above variables */ +#include "config.h" + +/* compile-time check if all tags fit into an unsigned int bit array. */ +struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; }; + +/* function implementations */ +void +applyrules(Client *c) +{ + const char *class, *instance; + unsigned int i; + const Rule *r; + Monitor *m; + XClassHint ch = { NULL, NULL }; + + /* rule matching */ + c->isfloating = 0; + c->tags = 0; + XGetClassHint(dpy, c->win, &ch); + class = ch.res_class ? ch.res_class : broken; + instance = ch.res_name ? ch.res_name : broken; + + for (i = 0; i < LENGTH(rules); i++) { + r = &rules[i]; + if ((!r->title || strstr(c->name, r->title)) + && (!r->class || strstr(class, r->class)) + && (!r->instance || strstr(instance, r->instance))) + { + c->isfloating = r->isfloating; + c->tags |= r->tags; + for (m = mons; m && m->num != r->monitor; m = m->next); + if (m) + c->mon = m; + } + } + if (ch.res_class) + XFree(ch.res_class); + if (ch.res_name) + XFree(ch.res_name); + c->tags = c->tags & TAGMASK ? c->tags & TAGMASK : c->mon->tagset[c->mon->seltags]; +} + +int +applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact) +{ + int baseismin; + Monitor *m = c->mon; + + /* set minimum possible */ + *w = MAX(1, *w); + *h = MAX(1, *h); + if (interact) { + if (*x > sw) + *x = sw - WIDTH(c); + if (*y > sh) + *y = sh - HEIGHT(c); + if (*x + *w + 2 * c->bw < 0) + *x = 0; + if (*y + *h + 2 * c->bw < 0) + *y = 0; + } else { + if (*x >= m->wx + m->ww) + *x = m->wx + m->ww - WIDTH(c); + if (*y >= m->wy + m->wh) + *y = m->wy + m->wh - HEIGHT(c); + if (*x + *w + 2 * c->bw <= m->wx) + *x = m->wx; + if (*y + *h + 2 * c->bw <= m->wy) + *y = m->wy; + } + if (*h < bh) + *h = bh; + if (*w < bh) + *w = bh; + if (resizehints || c->isfloating || !c->mon->lt[c->mon->sellt]->arrange) { + /* see last two sentences in ICCCM 4.1.2.3 */ + baseismin = c->basew == c->minw && c->baseh == c->minh; + if (!baseismin) { /* temporarily remove base dimensions */ + *w -= c->basew; + *h -= c->baseh; + } + /* adjust for aspect limits */ + if (c->mina > 0 && c->maxa > 0) { + if (c->maxa < (float)*w / *h) + *w = *h * c->maxa + 0.5; + else if (c->mina < (float)*h / *w) + *h = *w * c->mina + 0.5; + } + if (baseismin) { /* increment calculation requires this */ + *w -= c->basew; + *h -= c->baseh; + } + /* adjust for increment value */ + if (c->incw) + *w -= *w % c->incw; + if (c->inch) + *h -= *h % c->inch; + /* restore base dimensions */ + *w = MAX(*w + c->basew, c->minw); + *h = MAX(*h + c->baseh, c->minh); + if (c->maxw) + *w = MIN(*w, c->maxw); + if (c->maxh) + *h = MIN(*h, c->maxh); + } + return *x != c->x || *y != c->y || *w != c->w || *h != c->h; +} + +void +arrange(Monitor *m) +{ + if (m) + showhide(m->stack); + else for (m = mons; m; m = m->next) + showhide(m->stack); + if (m) { + arrangemon(m); + restack(m); + } else for (m = mons; m; m = m->next) + arrangemon(m); +} + +void +arrangemon(Monitor *m) +{ + strncpy(m->ltsymbol, m->lt[m->sellt]->symbol, sizeof m->ltsymbol); + if (m->lt[m->sellt]->arrange) + m->lt[m->sellt]->arrange(m); +} + +void +attach(Client *c) +{ + c->next = c->mon->clients; + c->mon->clients = c; +} + +void +attachstack(Client *c) +{ + c->snext = c->mon->stack; + c->mon->stack = c; +} + +void +buttonpress(XEvent *e) +{ + unsigned int i, x, click; + Arg arg = {0}; + Client *c; + Monitor *m; + XButtonPressedEvent *ev = &e->xbutton; + + click = ClkRootWin; + /* focus monitor if necessary */ + if ((m = wintomon(ev->window)) && m != selmon) { + unfocus(selmon->sel, 1); + selmon = m; + focus(NULL); + } + if (ev->window == selmon->barwin) { + i = x = 0; + do + x += TEXTW(tags[i]); + while (ev->x >= x && ++i < LENGTH(tags)); + if (i < LENGTH(tags)) { + click = ClkTagBar; + arg.ui = 1 << i; + } else if (ev->x < x + blw) + click = ClkLtSymbol; + else if (ev->x > selmon->ww - (int)TEXTW(stext)) + click = ClkStatusText; + else + click = ClkWinTitle; + } else if ((c = wintoclient(ev->window))) { + focus(c); + restack(selmon); + XAllowEvents(dpy, ReplayPointer, CurrentTime); + click = ClkClientWin; + } + for (i = 0; i < LENGTH(buttons); i++) + if (click == buttons[i].click && buttons[i].func && buttons[i].button == ev->button + && CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state)) + buttons[i].func(click == ClkTagBar && buttons[i].arg.i == 0 ? &arg : &buttons[i].arg); +} + +void +checkotherwm(void) +{ + xerrorxlib = XSetErrorHandler(xerrorstart); + /* this causes an error if some other window manager is running */ + XSelectInput(dpy, DefaultRootWindow(dpy), SubstructureRedirectMask); + XSync(dpy, False); + XSetErrorHandler(xerror); + XSync(dpy, False); +} + +void +cleanup(void) +{ + Arg a = {.ui = ~0}; + Layout foo = { "", NULL }; + Monitor *m; + size_t i; + + view(&a); + selmon->lt[selmon->sellt] = &foo; + for (m = mons; m; m = m->next) + while (m->stack) + unmanage(m->stack, 0); + XUngrabKey(dpy, AnyKey, AnyModifier, root); + while (mons) + cleanupmon(mons); + for (i = 0; i < CurLast; i++) + drw_cur_free(drw, cursor[i]); + for (i = 0; i < LENGTH(colors); i++) + free(scheme[i]); + XDestroyWindow(dpy, wmcheckwin); + drw_free(drw); + XSync(dpy, False); + XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime); + XDeleteProperty(dpy, root, netatom[NetActiveWindow]); +} + +void +cleanupmon(Monitor *mon) +{ + Monitor *m; + + if (mon == mons) + mons = mons->next; + else { + for (m = mons; m && m->next != mon; m = m->next); + m->next = mon->next; + } + XUnmapWindow(dpy, mon->barwin); + XDestroyWindow(dpy, mon->barwin); + free(mon); +} + +void +clientmessage(XEvent *e) +{ + XClientMessageEvent *cme = &e->xclient; + Client *c = wintoclient(cme->window); + + if (!c) + return; + if (cme->message_type == netatom[NetWMState]) { + if (cme->data.l[1] == netatom[NetWMFullscreen] + || cme->data.l[2] == netatom[NetWMFullscreen]) + setfullscreen(c, (cme->data.l[0] == 1 /* _NET_WM_STATE_ADD */ + || (cme->data.l[0] == 2 /* _NET_WM_STATE_TOGGLE */ && !c->isfullscreen))); + } else if (cme->message_type == netatom[NetActiveWindow]) { + if (c != selmon->sel && !c->isurgent) + seturgent(c, 1); + } +} + +void +configure(Client *c) +{ + XConfigureEvent ce; + + ce.type = ConfigureNotify; + ce.display = dpy; + ce.event = c->win; + ce.window = c->win; + ce.x = c->x; + ce.y = c->y; + ce.width = c->w; + ce.height = c->h; + ce.border_width = c->bw; + ce.above = None; + ce.override_redirect = False; + XSendEvent(dpy, c->win, False, StructureNotifyMask, (XEvent *)&ce); +} + +void +configurenotify(XEvent *e) +{ + Monitor *m; + Client *c; + XConfigureEvent *ev = &e->xconfigure; + int dirty; + + /* TODO: updategeom handling sucks, needs to be simplified */ + if (ev->window == root) { + dirty = (sw != ev->width || sh != ev->height); + sw = ev->width; + sh = ev->height; + if (updategeom() || dirty) { + drw_resize(drw, sw, bh); + updatebars(); + for (m = mons; m; m = m->next) { + for (c = m->clients; c; c = c->next) + if (c->isfullscreen) + resizeclient(c, m->mx, m->my, m->mw, m->mh); + XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, bh); + } + focus(NULL); + arrange(NULL); + } + } +} + +void +configurerequest(XEvent *e) +{ + Client *c; + Monitor *m; + XConfigureRequestEvent *ev = &e->xconfigurerequest; + XWindowChanges wc; + + if ((c = wintoclient(ev->window))) { + if (ev->value_mask & CWBorderWidth) + c->bw = ev->border_width; + else if (c->isfloating || !selmon->lt[selmon->sellt]->arrange) { + m = c->mon; + if (ev->value_mask & CWX) { + c->oldx = c->x; + c->x = m->mx + ev->x; + } + if (ev->value_mask & CWY) { + c->oldy = c->y; + c->y = m->my + ev->y; + } + if (ev->value_mask & CWWidth) { + c->oldw = c->w; + c->w = ev->width; + } + if (ev->value_mask & CWHeight) { + c->oldh = c->h; + c->h = ev->height; + } + if ((c->x + c->w) > m->mx + m->mw && c->isfloating) + c->x = m->mx + (m->mw / 2 - WIDTH(c) / 2); /* center in x direction */ + if ((c->y + c->h) > m->my + m->mh && c->isfloating) + c->y = m->my + (m->mh / 2 - HEIGHT(c) / 2); /* center in y direction */ + if ((ev->value_mask & (CWX|CWY)) && !(ev->value_mask & (CWWidth|CWHeight))) + configure(c); + if (ISVISIBLE(c)) + XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h); + } else + configure(c); + } else { + wc.x = ev->x; + wc.y = ev->y; + wc.width = ev->width; + wc.height = ev->height; + wc.border_width = ev->border_width; + wc.sibling = ev->above; + wc.stack_mode = ev->detail; + XConfigureWindow(dpy, ev->window, ev->value_mask, &wc); + } + XSync(dpy, False); +} + +Monitor * +createmon(void) +{ + Monitor *m; + + m = ecalloc(1, sizeof(Monitor)); + m->tagset[0] = m->tagset[1] = 1; + m->mfact = mfact; + m->nmaster = nmaster; + m->showbar = showbar; + m->topbar = topbar; + m->lt[0] = &layouts[0]; + m->lt[1] = &layouts[1 % LENGTH(layouts)]; + strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol); + return m; +} + +void +destroynotify(XEvent *e) +{ + Client *c; + XDestroyWindowEvent *ev = &e->xdestroywindow; + + if ((c = wintoclient(ev->window))) + unmanage(c, 1); +} + +void +detach(Client *c) +{ + Client **tc; + + for (tc = &c->mon->clients; *tc && *tc != c; tc = &(*tc)->next); + *tc = c->next; +} + +void +detachstack(Client *c) +{ + Client **tc, *t; + + for (tc = &c->mon->stack; *tc && *tc != c; tc = &(*tc)->snext); + *tc = c->snext; + + if (c == c->mon->sel) { + for (t = c->mon->stack; t && !ISVISIBLE(t); t = t->snext); + c->mon->sel = t; + } +} + +Monitor * +dirtomon(int dir) +{ + Monitor *m = NULL; + + if (dir > 0) { + if (!(m = selmon->next)) + m = mons; + } else if (selmon == mons) + for (m = mons; m->next; m = m->next); + else + for (m = mons; m->next != selmon; m = m->next); + return m; +} + +void +drawbar(Monitor *m) +{ + int x, w, tw = 0; + int boxs = drw->fonts->h / 9; + int boxw = drw->fonts->h / 6 + 2; + unsigned int i, occ = 0, urg = 0; + Client *c; + + if (!m->showbar) + return; + + /* draw status first so it can be overdrawn by tags later */ + if (m == selmon) { /* status is only drawn on selected monitor */ + drw_setscheme(drw, scheme[SchemeNorm]); + tw = TEXTW(stext) - lrpad + 2; /* 2px right padding */ + drw_text(drw, m->ww - tw, 0, tw, bh, 0, stext, 0); + } + + for (c = m->clients; c; c = c->next) { + occ |= c->tags; + if (c->isurgent) + urg |= c->tags; + } + x = 0; + for (i = 0; i < LENGTH(tags); i++) { + w = TEXTW(tags[i]); + drw_setscheme(drw, scheme[m->tagset[m->seltags] & 1 << i ? SchemeSel : SchemeNorm]); + drw_text(drw, x, 0, w, bh, lrpad / 2, tags[i], urg & 1 << i); + if (occ & 1 << i) + drw_rect(drw, x + boxs, boxs, boxw, boxw, + m == selmon && selmon->sel && selmon->sel->tags & 1 << i, + urg & 1 << i); + x += w; + } + w = blw = TEXTW(m->ltsymbol); + drw_setscheme(drw, scheme[SchemeNorm]); + x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0); + + if ((w = m->ww - tw - x) > bh) { + if (m->sel) { + drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]); + drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0); + if (m->sel->isfloating) + drw_rect(drw, x + boxs, boxs, boxw, boxw, m->sel->isfixed, 0); + } else { + drw_setscheme(drw, scheme[SchemeNorm]); + drw_rect(drw, x, 0, w, bh, 1, 1); + } + } + drw_map(drw, m->barwin, 0, 0, m->ww, bh); +} + +void +drawbars(void) +{ + Monitor *m; + + for (m = mons; m; m = m->next) + drawbar(m); +} + +void +enternotify(XEvent *e) +{ + Client *c; + Monitor *m; + XCrossingEvent *ev = &e->xcrossing; + + if ((ev->mode != NotifyNormal || ev->detail == NotifyInferior) && ev->window != root) + return; + c = wintoclient(ev->window); + m = c ? c->mon : wintomon(ev->window); + if (m != selmon) { + unfocus(selmon->sel, 1); + selmon = m; + } else if (!c || c == selmon->sel) + return; + focus(c); +} + +void +expose(XEvent *e) +{ + Monitor *m; + XExposeEvent *ev = &e->xexpose; + + if (ev->count == 0 && (m = wintomon(ev->window))) + drawbar(m); +} + +void +focus(Client *c) +{ + if (!c || !ISVISIBLE(c)) + for (c = selmon->stack; c && !ISVISIBLE(c); c = c->snext); + if (selmon->sel && selmon->sel != c) + unfocus(selmon->sel, 0); + if (c) { + if (c->mon != selmon) + selmon = c->mon; + if (c->isurgent) + seturgent(c, 0); + detachstack(c); + attachstack(c); + grabbuttons(c, 1); + XSetWindowBorder(dpy, c->win, scheme[SchemeSel][ColBorder].pixel); + setfocus(c); + } else { + XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime); + XDeleteProperty(dpy, root, netatom[NetActiveWindow]); + } + selmon->sel = c; + drawbars(); +} + +/* there are some broken focus acquiring clients needing extra handling */ +void +focusin(XEvent *e) +{ + XFocusChangeEvent *ev = &e->xfocus; + + if (selmon->sel && ev->window != selmon->sel->win) + setfocus(selmon->sel); +} + +void +focusmon(const Arg *arg) +{ + Monitor *m; + + if (!mons->next) + return; + if ((m = dirtomon(arg->i)) == selmon) + return; + unfocus(selmon->sel, 0); + selmon = m; + focus(NULL); +} + +void +focusstack(const Arg *arg) +{ + Client *c = NULL, *i; + + if (!selmon->sel || (selmon->sel->isfullscreen && lockfullscreen)) + return; + if (arg->i > 0) { + for (c = selmon->sel->next; c && !ISVISIBLE(c); c = c->next); + if (!c) + for (c = selmon->clients; c && !ISVISIBLE(c); c = c->next); + } else { + for (i = selmon->clients; i != selmon->sel; i = i->next) + if (ISVISIBLE(i)) + c = i; + if (!c) + for (; i; i = i->next) + if (ISVISIBLE(i)) + c = i; + } + if (c) { + focus(c); + restack(selmon); + } +} + +Atom +getatomprop(Client *c, Atom prop) +{ + int di; + unsigned long dl; + unsigned char *p = NULL; + Atom da, atom = None; + + if (XGetWindowProperty(dpy, c->win, prop, 0L, sizeof atom, False, XA_ATOM, + &da, &di, &dl, &dl, &p) == Success && p) { + atom = *(Atom *)p; + XFree(p); + } + return atom; +} + +int +getrootptr(int *x, int *y) +{ + int di; + unsigned int dui; + Window dummy; + + return XQueryPointer(dpy, root, &dummy, &dummy, x, y, &di, &di, &dui); +} + +long +getstate(Window w) +{ + int format; + long result = -1; + unsigned char *p = NULL; + unsigned long n, extra; + Atom real; + + if (XGetWindowProperty(dpy, w, wmatom[WMState], 0L, 2L, False, wmatom[WMState], + &real, &format, &n, &extra, (unsigned char **)&p) != Success) + return -1; + if (n != 0) + result = *p; + XFree(p); + return result; +} + +int +gettextprop(Window w, Atom atom, char *text, unsigned int size) +{ + char **list = NULL; + int n; + XTextProperty name; + + if (!text || size == 0) + return 0; + text[0] = '\0'; + if (!XGetTextProperty(dpy, w, &name, atom) || !name.nitems) + return 0; + if (name.encoding == XA_STRING) + strncpy(text, (char *)name.value, size - 1); + else { + if (XmbTextPropertyToTextList(dpy, &name, &list, &n) >= Success && n > 0 && *list) { + strncpy(text, *list, size - 1); + XFreeStringList(list); + } + } + text[size - 1] = '\0'; + XFree(name.value); + return 1; +} + +void +grabbuttons(Client *c, int focused) +{ + updatenumlockmask(); + { + unsigned int i, j; + unsigned int modifiers[] = { 0, LockMask, numlockmask, numlockmask|LockMask }; + XUngrabButton(dpy, AnyButton, AnyModifier, c->win); + if (!focused) + XGrabButton(dpy, AnyButton, AnyModifier, c->win, False, + BUTTONMASK, GrabModeSync, GrabModeSync, None, None); + for (i = 0; i < LENGTH(buttons); i++) + if (buttons[i].click == ClkClientWin) + for (j = 0; j < LENGTH(modifiers); j++) + XGrabButton(dpy, buttons[i].button, + buttons[i].mask | modifiers[j], + c->win, False, BUTTONMASK, + GrabModeAsync, GrabModeSync, None, None); + } +} + +void +grabkeys(void) +{ + updatenumlockmask(); + { + unsigned int i, j; + unsigned int modifiers[] = { 0, LockMask, numlockmask, numlockmask|LockMask }; + KeyCode code; + + XUngrabKey(dpy, AnyKey, AnyModifier, root); + for (i = 0; i < LENGTH(keys); i++) + if ((code = XKeysymToKeycode(dpy, keys[i].keysym))) + for (j = 0; j < LENGTH(modifiers); j++) + XGrabKey(dpy, code, keys[i].mod | modifiers[j], root, + True, GrabModeAsync, GrabModeAsync); + } +} + +void +incnmaster(const Arg *arg) +{ + selmon->nmaster = MAX(selmon->nmaster + arg->i, 0); + arrange(selmon); +} + +#ifdef XINERAMA +static int +isuniquegeom(XineramaScreenInfo *unique, size_t n, XineramaScreenInfo *info) +{ + while (n--) + if (unique[n].x_org == info->x_org && unique[n].y_org == info->y_org + && unique[n].width == info->width && unique[n].height == info->height) + return 0; + return 1; +} +#endif /* XINERAMA */ + +void +keypress(XEvent *e) +{ + unsigned int i; + KeySym keysym; + XKeyEvent *ev; + + ev = &e->xkey; + keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0); + for (i = 0; i < LENGTH(keys); i++) + if (keysym == keys[i].keysym + && CLEANMASK(keys[i].mod) == CLEANMASK(ev->state) + && keys[i].func) + keys[i].func(&(keys[i].arg)); +} + +void +killclient(const Arg *arg) +{ + if (!selmon->sel) + return; + if (!sendevent(selmon->sel, wmatom[WMDelete])) { + XGrabServer(dpy); + XSetErrorHandler(xerrordummy); + XSetCloseDownMode(dpy, DestroyAll); + XKillClient(dpy, selmon->sel->win); + XSync(dpy, False); + XSetErrorHandler(xerror); + XUngrabServer(dpy); + } +} + +void +manage(Window w, XWindowAttributes *wa) +{ + Client *c, *t = NULL; + Window trans = None; + XWindowChanges wc; + + c = ecalloc(1, sizeof(Client)); + c->win = w; + /* geometry */ + c->x = c->oldx = wa->x; + c->y = c->oldy = wa->y; + c->w = c->oldw = wa->width; + c->h = c->oldh = wa->height; + c->oldbw = wa->border_width; + + updatetitle(c); + if (XGetTransientForHint(dpy, w, &trans) && (t = wintoclient(trans))) { + c->mon = t->mon; + c->tags = t->tags; + } else { + c->mon = selmon; + applyrules(c); + } + + if (c->x + WIDTH(c) > c->mon->mx + c->mon->mw) + c->x = c->mon->mx + c->mon->mw - WIDTH(c); + if (c->y + HEIGHT(c) > c->mon->my + c->mon->mh) + c->y = c->mon->my + c->mon->mh - HEIGHT(c); + c->x = MAX(c->x, c->mon->mx); + /* only fix client y-offset, if the client center might cover the bar */ + c->y = MAX(c->y, ((c->mon->by == c->mon->my) && (c->x + (c->w / 2) >= c->mon->wx) + && (c->x + (c->w / 2) < c->mon->wx + c->mon->ww)) ? bh : c->mon->my); + c->bw = borderpx; + + wc.border_width = c->bw; + XConfigureWindow(dpy, w, CWBorderWidth, &wc); + XSetWindowBorder(dpy, w, scheme[SchemeNorm][ColBorder].pixel); + configure(c); /* propagates border_width, if size doesn't change */ + updatewindowtype(c); + updatesizehints(c); + updatewmhints(c); + XSelectInput(dpy, w, EnterWindowMask|FocusChangeMask|PropertyChangeMask|StructureNotifyMask); + grabbuttons(c, 0); + if (!c->isfloating) + c->isfloating = c->oldstate = trans != None || c->isfixed; + if (c->isfloating) + XRaiseWindow(dpy, c->win); + attach(c); + attachstack(c); + XChangeProperty(dpy, root, netatom[NetClientList], XA_WINDOW, 32, PropModeAppend, + (unsigned char *) &(c->win), 1); + XMoveResizeWindow(dpy, c->win, c->x + 2 * sw, c->y, c->w, c->h); /* some windows require this */ + setclientstate(c, NormalState); + if (c->mon == selmon) + unfocus(selmon->sel, 0); + c->mon->sel = c; + arrange(c->mon); + XMapWindow(dpy, c->win); + focus(NULL); +} + +void +mappingnotify(XEvent *e) +{ + XMappingEvent *ev = &e->xmapping; + + XRefreshKeyboardMapping(ev); + if (ev->request == MappingKeyboard) + grabkeys(); +} + +void +maprequest(XEvent *e) +{ + static XWindowAttributes wa; + XMapRequestEvent *ev = &e->xmaprequest; + + if (!XGetWindowAttributes(dpy, ev->window, &wa)) + return; + if (wa.override_redirect) + return; + if (!wintoclient(ev->window)) + manage(ev->window, &wa); +} + +void +monocle(Monitor *m) +{ + unsigned int n = 0; + Client *c; + + for (c = m->clients; c; c = c->next) + if (ISVISIBLE(c)) + n++; + if (n > 0) /* override layout symbol */ + snprintf(m->ltsymbol, sizeof m->ltsymbol, "[%d]", n); + for (c = nexttiled(m->clients); c; c = nexttiled(c->next)) + resize(c, m->wx, m->wy, m->ww - 2 * c->bw, m->wh - 2 * c->bw, 0); +} + +void +motionnotify(XEvent *e) +{ + static Monitor *mon = NULL; + Monitor *m; + XMotionEvent *ev = &e->xmotion; + + if (ev->window != root) + return; + if ((m = recttomon(ev->x_root, ev->y_root, 1, 1)) != mon && mon) { + unfocus(selmon->sel, 1); + selmon = m; + focus(NULL); + } + mon = m; +} + +void +movemouse(const Arg *arg) +{ + int x, y, ocx, ocy, nx, ny; + Client *c; + Monitor *m; + XEvent ev; + Time lasttime = 0; + + if (!(c = selmon->sel)) + return; + if (c->isfullscreen) /* no support moving fullscreen windows by mouse */ + return; + restack(selmon); + ocx = c->x; + ocy = c->y; + if (XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync, + None, cursor[CurMove]->cursor, CurrentTime) != GrabSuccess) + return; + if (!getrootptr(&x, &y)) + return; + do { + XMaskEvent(dpy, MOUSEMASK|ExposureMask|SubstructureRedirectMask, &ev); + switch(ev.type) { + case ConfigureRequest: + case Expose: + case MapRequest: + handler[ev.type](&ev); + break; + case MotionNotify: + if ((ev.xmotion.time - lasttime) <= (1000 / 60)) + continue; + lasttime = ev.xmotion.time; + + nx = ocx + (ev.xmotion.x - x); + ny = ocy + (ev.xmotion.y - y); + if (abs(selmon->wx - nx) < snap) + nx = selmon->wx; + else if (abs((selmon->wx + selmon->ww) - (nx + WIDTH(c))) < snap) + nx = selmon->wx + selmon->ww - WIDTH(c); + if (abs(selmon->wy - ny) < snap) + ny = selmon->wy; + else if (abs((selmon->wy + selmon->wh) - (ny + HEIGHT(c))) < snap) + ny = selmon->wy + selmon->wh - HEIGHT(c); + if (!c->isfloating && selmon->lt[selmon->sellt]->arrange + && (abs(nx - c->x) > snap || abs(ny - c->y) > snap)) + togglefloating(NULL); + if (!selmon->lt[selmon->sellt]->arrange || c->isfloating) + resize(c, nx, ny, c->w, c->h, 1); + break; + } + } while (ev.type != ButtonRelease); + XUngrabPointer(dpy, CurrentTime); + if ((m = recttomon(c->x, c->y, c->w, c->h)) != selmon) { + sendmon(c, m); + selmon = m; + focus(NULL); + } +} + +Client * +nexttiled(Client *c) +{ + for (; c && (c->isfloating || !ISVISIBLE(c)); c = c->next); + return c; +} + +void +pop(Client *c) +{ + detach(c); + attach(c); + focus(c); + arrange(c->mon); +} + +void +propertynotify(XEvent *e) +{ + Client *c; + Window trans; + XPropertyEvent *ev = &e->xproperty; + + if ((ev->window == root) && (ev->atom == XA_WM_NAME)) + updatestatus(); + else if (ev->state == PropertyDelete) + return; /* ignore */ + else if ((c = wintoclient(ev->window))) { + switch(ev->atom) { + default: break; + case XA_WM_TRANSIENT_FOR: + if (!c->isfloating && (XGetTransientForHint(dpy, c->win, &trans)) && + (c->isfloating = (wintoclient(trans)) != NULL)) + arrange(c->mon); + break; + case XA_WM_NORMAL_HINTS: + updatesizehints(c); + break; + case XA_WM_HINTS: + updatewmhints(c); + drawbars(); + break; + } + if (ev->atom == XA_WM_NAME || ev->atom == netatom[NetWMName]) { + updatetitle(c); + if (c == c->mon->sel) + drawbar(c->mon); + } + if (ev->atom == netatom[NetWMWindowType]) + updatewindowtype(c); + } +} + +void +quit(const Arg *arg) +{ + running = 0; +} + +Monitor * +recttomon(int x, int y, int w, int h) +{ + Monitor *m, *r = selmon; + int a, area = 0; + + for (m = mons; m; m = m->next) + if ((a = INTERSECT(x, y, w, h, m)) > area) { + area = a; + r = m; + } + return r; +} + +void +resize(Client *c, int x, int y, int w, int h, int interact) +{ + if (applysizehints(c, &x, &y, &w, &h, interact)) + resizeclient(c, x, y, w, h); +} + +void +resizeclient(Client *c, int x, int y, int w, int h) +{ + XWindowChanges wc; + + c->oldx = c->x; c->x = wc.x = x; + c->oldy = c->y; c->y = wc.y = y; + c->oldw = c->w; c->w = wc.width = w; + c->oldh = c->h; c->h = wc.height = h; + wc.border_width = c->bw; + XConfigureWindow(dpy, c->win, CWX|CWY|CWWidth|CWHeight|CWBorderWidth, &wc); + configure(c); + XSync(dpy, False); +} + +void +resizemouse(const Arg *arg) +{ + int ocx, ocy, nw, nh; + Client *c; + Monitor *m; + XEvent ev; + Time lasttime = 0; + + if (!(c = selmon->sel)) + return; + if (c->isfullscreen) /* no support resizing fullscreen windows by mouse */ + return; + restack(selmon); + ocx = c->x; + ocy = c->y; + if (XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync, + None, cursor[CurResize]->cursor, CurrentTime) != GrabSuccess) + return; + XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->bw - 1, c->h + c->bw - 1); + do { + XMaskEvent(dpy, MOUSEMASK|ExposureMask|SubstructureRedirectMask, &ev); + switch(ev.type) { + case ConfigureRequest: + case Expose: + case MapRequest: + handler[ev.type](&ev); + break; + case MotionNotify: + if ((ev.xmotion.time - lasttime) <= (1000 / 60)) + continue; + lasttime = ev.xmotion.time; + + nw = MAX(ev.xmotion.x - ocx - 2 * c->bw + 1, 1); + nh = MAX(ev.xmotion.y - ocy - 2 * c->bw + 1, 1); + if (c->mon->wx + nw >= selmon->wx && c->mon->wx + nw <= selmon->wx + selmon->ww + && c->mon->wy + nh >= selmon->wy && c->mon->wy + nh <= selmon->wy + selmon->wh) + { + if (!c->isfloating && selmon->lt[selmon->sellt]->arrange + && (abs(nw - c->w) > snap || abs(nh - c->h) > snap)) + togglefloating(NULL); + } + if (!selmon->lt[selmon->sellt]->arrange || c->isfloating) + resize(c, c->x, c->y, nw, nh, 1); + break; + } + } while (ev.type != ButtonRelease); + XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->bw - 1, c->h + c->bw - 1); + XUngrabPointer(dpy, CurrentTime); + while (XCheckMaskEvent(dpy, EnterWindowMask, &ev)); + if ((m = recttomon(c->x, c->y, c->w, c->h)) != selmon) { + sendmon(c, m); + selmon = m; + focus(NULL); + } +} + +void +restack(Monitor *m) +{ + Client *c; + XEvent ev; + XWindowChanges wc; + + drawbar(m); + if (!m->sel) + return; + if (m->sel->isfloating || !m->lt[m->sellt]->arrange) + XRaiseWindow(dpy, m->sel->win); + if (m->lt[m->sellt]->arrange) { + wc.stack_mode = Below; + wc.sibling = m->barwin; + for (c = m->stack; c; c = c->snext) + if (!c->isfloating && ISVISIBLE(c)) { + XConfigureWindow(dpy, c->win, CWSibling|CWStackMode, &wc); + wc.sibling = c->win; + } + } + XSync(dpy, False); + while (XCheckMaskEvent(dpy, EnterWindowMask, &ev)); +} + +void +run(void) +{ + XEvent ev; + /* main event loop */ + XSync(dpy, False); + while (running && !XNextEvent(dpy, &ev)) + if (handler[ev.type]) + handler[ev.type](&ev); /* call handler */ +} + +void +scan(void) +{ + unsigned int i, num; + Window d1, d2, *wins = NULL; + XWindowAttributes wa; + + if (XQueryTree(dpy, root, &d1, &d2, &wins, &num)) { + for (i = 0; i < num; i++) { + if (!XGetWindowAttributes(dpy, wins[i], &wa) + || wa.override_redirect || XGetTransientForHint(dpy, wins[i], &d1)) + continue; + if (wa.map_state == IsViewable || getstate(wins[i]) == IconicState) + manage(wins[i], &wa); + } + for (i = 0; i < num; i++) { /* now the transients */ + if (!XGetWindowAttributes(dpy, wins[i], &wa)) + continue; + if (XGetTransientForHint(dpy, wins[i], &d1) + && (wa.map_state == IsViewable || getstate(wins[i]) == IconicState)) + manage(wins[i], &wa); + } + if (wins) + XFree(wins); + } +} + +void +sendmon(Client *c, Monitor *m) +{ + if (c->mon == m) + return; + unfocus(c, 1); + detach(c); + detachstack(c); + c->mon = m; + c->tags = m->tagset[m->seltags]; /* assign tags of target monitor */ + attach(c); + attachstack(c); + focus(NULL); + arrange(NULL); +} + +void +setclientstate(Client *c, long state) +{ + long data[] = { state, None }; + + XChangeProperty(dpy, c->win, wmatom[WMState], wmatom[WMState], 32, + PropModeReplace, (unsigned char *)data, 2); +} + +int +sendevent(Client *c, Atom proto) +{ + int n; + Atom *protocols; + int exists = 0; + XEvent ev; + + if (XGetWMProtocols(dpy, c->win, &protocols, &n)) { + while (!exists && n--) + exists = protocols[n] == proto; + XFree(protocols); + } + if (exists) { + ev.type = ClientMessage; + ev.xclient.window = c->win; + ev.xclient.message_type = wmatom[WMProtocols]; + ev.xclient.format = 32; + ev.xclient.data.l[0] = proto; + ev.xclient.data.l[1] = CurrentTime; + XSendEvent(dpy, c->win, False, NoEventMask, &ev); + } + return exists; +} + +void +setfocus(Client *c) +{ + if (!c->neverfocus) { + XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime); + XChangeProperty(dpy, root, netatom[NetActiveWindow], + XA_WINDOW, 32, PropModeReplace, + (unsigned char *) &(c->win), 1); + } + sendevent(c, wmatom[WMTakeFocus]); +} + +void +setfullscreen(Client *c, int fullscreen) +{ + if (fullscreen && !c->isfullscreen) { + XChangeProperty(dpy, c->win, netatom[NetWMState], XA_ATOM, 32, + PropModeReplace, (unsigned char*)&netatom[NetWMFullscreen], 1); + c->isfullscreen = 1; + c->oldstate = c->isfloating; + c->oldbw = c->bw; + c->bw = 0; + c->isfloating = 1; + resizeclient(c, c->mon->mx, c->mon->my, c->mon->mw, c->mon->mh); + XRaiseWindow(dpy, c->win); + } else if (!fullscreen && c->isfullscreen){ + XChangeProperty(dpy, c->win, netatom[NetWMState], XA_ATOM, 32, + PropModeReplace, (unsigned char*)0, 0); + c->isfullscreen = 0; + c->isfloating = c->oldstate; + c->bw = c->oldbw; + c->x = c->oldx; + c->y = c->oldy; + c->w = c->oldw; + c->h = c->oldh; + resizeclient(c, c->x, c->y, c->w, c->h); + arrange(c->mon); + } +} + +void +setlayout(const Arg *arg) +{ + if (!arg || !arg->v || arg->v != selmon->lt[selmon->sellt]) + selmon->sellt ^= 1; + if (arg && arg->v) + selmon->lt[selmon->sellt] = (Layout *)arg->v; + strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, sizeof selmon->ltsymbol); + if (selmon->sel) + arrange(selmon); + else + drawbar(selmon); +} + +/* arg > 1.0 will set mfact absolutely */ +void +setmfact(const Arg *arg) +{ + float f; + + if (!arg || !selmon->lt[selmon->sellt]->arrange) + return; + f = arg->f < 1.0 ? arg->f + selmon->mfact : arg->f - 1.0; + if (f < 0.05 || f > 0.95) + return; + selmon->mfact = f; + arrange(selmon); +} + +void +setup(void) +{ + int i; + XSetWindowAttributes wa; + Atom utf8string; + + /* clean up any zombies immediately */ + sigchld(0); + + /* init screen */ + screen = DefaultScreen(dpy); + sw = DisplayWidth(dpy, screen); + sh = DisplayHeight(dpy, screen); + root = RootWindow(dpy, screen); + drw = drw_create(dpy, screen, root, sw, sh); + if (!drw_fontset_create(drw, fonts, LENGTH(fonts))) + die("no fonts could be loaded."); + lrpad = drw->fonts->h; + bh = drw->fonts->h + 2; + updategeom(); + /* init atoms */ + utf8string = XInternAtom(dpy, "UTF8_STRING", False); + wmatom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False); + wmatom[WMDelete] = XInternAtom(dpy, "WM_DELETE_WINDOW", False); + wmatom[WMState] = XInternAtom(dpy, "WM_STATE", False); + wmatom[WMTakeFocus] = XInternAtom(dpy, "WM_TAKE_FOCUS", False); + netatom[NetActiveWindow] = XInternAtom(dpy, "_NET_ACTIVE_WINDOW", False); + netatom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False); + netatom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False); + netatom[NetWMState] = XInternAtom(dpy, "_NET_WM_STATE", False); + netatom[NetWMCheck] = XInternAtom(dpy, "_NET_SUPPORTING_WM_CHECK", False); + netatom[NetWMFullscreen] = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False); + netatom[NetWMWindowType] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False); + netatom[NetWMWindowTypeDialog] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DIALOG", False); + netatom[NetClientList] = XInternAtom(dpy, "_NET_CLIENT_LIST", False); + /* init cursors */ + cursor[CurNormal] = drw_cur_create(drw, XC_left_ptr); + cursor[CurResize] = drw_cur_create(drw, XC_sizing); + cursor[CurMove] = drw_cur_create(drw, XC_fleur); + /* init appearance */ + scheme = ecalloc(LENGTH(colors), sizeof(Clr *)); + for (i = 0; i < LENGTH(colors); i++) + scheme[i] = drw_scm_create(drw, colors[i], 3); + /* init bars */ + updatebars(); + updatestatus(); + /* supporting window for NetWMCheck */ + wmcheckwin = XCreateSimpleWindow(dpy, root, 0, 0, 1, 1, 0, 0, 0); + XChangeProperty(dpy, wmcheckwin, netatom[NetWMCheck], XA_WINDOW, 32, + PropModeReplace, (unsigned char *) &wmcheckwin, 1); + XChangeProperty(dpy, wmcheckwin, netatom[NetWMName], utf8string, 8, + PropModeReplace, (unsigned char *) "dwm", 3); + XChangeProperty(dpy, root, netatom[NetWMCheck], XA_WINDOW, 32, + PropModeReplace, (unsigned char *) &wmcheckwin, 1); + /* EWMH support per view */ + XChangeProperty(dpy, root, netatom[NetSupported], XA_ATOM, 32, + PropModeReplace, (unsigned char *) netatom, NetLast); + XDeleteProperty(dpy, root, netatom[NetClientList]); + /* select events */ + wa.cursor = cursor[CurNormal]->cursor; + wa.event_mask = SubstructureRedirectMask|SubstructureNotifyMask + |ButtonPressMask|PointerMotionMask|EnterWindowMask + |LeaveWindowMask|StructureNotifyMask|PropertyChangeMask; + XChangeWindowAttributes(dpy, root, CWEventMask|CWCursor, &wa); + XSelectInput(dpy, root, wa.event_mask); + grabkeys(); + focus(NULL); +} + + +void +seturgent(Client *c, int urg) +{ + XWMHints *wmh; + + c->isurgent = urg; + if (!(wmh = XGetWMHints(dpy, c->win))) + return; + wmh->flags = urg ? (wmh->flags | XUrgencyHint) : (wmh->flags & ~XUrgencyHint); + XSetWMHints(dpy, c->win, wmh); + XFree(wmh); +} + +void +showhide(Client *c) +{ + if (!c) + return; + if (ISVISIBLE(c)) { + /* show clients top down */ + XMoveWindow(dpy, c->win, c->x, c->y); + if ((!c->mon->lt[c->mon->sellt]->arrange || c->isfloating) && !c->isfullscreen) + resize(c, c->x, c->y, c->w, c->h, 0); + showhide(c->snext); + } else { + /* hide clients bottom up */ + showhide(c->snext); + XMoveWindow(dpy, c->win, WIDTH(c) * -2, c->y); + } +} + +void +sigchld(int unused) +{ + if (signal(SIGCHLD, sigchld) == SIG_ERR) + die("can't install SIGCHLD handler:"); + while (0 < waitpid(-1, NULL, WNOHANG)); +} + +void +spawn(const Arg *arg) +{ + if (arg->v == dmenucmd) + dmenumon[0] = '0' + selmon->num; + if (fork() == 0) { + if (dpy) + close(ConnectionNumber(dpy)); + setsid(); + execvp(((char **)arg->v)[0], (char **)arg->v); + fprintf(stderr, "dwm: execvp %s", ((char **)arg->v)[0]); + perror(" failed"); + exit(EXIT_SUCCESS); + } +} + +void +tag(const Arg *arg) +{ + if (selmon->sel && arg->ui & TAGMASK) { + selmon->sel->tags = arg->ui & TAGMASK; + focus(NULL); + arrange(selmon); + } +} + +void +tagmon(const Arg *arg) +{ + if (!selmon->sel || !mons->next) + return; + sendmon(selmon->sel, dirtomon(arg->i)); +} + +void +tile(Monitor *m) +{ + unsigned int i, n, h, mw, my, ty; + Client *c; + + for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); + if (n == 0) + return; + + if (n > m->nmaster) + mw = m->nmaster ? m->ww * m->mfact : 0; + else + mw = m->ww; + for (i = my = ty = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) + if (i < m->nmaster) { + h = (m->wh - my) / (MIN(n, m->nmaster) - i); + resize(c, m->wx, m->wy + my, mw - (2*c->bw), h - (2*c->bw), 0); + if (my + HEIGHT(c) < m->wh) + my += HEIGHT(c); + } else { + h = (m->wh - ty) / (n - i); + resize(c, m->wx + mw, m->wy + ty, m->ww - mw - (2*c->bw), h - (2*c->bw), 0); + if (ty + HEIGHT(c) < m->wh) + ty += HEIGHT(c); + } +} + +void +togglebar(const Arg *arg) +{ + selmon->showbar = !selmon->showbar; + updatebarpos(selmon); + XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh); + arrange(selmon); +} + +void +togglefloating(const Arg *arg) +{ + if (!selmon->sel) + return; + if (selmon->sel->isfullscreen) /* no support for fullscreen windows */ + return; + selmon->sel->isfloating = !selmon->sel->isfloating || selmon->sel->isfixed; + if (selmon->sel->isfloating) + resize(selmon->sel, selmon->sel->x, selmon->sel->y, + selmon->sel->w, selmon->sel->h, 0); + arrange(selmon); +} + +void +toggletag(const Arg *arg) +{ + unsigned int newtags; + + if (!selmon->sel) + return; + newtags = selmon->sel->tags ^ (arg->ui & TAGMASK); + if (newtags) { + selmon->sel->tags = newtags; + focus(NULL); + arrange(selmon); + } +} + +void +toggleview(const Arg *arg) +{ + unsigned int newtagset = selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK); + + if (newtagset) { + selmon->tagset[selmon->seltags] = newtagset; + focus(NULL); + arrange(selmon); + } +} + +void +unfocus(Client *c, int setfocus) +{ + if (!c) + return; + grabbuttons(c, 0); + XSetWindowBorder(dpy, c->win, scheme[SchemeNorm][ColBorder].pixel); + if (setfocus) { + XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime); + XDeleteProperty(dpy, root, netatom[NetActiveWindow]); + } +} + +void +unmanage(Client *c, int destroyed) +{ + Monitor *m = c->mon; + XWindowChanges wc; + + detach(c); + detachstack(c); + if (!destroyed) { + wc.border_width = c->oldbw; + XGrabServer(dpy); /* avoid race conditions */ + XSetErrorHandler(xerrordummy); + XConfigureWindow(dpy, c->win, CWBorderWidth, &wc); /* restore border */ + XUngrabButton(dpy, AnyButton, AnyModifier, c->win); + setclientstate(c, WithdrawnState); + XSync(dpy, False); + XSetErrorHandler(xerror); + XUngrabServer(dpy); + } + free(c); + focus(NULL); + updateclientlist(); + arrange(m); +} + +void +unmapnotify(XEvent *e) +{ + Client *c; + XUnmapEvent *ev = &e->xunmap; + + if ((c = wintoclient(ev->window))) { + if (ev->send_event) + setclientstate(c, WithdrawnState); + else + unmanage(c, 0); + } +} + +void +updatebars(void) +{ + Monitor *m; + XSetWindowAttributes wa = { + .override_redirect = True, + .background_pixmap = ParentRelative, + .event_mask = ButtonPressMask|ExposureMask + }; + XClassHint ch = {"dwm", "dwm"}; + for (m = mons; m; m = m->next) { + if (m->barwin) + continue; + m->barwin = XCreateWindow(dpy, root, m->wx, m->by, m->ww, bh, 0, DefaultDepth(dpy, screen), + CopyFromParent, DefaultVisual(dpy, screen), + CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa); + XDefineCursor(dpy, m->barwin, cursor[CurNormal]->cursor); + XMapRaised(dpy, m->barwin); + XSetClassHint(dpy, m->barwin, &ch); + } +} + +void +updatebarpos(Monitor *m) +{ + m->wy = m->my; + m->wh = m->mh; + if (m->showbar) { + m->wh -= bh; + m->by = m->topbar ? m->wy : m->wy + m->wh; + m->wy = m->topbar ? m->wy + bh : m->wy; + } else + m->by = -bh; +} + +void +updateclientlist() +{ + Client *c; + Monitor *m; + + XDeleteProperty(dpy, root, netatom[NetClientList]); + for (m = mons; m; m = m->next) + for (c = m->clients; c; c = c->next) + XChangeProperty(dpy, root, netatom[NetClientList], + XA_WINDOW, 32, PropModeAppend, + (unsigned char *) &(c->win), 1); +} + +int +updategeom(void) +{ + int dirty = 0; + +#ifdef XINERAMA + if (XineramaIsActive(dpy)) { + int i, j, n, nn; + Client *c; + Monitor *m; + XineramaScreenInfo *info = XineramaQueryScreens(dpy, &nn); + XineramaScreenInfo *unique = NULL; + + for (n = 0, m = mons; m; m = m->next, n++); + /* only consider unique geometries as separate screens */ + unique = ecalloc(nn, sizeof(XineramaScreenInfo)); + for (i = 0, j = 0; i < nn; i++) + if (isuniquegeom(unique, j, &info[i])) + memcpy(&unique[j++], &info[i], sizeof(XineramaScreenInfo)); + XFree(info); + nn = j; + if (n <= nn) { /* new monitors available */ + for (i = 0; i < (nn - n); i++) { + for (m = mons; m && m->next; m = m->next); + if (m) + m->next = createmon(); + else + mons = createmon(); + } + for (i = 0, m = mons; i < nn && m; m = m->next, i++) + if (i >= n + || unique[i].x_org != m->mx || unique[i].y_org != m->my + || unique[i].width != m->mw || unique[i].height != m->mh) + { + dirty = 1; + m->num = i; + m->mx = m->wx = unique[i].x_org; + m->my = m->wy = unique[i].y_org; + m->mw = m->ww = unique[i].width; + m->mh = m->wh = unique[i].height; + updatebarpos(m); + } + } else { /* less monitors available nn < n */ + for (i = nn; i < n; i++) { + for (m = mons; m && m->next; m = m->next); + while ((c = m->clients)) { + dirty = 1; + m->clients = c->next; + detachstack(c); + c->mon = mons; + attach(c); + attachstack(c); + } + if (m == selmon) + selmon = mons; + cleanupmon(m); + } + } + free(unique); + } else +#endif /* XINERAMA */ + { /* default monitor setup */ + if (!mons) + mons = createmon(); + if (mons->mw != sw || mons->mh != sh) { + dirty = 1; + mons->mw = mons->ww = sw; + mons->mh = mons->wh = sh; + updatebarpos(mons); + } + } + if (dirty) { + selmon = mons; + selmon = wintomon(root); + } + return dirty; +} + +void +updatenumlockmask(void) +{ + unsigned int i, j; + XModifierKeymap *modmap; + + numlockmask = 0; + modmap = XGetModifierMapping(dpy); + for (i = 0; i < 8; i++) + for (j = 0; j < modmap->max_keypermod; j++) + if (modmap->modifiermap[i * modmap->max_keypermod + j] + == XKeysymToKeycode(dpy, XK_Num_Lock)) + numlockmask = (1 << i); + XFreeModifiermap(modmap); +} + +void +updatesizehints(Client *c) +{ + long msize; + XSizeHints size; + + if (!XGetWMNormalHints(dpy, c->win, &size, &msize)) + /* size is uninitialized, ensure that size.flags aren't used */ + size.flags = PSize; + if (size.flags & PBaseSize) { + c->basew = size.base_width; + c->baseh = size.base_height; + } else if (size.flags & PMinSize) { + c->basew = size.min_width; + c->baseh = size.min_height; + } else + c->basew = c->baseh = 0; + if (size.flags & PResizeInc) { + c->incw = size.width_inc; + c->inch = size.height_inc; + } else + c->incw = c->inch = 0; + if (size.flags & PMaxSize) { + c->maxw = size.max_width; + c->maxh = size.max_height; + } else + c->maxw = c->maxh = 0; + if (size.flags & PMinSize) { + c->minw = size.min_width; + c->minh = size.min_height; + } else if (size.flags & PBaseSize) { + c->minw = size.base_width; + c->minh = size.base_height; + } else + c->minw = c->minh = 0; + if (size.flags & PAspect) { + c->mina = (float)size.min_aspect.y / size.min_aspect.x; + c->maxa = (float)size.max_aspect.x / size.max_aspect.y; + } else + c->maxa = c->mina = 0.0; + c->isfixed = (c->maxw && c->maxh && c->maxw == c->minw && c->maxh == c->minh); +} + +void +updatestatus(void) +{ + if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext))) + strcpy(stext, "dwm-"VERSION); + drawbar(selmon); +} + +void +updatetitle(Client *c) +{ + if (!gettextprop(c->win, netatom[NetWMName], c->name, sizeof c->name)) + gettextprop(c->win, XA_WM_NAME, c->name, sizeof c->name); + if (c->name[0] == '\0') /* hack to mark broken clients */ + strcpy(c->name, broken); +} + +void +updatewindowtype(Client *c) +{ + Atom state = getatomprop(c, netatom[NetWMState]); + Atom wtype = getatomprop(c, netatom[NetWMWindowType]); + + if (state == netatom[NetWMFullscreen]) + setfullscreen(c, 1); + if (wtype == netatom[NetWMWindowTypeDialog]) + c->isfloating = 1; +} + +void +updatewmhints(Client *c) +{ + XWMHints *wmh; + + if ((wmh = XGetWMHints(dpy, c->win))) { + if (c == selmon->sel && wmh->flags & XUrgencyHint) { + wmh->flags &= ~XUrgencyHint; + XSetWMHints(dpy, c->win, wmh); + } else + c->isurgent = (wmh->flags & XUrgencyHint) ? 1 : 0; + if (wmh->flags & InputHint) + c->neverfocus = !wmh->input; + else + c->neverfocus = 0; + XFree(wmh); + } +} + +void +view(const Arg *arg) +{ + if ((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags]) + return; + selmon->seltags ^= 1; /* toggle sel tagset */ + if (arg->ui & TAGMASK) + selmon->tagset[selmon->seltags] = arg->ui & TAGMASK; + focus(NULL); + arrange(selmon); +} + +Client * +wintoclient(Window w) +{ + Client *c; + Monitor *m; + + for (m = mons; m; m = m->next) + for (c = m->clients; c; c = c->next) + if (c->win == w) + return c; + return NULL; +} + +Monitor * +wintomon(Window w) +{ + int x, y; + Client *c; + Monitor *m; + + if (w == root && getrootptr(&x, &y)) + return recttomon(x, y, 1, 1); + for (m = mons; m; m = m->next) + if (w == m->barwin) + return m; + if ((c = wintoclient(w))) + return c->mon; + return selmon; +} + +/* There's no way to check accesses to destroyed windows, thus those cases are + * ignored (especially on UnmapNotify's). Other types of errors call Xlibs + * default error handler, which may call exit. */ +int +xerror(Display *dpy, XErrorEvent *ee) +{ + if (ee->error_code == BadWindow + || (ee->request_code == X_SetInputFocus && ee->error_code == BadMatch) + || (ee->request_code == X_PolyText8 && ee->error_code == BadDrawable) + || (ee->request_code == X_PolyFillRectangle && ee->error_code == BadDrawable) + || (ee->request_code == X_PolySegment && ee->error_code == BadDrawable) + || (ee->request_code == X_ConfigureWindow && ee->error_code == BadMatch) + || (ee->request_code == X_GrabButton && ee->error_code == BadAccess) + || (ee->request_code == X_GrabKey && ee->error_code == BadAccess) + || (ee->request_code == X_CopyArea && ee->error_code == BadDrawable)) + return 0; + fprintf(stderr, "dwm: fatal error: request code=%d, error code=%d\n", + ee->request_code, ee->error_code); + return xerrorxlib(dpy, ee); /* may call exit */ +} + +int +xerrordummy(Display *dpy, XErrorEvent *ee) +{ + return 0; +} + +/* Startup Error handler to check if another window manager + * is already running. */ +int +xerrorstart(Display *dpy, XErrorEvent *ee) +{ + die("dwm: another window manager is already running"); + return -1; +} + +void +zoom(const Arg *arg) +{ + Client *c = selmon->sel; + + if (!selmon->lt[selmon->sellt]->arrange + || (selmon->sel && selmon->sel->isfloating)) + return; + if (c == nexttiled(selmon->clients)) + if (!c || !(c = nexttiled(c->next))) + return; + pop(c); +} + +int +main(int argc, char *argv[]) +{ + if (argc == 2 && !strcmp("-v", argv[1])) + die("dwm-"VERSION); + else if (argc != 1) + die("usage: dwm [-v]"); + if (!setlocale(LC_CTYPE, "") || !XSupportsLocale()) + fputs("warning: no locale support\n", stderr); + if (!(dpy = XOpenDisplay(NULL))) + die("dwm: cannot open display"); + checkotherwm(); + setup(); +#ifdef __OpenBSD__ + if (pledge("stdio rpath proc exec", NULL) == -1) + die("pledge"); +#endif /* __OpenBSD__ */ + scan(); + run(); + cleanup(); + XCloseDisplay(dpy); + return EXIT_SUCCESS; +} diff --git a/dwm/dwm.o b/dwm/dwm.o new file mode 100644 index 0000000000000000000000000000000000000000..aad6c019897908b812d6b64ae702af00a68da1d1 GIT binary patch literal 56992 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 literal 0 HcmV?d00001 diff --git a/dwm/dwm.png b/dwm/dwm.png new file mode 100644 index 0000000000000000000000000000000000000000..b1f9ba7e5f4cc7350ee2392ebcea5fcbe00fb49b GIT binary patch literal 373 zcmeAS@N?(olHy`uVBq!ia0y~yU^u|Qz!1Q}1Y+HIE6l*az?S6g?!xdN1Q+aGKAC}m zfwRCPvY3H^TNs2H8D`CqU|?WiFY)wsWxvKQ%wx!QPg+ZWfq_A`#5JPCIX^cyHLrxh zxhOTUBsE2$JhLQ2AtWPJ!QIn0;C+f}9s>izO-~ockcwMx?>cfd81OJSD*yX``Xg^6 zTaZz4SYYHW?+Yi+q)+P5khOpNZ+qolCYF{40Rbi^MnwgdmIen04h}{|1pxsjCkGA= zh?J9q0!T_g04&AA!nDZw&Oe5$@0m;M>sM6OY71;LKv54jO6E(b|BHY2*SA&9y8V3S z8iyN)!0OOUb8_ejn#VrNZ2je0``gbZufgI1u!%>m)^#5eUAZ~`sxkuu1B0ilpUXO@ GgeCxv)opSB literal 0 HcmV?d00001 diff --git a/dwm/transient.c b/dwm/transient.c new file mode 100644 index 0000000..040adb5 --- /dev/null +++ b/dwm/transient.c @@ -0,0 +1,42 @@ +/* cc transient.c -o transient -lX11 */ + +#include <stdlib.h> +#include <unistd.h> +#include <X11/Xlib.h> +#include <X11/Xutil.h> + +int main(void) { + Display *d; + Window r, f, t = None; + XSizeHints h; + XEvent e; + + d = XOpenDisplay(NULL); + if (!d) + exit(1); + r = DefaultRootWindow(d); + + f = XCreateSimpleWindow(d, r, 100, 100, 400, 400, 0, 0, 0); + h.min_width = h.max_width = h.min_height = h.max_height = 400; + h.flags = PMinSize | PMaxSize; + XSetWMNormalHints(d, f, &h); + XStoreName(d, f, "floating"); + XMapWindow(d, f); + + XSelectInput(d, f, ExposureMask); + while (1) { + XNextEvent(d, &e); + + if (t == None) { + sleep(5); + t = XCreateSimpleWindow(d, r, 50, 50, 100, 100, 0, 0, 0); + XSetTransientForHint(d, t, f); + XStoreName(d, t, "transient"); + XMapWindow(d, t); + XSelectInput(d, t, ExposureMask); + } + } + + XCloseDisplay(d); + exit(0); +} diff --git a/dwm/util.c b/dwm/util.c new file mode 100644 index 0000000..fe044fc --- /dev/null +++ b/dwm/util.c @@ -0,0 +1,35 @@ +/* See LICENSE file for copyright and license details. */ +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "util.h" + +void * +ecalloc(size_t nmemb, size_t size) +{ + void *p; + + if (!(p = calloc(nmemb, size))) + die("calloc:"); + return p; +} + +void +die(const char *fmt, ...) { + va_list ap; + + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + + if (fmt[0] && fmt[strlen(fmt)-1] == ':') { + fputc(' ', stderr); + perror(NULL); + } else { + fputc('\n', stderr); + } + + exit(1); +} diff --git a/dwm/util.h b/dwm/util.h new file mode 100644 index 0000000..f633b51 --- /dev/null +++ b/dwm/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/dwm/util.o b/dwm/util.o new file mode 100644 index 0000000000000000000000000000000000000000..c0e1b2e540a7db2dd2bbe25ad82a49373d5cbbfb GIT binary patch literal 2216 zcmb<-^>JfjWMqH=Mg}_u1P><4z@Wj3U^{@B4h(z@ybQq}oxeRA-#lPoVDRWHQL*so z3{i3L==4$X@ac3>3GnIkQHf|dP-4Ze>7tUruj!*wz^^$)rGbHgfnRfu$^<aIL}dY( zUZb)BOm9&+0H*h-Twq{eNb%@qQPlvO@1mk%c)+9E7G%Fi=RJ?!7L^ZB2?>wh5ETKB zUKbUE<1Q)!91IK$$6ZuJ44~2qFF<-4tQkDIO+l;@9goiYAO~}RB|N%IR5%)HnEzXq z3h!57U|;}?8vX}UuetVf!G!jM!UilF2qryR50vtF^nzUk7Kl2WoS2i7pKQgz;O^{f zrJ&*N7pkdXXsBnT2XYGo3j+fK$O2Gsy8DGPFflM50EvOj1v!in%I5@e7#J8tpfqDu z5Cda{0HZVyJI4e@1_lWR1_l|Z+)ohg$S2Uu<i+;^DrW%_V_;yA1ksLs0^xk1AOUf( zW03tU3?KhvlV!$|A|R%Le1WQimw|yn2uVHIZ43+yf(#4{0;o#CJdi)Ii7Vnz4@wBw z)a&6;4~lJU>aC#egt-qKP7DkT);P>zC@sm%(Mx8~^Kmv{NXblPC@x7!Eh=ItODibK z%qvM_C@v|=NzG$OD<~~VW++H4D#|ZnNUg{$VMv7}2(WJ%7)qfu69WSSDD?jPhk%t( zaZp-dV_;x_iEoCAqpLpz6$hzjM^b+SNgNbMFmvuBiG$J>O#C&HII{Y$NaCQ>4^#ge zNt_4CUUpCdVqjnZxsw@5oChinawiDG%mL*AkWnD@APi!IunmZSngbGt#SepCab<2v zViJR1aY+$`&VaFsQgagZN>VFI81zySOA;CMl8TEN^osI99FTHDJwpb)<ow*+)VvY~ zy}bOAR6TdUP~GB^#N=!!KRvHhub?QuAhoEZl0gq_U}{EuT2W$dD%3#~QXv0=f&vt` z$VNfRQU(SgkR*}>8ka$ufdO20z|_N(7Jveqfq{Vos)3t<0i63laS2ib%3mN_4Jr;* z4iW<6AgDet2Z=xz)&beUz`#JRenY7JMo4ymm@xZc?gfc~FwA}!4e~dL4K74M3ZOU& zB*?(PAPnWhD5x+vEI?wOQ2Rk_WSk3Ah%AUjZ6pH&11O(?(j>Cd0;qm;ccJ^I5Nam6 z{smC|0mz0z!x~vA2S@x@fHD;W0|U%{Q2c}PH_U!m{DZ7Pw;N<WsJ;Nv79a%-3=E(= w4Kfm4Kgdk<xCiOefC@T+I7k?399#rc{zH|*#XyV|Aj=pS7^*=WB#f>f031mQZ~y=R literal 0 HcmV?d00001 -- GitLab