diff -Nru xsnow-3.1.1/addcopyright.sh xsnow-3.3.2/addcopyright.sh --- xsnow-3.1.1/addcopyright.sh 2020-10-13 12:50:56.000000000 +0000 +++ xsnow-3.3.2/addcopyright.sh 2021-11-04 14:24:27.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by @@ -23,7 +23,7 @@ xsnow: let it snow on your desktop Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen - 2019,2020 Willem Vermin + 2019,2020,2021 Willem Vermin This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -57,7 +57,7 @@ # Notice that sed requires a newline after the filename of the 'r' command sed -i "/^\s*#-#/d" "$f" sed -i "/$txt/{r $crfile - :a;n;ba}" "$f" +:a;n;ba;}" "$f" n=`expr $n + 1` done echo "$n files copyrighted" diff -Nru xsnow-3.1.1/bootstrap xsnow-3.3.2/bootstrap --- xsnow-3.1.1/bootstrap 2020-10-13 12:50:56.000000000 +0000 +++ xsnow-3.3.2/bootstrap 2021-11-04 14:24:27.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by @@ -28,49 +28,18 @@ echo "-" >> make.inc echo "EXTRA_DIST = \\" >> make.inc echo "make.inc \\" >> make.inc -ls *.xpm *.xbm *.svg *.jpg *.png | sed 's/$/ \\/' | sed '$s/\\//' >> make.inc +ls *.xpm *.xbm *.svg | sed 's/$/ \\/' | sed '$s/\\//' >> make.inc ) -./addcopyright.sh Makefile.am addcopyright.sh bootstrap configure.ac getversion README +./addcopyright.sh Makefile.am addcopyright.sh bootstrap configure.ac README simplemake.sh find src \( -name '*.c' -o -name '*.h' -o -name '*.am' -o -name '*.xpm' -o -name '*.xbm' \ -o -name '*.xml' -o -name '*.sh' -o -name '*.cpp' -o -name '*.inc' \) -print0 | xargs -0 ./addcopyright.sh -version=`./getversion` || exit 1 -date=`date -R` -echo "version = $version" -sed -i "/^AC_INIT(\[xsnow]/s/^.*/AC_INIT([xsnow], [$version], [wvermin@gmail.com])/" configure.ac || exit 1 - -# take care that debian*/changelog is ok: contains changelog from -# previous debian version and a first lines like: -# xsnow (1:2.0.9-1) unstable; urgency=low -# -# * New upstream release -# -# -- Willem Vermin Fri, 19 Jul 2019 14:59:21 +0200 -# -# the 'xsnow' line and the -- Willem line will be adapted to the -# new version and date automatically - -cd $curdir/../xsnow-debian || exit 1 -for d in debian debian.eoan debian.focal debian.stretch debian.sid debian.tara ; do - if [ -e $d/changelog ] ; then - sed -i "1s/(.*)/(1:$version-1)/" $d/changelog || exit 1 - sed -i "0,/^ --.*>/{/^ --.*>/s/> .*/> $date/}" $d/changelog || exit 1 - fi -done - -cp debian.sid/* debian - cd $curdir -mkdir -p debian/tests -for t in src/test1.sh ; do - cp $t debian/tests -done - - autoreconf -fvi || exit 1 +cd "$curdir" echo "## Do not modify this file, it is generated from README by bootstrap ##">README.md cat README >> README.md echo "$0 done" diff -Nru xsnow-3.1.1/ChangeLog xsnow-3.3.2/ChangeLog --- xsnow-3.1.1/ChangeLog 2020-10-08 13:45:04.000000000 +0000 +++ xsnow-3.3.2/ChangeLog 2021-11-03 14:31:43.000000000 +0000 @@ -1,3 +1,166 @@ +version 3.3.2 + remove redundand files maketar, makectags +version 3.3.1 + 1:fix issues with LXDE desktop and xscreensaver +version 3.3.0 + 1:replace transparent.{c,h} with maketrans.{c,h} + add overall scale factor + all drawings using cairo + use xdbe (double buffer) when not using cairo + moon and birds also when painting on root window + 45: doit.h:default followsanta = 0 + windows.c: do not snow on window with exactly width=SnowWinWidth, x=0, y<100 + 47: sanitize scenery.c with respect to color of the vintage tree + +version 3.2.3 + 1:minor adaption in simplemake.sh + :make use of VERSION in config.h + adapt simplemake.sh + 6:ixpm.c: correct stupid bug in xpm_set_color() + 7:remove UNUSED + 9:extended range of XSelectInput somewhat + change timing of do_wupdate to look more frequently if + something has changed + +version 3.2.2 + 1:change 'changes' into Flags.Changes + 2:change gdkwindow -> NULL, several files + ui.c: better behaviour of 'below windows' - 'confirm to click' + combo + 3:flags.c flags.h: separate FLAGS for default and vintage + docs.c: some minor additions + 4:buttons.h: change togglecode into scalecode + flags.h uitils.h: transport some macro's + ui.c: add documention about flags and buttons + main.c: optionally move windows to 0,0 (movewindow()) + Flags.MoveWindow --movewindow + 5:some tweaks MoveWindow + 6:more tweaks for MoveWindow + Use also XConfigureWindow to set below or above. Now behaviour is + OK when running in FVWM + xcompmgr or compton + transparent.c: fixed 'show desktop' issue by re-adding: + gdk_window_set_type_hint(gdk_window,GDK_WINDOW_TYPE_HINT_DOCK); + wmctrl.c: add check for _NET_SHOWING_DESKTOP for visibility of + windows + windows.c: keep SnowWin below if Flags.BelowAll. Needed when SnowWin + is not click-through. + 7:add -theme flag. No button: too complicated for me. + 9:make theme chooseable with a button + 11:ui.c: minor tweaks + +version 3.2.1 + 1:utils.h: add fflush(NULL) to UIDO and UIDOS + moon.c: create halo surface for painting. + 2:fine tuning of ui graphics + 3:start simplifying ui.c + 11:finished 3: + 12:doit.h flags.h: change DOIT macro's + 13:docs.c:make it better + 14:add option -hidemenu, add this to xsnow.desktop + better format noisy output + use #include "undefall.inc" to undef frquently used macros + 15:simplify glade-id's + 16:stratify ui.c code + 17:stratify ui.c code + 18:stratify ui.c code + +version 3.2.0 + 1:use 256x256 xpm for moon + start Santa, aware of moon position + adapt some trivial texts + 2:add halo around moon + add show-stars button + add grey-out for moon buttons if not compositing manager + add notice about that in the celestials tab + 3:fix bug in moon.c: show moon, independent of birds + some experiments with halo colours + 4:moon.c: fix memory leak: halo_draw() + docs.c: adapt man page + ui.c: better way to grey out moon buttons + configure.ac: remove test for alloca, and tell kdtree.c not to use + alloca + 6:ui.c: remove malicious assert from report_tree_type() + utils.h: create macros UIDO and UIDOS to better deal with + if(Flags.x != OldFlags.x) .... + many functions: replace construct above with UIDO or UIDOS + 7:Ack in man page for picture of moon. + +version 3.1.10 + 1:add moon and show-noshow for moon + 2:put wind, stars, moon, meteorites in celestials + add slider for moon speed + 3:add button for moon size + 4:let Santa like to hover the moon + +version 3.1.9 + 1:place 'Xsnow running' to a place wher this does not appear in + xsnow -h or xsnow-H + 2:wmctrl.c: a second check if window is hidden, based on WM_STATE + see: https://tronche.com/gui/x/icccm/sec-4.html#s-4.1.3.1 + 3: typos in docs.c + 5:wmctrl.c: use XQueryTree to find windows to snow on if + _NET and _GTK are not available. + Use also XGetWindowAttributes to determine if a window + is visible. + 6:change max number of scenery items to 60 + wmctrl.c: use XGetWindowAttributes in stead of XGetGeometry + +version 3.1.8 + 1:use config.h to determine if alloca.h should be included + configure.ac, Makefile.am: use pkg-config to locate + X11, Xpm, xt, xproto + 2:configure.ac: remove tests for libraries, relying on pkg-config now + 3:remove uses of alloca, except ik kdtree.c + define USE_LIST_NODE_ALLOCATOR and NO_ALLOCA in kdtree.c + remove USE_LIST_NODE_ALLOCATOR from Makefile.am + snow.c: free local variables in genxpmflake() + +version 3.1.7 + 1:windows.c: take care of redfining Rootwindow if xscreensaver + is detected +version 3.1.6 + 1:add xscreensaver support and vroot.h +version 3.1.5 + 1:remove .png and .jpg from bootstrap and src/Pixmaps/ from tar.gz + 2:main.c drawit(): draw stars and meteorites behind birds + 3:fallensnow.c: GenerateFlakesFromFallen(): reduce the amount of + generated snow + Changed info text by 'Blow off' slider. + 4:src/Makefile.am: separate scripts for generating ui_xml.h and + snow_includes.h + Create script 'simplemake.sh', to be used on systems where the + './configure;make;make install' suite does not work. +version 3.1.4 + 1:remove AC_FUNC_MALLOC AC_FUNC_REALLOC AC_FUNC_ALLOCA from + configure.ac (see comment there) + Checked all malloc's, alloca's and realloc's for allocating >0 bytes +version 3.1.3 + 1:add flag -showrudolph + add flag -blowsnow + remove FullScreen from .xsnowrc + add flag -usebg + add flag -snow + add flag -nosnow + add flag -showtrees + add flag -wind + add flag -keepsnowonwindows + add flag -keepsnowonscreen + add flag -keepsnowontrees + add flag -keepsnow + add flag -fluffy + add flag -meteorites + stratified version.h + moved PrintVersion to utils.c +version 3.1.2 + 1:hashtable.cpp: do not use 'auto' + docs.c: added note about no menu when files are present in + $HOME/xsnow/pixmaps + Check on version of GTK. If too low, give option to start + without ui. + 2:simplify code for running without menu if level of GTK is too low + 3:stratify above mentioned code +version 3.1.1 + moved debian stuff out of the distribution version 3.1.0 1:change version number some trivia in transparent.c diff -Nru xsnow-3.1.1/config.h.in xsnow-3.3.2/config.h.in --- xsnow-3.1.1/config.h.in 2020-10-13 14:45:46.000000000 +0000 +++ xsnow-3.3.2/config.h.in 2021-11-04 14:24:33.000000000 +0000 @@ -1,29 +1,20 @@ /* config.h.in. Generated from configure.ac by autoheader. */ -/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP - systems. This function is required for `alloca.c' support on those systems. - */ -#undef CRAY_STACKSEG_END - -/* Define to 1 if using `alloca.c'. */ -#undef C_ALLOCA - /* Define to 1 if you have the `alarm' function. */ #undef HAVE_ALARM -/* Define to 1 if you have `alloca', as a function or macro. */ -#undef HAVE_ALLOCA - -/* Define to 1 if you have and it should be used (not on Ultrix). - */ -#undef HAVE_ALLOCA_H - /* Define to 1 if you have the header file. */ #undef HAVE_ASSERT_H +/* Define to 1 if you have the `backtrace' function. */ +#undef HAVE_BACKTRACE + /* Define to 1 if you have the header file. */ #undef HAVE_CTYPE_H +/* Define to 1 if you have the header file. */ +#undef HAVE_EXECINFO_H + /* Define to 1 if you have the `gettimeofday' function. */ #undef HAVE_GETTIMEOFDAY @@ -33,19 +24,6 @@ /* Define to 1 if you have the header file. */ #undef HAVE_IOSTREAM -/* Define to 1 if you have the `m' library (-lm). */ -#undef HAVE_LIBM - -/* Define to 1 if you have the `X11' library (-lX11). */ -#undef HAVE_LIBX11 - -/* Define to 1 if you have the `Xpm' library (-lXpm). */ -#undef HAVE_LIBXPM - -/* Define to 1 if your system has a GNU libc compatible `malloc' function, and - to 0 otherwise. */ -#undef HAVE_MALLOC - /* Define to 1 if you have the header file. */ #undef HAVE_MATH_H @@ -55,10 +33,6 @@ /* Define to 1 if you have the header file. */ #undef HAVE_PTHREAD_H -/* Define to 1 if your system has a GNU libc compatible `realloc' function, - and to 0 otherwise. */ -#undef HAVE_REALLOC - /* Define to 1 if you have the header file. */ #undef HAVE_SIGNAL_H @@ -110,26 +84,8 @@ /* Define to 1 if you have the header file. */ #undef HAVE_UNORDERED_SET -/* Define to 1 if you have the header file. */ -#undef HAVE_X11_CURSORFONT_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_X11_INTRINSIC_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_X11_XATOM_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_X11_XLIB_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_X11_XOS_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_X11_XPM_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_X11_XUTIL_H +/* Define to 1 if you have the `XdbeAllocateBackBufferName' function. */ +#undef HAVE_XDBEALLOCATEBACKBUFFERNAME /* Define to 1 if the system has the type `_Bool'. */ #undef HAVE__BOOL @@ -155,25 +111,11 @@ /* Define to the version of this package. */ #undef PACKAGE_VERSION -/* If using the C implementation of alloca, define if you know the - direction of stack growth for your system; otherwise it will be - automatically deduced at runtime. - STACK_DIRECTION > 0 => grows toward higher addresses - STACK_DIRECTION < 0 => grows toward lower addresses - STACK_DIRECTION = 0 => direction of growth unknown */ -#undef STACK_DIRECTION - /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS /* Version number of package */ #undef VERSION -/* Define to rpl_malloc if the replacement function should be used. */ -#undef malloc - -/* Define to rpl_realloc if the replacement function should be used. */ -#undef realloc - /* Define to `unsigned int' if does not define. */ #undef size_t diff -Nru xsnow-3.1.1/configure xsnow-3.3.2/configure --- xsnow-3.1.1/configure 2020-10-13 14:45:46.000000000 +0000 +++ xsnow-3.3.2/configure 2021-11-04 14:24:33.000000000 +0000 @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for xsnow 3.1.1. +# Generated by GNU Autoconf 2.69 for xsnow 3.3.2. # # Report bugs to . # @@ -580,8 +580,8 @@ # Identity of this package. PACKAGE_NAME='xsnow' PACKAGE_TARNAME='xsnow' -PACKAGE_VERSION='3.1.1' -PACKAGE_STRING='xsnow 3.1.1' +PACKAGE_VERSION='3.3.2' +PACKAGE_STRING='xsnow 3.3.2' PACKAGE_BUGREPORT='wvermin@gmail.com' PACKAGE_URL='' @@ -625,8 +625,9 @@ ac_subst_vars='am__EXEEXT_FALSE am__EXEEXT_TRUE LTLIBOBJS -ALLOCA LIBOBJS +X11_LIBS +X11_CFLAGS GTK_LIBS GTK_CFLAGS XML_LIBS @@ -755,7 +756,9 @@ XML_CFLAGS XML_LIBS GTK_CFLAGS -GTK_LIBS' +GTK_LIBS +X11_CFLAGS +X11_LIBS' # Initialize some variables set by options. @@ -1306,7 +1309,7 @@ # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures xsnow 3.1.1 to adapt to many kinds of systems. +\`configure' configures xsnow 3.3.2 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1377,7 +1380,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of xsnow 3.1.1:";; + short | recursive ) echo "Configuration of xsnow 3.3.2:";; esac cat <<\_ACEOF @@ -1419,6 +1422,8 @@ XML_LIBS linker flags for XML, overriding pkg-config GTK_CFLAGS C compiler flags for GTK, overriding pkg-config GTK_LIBS linker flags for GTK, overriding pkg-config + X11_CFLAGS C compiler flags for X11, overriding pkg-config + X11_LIBS linker flags for X11, overriding pkg-config Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. @@ -1486,7 +1491,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -xsnow configure 3.1.1 +xsnow configure 3.3.2 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -1576,21 +1581,20 @@ } # ac_fn_cxx_try_compile -# ac_fn_c_try_link LINENO -# ----------------------- -# Try to link conftest.$ac_ext, and return whether this succeeded. -ac_fn_c_try_link () +# ac_fn_c_try_cpp LINENO +# ---------------------- +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - rm -f conftest.$ac_objext conftest$ac_exeext - if { { ac_try="$ac_link" + if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>conftest.err + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 @@ -1598,44 +1602,37 @@ mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { - test -z "$ac_c_werror_flag" || + test $ac_status = 0; } > conftest.i && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err - } && test -s conftest$ac_exeext && { - test "$cross_compiling" = yes || - test -x conftest$ac_exeext }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 - ac_retval=1 + ac_retval=1 fi - # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information - # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would - # interfere with the next link command; also delete a directory that is - # left behind by Apple's compiler. We do this before executing the actions. - rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval -} # ac_fn_c_try_link +} # ac_fn_c_try_cpp -# ac_fn_c_try_cpp LINENO -# ---------------------- -# Try to preprocess conftest.$ac_ext, and return whether this succeeded. -ac_fn_c_try_cpp () +# ac_fn_c_try_link LINENO +# ----------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if { { ac_try="$ac_cpp conftest.$ac_ext" + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 - (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 @@ -1643,21 +1640,29 @@ mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } > conftest.i && { - test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + test -x conftest$ac_exeext }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 - ac_retval=1 + ac_retval=1 fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval -} # ac_fn_c_try_cpp +} # ac_fn_c_try_link # ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES # ------------------------------------------------------- @@ -1951,60 +1956,6 @@ } # ac_fn_cxx_check_header_mongrel -# ac_fn_c_check_type LINENO TYPE VAR INCLUDES -# ------------------------------------------- -# Tests whether TYPE exists after having included INCLUDES, setting cache -# variable VAR accordingly. -ac_fn_c_check_type () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -else - eval "$3=no" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -int -main () -{ -if (sizeof ($2)) - return 0; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -int -main () -{ -if (sizeof (($2))) - return 0; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - -else - eval "$3=yes" -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - -} # ac_fn_c_check_type - # ac_fn_c_check_func LINENO FUNC VAR # ---------------------------------- # Tests whether FUNC exists, setting the cache variable VAR accordingly @@ -2071,11 +2022,65 @@ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_func + +# ac_fn_c_check_type LINENO TYPE VAR INCLUDES +# ------------------------------------------- +# Tests whether TYPE exists after having included INCLUDES, setting cache +# variable VAR accordingly. +ac_fn_c_check_type () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=no" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +if (sizeof ($2)) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +if (sizeof (($2))) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + eval "$3=yes" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_type cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by xsnow $as_me 3.1.1, which was +It was created by xsnow $as_me 3.3.2, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -2941,7 +2946,7 @@ # Define the identity of the package. PACKAGE='xsnow' - VERSION='3.1.1' + VERSION='3.3.2' cat >>confdefs.h <<_ACEOF @@ -3082,8 +3087,10 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. -set dummy ${ac_tool_prefix}gcc; ac_word=$2 + for ac_prog in cc gcc + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : @@ -3099,7 +3106,7 @@ test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="${ac_tool_prefix}gcc" + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi @@ -3119,11 +3126,15 @@ fi + test -n "$CC" && break + done fi -if test -z "$ac_cv_prog_CC"; then +if test -z "$CC"; then ac_ct_CC=$CC - # Extract the first word of "gcc", so it can be a program name with args. -set dummy gcc; ac_word=$2 + for ac_prog in cc gcc +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : @@ -3139,7 +3150,7 @@ test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_CC="gcc" + ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi @@ -3158,6 +3169,10 @@ $as_echo "no" >&6; } fi + + test -n "$ac_ct_CC" && break +done + if test "x$ac_ct_CC" = x; then CC="" else @@ -3169,247 +3184,45 @@ esac CC=$ac_ct_CC fi -else - CC="$ac_cv_prog_CC" fi -if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. -set dummy ${ac_tool_prefix}cc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="${ac_tool_prefix}cc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 + +test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "no acceptable C compiler found in \$PATH +See \`config.log' for more details" "$LINENO" 5; } + +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } done - done -IFS=$as_save_IFS -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ - - fi -fi -if test -z "$CC"; then - # Extract the first word of "cc", so it can be a program name with args. -set dummy cc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else - ac_prog_rejected=no -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then - ac_prog_rejected=yes - continue - fi - ac_cv_prog_CC="cc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -if test $ac_prog_rejected = yes; then - # We found a bogon in the path, so make sure we never use it. - set dummy $ac_cv_prog_CC - shift - if test $# != 0; then - # We chose a different compiler from the bogus one. - # However, it has the same basename, so the bogon will be chosen - # first if we set CC to just the basename; use the full file name. - shift - ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" - fi -fi -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - for ac_prog in cl.exe - do - # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. -set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="$ac_tool_prefix$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$CC" && break - done -fi -if test -z "$CC"; then - ac_ct_CC=$CC - for ac_prog in cl.exe -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_CC="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 -$as_echo "$ac_ct_CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$ac_ct_CC" && break -done - - if test "x$ac_ct_CC" = x; then - CC="" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - CC=$ac_ct_CC - fi -fi - -fi - - -test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "no acceptable C compiler found in \$PATH -See \`config.log' for more details" "$LINENO" 5; } - -# Provide some information about the compiler. -$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 -set X $ac_compile -ac_compiler=$2 -for ac_option in --version -v -V -qversion; do - { { ac_try="$ac_compiler $ac_option >&5" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_compiler $ac_option >&5") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - sed '10a\ -... rest of stderr output deleted ... - 10q' conftest.err >conftest.er1 - cat conftest.er1 >&5 - fi - rm -f conftest.er1 conftest.err - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } -done - -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ +int +main () +{ ; return 0; @@ -4125,7 +3938,7 @@ CXX=$CCC else if test -n "$ac_tool_prefix"; then - for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC + for ac_prog in c++ g++ do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 @@ -4169,7 +3982,7 @@ fi if test -z "$CXX"; then ac_ct_CXX=$CXX - for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC + for ac_prog in c++ g++ do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 @@ -4502,226 +4315,78 @@ -# Checks for libraries. - +LIBS="-lm" +# Checks for header files. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for XOpenDisplay in -lX11" >&5 -$as_echo_n "checking for XOpenDisplay in -lX11... " >&6; } -if ${ac_cv_lib_X11_XOpenDisplay+:} false; then : +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 +$as_echo_n "checking how to run the C preprocessor... " >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if ${ac_cv_prog_CPP+:} false; then : $as_echo_n "(cached) " >&6 else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lX11 $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" +#ifdef __STDC__ +# include +#else +# include #endif -char XOpenDisplay (); -int -main () -{ -return XOpenDisplay (); - ; - return 0; -} + Syntax error _ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_X11_XOpenDisplay=yes +if ac_fn_c_try_cpp "$LINENO"; then : + else - ac_cv_lib_X11_XOpenDisplay=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS + # Broken: fails on valid input. +continue fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_X11_XOpenDisplay" >&5 -$as_echo "$ac_cv_lib_X11_XOpenDisplay" >&6; } -if test "x$ac_cv_lib_X11_XOpenDisplay" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBX11 1 -_ACEOF - - LIBS="-lX11 $LIBS" +rm -f conftest.err conftest.i conftest.$ac_ext + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext - echo "libX11 is required" - exit -1 +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for XpmCreatePixmapFromData in -lXpm" >&5 -$as_echo_n "checking for XpmCreatePixmapFromData in -lXpm... " >&6; } -if ${ac_cv_lib_Xpm_XpmCreatePixmapFromData+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lXpm $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char XpmCreatePixmapFromData (); -int -main () -{ -return XpmCreatePixmapFromData (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_Xpm_XpmCreatePixmapFromData=yes -else - ac_cv_lib_Xpm_XpmCreatePixmapFromData=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_Xpm_XpmCreatePixmapFromData" >&5 -$as_echo "$ac_cv_lib_Xpm_XpmCreatePixmapFromData" >&6; } -if test "x$ac_cv_lib_Xpm_XpmCreatePixmapFromData" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBXPM 1 -_ACEOF - - LIBS="-lXpm $LIBS" - -else - as_fn_error $? "Exiting" "$LINENO" 5 -fi - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sin in -lm" >&5 -$as_echo_n "checking for sin in -lm... " >&6; } -if ${ac_cv_lib_m_sin+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lm $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char sin (); -int -main () -{ -return sin (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_m_sin=yes -else - ac_cv_lib_m_sin=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_sin" >&5 -$as_echo "$ac_cv_lib_m_sin" >&6; } -if test "x$ac_cv_lib_m_sin" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBM 1 -_ACEOF - - LIBS="-lm $LIBS" - -else - - echo "libm is required" - exit -1 -fi - - -# Checks for header files. -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 -$as_echo_n "checking how to run the C preprocessor... " >&6; } -# On Suns, sometimes $CPP names a directory. -if test -n "$CPP" && test -d "$CPP"; then - CPP= -fi -if test -z "$CPP"; then - if ${ac_cv_prog_CPP+:} false; then : - $as_echo_n "(cached) " >&6 -else - # Double quotes because CPP needs to be expanded - for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" - do - ac_preproc_ok=false -for ac_c_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # Prefer to if __STDC__ is defined, since - # exists even on freestanding compilers. - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. "Syntax error" is here to catch this case. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#ifdef __STDC__ -# include -#else -# include -#endif - Syntax error -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - -else - # Broken: fails on valid input. -continue -fi -rm -f conftest.err conftest.i conftest.$ac_ext - - # OK, works on sane cases. Now check whether nonexistent headers - # can be detected and how. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - # Broken: success on invalid input. -continue -else - # Passes both tests. -ac_preproc_ok=: -break -fi -rm -f conftest.err conftest.i conftest.$ac_ext - -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.i conftest.err conftest.$ac_ext -if $ac_preproc_ok; then : - break -fi - - done - ac_cv_prog_CPP=$CPP + done + ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP @@ -5243,18 +4908,6 @@ done -for ac_header in alloca.h -do : - ac_fn_c_check_header_mongrel "$LINENO" "alloca.h" "ac_cv_header_alloca_h" "$ac_includes_default" -if test "x$ac_cv_header_alloca_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_ALLOCA_H 1 -_ACEOF - -fi - -done - for ac_header in assert.h ctype.h math.h pthread.h signal.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` @@ -5270,7 +4923,7 @@ done -for ac_header in stdarg.h stdio.h stdlib.h string.h unistd.h X11/cursorfont.h X11/Intrinsic.h +for ac_header in stdarg.h stdio.h stdlib.h string.h unistd.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" @@ -5285,17 +4938,14 @@ done -for ac_header in X11/Xatom.h X11/Xlib.h X11/Xos.h X11/xpm.h X11/Xutil.h +for ac_header in execinfo.h do : - as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` -ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" -if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + ac_fn_c_check_header_mongrel "$LINENO" "execinfo.h" "ac_cv_header_execinfo_h" "$ac_includes_default" +if test "x$ac_cv_header_execinfo_h" = xyes; then : cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +#define HAVE_EXECINFO_H 1 _ACEOF -else - as_fn_error $? "Exiting" "$LINENO" 5 fi done @@ -5790,6 +5440,122 @@ fi +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for X11" >&5 +$as_echo_n "checking for X11... " >&6; } + +if test -n "$X11_CFLAGS"; then + pkg_cv_X11_CFLAGS="$X11_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"x11 xpm xt xext xproto\""; } >&5 + ($PKG_CONFIG --exists --print-errors "x11 xpm xt xext xproto") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_X11_CFLAGS=`$PKG_CONFIG --cflags "x11 xpm xt xext xproto" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$X11_LIBS"; then + pkg_cv_X11_LIBS="$X11_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"x11 xpm xt xext xproto\""; } >&5 + ($PKG_CONFIG --exists --print-errors "x11 xpm xt xext xproto") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_X11_LIBS=`$PKG_CONFIG --libs "x11 xpm xt xext xproto" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + X11_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "x11 xpm xt xext xproto" 2>&1` + else + X11_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "x11 xpm xt xext xproto" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$X11_PKG_ERRORS" >&5 + + as_fn_error $? "Package requirements (x11 xpm xt xext xproto) were not met: + +$X11_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +Alternatively, you may set the environment variables X11_CFLAGS +and X11_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details." "$LINENO" 5 +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +Alternatively, you may set the environment variables X11_CFLAGS +and X11_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details. + +To get pkg-config, see . +See \`config.log' for more details" "$LINENO" 5; } +else + X11_CFLAGS=$pkg_cv_X11_CFLAGS + X11_LIBS=$pkg_cv_X11_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +fi + +for ac_func in backtrace +do : + ac_fn_c_check_func "$LINENO" "backtrace" "ac_cv_func_backtrace" +if test "x$ac_cv_func_backtrace" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_BACKTRACE 1 +_ACEOF + +fi +done + +LIBS="$X11_LIBS" +# check for availability of double buffering +for ac_func in XdbeAllocateBackBufferName +do : + ac_fn_c_check_func "$LINENO" "XdbeAllocateBackBufferName" "ac_cv_func_XdbeAllocateBackBufferName" +if test "x$ac_cv_func_XdbeAllocateBackBufferName" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_XDBEALLOCATEBACKBUFFERNAME 1 +_ACEOF + +fi +done + + # Checks for typedefs, structures, and compiler characteristics. ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" if test "x$ac_cv_type_size_t" = xyes; then : @@ -5891,326 +5657,12 @@ # Checks for library functions. -for ac_header in stdlib.h -do : - ac_fn_c_check_header_mongrel "$LINENO" "stdlib.h" "ac_cv_header_stdlib_h" "$ac_includes_default" -if test "x$ac_cv_header_stdlib_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_STDLIB_H 1 -_ACEOF - -fi - -done - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU libc compatible malloc" >&5 -$as_echo_n "checking for GNU libc compatible malloc... " >&6; } -if ${ac_cv_func_malloc_0_nonnull+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test "$cross_compiling" = yes; then : - ac_cv_func_malloc_0_nonnull=no -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#if defined STDC_HEADERS || defined HAVE_STDLIB_H -# include -#else -char *malloc (); -#endif - -int -main () -{ -return ! malloc (0); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_run "$LINENO"; then : - ac_cv_func_malloc_0_nonnull=yes -else - ac_cv_func_malloc_0_nonnull=no -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_malloc_0_nonnull" >&5 -$as_echo "$ac_cv_func_malloc_0_nonnull" >&6; } -if test $ac_cv_func_malloc_0_nonnull = yes; then : - -$as_echo "#define HAVE_MALLOC 1" >>confdefs.h - -else - $as_echo "#define HAVE_MALLOC 0" >>confdefs.h - - case " $LIBOBJS " in - *" malloc.$ac_objext "* ) ;; - *) LIBOBJS="$LIBOBJS malloc.$ac_objext" - ;; -esac - - -$as_echo "#define malloc rpl_malloc" >>confdefs.h - -fi - - -for ac_header in stdlib.h -do : - ac_fn_c_check_header_mongrel "$LINENO" "stdlib.h" "ac_cv_header_stdlib_h" "$ac_includes_default" -if test "x$ac_cv_header_stdlib_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_STDLIB_H 1 -_ACEOF - -fi - -done - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU libc compatible realloc" >&5 -$as_echo_n "checking for GNU libc compatible realloc... " >&6; } -if ${ac_cv_func_realloc_0_nonnull+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test "$cross_compiling" = yes; then : - ac_cv_func_realloc_0_nonnull=no -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#if defined STDC_HEADERS || defined HAVE_STDLIB_H -# include -#else -char *realloc (); -#endif - -int -main () -{ -return ! realloc (0, 0); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_run "$LINENO"; then : - ac_cv_func_realloc_0_nonnull=yes -else - ac_cv_func_realloc_0_nonnull=no -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_realloc_0_nonnull" >&5 -$as_echo "$ac_cv_func_realloc_0_nonnull" >&6; } -if test $ac_cv_func_realloc_0_nonnull = yes; then : - -$as_echo "#define HAVE_REALLOC 1" >>confdefs.h - -else - $as_echo "#define HAVE_REALLOC 0" >>confdefs.h - - case " $LIBOBJS " in - *" realloc.$ac_objext "* ) ;; - *) LIBOBJS="$LIBOBJS realloc.$ac_objext" - ;; -esac - - -$as_echo "#define realloc rpl_realloc" >>confdefs.h - -fi - - -# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works -# for constant arguments. Useless! -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working alloca.h" >&5 -$as_echo_n "checking for working alloca.h... " >&6; } -if ${ac_cv_working_alloca_h+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -int -main () -{ -char *p = (char *) alloca (2 * sizeof (int)); - if (p) return 0; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_working_alloca_h=yes -else - ac_cv_working_alloca_h=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_working_alloca_h" >&5 -$as_echo "$ac_cv_working_alloca_h" >&6; } -if test $ac_cv_working_alloca_h = yes; then - -$as_echo "#define HAVE_ALLOCA_H 1" >>confdefs.h - -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for alloca" >&5 -$as_echo_n "checking for alloca... " >&6; } -if ${ac_cv_func_alloca_works+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#ifdef __GNUC__ -# define alloca __builtin_alloca -#else -# ifdef _MSC_VER -# include -# define alloca _alloca -# else -# ifdef HAVE_ALLOCA_H -# include -# else -# ifdef _AIX - #pragma alloca -# else -# ifndef alloca /* predefined by HP cc +Olibcalls */ -void *alloca (size_t); -# endif -# endif -# endif -# endif -#endif - -int -main () -{ -char *p = (char *) alloca (1); - if (p) return 0; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_func_alloca_works=yes -else - ac_cv_func_alloca_works=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_alloca_works" >&5 -$as_echo "$ac_cv_func_alloca_works" >&6; } - -if test $ac_cv_func_alloca_works = yes; then - -$as_echo "#define HAVE_ALLOCA 1" >>confdefs.h - -else - # The SVR3 libPW and SVR4 libucb both contain incompatible functions -# that cause trouble. Some versions do not even contain alloca or -# contain a buggy version. If you still want to use their alloca, -# use ar to extract alloca.o from them instead of compiling alloca.c. - -ALLOCA=\${LIBOBJDIR}alloca.$ac_objext - -$as_echo "#define C_ALLOCA 1" >>confdefs.h - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether \`alloca.c' needs Cray hooks" >&5 -$as_echo_n "checking whether \`alloca.c' needs Cray hooks... " >&6; } -if ${ac_cv_os_cray+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#if defined CRAY && ! defined CRAY2 -webecray -#else -wenotbecray -#endif - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "webecray" >/dev/null 2>&1; then : - ac_cv_os_cray=yes -else - ac_cv_os_cray=no -fi -rm -f conftest* - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_os_cray" >&5 -$as_echo "$ac_cv_os_cray" >&6; } -if test $ac_cv_os_cray = yes; then - for ac_func in _getb67 GETB67 getb67; do - as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` -ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" -if eval test \"x\$"$as_ac_var"\" = x"yes"; then : - -cat >>confdefs.h <<_ACEOF -#define CRAY_STACKSEG_END $ac_func -_ACEOF - - break -fi - - done -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking stack direction for C alloca" >&5 -$as_echo_n "checking stack direction for C alloca... " >&6; } -if ${ac_cv_c_stack_direction+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test "$cross_compiling" = yes; then : - ac_cv_c_stack_direction=0 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$ac_includes_default -int -find_stack_direction (int *addr, int depth) -{ - int dir, dummy = 0; - if (! addr) - addr = &dummy; - *addr = addr < &dummy ? 1 : addr == &dummy ? 0 : -1; - dir = depth ? find_stack_direction (addr, depth - 1) : 0; - return dir + dummy; -} - -int -main (int argc, char **argv) -{ - return find_stack_direction (0, argc + !argv + 20) < 0; -} -_ACEOF -if ac_fn_c_try_run "$LINENO"; then : - ac_cv_c_stack_direction=1 -else - ac_cv_c_stack_direction=-1 -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_stack_direction" >&5 -$as_echo "$ac_cv_c_stack_direction" >&6; } -cat >>confdefs.h <<_ACEOF -#define STACK_DIRECTION $ac_cv_c_stack_direction -_ACEOF - - -fi - +# check for AC_FUNC_MALLOC has detrimental effects on some systems +# symptom: undefined reference to rpl_malloc +# see also: https://github.com/maxmind/libmaxminddb/pull/152 +#AC_FUNC_MALLOC +#AC_FUNC_REALLOC +#AC_FUNC_ALLOCA for ac_func in alarm gettimeofday sqrt strchr strdup strstr strtol do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` @@ -6224,6 +5676,8 @@ done +LIBS="-lm" + ac_config_files="$ac_config_files Makefile src/Makefile src/Pixmaps/Makefile" @@ -6761,7 +6215,7 @@ # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by xsnow $as_me 3.1.1, which was +This file was extended by xsnow $as_me 3.3.2, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -6827,7 +6281,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -xsnow config.status 3.1.1 +xsnow config.status 3.3.2 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff -Nru xsnow-3.1.1/configure.ac xsnow-3.3.2/configure.ac --- xsnow-3.1.1/configure.ac 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/configure.ac 2021-11-04 14:24:27.000000000 +0000 @@ -5,7 +5,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by @@ -22,7 +22,7 @@ #-# AC_PREREQ([2.69]) -AC_INIT([xsnow], [3.1.1], [wvermin@gmail.com]) +AC_INIT([xsnow], [3.3.2], [wvermin@gmail.com]) AC_CONFIG_SRCDIR([src/xsnow.h]) AC_CONFIG_HEADERS([config.h]) AM_INIT_AUTOMAKE @@ -30,27 +30,16 @@ m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) # Checks for programs. -AC_PROG_CC -AC_PROG_CXX +AC_PROG_CC([cc gcc]) +AC_PROG_CXX([c++ g++]) AC_PROG_INSTALL -# Checks for libraries. - -AC_CHECK_LIB([X11], [XOpenDisplay], [],[ - echo "libX11 is required" - exit -1]) -AC_CHECK_LIB([Xpm], [XpmCreatePixmapFromData], [], AC_MSG_ERROR([Exiting])) - -AC_CHECK_LIB([m], [sin], [], [ - echo "libm is required" - exit -1]) - +LIBS="-lm" # Checks for header files. AC_PATH_X -AC_CHECK_HEADERS([alloca.h]) AC_CHECK_HEADERS([assert.h ctype.h math.h pthread.h signal.h],[],AC_MSG_ERROR([Exiting])) -AC_CHECK_HEADERS([stdarg.h stdio.h stdlib.h string.h unistd.h X11/cursorfont.h X11/Intrinsic.h],[],AC_MSG_ERROR([Exiting])) -AC_CHECK_HEADERS([X11/Xatom.h X11/Xlib.h X11/Xos.h X11/xpm.h X11/Xutil.h],[],AC_MSG_ERROR([Exiting])) +AC_CHECK_HEADERS([stdarg.h stdio.h stdlib.h string.h unistd.h],[],AC_MSG_ERROR([Exiting])) +AC_CHECK_HEADERS([execinfo.h]) AC_LANG_PUSH([C++]) AC_CHECK_HEADERS([iostream],[],AC_MSG_ERROR([Check your C++ compiler. Exiting])) @@ -60,17 +49,28 @@ PKG_CHECK_MODULES(XML, [libxml-2.0]) PKG_CHECK_MODULES(GTK, [gtk+-3.0 gmodule-2.0]) +PKG_CHECK_MODULES(X11, [x11 xpm xt xext xproto]) + +AC_CHECK_FUNCS([backtrace]) +LIBS="$X11_LIBS" +# check for availability of double buffering +AC_CHECK_FUNCS([XdbeAllocateBackBufferName]) # Checks for typedefs, structures, and compiler characteristics. AC_TYPE_SIZE_T AC_CHECK_HEADER_STDBOOL # Checks for library functions. -AC_FUNC_MALLOC -AC_FUNC_REALLOC -AC_FUNC_ALLOCA +# check for AC_FUNC_MALLOC has detrimental effects on some systems +# symptom: undefined reference to rpl_malloc +# see also: https://github.com/maxmind/libmaxminddb/pull/152 +#AC_FUNC_MALLOC +#AC_FUNC_REALLOC +#AC_FUNC_ALLOCA AC_CHECK_FUNCS([alarm gettimeofday sqrt strchr strdup strstr strtol]) +LIBS="-lm" + AC_CONFIG_FILES([Makefile src/Makefile] src/Pixmaps/Makefile) AC_OUTPUT diff -Nru xsnow-3.1.1/debian/changelog xsnow-3.3.2/debian/changelog --- xsnow-3.1.1/debian/changelog 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/debian/changelog 2021-11-04 14:47:37.000000000 +0000 @@ -1,3 +1,11 @@ +xsnow (1:3.3.2-1) unstable; urgency=low + + * New upstream release + * Changed Standards Version to 4.6.0.1 + * Added Bug-Submit in upstream/metadata + + -- Willem Vermin Thu, 04 Nov 2021 15:47:37 +0100 + xsnow (1:3.1.1-1) unstable; urgency=low * New upstream release diff -Nru xsnow-3.1.1/debian/control xsnow-3.3.2/debian/control --- xsnow-3.1.1/debian/control 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/debian/control 2021-11-04 14:47:37.000000000 +0000 @@ -1,12 +1,9 @@ Source: xsnow -Maintainer: Willem Vermin Section: games Priority: optional +Maintainer: Willem Vermin Build-Depends: debhelper (>= 13), libx11-dev, libxpm-dev, libxt-dev, pkg-config, libxml2-dev,libgtk-3-dev, debhelper-compat (=13) -Standards-Version: 4.5.0 -Homepage: https://www.ratrabbit.nl/ratrabbit/content/sw/xsnow/introduction -Vcs-Browser: https://sourceforge.net/p/xsnow/code/HEAD/tree -Rules-Requires-Root: no +Standards-Version: 4.6.0.1 Package: xsnow Architecture: any diff -Nru xsnow-3.1.1/debian/upstream/metadata xsnow-3.3.2/debian/upstream/metadata --- xsnow-3.1.1/debian/upstream/metadata 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/debian/upstream/metadata 2021-11-04 14:47:37.000000000 +0000 @@ -1,6 +1,7 @@ Repository: https://sourceforge.net/projects/xsnow/ Documentation: https://www.ratrabbit.nl/ratrabbit/content/sw/xsnow/introduction Donation: https://paypal.me/wvermin +Bug-Submit: https://sourceforge.net/p/xsnow/tickets/ Reference: - Author: Willem Vermin and Rick Jansen Title: Xsnow brings Xmas to your desktop. diff -Nru xsnow-3.1.1/dependencies xsnow-3.3.2/dependencies --- xsnow-3.1.1/dependencies 2019-05-13 14:34:25.000000000 +0000 +++ xsnow-3.3.2/dependencies 2020-10-21 11:24:17.000000000 +0000 @@ -1,6 +1,12 @@ +packages: libx11-dev libxpm-dev libxt-dev pkg-config libxml2-dev libgtk-3-dev + +compilers: +gcc +g++ + diff -Nru xsnow-3.1.1/getversion xsnow-3.3.2/getversion --- xsnow-3.1.1/getversion 2020-10-13 12:50:56.000000000 +0000 +++ xsnow-3.3.2/getversion 1970-01-01 00:00:00.000000000 +0000 @@ -1,21 +0,0 @@ -#!/bin/bash -# -copyright- -#-# -#-# xsnow: let it snow on your desktop -#-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin -#-# -#-# This program is free software: you can redistribute it and/or modify -#-# it under the terms of the GNU General Public License as published by -#-# the Free Software Foundation, either version 3 of the License, or -#-# (at your option) any later version. -#-# -#-# This program is distributed in the hope that it will be useful, -#-# but WITHOUT ANY WARRANTY; without even the implied warranty of -#-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -#-# GNU General Public License for more details. -#-# -#-# You should have received a copy of the GNU General Public License -#-# along with this program. If not, see . -#-# -grep -w VERSION src/version.h | awk '{print $3}' | tr -d '"' diff -Nru xsnow-3.1.1/makedeb xsnow-3.3.2/makedeb --- xsnow-3.1.1/makedeb 2020-10-13 13:00:55.000000000 +0000 +++ xsnow-3.3.2/makedeb 1970-01-01 00:00:00.000000000 +0000 @@ -1,75 +0,0 @@ -#!/bin/bash -# parameter all: produce debs for i386-stretch, amd64=stretch, amd64-sid -curdir=$PWD -unset CXXFLAGS -version=`./getversion` -echo "version = $version" -tar=$PWD/../versions/xsnow-$version.tar.gz -dir=xsnow-$version -dsc=xsnow_$version-1.dsc -debdir=$PWD/../debian/xsnow-$version-deb -#for d in debian debian.disco debian.stretch debian.sid ; do -# if [ -e $d/changelog ] ; then -# sed -i "1s/(.*)/($version-1)/" $d/changelog || exit 1 -# fi -#done -./maketar || exit 1 -rm -rf $debdir -mkdir -p $debdir || exit 1 -cd $debdir || exit 1 -cp $tar . || exit 1 -tar xf $tar || exit -cd $dir || exit -codename=`lsb_release -sc` -rm -rf debian -cp -r $curdir/../xsnow-debian/debian . -cp $curdir/../xsnow-debian/debian.$codename/* debian || exit -#dh_make --yes -s -f $tar -echo xxxxxxxxx dh_make -dh_make --yes -s --createorig -cd .. -echo xxxxxxxxx "dpkg-source -b $dir" -dpkg-source -b $dir || exit 1 -cd - -#debuild -us -uc --lintian-opts --profile debian || exit -echo xxxxxxxxx dpkg-buildpackage -dpkg-buildpackage -us -uc --check-command=lintian --check-option='--profile' --check-option=debian -if test "x$1" != xall ; then - cd .. - rm -r $dir || exit 1 - echo $0 done - exit 0 -fi -cd .. -#for dist in amd64-sid ; do -for dist in i386-stretch amd64-stretch ; do -#for dist in amd64-sid i386-stretch amd64-stretch ; do - debdirbuild=$curdir/../debian/xsnow-$version-deb-build.$dist - rm -rf $debdirbuild - mkdir -p $debdirbuild || exit 1 - workdir=`mktemp -d --tmpdir xsnow-pbuilder-$dist.XXXXXXX` - echo building for $dist in $workdir ... - cd $workdir || exit 1 - mkdir w || exit 1 - cd w || exit 1 - tar xf $tar || exit 1 - cd $dir || exit 1 - rm -rf debian - cp -r $curdir/../xsnow-debian/debian . - case $dist in - *stretch*) - cp $curdir/../xsnow-debian/debian.stretch/* debian || exit 1 - ;; - *sid*) - cp $curdir/../xsnow-debian/debian.sid/* debian || exit 1 - ;; - esac - dh_make --yes -s --createorig - cd .. - dpkg-source -b $dir || exit 1 - sudo pbuilder --build --configfile /root/pbuilderrc.$dist --buildresult $debdirbuild $workdir/w/*dsc - sudo chown -h $USER.$USER $debdirbuild/* || exit 1 - debsign $debdirbuild/*.changes || exit 1 -done -rm -r $dir || exit 1 -echo $0 done diff -Nru xsnow-3.1.1/Makefile.am xsnow-3.3.2/Makefile.am --- xsnow-3.1.1/Makefile.am 2020-10-13 12:50:56.000000000 +0000 +++ xsnow-3.3.2/Makefile.am 2021-11-04 14:24:27.000000000 +0000 @@ -2,7 +2,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by @@ -20,7 +20,6 @@ AUTOMAKE_OPTIONS = gnu SUBDIRS = src -EXTRA_DIST = bootstrap Changes getversion README.md \ +EXTRA_DIST = bootstrap Changes README.md \ addcopyright.sh prevent-remakes \ - pbuilderscript makeupload makedeb dependencies \ - maketar + dependencies simplemake.sh diff -Nru xsnow-3.1.1/Makefile.in xsnow-3.3.2/Makefile.in --- xsnow-3.1.1/Makefile.in 2020-10-13 14:45:46.000000000 +0000 +++ xsnow-3.3.2/Makefile.in 2021-11-04 14:24:33.000000000 +0000 @@ -201,7 +201,6 @@ | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' distcleancheck_listfiles = find . -type f -print ACLOCAL = @ACLOCAL@ -ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AUTOCONF = @AUTOCONF@ @@ -255,6 +254,8 @@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ +X11_CFLAGS = @X11_CFLAGS@ +X11_LIBS = @X11_LIBS@ XMKMF = @XMKMF@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ @@ -307,7 +308,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by @@ -324,10 +325,9 @@ #-# AUTOMAKE_OPTIONS = gnu SUBDIRS = src -EXTRA_DIST = bootstrap Changes getversion README.md \ +EXTRA_DIST = bootstrap Changes README.md \ addcopyright.sh prevent-remakes \ - pbuilderscript makeupload makedeb dependencies \ - maketar + dependencies simplemake.sh all: config.h $(MAKE) $(AM_MAKEFLAGS) all-recursive diff -Nru xsnow-3.1.1/maketar xsnow-3.3.2/maketar --- xsnow-3.1.1/maketar 2020-10-01 13:26:58.000000000 +0000 +++ xsnow-3.3.2/maketar 1970-01-01 00:00:00.000000000 +0000 @@ -1,14 +0,0 @@ -#!/bin/bash -curdir=`pwd` || exit 1 -version=`./getversion` || exit 1 -echo "version = $version" -./configure || exit 1 -make -j4 distcheck || exit 1 -#if [ -x /usr/games/xsnow ] ; then -# rm -rf ./autopkgtest-dir -# autopkgtest --output-dir ./autopkgtest-dir -B . -- null || exit 1 -#fi -mkdir -p ../versions || exit 1 -mv xsnow*.tar.gz ../versions || exit 1 -make distclean -echo "$0 done" diff -Nru xsnow-3.1.1/makeupload xsnow-3.3.2/makeupload --- xsnow-3.1.1/makeupload 2020-10-13 13:16:52.000000000 +0000 +++ xsnow-3.3.2/makeupload 1970-01-01 00:00:00.000000000 +0000 @@ -1,34 +0,0 @@ -#!/bin/bash -# creates directory for upload -# version numbers for upstream releases: -newversion=`./getversion` -#oldversion=2.0.19 -oldversion=3.0.7 -curdir=`pwd` -dist=sid -tar=$curdir/../versions/xsnow-$newversion.tar.gz -uploaddir=$curdir/../upload/upload-$newversion -./maketar || exit 1 -echo removing $uploaddir ... -mkdir -p $uploaddir -sudo chown -R willem.willem $uploaddir -rm -rf $uploaddir -mkdir -p $uploaddir -cd $uploaddir || exit 1 -cp -v $tar . || exit 1 -#apt source xsnow || exit 1 -cp -r $curdir/../xsnow-debian/debian . || exit 1 -sudo bash `which pbuilder` --execute --bindmounts $PWD \ - --configfile ~root/pbuilderrc.$dist \ - -- $curdir/pbuilderscript $PWD $oldversion $newversion|| exit 1 -sudo chown -R willem.willem $uploaddir -rm -r xsnow-$oldversion -rm xsnow_$oldversion-*.debian.tar.[gx]z -rm xsnow_$oldversion-*.dsc -rm xsnow_$oldversion.orig.tar.gz -rm -r xsnow-$newversion -rm -r xsnow-$newversion.orig -debsign -k8D232D69D0889859B1E7732ADC4874F4A7D3496F *.changes -echo to check: dput -s mentors $uploaddir/*.changes -echo to upload: dput mentors $uploaddir/*.changes -echo "$0 done" diff -Nru xsnow-3.1.1/NEWS xsnow-3.3.2/NEWS --- xsnow-3.1.1/NEWS 2019-01-26 15:57:48.000000000 +0000 +++ xsnow-3.3.2/NEWS 2020-10-30 11:46:11.000000000 +0000 @@ -0,0 +1,2 @@ + + diff -Nru xsnow-3.1.1/pbuilderscript xsnow-3.3.2/pbuilderscript --- xsnow-3.1.1/pbuilderscript 2020-10-13 13:18:14.000000000 +0000 +++ xsnow-3.3.2/pbuilderscript 1970-01-01 00:00:00.000000000 +0000 @@ -1,63 +0,0 @@ -#!/bin/bash -# script for pbuilder to create upload directory -workdir=$1 -oldversion=$2 -newversion=$3 -if [ -z "$3" ] ; then - echo usage: pbuilderscript workdir oldversion newversion - exit 1 -fi -cd "$workdir" || exit 1 -echo "working in `pwd`" -export DEBEMAIL=wvermin@gmail.com -export DEBFULLNAME="Willem Vermin" -sed -i 's/^#//' /etc/apt/sources.list # uncomment 2de regel -apt update -apt -y install apt-utils || exit 1 -apt -y install quilt devscripts debhelper autotools-dev equivs || exit 1 -apt source xsnow || exit 1 -cd xsnow-$oldversion || exit 1 -uupdate -v $newversion ../xsnow-$newversion.tar.gz || exit 1 -cd ../xsnow-$newversion -rm -rf debian -cp -r $workdir/debian . || exit 1 -#if [ -d debian.upstream ] ; then -# rm -r debian -# mv debian.upstream debian || exit 1 -#fi -echo quilt ... -while quilt push; do quilt refresh; done -#dch -echo "---------- mk-build-deps -----------------" -echo | mk-build-deps --install --remove debian/control || exit 1 -# got dpkg-source: error: aborting due to unexpected upstream changes -# caused by the files *-build-deps*.buildinfo and *-build-deps*.changes -# created by mk-build-deps -# hence the following: -if true ; then - if false ; then - # this seems to be the recommended way - mkdir -p debian/source - ( - echo "Description: to remedy this" - echo " dpkg-source: error: aborting due to unexpected upstream changes" - echo "Forwarded: not-needed" - ) > debian/source/local-patch-header - EDITOR=/bin/true dpkg-source --commit . buildinfo-changes - while quilt push; do quilt refresh; done - # - else - # simple remove the offending files - rm -f *-build-deps*.buildinfo *-build-deps*.changes - fi -fi -echo "-------------- dpkg-buildpackage ------------" -debuild -us -uc || exit 1 -if false ; then - # debuild already runs lintian - cd .. - echo "running lintian ..." - lintian -F -i -I --show-overrides --no-tag-display-limit xsnow_$newversion-1_amd64.changes - echo "end lintian" -fi -echo $0 done diff -Nru xsnow-3.1.1/README xsnow-3.3.2/README --- xsnow-3.1.1/README 2019-07-18 05:58:29.000000000 +0000 +++ xsnow-3.3.2/README 2021-11-04 14:24:27.000000000 +0000 @@ -1,3 +1,24 @@ +# -copyright- +#-# +#-# xsnow: let it snow on your desktop +#-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen +#-# 2019,2020,2021 Willem Vermin +#-# +#-# This program is free software: you can redistribute it and/or modify +#-# it under the terms of the GNU General Public License as published by +#-# the Free Software Foundation, either version 3 of the License, or +#-# (at your option) any later version. +#-# +#-# This program is distributed in the hope that it will be useful, +#-# but WITHOUT ANY WARRANTY; without even the implied warranty of +#-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +#-# GNU General Public License for more details. +#-# +#-# You should have received a copy of the GNU General Public License +#-# along with this program. If not, see . +#-# + + xsnow: let it snow on your desktop xsnow is derived from Rick Jansen's xsnow-1.42. @@ -23,5 +44,12 @@ Raspberry pi - Raspian users: choose the .deb with arch='armhf' . +If the above recipes do not work, you can try and run the +script 'simplemake.sh': + + ./simplemake.sh + +If problems persist, you can adapt simplemake.sh. + Have fun! diff -Nru xsnow-3.1.1/README.md xsnow-3.3.2/README.md --- xsnow-3.1.1/README.md 2020-10-13 12:51:00.000000000 +0000 +++ xsnow-3.3.2/README.md 2021-11-04 14:24:31.000000000 +0000 @@ -1,4 +1,25 @@ ## Do not modify this file, it is generated from README by bootstrap ## +# -copyright- +#-# +#-# xsnow: let it snow on your desktop +#-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen +#-# 2019,2020,2021 Willem Vermin +#-# +#-# This program is free software: you can redistribute it and/or modify +#-# it under the terms of the GNU General Public License as published by +#-# the Free Software Foundation, either version 3 of the License, or +#-# (at your option) any later version. +#-# +#-# This program is distributed in the hope that it will be useful, +#-# but WITHOUT ANY WARRANTY; without even the implied warranty of +#-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +#-# GNU General Public License for more details. +#-# +#-# You should have received a copy of the GNU General Public License +#-# along with this program. If not, see . +#-# + + xsnow: let it snow on your desktop xsnow is derived from Rick Jansen's xsnow-1.42. @@ -24,5 +45,12 @@ Raspberry pi - Raspian users: choose the .deb with arch='armhf' . +If the above recipes do not work, you can try and run the +script 'simplemake.sh': + + ./simplemake.sh + +If problems persist, you can adapt simplemake.sh. + Have fun! diff -Nru xsnow-3.1.1/simplemake.sh xsnow-3.3.2/simplemake.sh --- xsnow-3.1.1/simplemake.sh 1970-01-01 00:00:00.000000000 +0000 +++ xsnow-3.3.2/simplemake.sh 2021-11-04 14:24:27.000000000 +0000 @@ -0,0 +1,126 @@ +#!/bin/sh +# -copyright- +#-# +#-# xsnow: let it snow on your desktop +#-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen +#-# 2019,2020,2021 Willem Vermin +#-# +#-# This program is free software: you can redistribute it and/or modify +#-# it under the terms of the GNU General Public License as published by +#-# the Free Software Foundation, either version 3 of the License, or +#-# (at your option) any later version. +#-# +#-# This program is distributed in the hope that it will be useful, +#-# but WITHOUT ANY WARRANTY; without even the implied warranty of +#-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +#-# GNU General Public License for more details. +#-# +#-# You should have received a copy of the GNU General Public License +#-# along with this program. If not, see . +#-# +# +# This is a script which compiles xsnow. +# Use and adapt this if the +# ./configure; make; make install +# suite does not work on your system +# + +# Compilers: + +# C compiler to compile .c sources: +CC=gcc +# C++ compiler to compile .cpp sources: +CXX=g++ +# +# You can also use the C++ compiler for all sources: +# CC=$CXX +# +# The C++ compiler is only needed for mainstub.cpp and hashtable.cpp +# + +# compile and link flags + +FLAGS="-O2" +# if you have pkg-config working for gtk3: +FLAGS="$FLAGS `pkg-config --cflags --libs gtk+-3.0`" +# NOTE: on my system, pkg-config expands to: +# -pthread -I/usr/include/gtk-3.0 -I/usr/include/at-spi2-atk/2.0 -I/usr/include/at-spi-2.0 -I/usr/include/dbus-1.0 -I/usr/lib/x86_64-linux-gnu/dbus-1.0/include -I/usr/include/gtk-3.0 -I/usr/include/gio-unix-2.0 -I/usr/include/cairo -I/usr/include/pango-1.0 -I/usr/include/fribidi -I/usr/include/harfbuzz -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/include/pixman-1 -I/usr/include/uuid -I/usr/include/freetype2 -I/usr/include/libpng16 -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/libmount -I/usr/include/blkid -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -lgtk-3 -lgdk-3 -lpangocairo-1.0 -lpango-1.0 -lharfbuzz -latk-1.0 -lcairo-gobject -lcairo -lgdk_pixbuf-2.0 -lgio-2.0 -lgobject-2.0 -lglib-2.0 + +# if you have pkg-config working for libxml2: +FLAGS="$FLAGS `pkg-config --cflags --libs libxml-2.0`" +# NOTE: on my system, pkg-config expands to: +# -I/usr/include/libxml2 -lxml2 + +# if you have pkg-config working for gmodule-2.0: +FLAGS="$FLAGS `pkg-config --cflags --libs gmodule-2.0`" +# NOTE: on my system, pkg-config expands to: +# -pthread -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -Wl,--export-dynamic -lgmodule-2.0 -pthread -lglib-2.0 + +# if you have pkg-config working for these: x11 xpm xt xproto +FLAGS="$FLAGS `pkg-config --cflags --libs x11 xpm xt xproto`" +# NOTE: on my system, pkg-config expands to: +# -lXpm -lXt -lX11 + +# link flags for libmath: +FLAGS="$FLAGS -lm" + +# following is needed by gtk3 to recognize the buttons: +# (Should be delivered by pkg-config --cflags --libs gmodule-2.0) +# FLAGS="$FLAGS -Wl,--export-dynamic" +# or: +# FLAGS="$FLAGS -rdynamic" + +# comment out if your C++ compiler does not support unordered_map: +FLAGS="$FLAGS -DHAVE_UNORDERED_MAP" + +# comment out if your C++ compiler does not support unordered_set: +FLAGS="$FLAGS -DHAVE_UNORDERED_SET" + +version=`./getversion` +if [ "x$version" = x ]; then + version="Unknown" +fi + +FLAGS="$FLAGS -DVERSION=\"$version\"" + +cd src || exit 1 +echo "removing .o files :" +rm -f *.o + +echo "Creating snow_includes.h" +./gen_snow_includes.sh .. || exit 1 + +echo "Creating ui_xml.h" +./gen_ui_xml.sh .. || exit 1 + +echo compiling C sources: +$CC -c *.c $FLAGS || exit 1 + +echo compiling C++ sources: +$CXX -c *.cpp $FLAGS || exit 1 + +echo creating xsnow in directory $PWD: +$CXX -o xsnow *.o $FLAGS || exit 1 + +echo creating manpage in directory $PWD as xsnow.6: +./xsnow -H > xsnow.6 || exit 1 + +echo +echo " ********************************************************************" +echo " ** It seems that you compiled xsnow successfully. **" +echo " ** You can try to run it: **" +echo " ** **" +echo " ** src/xsnow **" +echo " ** **" +echo " ** If xsnow works satisfactorily, you can install it: **" +echo " ** Copy src/xsnow to for example /usr/local/bin/ **" +echo " ** **" +echo " ** Optionally, you can install the man page too: **" +echo " ** Copy src/xsnow.6 to for example /usr/local/share/man/man6/ **" +echo " ** **" +echo " ** Optionally, you can install the desktop file and icon: **" +echo " ** Copy src/xsnow.desktop to for example **" +echo " ** /usr/local/share/applications/ **" +echo " ** Copy src/Pixmaps/xsnow.svg to for example **" +echo " ** /usr/local/share/pixmaps/ **" +echo " ********************************************************************" diff -Nru xsnow-3.1.1/src/birdglobals.h xsnow-3.3.2/src/birdglobals.h --- xsnow-3.1.1/src/birdglobals.h 1970-01-01 00:00:00.000000000 +0000 +++ xsnow-3.3.2/src/birdglobals.h 2021-11-04 14:24:27.000000000 +0000 @@ -0,0 +1,60 @@ +/* -copyright- +#-# +#-# xsnow: let it snow on your desktop +#-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen +#-# 2019,2020,2021 Willem Vermin +#-# +#-# This program is free software: you can redistribute it and/or modify +#-# it under the terms of the GNU General Public License as published by +#-# the Free Software Foundation, either version 3 of the License, or +#-# (at your option) any later version. +#-# +#-# This program is distributed in the hope that it will be useful, +#-# but WITHOUT ANY WARRANTY; without even the implied warranty of +#-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +#-# GNU General Public License for more details. +#-# +#-# You should have received a copy of the GNU General Public License +#-# along with this program. If not, see . +#-# + */ +#pragma once + +#include "doitb.h" +#include "xsnow.h" + +extern struct _blobals { + int maxix, maxiy, maxiz; // [pixels] + float maxx, maxy, maxz; // [m] + float ax, ay, az; // [pixels/m] see r2i in main.c for usage + float ox, oy, oz; // [m] idem + float maxrange; // max distanc to look for other birds [m] + float bird_scale; // scale for drawing birds + float prefdweight; // dimensionless + float meanspeed; // [m/s] preferred mean speed of birds + int neighbours_max; // max number of neighbours to look at + float range; // range wherein neighbours are to be found [m] + float mean_distance; // mean distance [m] + float xc, zc; // coordinates of camera obscura lens + + unsigned int freeze BITS(1); // when true, system freezes + +#define DOITB(what,type) \ + type what; \ + type what ## _new; + + DOITALLB() +#undef DOITB +#define DOITB(what,type) \ + unsigned int what ## _changed BITS(1); + + DOITALLB() +#undef DOITB + +#define DOITB(what) \ + unsigned int what ## _requested BITS(1); + BUTTONALL() +#undef DOITB + +} blobals; + diff -Nru xsnow-3.1.1/src/birds.c xsnow-3.3.2/src/birds.c --- xsnow-3.1.1/src/birds.c 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/birds.c 2021-11-04 14:24:28.000000000 +0000 @@ -2,7 +2,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by @@ -24,13 +24,14 @@ #include #include #include +#include #include "Santa.h" #include "birds.h" #include "clocks.h" #include "debug.h" #include "doitb.h" #include "flags.h" -#include "globals.h" +#include "birdglobals.h" #include "hashtable.h" #include "ixpm.h" #include "kdtree.h" @@ -39,7 +40,6 @@ #include "ui.h" #include "utils.h" #include "windows.h" -#include "varia.h" @@ -48,7 +48,7 @@ #define LEAVE_IF_INACTIVE\ - if (!Flags.ShowBirds || globals.freeze || !WorkspaceActive()) return TRUE + if (!Flags.ShowBirds || blobals.freeze || !WorkspaceActive()) return TRUE /* Surface to store current scribbles */ @@ -70,9 +70,11 @@ // ix .. in pixels, used to store previous screen parameters int wingstate, orient; int drawable; // is in drawable range + // comes in handy at erasing a bird: + int prevx, prevy, prevw, prevh, prevdrawable; } BirdType; -struct _globals globals; +struct _blobals blobals; static void attrbird2surface(void); @@ -81,17 +83,19 @@ static void birds_set_scale(void); static void birds_set_speed(void); static void clear_flags(void); -static int do_change_attr(gpointer data); -static int do_update_pos_birds(gpointer data); -static int do_wings(gpointer data); -static int do_update_speed_birds(gpointer data); -static void init_birds(int start); +static int do_change_attr(void *); +static int do_update_pos_birds(void *); +static int do_wings(void *); +static int do_update_speed_birds(void *); +static int do_main_window(void *); static void init_bird_pixbufs(const char *color); static void main_window(void); static void normalize_speed(BirdType *bird, float speed); static void prefxyz(BirdType *bird, float d, float e, float x, float y, float z, float *prefx, float *prefy, float *prefz); static void r2i(BirdType *bird); static void i2r(BirdType *bird); +static int attrbird_erase(int force); +static void init_birds(int start); static float time_update_pos_birds = 0.01; @@ -104,135 +108,48 @@ static BirdType attrbird; - -int birds_ui() +void birds_ui() { - int changes = 0; + UIDO(ShowBirds , birds_erase(1); attrbird_erase(1); ); + UIDO(BirdsOnly , ClearScreen(); ); + UIDO(Neighbours , ); + UIDO(Anarchy , ); + UIDO(PrefDistance , ); + UIDO(ViewingDistance , attrbird2surface(); ); + UIDO(BirdsSpeed , birds_set_speed(); ); + UIDO(AttrFactor , ); + UIDO(DisWeight , ); + UIDO(FollowWeight , ); + UIDO(BirdsScale , birds_set_scale(); ); + UIDO(ShowAttrPoint , attrbird_erase(1); ); + UIDOS(BirdsColor , + birds_init_color(); + ClearScreen();); + UIDO(Nbirds , + int start = OldFlags.Nbirds; + if (Flags.Nbirds <= 0) + Flags.Nbirds = 1; + if (Flags.Nbirds > NBIRDS_MAX) + Flags.Nbirds = NBIRDS_MAX; + init_birds(start);); + UIDO(FollowSanta, + if (!Flags.FollowSanta) + birds_set_attraction_point_relative(0.5, 0.5, 0.5);); - if(Flags.ShowBirds != OldFlags.ShowBirds) - { - OldFlags.ShowBirds = Flags.ShowBirds; - changes++; - P("changes: %d\n",changes); - } - if(Flags.BirdsOnly != OldFlags.BirdsOnly) - { - P("BirdsOnly %d %d\n",Flags.BirdsOnly,OldFlags.BirdsOnly); - OldFlags.BirdsOnly = Flags.BirdsOnly; - ClearScreen(); - changes++; - P("changes: %d\n",changes); - } - if(Flags.Neighbours != OldFlags.Neighbours) - { - OldFlags.Neighbours = Flags.Neighbours; - changes++; - P("changes: %d\n",changes); - } - if(Flags.Anarchy != OldFlags.Anarchy) - { - OldFlags.Anarchy = Flags.Anarchy; - changes++; - P("changes: %d\n",changes); - } - if(Flags.PrefDistance != OldFlags.PrefDistance) - { - OldFlags.PrefDistance = Flags.PrefDistance; - changes++; - P("changes: %d\n",changes); - } if(Flags.BirdsRestart) { Flags.BirdsRestart = 0; init_birds(0); birds_set_attraction_point_relative(0.5, 0.5, 0.5); - P("changes: %d\n",changes); - } - if(Flags.ViewingDistance != OldFlags.ViewingDistance) - { - OldFlags.ViewingDistance = Flags.ViewingDistance; - attrbird2surface(); - changes++; - P("changes: %d\n",changes); - } - if(Flags.BirdsSpeed != OldFlags.BirdsSpeed) - { - OldFlags.BirdsSpeed = Flags.BirdsSpeed; - birds_set_speed(); - changes++; - P("changes: %d\n",changes); + P("Changes: %d\n",Flags.Changes); } - if(Flags.AttrFactor != OldFlags.AttrFactor) - { - OldFlags.AttrFactor = Flags.AttrFactor; - changes++; - P("changes: %d\n",changes); - } - if(Flags.DisWeight != OldFlags.DisWeight) - { - OldFlags.DisWeight = Flags.DisWeight; - changes++; - P("changes: %d\n",changes); - } - if(Flags.FollowWeight != OldFlags.FollowWeight) - { - OldFlags.FollowWeight = Flags.FollowWeight; - changes++; - P("changes: %d\n",changes); - } - if(Flags.BirdsScale != OldFlags.BirdsScale) - { - OldFlags.BirdsScale = Flags.BirdsScale; - birds_set_scale(); - changes++; - P("changes: %d\n",changes); - } - if(Flags.ShowAttrPoint != OldFlags.ShowAttrPoint) - { - OldFlags.ShowAttrPoint = Flags.ShowAttrPoint; - changes++; - P("changes: %d\n",changes); - } - if(strcmp(Flags.BirdsColor, OldFlags.BirdsColor)) - { - P("%s %s\n",Flags.BirdsColor,OldFlags.BirdsColor); - birds_init_color(); - ClearScreen(); - free(OldFlags.BirdsColor); - OldFlags.BirdsColor = strdup(Flags.BirdsColor); - changes++; - P("changes: %d\n",changes); - } - - if(Flags.Nbirds != OldFlags.Nbirds) - { - int start = OldFlags.Nbirds; - if (Flags.Nbirds <= 0) - Flags.Nbirds = 1; - if (Flags.Nbirds > NBIRDS_MAX) - Flags.Nbirds = NBIRDS_MAX; - OldFlags.Nbirds = Flags.Nbirds; - changes++; - P("changes: %d\n",changes); - init_birds(start); - } - - if(Flags.FollowSanta != OldFlags.FollowSanta) - { - P("FollowSanta: %d->%d\n",OldFlags.FollowSanta,Flags.FollowSanta); - OldFlags.FollowSanta = Flags.FollowSanta; - if (!Flags.FollowSanta) - birds_set_attraction_point_relative(0.5, 0.5, 0.5); - changes ++; - } - return changes; } static void normalize_speed(BirdType *bird, float speed) { float v2 = sq3(bird->sx, bird->sy, bird->sz); if (fabsf(v2) < 1.0e-10) - v2 = globals.meanspeed; + v2 = blobals.meanspeed; float a = speed/sqrtf(v2); bird->sx *= a; bird->sy *= a; @@ -245,7 +162,7 @@ float s; if (y != 0) { - s = 0.005*(100-Flags.ViewingDistance)*globals.maxy/y; + s = 0.005*(100-Flags.ViewingDistance)*blobals.maxy/y; } else s = 1.0e6; @@ -261,19 +178,19 @@ { bird->drawable = 1; float f = scale(bird->y); - P("%f %d %f\n",globals.maxy,Flags.ViewingDistance,f); + P("%f %d %f\n",blobals.maxy,Flags.ViewingDistance,f); #ifdef CO_REAL // classical camera obscura, inverted image: - float x = f*(globals.xc-bird->x) + globals.xc; - float z = f*(globals.zc-bird->z) + globals.zc; + float x = f*(blobals.xc-bird->x) + blobals.xc; + float z = f*(blobals.zc-bird->z) + blobals.zc; #else // alternative camera obscura, not inverted image: - float x = f*(bird->x-globals.xc) + globals.xc; - float z = f*(bird->z-globals.zc) + globals.zc; + float x = f*(bird->x-blobals.xc) + blobals.xc; + float z = f*(bird->z-blobals.zc) + blobals.zc; #endif - bird->ix = globals.ax*x; - bird->iy = globals.ay*bird->y; - bird->iz = globals.az*z; + bird->ix = blobals.ax*x; + bird->iy = blobals.ay*bird->y; + bird->iz = blobals.az*z; } else { @@ -287,13 +204,13 @@ { float f = scale(bird->y); #ifdef CO_REAL - bird->x = (globals.ax*globals.xc - bird->ix)/(globals.ax*f) + globals.xc; - bird->z = (globals.az*globals.zc - bird->iz)/(globals.az*f) + globals.zc; + bird->x = (blobals.ax*blobals.xc - bird->ix)/(blobals.ax*f) + blobals.xc; + bird->z = (blobals.az*blobals.zc - bird->iz)/(blobals.az*f) + blobals.zc; #else - bird->x = (bird->ix - globals.ax*globals.xc)/(globals.ax*f) + globals.xc; - bird->z = (bird->iz - globals.az*globals.zc)/(globals.az*f) + globals.zc; + bird->x = (bird->ix - blobals.ax*blobals.xc)/(blobals.ax*f) + blobals.xc; + bird->z = (bird->iz - blobals.az*blobals.zc)/(blobals.az*f) + blobals.zc; #endif - bird->iy = globals.ay*bird->y; + bird->iy = blobals.ay*bird->y; } // given: @@ -324,7 +241,7 @@ cairo_surface_destroy(attrsurface); r2i(&attrbird); float f = - scale(attrbird.y)*4.0e-6*globals.bird_scale*Flags.BirdsScale*globals.maxix; + scale(attrbird.y)*4.0e-6*blobals.bird_scale*Flags.BirdsScale*blobals.maxix; P("attrbird2surface %d %f\n",counter++,f); attrsurface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32,2*f+2,2*f+2); cairo_t *cr = cairo_create(attrsurface); @@ -339,12 +256,10 @@ attrbird2surface(); } -int do_update_speed_birds(UNUSED gpointer data) +int do_update_speed_birds(void *d) { if (Flags.Done) return FALSE; - if (!switches.DrawBirds) - return TRUE; LEAVE_IF_INACTIVE; P("do_update_speed_birds %d\n",counter); @@ -367,7 +282,7 @@ continue; BirdType *bird = &birds[i]; - struct kdres *result = kd_nearest_range3f(kd,bird->x,bird->y,bird->z,globals.range); + struct kdres *result = kd_nearest_range3f(kd,bird->x,bird->y,bird->z,blobals.range); float sumsx = 0; float sumsy = 0; float sumsz = 0; @@ -465,33 +380,32 @@ bird->sz += bird->sz*p*drand48(); } - normalize_speed(bird,globals.meanspeed*(0.9+drand48()*0.2)); + normalize_speed(bird,blobals.meanspeed*(0.9+drand48()*0.2)); } float meannum = (float)sumnum/(float)Nbirds; - globals.mean_distance = summeandist/Nbirds; - P("meannum %f %f\n",meannum,globals.range); + blobals.mean_distance = summeandist/Nbirds; + P("meannum %f %f\n",meannum,blobals.range); if (meannum < Flags.Neighbours) { - if (globals.range < 0.1) - globals.range = 0.1; + if (blobals.range < 0.1) + blobals.range = 0.1; if (meannum < Nbirds-1) - globals.range *=1.1; - if (globals.range > globals.maxrange) - globals.range /=1.1; + blobals.range *=1.1; + if (blobals.range > blobals.maxrange) + blobals.range /=1.1; } else - globals.range /=1.1; + blobals.range /=1.1; return TRUE; + (void)d; } -int do_update_pos_birds(UNUSED gpointer data) +int do_update_pos_birds(void *d) { if (Flags.Done) return FALSE; - if (!switches.DrawBirds) - return TRUE; LEAVE_IF_INACTIVE; P("do_update_pos_birds %d %d\n",Nbirds,counter++); double dt; @@ -509,12 +423,14 @@ bird->z += dt*bird->sz; } return TRUE; + (void)d; } int birds_draw(cairo_t *cr) { - P("birds_draw %d %d\n",counter++,switches.DrawBirds); + P("birds_draw %d\n",counter++); LEAVE_IF_INACTIVE; + P("drawing birds %d\n",counter++); int before; int i; @@ -525,13 +441,13 @@ { static int prevSantasize = -1; Santa_draw(cr); - attrbird.ix = SantaX+SantaWidth/2; - attrbird.iz = SantaY+SantaHeight/2; + attrbird.ix = global.SantaX+global.SantaWidth/2; + attrbird.iz = global.SantaY+global.SantaHeight/2; switch(Flags.SantaSize) { - case 0: attrbird.y = globals.maxy*1.5; break; - case 1: attrbird.y = globals.maxy*1.0; break; - default: attrbird.y = globals.maxy*0.5; break; + case 0: attrbird.y = blobals.maxy*1.5; break; + case 1: attrbird.y = blobals.maxy*1.0; break; + default: attrbird.y = blobals.maxy*0.5; break; } i2r(&attrbird); P("santasize: %d %d %d %f\n",prevSantasize,Flags.SantaSize,Flags.ViewingDistance,scale(attrbird.y)); @@ -548,8 +464,13 @@ P("attrbird %f %f %f %d %d %d\n",attrbird.x,attrbird.y,attrbird.z,attrbird.ix,attrbird.iy,attrbird.iz); int mx = cairo_image_surface_get_width(attrsurface); int mz = cairo_image_surface_get_height(attrsurface); + P("mx: %d mz: %d\n",mx,mz); cairo_set_source_surface (cr, attrsurface, attrbird.ix-mx/2, attrbird.iz-mz/2); my_cairo_paint_with_alpha(cr,ALPHA); + attrbird.prevx = attrbird.ix-mx/2; + attrbird.prevy = attrbird.iz-mz/2; + attrbird.prevw = mx; + attrbird.prevh = mz; //#define TESTBIRDS #ifdef TESTBIRDS { @@ -570,8 +491,10 @@ (float)gdk_pixbuf_get_width(bird_pixbuf); GdkPixbuf *pixbuf = 0; const GdkInterpType interpolation = GDK_INTERP_HYPER; + if(iw < 1)iw = 1; + if(ih < 1)ih = 1; pixbuf = gdk_pixbuf_scale_simple(bird_pixbuf,iw,ih,interpolation); - cairo_surface_t *surface = gdk_cairo_surface_create_from_pixbuf (pixbuf, 0, gdkwindow); + cairo_surface_t *surface = gdk_cairo_surface_create_from_pixbuf (pixbuf, 0, NULL); r2i(&testbird); cairo_set_source_surface (cr, surface, testbird.ix +(i-centerbird)*(iw+20), testbird.iz); my_cairo_paint_with_alpha(cr,ALPHA); @@ -599,9 +522,9 @@ r2i(bird); P("%d %f %f %f %d %d %d %d\n",i,bird->x,bird->y,bird->z,bird->ix,bird->iy,bird->iz,bird->drawable); + bird->prevdrawable = bird->drawable; if (bird->drawable) { - //float p = Flags.ViewingDistance/bird->y; float p = scale(bird->y); cairo_surface_t *surface; @@ -645,19 +568,18 @@ P("%f %f %d\n",sxz,bird->sy,orient); GdkPixbuf *bird_pixbuf = bird_pixbufs[nw+orient]; - iw = p*globals.bird_scale*Flags.BirdsScale*6.0e-6*globals.maxix; - P("%d %d\n",Flags.BirdsScale,globals.maxix); + iw = p*blobals.bird_scale*Flags.BirdsScale*6.0e-6*blobals.maxix; + P("%d %d\n",Flags.BirdsScale,blobals.maxix); ih = (float)iw*gdk_pixbuf_get_height(bird_pixbuf)/ (float)gdk_pixbuf_get_width(bird_pixbuf); // do not draw very large birds (would be bad for cache use) // and do not draw vanishing small birds - if (ih > globals.maxiz*0.2 || ih <=0) // iw is always larger than ih, we don't have to check iw + if (ih > blobals.maxiz*0.2 || ih <=0) // iw is always larger than ih, we don't have to check iw { - P("ih: %d %d\n",ih,globals.maxiz); + P("ih: %d %d\n",ih,blobals.maxiz); continue; } - //const GdkInterpType interpolation = GDK_INTERP_BILINEAR; const GdkInterpType interpolation = GDK_INTERP_HYPER; // since we are caching the surfaces, we go for the highest quality @@ -672,8 +594,10 @@ table_counter++; cache += iw*ih; P("Entries: %d Cache: %.0f MB width: %d Wing: %d orient: %d\n",table_counter,cache*4.0e-6,iw,nw,orient/8); + if(iw < 1)iw = 1; + if(ih < 1)ih = 1; GdkPixbuf *pixbuf = gdk_pixbuf_scale_simple(bird_pixbuf,iw,ih,interpolation); - table_insert(key,gdk_cairo_surface_create_from_pixbuf (pixbuf, 0, gdkwindow)); + table_insert(key,gdk_cairo_surface_create_from_pixbuf (pixbuf, 0, NULL)); g_clear_object(&pixbuf); } surface = (cairo_surface_t*) table_get(key); @@ -682,6 +606,10 @@ int mz = cairo_image_surface_get_height(surface); cairo_set_source_surface (cr, surface, bird->ix-mx/2, bird->iz-mz/2); my_cairo_paint_with_alpha(cr,ALPHA); + bird->prevx = bird->ix-mx/2; + bird->prevy = bird->iz-mz/2; + bird->prevw = mx; + bird->prevh = mz; P("draw: %d %d\n",bird->ix-mx/2,bird->iz-mz/2); } else @@ -695,11 +623,62 @@ return TRUE; } +int birds_erase(int force) +{ + if(global.IsDouble) + return TRUE; + if(!force) + LEAVE_IF_INACTIVE; + P("birds_erase %d\n",counter++); + int i; + for (i=0; iprevdrawable && bird->prevw != 0 && bird->prevh != 0) + { + P("birds_erase xclear %d\n",counter++); + myXClearArea(global.display,global.SnowWin, + bird->prevx, bird->prevy, + bird->prevw, bird->prevh, + global.xxposures); + } + } + P("clearattr: %d %d %d %d\n", attrbird.prevx, attrbird.prevy, attrbird.prevw, attrbird.prevh); + + attrbird_erase(0); + + return TRUE; +} + +int attrbird_erase(int force) +{ + if(global.IsDouble) + return TRUE; + if (!force) + LEAVE_IF_INACTIVE; + static int px = -10000; + static int py = -10000; + static int pw = -10000; + + if(force || (attrbird.prevw && ( attrbird.prevx != px || attrbird.prevy!= py || attrbird.prevw != pw))) + { + P("erase attrbird\n"); + px = attrbird.prevx; + py = attrbird.prevy; + pw = attrbird.prevw; + myXClearArea(global.display,global.SnowWin, px, py, pw, attrbird.prevh, global.xxposures); + } + return TRUE; +} + void init_birds(int start) { int i; + if(!global.IsDouble) + birds_erase(1); P("nbirds: %d %d\n",start,Flags.Nbirds); - birds = (BirdType *)realloc(birds,sizeof(BirdType)*Flags.Nbirds); + // Bbirds+1 to prevent allocating zero bytes: + birds = (BirdType *)realloc(birds,sizeof(BirdType)*(Flags.Nbirds+1)); if (kd) kd_free(kd); kd = kd_create(3); @@ -707,19 +686,19 @@ for (i=start; ix = drand48()*globals.maxx; - bird->y = drand48()*globals.maxy; - bird->z = drand48()*globals.maxz; + bird->x = drand48()*blobals.maxx; + bird->y = drand48()*blobals.maxy; + bird->z = drand48()*blobals.maxz; double r = drand48(); if (r > 0.75) - bird->x += globals.maxx; + bird->x += blobals.maxx; else if (r > 0.50) - bird->x -= globals.maxx; + bird->x -= blobals.maxx; else if (r > 0.25) - bird->y += globals.maxy; + bird->y += blobals.maxy; else - bird->y -= globals.maxy; + bird->y -= blobals.maxy; bird->iw = 1; bird->ih = 1; @@ -729,22 +708,25 @@ P("init %f\n",bird->sx); bird->sy = (0.5-drand48()); bird->sz = (0.5-drand48()); - normalize_speed(bird,globals.meanspeed); + normalize_speed(bird,blobals.meanspeed); P("speed1: %d %f\n",i,sqrtf(sq3(bird->sx,bird->sy,bird->sz))); bird->drawable = 1; bird->wingstate = drand48()*NWINGS; + bird->prevdrawable = 0; + bird->prevw = 0; + bird->prevh = 0; + bird->prevx = 0; + bird->prevy = 0; kd_insert3f(kd, bird->x, bird->y, bird->z, NULL); } } -static int do_wings(UNUSED gpointer data) +static int do_wings(void *d) { if (Flags.Done) return FALSE; - if (!switches.DrawBirds) - return TRUE; LEAVE_IF_INACTIVE; int i; for (i=0; iwingstate = 0; } return TRUE; + (void)d; } float birds_get_range() { - return globals.range; + return blobals.range; } float birds_get_mean_dist() { - return globals.mean_distance; + return blobals.mean_distance; } void birds_set_attraction_point_relative(float x, float y, float z) { - attrbird.x = globals.maxx*x; - attrbird.y = globals.maxy*y; - attrbird.z = globals.maxz*z; + attrbird.x = blobals.maxx*x; + attrbird.y = blobals.maxy*y; + attrbird.z = blobals.maxz*z; } void clear_flags() { #define DOITB(what,type) \ - globals.what ## _changed = 0; + blobals.what ## _changed = 0; DOITALLB(); -#undef DOITB +#include "undefall.inc" #define DOITB(what) \ - globals.what ## _requested = 0; + blobals.what ## _requested = 0; BUTTONALL(); -#undef DOITB +#include "undefall.inc" } void birds_set_speed() { - globals.meanspeed = Flags.BirdsSpeed*0.01*globals.maxx*0.05; - P("%f\n",globals.meanspeed); + blobals.meanspeed = Flags.BirdsSpeed*0.01*blobals.maxx*0.05; + P("%f\n",blobals.meanspeed); +} + +int do_main_window(void *d) +{ + (void) d; + if (blobals.maxix != global.SnowWinWidth || blobals.maxiz != global.SnowWinHeight) + { + P("do_main_window\n"); + main_window(); + do_change_attr(NULL); + } + return TRUE; } static void main_window() { - globals.maxix = SnowWinWidth; - globals.maxiz = SnowWinHeight; - globals.maxiy = (globals.maxix+globals.maxiz)/2; - - P("%d %d %d\n",globals.maxix,globals.maxiy,globals.maxiz); - - globals.maxz = globals.maxx*(float)globals.maxiz/(float)globals.maxix; - globals.maxy = globals.maxx*(float)globals.maxiy/(float)globals.maxix; - globals.xc = (globals.maxx-globals.ox)/2; - globals.zc = (globals.maxz-globals.oz)/2; + blobals.maxix = global.SnowWinWidth; + blobals.maxiz = global.SnowWinHeight; + blobals.maxiy = (blobals.maxix+blobals.maxiz)/2; + + P("%d %d %d\n",blobals.maxix,blobals.maxiy,blobals.maxiz); + + blobals.maxz = blobals.maxx*(float)blobals.maxiz/(float)blobals.maxix; + blobals.maxy = blobals.maxx*(float)blobals.maxiy/(float)blobals.maxix; + blobals.xc = (blobals.maxx-blobals.ox)/2; + blobals.zc = (blobals.maxz-blobals.oz)/2; + + blobals.ax = blobals.maxix/blobals.maxx; + blobals.ay = blobals.maxiy/blobals.maxy; + blobals.az = blobals.maxiz/blobals.maxz; P("drawing window: %d %d %d %f %f %f\n", - globals.maxix, globals.maxiy, globals.maxiz, globals.maxx, globals.maxy,globals.maxz); + blobals.maxix, blobals.maxiy, blobals.maxiz, blobals.maxx, blobals.maxy,blobals.maxz); } void birds_init_color() { - if (!switches.DrawBirds) - return; int i; for (i=0; i +#define NBIRDS_MAX 1000 + extern int birds_draw(cairo_t *cr); +extern int birds_erase(int force); extern float birds_get_mean_dist(void); extern float birds_get_range(void); extern void birds_init(void); -extern int birds_ui(void); +extern void birds_ui(void); diff -Nru xsnow-3.1.1/src/blowoff.c xsnow-3.3.2/src/blowoff.c --- xsnow-3.1.1/src/blowoff.c 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/blowoff.c 2021-11-04 14:24:28.000000000 +0000 @@ -2,7 +2,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by @@ -30,72 +30,54 @@ #include "debug.h" #include "windows.h" #include "fallensnow.h" -#include "varia.h" #define NOTACTIVE \ (Flags.BirdsOnly || !WorkspaceActive()) -static float BlowOffFactor; +static int do_blowoff(void *); void blowoff_init() { - add_to_mainloop(PRIORITY_DEFAULT, time_blowoff, do_blowoff, NULL); + add_to_mainloop(PRIORITY_DEFAULT, time_blowoff, do_blowoff); } -int blowoff_ui() +void blowoff_ui() { - int changes = 0; - if(Flags.BlowOffFactor != OldFlags.BlowOffFactor) - { - OldFlags.BlowOffFactor = Flags.BlowOffFactor; - InitBlowOffFactor(); - changes++; - P("changes: %d\n",changes); - } - if(Flags.NoBlowSnow != OldFlags.NoBlowSnow) - { - OldFlags.NoBlowSnow = Flags.NoBlowSnow; - changes++; - P("changes: %d\n",changes); - } - return changes; + UIDO(BlowOffFactor , ); + UIDO(BlowSnow , ); } -void blowoff_draw(UNUSED cairo_t *cr) +void blowoff_draw() { // nothing to draw here } int BlowOff() { - float g = gaussian(BlowOffFactor,0.5*BlowOffFactor,0.0,2.0*MAXBLOWOFFFACTOR); - return lrint(g); + int r = 0.04*Flags.BlowOffFactor*drand48(); + P("Blowoff: %d\n",r); + return r; } -void InitBlowOffFactor() -{ - BlowOffFactor = 0.01*Flags.BlowOffFactor; - if (BlowOffFactor > MAXBLOWOFFFACTOR) - BlowOffFactor = MAXBLOWOFFFACTOR; -} // determine if fallensnow should be handled for fsnow -int do_blowoff(UNUSED gpointer data) +int do_blowoff(void *d) { if (Flags.Done) return FALSE; - if (NOTACTIVE || Flags.NoBlowSnow) + if (NOTACTIVE || !Flags.BlowSnow) return TRUE; - FallenSnow *fsnow = FsnowFirst; + FallenSnow *fsnow = global.FsnowFirst; while(fsnow) { P("blowoff ...\n"); if (HandleFallenSnow(fsnow) && !Flags.NoSnowFlakes) if(fsnow->win.id == 0 || (!fsnow->win.hidden && - (fsnow->win.ws == CWorkSpace || fsnow->win.sticky))) + (fsnow->win.ws == global.CWorkSpace || fsnow->win.sticky))) UpdateFallenSnowWithWind(fsnow,fsnow->w/4,fsnow->h/4); fsnow = fsnow->next; } return TRUE; + (void)d; } diff -Nru xsnow-3.1.1/src/blowoff.h xsnow-3.3.2/src/blowoff.h --- xsnow-3.1.1/src/blowoff.h 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/blowoff.h 2021-11-04 14:24:28.000000000 +0000 @@ -2,7 +2,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by @@ -19,11 +19,9 @@ #-# */ #pragma once + extern void blowoff_init(void); -extern void blowoff_draw(cairo_t *cr); -extern int blowoff_ui(void); +extern void blowoff_draw(void); +extern void blowoff_ui(void); extern int BlowOff(void); -extern void InitBlowOffFactor(void); -extern int do_blowoff(gpointer data); - diff -Nru xsnow-3.1.1/src/buttons.h xsnow-3.3.2/src/buttons.h --- xsnow-3.1.1/src/buttons.h 1970-01-01 00:00:00.000000000 +0000 +++ xsnow-3.3.2/src/buttons.h 2021-11-04 14:24:28.000000000 +0000 @@ -0,0 +1,108 @@ +/* -copyright- +#-# +#-# xsnow: let it snow on your desktop +#-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen +#-# 2019,2020,2021 Willem Vermin +#-# +#-# This program is free software: you can redistribute it and/or modify +#-# it under the terms of the GNU General Public License as published by +#-# the Free Software Foundation, either version 3 of the License, or +#-# (at your option) any later version. +#-# +#-# This program is distributed in the hope that it will be useful, +#-# but WITHOUT ANY WARRANTY; without even the implied warranty of +#-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +#-# GNU General Public License for more details. +#-# +#-# You should have received a copy of the GNU General Public License +#-# along with this program. If not, see . +#-# +*/ +#pragma once + +/* name of button will be Button.NStars + * glade: + * id will be stars-NStars + * name of call back will be button_stars_NStars + */ +#define xsnow_snow 1 +#define xsnow_santa 2 +#define xsnow_scenery 3 +#define xsnow_celestials 4 +#define xsnow_birds 5 +#define xsnow_settings 6 + +/* code type name modifier */ +#define ALL_TOGGLES \ + BUTTON(togglecode ,xsnow_birds ,BirdsOnly ,1 ) \ + BUTTON(togglecode ,xsnow_birds ,FollowSanta ,1 ) \ + BUTTON(togglecode ,xsnow_birds ,ShowAttrPoint ,1 ) \ + BUTTON(togglecode ,xsnow_birds ,ShowBirds ,1 ) \ + BUTTON(togglecode ,xsnow_settings ,AllWorkspaces ,1 ) \ + BUTTON(togglecode ,xsnow_settings ,BelowAll ,1 ) \ + BUTTON(togglecode ,xsnow_settings ,BelowConfirm ,0 ) \ + BUTTON(togglecode ,xsnow_settings ,ThemeXsnow ,1 ) \ + BUTTON(togglecode ,xsnow_celestials ,NoMeteorites ,-1 ) /*i*/ \ + BUTTON(togglecode ,xsnow_celestials ,Halo ,1 ) \ + BUTTON(togglecode ,xsnow_celestials ,Moon ,1 ) \ + BUTTON(togglecode ,xsnow_santa ,NoSanta ,-1 ) /*i*/ \ + BUTTON(togglecode ,xsnow_snow ,BlowSnow ,1 ) \ + BUTTON(togglecode ,xsnow_snow ,NoFluffy ,-1 ) /*i*/ \ + BUTTON(togglecode ,xsnow_snow ,NoKeepSBot ,-1 ) /*i*/ \ + BUTTON(togglecode ,xsnow_snow ,NoKeepSWin ,-1 ) /*i*/ \ + BUTTON(togglecode ,xsnow_snow ,NoKeepSnowOnTrees ,-1 ) /*i*/ \ + BUTTON(togglecode ,xsnow_snow ,NoSnowFlakes ,-1 ) /*i*/ \ + BUTTON(togglecode ,xsnow_celestials ,Stars ,1 ) \ + BUTTON(togglecode ,xsnow_scenery ,NoTrees ,-1 ) /*i*/ \ + BUTTON(togglecode ,xsnow_scenery ,Overlap ,1 ) \ + BUTTON(togglecode ,xsnow_celestials ,NoWind ,-1 ) /*i*/ \ + + +#define ALL_SCALES \ + BUTTON(scalecode ,xsnow_birds ,Anarchy ,1 ) \ + BUTTON(scalecode ,xsnow_birds ,AttrFactor ,1 ) \ + BUTTON(scalecode ,xsnow_birds ,BirdsScale ,1 ) \ + BUTTON(scalecode ,xsnow_birds ,BirdsSpeed ,1 ) \ + BUTTON(scalecode ,xsnow_birds ,DisWeight ,1 ) \ + BUTTON(scalecode ,xsnow_birds ,FollowWeight ,1 ) \ + BUTTON(scalecode ,xsnow_birds ,Nbirds ,1 ) \ + BUTTON(scalecode ,xsnow_birds ,Neighbours ,1 ) \ + BUTTON(scalecode ,xsnow_birds ,PrefDistance ,1 ) \ + BUTTON(scalecode ,xsnow_birds ,ViewingDistance ,1 ) \ + BUTTON(scalecode ,xsnow_settings ,CpuLoad ,1 ) \ + BUTTON(scalecode ,xsnow_settings ,OffsetS ,-1 ) /*i*/ \ + BUTTON(scalecode ,xsnow_settings ,OffsetY ,-1 ) /*i*/ \ + BUTTON(scalecode ,xsnow_settings ,Transparency ,1 ) \ + BUTTON(scalecode ,xsnow_settings ,Scale ,1 ) \ + BUTTON(scalecode ,xsnow_celestials ,HaloBright ,1 ) \ + BUTTON(scalecode ,xsnow_celestials ,MoonSize ,1 ) \ + BUTTON(scalecode ,xsnow_celestials ,MoonSpeed ,1 ) \ + BUTTON(scalecode ,xsnow_santa ,SantaSpeedFactor ,1 ) \ + BUTTON(scalecode ,xsnow_snow ,BlowOffFactor ,1 ) \ + BUTTON(scalecode ,xsnow_snow ,FlakeCountMax ,1 ) \ + BUTTON(scalecode ,xsnow_snow ,MaxOnTrees ,1 ) \ + BUTTON(scalecode ,xsnow_snow ,MaxScrSnowDepth ,1 ) \ + BUTTON(scalecode ,xsnow_snow ,MaxWinSnowDepth ,1 ) \ + BUTTON(scalecode ,xsnow_snow ,SnowFlakesFactor ,1 ) \ + BUTTON(scalecode ,xsnow_snow ,SnowSize ,1 ) \ + BUTTON(scalecode ,xsnow_snow ,SnowSpeedFactor ,1 ) \ + BUTTON(scalecode ,xsnow_celestials ,NStars ,1 ) \ + BUTTON(scalecode ,xsnow_scenery ,DesiredNumberOfTrees ,1 ) \ + BUTTON(scalecode ,xsnow_scenery ,TreeFill ,1 ) \ + BUTTON(scalecode ,xsnow_celestials ,WhirlFactor ,1 ) \ + BUTTON(scalecode ,xsnow_celestials ,WindTimer ,1 ) \ + + +#define ALL_COLORS \ + BUTTON(colorcode ,xsnow_birds ,BirdsColor ,1 ) \ + BUTTON(colorcode ,xsnow_snow ,SnowColor ,1 ) \ + BUTTON(colorcode ,xsnow_scenery ,TreeColor ,1 ) \ + + +#define BUTTON(code, type, name, m) code(type,name,m) + +#define ALL_BUTTONS \ + ALL_TOGGLES \ + ALL_SCALES \ + ALL_COLORS + diff -Nru xsnow-3.1.1/src/clientwin.c xsnow-3.3.2/src/clientwin.c --- xsnow-3.1.1/src/clientwin.c 2020-10-13 12:50:56.000000000 +0000 +++ xsnow-3.3.2/src/clientwin.c 2021-11-04 14:24:27.000000000 +0000 @@ -2,7 +2,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/clientwin.h xsnow-3.3.2/src/clientwin.h --- xsnow-3.1.1/src/clientwin.h 2020-10-13 12:50:56.000000000 +0000 +++ xsnow-3.3.2/src/clientwin.h 2021-11-04 14:24:27.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/clocks.c xsnow-3.3.2/src/clocks.c --- xsnow-3.1.1/src/clocks.c 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/clocks.c 2021-11-04 14:24:28.000000000 +0000 @@ -2,7 +2,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/clocks.h xsnow-3.3.2/src/clocks.h --- xsnow-3.1.1/src/clocks.h 2020-10-13 12:50:56.000000000 +0000 +++ xsnow-3.3.2/src/clocks.h 2021-11-04 14:24:27.000000000 +0000 @@ -2,7 +2,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by @@ -19,5 +19,6 @@ #-# */ #pragma once + extern double wallclock(void); extern double wallcl(void); diff -Nru xsnow-3.1.1/src/csvpos.c xsnow-3.3.2/src/csvpos.c --- xsnow-3.1.1/src/csvpos.c 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/csvpos.c 2021-11-04 14:24:28.000000000 +0000 @@ -2,7 +2,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/csvpos.h xsnow-3.3.2/src/csvpos.h --- xsnow-3.1.1/src/csvpos.h 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/csvpos.h 2021-11-04 14:24:28.000000000 +0000 @@ -2,7 +2,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by @@ -19,5 +19,6 @@ #-# */ #pragma once + extern void csvpos(char *s, int **k, int *n); extern void vsc(char **s, int *k, int n); diff -Nru xsnow-3.1.1/src/debug.h xsnow-3.3.2/src/debug.h --- xsnow-3.1.1/src/debug.h 2020-10-13 12:50:56.000000000 +0000 +++ xsnow-3.3.2/src/debug.h 2021-11-04 14:24:27.000000000 +0000 @@ -2,7 +2,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by @@ -19,6 +19,7 @@ #-# */ #pragma once + #include #ifdef DEBUG #define P(...) do {printf ("%s: %d: ",__FILE__,__LINE__);printf(__VA_ARGS__);fflush(stdout);}while(0) @@ -28,4 +29,3 @@ #define R(...) do {printf ("%s: %d: ",__FILE__,__LINE__);printf(__VA_ARGS__);fflush(stdout);} while(0) #define I(...) do {printf ("Xsnow info: %s: %d: ",__FILE__,__LINE__);printf(__VA_ARGS__);fflush(stdout);} while(0) -extern int counter; diff -Nru xsnow-3.1.1/src/docs.c xsnow-3.3.2/src/docs.c --- xsnow-3.1.1/src/docs.c 2020-10-13 12:50:56.000000000 +0000 +++ xsnow-3.3.2/src/docs.c 2021-11-04 14:24:27.000000000 +0000 @@ -2,7 +2,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by @@ -21,14 +21,17 @@ #include #include #include +#include #include "xsnow.h" #include "docs.h" #include "version.h" +#include "utils.h" +#include "flags.h" // return char* with all occurences of needle in s replaced with rep // s, needle, rep will not be modified static char *replace_all(const char *s, const char *needle, const char *rep); -static void manout(const char*flag, const char*txt); +static void manout(const char*flag, const char*txt, ...); static int doman; static void printdescription(void); @@ -46,6 +49,8 @@ printf("If xsnow is misbehaving, try to remove the file $HOME/.xsnowrc.\n"); } +#define F(x) DefaultFlags.x + void docs_usage(int man) { @@ -53,7 +58,7 @@ { doman = 1; printf(".\\\" DO NOT MODIFY THIS FILE! It was created by xsnow -manpage .\n"); - printf(".TH XSNOW \"6\" \"2020\" \"xsnow\\-" VERSION "\" \"User Commands\"\n"); + printf(".TH XSNOW \"6\" \"2021\" \"xsnow\\-" VERSION "\" \"User Commands\"\n"); printf(".SH NAME\n"); printf(".\\\" Turn of hyphenation:\n"); printf(".hy 0\n"); @@ -70,7 +75,7 @@ else { doman = 0; - printf("XSNOW 2019 xsnow-" VERSION " User Commands\n"); + printf("XSNOW 2021 xsnow-" VERSION " User Commands\n"); printf("NAME\n"); printf("xsnow - Snow and Santa on your desktop\n"); printf("SYNOPSIS\n"); @@ -84,37 +89,44 @@ manout(" ","Below: denotes an unsigned decimal (e.g 123)"); manout(" ","or octal (e.g. 017) or hex (e.g. 0x50009) number."); - manout(" "," denotes a color name like \"red\" or \"#123456\"."); + manout(" "," denotes a string like \"red\" or \"#123456\"."); manout(" "," "); if (!doman) printf("\n"); - manout("-h, -help" ,"print this text."); - manout("-H, -manpage" ,"print man page."); - manout("-v, -version" ,"prints version of xsnow."); - manout("-display name" ,"Drop the snowflakes on the given display."); - manout(" " ,"Make sure the display is nearby, so you can hear them enjoy..."); - manout("-vintage" ,"Run xsnow in vintage settings."); - manout("-defaults" ,"Do not read config file (see FILES)."); - manout("-noconfig" ,"Do not read or write config file (see FILES)."); - manout("-nomenu" ,"Do not show interactive menu."); - manout("-id " ,"Snow in window with id (for example from xwininfo)."); - manout("-desktop" ,"Act as if window is a desktop."); - manout("-allworkspaces " ,"0: use one desktop for snow, 1: use all desktops (default: " EQ(DEFAULT_AllWorkspaces) ")."); - manout("-fullscreen" ,"Snow on full screen window: panels, task bars etc. will be not accessible."); - manout("-above" ,"Snow above your windows. Default is to snow below your windows."); - manout(" " ,"NOTE: in some environments this results in an un-clickable desktop."); - manout("-xwininfo " ,"Use a cursor to point at the window you want the snow to be fallen in."); - manout("-bg " ,"Use color to erase obsolete drawings (snow, santa, ...)."); - manout(" " ,"Useful in for example KDE: create mono colored background, and specify"); - manout(" " ,"the same color here, e.g: -bg \"#123456\" (default: " EQ(DEFAULT_BGColor) ".)"); - manout("-exposures" ,"Use XClearArea(...,exposures=True) when erasing."); - manout("-noexposures" ,"Use XClearArea(...,exposures=False) when erasing."); - manout(" " ,"Exposures have effect with '-alpha 0' or '-xwininfo'."); - manout("-stopafter " ,"Stop xsnow after so many seconds."); - manout("-wantwindow" ,"Specify your favorite window:"); - manout(" default" ,"If possible, use GTK-Cairo window for Santa snow and scenery."); - manout(" transparent" ,"If possible, use transparent X11-window for Santa, snow and scenery."); - manout("-noisy" ,"Write extra info about some mouse clicks, X errors etc, to stdout."); + manout("-h, -help" ,"print this text."); + manout("-H, -manpage" ,"print man page."); + manout("-v, -version" ,"prints version of xsnow."); + manout("-display name" ,"Drop the snowflakes on the given display."); + manout(" " ,"Make sure the display is nearby, so you can hear them enjoy..."); + manout("-vintage" ,"Run xsnow in vintage settings."); + manout("-defaults" ,"Do not read config file (see FILES)."); + manout("-noconfig" ,"Do not read or write config file (see FILES)."); + manout("-hidemenu" ,"Start with hidden interactive menu."); + manout("-nomenu" ,"Do not start and show interactive menu."); + manout("-scale " ,"Apply scalefactor (default: %d).",F(Scale)); + manout("-doublebuffer " ,"1: use double buffering; 0: do not use double buffering (default: %d).",F(UseDouble)); + manout(" " ,"Only effective with '-root' or '-id' or '-xwininfo'."); + manout("-theme " ,"1: use xsnow theme for menu; 0: use system theme (default: %d)",F(ThemeXsnow)); + manout("-checkgtk " ,"0: Do not check gtk version before starting the user interface."); + manout(" " ,"1: Check gtk version before starting the user interface."); + manout(" " ,"(default: %d).",F(CheckGtk)); + manout("-id , -window-id " ,"Snow in window with id (for example from xwininfo)."); + manout("-desktop" ,"Act as if window is a desktop."); + manout("-allworkspaces " ,"0: use one desktop for snow, 1: use all desktops (default: %d).",F(AllWorkspaces)); + manout("-above" ,"Snow above your windows. Default is to snow below your windows."); + manout(" " ,"NOTE: in some environments this results in an un-clickable desktop."); + manout("-xwininfo " ,"Use a cursor to point at the window you want the snow to be fallen in."); + manout("-stopafter " ,"Stop xsnow after so many seconds."); + manout("-root " ,"Force to paint on (virtual) root window."); + manout("." ,"Use this for xscreensaver: in ~.xscreensaver add:"); + manout("." ," xsnow -root"); + manout("." ,"On some systems you need to add the flag -nomenu to disable the menu:"); + manout("." ," xsnow -root -nomenu"); + manout("." ,"Probably, you want to start xscreensaver as follows:"); + manout("." ," xscreensaver -no-capture-stderr"); + manout("-noisy " ,"Write extra info about some mouse clicks, X errors etc, to stdout."); + manout("-cpuload " ,"How busy is your system with xsnow:"); + manout(" " ,"the higher, the more load on the system (default: %d).",F(CpuLoad)); if(doman) { @@ -124,14 +136,16 @@ { printf("\n Snow options:\n\n"); } - manout("-snowflakes " ,"The higher, the more snowflakes are generated per second. Default: " EQ(DEFAULT_SnowFlakesFactor) "."); - manout("-noblowsnow" ,"Do not animate blowing snow from trees or windows."); - manout("-sc " ,"Use the given string as color for the flakes (default: " EQ(DEFAULT_SnowColor) ")."); - manout("-snowspeedfactor " ,"Multiply the speed of snow with this number/100 (default: " EQ(DEFAULT_SnowSpeedFactor) ")."); - manout("-snowsize " ,"Set size of (non-vintage) snow flakes (default: " EQ(DEFAULT_SnowSize) ")."); - manout("-nosnowflakes" ,"Do not show falling snowflakes. (Weird!)"); - manout("-flakecountmax " ,"Maximum number of active flakes (default: " EQ(DEFAULT_FlakeCountMax) ")."); - manout("-blowofffactor " ,"The higher, the more snow is generated in blow-off scenarios (default: " EQ(DEFAULT_BlowOffFactor) ")."); + manout("-snowflakes " ,"The higher, the more snowflakes are generated per second. Default: %d.",F(SnowFlakesFactor)); + manout("-blowsnow" ,"(Default) Animate blow-off snow."); + manout("-noblowsnow" ,"Do not animate blowing snow from trees or windows"); + manout("-sc " ,"Use the given string as color for the flakes (default: %s).",F(SnowColor)); + manout("-snowspeedfactor " ,"Multiply the speed of snow with this number/100 (default: %d).",F(SnowSpeedFactor)); + manout("-snowsize " ,"Set size of (non-vintage) snow flakes (default: %d).",F(SnowSize)); + manout("-snow " ,"(Default) Show snow."); + manout("-nosnow -nosnowflakes" ,"Do not show snow."); + manout("-flakecountmax " ,"Maximum number of active flakes (default: %d).",F(FlakeCountMax)); + manout("-blowofffactor " ,"The higher, the more snow is generated in blow-off scenarios (default: %d).",F(BlowOffFactor)); if(doman) { @@ -141,15 +155,16 @@ { printf("\n Tree options:\n\n"); } - manout("-treetype [, ...]" ,"Choose tree types: minimum 0, maximum " EQ(MAXTREETYPE) " (default: " EQ(DEFAULT_TreeType) ")."); - manout(" " ,"Thanks to Carla Vermin for numbers >=3!"); - manout(" " ,"Credits: Image by b0red on Pixabay."); - manout("-treetype all" ,"Use all available tree types."); - manout("-tc " ,"Use the given string as the color for the default trees (default: " EQ(DEFAULT_TreeColor) ")."); - manout(" " ,"Works only for treetype 0."); - manout("-notrees" ,"Do not display the trees."); - manout("-trees " ,"Desired number of trees. Default " EQ(DEFAULT_DesiredNumberOfTrees) "."); - manout("-treefill " ,"Region in percents of the height of the window where trees grow (default: " EQ(DEFAULT_TreeFill) ")."); + manout("-treetype [, ...]" ,"Choose tree types: minimum 0, maximum %d (default: %s).", MAXTREETYPE,F(TreeType)); + manout(" " ,"Thanks to Carla Vermin for numbers >=3!"); + manout(" " ,"Credits: Image by b0red on Pixabay."); + manout("-treetype all" ,"(Default) Use all non-vintage available tree types."); + manout("-tc " ,"Use the given string as the color for the vintage tree (default: %s).",F(TreeColor)); + manout(" " ,"Works only for treetype 0."); + manout("-notrees" ,"Do not display the trees."); + manout("-showtrees" ,"(Default) Display the trees."); + manout("-trees " ,"Desired number of trees. Default %d.",F(DesiredNumberOfTrees)); + manout("-treefill " ,"Region in percents of the height of the window where trees grow (default: %d).",F(TreeFill)); if(doman) { @@ -159,30 +174,43 @@ { printf("\n Santa options:\n\n"); } - manout("-nosanta" ,"Do not display Santa running all over the screen."); - manout("-norudolph" ,"No Rudolph."); - manout("-santa " ,"The minimum size of Santa is 0, the maximum size is " EQ(MAXSANTA) ". Default is " EQ(DEFAULT_SantaSize) "."); - manout(" " ,"Thanks to Thomas Linder for the (big) Santa 2!"); - manout(" " ,"Santa 3 is derived from Santa 2, and shows the required eight reindeer."); - manout(" " ,"The appearance of Santa 4 may be a surprise, thanks to Carla Vermin for this one."); - manout("-santaspeedfactor " ,"The speed Santa should not be excessive if he doesn't want to get"); - manout(" " ,"fined. The appropriate speed for the Santa chosen"); - manout(" " ,"will be multiplied by santaspeedfactor/100 (default: " EQ(DEFAULT_SantaSpeedFactor) ")."); + manout("-showsanta" ,"(Default) Display Santa running all over the screen."); + manout("-nosanta" ,"Do not display Santa running all over the screen."); + manout("-showrudolph" ,"(Default) With Rudolph."); + manout("-norudolph" ,"No Rudolph."); + manout("-santa " ,"The minimum size of Santa is 0, the maximum size is %d. Default is %d.",MAXSANTA,F(SantaSize)); + manout(" " ,"Thanks to Thomas Linder for the (big) Santa 2!"); + manout(" " ,"Santa 3 is derived from Santa 2, and shows the required eight reindeer."); + manout(" " ,"The appearance of Santa 4 may be a surprise, thanks to Carla Vermin for this one."); + manout("-santaspeedfactor " ,"The speed Santa should not be excessive if he doesn't want to get"); + manout(" " ,"fined. The appropriate speed for the Santa chosen"); + manout(" " ,"will be multiplied by santaspeedfactor/100 (default: %d).",F(SantaSpeedFactor)); if(doman) { - printf(".PP\n"); printf(".SS \"Wind options:\n"); + printf(".PP\n"); printf(".SS \"Celestial options:\n"); } else { - printf("\n Wind options:\n\n"); - } - manout("-nowind " ,"By default it gets windy now and then. If you prefer quiet weather"); - manout(" " ,"specify -nowind."); - manout("-whirlfactor " ,"This sets the whirl factor, i.e. the maximum adjustment of the"); - manout(" " ,"horizontal speed. The default value is " EQ(DEFAULT_WhirlFactor) "."); - manout("-windtimer " ,"With -windtimer you can specify how often it gets windy. It's"); - manout(" " ,"sort of a period in seconds, default value is " EQ(DEFAULT_WindTimer) "."); + printf("\n Celestial options:\n\n"); + } + manout("-wind " ,"(Default) It will get windy now and then."); + manout("-nowind " ,"By default it gets windy now and then. If you prefer quiet weather"); + manout(" " ,"specify -nowind."); + manout("-whirlfactor " ,"This sets the whirl factor, i.e. the maximum adjustment of the"); + manout(" " ,"horizontal speed. The default value is %d.",F(WhirlFactor)); + manout("-windtimer " ,"With -windtimer you can specify how often it gets windy. It's"); + manout(" " ,"sort of a period in seconds, default value is %d.",F(WindTimer)); + manout("-stars " ,"The number of stars (default: %d).",F(NStars)); + manout("-meteorites" ,"(Default) Show meteorites."); + manout("-nometeorites" ,"Do not show meteorites."); + manout("-moon " ,"1: show moon, 0: do not show moon (default: %d).",F(Moon)); + manout("." ,"Picture of moon thanks to Pedro Lasta on Unsplash."); + manout("." ,"https://unsplash.com/photos/wCujVcf0JDw"); + manout("-moonspeed " ,"Speed of moon in pixels/minute (default: %d).",F(MoonSpeed)); + manout("-moonsize " ,"Realtive size of moon (default: %d).",F(MoonSize)); + manout("-halo " ,"1: show halo around moon, 0: do not show halo (default: %d).",F(Halo)); + manout("-halobrightness " ,"Brightness of halo (default: %d).",F(HaloBright)); if(doman) { @@ -192,19 +220,24 @@ { printf("\n Fallen snow options:\n\n"); } - manout("-wsnowdepth " ,"Maximum thickness of snow on top of windows (default: " EQ(DEFAULT_MaxWinSnowDepth) ")."); - manout("-ssnowdepth " ,"Maximum thickness of snow at the bottom of the screen (default: " EQ(DEFAULT_MaxScrSnowDepth) ")."); - manout("-maxontrees " ,"Maximum number of flakes on trees. Default " EQ(DEFAULT_MaxOnTrees) "."); - manout("-nokeepsnowonwindows" ,"Do not keep snow on top of the windows."); - manout("-nokeepsnowonscreen" ,"Do not keep snow at the bottom of the screen."); - manout("-nokeepsnowontrees" ,"Do not keep snow on trees."); - manout("-nokeepsnow" ,"Do not have snow sticking anywhere."); - manout("-nofluffy" ,"Do not create fluff on fallen snow."); - manout("-offsetx " ,"Correction for window-manager provided of x-coordinate of window. Default " EQ(DEFAULT_OffsetX) "."); - manout("-offsety " ,"Correction for window-managr provided of y-coordinate of window. Default " EQ(DEFAULT_OffsetY) "."); - manout("-offsetw " ,"Correction for window-manager provided width of window. Default " EQ(DEFAULT_OffsetW) "."); - manout("-offsets " ,"Correction for bottom coordinate of your screen. A negative value lifts"); - manout(" " ,"the xsnow screen up. Default " EQ(DEFAULT_OffsetS) "."); + manout("-wsnowdepth " ,"Maximum thickness of snow on top of windows (default: %d).",F(MaxWinSnowDepth)); + manout("-ssnowdepth " ,"Maximum thickness of snow at the bottom of the screen (default: %d).",F(MaxScrSnowDepth)); + manout("-maxontrees " ,"Maximum number of flakes on trees. Default %d.",F(MaxOnTrees)); + manout("-keepsnowonwindows" ,"(Default) Keep snow on top of the windows."); + manout("-nokeepsnowonwindows" ,"Do not keep snow on top of the windows."); + manout("-keepsnowonscreen" ,"(Default) Keep snow at the bottom of the screen."); + manout("-nokeepsnowonscreen" ,"Do not keep snow at the bottom of the screen."); + manout("-keepsnowontrees" ,"(Default) Keep snow on trees."); + manout("-nokeepsnowontrees" ,"Do not keep snow on trees."); + manout("-keepsnow" ,"(Default) Have snow sticking anywhere."); + manout("-nokeepsnow" ,"Do not have snow sticking anywhere."); + manout("-fluffy" ,"(Default) Create fluff on fallen snow."); + manout("-nofluffy" ,"Do not create fluff on fallen snow."); + manout("-offsetx " ,"Correction for window-manager provided x-coordinate of window. Default %d.",F(OffsetX)); + manout("-offsety " ,"Correction for window-manager provided y-coordinate of window. Default %d.",F(OffsetY)); + manout("-offsetw " ,"Correction for window-manager provided width of window. Default %d.",F(OffsetW)); + manout("-offsets " ,"Correction for bottom coordinate of your screen. A negative value lifts"); + manout(" " ,"the xsnow screen up. Default %d.",F(OffsetS)); if(doman) { @@ -214,33 +247,21 @@ { printf("\n Birds options:\n\n"); } - manout("-anarchy " ,"Anarchy factor ( 0..100 default: " EQ(DEFAULT_Anarchy) ")."); - manout("-birdscolor " ,"Use the given string as color for the birds (default: " EQ(DEFAULT_BirdsColor) ")."); - manout("-birdsonly " ,"Show only birds ( 0/1 default: " EQ(DEFAULT_BirdsOnly) ")."); - manout("-birdsspeed " ,"Speed of birds ( 0..300 default: " EQ(DEFAULT_BirdsSpeed) ")."); - manout("-disweight " ,"Eagerness to keep desired distance ( 0..100 default: " EQ(DEFAULT_DisWeight) ")."); - manout("-focuscentre " ,"Eagerness to fly to the focus ( 0..300 default: " EQ(DEFAULT_AttrFactor) ")."); - manout("-followneighbours " ,"Eagerness to follow neighbours ( 0..100 default: " EQ(DEFAULT_FollowWeight) ")."); - manout("-nbirds " ,"Number of birds ( 0..400 default: " EQ(DEFAULT_Nbirds) ")."); - manout("-neighbours " ,"Number of neighbours to watch ( 0..20 default: " EQ(DEFAULT_Neighbours) ")."); - manout("-prefdistance " ,"Preferred distance to neighbours ( 0..100 default: " EQ(DEFAULT_PrefDistance) ")."); - manout("-showbirds " ,"Show birds ( 0/1 default: " EQ(DEFAULT_ShowBirds) ")."); - manout("-showattr " ,"Show attraction point ( 0/1 default: " EQ(DEFAULT_ShowAttrPoint) ")."); - manout("-followsanta " ,"Birds like Santa ( 0/1 default: " EQ(DEFAULT_FollowSanta) ")."); - manout("-viewingdistance " ,"Viewing distance ( 0..95 default: " EQ(DEFAULT_ViewingDistance) ")."); + manout("-anarchy " ,"Anarchy factor ( 0..100 default: %d).",F(Anarchy)); + manout("-birdscolor " ,"Use the given string as color for the birds (default: %s).",F(BirdsColor)); + manout("-birdsonly " ,"Show only birds ( 0/1 default: %d).",F(BirdsOnly)); + manout("-birdsspeed " ,"Speed of birds ( 0..300 default: %d).",F(BirdsSpeed)); + manout("-disweight " ,"Eagerness to keep desired distance ( 0..100 default: %d).",F(DisWeight)); + manout("-focuscentre " ,"Eagerness to fly to the focus ( 0..300 default: %d).",F(AttrFactor)); + manout("-followneighbours " ,"Eagerness to follow neighbours ( 0..100 default: %d).",F(FollowWeight)); + manout("-nbirds " ,"Number of birds ( 0..400 default: %d).",F(Nbirds)); + manout("-neighbours " ,"Number of neighbours to watch ( 0..20 default: %d).",F(Neighbours)); + manout("-prefdistance " ,"Preferred distance to neighbours ( 0..100 default: %d).",F(PrefDistance)); + manout("-showbirds " ,"Show birds ( 0/1 default: %d).",F(ShowBirds)); + manout("-showattr " ,"Show attraction point ( 0/1 default: %d).",F(ShowAttrPoint)); + manout("-followsanta " ,"Birds like Santa ( 0/1 default: %d).",F(FollowSanta)); + manout("-viewingdistance " ,"Viewing distance ( 0..95 default: %d).",F(ViewingDistance)); - if(doman) - { - printf(".PP\n"); printf(".SS \"Other options:\n"); - } - else - { - printf("\n Other options:\n\n"); - } - manout("-stars " ,"The number of stars (default: " EQ(DEFAULT_NStars) ")."); - manout("-nometeorites" ,"Do not show meteorites."); - manout("-cpuload " ,"How busy is your system with xsnow:"); - manout(" " ,"the higher, the more load on the system (default: " EQ(DEFAULT_CpuLoad) ")."); if(doman) { @@ -253,14 +274,21 @@ } manout("$HOME/.xsnowrc", "Settings are read from and written to this file."); manout(" ","See flags -noconfig and -defaults how to influence this behaviour."); - manout (" "," "); + manout("."," NOTE: the following settings are not read or written:"); + manout("."," -above -defaults -desktop -fullscreen -noconfig -id"); + manout("."," -nomenu -stopafter -xwininfo -display -noisy -checkgtk"); + manout(" "," "); manout("$HOME/xsnow/pixmaps/tree.xpm", "If present, xsnow will try this file for displaying"); manout(" ", "the trees. The format must be xpm (X PixMap) format, see"); manout(" ", "https://en.wikipedia.org/wiki/X_PixMap ."); + manout(".", " NOTE: when this file is present, no menu will appear."); + manout(" "," "); manout("$HOME/xsnow/pixmaps/santa.xpm", "where = 1,2,3,4."); manout(" ", "If present, xsnow will try this files (4 of them) for displaying"); manout(" ", "Santa. The format must be xpm (X PixMap) format, see"); manout(" ", "https://en.wikipedia.org/wiki/X_PixMap ."); + manout(".", " NOTE: when these files are present, no menu will appear."); + manout(" "," "); if(doman) { @@ -271,9 +299,9 @@ { printf("\n EXAMPLES\n\n"); } - manout("."," $ xsnow -defaults # run with defaults."); - manout("."," $ xsnow # run using values from the config file."); - manout("."," $ xsnow -treetype 1,2 # use tree types 1 and 2."); + manout ("."," $ xsnow -defaults # run with defaults."); + manout ("."," $ xsnow # run using values from the config file."); + manout ("."," $ xsnow -treetype 1,2 # use tree types 1 and 2."); if(doman) { @@ -285,19 +313,23 @@ printf("\n BUGS\n\n"); } manout(".","- Xsnow needs a complete rewrite: the code is a mess."); + manout(".","- The flags are not consistent, caused by trying to be"); + manout(" "," compatible with older versions."); manout(".","- Xsnow stresses the Xserver too much."); manout(".","- Xsnow does run in Wayland, but will not snow on all windows."); + manout(".","- Xsnow tries to create a click-through window. This is not successful"); + manout(" "," in for example FVWM/xcompmgr. In that case, xsnow tries to keep"); + manout(" "," the snow window below all others, resulting in a transient effect"); + manout(" "," when you click on the desktop. Sadly, no FVWM menu will appear..."); manout(".","- Remnants of fluffy snow can persist after removing the"); - manout(" "," fallen snow. These will gradually disappear, so no big deal."); + manout(" "," fallen snow. These will gradually disappear, so no big deal."); + manout(".","- Remnants of meteorites can persist after passage of Santa."); + manout(" "," These will eventually be wiped out by snow or Santa."); manout(".","- Xsnow tries to adapt its snowing window if the display"); - manout(" "," settings are changed while xsnow is running."); - manout(" "," This does not function always well."); - manout(".","- In some combinations of display managers and compositors"); - manout(" "," the desktop is visible, but unclickable."); - manout(" "," Known example is FVWM in combination with xcompmgr or compton."); - manout(" "," Solution: xsnow -xwininfo, and click on the desktop."); - manout(" "," This will result in stuttering Santa and snow flakes."); - manout(" "," In FVWM, for xsnow it is better to run without compositor."); + manout(" "," settings are changed while xsnow is running."); + manout(" "," This does not function always well."); + manout(".","- In multi-screen environments, it depends on the display settings"); + manout(" "," if it is snowing on all screens. Experiment!"); if(doman) { @@ -345,21 +377,34 @@ // otherwize : skip to new paragraph and use bold format // txt: Line to output // -void manout(const char*flag, const char*txt) +void manout(const char*flag, const char*txt, ...) { + va_list args; + va_start(args,txt); if (doman) { char *mantxt = replace_all(txt, "-","\\-"); char *manflag = replace_all(flag,"-","\\-"); if (!strcmp(manflag," ")) - printf("%s\n",mantxt); + { + //printf("%s\n",mantxt); + vprintf(mantxt,args); + printf("\n"); + } else if(!strcmp(manflag,".")) - printf(".br\n%s\n",mantxt); + { + //printf(".br\n%s\n",mantxt); + printf(".br\n"); + vprintf(mantxt,args); + printf("\n"); + } else { printf(".TP\n"); printf("\\fB%s\\fR\n",manflag); - printf("%s\n",mantxt); + //printf("%s\n",mantxt); + vprintf(mantxt,args); + printf("\n"); } free(mantxt); free(manflag); @@ -367,11 +412,26 @@ else { if (!strcmp(flag," ")) - printf("\t\t %s\n",txt); + { + //printf("\t\t %s\n",txt); + printf("\t\t "); + vprintf(txt,args); + printf("\n"); + } else if(!strcmp(flag,".")) - printf("%s\n",txt); + { + //printf("\t\t %s\n",txt); + printf("\t\t "); + vprintf(txt,args); + printf("\n"); + } else - printf("%s\t: %s\n",flag,txt); + { + //printf("%s\t: %s\n",flag,txt); + printf("%s\t: ",flag); + vprintf(txt,args); + printf("\n"); + } } } diff -Nru xsnow-3.1.1/src/docs.h xsnow-3.3.2/src/docs.h --- xsnow-3.1.1/src/docs.h 2020-10-13 12:50:56.000000000 +0000 +++ xsnow-3.3.2/src/docs.h 2021-11-04 14:24:27.000000000 +0000 @@ -2,7 +2,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/doitb.h xsnow-3.3.2/src/doitb.h --- xsnow-3.1.1/src/doitb.h 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/doitb.h 2021-11-04 14:24:28.000000000 +0000 @@ -2,7 +2,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by @@ -19,6 +19,7 @@ #-# */ #pragma once + #define DOITALLB() //DOITB(prefdistance ,float) /* [meter] preferred distance */ diff -Nru xsnow-3.1.1/src/doit.h xsnow-3.3.2/src/doit.h --- xsnow-3.1.1/src/doit.h 2020-10-13 12:50:56.000000000 +0000 +++ xsnow-3.3.2/src/doit.h 2021-11-04 14:24:27.000000000 +0000 @@ -2,7 +2,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by @@ -19,90 +19,104 @@ #-# */ #pragma once + // calls macro's for elements of FLAGS // DOIT_I is for x that should be output as 1234 // DOIT_S is for x that is a char* // DOIT_L is for x that should be output as 0x123456 +// parameters are: name, default value, vintage value // these flags are not written to the config file and // are no part of the ui (except BelowAll) #define DOITALL \ - DOIT_I(BelowAll) \ - DOIT_I(Defaults) \ - DOIT_I(Desktop) \ - DOIT_I(NoConfig) \ - DOIT_I(NoMenu) \ - DOIT_I(StopAfter) \ - DOIT_I(Done) \ - DOIT_I(WindNow) \ - DOIT_I(XWinInfoHandling) \ - DOIT_L(WindowId) \ - DOIT_I(Noisy) \ + DOIT_I(BelowAll ,1 ,1 ) \ + DOIT_I(BelowConfirm ,0 ,0 ) /*not a button or parameter */ \ + DOIT_I(Changes ,0 ,0 ) /* not a parameter or button */ \ + DOIT_I(CheckGtk ,1 ,1 ) \ + DOIT_I(Defaults ,0 ,0 ) \ + DOIT_I(Desktop ,0 ,0 ) \ + DOIT_I(Done ,0 ,0 ) \ + DOIT_I(ForceRoot ,0 ,0 ) \ + DOIT_I(FullScreen ,0 ,0 ) \ + DOIT_I(HideMenu ,0 ,0 ) \ + DOIT_I(NoConfig ,0 ,0 ) \ + DOIT_I(NoMenu ,0 ,0 ) \ + DOIT_I(Noisy ,0 ,0 ) \ + DOIT_I(StopAfter ,-1 ,-1) \ + DOIT_I(UseDouble ,1 ,1 ) \ + DOIT_I(WindNow ,0 ,0 ) \ + DOIT_I(XWinInfoHandling ,0 ,0 ) \ + DOIT_L(WindowId ,0 ,0 ) \ + DOIT_S(DisplayName ,"" ,"") \ DOIT // following flags are written to the config file and // are part of the ui #define DOIT \ - DOIT_I(AllWorkspaces) \ - DOIT_I(BlowOffFactor) \ - DOIT_I(CpuLoad) \ - DOIT_I(Transparency) \ - DOIT_I(DesiredNumberOfTrees) \ - DOIT_I(Exposures) \ - DOIT_I(FlakeCountMax) \ - DOIT_I(FullScreen) \ - DOIT_I(MaxOnTrees) \ - DOIT_I(MaxScrSnowDepth) \ - DOIT_I(MaxWinSnowDepth) \ - DOIT_I(NoBlowSnow) \ - DOIT_I(NoFluffy) \ - DOIT_I(NoKeepSBot) \ - DOIT_I(NoKeepSnow) \ - DOIT_I(NoKeepSnowOnTrees) \ - DOIT_I(NoKeepSWin) \ - DOIT_I(NoMeteorites) \ - DOIT_I(NoRudolf) \ - DOIT_I(NoSanta) \ - DOIT_I(NoSnowFlakes) \ - DOIT_I(NoTrees) \ - DOIT_I(NoWind) \ - DOIT_I(NStars) \ - DOIT_I(OffsetS) \ - DOIT_I(OffsetW) \ - DOIT_I(OffsetX) \ - DOIT_I(OffsetY) \ - DOIT_I(SantaSize) \ - DOIT_I(SantaSpeedFactor) \ - DOIT_I(SnowFlakesFactor) \ - DOIT_I(SnowSize) \ - DOIT_I(SnowSpeedFactor) \ - DOIT_I(TreeFill) \ - DOIT_I(UseBG) \ - DOIT_I(WantWindow) \ - DOIT_I(WhirlFactor) \ - DOIT_I(WindTimer) \ + DOIT_I(AllWorkspaces ,1 ,1 ) \ + DOIT_I(BlowOffFactor ,40 ,40 ) \ + DOIT_I(BlowSnow ,1 ,0 ) \ + DOIT_I(CpuLoad ,100 ,100 ) \ + DOIT_I(Transparency ,0 ,0 ) \ + DOIT_I(Scale ,100 ,100 ) \ + DOIT_I(DesiredNumberOfTrees ,10 ,6 ) \ + DOIT_I(FlakeCountMax ,300 ,300 ) \ + DOIT_I(Halo ,1 ,1 ) \ + DOIT_I(HaloBright ,25 ,25 ) \ + DOIT_I(MaxOnTrees ,200 ,200 ) \ + DOIT_I(MaxScrSnowDepth ,50 ,50 ) \ + DOIT_I(MaxWinSnowDepth ,30 ,30 ) \ + DOIT_I(Moon ,1 ,0 ) \ + DOIT_I(MoonSpeed ,120 ,120 ) \ + DOIT_I(MoonSize ,100 ,100 ) \ + DOIT_I(NoFluffy ,0 ,0 ) \ + DOIT_I(NoKeepSBot ,0 ,0 ) \ + DOIT_I(NoKeepSnow ,0 ,0 ) \ + DOIT_I(NoKeepSnowOnTrees ,0 ,1 ) \ + DOIT_I(NoKeepSWin ,0 ,0 ) \ + DOIT_I(NoMeteorites ,0 ,1 ) \ + DOIT_I(NoSanta ,0 ,0 ) \ + DOIT_I(NoSnowFlakes ,0 ,0 ) \ + DOIT_I(NoTrees ,0 ,0 ) \ + DOIT_I(NoWind ,0 ,0 ) \ + DOIT_I(NStars ,20 ,0 ) \ + DOIT_I(OffsetS ,0 ,0 ) \ + DOIT_I(OffsetW ,-8 ,-8 ) \ + DOIT_I(OffsetX ,4 ,4 ) \ + DOIT_I(OffsetY ,0 ,0 ) \ + DOIT_I(Overlap ,1 ,0 ) \ + DOIT_I(Rudolf ,1 ,1 ) \ + DOIT_I(SantaSize ,3 ,2 ) \ + DOIT_I(SantaSpeedFactor ,100 ,100 ) \ + DOIT_I(SnowFlakesFactor ,100 ,15 ) \ + DOIT_I(SnowSize ,8 ,8 ) \ + DOIT_I(SnowSpeedFactor ,100 ,100 ) \ + DOIT_I(Stars ,1 ,0 ) \ + DOIT_I(ThemeXsnow ,1 ,1 ) \ + DOIT_I(TreeFill ,30 ,30 ) \ + DOIT_I(VintageFlakes ,0 ,1 ) /* internal flag */\ + DOIT_I(WhirlFactor ,100 ,100 ) \ + DOIT_I(WindTimer ,30 ,30 ) \ \ - DOIT_S(BGColor) \ - DOIT_S(DisplayName) \ - DOIT_S(SnowColor) \ - DOIT_S(TreeColor) \ - DOIT_S(TreeType) \ + DOIT_S(SnowColor ,"snow" ,"snow" ) \ + DOIT_S(TreeColor ,"chartreuse" ,"chartreuse") \ + DOIT_S(TreeType ,"1,2,3,4,5,6,7," ,"0," ) \ \ - DOIT_I(Anarchy) \ - DOIT_I(AttrFactor) \ - DOIT_I(BirdsOnly) \ - DOIT_I(BirdsRestart) \ - DOIT_I(BirdsScale) \ - DOIT_I(BirdsSpeed) \ - DOIT_I(DisWeight) \ - DOIT_I(FollowWeight) \ - DOIT_I(FollowSanta) \ - DOIT_I(Nbirds) \ - DOIT_I(Neighbours) \ - DOIT_I(PrefDistance) \ - DOIT_I(ShowAttrPoint) \ - DOIT_I(ShowBirds) \ - DOIT_I(ViewingDistance) \ + DOIT_I(Anarchy ,50 ,50 ) \ + DOIT_I(AttrFactor ,100 ,100) \ + DOIT_I(BirdsOnly ,0 ,0 ) \ + DOIT_I(BirdsRestart ,0 ,0 ) \ + DOIT_I(BirdsScale ,100 ,100) \ + DOIT_I(BirdsSpeed ,100 ,100) \ + DOIT_I(DisWeight ,20 ,20 ) \ + DOIT_I(FollowWeight ,30 ,30 ) \ + DOIT_I(FollowSanta ,0 ,0 ) \ + DOIT_I(Nbirds ,70 ,70 ) \ + DOIT_I(Neighbours ,7 ,7 ) \ + DOIT_I(PrefDistance ,40 ,40 ) \ + DOIT_I(ShowAttrPoint ,0 ,0 ) \ + DOIT_I(ShowBirds ,1 ,0 ) \ + DOIT_I(ViewingDistance ,40 ,40 ) \ \ - DOIT_S(BirdsColor) + DOIT_S(BirdsColor ,"#361A07" ,"#361A07") diff -Nru xsnow-3.1.1/src/dsimple.c xsnow-3.3.2/src/dsimple.c --- xsnow-3.1.1/src/dsimple.c 2020-10-13 12:50:56.000000000 +0000 +++ xsnow-3.3.2/src/dsimple.c 2021-11-04 14:24:27.000000000 +0000 @@ -2,7 +2,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by @@ -47,7 +47,6 @@ */ -static int screen = 0; #include #include #include @@ -55,6 +54,8 @@ #include #include #include + +#include "vroot.h" /* * Other_stuff.h: Definitions of routines in other_stuff. * @@ -64,6 +65,14 @@ #include "clientwin.h" #include "dsimple.h" +static int screen = 0; +static Display *dpy = NULL; +static void Fatal_Error(const char *, ...) _X_NORETURN _X_ATTRIBUTE_PRINTF(1,2); + +static char *Get_Display_Name(int *, char **); +static Display *Open_Display(const char *); +static void Close_Display(void); + // added: static void usage() { @@ -83,8 +92,7 @@ /* This stuff is defined in the calling program by just_display.h */ -const char *program_name = "unknown_program"; -Display *dpy = NULL; +const char *program_name = "xsnow"; /* * Get_Display_Name (argc, argv) Look for -display, -d, or host:dpy (obselete) diff -Nru xsnow-3.1.1/src/dsimple.h xsnow-3.3.2/src/dsimple.h --- xsnow-3.1.1/src/dsimple.h 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/dsimple.h 2021-11-04 14:24:28.000000000 +0000 @@ -2,7 +2,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by @@ -59,36 +59,6 @@ */ #pragma once - /* Simple helper macros */ -#ifndef MAX -#define MAX(a,b) (((a)>(b))?(a):(b)) -#endif /* MAX */ -#ifndef MIN -#define MIN(a,b) (((a)<(b))?(a):(b)) -#endif /* MIN */ - - /* Global variables used by routines in just_display.c */ - -extern const char *program_name; /* Name of this program */ -extern Display *dpy; /* The current display */ -extern int screen; /* The current screen */ - -#define INIT_NAME program_name=argv[0] /* use this in main to setup - program_name */ - - /* Declarations for functions in just_display.c */ - -char *Get_Display_Name(int *, char **); -Display *Open_Display(const char *); -void Setup_Display_And_Screen(int *, char **); -void Close_Display(void); -XFontStruct *Open_Font(const char *); -Window Select_Window_Args(int *, char **); -// removed: -// void usage(void) _X_NORETURN; - -#define X_USAGE "[host:display]" /* X arguments handled by - Get_Display_Name */ /* * Other_stuff.h: Definitions of routines in other_stuff. @@ -98,7 +68,6 @@ * Send bugs, etc. to chariot@athena.mit.edu. */ -Window Select_Window(Display *, int descend); -Window Window_With_Name(Display *, Window, const char *); +extern Window Select_Window(Display *, int descend); +extern Window Window_With_Name(Display *, Window, const char *); -void Fatal_Error(const char *, ...) _X_NORETURN _X_ATTRIBUTE_PRINTF(1,2); diff -Nru xsnow-3.1.1/src/fallensnow.c xsnow-3.3.2/src/fallensnow.c --- xsnow-3.1.1/src/fallensnow.c 2020-10-13 12:50:56.000000000 +0000 +++ xsnow-3.3.2/src/fallensnow.c 2021-11-04 14:24:27.000000000 +0000 @@ -2,7 +2,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by @@ -18,6 +18,9 @@ #-# along with this program. If not, see . #-# */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif #include #include #include @@ -33,96 +36,85 @@ #include "blowoff.h" #include "wind.h" #include "debug.h" -#include "varia.h" #define NOTACTIVE \ (Flags.BirdsOnly || !WorkspaceActive() || Flags.NoSnowFlakes) -int MaxScrSnowDepth = 0; -FallenSnow *FsnowFirst = NULL; -static GC EFallenGC; -static GC FallenGC; static void drawquartcircle(int n, short int *y); // nb: dimension of y > n+1 static void CreateSurfaceFromFallen(FallenSnow *f); -static Pixmap CreatePixmapFromFallen(FallenSnow *f); static void EraseFallenPixel(FallenSnow *fsnow,int x); void fallensnow_init() { InitFallenSnow(); - P(" "); - FallenGC = XCreateGC(display, SnowWin, 0, NULL); - EFallenGC = XCreateGC(display, SnowWin, 0, NULL); // used to erase fallen snow + P(" \n"); } -void fallensnow_set_gc() +void UpdateFallenSnowAtBottom() { - XSetLineAttributes(display, FallenGC, 1, LineSolid,CapRound,JoinMiter); - XSetFillStyle( display, EFallenGC, FillSolid); - XSetFunction( display, EFallenGC, GXcopy); - XSetForeground(display, EFallenGC, ErasePixel); + FallenSnow *fsnow = FindFallen(global.FsnowFirst, 0); + if (fsnow) + fsnow->y = global.SnowWinHeight; } void fallensnow_draw(cairo_t *cr) { if (NOTACTIVE) return; - FallenSnow *fsnow = FsnowFirst; + FallenSnow *fsnow = global.FsnowFirst; while(fsnow) { if (HandleFallenSnow(fsnow)) { - P("fallensnow_draw %d\n", + P("fallensnow_draw %d %d\n",counter++, cairo_image_surface_get_width(fsnow->surface)); + P("fallensnow_draw: x:%d y:%d\n",fsnow->x,fsnow->y); cairo_set_source_surface (cr, fsnow->surface, fsnow->x, fsnow->y-fsnow->h+1); my_cairo_paint_with_alpha(cr,ALPHA); + fsnow->prevx = fsnow->x; + fsnow->prevy = fsnow->y-fsnow->h+1; + fsnow->prevw = cairo_image_surface_get_width(fsnow->surface); + fsnow->prevh = fsnow->h; } fsnow = fsnow->next; } } -int fallensnow_ui() +void fallensnow_erase() { - int changes = 0; - if(Flags.MaxWinSnowDepth != OldFlags.MaxWinSnowDepth) - { - OldFlags.MaxWinSnowDepth = Flags.MaxWinSnowDepth; - InitFallenSnow(); - ClearScreen(); - changes++; - P("changes: %d\n",changes); - } - if(Flags.MaxScrSnowDepth != OldFlags.MaxScrSnowDepth) - { - OldFlags.MaxScrSnowDepth = Flags.MaxScrSnowDepth; - SetMaxScreenSnowDepth(); - InitFallenSnow(); - ClearScreen(); - changes++; - P("changes: %d\n",changes); - } - if(Flags.NoKeepSBot != OldFlags.NoKeepSBot) - { - OldFlags.NoKeepSBot = Flags.NoKeepSBot; - InitFallenSnow(); - ClearScreen(); - changes++; - P("changes: %d\n",changes); - } - if(Flags.NoKeepSWin != OldFlags.NoKeepSWin) + if (NOTACTIVE) + return; + FallenSnow *fsnow = global.FsnowFirst; + while(fsnow) { - OldFlags.NoKeepSWin = Flags.NoKeepSWin; - InitFallenSnow(); - ClearScreen(); - changes++; - P("changes: %d\n",changes); + if (HandleFallenSnow(fsnow)) + { + P("fallensnow_erase %d %d %d %d %d\n",counter++, + fsnow->prevx, fsnow->prevy, fsnow->prevw, fsnow->prevh); + + myXClearArea(global.display,global.SnowWin, + fsnow->prevx, fsnow->prevy, fsnow->prevw, fsnow->prevh, global.xxposures); + } + fsnow = fsnow->next; } - return changes; + } -int do_fallen(UNUSED gpointer data) +void fallensnow_ui() +{ + UIDO(MaxWinSnowDepth , InitFallenSnow(); ClearScreen(); ); + UIDO(MaxScrSnowDepth , + SetMaxScreenSnowDepth(); + InitFallenSnow(); + ClearScreen(); + ); + UIDO(NoKeepSBot , InitFallenSnow(); ClearScreen(); ); + UIDO(NoKeepSWin , InitFallenSnow(); ClearScreen(); ); +} + +int do_fallen(void *d) { if (Flags.Done) @@ -130,15 +122,16 @@ if (NOTACTIVE) return TRUE; - FallenSnow *fsnow = FsnowFirst; + FallenSnow *fsnow = global.FsnowFirst; while(fsnow) { if (HandleFallenSnow(fsnow)) DrawFallen(fsnow); fsnow = fsnow->next; } - XFlush(display); + XFlush(global.display); return TRUE; + (void)d; } void drawquartcircle(int n, short int *y) // nb: dimension of y > n+1 @@ -158,10 +151,13 @@ p->y = y; p->w = w; p->h = h; + p->prevx = 0; + p->prevy = 0; + p->prevw = 10; + p->prevh = 10; p->w8 = ((w-1)/8+1)*8; p->acth = (short int *)malloc(sizeof(*(p->acth))*w); p->desh = (short int *)malloc(sizeof(*(p->desh))*w); - p->clean = 0; p->surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32,w,h); cairo_t *cr = cairo_create(p->surface); @@ -209,6 +205,7 @@ // remove by id int RemoveFallenSnow(FallenSnow **list, Window id) { + P("RemoveFallenSnow\n"); if (*list == NULL) return 0; @@ -268,75 +265,41 @@ int i; for(i=0; iw; i++) sumact += fallen->acth[i]; - printf("id:%#10lx ws:%4d x:%6d y:%6d w:%6d cln:%2d sty:%2d hid:%2d sum:%8d\n", fallen->win.id, fallen->win.ws, - fallen->x, fallen->y, fallen->w, fallen->clean, fallen->win.sticky, fallen->win.hidden, sumact); + printf("id:%#10lx ws:%4d x:%6d y:%6d w:%6d sty:%2d hid:%2d sum:%8d\n", fallen->win.id, fallen->win.ws, + fallen->x, fallen->y, fallen->w, fallen->win.sticky, fallen->win.hidden, sumact); fallen = fallen->next; } } void CleanFallenArea(FallenSnow *fsnow,int xstart,int w) { - if(switches.UseGtk) + if(global.IsDouble) return; - if(fsnow->clean) - return; - int x = fsnow->x; - int y = fsnow->y - fsnow->h; - if(switches.Trans|Flags.UseBG) - XFillRectangle(display, SnowWin, EFallenGC, x+xstart,y, - w, fsnow->h+MaxSnowFlakeHeight); - else - XClearArea(display, SnowWin, x+xstart, y, w, fsnow->h+MaxSnowFlakeHeight, switches.Exposures); - if(xstart <= 0 && w >= fsnow->w) - fsnow->clean = 1; + P("CleanFallenArea %d %d\n",counter++,global.IsDouble); + int x = fsnow->prevx; + int y = fsnow->prevy; + myXClearArea(global.display, global.SnowWin, x+xstart, y, w, fsnow->h+global.MaxSnowFlakeHeight, global.xxposures); } // clean area for fallensnow with id void CleanFallen(Window id) { - FallenSnow *fsnow = FsnowFirst; + P("CleanFallen %#lx\n",id); + FallenSnow *fsnow = global.FsnowFirst; // search the id while(fsnow) { if(fsnow->win.id == id) { CleanFallenArea(fsnow,0,fsnow->w); + //myXClearArea(global.display,global.SnowWin, + // fsnow->prevx, fsnow->prevy, fsnow->prevw, fsnow->prevh, global.xxposures); break; } fsnow = fsnow->next; } } -Pixmap CreatePixmapFromFallen(FallenSnow *f) -{ - // todo: takes too much cpu - int j; - int p = 0; - unsigned char *bitmap = (unsigned char *) alloca((f->w8*f->h/8)*sizeof(unsigned char)); - - for (j=0; jh; j++) - { - int i; - for (i=0; iw8; i+=8) - { - int b = 0; - int m = 1; - int k; - int kmax = i+8; - if (kmax > f->w) kmax = f->w; - for (k=i; kacth[k] >= f->h-j) - b |= m; - m <<= 1; - } - bitmap[p++] = b; - } - } - Pixmap pixmap = XCreateBitmapFromData(display, SnowWin, (char *)bitmap, f->w, f->h); - return pixmap; -} - void CreateSurfaceFromFallen(FallenSnow *f) { P("createsurface %#10lx %d %d %d %d %d %d\n",f->id,f->x,f->y,f->w,f->h, @@ -369,62 +332,44 @@ void DrawFallen(FallenSnow *fsnow) { - if(!fsnow->clean) - if(fsnow->win.id == 0 || (!fsnow->win.hidden && - (fsnow->win.ws == CWorkSpace || fsnow->win.sticky))) + if(fsnow->win.id == 0 || (!fsnow->win.hidden && + (fsnow->win.ws == global.CWorkSpace || fsnow->win.sticky))) + { + // do not interfere with Santa + if(!Flags.NoSanta) { - // do not interfere with Santa - if(!Flags.NoSanta) + int in = XRectInRegion(global.SantaPlowRegion, fsnow->x, fsnow->y - fsnow->h, + fsnow->w, fsnow->h); + if (in == RectangleIn || in == RectanglePart) { - int in = XRectInRegion(SantaPlowRegion, fsnow->x, fsnow->y - fsnow->h, - fsnow->w, fsnow->h); - if (in == RectangleIn || in == RectanglePart) - { - // determine front of Santa in fsnow - int xfront = SantaX+SantaWidth - fsnow->x; - // determine back of Santa in fsnow, Santa can move backwards in strong wind - int xback = xfront - SantaWidth; - const int clearing = 1; - float vy = -1.5*ActualSantaSpeed; - if(vy > 0) vy = -vy; - if (vy < -100.0) - vy = -100; - if (ActualSantaSpeed > 0) - GenerateFlakesFromFallen(fsnow,xfront,clearing,vy); - CleanFallenArea(fsnow,xback-clearing,SantaWidth+2*clearing); - int i; - for (i=0; iw; i++) - if (i < xfront+clearing && i>=xback-clearing) - fsnow->acth[i] = 0; - XFlush(display); - } - } - if(switches.UseGtk) - { - CreateSurfaceFromFallen(fsnow); - // drawing is handled in fallensnow-draw - } - else - { - Pixmap pixmap = CreatePixmapFromFallen(fsnow); - XSetStipple(display, FallenGC, pixmap); - XFreePixmap(display,pixmap); - int x = fsnow->x; - int y = fsnow->y - fsnow->h; - XSetFillStyle( display, FallenGC, FillStippled); - XSetFunction( display, FallenGC, GXcopy); - XSetForeground(display, FallenGC, SnowcPix); - XSetTSOrigin( display, FallenGC, x+fsnow->w, y+fsnow->h); - XFillRectangle(display, SnowWin, FallenGC, x,y, fsnow->w, fsnow->h); - P("Fallensnow %d %d %d %d\n",x,y,fsnow->w,fsnow->h); + // determine front of Santa in fsnow + int xfront = global.SantaX+global.SantaWidth - fsnow->x; + // determine back of Santa in fsnow, Santa can move backwards in strong wind + int xback = xfront - global.SantaWidth; + const int clearing = 1; + float vy = -1.5*global.ActualSantaSpeed; + if(vy > 0) vy = -vy; + if (vy < -100.0) + vy = -100; + if (global.ActualSantaSpeed > 0) + GenerateFlakesFromFallen(fsnow,xfront,clearing,vy); + CleanFallenArea(fsnow,xback-clearing,global.SantaWidth+2*clearing); + int i; + for (i=0; iw; i++) + if (i < xfront+clearing && i>=xback-clearing) + fsnow->acth[i] = 0; + XFlush(global.display); } } + CreateSurfaceFromFallen(fsnow); + // drawing is handled in fallensnow-draw + } } void GenerateFlakesFromFallen(FallenSnow *fsnow, int x, int w, float vy) { P("GenerateFlakes %d %d %d %f\n",counter++,x,w,vy); - if (Flags.NoBlowSnow || Flags.NoSnowFlakes) + if (!Flags.BlowSnow || Flags.NoSnowFlakes) return; // animation of fallen fallen snow // x-values x..x+w are transformed in flakes, vertical speed vy @@ -433,9 +378,9 @@ if (ifirst > fsnow->w) ifirst = fsnow->w; int ilast = x+w; if(ilast < 0) ilast = 0; if (ilast > fsnow->w) ilast = fsnow->w; - P("ifirst ilast: %d %d %d %d\n",ifirst,ilast,w,wrx = fsnow->x + i + 2*MaxSnowFlakeWidth*(drand48()-0.5); - //flake->ry = fsnow->y - j - MaxSnowFlakeHeight; flake->rx = fsnow->x + i + 16*(drand48()-0.5); flake->ry = fsnow->y - j - 8; if (Flags.NoWind) flake->vx = 0; else - flake->vx = NewWind/8; + flake->vx = global.NewWind/8; flake->vy = vy; flake->cyclic = 0; - if (switches.UseGtk && drand48() > 0.25) - { - fluffify(flake,0.7); - //flake->ry += 2*MaxSnowFlakeHeight*drand48(); - } } } } @@ -478,14 +417,11 @@ { if(fsnow->acth[x] > 0) { - if(!switches.UseGtk) + if(!global.IsDouble) { int x1 = fsnow->x + x; int y1 = fsnow->y - fsnow->acth[x]; - if(switches.Trans|Flags.UseBG) - XDrawPoint(display, SnowWin, EFallenGC, x1, y1); - else - XClearArea(display, SnowWin, x1 , y1, 1, 1, switches.Exposures); + myXClearArea(global.display, global.SnowWin, x1 , y1, 1, 1, global.xxposures); } fsnow->acth[x]--; } @@ -493,13 +429,14 @@ void InitFallenSnow() { - while (FsnowFirst) - PopFallenSnow(&FsnowFirst); + while (global.FsnowFirst) + PopFallenSnow(&global.FsnowFirst); // create fallensnow on bottom of screen: WinInfo *NullWindow = (WinInfo *)malloc(sizeof(WinInfo)); memset(NullWindow,0,sizeof(WinInfo)); - PushFallenSnow(&FsnowFirst, NullWindow, 0, SnowWinHeight, SnowWinWidth, MaxScrSnowDepth); + PushFallenSnow(&global.FsnowFirst, NullWindow, 0, global.SnowWinHeight, global.SnowWinWidth, global.MaxScrSnowDepth); + free(NullWindow); } // removes some fallen snow from fsnow, w pixels. If fallensnowheight < h: no removal @@ -512,16 +449,15 @@ if(fsnow->acth[i] > h) { // animation of blown off snow - if (!Flags.NoWind && Wind != 0 && drand48() > 0.5) + if (!Flags.NoWind && global.Wind != 0 && drand48() > 0.5) { int j, jmax = BlowOff(); - //P("%d\n",jmax); for (j=0; j< jmax; j++) { Snow *flake = MakeFlake(0); flake->rx = fsnow->x + i; - flake->ry = fsnow->y - fsnow->acth[i] - drand48()*8;// randint(MaxSnowFlakeWidth); - flake->vx = fsignf(NewWind)*WindMax; + flake->ry = fsnow->y - fsnow->acth[i] - drand48()*8; + flake->vx = fsignf(global.NewWind)*global.WindMax; flake->vy = -5; flake->cyclic = (fsnow->win.id == 0); // not cyclic for Windows, cyclic for bottom P("%d:\n",counter++); @@ -533,10 +469,10 @@ void SetMaxScreenSnowDepth() { - MaxScrSnowDepth = Flags.MaxScrSnowDepth; - if (MaxScrSnowDepth> (SnowWinHeight-SNOWFREE)) { - printf("** Maximum snow depth set to %d\n", SnowWinHeight-SNOWFREE); - MaxScrSnowDepth = SnowWinHeight-SNOWFREE; + global.MaxScrSnowDepth = Flags.MaxScrSnowDepth; + if (global.MaxScrSnowDepth> (global.SnowWinHeight-SNOWFREE)) { + printf("** Maximum snow depth set to %d\n", global.SnowWinHeight-SNOWFREE); + global.MaxScrSnowDepth = global.SnowWinHeight-SNOWFREE; } } @@ -553,7 +489,7 @@ if (imax > fsnow->w) imax = fsnow->w; int i, k; k = 0; - typeof(fsnow->acth[0]) *old; + short int *old; // old will contain the acth values, corresponding with x-1..x+w (including) old = (short int *)malloc(sizeof(*old)*(w+2)); for (i=imin-1; i<=imax; i++) @@ -604,7 +540,6 @@ k++; } free(old); - fsnow->clean = 0; } int HandleFallenSnow(FallenSnow *fsnow) @@ -615,7 +550,7 @@ return 0; if (!fsnow->win.sticky) { - if (fsnow->win.ws != CWorkSpace) + if (fsnow->win.ws != global.CWorkSpace) return 0; } return !Flags.NoKeepSWin; diff -Nru xsnow-3.1.1/src/fallensnow.h xsnow-3.3.2/src/fallensnow.h --- xsnow-3.1.1/src/fallensnow.h 2020-10-13 12:50:56.000000000 +0000 +++ xsnow-3.3.2/src/fallensnow.h 2021-11-04 14:24:27.000000000 +0000 @@ -2,7 +2,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by @@ -19,47 +19,29 @@ #-# */ #pragma once + #include #include #include #include -#include "wmctrl.h" - -typedef struct _FallenSnow { - WinInfo win; // WinInfo of window, win.id == 0 if snow at bottom - int x,y; // Coordinates of fallen snow, y for bottom of fallen snow - int w,h; // width, max height of fallen snow - int w8; // width rounded up to 8-fold - short int *acth; // actual heights - short int *desh; // desired heights - struct _FallenSnow *next; // pointer to next item - cairo_surface_t *surface; // - -#ifdef NO_USE_BITS - unsigned int clean ; // if True, this area has been cleaned -#else - unsigned int clean : 1; // if True, this area has been cleaned -#endif -} FallenSnow; +#include "xsnow.h" -extern FallenSnow *FsnowFirst; extern void UpdateFallenSnowPartial(FallenSnow *fsnow, int x, int w); // used in snow.c extern int HandleFallenSnow(FallenSnow *fsnow); - - extern void fallensnow_init(void); extern void fallensnow_draw(cairo_t *cr); -extern int fallensnow_ui(void); +extern void fallensnow_erase(void); +extern void fallensnow_ui(void); extern void CleanFallenArea(FallenSnow *fsnow, int x, int w); extern void CleanFallen(Window id); extern void DrawFallen(FallenSnow *fsnow); extern void GenerateFlakesFromFallen(FallenSnow *fsnow, int x, int w, float vy); extern void InitFallenSnow(void); extern void UpdateFallenSnowWithWind(FallenSnow *fsnow,int w, int h); -extern int do_fallen(gpointer data); +extern int do_fallen(void *); extern void SetMaxScreenSnowDepth(void); -extern void fallensnow_set_gc(void); +extern void UpdateFallenSnowAtBottom(void); // insert a node at the start of the list @@ -80,4 +62,3 @@ // find fallensnow with id extern FallenSnow *FindFallen(FallenSnow *first, Window id); -extern int MaxScrSnowDepth; diff -Nru xsnow-3.1.1/src/flags.c xsnow-3.3.2/src/flags.c --- xsnow-3.1.1/src/flags.c 2020-10-13 12:50:56.000000000 +0000 +++ xsnow-3.3.2/src/flags.c 2021-11-04 14:24:27.000000000 +0000 @@ -2,7 +2,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by @@ -28,12 +28,17 @@ #include "utils.h" #include "xsnow.h" #include "docs.h" -#include "version.h" #include "doit.h" #include "birds.h" #include "windows.h" #include "debug.h" + +FLAGS Flags; +FLAGS OldFlags; +FLAGS DefaultFlags; +FLAGS VintageFlags; + static void ReadFlags(void); static void SetDefaultFlags(void); @@ -48,26 +53,17 @@ return x; } -void PrintVersion() -{ - printf("Xsnow-%s\n" "December 14th 2001 by Rick Jansen \n" - "February 2020 by Willem Vermin\n" - , VERSION); -} - static char *FlagsFile = NULL; static int FlagsFileAvailable = 1; void SetDefaultFlags() { -#define DOIT_I(x) Flags.x = DEFAULT_ ## x ; -#define DOIT_S(x) free(Flags.x); Flags.x = strdup(DEFAULT_ ## x); -#define DOIT_L(x) DOIT_I(x) +#define DOIT_I(x,d,v) Flags.x = DefaultFlags.x ; +#define DOIT_S(x,d,v) free(Flags.x); Flags.x = strdup(DefaultFlags.x); +#define DOIT_L(x,d,v) DOIT_I(x,d,v) DOITALL; -#undef DOIT_I -#undef DOIT_L -#undef DOIT_S +#include "undefall.inc" } // return value: @@ -79,13 +75,11 @@ void InitFlags() { // to make sure that strings in Flags are malloc'd -#define DOIT_I(x) Flags.x = 0; -#define DOIT_S(x) Flags.x = strdup(""); -#define DOIT_L(x) DOIT_I(x) +#define DOIT_I(x,d,v) Flags.x = 0; DefaultFlags.x=d; VintageFlags.x=v; +#define DOIT_L DOIT_I +#define DOIT_S(x,d,v) Flags.x = strdup(""); DefaultFlags.x=strdup(d); VintageFlags.x=strdup(v); DOITALL; -#undef DOIT_I -#undef DOIT_L -#undef DOIT_S +#include "undefall.inc" } #define handlestring(x) checkax; free(Flags.x); Flags.x = strdup(argv[++ax]) @@ -138,21 +132,6 @@ PrintVersion(); return 1; } - else if (!strcmp(arg, "-wantwindow")) - { - checkax; - char *v = argv[++ax]; - if (!strcmp(v,"default")) - Flags.WantWindow = UW_DEFAULT; - else if (!strcmp(v,"transparent")) - Flags.WantWindow = UW_TRANSPARENT; - else - { - printf("** Invalid value for -wantwindow: %s\n",v); - printf("** Expected on of: default, transparent\n"); - return -1; - } - } else if (strcmp(arg, "-nokeepsnow") == 0) { Flags.NoKeepSnow = 1; @@ -160,55 +139,55 @@ Flags.NoKeepSBot = 1; Flags.NoKeepSnowOnTrees = 1; } - else if (strcmp(arg, "-vintage") == 0) { - Flags.SnowFlakesFactor = VINTAGE_SnowFlakesFactor; - Flags.NoBlowSnow = VINTAGE_NoBlowSnow; - Flags.NStars = VINTAGE_NStars; - Flags.DesiredNumberOfTrees = VINTAGE_DesiredNumberOfTrees; - Flags.NoKeepSnowOnTrees = VINTAGE_NoKeepSnowOnTrees; - Flags.NoMeteorites = VINTAGE_NoMeteorites; - Flags.NoRudolf = VINTAGE_NoRudolf; - Flags.SantaSize = VINTAGE_SantaSize; - free(Flags.TreeType); - Flags.TreeType = strdup(VINTAGE_TreeType); - Flags.ShowBirds = 0; - Flags.BirdsOnly = 0; + else if (strcmp(arg, "-keepsnow") == 0) + { + Flags.NoKeepSnow = 0; + Flags.NoKeepSWin = 0; + Flags.NoKeepSBot = 0; + Flags.NoKeepSnowOnTrees = 0; } - else if (strcmp(arg, "-bg") == 0) { - handlestring(BGColor); - Flags.UseBG = 1; + else if (strcmp(arg, "-vintage") == 0) { +#define DOIT_I(x,d,v) Flags.x = VintageFlags.x; +#define DOIT_L DOIT_I +#define DOIT_S(x,d,v) free(Flags.x); Flags.x = strdup(VintageFlags.x); + DOITALL +#include "undefall.inc" } else if (strcmp(arg, "-desktop") == 0) { Flags.Desktop = 1; } - else if (strcmp(arg, "-fullscreen") == 0) { - Flags.FullScreen = 1; - } - else if (strcmp(arg, "-above") == 0) { - Flags.BelowAll = 0; - } + handle_ia(-allworkspaces ,AllWorkspaces ); handle_ia(-blowofffactor ,BlowOffFactor ); + handle_ia(-checkgtk ,CheckGtk ); handle_ia(-cpuload ,CpuLoad ); + handle_ia(-doublebuffer ,UseDouble ); handle_ia(-flakecountmax ,FlakeCountMax ); handle_ia(-id ,WindowId ); + handle_ia(-window-id ,WindowId ); handle_ia(-maxontrees ,MaxOnTrees ); + handle_ia(-moon ,Moon ); + handle_ia(-moonspeed ,MoonSpeed ); + handle_ia(-moonsize ,MoonSize ); + handle_ia(-halo ,Halo ); + handle_ia(-halobrightness ,HaloBright ); handle_im(-offsets ,OffsetS ); handle_im(-offsetw ,OffsetW ); handle_im(-offsetx ,OffsetX ); handle_im(-offsety ,OffsetY ); handle_ia(-santa ,SantaSize ); handle_ia(-santaspeedfactor ,SantaSpeedFactor ); + handle_ia(-scale ,Scale ); handle_ia(-snowflakes ,SnowFlakesFactor ); handle_ia(-snowspeedfactor ,SnowSpeedFactor ); handle_ia(-snowsize ,SnowSize ); handle_ia(-ssnowdepth ,MaxScrSnowDepth ); handle_ia(-stars ,NStars ); handle_ia(-stopafter ,StopAfter ); + handle_ia(-theme ,ThemeXsnow ); handle_ia(-treefill ,TreeFill ); handle_ia(-trees ,DesiredNumberOfTrees ); handle_ia(-whirlfactor ,WhirlFactor ); handle_ia(-windtimer ,WindTimer ); - handle_ia(-allworkspaces ,AllWorkspaces ); handle_ia(-wsnowdepth ,MaxWinSnowDepth ); @@ -217,23 +196,36 @@ handle_is(-tc ,TreeColor ); handle_is(-treetype ,TreeType ); + handle_iv(-above ,BelowAll ,0 ); handle_iv(-defaults ,Defaults ,1 ); - handle_iv(-exposures ,Exposures ,True ); - handle_iv(-noblowsnow ,NoBlowSnow ,1 ); + handle_iv(-noblowsnow ,BlowSnow ,0 ); + handle_iv(-blowsnow ,BlowSnow ,1 ); handle_iv(-noconfig ,NoConfig ,1 ); - handle_iv(-noexposures ,Exposures ,False ); + handle_iv(-fluffy ,NoFluffy ,0 ); + handle_iv(-hidemenu ,HideMenu ,1 ); handle_iv(-nofluffy ,NoFluffy ,1 ); handle_iv(-noisy ,Noisy ,1 ); handle_iv(-nokeepsnowonscreen ,NoKeepSBot ,1 ); + handle_iv(-keepsnowonscreen ,NoKeepSBot ,0 ); handle_iv(-nokeepsnowontrees ,NoKeepSnowOnTrees ,1 ); + handle_iv(-keepsnowontrees ,NoKeepSnowOnTrees ,0 ); handle_iv(-nokeepsnowonwindows ,NoKeepSWin ,1 ); + handle_iv(-keepsnowonwindows ,NoKeepSWin ,0 ); handle_iv(-nomenu ,NoMenu ,1 ); handle_iv(-nometeorites ,NoMeteorites ,1 ); - handle_iv(-norudolph ,NoRudolf ,1 ); + handle_iv(-meteorites ,NoMeteorites ,0 ); + handle_iv(-norudolph ,Rudolf ,0 ); + handle_iv(-showrudolph ,Rudolf ,1 ); handle_iv(-nosanta ,NoSanta ,1 ); + handle_iv(-root ,ForceRoot ,1 ); + handle_iv(-showsanta ,NoSanta ,0 ); + handle_iv(-snow ,NoSnowFlakes ,0 ); + handle_iv(-nosnow ,NoSnowFlakes ,1 ); handle_iv(-nosnowflakes ,NoSnowFlakes ,1 ); handle_iv(-notrees ,NoTrees ,1 ); + handle_iv(-showtrees ,NoTrees ,0 ); handle_iv(-nowind ,NoWind ,1 ); + handle_iv(-wind ,NoWind ,0 ); handle_iv(-xwininfo ,XWinInfoHandling ,1 ); // birds: @@ -271,7 +263,9 @@ if (!strcmp(Flags.TreeType,"all")) { free(Flags.TreeType); - Flags.TreeType = strdup(ALLTREETYPES); + Flags.TreeType = (char*) malloc(1+2+sizeof(DefaultFlags.TreeType)); + Flags.TreeType = strdup("0,"); + strcat(Flags.TreeType,DefaultFlags.TreeType); } if (Flags.SnowSize > 40) { @@ -338,7 +332,7 @@ if (!FlagsFileAvailable) return; doc = xmlParseFile(FlagsFile); -#define DOIT_I(x) \ +#define DOIT_I(x,d,v) \ /* printf("%d:DOIT_I:%s\n",__LINE__,#x); */ \ result = getnodeset(doc, BAD_CAST "//" # x); \ if (result) {\ @@ -353,8 +347,8 @@ xmlFree(value); \ xmlXPathFreeObject(result); \ } -#define DOIT_L(x) DOIT_I(x) -#define DOIT_S(x) \ +#define DOIT_L(x,d,v) DOIT_I(x,d,v) +#define DOIT_S(x,d,v) \ /* printf("%d:DOIT_S:%s\n",__LINE__,#x); */ \ result = getnodeset(doc, BAD_CAST "//" # x); \ if (result) {\ @@ -371,9 +365,7 @@ } DOIT; //printf("%d\n",__LINE__); -#undef DOIT_I -#undef DOIT_L -#undef DOIT_S +#include "undefall.inc" xmlFreeDoc(doc); xmlCleanupParser(); } @@ -393,13 +385,11 @@ root_node = xmlNewNode(NULL, BAD_CAST "xsnow_flags"); xmlDocSetRootElement(doc, root_node); -#define DOIT_I(x) myxmlNewChild(root_node,NULL,(char *)# x,Flags.x,(char *)"%d"); -#define DOIT_L(x) DOIT_I(x) -#define DOIT_S(x) xmlNewChild(root_node,NULL,BAD_CAST # x,BAD_CAST Flags.x); +#define DOIT_I(x,d,v) myxmlNewChild(root_node,NULL,(char *)# x,Flags.x,(char *)"%d"); +#define DOIT_L(x,d,v) DOIT_I(x,d,v) +#define DOIT_S(x,d,v) xmlNewChild(root_node,NULL,BAD_CAST # x,BAD_CAST Flags.x); DOIT; -#undef DOIT_I -#undef DOIT_L -#undef DOIT_S +#include "undefall.inc" makeflagsfile(); if (!FlagsFileAvailable) diff -Nru xsnow-3.1.1/src/flags.h xsnow-3.3.2/src/flags.h --- xsnow-3.1.1/src/flags.h 2020-10-13 12:50:56.000000000 +0000 +++ xsnow-3.3.2/src/flags.h 2021-11-04 14:24:27.000000000 +0000 @@ -2,7 +2,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by @@ -19,15 +19,34 @@ #-# */ #pragma once + #include #include "doit.h" -#define DOIT_I(x) int x; -#define DOIT_L(x) unsigned long int x; -#define DOIT_S(x) char *x; +#define UIDO(_x,_y) \ + if(Flags._x != OldFlags._x) \ +{ \ + if(Flags.Noisy) { printf("%-16s %6d: %-22s %8d -> %8d\n",__FILE__,__LINE__,#_x,OldFlags._x, Flags._x); fflush(NULL); } \ + {_y} \ + OldFlags._x = Flags._x; \ + Flags.Changes++; \ +} + +#define UIDOS(_x,_y) \ + if(strcmp(Flags._x, OldFlags._x)) \ +{ \ + if(Flags.Noisy) { printf("%-16s %6d: %-22s %8s -> %8s\n",__FILE__,__LINE__,#_x,OldFlags._x, Flags._x); fflush(NULL); } \ + {_y} \ + free(OldFlags._x); \ + OldFlags._x = strdup(Flags._x); \ + Flags.Changes++; \ +} + +#define DOIT_I(x,d,v) int x; +#define DOIT_L(x,d,v) unsigned long int x; +#define DOIT_S(x,d,v) char *x; -typedef struct flags { - //unsigned long int WindowId; +typedef struct _flags { DOITALL int dummy; }FLAGS; @@ -37,8 +56,9 @@ extern FLAGS Flags; extern FLAGS OldFlags; +extern FLAGS DefaultFlags; +extern FLAGS VintageFlags; extern int HandleFlags(int argc, char*argv[]); extern void InitFlags(void); -extern void PrintVersion(void); extern void WriteFlags(void); diff -Nru xsnow-3.1.1/src/gen_snow_includes.sh xsnow-3.3.2/src/gen_snow_includes.sh --- xsnow-3.1.1/src/gen_snow_includes.sh 1970-01-01 00:00:00.000000000 +0000 +++ xsnow-3.3.2/src/gen_snow_includes.sh 2021-11-04 14:24:28.000000000 +0000 @@ -0,0 +1,32 @@ +#!/bin/sh +# -copyright- +#-# +#-# xsnow: let it snow on your desktop +#-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen +#-# 2019,2020,2021 Willem Vermin +#-# +#-# This program is free software: you can redistribute it and/or modify +#-# it under the terms of the GNU General Public License as published by +#-# the Free Software Foundation, either version 3 of the License, or +#-# (at your option) any later version. +#-# +#-# This program is distributed in the hope that it will be useful, +#-# but WITHOUT ANY WARRANTY; without even the implied warranty of +#-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +#-# GNU General Public License for more details. +#-# +#-# You should have received a copy of the GNU General Public License +#-# along with this program. If not, see . +#-# +root="${1:-..}" +out="snow_includes.h" +echo "#pragma once" > "$out" +echo "/* -""copyright-" >> "$out" +echo "*/" >> "$out" +ls "$root/src/Pixmaps"/flake*.xpm | sed "s/^/#include \"/;s/$/\"/" >> "$out" +echo "#define SNOW_ALL \\" >> "$out" +for i in $(seq `ls "$root/src/Pixmaps"/flake*.xpm | wc -l`) ; do + printf 'SNOW(%d) \\\n' `expr $i - 1` ; +done >> "$out" +echo >> "$out" +if [ -x "$root/addcopyright.sh" ] ; then "$root/addcopyright.sh" "$out" ; fi diff -Nru xsnow-3.1.1/src/gen_ui_xml.sh xsnow-3.3.2/src/gen_ui_xml.sh --- xsnow-3.1.1/src/gen_ui_xml.sh 1970-01-01 00:00:00.000000000 +0000 +++ xsnow-3.3.2/src/gen_ui_xml.sh 2021-11-04 14:24:27.000000000 +0000 @@ -0,0 +1,39 @@ +#!/bin/sh +# -copyright- +#-# +#-# xsnow: let it snow on your desktop +#-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen +#-# 2019,2020,2021 Willem Vermin +#-# +#-# This program is free software: you can redistribute it and/or modify +#-# it under the terms of the GNU General Public License as published by +#-# the Free Software Foundation, either version 3 of the License, or +#-# (at your option) any later version. +#-# +#-# This program is distributed in the hope that it will be useful, +#-# but WITHOUT ANY WARRANTY; without even the implied warranty of +#-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +#-# GNU General Public License for more details. +#-# +#-# You should have received a copy of the GNU General Public License +#-# along with this program. If not, see . +#-# +# create C code to get ui.xml in a string +# ISO C stipulates that the length of a string constant should +# not be larger than 4096, so we create a definition as in +# char xsnow_xml[] = {60,63,120,109,108,32,118,101,0}; +# +root="${1:-..}" +in="ui.xml" +out="ui_xml.h" +echo "/* This file is generated from '$in' by '$0' */" > "$out" +echo "/* -copyright-" >> "$out" +echo "*/" >> "$out" +echo "#pragma once" >> "$out" +echo "char xsnow_xml[] = {" >> "$out" +sed 's/^ *//' "$root/src/$in" | awk -v FS="" \ + 'BEGIN{for(n=0;n<256;n++)ord[sprintf("%c",n)]=n;} + {for (i=1;i<=NF;i++) printf "%d,", ord[$i]; + printf "%d,\n",ord["\n"];}' >> "$out" +echo "0};">> "$out" +if [ -x "$root/addcopyright.sh" ] ; then "$root/addcopyright.sh" "$out" ; fi diff -Nru xsnow-3.1.1/src/globals.h xsnow-3.3.2/src/globals.h --- xsnow-3.1.1/src/globals.h 2020-10-13 12:50:56.000000000 +0000 +++ xsnow-3.3.2/src/globals.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,71 +0,0 @@ -/* -copyright- -#-# -#-# xsnow: let it snow on your desktop -#-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin -#-# -#-# This program is free software: you can redistribute it and/or modify -#-# it under the terms of the GNU General Public License as published by -#-# the Free Software Foundation, either version 3 of the License, or -#-# (at your option) any later version. -#-# -#-# This program is distributed in the hope that it will be useful, -#-# but WITHOUT ANY WARRANTY; without even the implied warranty of -#-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -#-# GNU General Public License for more details. -#-# -#-# You should have received a copy of the GNU General Public License -#-# along with this program. If not, see . -#-# - */ -#pragma once -#include "doitb.h" -extern struct _globals { - int maxix, maxiy, maxiz; // [pixels] - float maxx, maxy, maxz; // [m] - float ax, ay, az; // [pixels/m] see r2i in main.c for usage - float ox, oy, oz; // [m] idem - float maxrange; // max distanc to look for other birds [m] - float bird_scale; // scale for drawing birds - float prefdweight; // dimensionless - float meanspeed; // [m/s] preferred mean speed of birds - int neighbours_max; // max number of neighbours to look at - float range; // range wherein neighbours are to be found [m] - float mean_distance; // mean distance [m] - //float vd; // viewing distance (camera obscura) [m] - float xc, zc; // coordinates of camera obscura lens -#ifdef NO_USE_BITS - unsigned int freeze ; // when true, system freezes -#else - unsigned int freeze :1; // when true, system freezes -#endif - -#define DOITB(what,type) \ - type what; \ - type what ## _new; - - DOITALLB() -#undef DOITB -#ifdef NO_USE_BITS -#define DOITB(what,type) \ - unsigned int what ## _changed ; -#else -#define DOITB(what,type) \ - unsigned int what ## _changed : 1; -#endif - - DOITALLB() -#undef DOITB - -#ifdef NO_USE_BITS -#define DOITB(what) \ - unsigned int what ## _requested ; -#else -#define DOITB(what) \ - unsigned int what ## _requested : 1; -#endif - BUTTONALL() -#undef DOITB - -} globals; - diff -Nru xsnow-3.1.1/src/hashtable.cpp xsnow-3.3.2/src/hashtable.cpp --- xsnow-3.1.1/src/hashtable.cpp 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/hashtable.cpp 2021-11-04 14:24:28.000000000 +0000 @@ -2,7 +2,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by @@ -30,7 +30,7 @@ #else #include #define MAP std::map -#pragma message(__FILE__ ":\nUsing map for the hash table, because unordered_map is not available.") +#pragma message __FILE__ ": Using map for the hash table, because unordered_map is not available." #endif static MAP table; @@ -43,20 +43,11 @@ } void *table_get(unsigned int key) { - void *v; - try - { - v = table[key]; - } - catch(...) - { - v = 0; - } - return v; + return(table[key]); } void table_clear(void(*destroy)(void *p)) { - for ( auto it = table.begin(); it != table.end(); ++it ) + for ( MAP::iterator it = table.begin(); it != table.end(); ++it ) { P("%d %p\n",it->first,it->second); destroy(it->second); @@ -70,7 +61,7 @@ #define SET std::unordered_set #else #include -#pragma message(__FILE__ ":\nUsing set, because unordered_set is not available.") +#pragma message __FILE__ ": Using set, because unordered_set is not available." #define SET std::set #endif diff -Nru xsnow-3.1.1/src/hashtable.h xsnow-3.3.2/src/hashtable.h --- xsnow-3.1.1/src/hashtable.h 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/hashtable.h 2021-11-04 14:24:28.000000000 +0000 @@ -2,7 +2,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by @@ -19,6 +19,7 @@ #-# */ #pragma once + #ifdef __cplusplus extern "C" { #endif diff -Nru xsnow-3.1.1/src/ixpm.c xsnow-3.3.2/src/ixpm.c --- xsnow-3.1.1/src/ixpm.c 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/ixpm.c 2021-11-04 14:24:28.000000000 +0000 @@ -2,7 +2,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by @@ -21,6 +21,7 @@ #include #include #include +#include #include "ixpm.h" #include "debug.h" #include "utils.h" @@ -63,6 +64,7 @@ // if you know what I mean static void strrevert(char*s, size_t l) { + assert(l>0); size_t n = strlen(s)/l; size_t i; char *c = (char *)malloc(l*sizeof(*c)); @@ -92,6 +94,7 @@ sscanf(data[0],"%*s %d %d %d", &height, &ncolors, &w); lines = height+ncolors+1; + assert(lines>0); idata = (char **)malloc(lines*sizeof(*idata)); for (i=0; i0); *out = (char**)malloc(sizeof(char *)*(n+3)); char **x = *out; int j; for (j=0; j<2; j++) x[j] = strdup(data[j]); - x[2] = (char *)malloc(5+sizeof(color)); - x[2][0] = 0; + x[2] = (char *)malloc(5+strlen(color)); + x[2][0] = '\0'; strcat(x[2],". c "); strcat(x[2],color); P("c: [%s]\n",x[2]); diff -Nru xsnow-3.1.1/src/ixpm.h xsnow-3.3.2/src/ixpm.h --- xsnow-3.1.1/src/ixpm.h 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/ixpm.h 2021-11-04 14:24:28.000000000 +0000 @@ -2,7 +2,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by @@ -19,10 +19,14 @@ #-# */ #pragma once + #include +#include + extern int iXpmCreatePixmapFromData(Display *display, Drawable d, const char **data, Pixmap *p,Pixmap *s, XpmAttributes *attr, int flop); -extern Region regionfromxpm(const char **data, int flop); +extern Region regionfromxpm(const char **data, int flop, float scale); +cairo_region_t *gregionfromxpm(const char **data, int flop, float scale); extern void xpm_set_color(char **data, char ***out, int *lines, const char *color); extern void xpm_destroy(char **data); diff -Nru xsnow-3.1.1/src/kdtree.c xsnow-3.3.2/src/kdtree.c --- xsnow-3.1.1/src/kdtree.c 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/kdtree.c 2021-11-04 14:24:28.000000000 +0000 @@ -2,7 +2,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by @@ -46,14 +46,23 @@ */ /* single nearest neighbor search written by Tamas Nepusz */ +#define USE_LIST_NODE_ALLOCATOR +#define NO_ALLOCA + #ifdef HAVE_CONFIG_H #include #endif #include #include +#ifndef NO_ALLOCA +#ifdef HAVE_ALLOCA_H +#include +#endif +#endif #include #include +#include #include "kdtree.h" #if defined(WIN32) || defined(__WIN32__) @@ -192,6 +201,7 @@ if(!(node = (struct kdnode *)malloc(sizeof *node))) { return -1; } + assert(dim>0); if(!(node->pos = (double *)malloc(dim * sizeof *node->pos))) { free(node); return -1; @@ -232,6 +242,7 @@ static double sbuf[16]; double *bptr, *buf = NULL; int res, dim = tree->dim; + assert(dim>0); if(dim > 16) { #ifndef NO_ALLOCA @@ -481,6 +492,7 @@ double *bptr, *buf = NULL; int dim = tree->dim; struct kdres *res; + assert(dim>0); if(dim > 16) { #ifndef NO_ALLOCA @@ -583,6 +595,7 @@ double *bptr, *buf = NULL; int dim = kd->dim; struct kdres *res; + assert(dim>0); if(dim > 16) { #ifndef NO_ALLOCA @@ -712,6 +725,7 @@ /* ---- hyperrectangle helpers ---- */ static struct kdhyperrect* hyperrect_create(int dim, const double *min, const double *max) { + assert(dim>0); size_t size = dim * sizeof(double); struct kdhyperrect* rect = NULL; diff -Nru xsnow-3.1.1/src/kdtree.h xsnow-3.3.2/src/kdtree.h --- xsnow-3.1.1/src/kdtree.h 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/kdtree.h 2021-11-04 14:24:28.000000000 +0000 @@ -2,7 +2,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/loadmeasure.c xsnow-3.3.2/src/loadmeasure.c --- xsnow-3.1.1/src/loadmeasure.c 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/loadmeasure.c 2021-11-04 14:24:28.000000000 +0000 @@ -2,7 +2,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by @@ -17,7 +17,7 @@ #-# You should have received a copy of the GNU General Public License #-# along with this program. If not, see . #-# - */ +*/ #include #include @@ -28,16 +28,16 @@ #include "utils.h" #include "clocks.h" #include "xsnow.h" -#include "varia.h" +#include "flags.h" -static int do_loadmeasure(gpointer data); +static int do_loadmeasure(void *); int loadmeasure_ui() { // nothing to do return 0; } -void loadmeasure_draw(UNUSED cairo_t *cr) +void loadmeasure_draw() { // nothing to draw // @@ -45,18 +45,19 @@ void loadmeasure_init() { - add_to_mainloop(PRIORITY_DEFAULT, time_measure, do_loadmeasure, NULL); + add_to_mainloop(PRIORITY_DEFAULT, time_measure, do_loadmeasure); } // changes background color of ui if load to high -int do_loadmeasure(UNUSED gpointer data) +int do_loadmeasure(void *d) { double tnow = wallclock(); static double tprev; - static int count = 0; - static int status = 0; + static int count = 0; + static int status = 0; - if (tnow-tprev > 1.1*time_measure) + if (tnow-tprev > 1.2*time_measure) + //if (tnow-tprev > 0.9*time_measure) // for testing purposes count++; else count --; @@ -70,7 +71,8 @@ printf("system is too busy, suggest to lower 'cpu load' in 'settings'\n"); printf(" or have a look at 'snow': 'Intensity', 'Max # of flakes', ...\n"); printf(" or specify a smaller number of birds in 'birds'\n"); - ui_background(1); + if(!Flags.NoMenu) + ui_background(1); status = 1; } count = 0; @@ -80,11 +82,13 @@ if (status == 1) { P("white %d %d %f %f\n",count,status,time_measure,tnow-tprev); - ui_background(0); + if(!Flags.NoMenu) + ui_background(0); status = 0; } count = 0; } tprev = tnow; return TRUE; + (void)d; } diff -Nru xsnow-3.1.1/src/loadmeasure.h xsnow-3.3.2/src/loadmeasure.h --- xsnow-3.1.1/src/loadmeasure.h 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/loadmeasure.h 2021-11-04 14:24:28.000000000 +0000 @@ -2,7 +2,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by @@ -19,9 +19,8 @@ #-# */ -#include -#include +#pragma once extern int loadmeasure_ui(void); -extern void loadmeasure_draw(cairo_t *cr); +extern void loadmeasure_draw(void); extern void loadmeasure_init(void); diff -Nru xsnow-3.1.1/src/main.c xsnow-3.3.2/src/main.c --- xsnow-3.1.1/src/main.c 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/main.c 2021-11-04 14:24:28.000000000 +0000 @@ -2,7 +2,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by @@ -45,11 +45,10 @@ #include #endif #include -#ifdef HAVE_ALLOCA_H -#include -#endif +#include #include #include +#include #include #include #include @@ -64,10 +63,11 @@ #include "flags.h" #include "mainstub.h" #include "meteo.h" +#include "moon.h" #include "Santa.h" #include "scenery.h" #include "snow.h" -#include "transparent.h" +#include "transwindow.h" #include "ui.h" #include "utils.h" #include "version.h" @@ -80,196 +80,160 @@ #include "debug.h" #include "treesnow.h" #include "loadmeasure.h" -#include "varia.h" + +#include "vroot.h" #ifdef DEBUG #undef DEBUG #endif //#define DEBUG - -// from flags.h -FLAGS Flags; -FLAGS OldFlags; - -// from windows.h -Display *display; -int screen; -int SnowWinBorderWidth; -int SnowWinDepth; -int SnowWinHeight; -int SnowWinWidth; -char *DesktopSession = NULL; -int IsCompiz; -int IsWayland; -Pixel ErasePixel; -Pixel BlackPix; -int counter = 0; - -double cpufactor = 1.0; -float NewWind = 0; - -GtkWidget *drawing_area = NULL; -GdkWindow *gdkwindow = NULL; +#define BMETHOD XdbeBackground +//#define BMETHOD XdbeUndefined +//#define BMETHOD XdbeUntouched +//#define BMETHOD XdbeCopied // to see if double buffering is actually used + +struct _global global; + +int SnowWinChanged = 1; +cairo_t *CairoDC = NULL; +cairo_surface_t *CairoSurface = NULL; // miscellaneous char Copyright[] = "\nXsnow\nCopyright 1984,1988,1990,1993-1995,2000-2001 by Rick Jansen, all rights reserved, 2019,2020 also by Willem Vermin\n"; -static int HaltedByInterrupt = 0; +static char **Argv; +static int Argc; // timing stuff //static double TotSleepTime = 0; // windows stuff -int CWorkSpace = 0; -long TransWorkSpace = -SOMENUMBER; // workspace on which transparent window is placed -static int DoRestart = 0; -static guint draw_all_id = 0; -static gulong drawconnect = 0; - +static int DoRestart = 0; +static guint draw_all_id = 0; +static guint drawit_id = 0; +static int Xorig; +static int Yorig; +static GtkWidget *TransA = NULL; +static char *SnowWinName = NULL; /* Colo(u)rs */ static const char *BlackColor = "black"; - +static Pixel BlackPix; /* Forward decls */ static void HandleCpuFactor(void); -static void HandleExposures(void); static void RestartDisplay(void); -static void SetGCFunctions(void); static void SigHandler(int signum); static int XsnowErrors(Display *dpy, XErrorEvent *err); static void drawit(cairo_t *cr); static void restart_do_draw_all(void); -static int myDetermineWindow(void); static void set_below_above(void); +static void DoAllWorkspaces(void); +static void X11WindowById(Window *xwin, char **xwinname); +static int HandleX11Cairo(void); +static int StartWindow(void); +static void SetWindowScale(void); +static void movewindow(void); -static void Thanks(void) -{ - if (HaltedByInterrupt) - printf("\nXsnow: Caught signal %d\n",HaltedByInterrupt); - printf("\nThank you for using xsnow\n"); -} - // callbacks -static int do_displaychanged(gpointer data); +static int do_displaychanged(void *); static int do_draw_all(gpointer widget); -static int do_event(gpointer data); -static int do_show_range_etc(gpointer data); -static int do_testing(gpointer data); -static int do_ui_check(gpointer data); -static int do_stopafter(gpointer data); -static int do_show_desktop_type(gpointer data); -static int do_display_dimensions(UNUSED gpointer data); +static int do_event(void *); +static int do_show_range_etc(void *); +static int do_testing(void *); +static int do_ui_check(void *); +static int do_stopafter(void *); +static int do_show_desktop_type(void *); +static int do_display_dimensions(void *); +static int do_drawit(void*); static gboolean on_draw_event(GtkWidget *widget, cairo_t *cr, gpointer user_data); /**********************************************************************************************/ -/* About windows, user whishes and scenarios +/* About some technicalities of this program * The following animations exist: - - * - Snow: snow, Santa and scenery. - * - Birds: birds. + * =============================== + * - snow + * - treesnow + * - blowoff + * - Santa + * - scenery (trees etc) + * - stars + * - moon + halo + * - meteorites + * - birds * - * * The following windows are used: + * Selection of window to draw in + * ============================== * - * - TransA: transparent GtkWidget with drawing area - * - SnowWin: X11 window - * - depending on window manager and user whishes, this can be - * - the root window - * - an existing non-root window (see flags -xwindow and -id) - * - a new transparent window + * All drawing is done using the gtk-cairo library, using the window SnowWin. * - * * The following user whishes are possible: - * ( enum{UW_NONE,UW_ROOT,UW_TRANSPARENT}; ) + * For the definition of SnowWin, the following possibilities exist: + * + * A: SnowWin is a transparent, click-through window covering the + * whole screen. + * B: SnowWin is set to the root window, or a window with the name pcmanfm (LXDE desktop). + * C: SnowWin is set to the desired window (flags -id or -xwininfo). * - * - WantWindow = none: default, no special whish - * - Flags.WantWindow = UW_NONE - * - -wantwindow default - * - WantWindow = root: user whishes to use X11 window for snow - * - Flags.WantWindow = UW_ROOT - * - -wantwindow root - * - WantWindow = trans: user whishes to use X11 transparent window - * - Flags.WantWindow = UW_TRANSPARENT - * - -wantwindow transparent * - * If -id or -xwininfo are specified, WantWindow = 1 is implied, and SnowWin - * is an existing non-root window. - * If WantWindow = 1 and -id and -xwininfo are not specified, - * SnowWin is the root window. + * If the user specifies the flag -id or -xwininfo, case C is chosen + * (make_trans_window() in transwindow.c). + * else if a transparent, click-through window can be created, case A is chosen. + * else case B is chosen. * - * * The following switches are determined, dependend on window - * manager and user whishes. These switches should be sufficient - * to determine how to paint snow and birds. + * In cases B and C, usage is made of cairo_xlib_surface_create() to tell cairo + * in which window to paint. * - * - UseGtk: - * - 1: Snow is painted on TransA, using cairo - * - 0: Snow is painted on SnowWin, using X11 + * Double buffering + * ================ * - * - Trans: - * - 1: SnowWin is transparent - * - 0: SnowWin is not transparent + * In case A, double buffering is provided by the cairo library. + * In the other cases, double buffering is accomplished by XdbeSwapBuffers(). * - * - Root: (maybe this is superfluous, we will see) - * - 1: SnowWin is root window - * - 0: SnowWin is not root window + * If cases B and C, if double buffering is not possible, or not wanted + * (flag -doublebuffer), an attempt is made to erase and draw with minimal flicker. * - * - DrawBirds: - * - 1: Birds are painted on TransA, using cairo - * - 0: Birds cannot be painted + * Double buffer switches + * ====================== * - */ -/* - * * Depending on the possibility to create transparent windows and user wishes, - * the following scenarios exist: + * Trans: 1: case A + * UseDouble: 1: case B or C using XdbeSwapBuffers() and friends. + * IsDouble: 1: using double buffering + * + * The following scenario's exist: * - * - Transparent window is possible: TransA exists + * Scenario Trans UseDouble IsDouble + * I 1 0 1 case A + * II 0 1 1 case B or C, using XdbeSwapBuffers and friends + * III 0 0 0 case B or C, not using double buffering * - * - SCENARIO 1: ** Not implemented, starting with scenario1, switch to - * ** scenario 2 gives no Santa, snow etc. Something wrong probably - * ** with GC's, but also when re-creating GC's, got no visuals of Santa etc. - * ** Snowing in root window is useless in a compositing window manager - * ** so: no big loss. - * - WantWindow = root - * - Snow in SnowWin - * - Birds in TransA - * - UseGtk = 0 - * - Trans = 0 - * - Root = 0 or 1 - * - DrawBirds = 1 + * Note: + * In scenario III it is necessary to explicitly erase moving objects before + * drawing. + * One could use XlearWindow() to erase everything, and then draw everything again, + * but this results in severe flicker. * - * - SCENARIO 2: - * - WantWindow = trans - * - Snow in SnowWin - * - Birds in TransA - * - UseGtk = 0 - * - Trans = 1 - * - Root = 1 - * - DrawBirds = 1 + * In scenario's I and II, it is necessary to repaint everything, also not moving objects. * - * - SCENARIO 3: - * - WantWindow = none - * - Snow in TransA - * - Birds in TransA - * - UseGtk = 1 - * - Trans = n/a - * - Root = n/a - * - DrawBirds = 1 + */ +/* + * Globals + * ======= * - * - Transparent window is NOT possible, TransA does not exist + * Many gobal variables are used. If a global is only used in one file only, it is declared + * there as static. + * Globals that are used in more than one file, are members of the struct 'global', defined in xsnow.h + * + * Types + * ===== + * + * All types are defined in xsnow.h * - * - SCENARIO 4: - * - WantWindow = none|trans|root, user cannot force anything - * - Snow in SnowWin - * - Birds in nothing, birds cannot fly - * - UseGtk = 0 - * - Trans = 0 - * - Root = 1 - * - DrawBirds = 0 */ /**********************************************************************************************/ @@ -281,16 +245,55 @@ signal(SIGTERM, SigHandler); signal(SIGHUP, SigHandler); srand48((long int)(wallcl()*1.0e6)); + + + memset((void *)&global,0,sizeof(global)); + + global.counter = 0; + global.cpufactor = 1.0; + global.WindowScale = 1.0; + + global.MaxSnowFlakeHeight = 0; + global.MaxSnowFlakeWidth = 0; + global.FlakeCount = 0; /* # active flakes */ + global.FluffCount = 0; + + global.SnowWin = 0; + global.DesktopSession = NULL; + global.CWorkSpace = 0; + global.WindowsChanged = 0; + + global.FsnowFirst = NULL; + global.MaxScrSnowDepth = 0; + global.RemoveFluff = 0; + + global.SnowOnTrees = NULL; + global.OnTrees = 0; + + global.moonX = 1000; + global.moonY = 80; + + global.Wind = 0; + global.Direction = 0; + global.WindMax = 100.0; + global.NewWind = 0; + + global.HaltedByInterrupt = 0; + global.Message[0] = 0; + + global.SantaPlowRegion = 0; + int i; // make a copy of all flags, before gtk_init() maybe removes some. // we need this at a restart of the program. - char **Argv; Argv = (char**) malloc((argc+1)*sizeof(char**)); for (i=0; i= %s, found version %s\n",ui_gtk_required(),ui_gtk_version()); + + if(!ui_run_nomenu()) + { + Thanks(); + return 0; + } + else + { + Flags.NoMenu = 1; + printf("Continuing with flag '-nomenu'\n"); + } + } + + global.display = XOpenDisplay(Flags.DisplayName); + XSynchronize(global.display,dosync); XSetErrorHandler(XsnowErrors); - screen = DefaultScreen(display); - Black = BlackPixel(display, screen); - White = WhitePixel(display, screen); + int screen = DefaultScreen(global.display); + global.Black = BlackPixel(global.display, screen); + global.White = WhitePixel(global.display, screen); - HandleExposures(); InitSnowOnTrees(); - if (display == NULL) { + if (global.display == NULL) { if (Flags.DisplayName == NULL) Flags.DisplayName = getenv("DISPLAY"); (void) fprintf(stderr, "%s: cannot connect to X server %s\n", argv[0], Flags.DisplayName ? Flags.DisplayName : "(default)"); @@ -391,7 +408,7 @@ // - clearing is done writing the same image, but with color black (0x00000000) // else // - we will use XClearArea to erase flakes and the like. This works well - // on fvwm-like desktops (desktop == RootWindow) with exposures set to 0 + // on fvwm-like desktops (desktop == Rootwindow) with exposures set to 0 // It works more or less in for example KDE, but exposures must be set to 1 // which severely stresses plasma shell (or nautilus-desktop in Gnome, // but we do not use XClearArea in Gnome). @@ -401,17 +418,14 @@ - if (!myDetermineWindow()) + if (!StartWindow()) { return 1; } - Flags.Done = 0; - NoSnowArea_dynamic = XCreateRegion(); // needed when drawing on background with xor. - // unpleasant things happen when a snowflake - // is in the trajectory of a meteorite windows_init(); + moon_init(); Santa_init(); birds_init(); scenery_init(); @@ -424,57 +438,45 @@ treesnow_init(); loadmeasure_init(); - add_to_mainloop(PRIORITY_DEFAULT, time_displaychanged, do_displaychanged ,NULL); - add_to_mainloop(PRIORITY_DEFAULT, time_event, do_event ,NULL); - add_to_mainloop(PRIORITY_DEFAULT, time_testing, do_testing ,NULL); - add_to_mainloop(PRIORITY_DEFAULT, 1.0, do_display_dimensions ,NULL); - add_to_mainloop(PRIORITY_HIGH, time_ui_check, do_ui_check ,NULL); - add_to_mainloop(PRIORITY_DEFAULT, time_show_range_etc, do_show_range_etc ,NULL); + add_to_mainloop(PRIORITY_DEFAULT, time_displaychanged, do_displaychanged ); + add_to_mainloop(PRIORITY_DEFAULT, time_event, do_event ); + add_to_mainloop(PRIORITY_DEFAULT, time_testing, do_testing ); + add_to_mainloop(PRIORITY_DEFAULT, 0.5, do_display_dimensions ); + add_to_mainloop(PRIORITY_HIGH, time_ui_check, do_ui_check ); + add_to_mainloop(PRIORITY_DEFAULT, time_show_range_etc, do_show_range_etc ); if (Flags.StopAfter > 0) - add_to_mainloop(PRIORITY_DEFAULT, Flags.StopAfter, do_stopafter, NULL); + add_to_mainloop(PRIORITY_DEFAULT, Flags.StopAfter, do_stopafter); HandleCpuFactor(); -#define DOIT_I(x) OldFlags.x = Flags.x; -#define DOIT_L(x) DOIT_I(x); -#define DOIT_S(x) OldFlags.x = strdup(Flags.x); +#define DOIT_I(x,d,v) OldFlags.x = Flags.x; +#define DOIT_L(x,d,v) DOIT_I(x,d,v); +#define DOIT_S(x,d,v) OldFlags.x = strdup(Flags.x); DOITALL; -#undef DOIT_I -#undef DOIT_L -#undef DOIT_S +#include "undefall.inc" OldFlags.FullScreen = !Flags.FullScreen; - BlackPix = AllocNamedColor(BlackColor, Black); - - SetGCFunctions(); + BlackPix = AllocNamedColor(BlackColor, global.Black); // events - if(switches.Desktop) - XSelectInput(display, SnowWin, 0); + if(global.Desktop) + { + XSelectInput(global.display, global.Rootwindow, StructureNotifyMask| SubstructureNotifyMask); + } else - XSelectInput(display, SnowWin, - StructureNotifyMask); + XSelectInput(global.display, global.SnowWin, StructureNotifyMask|SubstructureNotifyMask); ClearScreen(); // without this, no snow, scenery etc. in KDE; this seems to be a vintage comment if(!Flags.NoMenu) { - ui(&argc, &argv); - - ui_gray_erase(switches.UseGtk); - - if (!TransA) - { - ui_gray_ww(1); - ui_gray_below(1); - ui_gray_birds(1); - ui_set_birds_header("No alpha channel: no birds will fly."); - } + ui(); + ui_gray_erase(global.Trans); ui_set_sticky(Flags.AllWorkspaces); - add_to_mainloop(PRIORITY_DEFAULT, 2.0, do_show_desktop_type, NULL); + add_to_mainloop(PRIORITY_DEFAULT, 2.0, do_show_desktop_type); } // main loop @@ -483,14 +485,15 @@ if (SnowWinName) free(SnowWinName); - XClearArea(display, SnowWin, 0,0,0,0,True); - XFlush(display); - XCloseDisplay(display); //also frees the GC's, pixmaps and other resources on display + XClearWindow(global.display, global.SnowWin); + XFlush(global.display); + XCloseDisplay(global.display); //also frees the GC's, pixmaps and other resources on display if (DoRestart) { sleep(0); printf("Xsnow restarting: %s\n",Argv[0]); + fflush(NULL); execvp(Argv[0],Argv); } else @@ -498,154 +501,271 @@ return 0; } /* End of snowing */ + + void set_below_above() { - P("%d set_below_above\n",counter++); + P("%d set_below_above\n",global.counter++); + XWindowChanges changes; + // to be sure: we do it in gtk mode and window mode if (Flags.BelowAll) { - setbelow(GTK_WINDOW(TransA)); - setbelow(GTK_WINDOW(TransB)); + if(TransA)setbelow(GTK_WINDOW(TransA)); + changes.stack_mode = Below; + if(global.SnowWin)XConfigureWindow(global.display,global.SnowWin,CWStackMode,&changes); } else { - setabove(GTK_WINDOW(TransA)); - setabove(GTK_WINDOW(TransB)); + if(TransA)setabove(GTK_WINDOW(TransA)); + changes.stack_mode = Above; + if(global.SnowWin)XConfigureWindow(global.display,global.SnowWin,CWStackMode,&changes); } } -int myDetermineWindow() +void X11WindowById(Window *xwin, char **xwinname) { - P("myDetermineWindow root: %#lx\n",RootWindow); - - if (drawconnect) + *xwin = 0; + // user supplied window id: + if (Flags.WindowId) { - P("disconnecting %ld\n",drawconnect); - g_signal_handler_disconnect(TransA,drawconnect); - P("disconnected\n"); + *xwin = Flags.WindowId; + return; } - - static char * SnowWinaName = NULL; - static char * SnowWinbName = NULL; - static int IsDesktop; - if (!SnowWina) + if (Flags.XWinInfoHandling) { - if (SnowWinaName) + // user ask to point to a window + printf("Click on a window ...\n"); + *xwin = XWinInfo(xwinname); + if (*xwin == 0) { - free(SnowWinaName); - SnowWinaName = NULL; + fprintf(stderr,"XWinInfo failed\n"); + exit(1); } - if (!DetermineWindow(&SnowWina,&SnowWinaName,&TransA,"Xsnow-A", &IsDesktop)) - { - printf("xsnow: Cannot run, probably missing a window manager. Exiting...\n"); - return 0; - } - - P("SnowWina: %#lx %s TransA: %p\n",SnowWina,SnowWinaName,(void *)TransA); + } + return; +} - // if user specified window, TransA will be 0 - if (TransA) - { - if (SnowWinbName) - { - free(SnowWinbName); - SnowWinbName = NULL; - } - drawing_area = gtk_drawing_area_new(); - gtk_container_add(GTK_CONTAINER(TransA), drawing_area); +int StartWindow() +{ + int X11cairo = 0; - DetermineWindow(&SnowWinb, &SnowWinbName, &TransB, "Xsnow-B", &IsDesktop); + global.Trans = 0; + global.xxposures = 0; + global.Desktop = 0; + global.UseDouble = 0; + global.IsDouble = 0; - P("SnowWinb: %#lx %s TransB: %p\n",SnowWinb,SnowWinbName,(void *)TransB); + global.Rootwindow = DefaultRootWindow(global.display); + Window xwin; + // see if user chooses window + X11WindowById(&xwin, NULL); + if (xwin) + { + P("StartWindow xwin%#lx\n",xwin); + global.SnowWin = xwin; + X11cairo = 1; + } + else if(Flags.ForceRoot) + { + // user specified to run on root window + printf("Trying to snow in root window\n"); + global.SnowWin = global.Rootwindow; + if (getenv("XSCREENSAVER_WINDOW")) + { + global.SnowWin = strtol(getenv("XSCREENSAVER_WINDOW"),NULL,0); + global.Rootwindow = global.SnowWin; } + X11cairo = 1; } - - switches.UseGtk = 1; - switches.DrawBirds = 1; - switches.Trans = 0; - switches.Root = 0; - switches.Desktop = IsDesktop; - - - if (TransA) // we have a transparent window + else { - if (Flags.WantWindow == UW_TRANSPARENT) // Scenario 2 + // default behaviour + // try to create a transparent clickthrough window + GtkWidget *gtkwin = gtk_window_new(GTK_WINDOW_TOPLEVEL); + int rc = make_trans_window(gtkwin, + 1, // full screen + Flags.AllWorkspaces, // sticky + Flags.BelowAll, // below + 1, // dock + NULL, // gdk_window + &xwin // x11_window + ); + if (rc) { - P("Scenario 2\n"); - - printf("Scenario: Use X11 for drawing snow in transparent window, birds can fly.\n"); - SnowWin = SnowWinb; - SnowWinName = SnowWinbName; - gtk_widget_show_all(TransB); - - switches.UseGtk = 0; - switches.DrawBirds = 1; - switches.Trans = 1; - switches.Root = 0; - switches.Desktop = IsDesktop; + global.Trans = 1; + global.IsDouble = 1; + global.Desktop = 1; + TransA = gtkwin; + GtkWidget *drawing_area = gtk_drawing_area_new(); + gtk_container_add(GTK_CONTAINER(TransA), drawing_area); + g_signal_connect(TransA, "draw", G_CALLBACK(on_draw_event), NULL); + set_below_above(); + global.SnowWin = xwin; + printf("Using transparent window\n"); } - else if(Flags.WantWindow == UW_DEFAULT) // Scenario 3 + else { - P("Scenario 3\n"); - printf("Scenario: Use Gtk for drawing snow in transparent window, birds can fly.\n"); - SnowWin = SnowWina; - SnowWinName = SnowWinaName; - gtk_widget_hide(TransB); - - switches.UseGtk = 1; - switches.DrawBirds = 1; - switches.Trans = 0; - switches.Root = 0; - switches.Desktop = 1; + global.Desktop = 1; + X11cairo = 1; + // use rootwindow, pcmanfm or Desktop: + printf("Cannot create transparent window\n"); + if (global.DesktopSession == NULL) + { + char *desktopsession = NULL; + const char *desktops[] = { + "DESKTOP_SESSION", + "XDG_SESSION_DESKTOP", + "XDG_CURRENT_DESKTOP", + "GDMSESSION", + NULL + }; + + int i; + for (i=0; desktops[i]; i++) + { + desktopsession = getenv(desktops[i]); + if (desktopsession) + break; + } + if (desktopsession) + printf("Detected desktop session: %s\n",desktopsession); + else + { + printf("Could not determine desktop session\n"); + desktopsession = (char *)"unknown_desktop_session"; + } + + global.DesktopSession = strdup(desktopsession); + + if (!strcasecmp(global.DesktopSession,"enlightenment")) + printf("NOTE: xsnow will probably run, but some glitches are to be expected.\n"); + else if(!strcasecmp(global.DesktopSession,"twm")) + printf("NOTE: you probably need to tweak 'Lift snow on windows' in the 'settings' panel.\n"); + } + // if envvar DESKTOP_SESSION == LXDE, search for window with name pcmanfm + if (global.DesktopSession != NULL && + !strncmp(global.DesktopSession,"LXDE",4) && + (xwin = FindWindowWithName(global.display,"pcmanfm"))) + { + printf("LXDE session found, using window 'pcmanfm'.\n"); + P("lxdefound: %d %#lx\n",lxdefound,*xwin); + } + else if ((xwin = FindWindowWithName(global.display,"Desktop"))) + { + printf("Using window 'Desktop'.\n"); + } + else + { + printf("Using root window\n"); + xwin = global.Rootwindow; + } + global.SnowWin = xwin; } } - else // No transparent window: Scenario 4 + + if(X11cairo) { - P("Scenario 4 Desktop: %d\n",IsDesktop); - printf("Scenario: Use X11 for drawing snow in root window, no birds will fly.\n"); - // in LXDE, SnowWin will be overwritten by id of window pcmanfm - SnowWin = SnowWina; - SnowWinName = SnowWinaName; - switches.UseGtk = 0; - switches.DrawBirds = 0; - switches.Trans = 0; - switches.Root = 1; - switches.Desktop = IsDesktop; + HandleX11Cairo(); + drawit_id = add_to_mainloop1(PRIORITY_HIGH, time_draw_all, do_drawit, CairoDC); } - InitDisplayDimensions(); + global.IsDouble = global.Trans || global.UseDouble; // just to be sure ... - P("windows: SnowWin:%s SnowWina:%s SnowWinb:%s\n",SnowWinName,SnowWinaName,SnowWinbName); - printf("Snowing in window: %#lx - \"%s\" - depth: %d - geom: %d %d %dx%d - alpha: %s - exposures: %d\n", - SnowWin,SnowWinName,SnowWinDepth, - SnowWinX,SnowWinY,SnowWinWidth,SnowWinHeight, TransA?"yes":"no",switches.Exposures); - if (TransA) - printf("Birds in window: %#lx - \"%s\"\n",SnowWina,SnowWinaName); + XTextProperty x; + if (XGetWMName(global.display,xwin,&x)) + SnowWinName = strdup((char *)x.value); else - printf("No birds (you need a compositing display manager to let birds fly).\n"); + SnowWinName = strdup("no name"); + XFree(x.value); + InitDisplayDimensions(); + I("Snowing in %#lx: %s %d+%d %dx%d\n",global.SnowWin,SnowWinName,global.SnowWinX,global.SnowWinY,global.SnowWinWidth,global.SnowWinHeight); + + Xorig = global.SnowWinX; + Yorig = global.SnowWinY; - if(TransA) + movewindow(); + + SetWindowScale(); + + return TRUE; +} + +int HandleX11Cairo() +{ + XWindowAttributes attr; + XGetWindowAttributes(global.display,global.SnowWin,&attr); + int w = attr.width; + int h = attr.height; + Visual *visual = DefaultVisual(global.display,DefaultScreen(global.display)); + int rcv; + P("double: %d\n",Flags.UseDouble); +#ifdef XDBE_AVAILABLE + int dodouble = Flags.UseDouble; +#else + int dodouble = 0; +#endif +#ifdef XDBE_AVAILABLE + if(dodouble) { - TransWorkSpace = GetCurrentWorkspace(); + static Drawable backBuf = 0; + if(backBuf) + XdbeDeallocateBackBufferName(global.display,backBuf); + backBuf = XdbeAllocateBackBufferName(global.display,global.SnowWin,BMETHOD); + if (CairoSurface) + cairo_surface_destroy(CairoSurface); + CairoSurface = cairo_xlib_surface_create(global.display, backBuf, visual, w, h); + global.UseDouble = 1; + global.IsDouble = 1; + printf("Using double buffer: %#lx.\n",backBuf); + rcv = TRUE; + } +#endif + if(!dodouble) + { + CairoSurface = cairo_xlib_surface_create(global.display, global.SnowWin, visual, w, h); + printf("NOT using double buffering:"); + if (Flags.UseDouble) + printf(" because double buffering is not available on this system\n"); + else + printf(" on your request.\n"); + rcv = FALSE; + } + + if (CairoDC) + cairo_destroy(CairoDC); + + CairoDC = cairo_create(CairoSurface); + cairo_xlib_surface_set_size(CairoSurface,w,h); + return rcv; +} - drawconnect = g_signal_connect(TransA, "draw", G_CALLBACK(on_draw_event), NULL); - P("connecting %ld\n",drawconnect); - restart_do_draw_all(); // to (re-)establish the timeout for do_draw_all - set_below_above(); +void DoAllWorkspaces() +{ + if(Flags.AllWorkspaces) + { + P("stick\n"); + if (global.Trans) + { + gtk_window_stick(GTK_WINDOW(TransA)); + } } else { - drawconnect = 0; + P("unstick\n"); + if (global.Trans) + { + gtk_window_unstick(GTK_WINDOW(TransA)); + } } - return 1; + ui_set_sticky(Flags.AllWorkspaces); } - // here we are handling the buttons in ui // Ok, this is a long list, and could be implemented more efficient. // But, do_ui_check is called not too frequently, so.... // Note: if changes != 0, the settings will be written to .xsnowrc // -int do_ui_check(UNUSED gpointer data) +int do_ui_check(void *d) { if (Flags.Done) gtk_main_quit(); @@ -653,174 +773,62 @@ if (Flags.NoMenu) return TRUE; - int changes = 0; - changes += Santa_ui(); - changes += scenery_ui(); - changes += birds_ui(); - changes += snow_ui(); - changes += meteo_ui(); - changes += wind_ui(); - changes += stars_ui(); - changes += fallensnow_ui(); - changes += blowoff_ui(); - changes += treesnow_ui(); - - if (Flags.WantWindow != OldFlags.WantWindow) - { - ClearScreen(); - OldFlags.WantWindow = Flags.WantWindow; - P("WantWindow: %d\n",Flags.WantWindow); - if(draw_all_id) - { - g_source_remove(draw_all_id); - P("removed %d\n",draw_all_id); - } - draw_all_id = 0; - myDetermineWindow(); - ui_gray_erase(switches.UseGtk); - changes++; - P("changes: %d\n",changes); - } - if(Flags.CpuLoad != OldFlags.CpuLoad) - { - OldFlags.CpuLoad = Flags.CpuLoad; - P("cpuload: %d %d\n",OldFlags.CpuLoad,Flags.CpuLoad); - HandleCpuFactor(); - changes++; - P("changes: %d\n",changes); - } - if(Flags.Transparency != OldFlags.Transparency) - { - OldFlags.Transparency = Flags.Transparency; - P("Transparency: %d %d\n",OldFlags.Transparency,Flags.Transparency); - changes++; - P("changes: %d\n",changes); - } - if(Flags.UseBG != OldFlags.UseBG) - { - OldFlags.UseBG = Flags.UseBG; - SetGCFunctions(); - ClearScreen(); - changes++; - P("changes: %d\n",changes); - } - if(strcmp(Flags.BGColor,OldFlags.BGColor)) - { - free(OldFlags.BGColor); - OldFlags.BGColor = strdup(Flags.BGColor); - if(Flags.UseBG) - { - SetGCFunctions(); - ClearScreen(); - } - changes++; - P("changes: %d\n",changes); - } - if(Flags.Exposures != OldFlags.Exposures) - { - P("changes: %d %d %d\n",changes,OldFlags.Exposures,Flags.Exposures); - OldFlags.Exposures = Flags.Exposures; - HandleExposures(); - HandleCpuFactor(); - ClearScreen(); - changes++; - P("changes: %d %d %d\n",changes,OldFlags.Exposures,Flags.Exposures); - P("changes: %d\n",changes); - } - if(Flags.OffsetS != OldFlags.OffsetS) - { - OldFlags.OffsetS = Flags.OffsetS; - changes++; - P("changes: %d %d\n",changes,Flags.OffsetS); - } - if(Flags.OffsetY != OldFlags.OffsetY) - { - OldFlags.OffsetY = Flags.OffsetY; - changes++; - P("changes: %d %d\n",changes,Flags.OffsetY); - } - if(Flags.NoFluffy != OldFlags.NoFluffy) - { - OldFlags.NoFluffy = Flags.NoFluffy; - ClearScreen(); - changes++; - P("changes: %d\n",changes); - } - if(Flags.FullScreen != OldFlags.FullScreen) - { - OldFlags.FullScreen = Flags.FullScreen; - if(TransA) - { - if (Flags.FullScreen) - { - gtk_window_fullscreen(GTK_WINDOW(TransA)); - gtk_window_fullscreen(GTK_WINDOW(TransB)); - } - else - { - gtk_window_unfullscreen(GTK_WINDOW(TransA)); - gtk_window_unfullscreen(GTK_WINDOW(TransB)); - } - set_below_above(); - } - changes++; - P("changes: %d\n",changes); - } - if(Flags.AllWorkspaces != OldFlags.AllWorkspaces) - { - if(Flags.AllWorkspaces) - { - P("stick\n"); - if (switches.UseGtk||switches.Trans) - { - gtk_window_stick(GTK_WINDOW(TransA)); - gtk_window_stick(GTK_WINDOW(TransB)); - } - } - else - { - P("unstick\n"); - if (switches.UseGtk||switches.Trans) - { - gtk_window_unstick(GTK_WINDOW(TransA)); - gtk_window_unstick(GTK_WINDOW(TransB)); - } - } - OldFlags.AllWorkspaces = Flags.AllWorkspaces; - ui_set_sticky(Flags.AllWorkspaces); - changes++; - P("changes: %d\n",changes); - } - if(Flags.BelowAll != OldFlags.BelowAll) - { - OldFlags.BelowAll = Flags.BelowAll; - set_below_above(); - changes++; - P("changes: %d %d\n",changes,Flags.BelowAll); - } + Santa_ui(); + scenery_ui(); + birds_ui(); + snow_ui(); + meteo_ui(); + wind_ui(); + stars_ui(); + fallensnow_ui(); + blowoff_ui(); + treesnow_ui(); + moon_ui(); + ui_ui(); + + UIDO (CpuLoad , HandleCpuFactor(); ); + UIDO (Transparency , ); + UIDO (Scale , ); + UIDO (OffsetS , DisplayDimensions(); ); + UIDO (OffsetY , UpdateFallenSnowRegions(); ); + UIDO (NoFluffy , ClearScreen(); ); + UIDO (AllWorkspaces , DoAllWorkspaces(); ); + UIDO (BelowAll , set_below_above(); ); - if (changes > 0) + if (Flags.Changes > 0) { P("WriteFlags\n"); WriteFlags(); - P("-----------changes: %d\n",changes); + P("-----------Changes: %d\n",Flags.Changes); } + Flags.Changes = 0; return TRUE; + (void)d; } -int do_displaychanged(UNUSED gpointer data) +void movewindow() +{ + if(!global.Desktop) + return; + XMoveWindow(global.display,global.SnowWin,0,0); + //InitDisplayDimensions(); + P("movewindow: Orig: %d %d %d %d\n",Xorig,Yorig,global.SnowWinWidth,global.SnowWinHeight); +} + +int do_displaychanged(void *d) { // if we are snowing in the desktop, we check if the size has changed, // this can happen after changing of the displays settings // If the size has been changed, we restart the program + (void)d; if (Flags.Done) return FALSE; - P("UseGtk: %d Trans: %d Root: %d DrawBirds: %d Exposures: %d Desktop: %d\n", - switches.UseGtk, switches.Trans, switches.Root, switches.DrawBirds, - switches.Exposures, switches.Desktop); + P("Trans: %d xxposures: %d Desktop: %d\n", + global.Trans, + global.xxposures, global.Desktop); - if (!switches.Desktop) + if (!global.Desktop) return TRUE; { unsigned int w,h; @@ -829,7 +837,7 @@ w = WidthOfScreen(screen); h = HeightOfScreen(screen); P("width height: %d %d\n",w,h); - if(Wroot != w || Hroot != h) + if(global.Wroot != w || global.Hroot != h) { DoRestart = 1; Flags.Done = 1; @@ -840,23 +848,28 @@ } } -int do_event(UNUSED gpointer data) +int do_event(void *d) { + (void)d; + P("do_event %d\n",counter++); if (Flags.Done) return FALSE; - //if(switches.Trans) return; we are tempted, but if the event loop is escaped, - // a memory leak appears XEvent ev; - XFlush(display); - while (XPending(display)) + XFlush(global.display); + while (XPending(global.display)) { - XNextEvent(display, &ev); - if(!switches.Trans) + XNextEvent(global.display, &ev); { + if (ev.type == ConfigureNotify || ev.type == MapNotify + || ev.type == UnmapNotify) + { + global.WindowsChanged++; + P("WindowsChanged %d %d\n",counter++,global.WindowsChanged); + } switch (ev.type) { case ConfigureNotify: - P("ConfigureNotify: r=%ld w=%ld geo=(%d,%d,%d,%d) bw=%d root: %d\n", + P("ConfigureNotify: ev=%ld win=%#lx geo=(%d,%d,%d,%d) bw=%d root: %d\n", ev.xconfigure.event, ev.xconfigure.window, ev.xconfigure.x, @@ -864,15 +877,11 @@ ev.xconfigure.width, ev.xconfigure.height, ev.xconfigure.border_width, - (SnowWin == ev.xconfigure.event) + (global.SnowWin == ev.xconfigure.event) ); - if (ev.xconfigure.window == SnowWin && - (ev.xconfigure.width != SnowWinWidth || - ev.xconfigure.height != SnowWinHeight)) + if (ev.xconfigure.window == global.SnowWin) { - P("init %d %d\n",ev.xconfigure.width, ev.xconfigure.height); - P("Calling RestartDisplay\n"); - RestartDisplay(); + SnowWinChanged = 1; } break; } @@ -881,10 +890,9 @@ return TRUE; } -void RestartDisplay() // todo +void RestartDisplay() { - P("Calling InitDisplayDimensions\n"); - InitDisplayDimensions(); + P("Restartdisplay: %d W: %d H: %d\n",counter++,global.SnowWinWidth,global.SnowWinHeight); InitFallenSnow(); init_stars(); EraseTrees(); @@ -894,15 +902,16 @@ } if(!Flags.NoTrees) { - XDestroyRegion(TreeRegion); - TreeRegion = XCreateRegion(); + cairo_region_destroy(global.TreeRegion); + global.TreeRegion = cairo_region_create(); } - XClearArea(display, SnowWin, 0,0,0,0,switches.Exposures); + if(!global.IsDouble) + ClearScreen(); } -int do_show_range_etc(UNUSED gpointer data) +int do_show_range_etc(void *d) { if (Flags.Done) return FALSE; @@ -911,97 +920,86 @@ return TRUE; ui_show_range_etc(); return TRUE; + (void)d; } -int do_show_desktop_type(UNUSED gpointer data) +int do_show_desktop_type(void *d) { P("do_show_desktop_type %d\n",counter++); if (Flags.NoMenu) return TRUE; char *s; - if (IsWayland) + if (global.IsWayland) s = (char *)"Wayland (Expect some slugginess)"; - else if (IsCompiz) + else if (global.IsCompiz) s = (char *)"Compiz"; else s = (char *)"Probably X11"; char t[128]; - snprintf(t,64,"%s. Snow window: %#lx",s,SnowWin); + snprintf(t,64,"%s. Snow window: %#lx",s,global.SnowWin); ui_show_desktop_type(t); return TRUE; + (void)d; } -int do_testing(UNUSED gpointer data) +int do_testing(void *d) { - counter++; + (void)d; if (Flags.Done) return FALSE; + return TRUE; - P("Flakecount: %d FluffCount: %d\n",FlakeCount,FluffCount); - if (FluffCount < 0 || FluffCount > FlakeCount) - Flags.Done = 1; - /* -#include "hashtable.h" -#include "snow.h" -P("flakes: %d %d\n",set_size(),FlakeCount); -*/ + global.counter++; + XWindowAttributes attr; + XGetWindowAttributes(global.display,global.SnowWin,&attr); + + P("%d wxh %d %d %d %d %d %d %d %d \n",counter,SnowWinX,SnowWinY,global.SnowWinWidth,global.SnowWinHeight,attr.x,attr.y,attr.width,attr.height); + return TRUE; - Flags.BelowAll = !Flags.BelowAll; } -/* ------------------------------------------------------------------ */ void SigHandler(int signum) { - HaltedByInterrupt = signum; + global.HaltedByInterrupt = signum; Flags.Done = 1; } -/* ------------------------------------------------------------------ */ - - - -#if 0 -// keep this in case I need the erasure code -void EraseStars() -{ - int i; - for (i=0; ierror_code, msg,sizeof(msg)); if(Flags.Noisy) - I("%d %s\n",counter++,msg); + I("%d %s\n",global.counter++,msg); + + if (++count > countmax) + { + snprintf(global.Message,sizeof(global.Message),"More than %d errors, I quit!",countmax); + Flags.Done = 1; + } return 0; } // the draw callback -gboolean on_draw_event(UNUSED GtkWidget *widget, cairo_t *cr, UNUSED gpointer user_data) +gboolean on_draw_event(GtkWidget *widget, cairo_t *cr, gpointer user_data) { P("Just to check who this is: %p %p\n",(void *)widget,(void *)TransA); drawit(cr); return FALSE; + (void)widget; + (void)user_data; +} + +int do_drawit(void *cr) +{ + P("do_drawit %d %p\n",counter++,cr); + drawit((cairo_t*)cr); + return TRUE; } void drawit(cairo_t *cr) @@ -1011,16 +1009,43 @@ if (Flags.Done) return; - birds_draw(cr); + if(global.UseDouble) + { + XdbeSwapInfo swapInfo; + swapInfo.swap_window = global.SnowWin; + swapInfo.swap_action = BMETHOD; + XdbeSwapBuffers(global.display,&swapInfo,1); + } + else if(!global.IsDouble) + { + XFlush(global.display); + moon_erase (0); + Santa_erase(cr); + stars_erase(); // not really necessary + birds_erase(0); + snow_erase(1); + XFlush(global.display); + } - if (!switches.UseGtk || Flags.BirdsOnly || !WorkspaceActive()) - return; + int skipit = Flags.BirdsOnly || !WorkspaceActive(); - stars_draw(cr); + if (!skipit) + { + stars_draw(cr); + meteo_draw(cr); - meteo_draw(cr); + P("moon\n"); + moon_draw(cr); + scenery_draw(cr); + } - scenery_draw(cr); + P("birds %d\n",counter++); + birds_draw(cr); + + if (skipit) + return; + + fallensnow_draw(cr); if(!Flags.FollowSanta || !Flags.ShowBirds) // if Flags.FollowSanta: drawing of Santa is done in birds_draw() Santa_draw(cr); @@ -1029,55 +1054,56 @@ snow_draw(cr); - fallensnow_draw(cr); + XFlush(global.display); } -int do_display_dimensions(UNUSED gpointer data) +void SetWindowScale() { + // assuming a standard screen of 1024x576, we suggest to use the scalefactor + // WindowScale + float x = global.SnowWinWidth / 1000.0; + float y = global.SnowWinHeight / 576.0; + if (x < y) + global.WindowScale = x; + else + global.WindowScale = y; + P("WindowScale: %f\n",global.WindowScale); +} + +int do_display_dimensions(void *d) +{ + (void)d; if (Flags.Done) return FALSE; - static int prevw = 0, prevh = 0; - P("%d do_init_display_dimensions\n",counter); - static int first = 1; - if(first) - { - // at the first call, nothing has to be done, except: - prevw = SnowWinWidth; - prevh = SnowWinHeight; - first = 0; + if (!SnowWinChanged) return TRUE; - } + SnowWinChanged = 0; + static int prevw = 0, prevh = 0; + P("%d do_display_dimensions %d %d\n",counter++,global.SnowWinWidth,global.SnowWinHeight); DisplayDimensions(); - P("do_display_dim: prevw: %d SnowWinWidth: %d prevh: %d SnowWinHeight: %d\n",prevw,SnowWinWidth,prevh,SnowWinHeight); - if (prevw != SnowWinWidth || prevh != SnowWinHeight) + if (prevw != global.SnowWinWidth || prevh != global.SnowWinHeight) { - if (prevw == SnowWinWidth) + // if(global.X11cairo) // let op + if (!global.Trans) { - // search fallensnow at bottom - FallenSnow *f = FindFallen(FsnowFirst,0); - if (f) - f->y = SnowWinHeight; + HandleX11Cairo(); + RestartDisplay(); } - else - InitFallenSnow(); - P("%d do_display_dimensions\n",counter++); - init_stars(); - EraseTrees(); - ClearScreen(); - prevw = SnowWinWidth; - prevh = SnowWinHeight; + prevw = global.SnowWinWidth; + prevh = global.SnowWinHeight; + SetWindowScale(); } return TRUE; } int do_draw_all(gpointer widget) { - // called via drawit() if (Flags.Done) return FALSE; P("do_draw_all %d %p\n",counter++,(void *)widget); + // this will result in a call off on_draw_event(): gtk_widget_queue_draw(GTK_WIDGET(widget)); return TRUE; } @@ -1090,71 +1116,43 @@ // re-add things whose timing is dependent on cpufactor if (Flags.CpuLoad <= 0) - cpufactor = 1; + global.cpufactor = 1; else - cpufactor = 100.0/Flags.CpuLoad; + global.cpufactor = 100.0/Flags.CpuLoad; if (fallen_id) g_source_remove(fallen_id); - Santa_HandleCpuFactor(); - - fallen_id = add_to_mainloop(PRIORITY_DEFAULT, time_fallen, do_fallen, NULL); + fallen_id = add_to_mainloop(PRIORITY_DEFAULT, time_fallen, do_fallen); P("handlecpufactor %f %f %d\n",oldcpufactor,cpufactor,counter++); - add_to_mainloop(PRIORITY_HIGH, 0.2 , do_initsnow, NULL); // remove flakes + add_to_mainloop(PRIORITY_HIGH, 0.2 , do_initsnow); // remove flakes restart_do_draw_all(); } void restart_do_draw_all() { - if (!TransA) - return; - if (draw_all_id) - g_source_remove(draw_all_id); - draw_all_id = add_to_mainloop(PRIORITY_HIGH, time_draw_all, do_draw_all, TransA); - P("started do_draw_all %d %p %f\n",draw_all_id, (void *)TransA, time_draw_all); -} - - -void SetGCFunctions() -{ - if (Flags.UseBG) - ErasePixel = AllocNamedColor(Flags.BGColor,Black) | 0xff000000; - else - ErasePixel = 0; - - Santa_set_gc(); - P("Santa_set_gc\n"); - - scenery_set_gc(); - - treesnow_set_gc(); - - snow_set_gc(); - - stars_set_gc(); - - fallensnow_set_gc(); - -} - - -void HandleExposures() -{ - if (Flags.Exposures == -SOMENUMBER) // no -exposures or -noexposures given - if (Flags.XWinInfoHandling) - switches.Exposures = 1; - else - switches.Exposures = 0; + if (global.Trans) + { + if (draw_all_id) + g_source_remove(draw_all_id); + draw_all_id = add_to_mainloop1(PRIORITY_HIGH, time_draw_all, do_draw_all, TransA); + P("started do_draw_all %d %p %f\n",draw_all_id, (void *)TransA, time_draw_all); + } else - switches.Exposures = Flags.Exposures; + { + if (drawit_id) + g_source_remove(drawit_id); + drawit_id = add_to_mainloop1(PRIORITY_HIGH, time_draw_all, do_drawit, CairoDC); + P("started do_drawit %d %p %f\n",drawit_id, (void *)CairoDC, time_draw_all); + } } -int do_stopafter(UNUSED gpointer data) +int do_stopafter(void *d) { Flags.Done = 1; printf("Halting because of flag -stopafter\n"); return FALSE; + (void)d; } diff -Nru xsnow-3.1.1/src/mainstub.cpp xsnow-3.3.2/src/mainstub.cpp --- xsnow-3.1.1/src/mainstub.cpp 2020-10-13 12:50:56.000000000 +0000 +++ xsnow-3.3.2/src/mainstub.cpp 2021-11-04 14:24:27.000000000 +0000 @@ -2,7 +2,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/mainstub.h xsnow-3.3.2/src/mainstub.h --- xsnow-3.1.1/src/mainstub.h 2020-10-13 12:50:56.000000000 +0000 +++ xsnow-3.3.2/src/mainstub.h 2021-11-04 14:24:27.000000000 +0000 @@ -2,7 +2,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by @@ -19,6 +19,7 @@ #-# */ #pragma once + #ifdef __cplusplus extern "C" { #endif diff -Nru xsnow-3.1.1/src/Makefile.am xsnow-3.3.2/src/Makefile.am --- xsnow-3.1.1/src/Makefile.am 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/Makefile.am 2021-11-04 14:24:28.000000000 +0000 @@ -2,7 +2,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by @@ -22,66 +22,44 @@ gamesdir = $(exec_prefix)/games games_PROGRAMS = xsnow -xsnow_CPPFLAGS = $(XML_CFLAGS) $(GTK_CFLAGS) -DUSE_LIST_NODE_ALLOCATOR -xsnow_LDADD = $(XML_LIBS) $(GTK_LIBS) +xsnow_CPPFLAGS = $(XML_CFLAGS) $(GTK_CFLAGS) $(X11_CFLAGS) +xsnow_LDADD = $(XML_LIBS) $(GTK_LIBS) $(X11_LIBS) xsnow_SOURCES = clocks.c ixpm.c main.c fallensnow.c wmctrl.c docs.c \ clocks.h ixpm.h docs.h fallensnow.h pixmaps.h \ pixmaps.c version.h wmctrl.h xsnow.h windows.c windows.h\ flags.c flags.h csvpos.c csvpos.h \ dsimple.c dsimple.h clientwin.c clientwin.h \ - test1.sh test2.sh test3.sh xsnow.desktop \ + test1.sh xsnow.desktop \ doit.h ui.c ui.h ui.xml \ - transparent.c transparent.h debug.h \ + debug.h \ mainstub.cpp mainstub.h \ - birds.c kdtree.c birds.h kdtree.h globals.h doitb.h \ + birds.c kdtree.c birds.h kdtree.h birdglobals.h doitb.h \ hashtable.cpp hashtable.h \ Santa.c Santa.h utils.c utils.h \ scenery.c scenery.h snow.c snow.h \ meteo.c meteo.h wind.c wind.h \ stars.c stars.h blowoff.c blowoff.h \ treesnow.c treesnow.h loadmeasure.c loadmeasure.h \ - varia.h snow_includes.h + snow_includes.h vroot.h \ + moon.c moon.h buttons.h undefall.inc \ + transwindow.c transwindow.h -nodist_xsnow_SOURCES = ui_xml.h +nodist_xsnow_SOURCES = ui_xml.h snow_includes.h BUILT_SOURCES = ui_xml.h snow_includes.h -# create C code to get ui.xml in a string -# ISO C stipulates that the length of a string constant should -# not be larger than 4096, so we create a definition as in -# char xsnow_xml[] = {60,63,120,109,108,32,118,101,0}; -# +EXTRA_DIST = gen_snow_includes.sh gen_ui_xml.sh + ui_xml.h: ui.xml @echo "Creating $@ from $<" - @echo "/* This file is generated from $< by Makefile */" > $@ - @echo "/* -""copyright-" >> $@ - @echo "*/" >> $@ - @echo "#pragma once" >> $@ - @echo "char xsnow_xml[] = {" >> $@ - @sed 's/^ *//' $< | awk -v FS="" \ - 'BEGIN{for(n=0;n<256;n++)ord[sprintf("%c",n)]=n;}'\ - '{for (i=1;i<=NF;i++) printf "%d,", ord[$$i];'\ - 'printf "%d,\n",ord["\n"];}' >> $@ - @echo "0};" >> $@ - if [ -x $(top_srcdir)/addcopyright.sh ] ; then $(top_srcdir)/addcopyright.sh $@ ; fi + $(top_srcdir)/src/gen_ui_xml.sh $(top_srcdir) snow_includes.h: Pixmaps @echo "Creating $@" - @echo "#pragma once" > $@ - @echo "/* -""copyright-" >> $@ - @echo "*/" >> $@ - @ls $(top_srcdir)/src/Pixmaps/flake*.xpm | sed "s/^/#include \"/;s/$$/\"/" >> $@ - @echo "#define SNOW_ALL \\" >> $@ - @for i in $$(seq `ls $(top_srcdir)/src/Pixmaps/flake*.xpm | wc -l`) ; do \ - printf 'SNOW(%d) \\\n' `expr $$i - 1` ;\ - done >> $@ - @echo >> $@ - if [ -x $(top_srcdir)/addcopyright.sh ] ; then $(top_srcdir)/addcopyright.sh $@ ; fi + $(top_srcdir)/src/gen_snow_includes.sh $(top_srcdir) TESTS = test1.sh -# test2.sh and test3.sh are still available, they test xsnow using Xvfb and xdotool. -# I am not satisfied with the quality of these tests, so I left them out here. desktopdir = $(datadir)/applications desktop_DATA = xsnow.desktop diff -Nru xsnow-3.1.1/src/Makefile.in xsnow-3.3.2/src/Makefile.in --- xsnow-3.1.1/src/Makefile.in 2020-10-13 14:45:46.000000000 +0000 +++ xsnow-3.3.2/src/Makefile.in 2021-11-04 14:24:33.000000000 +0000 @@ -107,18 +107,20 @@ xsnow-pixmaps.$(OBJEXT) xsnow-windows.$(OBJEXT) \ xsnow-flags.$(OBJEXT) xsnow-csvpos.$(OBJEXT) \ xsnow-dsimple.$(OBJEXT) xsnow-clientwin.$(OBJEXT) \ - xsnow-ui.$(OBJEXT) xsnow-transparent.$(OBJEXT) \ - xsnow-mainstub.$(OBJEXT) xsnow-birds.$(OBJEXT) \ - xsnow-kdtree.$(OBJEXT) xsnow-hashtable.$(OBJEXT) \ - xsnow-Santa.$(OBJEXT) xsnow-utils.$(OBJEXT) \ - xsnow-scenery.$(OBJEXT) xsnow-snow.$(OBJEXT) \ - xsnow-meteo.$(OBJEXT) xsnow-wind.$(OBJEXT) \ - xsnow-stars.$(OBJEXT) xsnow-blowoff.$(OBJEXT) \ - xsnow-treesnow.$(OBJEXT) xsnow-loadmeasure.$(OBJEXT) + xsnow-ui.$(OBJEXT) xsnow-mainstub.$(OBJEXT) \ + xsnow-birds.$(OBJEXT) xsnow-kdtree.$(OBJEXT) \ + xsnow-hashtable.$(OBJEXT) xsnow-Santa.$(OBJEXT) \ + xsnow-utils.$(OBJEXT) xsnow-scenery.$(OBJEXT) \ + xsnow-snow.$(OBJEXT) xsnow-meteo.$(OBJEXT) \ + xsnow-wind.$(OBJEXT) xsnow-stars.$(OBJEXT) \ + xsnow-blowoff.$(OBJEXT) xsnow-treesnow.$(OBJEXT) \ + xsnow-loadmeasure.$(OBJEXT) xsnow-moon.$(OBJEXT) \ + xsnow-transwindow.$(OBJEXT) nodist_xsnow_OBJECTS = xsnow_OBJECTS = $(am_xsnow_OBJECTS) $(nodist_xsnow_OBJECTS) am__DEPENDENCIES_1 = -xsnow_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +xsnow_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false @@ -143,12 +145,12 @@ ./$(DEPDIR)/xsnow-ixpm.Po ./$(DEPDIR)/xsnow-kdtree.Po \ ./$(DEPDIR)/xsnow-loadmeasure.Po ./$(DEPDIR)/xsnow-main.Po \ ./$(DEPDIR)/xsnow-mainstub.Po ./$(DEPDIR)/xsnow-meteo.Po \ - ./$(DEPDIR)/xsnow-pixmaps.Po ./$(DEPDIR)/xsnow-scenery.Po \ - ./$(DEPDIR)/xsnow-snow.Po ./$(DEPDIR)/xsnow-stars.Po \ - ./$(DEPDIR)/xsnow-transparent.Po ./$(DEPDIR)/xsnow-treesnow.Po \ - ./$(DEPDIR)/xsnow-ui.Po ./$(DEPDIR)/xsnow-utils.Po \ - ./$(DEPDIR)/xsnow-wind.Po ./$(DEPDIR)/xsnow-windows.Po \ - ./$(DEPDIR)/xsnow-wmctrl.Po + ./$(DEPDIR)/xsnow-moon.Po ./$(DEPDIR)/xsnow-pixmaps.Po \ + ./$(DEPDIR)/xsnow-scenery.Po ./$(DEPDIR)/xsnow-snow.Po \ + ./$(DEPDIR)/xsnow-stars.Po ./$(DEPDIR)/xsnow-transwindow.Po \ + ./$(DEPDIR)/xsnow-treesnow.Po ./$(DEPDIR)/xsnow-ui.Po \ + ./$(DEPDIR)/xsnow-utils.Po ./$(DEPDIR)/xsnow-wind.Po \ + ./$(DEPDIR)/xsnow-windows.Po ./$(DEPDIR)/xsnow-wmctrl.Po am__mv = mv -f AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) @@ -458,7 +460,6 @@ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ -ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AUTOCONF = @AUTOCONF@ @@ -512,6 +513,8 @@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ +X11_CFLAGS = @X11_CFLAGS@ +X11_LIBS = @X11_LIBS@ XMKMF = @XMKMF@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ @@ -564,7 +567,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by @@ -581,31 +584,32 @@ #-# SUBDIRS = Pixmaps gamesdir = $(exec_prefix)/games -xsnow_CPPFLAGS = $(XML_CFLAGS) $(GTK_CFLAGS) -DUSE_LIST_NODE_ALLOCATOR -xsnow_LDADD = $(XML_LIBS) $(GTK_LIBS) +xsnow_CPPFLAGS = $(XML_CFLAGS) $(GTK_CFLAGS) $(X11_CFLAGS) +xsnow_LDADD = $(XML_LIBS) $(GTK_LIBS) $(X11_LIBS) xsnow_SOURCES = clocks.c ixpm.c main.c fallensnow.c wmctrl.c docs.c \ clocks.h ixpm.h docs.h fallensnow.h pixmaps.h \ pixmaps.c version.h wmctrl.h xsnow.h windows.c windows.h\ flags.c flags.h csvpos.c csvpos.h \ dsimple.c dsimple.h clientwin.c clientwin.h \ - test1.sh test2.sh test3.sh xsnow.desktop \ + test1.sh xsnow.desktop \ doit.h ui.c ui.h ui.xml \ - transparent.c transparent.h debug.h \ + debug.h \ mainstub.cpp mainstub.h \ - birds.c kdtree.c birds.h kdtree.h globals.h doitb.h \ + birds.c kdtree.c birds.h kdtree.h birdglobals.h doitb.h \ hashtable.cpp hashtable.h \ Santa.c Santa.h utils.c utils.h \ scenery.c scenery.h snow.c snow.h \ meteo.c meteo.h wind.c wind.h \ stars.c stars.h blowoff.c blowoff.h \ treesnow.c treesnow.h loadmeasure.c loadmeasure.h \ - varia.h snow_includes.h + snow_includes.h vroot.h \ + moon.c moon.h buttons.h undefall.inc \ + transwindow.c transwindow.h -nodist_xsnow_SOURCES = ui_xml.h +nodist_xsnow_SOURCES = ui_xml.h snow_includes.h BUILT_SOURCES = ui_xml.h snow_includes.h +EXTRA_DIST = gen_snow_includes.sh gen_ui_xml.sh TESTS = test1.sh -# test2.sh and test3.sh are still available, they test xsnow using Xvfb and xdotool. -# I am not satisfied with the quality of these tests, so I left them out here. desktopdir = $(datadir)/applications desktop_DATA = xsnow.desktop appicondir = $(datadir)/pixmaps @@ -716,11 +720,12 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xsnow-main.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xsnow-mainstub.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xsnow-meteo.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xsnow-moon.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xsnow-pixmaps.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xsnow-scenery.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xsnow-snow.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xsnow-stars.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xsnow-transparent.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xsnow-transwindow.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xsnow-treesnow.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xsnow-ui.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xsnow-utils.Po@am__quote@ # am--include-marker @@ -930,20 +935,6 @@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xsnow_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsnow-ui.obj `if test -f 'ui.c'; then $(CYGPATH_W) 'ui.c'; else $(CYGPATH_W) '$(srcdir)/ui.c'; fi` -xsnow-transparent.o: transparent.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xsnow_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsnow-transparent.o -MD -MP -MF $(DEPDIR)/xsnow-transparent.Tpo -c -o xsnow-transparent.o `test -f 'transparent.c' || echo '$(srcdir)/'`transparent.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xsnow-transparent.Tpo $(DEPDIR)/xsnow-transparent.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='transparent.c' object='xsnow-transparent.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xsnow_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsnow-transparent.o `test -f 'transparent.c' || echo '$(srcdir)/'`transparent.c - -xsnow-transparent.obj: transparent.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xsnow_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsnow-transparent.obj -MD -MP -MF $(DEPDIR)/xsnow-transparent.Tpo -c -o xsnow-transparent.obj `if test -f 'transparent.c'; then $(CYGPATH_W) 'transparent.c'; else $(CYGPATH_W) '$(srcdir)/transparent.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xsnow-transparent.Tpo $(DEPDIR)/xsnow-transparent.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='transparent.c' object='xsnow-transparent.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xsnow_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsnow-transparent.obj `if test -f 'transparent.c'; then $(CYGPATH_W) 'transparent.c'; else $(CYGPATH_W) '$(srcdir)/transparent.c'; fi` - xsnow-birds.o: birds.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xsnow_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsnow-birds.o -MD -MP -MF $(DEPDIR)/xsnow-birds.Tpo -c -o xsnow-birds.o `test -f 'birds.c' || echo '$(srcdir)/'`birds.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xsnow-birds.Tpo $(DEPDIR)/xsnow-birds.Po @@ -1112,6 +1103,34 @@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xsnow_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsnow-loadmeasure.obj `if test -f 'loadmeasure.c'; then $(CYGPATH_W) 'loadmeasure.c'; else $(CYGPATH_W) '$(srcdir)/loadmeasure.c'; fi` +xsnow-moon.o: moon.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xsnow_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsnow-moon.o -MD -MP -MF $(DEPDIR)/xsnow-moon.Tpo -c -o xsnow-moon.o `test -f 'moon.c' || echo '$(srcdir)/'`moon.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xsnow-moon.Tpo $(DEPDIR)/xsnow-moon.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='moon.c' object='xsnow-moon.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xsnow_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsnow-moon.o `test -f 'moon.c' || echo '$(srcdir)/'`moon.c + +xsnow-moon.obj: moon.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xsnow_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsnow-moon.obj -MD -MP -MF $(DEPDIR)/xsnow-moon.Tpo -c -o xsnow-moon.obj `if test -f 'moon.c'; then $(CYGPATH_W) 'moon.c'; else $(CYGPATH_W) '$(srcdir)/moon.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xsnow-moon.Tpo $(DEPDIR)/xsnow-moon.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='moon.c' object='xsnow-moon.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xsnow_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsnow-moon.obj `if test -f 'moon.c'; then $(CYGPATH_W) 'moon.c'; else $(CYGPATH_W) '$(srcdir)/moon.c'; fi` + +xsnow-transwindow.o: transwindow.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xsnow_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsnow-transwindow.o -MD -MP -MF $(DEPDIR)/xsnow-transwindow.Tpo -c -o xsnow-transwindow.o `test -f 'transwindow.c' || echo '$(srcdir)/'`transwindow.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xsnow-transwindow.Tpo $(DEPDIR)/xsnow-transwindow.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='transwindow.c' object='xsnow-transwindow.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xsnow_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsnow-transwindow.o `test -f 'transwindow.c' || echo '$(srcdir)/'`transwindow.c + +xsnow-transwindow.obj: transwindow.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xsnow_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xsnow-transwindow.obj -MD -MP -MF $(DEPDIR)/xsnow-transwindow.Tpo -c -o xsnow-transwindow.obj `if test -f 'transwindow.c'; then $(CYGPATH_W) 'transwindow.c'; else $(CYGPATH_W) '$(srcdir)/transwindow.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xsnow-transwindow.Tpo $(DEPDIR)/xsnow-transwindow.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='transwindow.c' object='xsnow-transwindow.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xsnow_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xsnow-transwindow.obj `if test -f 'transwindow.c'; then $(CYGPATH_W) 'transwindow.c'; else $(CYGPATH_W) '$(srcdir)/transwindow.c'; fi` + .cpp.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @@ -1625,11 +1644,12 @@ -rm -f ./$(DEPDIR)/xsnow-main.Po -rm -f ./$(DEPDIR)/xsnow-mainstub.Po -rm -f ./$(DEPDIR)/xsnow-meteo.Po + -rm -f ./$(DEPDIR)/xsnow-moon.Po -rm -f ./$(DEPDIR)/xsnow-pixmaps.Po -rm -f ./$(DEPDIR)/xsnow-scenery.Po -rm -f ./$(DEPDIR)/xsnow-snow.Po -rm -f ./$(DEPDIR)/xsnow-stars.Po - -rm -f ./$(DEPDIR)/xsnow-transparent.Po + -rm -f ./$(DEPDIR)/xsnow-transwindow.Po -rm -f ./$(DEPDIR)/xsnow-treesnow.Po -rm -f ./$(DEPDIR)/xsnow-ui.Po -rm -f ./$(DEPDIR)/xsnow-utils.Po @@ -1699,11 +1719,12 @@ -rm -f ./$(DEPDIR)/xsnow-main.Po -rm -f ./$(DEPDIR)/xsnow-mainstub.Po -rm -f ./$(DEPDIR)/xsnow-meteo.Po + -rm -f ./$(DEPDIR)/xsnow-moon.Po -rm -f ./$(DEPDIR)/xsnow-pixmaps.Po -rm -f ./$(DEPDIR)/xsnow-scenery.Po -rm -f ./$(DEPDIR)/xsnow-snow.Po -rm -f ./$(DEPDIR)/xsnow-stars.Po - -rm -f ./$(DEPDIR)/xsnow-transparent.Po + -rm -f ./$(DEPDIR)/xsnow-transwindow.Po -rm -f ./$(DEPDIR)/xsnow-treesnow.Po -rm -f ./$(DEPDIR)/xsnow-ui.Po -rm -f ./$(DEPDIR)/xsnow-utils.Po @@ -1754,37 +1775,13 @@ .PRECIOUS: Makefile -# create C code to get ui.xml in a string -# ISO C stipulates that the length of a string constant should -# not be larger than 4096, so we create a definition as in -# char xsnow_xml[] = {60,63,120,109,108,32,118,101,0}; -# ui_xml.h: ui.xml @echo "Creating $@ from $<" - @echo "/* This file is generated from $< by Makefile */" > $@ - @echo "/* -""copyright-" >> $@ - @echo "*/" >> $@ - @echo "#pragma once" >> $@ - @echo "char xsnow_xml[] = {" >> $@ - @sed 's/^ *//' $< | awk -v FS="" \ - 'BEGIN{for(n=0;n<256;n++)ord[sprintf("%c",n)]=n;}'\ - '{for (i=1;i<=NF;i++) printf "%d,", ord[$$i];'\ - 'printf "%d,\n",ord["\n"];}' >> $@ - @echo "0};" >> $@ - if [ -x $(top_srcdir)/addcopyright.sh ] ; then $(top_srcdir)/addcopyright.sh $@ ; fi + $(top_srcdir)/src/gen_ui_xml.sh $(top_srcdir) snow_includes.h: Pixmaps @echo "Creating $@" - @echo "#pragma once" > $@ - @echo "/* -""copyright-" >> $@ - @echo "*/" >> $@ - @ls $(top_srcdir)/src/Pixmaps/flake*.xpm | sed "s/^/#include \"/;s/$$/\"/" >> $@ - @echo "#define SNOW_ALL \\" >> $@ - @for i in $$(seq `ls $(top_srcdir)/src/Pixmaps/flake*.xpm | wc -l`) ; do \ - printf 'SNOW(%d) \\\n' `expr $$i - 1` ;\ - done >> $@ - @echo >> $@ - if [ -x $(top_srcdir)/addcopyright.sh ] ; then $(top_srcdir)/addcopyright.sh $@ ; fi + $(top_srcdir)/src/gen_snow_includes.sh $(top_srcdir) xsnow.6: xsnow ./xsnow -manpage > $@ diff -Nru xsnow-3.1.1/src/meteo.c xsnow-3.3.2/src/meteo.c --- xsnow-3.1.1/src/meteo.c 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/meteo.c 2021-11-04 14:24:28.000000000 +0000 @@ -2,7 +2,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by @@ -31,50 +31,33 @@ #include "meteo.h" #include "utils.h" #include "xsnow.h" -#include "varia.h" #define NOTACTIVE \ (Flags.BirdsOnly || !WorkspaceActive()) static int do_emeteorite(gpointer data); -static int do_meteorite(gpointer data); +static int do_meteorite(void *); static GdkRGBA color; static const char *MeteoColor = "orange"; -static Pixel MeteoPix; static MeteoMap meteorite; void meteo_init() { - { - if (!gdk_rgba_parse(&color, MeteoColor)) - gdk_rgba_parse(&color,"rgb(255,165,0)"); - } - { - meteorite.gc = XCreateGC(display, SnowWin, 0, NULL); - meteorite.egc = XCreateGC(display, SnowWin, 0, NULL); - MeteoPix = IAllocNamedColor(MeteoColor, White); - XSetLineAttributes(display, meteorite.gc, 1,LineSolid,CapRound,JoinMiter); - XSetLineAttributes(display, meteorite.egc, 1,LineSolid,CapRound,JoinMiter); - } - add_to_mainloop(PRIORITY_DEFAULT, time_emeteorite, do_emeteorite, NULL); - add_to_mainloop(PRIORITY_DEFAULT, time_meteorite, do_meteorite, NULL); + if (!gdk_rgba_parse(&color, MeteoColor)) + gdk_rgba_parse(&color,"rgb(255,165,0)"); + add_to_mainloop1(PRIORITY_DEFAULT, time_emeteorite, do_emeteorite, NULL); + add_to_mainloop (PRIORITY_DEFAULT, time_meteorite, do_meteorite); } -int meteo_ui() +void meteo_ui() { - int changes = 0; - if(Flags.NoMeteorites != OldFlags.NoMeteorites) - { - OldFlags.NoMeteorites = Flags.NoMeteorites; - changes++; - P("changes: %d %d\n",changes,Flags.NoMeteorites); - } - return changes; + UIDO(NoMeteorites , ); } void meteo_draw(cairo_t *cr) { + P("meteo_draw %d %d\n",counter++,meteorite.active); if (!meteorite.active) return; cairo_save(cr); @@ -92,43 +75,49 @@ void meteo_erase() { - int x=1; - do_emeteorite((gpointer)&x); + do_emeteorite(NULL); } int do_emeteorite(gpointer data) { + (void)data; if (Flags.Done) return FALSE; if (!meteorite.active || NOTACTIVE || Flags.NoMeteorites) return TRUE; - if (wallclock() - meteorite.starttime > 0.3 || data) + if (wallclock() - meteorite.starttime > 0.3) { - if (!switches.UseGtk) + if (!global.IsDouble) { - if(switches.Trans) + int x = meteorite.x1; + int y = meteorite.y1; + int w = meteorite.x2 - x; + int h = meteorite.y2 - y; + if (w<0) { - XSetFunction(display, meteorite.egc, GXcopy); - XSetForeground(display, meteorite.egc, ErasePixel); + x += w; + w = -w; } - else + if (h<0) { - XSetFunction(display, meteorite.egc, GXxor); - XSetForeground(display, meteorite.egc, MeteoPix); + y += h; + h = -h; } - XDrawLine(display, SnowWin, meteorite.egc, - meteorite.x1,meteorite.y1,meteorite.x2,meteorite.y2); - XSubtractRegion(NoSnowArea_dynamic ,meteorite.r,NoSnowArea_dynamic); - XDestroyRegion(meteorite.r); - XFlush(display); + x -= 1; + y -= 1; + w += 2; + h += 2; + myXClearArea(global.display,global.SnowWin,x,y,w,h,global.xxposures); } meteorite.active = 0; } return TRUE; } -int do_meteorite(UNUSED gpointer data) +int do_meteorite(void *d) { + (void)d; + P("do_meteorite %d\n",counter++); if (Flags.Done) return FALSE; if (NOTACTIVE) @@ -137,47 +126,15 @@ if(Flags.NoMeteorites) return TRUE; if (drand48() > 0.2) return TRUE; - meteorite.x1 = randint(SnowWinWidth); - meteorite.y1 = randint(SnowWinHeight/4); - meteorite.x2 = meteorite.x1 + SnowWinWidth/10 - randint(SnowWinWidth/5); + meteorite.x1 = randint(global.SnowWinWidth); + meteorite.y1 = randint(global.SnowWinHeight/4); + meteorite.x2 = meteorite.x1 + global.SnowWinWidth/10 - randint(global.SnowWinWidth/5); if (meteorite.x2 == meteorite.x1) meteorite.x2 +=5; - meteorite.y2 = meteorite.y1 + SnowWinHeight/5 - randint(SnowWinHeight/5); + meteorite.y2 = meteorite.y1 + global.SnowWinHeight/5 - randint(global.SnowWinHeight/5); if (meteorite.y2 == meteorite.y1) meteorite.y2 +=5; meteorite.active = 1; - if(!switches.UseGtk) - { - if(switches.Trans) - { - XSetFunction(display, meteorite.gc, GXcopy); - XSetForeground(display, meteorite.gc, MeteoPix); - } - else - { - XSetFunction(display, meteorite.gc, GXxor); - XSetForeground(display, meteorite.gc, MeteoPix); - } - const int npoints = 5; - XPoint points[npoints]; - - points[0].x = meteorite.x1+1; - points[0].y = meteorite.y1-1; - points[1].x = meteorite.x2+1; - points[1].y = meteorite.y2-1; - points[2].x = meteorite.x2-1; - points[2].y = meteorite.y2+1; - points[3].x = meteorite.x1-1; - points[3].y = meteorite.y1+1; - points[4].x = meteorite.x1+1; - points[4].y = meteorite.y1-1; - - meteorite.r = XPolygonRegion(points,npoints,EvenOddRule); - XUnionRegion(meteorite.r,NoSnowArea_dynamic,NoSnowArea_dynamic); - XDrawLine(display, SnowWin, meteorite.gc, - meteorite.x1,meteorite.y1,meteorite.x2,meteorite.y2); - XFlush(display); - } meteorite.starttime = wallclock(); return TRUE; diff -Nru xsnow-3.1.1/src/meteo.h xsnow-3.3.2/src/meteo.h --- xsnow-3.1.1/src/meteo.h 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/meteo.h 2021-11-04 14:24:28.000000000 +0000 @@ -2,7 +2,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by @@ -20,16 +20,10 @@ */ #pragma once -typedef struct _MeteoMap { - int x1,x2,y1,y2,active; - double starttime; - GC gc,egc; - Region r; -} MeteoMap; - +#include extern void meteo_init(void); -extern int meteo_ui(void); +extern void meteo_ui(void); extern void meteo_draw(cairo_t *cr); extern void meteo_erase(void); diff -Nru xsnow-3.1.1/src/moon.c xsnow-3.3.2/src/moon.c --- xsnow-3.1.1/src/moon.c 1970-01-01 00:00:00.000000000 +0000 +++ xsnow-3.3.2/src/moon.c 2021-11-04 14:24:28.000000000 +0000 @@ -0,0 +1,242 @@ +/* -copyright- +#-# +#-# xsnow: let it snow on your desktop +#-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen +#-# 2019,2020,2021 Willem Vermin +#-# +#-# This program is free software: you can redistribute it and/or modify +#-# it under the terms of the GNU General Public License as published by +#-# the Free Software Foundation, either version 3 of the License, or +#-# (at your option) any later version. +#-# +#-# This program is distributed in the hope that it will be useful, +#-# but WITHOUT ANY WARRANTY; without even the implied warranty of +#-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +#-# GNU General Public License for more details. +#-# +#-# You should have received a copy of the GNU General Public License +#-# along with this program. If not, see . +#-# +*/ + +#include +#include +#include "debug.h" +#include "flags.h" +#include "moon.h" +#include "pixmaps.h" +#include "utils.h" +#include "windows.h" + + +#define LEAVE_IF_INACTIVE\ + if (!Flags.Moon || !WorkspaceActive()) return TRUE + +static int do_umoon(void *); +static void init_moon_surface(void); +static void init_halo_surface(void); +static void halo_draw(cairo_t *cr); +static void halo_erase(); + +static cairo_surface_t *moon_surface = NULL; +static cairo_surface_t *halo_surface = NULL; +static double haloR; // radius of halo in pixels + +static double OldmoonX; +static double OldmoonY; + +static float moonScale; + +void moon_init(void) +{ + moonScale = (float)Flags.Scale*0.01*global.WindowScale; + init_moon_surface(); + add_to_mainloop(PRIORITY_DEFAULT, time_umoon, do_umoon); + if (global.SnowWinWidth > 400*moonScale) + global.moonX = moonScale*200+drand48()*(global.SnowWinWidth - 400*moonScale - 2*global.moonR); +} + +int moon_draw(cairo_t *cr) +{ + LEAVE_IF_INACTIVE; + P("moon_draw %d %d %d\n",counter++,(int)global.moonX,(int)global.moonY); + cairo_set_source_surface (cr, moon_surface, global.moonX, global.moonY); + my_cairo_paint_with_alpha(cr,ALPHA); + OldmoonX = global.moonX; + OldmoonY = global.moonY; + halo_draw(cr); + return TRUE; +} + +int moon_erase(int force) +{ + if(global.IsDouble) + return 0; + if(!force) + LEAVE_IF_INACTIVE; + if (Flags.Halo) + { + halo_erase(); + } + else + { + myXClearArea(global.display, global.SnowWin, + OldmoonX, OldmoonY, + 2*global.moonR+1,2*global.moonR+1, + global.xxposures); + } + return 0; +} + + +void moon_ui() +{ + UIDO(MoonSpeed, ); + UIDO(Halo ,halo_erase(); ); + UIDO(Moon ,moon_erase(1); ); + UIDO(MoonSize ,init_moon_surface(); ); + UIDO(HaloBright ,init_halo_surface(); ); + + static int prevw = 0; + static int prevh = 0; + + static int prev; + if(ScaleChanged(&prev)) + { + P("%d moonscale\n",global.counter); + moonScale = 0.01*global.WindowScale*Flags.Scale; + init_moon_surface(); + if(prevw>0 && prevh>0) + { + global.moonX = (float)global.moonX/prevw*global.SnowWinWidth; + global.moonY = (float)global.moonY/prevh*global.SnowWinHeight; + } + prevw = global.SnowWinWidth; + prevh = global.SnowWinHeight; + } +} + +static void init_moon_surface() +{ + const GdkInterpType interpolation = GDK_INTERP_HYPER; + int whichmoon = 0; + static GdkPixbuf *pixbuf, *pixbufscaled; + pixbuf = gdk_pixbuf_new_from_xpm_data((const char **)moons_xpm[whichmoon]); + // standard moon is some percentage of window width + const float p = 30.0; + global.moonR = p*Flags.MoonSize*0.01*moonScale; + int w = global.moonR*2; + int h = w; + if(moon_surface) + cairo_surface_destroy(moon_surface); + if (w < 1) { w = 1; h = 1;} + if (w == 1 && h == 1) h = 2; + pixbufscaled = gdk_pixbuf_scale_simple(pixbuf,w,h,interpolation); + moon_surface = gdk_cairo_surface_create_from_pixbuf (pixbufscaled, 0, NULL); + g_clear_object(&pixbuf); + g_clear_object(&pixbufscaled); + init_halo_surface(); + if (!global.IsDouble) + ClearScreen(); +} + +int do_umoon(void *d) +{ + (void)d; + static int xdirection = 1; + static int ydirection = 1; + if (Flags.Done) + return FALSE; + LEAVE_IF_INACTIVE; + if(!Flags.Moon) + return TRUE; + + + global.moonX += xdirection*time_umoon*Flags.MoonSpeed/60.0; + global.moonY += 0.2*ydirection*time_umoon*Flags.MoonSpeed/60.0; + + if (global.moonX > global.SnowWinWidth - 2*global.moonR) + { + global.moonX = global.SnowWinWidth - 2*global.moonR; + xdirection = -1; + } + else if (global.moonX < 2*global.moonR) + { + global.moonX = 2*global.moonR; + xdirection = 1; + } + + if (global.moonY > 2*global.moonR) + { + global.moonY = 2*global.moonR; + ydirection = -1; + } + else if (global.moonY < 2*global.moonR) + { + global.moonY = 2*global.moonR; + ydirection = 1; + } + + return TRUE; +} + +void init_halo_surface() +{ + if (halo_surface) + cairo_surface_destroy(halo_surface); + cairo_pattern_t *pattern; + haloR = 1.8*global.moonR; + P("halo_draw %f %f \n",global.moonR,haloR); + pattern = cairo_pattern_create_radial(haloR, haloR, global.moonR, haloR, haloR, haloR); + double bright = Flags.HaloBright * ALPHA * 0.01; + //cairo_pattern_add_color_stop_rgba(pattern, 0.0, 1.0, 1.0, 1.0, 0.4*ALPHA); + //cairo_pattern_add_color_stop_rgba(pattern, 1.0, 1.0, 1.0, 1.0, 0.0); + //cairo_pattern_add_color_stop_rgba(pattern, 0.0, 0.9725, 0.9725, 1.0, 0.4*ALPHA); + //cairo_pattern_add_color_stop_rgba(pattern, 1.0, 0.9725, 0.9725, 1.0, 0.0); + //cairo_pattern_add_color_stop_rgba(pattern, 0.0, 0.96078, 0.96078, 0.96078, 0.4*ALPHA); + //cairo_pattern_add_color_stop_rgba(pattern, 1.0, 0.96078, 0.96078, 0.96078, 0.0); + //cairo_pattern_add_color_stop_rgba(pattern, 0.0, 0.94, 0.94, 0.9, 0.4*ALPHA); + //cairo_pattern_add_color_stop_rgba(pattern, 1.0, 0.94, 0.94, 0.9, 0.0); + //cairo_pattern_add_color_stop_rgba(pattern, 0.0, 244.0/255, 241.0/255, 201.0/255, 0.4*ALPHA); + //cairo_pattern_add_color_stop_rgba(pattern, 1.0, 244.0/255, 241.0/255, 201.0/255, 0.0); + //cairo_pattern_add_color_stop_rgba(pattern, 0.0, 245.0/255, 243.0/255, 206.0/255, 0.4*ALPHA); + //cairo_pattern_add_color_stop_rgba(pattern, 1.0, 245.0/255, 243.0/255, 206.0/255, 0.0); + cairo_pattern_add_color_stop_rgba(pattern, 0.0, 234.0/255, 244.0/255, 252.0/255, bright); + cairo_pattern_add_color_stop_rgba(pattern, 1.0, 234.0/255, 244.0/255, 252.0/255, 0.0); + + GdkPixbuf *pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, 2*haloR, 2*haloR); + halo_surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 2*haloR, 2*haloR); + cairo_t *halocr = cairo_create(halo_surface); + gdk_cairo_set_source_pixbuf(halocr, pixbuf, 0, 0); + + cairo_set_source_rgba(halocr, 0, 0, 0, 0); + cairo_paint (halocr); + cairo_set_source (halocr, pattern); + cairo_arc (halocr, haloR, haloR, haloR, 0, M_PI * 2); + cairo_fill (halocr); + + cairo_destroy (halocr); + cairo_pattern_destroy (pattern); + g_clear_object (&pixbuf); +} + +void halo_draw(cairo_t *cr) +{ + if (!Flags.Halo) + return; + P("halo_draw %f %f \n", global.moonR, haloR); + double xc = global.moonX + global.moonR; + double yc = global.moonY + global.moonR; + + cairo_set_source_surface(cr, halo_surface, xc-haloR, yc-haloR); + my_cairo_paint_with_alpha(cr, ALPHA); +} + +void halo_erase() +{ + int x = OldmoonX + global.moonR - haloR; + int y = OldmoonY + global.moonR - haloR; + int w = 2*haloR; + int h = w; + myXClearArea(global.display,global.SnowWin,x,y,w+1,h+1,global.xxposures); +} diff -Nru xsnow-3.1.1/src/moon.h xsnow-3.3.2/src/moon.h --- xsnow-3.1.1/src/moon.h 1970-01-01 00:00:00.000000000 +0000 +++ xsnow-3.3.2/src/moon.h 2021-11-04 14:24:28.000000000 +0000 @@ -0,0 +1,29 @@ +/* -copyright- +#-# +#-# xsnow: let it snow on your desktop +#-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen +#-# 2019,2020,2021 Willem Vermin +#-# +#-# This program is free software: you can redistribute it and/or modify +#-# it under the terms of the GNU General Public License as published by +#-# the Free Software Foundation, either version 3 of the License, or +#-# (at your option) any later version. +#-# +#-# This program is distributed in the hope that it will be useful, +#-# but WITHOUT ANY WARRANTY; without even the implied warranty of +#-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +#-# GNU General Public License for more details. +#-# +#-# You should have received a copy of the GNU General Public License +#-# along with this program. If not, see . +#-# + */ +#pragma once + +#include + +extern int moon_draw(cairo_t *cr); +extern void moon_init(void); +extern void moon_ui(void); +extern int moon_erase(int force); + diff -Nru xsnow-3.1.1/src/Pixmaps/AltSanta1.xpm xsnow-3.3.2/src/Pixmaps/AltSanta1.xpm --- xsnow-3.1.1/src/Pixmaps/AltSanta1.xpm 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/AltSanta1.xpm 2021-11-04 14:24:27.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/Pixmaps/AltSanta2.xpm xsnow-3.3.2/src/Pixmaps/AltSanta2.xpm --- xsnow-3.1.1/src/Pixmaps/AltSanta2.xpm 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/AltSanta2.xpm 2021-11-04 14:24:28.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/Pixmaps/AltSanta3.xpm xsnow-3.3.2/src/Pixmaps/AltSanta3.xpm --- xsnow-3.1.1/src/Pixmaps/AltSanta3.xpm 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/AltSanta3.xpm 2021-11-04 14:24:28.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/Pixmaps/AltSanta4.xpm xsnow-3.3.2/src/Pixmaps/AltSanta4.xpm --- xsnow-3.1.1/src/Pixmaps/AltSanta4.xpm 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/AltSanta4.xpm 2021-11-04 14:24:27.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/Pixmaps/AltSantaRudolf1.xpm xsnow-3.3.2/src/Pixmaps/AltSantaRudolf1.xpm --- xsnow-3.1.1/src/Pixmaps/AltSantaRudolf1.xpm 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/AltSantaRudolf1.xpm 2021-11-04 14:24:28.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/Pixmaps/AltSantaRudolf2.xpm xsnow-3.3.2/src/Pixmaps/AltSantaRudolf2.xpm --- xsnow-3.1.1/src/Pixmaps/AltSantaRudolf2.xpm 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/AltSantaRudolf2.xpm 2021-11-04 14:24:28.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/Pixmaps/AltSantaRudolf3.xpm xsnow-3.3.2/src/Pixmaps/AltSantaRudolf3.xpm --- xsnow-3.1.1/src/Pixmaps/AltSantaRudolf3.xpm 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/AltSantaRudolf3.xpm 2021-11-04 14:24:28.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/Pixmaps/AltSantaRudolf4.xpm xsnow-3.3.2/src/Pixmaps/AltSantaRudolf4.xpm --- xsnow-3.1.1/src/Pixmaps/AltSantaRudolf4.xpm 2020-10-13 12:50:56.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/AltSantaRudolf4.xpm 2021-11-04 14:24:27.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/Pixmaps/BigSanta1.xpm xsnow-3.3.2/src/Pixmaps/BigSanta1.xpm --- xsnow-3.1.1/src/Pixmaps/BigSanta1.xpm 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/BigSanta1.xpm 2021-11-04 14:24:27.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/Pixmaps/BigSanta2.xpm xsnow-3.3.2/src/Pixmaps/BigSanta2.xpm --- xsnow-3.1.1/src/Pixmaps/BigSanta2.xpm 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/BigSanta2.xpm 2021-11-04 14:24:28.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/Pixmaps/BigSanta3.xpm xsnow-3.3.2/src/Pixmaps/BigSanta3.xpm --- xsnow-3.1.1/src/Pixmaps/BigSanta3.xpm 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/BigSanta3.xpm 2021-11-04 14:24:27.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/Pixmaps/BigSanta4.xpm xsnow-3.3.2/src/Pixmaps/BigSanta4.xpm --- xsnow-3.1.1/src/Pixmaps/BigSanta4.xpm 2020-10-13 12:50:56.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/BigSanta4.xpm 2021-11-04 14:24:27.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/Pixmaps/BigSanta81.xpm xsnow-3.3.2/src/Pixmaps/BigSanta81.xpm --- xsnow-3.1.1/src/Pixmaps/BigSanta81.xpm 2020-10-13 12:50:56.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/BigSanta81.xpm 2021-11-04 14:24:27.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/Pixmaps/BigSanta82.xpm xsnow-3.3.2/src/Pixmaps/BigSanta82.xpm --- xsnow-3.1.1/src/Pixmaps/BigSanta82.xpm 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/BigSanta82.xpm 2021-11-04 14:24:28.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/Pixmaps/BigSanta83.xpm xsnow-3.3.2/src/Pixmaps/BigSanta83.xpm --- xsnow-3.1.1/src/Pixmaps/BigSanta83.xpm 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/BigSanta83.xpm 2021-11-04 14:24:28.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/Pixmaps/BigSanta84.xpm xsnow-3.3.2/src/Pixmaps/BigSanta84.xpm --- xsnow-3.1.1/src/Pixmaps/BigSanta84.xpm 2020-10-13 12:50:56.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/BigSanta84.xpm 2021-11-04 14:24:27.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/Pixmaps/BigSantaRudolf1.xpm xsnow-3.3.2/src/Pixmaps/BigSantaRudolf1.xpm --- xsnow-3.1.1/src/Pixmaps/BigSantaRudolf1.xpm 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/BigSantaRudolf1.xpm 2021-11-04 14:24:27.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/Pixmaps/BigSantaRudolf2.xpm xsnow-3.3.2/src/Pixmaps/BigSantaRudolf2.xpm --- xsnow-3.1.1/src/Pixmaps/BigSantaRudolf2.xpm 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/BigSantaRudolf2.xpm 2021-11-04 14:24:28.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/Pixmaps/BigSantaRudolf3.xpm xsnow-3.3.2/src/Pixmaps/BigSantaRudolf3.xpm --- xsnow-3.1.1/src/Pixmaps/BigSantaRudolf3.xpm 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/BigSantaRudolf3.xpm 2021-11-04 14:24:28.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/Pixmaps/BigSantaRudolf4.xpm xsnow-3.3.2/src/Pixmaps/BigSantaRudolf4.xpm --- xsnow-3.1.1/src/Pixmaps/BigSantaRudolf4.xpm 2020-10-13 12:50:56.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/BigSantaRudolf4.xpm 2021-11-04 14:24:27.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/Pixmaps/BigSantaRudolf81.xpm xsnow-3.3.2/src/Pixmaps/BigSantaRudolf81.xpm --- xsnow-3.1.1/src/Pixmaps/BigSantaRudolf81.xpm 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/BigSantaRudolf81.xpm 2021-11-04 14:24:28.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/Pixmaps/BigSantaRudolf82.xpm xsnow-3.3.2/src/Pixmaps/BigSantaRudolf82.xpm --- xsnow-3.1.1/src/Pixmaps/BigSantaRudolf82.xpm 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/BigSantaRudolf82.xpm 2021-11-04 14:24:27.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/Pixmaps/BigSantaRudolf83.xpm xsnow-3.3.2/src/Pixmaps/BigSantaRudolf83.xpm --- xsnow-3.1.1/src/Pixmaps/BigSantaRudolf83.xpm 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/BigSantaRudolf83.xpm 2021-11-04 14:24:28.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/Pixmaps/BigSantaRudolf84.xpm xsnow-3.3.2/src/Pixmaps/BigSantaRudolf84.xpm --- xsnow-3.1.1/src/Pixmaps/BigSantaRudolf84.xpm 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/BigSantaRudolf84.xpm 2021-11-04 14:24:28.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/Pixmaps/bird1.xpm xsnow-3.3.2/src/Pixmaps/bird1.xpm --- xsnow-3.1.1/src/Pixmaps/bird1.xpm 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/bird1.xpm 2021-11-04 14:24:28.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/Pixmaps/bird2.xpm xsnow-3.3.2/src/Pixmaps/bird2.xpm --- xsnow-3.1.1/src/Pixmaps/bird2.xpm 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/bird2.xpm 2021-11-04 14:24:28.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/Pixmaps/bird3.xpm xsnow-3.3.2/src/Pixmaps/bird3.xpm --- xsnow-3.1.1/src/Pixmaps/bird3.xpm 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/bird3.xpm 2021-11-04 14:24:28.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/Pixmaps/bird4.xpm xsnow-3.3.2/src/Pixmaps/bird4.xpm --- xsnow-3.1.1/src/Pixmaps/bird4.xpm 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/bird4.xpm 2021-11-04 14:24:28.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/Pixmaps/bird5.xpm xsnow-3.3.2/src/Pixmaps/bird5.xpm --- xsnow-3.1.1/src/Pixmaps/bird5.xpm 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/bird5.xpm 2021-11-04 14:24:28.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/Pixmaps/bird6.xpm xsnow-3.3.2/src/Pixmaps/bird6.xpm --- xsnow-3.1.1/src/Pixmaps/bird6.xpm 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/bird6.xpm 2021-11-04 14:24:27.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/Pixmaps/bird7.xpm xsnow-3.3.2/src/Pixmaps/bird7.xpm --- xsnow-3.1.1/src/Pixmaps/bird7.xpm 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/bird7.xpm 2021-11-04 14:24:28.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/Pixmaps/bird8.xpm xsnow-3.3.2/src/Pixmaps/bird8.xpm --- xsnow-3.1.1/src/Pixmaps/bird8.xpm 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/bird8.xpm 2021-11-04 14:24:28.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/Pixmaps/birdd1.xpm xsnow-3.3.2/src/Pixmaps/birdd1.xpm --- xsnow-3.1.1/src/Pixmaps/birdd1.xpm 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/birdd1.xpm 2021-11-04 14:24:28.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/Pixmaps/birdd2.xpm xsnow-3.3.2/src/Pixmaps/birdd2.xpm --- xsnow-3.1.1/src/Pixmaps/birdd2.xpm 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/birdd2.xpm 2021-11-04 14:24:27.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/Pixmaps/birdd3.xpm xsnow-3.3.2/src/Pixmaps/birdd3.xpm --- xsnow-3.1.1/src/Pixmaps/birdd3.xpm 2020-10-13 12:50:56.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/birdd3.xpm 2021-11-04 14:24:27.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/Pixmaps/birdd4.xpm xsnow-3.3.2/src/Pixmaps/birdd4.xpm --- xsnow-3.1.1/src/Pixmaps/birdd4.xpm 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/birdd4.xpm 2021-11-04 14:24:27.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/Pixmaps/birdd5.xpm xsnow-3.3.2/src/Pixmaps/birdd5.xpm --- xsnow-3.1.1/src/Pixmaps/birdd5.xpm 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/birdd5.xpm 2021-11-04 14:24:27.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/Pixmaps/birdd6.xpm xsnow-3.3.2/src/Pixmaps/birdd6.xpm --- xsnow-3.1.1/src/Pixmaps/birdd6.xpm 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/birdd6.xpm 2021-11-04 14:24:27.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/Pixmaps/birdd7.xpm xsnow-3.3.2/src/Pixmaps/birdd7.xpm --- xsnow-3.1.1/src/Pixmaps/birdd7.xpm 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/birdd7.xpm 2021-11-04 14:24:28.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/Pixmaps/birdd8.xpm xsnow-3.3.2/src/Pixmaps/birdd8.xpm --- xsnow-3.1.1/src/Pixmaps/birdd8.xpm 2020-10-13 12:50:56.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/birdd8.xpm 2021-11-04 14:24:27.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/Pixmaps/birdl1.xpm xsnow-3.3.2/src/Pixmaps/birdl1.xpm --- xsnow-3.1.1/src/Pixmaps/birdl1.xpm 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/birdl1.xpm 2021-11-04 14:24:28.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/Pixmaps/birdl2.xpm xsnow-3.3.2/src/Pixmaps/birdl2.xpm --- xsnow-3.1.1/src/Pixmaps/birdl2.xpm 2020-10-13 12:50:56.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/birdl2.xpm 2021-11-04 14:24:27.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/Pixmaps/birdl3.xpm xsnow-3.3.2/src/Pixmaps/birdl3.xpm --- xsnow-3.1.1/src/Pixmaps/birdl3.xpm 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/birdl3.xpm 2021-11-04 14:24:27.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/Pixmaps/birdl4.xpm xsnow-3.3.2/src/Pixmaps/birdl4.xpm --- xsnow-3.1.1/src/Pixmaps/birdl4.xpm 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/birdl4.xpm 2021-11-04 14:24:28.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/Pixmaps/birdl5.xpm xsnow-3.3.2/src/Pixmaps/birdl5.xpm --- xsnow-3.1.1/src/Pixmaps/birdl5.xpm 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/birdl5.xpm 2021-11-04 14:24:28.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/Pixmaps/birdl6.xpm xsnow-3.3.2/src/Pixmaps/birdl6.xpm --- xsnow-3.1.1/src/Pixmaps/birdl6.xpm 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/birdl6.xpm 2021-11-04 14:24:28.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/Pixmaps/birdl7.xpm xsnow-3.3.2/src/Pixmaps/birdl7.xpm --- xsnow-3.1.1/src/Pixmaps/birdl7.xpm 2020-10-13 12:50:56.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/birdl7.xpm 2021-11-04 14:24:27.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/Pixmaps/birdl8.xpm xsnow-3.3.2/src/Pixmaps/birdl8.xpm --- xsnow-3.1.1/src/Pixmaps/birdl8.xpm 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/birdl8.xpm 2021-11-04 14:24:28.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/Pixmaps/eland.xpm xsnow-3.3.2/src/Pixmaps/eland.xpm --- xsnow-3.1.1/src/Pixmaps/eland.xpm 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/eland.xpm 2021-11-04 14:24:28.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/Pixmaps/flake0.xpm xsnow-3.3.2/src/Pixmaps/flake0.xpm --- xsnow-3.1.1/src/Pixmaps/flake0.xpm 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/flake0.xpm 2021-11-04 14:24:28.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/Pixmaps/flake1.xpm xsnow-3.3.2/src/Pixmaps/flake1.xpm --- xsnow-3.1.1/src/Pixmaps/flake1.xpm 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/flake1.xpm 2021-11-04 14:24:28.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/Pixmaps/flake2.xpm xsnow-3.3.2/src/Pixmaps/flake2.xpm --- xsnow-3.1.1/src/Pixmaps/flake2.xpm 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/flake2.xpm 2021-11-04 14:24:28.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/Pixmaps/flake3.xpm xsnow-3.3.2/src/Pixmaps/flake3.xpm --- xsnow-3.1.1/src/Pixmaps/flake3.xpm 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/flake3.xpm 2021-11-04 14:24:28.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/Pixmaps/flake4.xpm xsnow-3.3.2/src/Pixmaps/flake4.xpm --- xsnow-3.1.1/src/Pixmaps/flake4.xpm 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/flake4.xpm 2021-11-04 14:24:28.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/Pixmaps/flake5.xpm xsnow-3.3.2/src/Pixmaps/flake5.xpm --- xsnow-3.1.1/src/Pixmaps/flake5.xpm 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/flake5.xpm 2021-11-04 14:24:28.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/Pixmaps/flake6.xpm xsnow-3.3.2/src/Pixmaps/flake6.xpm --- xsnow-3.1.1/src/Pixmaps/flake6.xpm 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/flake6.xpm 2021-11-04 14:24:28.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/Pixmaps/huis4.xpm xsnow-3.3.2/src/Pixmaps/huis4.xpm --- xsnow-3.1.1/src/Pixmaps/huis4.xpm 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/huis4.xpm 2021-11-04 14:24:28.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/Pixmaps/Makefile.am xsnow-3.3.2/src/Pixmaps/Makefile.am --- xsnow-3.1.1/src/Pixmaps/Makefile.am 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/Makefile.am 2021-11-04 14:24:28.000000000 +0000 @@ -2,7 +2,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/Pixmaps/Makefile.in xsnow-3.3.2/src/Pixmaps/Makefile.in --- xsnow-3.1.1/src/Pixmaps/Makefile.in 2020-10-13 14:45:46.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/Makefile.in 2021-11-04 14:24:33.000000000 +0000 @@ -118,7 +118,6 @@ am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/make.inc DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ -ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AUTOCONF = @AUTOCONF@ @@ -172,6 +171,8 @@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ +X11_CFLAGS = @X11_CFLAGS@ +X11_LIBS = @X11_LIBS@ XMKMF = @XMKMF@ XML_CFLAGS = @XML_CFLAGS@ XML_LIBS = @XML_LIBS@ @@ -224,7 +225,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by @@ -306,6 +307,7 @@ MediumSantaRudolf2.xpm \ MediumSantaRudolf3.xpm \ MediumSantaRudolf4.xpm \ +moon1.xpm \ polarbear.xpm \ RegularSanta1.xpm \ RegularSanta2.xpm \ @@ -321,8 +323,6 @@ tannenbaum.xpm \ tree-1_100px.xpm \ tree.xpm \ -xsnow.jpg \ -xsnow.png \ xsnow.svg \ xsnow.xpm @@ -519,7 +519,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/Pixmaps/make.inc xsnow-3.3.2/src/Pixmaps/make.inc --- xsnow-3.1.1/src/Pixmaps/make.inc 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/make.inc 2021-11-04 14:24:28.000000000 +0000 @@ -2,7 +2,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by @@ -84,6 +84,7 @@ MediumSantaRudolf2.xpm \ MediumSantaRudolf3.xpm \ MediumSantaRudolf4.xpm \ +moon1.xpm \ polarbear.xpm \ RegularSanta1.xpm \ RegularSanta2.xpm \ @@ -99,7 +100,5 @@ tannenbaum.xpm \ tree-1_100px.xpm \ tree.xpm \ -xsnow.jpg \ -xsnow.png \ xsnow.svg \ xsnow.xpm diff -Nru xsnow-3.1.1/src/Pixmaps/MediumSanta1.xpm xsnow-3.3.2/src/Pixmaps/MediumSanta1.xpm --- xsnow-3.1.1/src/Pixmaps/MediumSanta1.xpm 2020-10-13 12:50:56.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/MediumSanta1.xpm 2021-11-04 14:24:27.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/Pixmaps/MediumSanta2.xpm xsnow-3.3.2/src/Pixmaps/MediumSanta2.xpm --- xsnow-3.1.1/src/Pixmaps/MediumSanta2.xpm 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/MediumSanta2.xpm 2021-11-04 14:24:28.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/Pixmaps/MediumSanta3.xpm xsnow-3.3.2/src/Pixmaps/MediumSanta3.xpm --- xsnow-3.1.1/src/Pixmaps/MediumSanta3.xpm 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/MediumSanta3.xpm 2021-11-04 14:24:28.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/Pixmaps/MediumSanta4.xpm xsnow-3.3.2/src/Pixmaps/MediumSanta4.xpm --- xsnow-3.1.1/src/Pixmaps/MediumSanta4.xpm 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/MediumSanta4.xpm 2021-11-04 14:24:28.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/Pixmaps/MediumSantaRudolf1.xpm xsnow-3.3.2/src/Pixmaps/MediumSantaRudolf1.xpm --- xsnow-3.1.1/src/Pixmaps/MediumSantaRudolf1.xpm 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/MediumSantaRudolf1.xpm 2021-11-04 14:24:28.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/Pixmaps/MediumSantaRudolf2.xpm xsnow-3.3.2/src/Pixmaps/MediumSantaRudolf2.xpm --- xsnow-3.1.1/src/Pixmaps/MediumSantaRudolf2.xpm 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/MediumSantaRudolf2.xpm 2021-11-04 14:24:27.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/Pixmaps/MediumSantaRudolf3.xpm xsnow-3.3.2/src/Pixmaps/MediumSantaRudolf3.xpm --- xsnow-3.1.1/src/Pixmaps/MediumSantaRudolf3.xpm 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/MediumSantaRudolf3.xpm 2021-11-04 14:24:27.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/Pixmaps/MediumSantaRudolf4.xpm xsnow-3.3.2/src/Pixmaps/MediumSantaRudolf4.xpm --- xsnow-3.1.1/src/Pixmaps/MediumSantaRudolf4.xpm 2020-10-13 12:50:56.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/MediumSantaRudolf4.xpm 2021-11-04 14:24:27.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/Pixmaps/moon1.xpm xsnow-3.3.2/src/Pixmaps/moon1.xpm --- xsnow-3.1.1/src/Pixmaps/moon1.xpm 1970-01-01 00:00:00.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/moon1.xpm 2021-11-04 14:24:28.000000000 +0000 @@ -0,0 +1,471 @@ +/* XPM */ +/* Thanks to Pedro Lasta on Unsplash https://unsplash.com/photos/wCujVcf0JDw */ +/* -copyright- +#-# +#-# xsnow: let it snow on your desktop +#-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen +#-# 2019,2020,2021 Willem Vermin +#-# +#-# This program is free software: you can redistribute it and/or modify +#-# it under the terms of the GNU General Public License as published by +#-# the Free Software Foundation, either version 3 of the License, or +#-# (at your option) any later version. +#-# +#-# This program is distributed in the hope that it will be useful, +#-# but WITHOUT ANY WARRANTY; without even the implied warranty of +#-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +#-# GNU General Public License for more details. +#-# +#-# You should have received a copy of the GNU General Public License +#-# along with this program. If not, see . +#-# +*/ +XPM_TYPE *moon1_xpm[] = { +/* columns rows colors chars-per-pixel */ +"255 256 188 2 ", +" c #63583D", +". c #665D43", +"X c #695D45", +"o c #6C6345", +"O c #666448", +"+ c #6D654A", +"@ c #6E6A4D", +"# c #666247", +"$ c #72674C", +"% c #736B4E", +"& c #786C4F", +"* c #6C6F53", +"= c #756D51", +"- c #7B6E53", +"; c #6F7257", +": c #767454", +"> c #7C7254", +", c #7E7559", +"< c #7D7B5C", +"1 c #747659", +"2 c #7C7E61", +"3 c #817456", +"4 c #847659", +"5 c #857A5C", +"6 c #8B7C5D", +"7 c #88775B", +"8 c #857D63", +"9 c #8D7E61", +"0 c #907F61", +"q c #7D8365", +"w c #7E987D", +"e c #89805F", +"r c #858263", +"t c #8D8163", +"y c #848469", +"u c #8C8B6C", +"i c #938465", +"p c #998666", +"a c #948867", +"s c #998867", +"d c #968669", +"f c #98876C", +"g c #96896A", +"h c #9B8C6D", +"j c #84916F", +"k c #9D906F", +"l c #8F8F71", +"z c #9D8E71", +"x c #908971", +"c c #8C9272", +"v c #949475", +"b c #9F9071", +"n c #95967A", +"m c #989678", +"M c #94997B", +"N c #9B9C7C", +"B c #A18E6E", +"V c #A0906F", +"C c #A08F72", +"Z c #A49374", +"A c #A99676", +"S c #A69877", +"D c #AA9877", +"F c #A69678", +"G c #A99778", +"H c #A79879", +"J c #AC9B7B", +"K c #B19E7D", +"L c #B09B77", +"P c #9CA07D", +"I c #AEA07F", +"U c #B3A07F", +"Y c #919B81", +"T c #9A9C80", +"R c #A19E80", +"E c #AE9E80", +"W c #B19F81", +"Q c #8AA589", +"! c #96A185", +"~ c #9CA283", +"^ c #94A489", +"/ c #9CA58A", +"( c #92AB8F", +") c #9EAA8D", +"_ c #9DAE93", +"` c #94AD90", +"' c #9EB195", +"] c #9EB298", +"[ c #A5A383", +"{ c #AFA182", +"} c #AAA789", +"| c #A4AB8D", +" . c #ACAB8A", +".. c #AAA987", +"X. c #B4A383", +"o. c #B9A585", +"O. c #B4A887", +"+. c #BBA887", +"@. c #B6A688", +"#. c #B9A789", +"$. c #B6A98B", +"%. c #BCAA8C", +"&. c #BFB08F", +"*. c #AAA790", +"=. c #A4AC92", +"-. c #ACAF91", +";. c #B5AE90", +":. c #BEAE91", +">. c #A5B295", +",. c #ABB294", +"<. c #A4B69B", +"1. c #ABB59A", +"2. c #A3B99D", +"3. c #ACBA9E", +"4. c #B5B395", +"5. c #BEB193", +"6. c #B3B69B", +"7. c #BDB69A", +"8. c #B3BA9D", +"9. c #BCBA9B", +"0. c #ABBDA2", +"q. c #A6BCA0", +"w. c #B4BDA2", +"e. c #BCBDA3", +"r. c #B4B5A1", +"t. c #C1AD8E", +"y. c #C1B08F", +"u. c #C1AF91", +"i. c #C4B294", +"p. c #C9B596", +"a. c #C9B897", +"s. c #C6B699", +"d. c #C9B799", +"f. c #C6B99B", +"g. c #CBBA9D", +"h. c #D0BC9E", +"j. c #C2BEA3", +"k. c #CEBEA1", +"l. c #D0BFA2", +"z. c #ACC1A3", +"x. c #ADC3AA", +"c. c #B3C2A5", +"v. c #BCC1A5", +"b. c #B4C4AA", +"n. c #BDC5AA", +"m. c #BBC9AD", +"M. c #BDCCB2", +"N. c #C5C1A4", +"B. c #CFC0A3", +"V. c #C3C5AB", +"C. c #CCC6AA", +"Z. c #C4C9AE", +"A. c #CBC9AE", +"S. c #D2C2A5", +"D. c #D8C4A7", +"F. c #D5C5AA", +"G. c #D8C7AC", +"H. c #D7C8AC", +"J. c #D9C9AE", +"K. c #C3CBB2", +"L. c #CCCCB3", +"P. c #D4CDB2", +"I. c #DCCCB2", +"U. c #DECFB8", +"Y. c #CED1B6", +"T. c #C9D4BB", +"R. c #D4D0B6", +"E. c #DED0B6", +"W. c #D5D3B9", +"Q. c #DED2B9", +"!. c #DAD8BF", +"~. c #E0CFB5", +"^. c #E0D1B7", +"/. c #E2D4BB", +"(. c #E5D8BF", +"). c #DCD9C2", +"_. c #E5D7C0", +"`. c #E5DAC2", +"'. c #E9DCC5", +"]. c #E6DDC8", +"[. c #E9DEC9", +"{. c #E7E0C9", +"}. c #ECE2CC", +"|. c #EEE5D2", +" X c #F0E6D2", +".X c #F3EDDB", +"XX c #F1E9D6", +"oX c None", +/* pixels */ +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX' ] b.3.z.' >.b.b.b.0.>.>.>.z.<.m.x.] ( 2.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX3.>.c.n.Z.Z.R.R.R.E.P.H.H.H.H.F.H.P.E.P.J.P.J.F.H.R.R.R.R.R.Y.Y.m.m.b.z.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXb.1.c.Z.A.L.H.H.J.I.J.H.H.H.F.D.J.F.F.F.H.H.I.I.I.J.F.F.G.H.H.H.I.J.E./.^.E.P.H.P.P.P.L.L.m.3.( w oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX<.w.n.Z.P.I.E.J.H.J.H.J.I.F.H.F.F.F.S.S.S.S.S.D.H.P.I.I.H.F.F.H.H.F.H.J.H.H.H.D.J.D.F.H.E.I.J.H.F.F.H.P.Q.Y.L.K.T.z.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXw.m.A.H.H.H.I.J.I.I.G.G.F.S.D.S.g.B.S.D.B.k.B.B.B.S.H.F.H.E.J.I.J.F.J.J.J.J.J.H.S.B.S.D.S.F.J.F.S.J.I.J.J.J.H.I.I.I.I.Q.R.R.K.0.] oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX) w.Z.P.l.g.h.h.d.k.B.F.I.I.F.S.l.l.g.g.S.H.S.B.S.J.H.F.D.S.H.S.S.H.H.I.Q.Q.I.E.E.J.F.D.S.B.B.l.l.S.H.S.S.S.H.J.J.J.H.G.P.H.H.S.J.I.I.Q.).T.M.z.Q oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX<.w.V.J.D.a.u.t.+.o.t.a.S.S.S.F.l.l.l.k.g.g.g.g.S.S.F.F.F.F.J.F.J.H.B.S.H.J.J.I.E.I.E.J.F.F.B.g.g.g.h.k.S.S.B.S.S.S.D.F.H.G.G.G.G.P.J.J.J.E.Q.Q./.(.!.W.T.K.z.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX<.Z.L.A.S.g.i.t.#.W W X.y.a.g.g.s.g.g.g.g.g.k.k.k.S.D.S.S.F.S.S.D.D.S.S.D.F.J.E.H.H.D.S.B.S.S.S.F.S.g.h.h.B.h.k.S.S.S.S.F.F.J.F.k.F.G.G.I.I.H.J.I.Q.E.E.E./.Q.Q.Q.P.Y.m.] oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX^ c.K.P.G.G.k.j.i.:.:.:.:.j.B.k.k.g.B.B.g.B.S.S.k.S.k.g.k.S.S.F.F.H.H.S.S.g.h.S.D.S.S.S.F.S.S.B.S.S.B.S.B.k.a.a.l.h.S.B.B.B.S.F.J.J.S.S.F.H.G.I./.^.G.I.I.I.J.J.I.E.^.E.I.I.I.Y.Z.b.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXc.n.A.I.U.U.G.l.l.l.l.l.l.k.F.l.S.k.S.H.J.J.J.J.J.J.F.F.F.F.S.H.D.l.S.S.S.k.a.o.t.i.d.g.l.S.S.S.S.B.g.g.B.h.h.a.a.a.g.h.B.B.B.h.S.F.I.I.I.I.I.I.G.I.I.I.G.G.I.G.I.H.J.I.I.^.(./.E.I.J.R.W.M.x.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX] b.A.P.E.Q.Q.U.l.l.I.G.P.G.l.k.k.k.l.B.S.I.G.F.S.F.J.J.J.J.I.F.S.H.H.I.J.I.I.J.S.k.&.X.o.a.a.g.l.S.k.k.S.S.S.B.S.S.S.h.S.l.g.h.S.H.H.H.D.G.G.G.G.H.I.I.G.G.G.G.G.G.G.H.H.S.H.J.I.I.I./.E.J.J.J.E.R.Z.x.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX>.Z.W.W.J.I.E.I.J.l.l.U.I.l.l.l.l.k.k.k.l.F.S.S.S.S.S.g.B.S.l.S.D.S.S.l.S.S.S.D.J.D.D.H.S.S.l.l.l.g.g.B.D.F.S.S.l.B.S.S.F.B.S.B.B.B.S.D.B.l.S.S.F.l.G.G.G.I.H.F.F.G.F.F.I.I.J.S.D.J.J.J.I.I.I.E.E.J.H.F.H.R.A.b.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX' v.A.I.U.Q.I.I.I.G.G.G.F.l.l.l.k.k.k.l.l.G.P.G.F.F.F.F.S.S.g.a.a.g.h.h.l.l.l.S.h.h.h.h.h.h.l.g.S.D.H.D.S.D.H.J.F.S.S.g.k.B.S.H.S.S.h.S.B.h.g.g.h.h.h.d.l.F.F.G.F.F.G.I.G.F.l.J.I.I.I.I.H.D.H.H.H.J.I.H.J.I.I.H.S.f.f.m.z.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX,.V.H.J.I.I.Q.I.I.I.H.G.F.P.k.k.k.l.l.G.J.U.G.G.l.G.I.I.P.S.F.H.k.a.g.S.S.S.g.S.l.h.p.t.t.p.h.g.a.p.p.h.S.S.g.S.D.H.F.D.D.S.S.S.B.B.S.B.B.D.S.B.h.g.a.g.a.g.l.S.F.I.H.l.l.G.G.P.l.a.H.I.J.D.H.S.S.H.H.F.H.H.J.J.I.J.D.S.5.4.f.V.2.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX8.v.A.R.I.Q.Q.Q.U.I.I.H.G.F.F.l.k.k.l.U.J.l.l.l.G.G.l.D.S.H.I.J.J.J.H.D.D.D.h.S.h.a.i.t.t.+.t.y.p.p.i.a.a.h.h.g.g.g.k.S.I.E.^.E.H.H.F.S.F.F.F.H.B.B.k.g.g.g.S.S.S.S.F.l.F.F.I.G.I.I.l.B.S.H.H.h.B.S.D.H.D.D.H.F.H.J.H.F.S.F.F.l.p.i.7.1.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX| 8.C.F.E./.Q.Q.E.I.I.U.I.S.S.F.G.l.G.J.I.P.l.J.J.I.l.k.s.p.i.l.I.I.J.D.D.D.g.p.p.y.p.p.g.p.p.a.g.g.g.S.k.D.D.S.S.S.S.D.S.D.J.I././.E.E.H.D.J.I.I.H.D.D.B.S.h.g.h.g.k.S.F.S.F.I.U.I.I.U.l.S.D.J.P.h.h.B.B.S.h.S.S.D.F.J.J.G.D.B.B.S.F.S.g.5.;.-.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX=.6.N.C.I.U.U.U.U.U.U.G.I.U.I.G.I.F.F.F.H.I.F.l.S.G.G.l.i.i.+.%.i.D.J.D.g.g.S.d.i.i.y.i.p.a.g.l.h.a.d.l.D.S.B.G.J.I.H.F.S.D.S.H.H.H.H.~.I.^.^.I.^.^.J.H.F.S.S.S.S.S.g.k.g.H.J.F.F.D.S.S.k.F.k.h.d.d.S.S.p.p.S.h.p.g.S.h.h.S.D.I.J.H.S.S.B.S.F.B.5.O.-./ oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXe.C.F.Q.Q.U.Q.Q.U.U.Q.I.I.I.G.G.I.G.G.I.I.I.I.H.H.~.I.I.P.B.k.k.S.F.J.J.B.S.S.S.k.a.i.y.a.a.g.a.i.p.g.h.l.h.S.J.I.J.I.D.F.F.F.F.B.D.D.H.D.I.^.(.(.(.(.I.J.J.F.S.S.D.S.S.S.F.J.I.I.J.J.S.k.k.S.S.h.I.(.l.a.t.o.+.t.t.a.D.S.g.g.h.S.H.E.J.F.S.a.B.g.a.i.i.;.} ! oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX| 7.l.P.U.U.I.I.)./.Q./.Q.U.I.I.U.Q.U.G.G.G.I.I.I.G.I.G.J.I.~././.E.I.J.J.S.F.S.l.l.S.S.g.a.h.g.h.h.a.d.k.S.S.S.k.D.D.l.D.S.S.S.G.G.H.D.D.D.D.H.E.^.(././.E.I.J.D.F.D.J.H.D.H.D.D.F.I.I.^.J.S.g.g.g.h.D.~.I.S.a.i.i.y.i.p.g.g.h.g.h.D.S.D.J.J.J.g.p.a.i.g.B.g.5. .,.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX! 9.f.B.I.P.G.I.I.Q.I.I.Q._._.U./.I.U.I.I.G.I./.I.F.G.G.G.I.I.I.I.G.F.H.F.h.g.h.S.g.k.S.S.S.S.C.S.l.B.g.d.g.g.l.S.S.h.h.p.a.h.S.l.l.D.I.H.H.H.D.B.D.D.H.~.J.I.J.I.^.I.I.I.F.F.k.S.S.H.H.J.E.E.J.l.h.S.S.p.p.p.h.S.h.i.t.a.S.p.t.t.+.t.S.F.k.S.H.E.E.J.F.B.f.g.f.y.B.B.i.j.3.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX-.j.f.B.S.l.U.P.I.U.I.G.I.U.`._.Q.U.G.H.F.H.I.I.I.I.I.I.Q.^.^.U.I.S.a.B.F.J.g.g.k.S.S.G.D.D.I.{.E.J.I.F.l.S.g.g.a.a.g.g.a.p.p.S.S.B.l.D.F.D.C.H.H.H.S.S.S.h.D.J.H.J.^.I.~.E.E.J.D.G.J.D.H.F.J.J.S.S.S.S.g.t.t.t.t.h.p.t.t.K t.W K G W +.X.t.h.l.D.D.J.I.J.J.J.H.S.g.B.H.C.a.B.j.<.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX~ e.j.k.B.B.F.P.G.l.U.F.F.G.G.G./._./.U._.I.I.Q._._._._./.I.I.I.I.U.I.J.H.F.F.J.F.F.F.D.F.I.D.H.I.^.E.I.E.J.S.B.S.S.B.l.k.g.p.g.a.h.h.B.B.S.H.H.D.D.H.P.D.S.S.D.J.I.~.J.J.J.J.J.I.I.H.S.S.D.D.D.F.l.h.D.S.S.g.p.p.t.t.t.t.K o.K L K D A A J U D L t.a.D.h.D.I.I.E.I.H.F.J.E.E.H.B.g.f.8.=.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX~ j.F.l.l.F.H.J.G.G.G.I.G.l.F.F.H.G.^./._./././.(././.Q.~.I.~./.~.G.G.H.H.J.H.S.S.S.S.D.S.S.F.F.D.S.S.F.H.J.^.D.S.S.S.S.F.S.S.S.l.a.h.l.S.S.S.S.h.S.D.D.S.D.D.S.H.H.J.J.J.J.D.J.J.I./.~.S.l.g.g.B.D.l.a.S.k.a.a.t.p.o.t.K K K K K K L A A A A A G G A L t.t.h.H.I.J.J.J.J.F.S.F.E.H.C.S.B.9.1.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX~ } f.S.F.k.G.F.H.H.l.G.G.F.U.I.F.S.k.l.I._.U.U.^./.I.I./.I./.I.G.G.I.F.F.F.S.F.F.F.S.H.S.D.S.S.H.J.H.H.S.B.g.D.J.H.S.S.D.H.H.F.D.G.H.F.S.S.l.l.H.S.B.S.h.a.B.D.D.D.D.H.D.H.I.I.J.D.J.I./.(.~.S.l.S.a.h.l.l.g.g.S.a.o.W K K K t.L t.o.L A A A A A S G L L K K t.p.h.S.H.J.E.J.F.g.S.F.H.H.F.g.B.N.8.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXT j.j.B.k.k.F.F.G.G.G.F.F.G.J.~.F.S.l.k.G.(././.I.I.I.I.I.J.I.~.I.I.F.S.h.h.S.S.S.F.S.H.S.B.B.S.H.S.S.S.F.I.D.h.S.D.D.S.S.S.D.J.D.D.J.H.h.a.h.D.S.J.J.D.S.h.h.B.D.D.D.F.J.D.F.J.J.J.H.H.J.H.H.H.B.g.p.a.a.B.B.D.h.h.B.p.o.o.W t.W W W X.K G A D A D D L K U U X.U t.g.d.S.D.J.J.F.S.S.H.H.H.H.F.S.F.F.v.' oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXj T :.g.l.k.C.F.l.F.G.F.G.F.H.G.G.G.F.S.C.G.~./.I.I.J.I.I.I.I.I.I.F.D.F.F.H.J.D.J.F.H.F.S.D.F.S.H.H.J.D.D.F.g.F.D.S.S.S.h.h.g.S.F.I.J.S.H.D.B.B.B.S.S.D.H.A.D.D.S.B.H.D.H.F.D.F.F.D.J.J.H.D.D.H.H.J.D.h.d.a.S.F.S.F.B.B.a.+.o.o.+.t.t.W K X.K J J L D D A C Z D J U %.p.l.g.g.g.i.h.D.G.H.J.F.D.H.F.D.F.I.H.A.w.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXl .s.j.l.l.S.S.S.F.l.G.l.G.F.F.F.S.F.G.S.F.I.~.I.I.I.G.S.I.I.I.D.D.F.S.k.k.S.S.F.F.S.F.H.F.F.B.S.H.D.S.B.B.S.S.g.k.S.h.h.h.h.h.S.D.H.D.S.D.B.h.h.h.h.S.B.H.H.H.H.H.H.D.A.B.H.H.S.S.F.H.I.J.S.S.D.H.H.H.D.H.S.D.S.S.H.H.F.B.#.o.K o.t.t.W t.W K J K K D A V A Z A Z A o.h.S.S.F.l.l.i.k.J.S.B.h.H.J.D.J.S.I.I.J.A.c.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXT 7.j.l.l.l.l.l.S.F.F.A.G.G.l.l.S.k.D.S.l.S.G.G.I.G.G.I.H.D.D.l.h.l.p.p.l.g.i.a.l.S.S.S.D.H.H.F.S.D.S.B.B.S.D.S.h.g.g.h.h.a.d.h.g.g.g.h.B.B.S.C.B.h.B.h.B.D.D.D.B.H.E.H.H.D.S.J.J.F.S.B.J.J.~.J.H.D.H.H.H.J.~.F.S.l.D.H.H.H.H.u.o.o.X.o.t.t.W X.U D G K K J D A Z Z D G L t.p.S.G.D.I.F.S.D.I.h.a.a.h.l.J.I.D.I.I.E.A.v.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXM 5.f.B.l.l.l.l.l.G.G.l.l.G.l.l.S.h.g.S.S.k.S.F.G.G.F.l.D.D.h.d.a.p.p.p.u.i.d.p.a.a.S.S.g.F.S.S.S.B.S.H.H.H.S.k.h.h.h.p.p.h.h.g.g.l.h.B.D.B.D.S.S.h.a.a.B.I.I.J.D.H.H.I.H.H.H.^.~.I.J.H.D.J.^.^.^.J.F.E.J.H.D.J.J.h.g.h.S.F.J.J.g.%.+.X.o.%.+.X.K U J J J U K J S S A D G D A K t.h.I./.I.S.D.J.F.S.g.S.a.S.l.D.D.I./.I.H.e.^ oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXn v 5.f.k.B.U.l.l._.P.G.l.G.l.l.l.l.l.S.g.k.B.k.F.F.F.F.S.l.h.h.p.p.h.h.h.h.p.t.t.p.k.a.a.S.F.S.F.D.F.F.H.h.D.J.H.a.g.g.h.a.t.p.p.p.l.D.S.D.D.h.h.h.B.h.a.a.B.(.(.I.J.J.H.S.E.E.^.^./.(.'.I.D.J.I././.E.D.D.H.D.H.J.D.l.H.a.a.B.l.a.i.%.t.o.X.o.+.U K K I J J J J D A F A D D A A A L t.h.D.I.F.S.J.D.y.y.H.S.h.d.d.S.S.J.J.J.H.V.>.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXn T 7.j.k.k.S.l.l.P.l.l.l.G.l.l.l.l.l.g.g.g.g.k.F.G.F.F.S.l.g.h.p.p.p.p.p.p.t.o.o.+.u.a.g.a.h.S.S.S.g.B.H.D.a.J.H.k.a.g.p.h.p.h.p.p.d.S.H.D.D.h.a.B.H.J.D.h.h.B.J.J.J.H.H.H.D.D.H.^.I.^.^././.I.I.E.(.(./.H.B.S.H.H.H.S.J.J.a.p.J.H.l.%.o.+.+.o.X.+.U I I X.I J J J J D D G D G A A A A X.p.h.S.S.l.S.D.i.+.y.p.t.t.p.S.D.F.D.F.H.H.N.1.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXT [ s.k.k.k.l.S.P.l.l.l.k.G.l.l.l.k.k.j.l.g.g.k.F.I.H.D.S.l.k.g.p.p.h.t.t.t.U U U X.o.t.a.g.g.S.S.B.g.g.h.B.S.B.S.D.B.a.p.a.p.g.h.p.h.h.S.F.H.B.B.B.S.D.H.B.B.H.D.J.H.J.I.J.H.D.B.D.I.J.J.J.I./.^.I.I./.[.`.I.H.D.S.S.S.l.g.l.l.a.a.S.S.g.%.O.+.X.o.X.I U X.X.U U J J G J K J K L G G L K L o.g.h.S.S.F.S.a.a.+.+.p.%.o.p.I.J.S.H.H.B.S.C.,.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX[ .s.j.k.k.k.k.l.F.l.k.k.k.k.l.F.C.k.k.g.k.l.k.S.J.G.F.D.l.k.l.g.p.p.t.o.o.L o.L +.o.+.o.t.a.p.h.S.S.S.g.h.h.a.S.g.h.h.g.g.h.a.h.h.h.p.h.D.h.h.D.D.D.h.D.F.l.D.~.I.~.D.~.^.^.I.D.D.D.H.H.H.H.I.I.I.~.~.I.}.(.I.D.H.D.k.d.p.k.k.F.J.g.a.S.a.%.O.+.O.+.O.E E X.X.K U I G J J D J D K K D D X.D K g.S.g.D.D.D.g.g.%.K o.i.p.t.h.J.H.H.J.F.S.J.N.8.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX/ ;.s.k.k.k.k.F.F.l.l.l.j.k.k.l.l.G.F.F.k.k.S.k.S.l.D.J.D.S.S.l.g.p.t.t.o.L L o.L o.o.+.o.o.o.o.t.p.h.h.F.D.l.g.p.g.g.a.a.p.y.p.a.h.a.p.p.p.p.p.p.h.D.D.D.~.F.D.l.l.S.D.D.J.H.I.^.H.D.H.D.H.(.^.I.H.H.I.I.H.J.J.J.S.S.D.S.g.a.k.g.g.D.F.S.S.S.a.%.X.$.+.%.+.X.K X.X.{ J D J J U K D D D J J U K K a.S.a.g.h.S.S.J.H.X.K X.t.i.h.J.J.S.g.S.S.S.S.B.1.^ oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXT r.j.j.l.l.F.F.l.l.l.C.k.k.l.l.l.l.I.G.F.S.l.g.g.k.S.F.S.S.S.l.p.d.p.o.L L o.o.o.o.L o.L o.+.t.t.t.t.a.g.h.F.S.a.a.a.a.i.i.t.p.p.h.h.h.p.p.p.h.t.o.t.a.h.D.D.F.k.d.p.p.p.p.h.B.D.D.I.^.H.H.H./.^.(.^.H.E.H.D.D.F.H.k.a.g.S.l.k.k.g.l.S.H.H.S.S.S.a.+.+.+.%.O.E K o.o.U U J D J U K U K D J J U J K p.k.S.g.k.l.S.S.J.p.J X.%.t.y.g.J.D.h.g.p.S.S.D.f.;.! oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXT :.s.j.S.l.C.G.F.G.C.l.k.k.l.l.k.l.F.l.k.k.S.k.g.g.S.S.k.l.l.S.h.p.h.t.o.o.o.U L o.o.o.o.o.+.p.p.t.t.t.p.a.l.F.S.g.i.p.t.p.a.a.h.h.a.h.p.p.h.h.h.t.U t.t.p.h.h.l.d.i.p.t.t.i.h.D.H.H.H.J.I.I.I.J.^.~.I.H.H.D.D.S.H.J.J.D.S.S.S.S.l.k.l.S.D.H.H.E.J.J.f.i.i.a.+.X.X.#.X.I J J U J D J U K K J J J U X.%.S.H.S.g.a.p.t.S.g.X.I a.h.p.a.S.D.H.g.i.g.g.g.S.f.4.>.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXN :.s.k.l.l.l.I.l.l.F.l.G.C.l.C.l.l.S.l.l.l.l.l.S.k.S.S.h.h.D.h.p.p.t.t.U o.o.U o.L +.o.o.o.t.t.p.p.t.t.a.t.p.a.D.h.k.g.a.p.g.g.h.g.h.g.a.t.p.p.t.t.+.o.o.o.+.t.t.t.t.t.t.t.t.a.S.H.H.I.H.J.J.H.I.~.^.I.D.H.H.H.D.F.F.H.H.S.i.p.h.l.F.S.B.g.k.S.H.J.J.D.D.H.B.k.i.%.%.:.X.X.I U +.O.S J U U D J I J X.y.g.D.F.S.B.i.%.X.O.S.g.p.+.p.h.g.a.g.g.g.y.i.k.a.B.B.B.7.>.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX[ 7.j.l.l.l.).l.l.l.F.F.G.l.l.P.F.l.k.S.l.l.k.k.k.g.a.S.g.g.h.h.p.p.t.+.o.U o.L U o.+.+.L o.o.+.p.h.a.t.t.y.t.t.p.p.g.h.a.a.a.a.h.h.g.d.a.p.p.p.t.o.U U o.U o.o.+.+.t.t.p.d.i.i.l.D.D.D.D.H.I.J.D.I.D.H.I.I.I.I.D.B.S.D.D.F.g.a.y.S.S.k.F.H.D.S.B.H.H.J.J.H.J.S.S.k.k.S.f.&.X.X.X.I J J I J I I J J J K t.g.B.D.F.B.g.a.F.g.S.B.g.g.%.W u.g.g.l.S.S.g.k.B.g.S.S.B.7.| oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXq 4.f.l.l.l._.l.l.l.I.l.l.l.l.U.G.k.k.k.S.l.l.g.l.f.f.g.h.g.g.S.h.y.t.t.o.o.t.U o.o.o.L L o.+.+.+.p.h.h.t.t.t.t.t.t.p.a.h.S.g.a.a.g.p.p.a.d.g.p.p.t.o.U o.o.U U U U t.t.t.h.g.S.l.F.S.H.D.H.J.H.J.J.J.H.H.H.I.I.I.H.D.g.S.S.S.g.d.y.a.l.S.D.S.S.S.S.S.H.H.J.^.^.I.J.J.J.I.I.g.y.O.X.X.U U U I I I I J J X.+.h.g.S.D.J.S.k.H.E.F.D.k.S.k.s.l.l.g.l.F.F.S.B.S.g.S.S.S.B.9.' oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXv $.f.k.l.).l.l.l._.J.J.G.F.G.P.I.l.l.l.l.l.k.k.f.l.g.g.g.g.h.g.g.a.y.t.t.+.o.U o.o.o.o.+.t.+.+.t.p.p.p.h.p.p.p.t.t.t.t.a.g.S.S.S.D.h.g.h.g.h.h.h.t.t.p.t.+.o.U o.U L U t.y.h.t.a.S.F.D.H.H.H.I.~.H.I.J.J.H.H.H.D.H.I.I.J.J.J.G.S.S.g.i.d.S.H.D.S.D.D.F.H.E.J.^.^./.(.(.E.J.I.J.g.&.+.O.O.+.O.+.U U { X.U o.a.l.S.F.S.S.S.S.H.J.J.F.J.H.S.g.p.p.g.d.l.G.S.S.S.S.S.B.S.F.g.7.,.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXq c ;.k.k.G.P.F.G.F.l.I.G.I.S.S.H.J.F.F.S.B.S.l.k.k.f.f.g.p.h.h.S.h.g.p.p.t.o.t.t.U U o.o.t.+.+.+.+.+.+.y.p.a.h.y.y.t.t.p.p.p.y.a.g.h.a.h.g.h.p.p.p.p.p.p.p.h.t.o.o.o.o.L o.o.o.t.y.h.~.H.D.H.I.H.E.I.H.I.J.H.J.J.H.D.J.I.E.I.J.F.D.H.S.f.t.y.a.D.J.I.J.H.J.J.~./.~.~.(.'.'./.J.g.k.a.a.f.i.&.&.y.a.a.f.+.f.g.a.S.S.S.F.F.l.F.J.F.H.F.F.J.F.H.F.g.t.i.h.u.p.k.g.g.S.S.g.S.J.S.g.j.,.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXu { s.j.G.P.G.G.G.G.P.F.l.l.S.S.H.F.S.B.F.S.l.l.k.k.k.k.g.g.p.h.h.l.a.i.t.U o.t.o.t.t.o.t.t.t.+.+.o.y.a.a.a.a.h.p.y.t.h.l.l.a.p.i.D.S.l.S.S.p.p.p.p.h.h.p.h.p.o.o.+.+.t.+.L t.U U p.D.D.S.S.H.H.S.D.I.J.H.H.J.J.E.H.D.H.J.E.I.J.F.H.E.S.g.a.g.a.h.F.F.J.J.J.J.~.(.^.~.(.'.'.[.(.E.D.J.F.F.D.B.g.a.g.k.F.g.H.J.D.h.l.S.S.l.S.S.H.F.I.J.S.B.D.l.F.k.u.o.%.p.h.S.g.a.g.S.l.l.F.H.F.B.9.>.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXy { f.7.l.l.G.U.l.l.U.I.G.F.F.F.F.F.S.B.F.F.B.S.l.l.k.k.h.d.d.p.p.p.p.t.t.U t.p.o.t.U o.t.u.p.t.t.p.t.a.a.a.h.h.a.p.y.p.h.l.h.p.t.p.S.D.D.D.a.t.p.p.h.h.h.p.p.t.o.o.+.+.o.+.o.t.o.t.d.h.h.p.g.H.D.D.D.J.I.H.J.J.J.J.J.H.J.E.J.J.F.G.H.H.J.H.B.S.F.S.S.D.F.D.I.~.^./.'.'.(. X X`.'./.^.^.^.Q.E.J.E.D.S.F.F.S.H.J.S.S.S.S.S.S.S.J.J.H.F.D.D.p.S.S.k.F.I.;.K X.u.S.i.g.g.a.l.S.l.S.F.D.C.9.| oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXv [ 5.7.k.F.F.J.U.l.I.P.I.G.F.G.J.F.S.B.F.F.S.D.F.l.G.S.g.d.g.h.h.p.p.p.t.U t.t.+.o.o.o.t.o.i.u.t.t.t.p.a.a.h.h.a.p.y.y.p.p.p.t.t.t.p.p.g.D.p.p.t.t.t.p.h.p.t.+.o.t.+.t.t.t.t.t.t.t.t.p.p.i.a.h.H.H.J.J.I.J.D.D.^.^.^.J.J.J.E.J.J.G.F.l.F.J.D.B.k.k.k.h.H.J.H.I.~./.(.'.'.'.}. X`.(.(./.^.^.(.(.(.^.^.D.D.J.J.I.D.H.H.D.F.D.k.D.H.D.J.H.S.H.F.S.S.i.i.D.F.@.K X.a.a.t.g.g.S.S.k.B.S.S.H.S.9.>.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXy H i.5.k.l.G.F.P.P.J.I.I.G.G.G.G.H.F.S.D.S.S.D.F.I.I.G.F.k.g.g.k.p.p.p.t.o.o.+.o.+.t.+.t.t.u.u.u.t.t.t.t.p.p.a.h.h.p.y.y.t.p.p.t.t.a.h.p.a.h.a.y.t.t.o.t.p.t.p.p.y.y.a.h.p.+.t.p.p.u.u.p.t.l.l.l.D.H.H.E.~.J.J.~.~.~.^.~.E.J.E.H.J.~.I.G.D.J.J.G.F.k.k.F.G.I.I.^.^.(.(.(./.~.~.J.^./.(.'.(.(./././././.I.I.J.I.J.F.J.I.H.J.J.F.F.J.F.F.I.I.J.F.S.g.g.i.t.k.g.X.O.o.t.p.h.S.F.F.k.S.F.J.D.S.B.V.>.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXq R 4.f.k.l.G.P.U.G.I.U.U.I.I.U.I.G.F.S.B.g.g.g.g.B.J.G.S.l.l.p.l.l.p.t.p.p.+.+.+.o.o.t.t.o.+.s.f.p.p.p.p.t.a.h.a.h.a.y.y.i.p.t.t.t.t.p.p.p.p.h.a.p.t.t.t.t.p.t.+.p.y.t.p.a.p.+.+.p.g.f.p.d.h.h.p.l.S.H.H.H.J.~.E.E.~.~.(.(.^.~.~.I.I.I.G.G.H.H.I.(.{.J.D.H.I.I.^.^.^.^.G.D.F.D.S.D.D.D.D.^.'.'./.^.I.J.I.J.J.I.J.F.I.J.H.H.J.I.I.J.J.J.F.J.J.F.H.B.l.g.g.i.i.p.O.+.i.%.g.S.a.S.F.k.S.S.F.S.B.S.F.C._ oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXR ;.s.k.k.k.P.I.U.U.U.U.U.U.I.I.G.F.J.B.k.k.k.l.F.D.S.l.h.h.h.p.d.d.t.p.p.t.t.t.o.t.t.t.t.t.t.u.d.j.p.p.p.p.h.h.h.h.h.a.y.y.t.p.t.t.p.t.p.p.y.t.p.p.t.t.t.t.t.+.o.o.t.t.y.a.h.h.h.D.F.D.l.k.l.l.k.l.D.B.D.D.I.~.~.~.^./.'.(./.I.H.D.G.G.G.k.l.S.D././.^.E.S.l.F.D.l.S.l.l.l.S.S.S.h.h.S.S.D.J.^.^.^.^.^.^.I.^.^.I.J.~.J.J.H.J.G.D.D.I.J.S.S.S.S.B.g.a.i.%.d.%.+.s.g.p.s.h.F.F.S.l.S.l.S.S.S.S.k.S.H.L.1.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXN :.7.f.k.k.k.F.P.U._._._./.U.I.P.F.H.J.F.S.k.g.l.k.S.g.a.p.p.p.p.p.u.p.t.p.t.p.t.o.t.t.t.t.p.s.k.k.k.p.p.t.p.h.h.h.h.a.h.h.a.p.t.p.h.p.t.t.o.t.o.t.t.+.t.t.t.t.+.o.o.t.t.+.p.h.a.D.D.l.D.~.~.l.l.l.k.a.h.B.D.H.~.^.~.~.~.(.(./.J.H.D.l.l.l.g.p.d.g.S.H.J.(.F.p.i.i.f.l.l.l.D.S.S.S.l.g.S.S.l.D.J.D.D.D.D.J.^.^.^.~.J.H.J.H.H.F.F.G.~.H.F.D.S.H.H.S.i.X.K X.%.i.5.%.p.p.+.t.i.S.S.g.l.S.k.g.k.S.S.S.F.J.A.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXl ;.7.s.j.j.l.F.G.I.U./.U._././.U.l.l.I.H.S.S.B.k.S.k.k.g.d.a.p.p.p.p.t.t.t.o.o.t.t.o.o.t.t.p.h.l.G.G.l.d.g.g.a.g.g.S.g.g.k.l.a.p.a.D.h.p.t.t.t.t.o.t.t.t.t.t.t.p.t.o.K o.X.+.t.t.p.h.l.l.l.G.~.l.k.k.l.N.h.h.h.H.H.I.^.G.~.l.~./.~.I.l.l.d.p.i.t.t.u.d.S.S.l.i.u.X.t.k.l.l.l.l.l.l.l.l.l.F.k.k.k.F.l.l.l.l.D.~.~.~.~.~.l.~.l.l.G.D.l.G.F.S.S.a.l.F.l.u.E J W #.%.i.t.u.h.i.u.k.F.S.k.g.k.g.g.l.S.S.B.S.S.J.V.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXy ;.s.i.s.k.l.l.l.U.U./././._._./.U.U.I.I.S.B.B.S.H.G.S.k.d.d.p.u.p.u.t.U o.t.t.t.t.t.t.o.t.t.h.h.l.l.l.k.a.g.g.a.h.S.l.S.S.S.k.g.g.g.h.p.p.t.t.o.o.o.t.t.t.U t.t.t.t.L K X.L K W t.p.p.l.l.l.l.G.D.h.l.d.a.h.B.B.D.H.H.H.~.G.~.l.G.l.l.l.l.d.p.W W t.t.p.h.h.u.%.#.X.+.g.l.l.l.l.l.l.G.l.l.F.k.k.k.l.l.k.h.h.l.G.~.D.~.~.l.l.l.l.l.l.h.l.S.l.S.g.p.d.i.u.E A W %.%.i.p.+.p.d.k.l.F.I.l.k.f.g.g.d.g.S.B.S.S.F.P.0.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXy T s.s.s.k.k.G.F.I./._._._._._._.U.I.I.U.l.S.S.S.S.S.H.k.g.g.p.p.p.t.t.t.o.t.t.t.t.t.o.t.o.o.p.l.l.G.l.k.k.s.f.g.g.S.F.^.F.S.S.g.g.k.g.d.p.p.t.t.o.t.t.o.t.K t.t.p.p.o.L K o.U U t.t.t.t.h.l.l.D.l.p.p.p.t.a.a.h.h.h.D.D.D.~.~._.l.l.l.l.l.l.d.s.u.#.t.o.t.a.t.%.#.@.X.X.d.g.l.l.h.g.l.l.l.l.l.l.k.k.l.l.p.p.i.p.l.l.l.p.p.u.i.h.i.h.p.u.W U +.t.t.X.J A J X.A J J K X.i.t.o.u.i.g.g.F.l.l.p.f.l.g.g.S.B.S.S.l.F.P.<.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXv ;.j.k.k.l.G.l.G.U._././._./._.U.G.I.G.l.J.F.S.k.k.k.g.d.p.p.t.p.d.a.p.p.y.t.t.t.t.t.t.t.t.t.p.l.l.l.I.l.d.d.k.g.g.S.S.S.S.B.k.S.g.g.g.t.t.t.t.o.o.o.o.o.o.o.K o.o.t.W L K K L o.%.L o.p.p.h.h.p.h.t.t.t.t.a.a.a.h.h.h.a.B.l.D.~.l.k.l.l.k.k.k.d.p.u.t.W t.%.%.+.X.X.X.X.d.h.d.h.d.p.f.s.k.l.l.l.g.p.g.g.@.t.i.t.p.l.t.t.t.t.t.t.t.t.#.W J A A A A Z F J F C Z F A K X.X.o.X.o.i.i.p.g.k.k.g.p.g.k.S.S.F.D.F.H.S.J.A.^ oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXu 4.i.f.S.C.S.G.G.U._._./._._.Q.Q.U.U.^.I.G.J.B.k.k.k.k.g.d.p.i.p.p.p.u.p.g.g.t.p.p.t.t.t.t.t.t.p.l.l.l.~.k.p.s.d.a.d.g.S.S.S.k.k.k.g.g.g.t.X.t.t.+.+.p.t.+.X.K X.t.t.X.X.D K D K K J K L K t.t.t.#.W W W W o.t.t.U U +.p.y.h.k.p.p.l.k.k.k.k.d.k.k.k.d.d.u.t.o.o.U D A A D U W W t.p.d.p.g.g.l.l.h.%.X.#.W A o.g.p.i.p.t.W t.+.t.t.t.u.%.X.I D A A S Z F S H Z C C F D X.o.W @.X.#.#.t.p.d.l.k.f.S.l.l.l.S.D.F./.J.H.J.n.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX2 } 7.g.k.B.k.S.A.U.U.)./././././.U././.^.I.l.l.k.k.k.S.B.g.l.S.d.d.a.y.t.p.a.p.t.t.t.t.t.t.t.t.t.p.p.k.k.k.d.d.p.p.p.d.g.g.l.l.g.S.S.S.l.g.g.i.p.p.t.p.p.+.o.o.t.i.g.h.u.o.X.K K K J J D D A D L K L Z A K A A L L D S U y.a.a.d.p.p.d.d.k.k.l.l.k.k.d.k.d.i.u.t.+.X.J A A A Z L L A W h.h.p.p.d.h.u.A Z A F F +.f.s.p.t.t.W K %.t.+.o.%.+.X.I L A A A S Z z b F F F F A J W X.@.#.#.o.t.p.u.h.l.g.g.l.S.l.g.S.S.F.J.D.J.W.b.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX} 5.f.k.k.k.C.H.I.G._.)./._.(./.E.^.^.(./.I.G.G.F.B.B.k.l.f.g.g.i.i.p.p.p.p.p.y.t.t.t.i.p.t.t.t.p.t.p.p.p.d.d.p.p.i.g.F.J.H.J.S.k.l.S.l.l.S.S.l.h.p.p.h.h.d.u.i.a.d.h.p.p.t.%.X.U U I J D G Z A G A A A A A B Z B Z V L U y.a.p.p.p.p.p.d.d.k.l.l.k.d.k.d.u.t.t.t.t.u.X.K G A A A L A C W u.u.p.%.@.A z C C Z X.t.u.i.i.t.o.t.W %.s.g.+.o.X.U J K A Z C z Z Z Z Z Z F F A J W @.@.%.t.+.+.t.t.p.g.d.d.l.F.S.g.l.S.S.S.S.H.I.P.0.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXv 7.i.f.k.S.l.G.U.I./._.I.Q././.I.^.E.~.I.I.P.l.l.k.k.g.i.d.s.g.S.p.t.t.t.t.t.t.p.t.o.t.t.i.i.u.t.p.p.t.p.p.d.d.p.p.a.l.~.J.F.J.G.k.g.l.g.l.g.k.l.h.h.h.D.g.g.d.a.p.g.p.p.o.X.o.+.t.X.J G J J D V A B B A A B B B B B A D U U t.t.t.p.u.k.k.i.d.k.d.k.p.p.u.W W W X.o.%.X.K K D D G A C B B C A J Z Z J F C C A %.p.t.u.o.t.t.t.t.a.g.l.B.i.#.X.I K A A S Z Z H F Z Z Z J J J W @.%.%.+.t.t.o.t.p.p.d.d.l.F.G.S.S.F.S.S.S.S.S.H.V.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXq 4.:.e.k.l.F.I.G.G.F.G.I.I.Q././.J.I.I.I.I.G.G.l.G.l.h.p.p.p.p.p.p.%.t.t.t.t.t.t.t.t.t.t.i.l.l.u.u.y.i.i.a.f.p.i.i.p.g.F.^.J.G.J.J.l.l.l.l.l.d.g.l.k.l.k.k.h.h.p.p.p.p.p.p.o.K +.o.o.L L A A D S S A V B A V B B Z h h Z A A o.+.t.t.t.t.h.G.k.k.k.k.k.k.p.p.t.o.W X.o.o.W I J J Z A G C z h h h h z z Z Z F Z E d.l.l.d.%.u.i.t.t.y.i.i.k.g.u.@.X.W D A S S S J J Z b Z F G E W X.+.%.%.i.%.o.o.t.a.a.h.S.S.F.D.B.S.S.F.H.S.S.S.H.n.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXv H 4.5.l.F.P.F.I.G.F.F.G.I.I.I.I.H.I.G.G.G.F.G.l.l.k.p.p.y.p.p.t.t.t.+.t.t.t.t.t.p.t.t.t.t.t.l.l.g.p.t.t.p.g.a.a.i.p.i.l.S.I.^.J.~.H.h.l.l.S.S.l.l.S.l.l.l.k.k.p.p.t.t.y.p.t.L K o.K t.K X.G D J X.U A A V V B B h h B B V Z Z Z A X.X.t.t.t.l.p.u.d.k.k.k.d.i.p.t.W X.+.+.X.X.U J S L G C f h h g f f z Z { H Z Z D u.l.l.d.t.t.%.t.a.l.g.k.g.&.X.X.K D J K A H X.W H F Z F J J J W o.+.%.%.%.o.+.+.a.B.S.J.S.S.H.F.S.S.S.H.S.g.C.F.L.( oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX} { s.k.C.G.F.F.F.I.G.I.I.I.U.I.F.G.G.I.F.F.S.k.k.F.s.t.t.t.t.t.t.o.+.t.t.+.t.t.t.t.t.t.t.t.a.g.i.a.p.t.t.i.d.g.k.g.S.l.S.S.F.J.D.S.h.l.l.l.F.S.D.S.S.l.l.k.l.l.h.t.t.%.t.y.+.W W L K K t.X.K J U I J D J Z V V A Z h B V Z B Z Z S Z G K W o.W p.p.s.k.k.s.s.p.i.p.l.%.o.o.X.X.G S S J J Z C h Z z f f z b E { Z Z H K p.a.%.u.t.t.t.d.g.g.l.f.5.+.J D D D W G D K K E F b Z G J D J U X.%.%.o.X.X.t.h.J.I.^.H.S.D.E.J.S.B.F.S.B.B.D.F.Z.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX* H f.N.l.k.k.G.I.P.I.G.U.U.Q.I.G.F.H.H.l.F.F.S.k.k.k.s.t.t.t.t.t.t.o.o.+.t.o.o.t.t.t.p.t.t.t.t.p.t.t.t.t.p.p.g.S.F.S.H.D.l.S.S.D.S.S.S.l.l.F.D.D.F.S.l.k.k.k.h.i.t.t.t.t.+.t.L K L L K K t.U X.K J J J D J D Z Z A D S A A A A Z z Z Z G W p.u.W J d.l.k.l.l.d.p.t.i.i.+.o.o.X.J G S Z S A A A Z Z C f f z z F F Z F { X.t.d.W X.o.o.t.p.u.i.i.%.%.+.I G X.K J D K W K H J F Z D D K K X.o.+.i.%.+.X.+.h.~.E.(.(.H.B.J.J.H.S.F.S.S.g.S.F.F.m.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXY j.l.l.l.l.l.U.G.G.I.G.I.U.U.I.I.F.F.F.S.l.S.k.h.h.p.t.t.t.U t.t.t.o.o.U t.t.U t.t.t.p.i.i.+.+.t.t.t.t.t.p.p.p.g.l.k.F.B.B.S.F.D.D.S.S.h.l.D.D.l.l.D.l.l.l.k.t.t.o.o.o.L t.t.K K L L L W o.o.+.U I J J D J S Z A A D U D A J J Z k b Z C Z G C C C @.p.t.u.d.d.d.u.u.u.u.t.+.+.X.J J F Z Z A F z z h h z z b F m Z Z H o.u.i.X.J W o.t.d.i.i.+.X.O.+.O.U I J D A D D D G J D A K K K J U X.+.t.y.t.t.U h.~./.^.(.^.F.S.F.S.F.S.D.S.B.S.F.D.A.2.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXY :.j.l.j.j.l.I.J.F.F.P.G.I.U.G.G.F.l.l.k.k.l.B.k.g.y.t.o.+.W K o.t.t.t.t.t.t.t.t.t.t.h.p.i.d.d.g.p.a.p.i.p.p.p.p.d.a.g.g.a.k.D.D.J.D.S.D.l.l.l.h.l.~.l.D.l.p.t.W K K W K K o.K W K L A A L K K +.+.U I J J D Z D Z A D U J D J D J Z Z Z C Z F F f J +.%.t.u.i.p.g.u.#.W t.u.X.@.X.{ J J Z C C z z f z z b z Z %.W S F H E %.%.@.J J U +.t.i.i.%.X.X.+.&.+.X.X.J A S D A G A G G G K L A K U o.o.t.t.t.t.h.J./.(./.(.J.S.S.S.S.S.C.S.S.k.F.S.F.L.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX*.:.l.l.l.l.U.l.l.k.G.U.G.G.I.G.I.F.l.k.l.f.k.l.k.d.p.t.K o.U o.t.t.t.t.t.t.t.t.t.X.o.p.h.k.k.l.k.g.d.g.a.p.u.p.p.i.l.S.g.d.S.F.H.l.S.F.l.h.p.p.p.l.G.l.l.t.K K K K K K o.o.K K K L A L G A L L U o.X.U U U J D S S A D J U I J J J D D D G F G F C A A E t.t.W #.u.t.W E W E K W J F F A C z z z z z z z z b h Z F F S Z Z A u.#.J { K X.X.%.%.y.y.+.O.X.+.X.X.X.J D Z A A Z A A G L J J X.X.U U U o.t.t.y.h.D.^.^.^./.F.S.S.k.B.B.B.S.g.S.F.F.P.M.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXn $.r.l.l.I.l.l._.l.F.I.U.G.I.I.I.I.l.k.k.k.d.s.g.g.d.t.L L L L U U t.t.t.y.t.t.i.+.X.%.i.g.k.l.k.l.g.g.g.d.d.d.g.g.k.S.l.g.a.F.I.J.h.S.J.D.p.i.p.D.l.l.o.o.W K A L L L K K K L W W A G L L L D K X.U X.U U O.X.I D D D J D J J J J D I I J D A A G C G X.@.u.:.W G W W W W E J F A F Z b z z h h z z f f z z z b Z Z Z F Z C Z X.#.G J J J K t.y.i.p.i.X.J I X.I X.I U K A A A Z A K K A G K L o.o.L U t.y.a.h.D.J.I.I./.H.B.S.H.F.S.k.B.S.S.F.H.J.R.x.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXS $.g.l.l.l.U.l.l.l.).l._.l.J.J.F.F.S.g.g.k.d.s.g.k.p.o.L L L U U U o.+.p.a.g.a.a.+.%.a.h.S.S.l.g.B.g.F.B.C.k.k.l.F.l.l.k.k.k.l.l.F.H.F.J.J.l.h.F.S.B.y.U U A L L A A L L K K L K K L A L A A L L L K K L K O.X.D J S S D D A L D L K J J J E W E C C F E E W W #.W E C E E F G F F F C C C f z z x z z z z h b b b Z b b Z h Z A K X.J D J W +.t.u.p.g.5.E Z J U U W X.K D D A Z D K K D D L W K K J o.W t.p.p.l.~.~.~.~.l.l.l.~.I.l.l.l.F.S.F.F.F.J.K.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXm { 5.j.l.l.U.l._.l.U.l.U._.l.J.J.B.g.S.k.g.S.k.s.i.a.t.o.L L U U U U t.p.h.h.S.S.S.B.g.g.S.S.S.S.S.S.S.F.S.l.k.k.F.l.l.l.l.l.l.k.s.l.H.D.J.^.I.F.H.D.l.&.U D A A L L G L K K K K K L A A Z A A A A L K K K L J U I D D Z V A A A A A D J J J G W 0 R C C C C E G E 0 z z z C C C C C x C C C z z z z z z z z b b h h Z b h z Z Z A G K K J J W o.+.u.s.k.:.X.Z S D J K D K X.o.A S A D X.K D G W L J X.%.t.t.t.p.h.D.~.~.~.l.l.l.l.l.G.l.k.k.g.l.J.S.J.P.] oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXM R ;.s.l.l.l.l._._.k.l.l.U.l.U.F.F.g.a.g.s.i.p.p.u.%.t.+.o.U U U U U t.p.g.a.h.J.J.E.J.H.F.I.F.S.S.J.H.H.S.S.S.l.k.l.k.l.F.l.F.k.k.k.F.J.S.S.I.J.S.H.B.y.+.U A Z A L K K K K K K K L L A A A D L A A A L K W K J I U J K D Z V V A A A D J K D G G C C C F C F 0 W C T C R C C C C F C C C C f z z z z z z z b m h h h b Z h h Z Z G A A J X.+.o.W +.+.i.a.u.+.J S X.I A D G +.o.U H D A W D A A D J K %.t.t.o.t.p.p.h.D.D.G.G.l.l.l.k.l.l.k.k.d.g.S.D.F.I.Z.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXN { k.s.l.U.l.l.l.l.l.l.l.U.l.l.S.S.g.i.s.i.%.+.u.t.o.+.o.+.+.U L t.p.h.a.g.a.h.H.J.^.J.F.I.^.J.B.g.S.H.H.S.S.H.S.F.I.l.l.F.l.l.F.F.F.G.F.F.D./.I.F.F.S.&.U o.L L L L K K K W W J L L K D L D D L L A A A W o.K J J J U U J D A A A Z Z Z D J G G E E E C C C F E E C E E 0 C C F F F C G G C f C z z z z z z Z Z z z z b Z Z z Z D J D D D X.X.X.K o.%.t.+.t.%.I J J U K W D W J I U G G J K L A A J W U +.+.+.t.t.p.p.h.D.l.l.l.l.h.k.l.l.k.k.g.d.k.D.F.J.W.' oXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoX< J 5.f.f.k.H.k.k.k.l.l.l.U.l.l.k.l.S.a.y.p.t.+.+.t.+.o.o.U o.U U t.i.d.d.h.k.g.g.H.H.J.H.S.I.J.D.F.k.k.g.S.l.S.F.I.F.l.F.F.G.G.D.I.H.F.l.G.G.I.I.F.F.J.F.a.+.U J L K U K U U K D L J G J D D D D L K L A A K o.K U U K X.U I J Z V V V A A A A A A G G E F C F C E C E E C E C C C F C x C *.W C C z z C z F z z z h b b Z Z Z S D J J I J J J J J K X.W :.i.@.E S G J W W W W E G J W K L K W L A A A L K K K t.t.t.i.p.p.p.p.p.g.l.j.k.l.l.l.l.k.g.f.g.F.F.U.V.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXN { 7.i.k.S.k.k.d.j.l.l.U.I.l.k.k.S.h.g.t.t.t.+.+.t.X.o.o.L o.t.p.d.l.g.g.a.a.a.g.S.D.D.S.F.H.J.F.B.F.D.S.l.S.S.^.I.l.l.l.l.l.F.G.I.F.l.f.S.J.I.S.k.l.H.D.S.&.K A A U t.U K D D A G G G J J H D D K L L D A L J W U o.K U U J I S A Z V Z A A A S W W G G C C F *.@.E F E G T C C F C F E G G G C z z z z Z z z z z z h b z Z Z H X.X.U J G S S S A X.E J +.s.:.i.J G J X.W W X.E E E J K W K G G K G A K K W W o.t.p.t.u.t.i.i.t.p.l.k.k.l.k.k.G.S.g.d.d.l.S.G.W.<.oXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoX;.{ f.s.B.l.k.j.j.k.l.P.l.l.l.k.k.h.h.h.p.t.t.t.o.o.U U o.+.t.p.a.S.l.g.g.a.p.a.a.g.g.l.S.J.J.D.G.g.B.S.k.k.k.k.H.F.F.l.D.G.g.k.l.l.g.g.p.g.~.^.S.S.S.l.S.p.%.L A A X.o.U L D L V A D D G S Z A D K L K U K G J K U U U I I J J J A Z Z A Z A Z G W W W G C E E E *.E E E E f F F F F F E G G G C z f z z b b z b C Z S h h h [ J J X.I J G S Z b Z F W +.@.%.5.g.%.J J J W X.W J W W W W W K G K W G G L A G W o.t.t.t.t.t.t.p.t.u.l.l.k.d.d.k.k.k.g.d.s.l.H.F.I.K.oXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoX..O.O.k.f.S.l.l.k.k.l.l.l.l.P.k.k.k.h.D.h.t.+.+.t.+.o.t.t.U +.t.p.a.k.g.a.a.p.p.a.h.S.g.g.h.a.g.l.l.J.H.g.a.g.k.g.g.l.l.k.l.F.l.h.g.p.u.p.d.d.F.I.G.F.D.S.l.a.X.L A L U D A A A Z V Z K J G Z S A J G K X.o.J G D D U U U I J J S J S V S V Z G A A A G G F C C E E G C E F C x F E C C C F *.G G C z f z C Z Z b Z b z S Z z h S J H J G X.{ G S Z F F J %.i.+.a.g.i.X.E G A X.W K E E W W W W K G J K G C A G J o.t.t.t.t.t.t.p.p.u.d.l.k.k.d.s.f.l.l.f.s.k.l.F.G.W.2.oXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoX9.H i.k.k.l.l.l.k.l.l.k.l.l.P.l.l.l.h.h.p.t.U t.t.t.y.U o.U +.a.g.a.a.g.d.p.p.p.h.h.h.h.i.d.l.h.l.G.I.S.a.g.p.p.p.a.h.k.a.a.s.g.l.l.l.k.d.k.d.k.F.G.F.S.S.k.g.i.+.K A A A S V A B s S U D S Z D Z A D K K W J S J D U U O.U K J G J A S S A S J A D G G G G C C F F C C C F C C C F G F C F *.C E f f z 0 E E E 0 E b b b Z b z b H { J J J E J S G S S A A J K o.k.k.:.J H D K X.K K W J J G W W W W J A Z G J J o.t.t.t.W t.o.t.p.p.d.S.S.g.s.i.i.g.k.a.g.k.k.l.G.P.K.oXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoX .&.J k.k.j.j.l.k.l.l.k.l.l.l.l.G.l.l.p.t.t.o.o.o.o.t.t.o.t.o.%.g.k.k.g.g.g.d.h.p.p.h.h.i.i.S.~.l.l.D.a.g.k.l.h.t.p.p.h.D.f.p.g.g.F.J.G.l.s.d.s.s.l.I.S.B.F.J.J.F.g.X.J J A V Z Z B B V D D S D Z A A D L K X.J I J J J J o.o.X.J J J D D J S A A D D G G G 0 C C C f C C F C C f C C C G C C C E *.C T z E 0 0 E E 0 z b Z b b b Z F @.{ #.E E J S S Z G X.W X.:.i.S.B.s.{ J J J D I W W W A J J W W X.X.A Z A J K o.L W t.t.t.t.t.t.p.i.k.S.k.:.:.:.i.g.g.l.l.l.l.G.J.P.2.oXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXf.$.5.j.d.k.k.l.j.S.C.k.j.l.l.l.l.l.A.p.t.o.o.t.o.o.o.t.U %.o.p.k.k.g.d.d.p.t.t.h.p.i.i.i.g.S.D.l.G.t.+.i.a.l.D.h.D.h.B.J.B.s.g.g.l.G.l.k.u.d.s.s.d.l.B.S.I.E.H.F.k.@.J J J Z A B B V Z A D J S Z S C A A D K J D J J S J U %.o.X.{ J I J S A A A D D G G G C C C C C F C C C C C x C x C C C G E E C 0 E 0 E C C 0 G b b b Z b H H S J X.X.X.K Z S S S G E i.a.k.s.g.F.k.%.@.+.J J J E W W K E J G G D X.J F J K K K W o.t.t.t.t.t.t.t.i.g.S.g.u.+.u.i.d.g.l.k.l.l.F.H.H.n.oXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXv $.5.f.k.d.l.l.l.l.S.k.k.k.k.k.l.k.k.l.p.t.+.+.t.o.o.L U +.%.%.k.S.g.p.S.p.L A D p.p.t.i.k.l.i.t.p.t.o.U t.y.h.h.h.h.D.F.J.p.i.a.d.d.p.p.p.u.s.f.k.k.d.g.S.J.H.F.H.S.%.U I J D Z A Z B A A J J A Z Z A Z A A G D S D G J J I o.%.X.X.X.U J A A A A A A C G C C f C F @.:.*.F f f C x C C C E E E C G G R 0 T 0 C C C C b b F Z Z H J S H J X.J J S A A A O.X.i.S.S.g.g.B.B.i.;.s.%.X.X.%.%.E W #.A W E S G W W W W W W K W t.t.t.W W t.t.t.i.h.g.i.:.:.i.a.k.l.k.k.l.l.D.F.H.' oXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXS :.f.k.k.k.s.F.k.k.k.B.g.k.g.k.j.d.d.p.+.o.o.+.+.o.U U U o.t.t.l.g.g.a.h.U Z B A p.a.d.g.d.p.o.t.t.t.o.U U o.+.o.L o.t.a.a.t.u.i.p.p.u.u.i.p.p.l.F.l.d.f.g.F.l.k.S.S.i.i.+.I G D D A Z D A J J J A S A Z B Z A L D D S Z D D U t.+.X.E I I G D D A A A G C C C f C *.s.k.:.F C C C C C C G *.W E E E E Z b b b C z Z F Z b H b F H J F Z Z W J J J W W J i.p.s.S.k.d.g.g.k.p.%.f.k.g.g.g.g.@.J E E E E S S A J X.o.K W W o.t.t.s.%.o.%.+.+.t.p.h.p.:.u.i.d.k.k.S.k.g.l.S.D.F.m.oXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXq S :.s.k.k.k.k.l.C.l.l.k.k.k.f.f.d.d.u.#.U U L +.+.o.+.t.o.o.t.t.l.g.p.h.t.L A C A p.h.h.p.t.W o.t.o.o.o.t.U U o.o.+.o.o.t.+.t.t.u.u.i.u.u.u.u.p.f.p.u.p.d.u.a.g.u.i.d.g.a.i.I J U D U A D A J J L G A G A A A Z A D S Z Z Z A U o.y.@.{ U U I U D D A D G C 0 W C C E :.:.E C C C C C C C G G W :.W G G Z Z z b C F Z E F H H b F E J J Z S J G J %.d.:.X.s.k.k.l.k.g.f.s.f.g.a.g.S.B.S.s.i.i.W J X.X.W I X.G J K X.t.t.W o.o.p.p.s.%.o.o.t.t.p.l.l.d.p.g.g.k.g.k.g.k.l.S.H.D.A.oXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoX; r X.%.k.P.I.k.S.k.l.l.k.k.f.k.k.s.i.p.t.W o.o.o.+.+.o.t.U U o.+.p.F.k.d.h.p.L L A U p.a.y.+.K W t.W o.W o.t.o.o.o.o.+.t.+.t.t.t.t.i.i.p.t.t.o.p.p.i.u.t.u.:.%.%.i.i.i.s.s.%.t.U D U +.U I D D I U W G L A A A A A A A G S Z Z V S J O.+.X.J I K X.J K L G G C f W E F E F C C C x C C C z C C G E *.W *.f b F z z z z F F H J F b b F F H E W X.J X.s.F.g.+.g.k.k.k.l.S.S.g.g.k.g.s.k.B.g.%.%.:.@.E %.i.X.X.%.X.D L W W t.t.W t.t.u.f.i.#.W t.t.t.k.l.l.l.k.g.a.f.k.l.l.F.S.S.S.F.w.oXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoX: J O.5.I.H.l.F.F.C.F.l.k.d.s.d.g.p.u.i.t.t.o.+.U U o.o.o.o.o.o.o.a.G.G.d.g.l.X.X.+.p.y.o.U L K K o.W o.o.o.U U o.U L o.+.t.+.t.t.t.t.t.p.p.t.t.o.t.u.u.+.%.:.%.o.%.u.i.k.S.+.I U I I U U U I I I O.K A A A A A A A Z A D D Z V S Z D J X.+.U J J W D D G A G G F :.r.G F x C C C C x C x C f C G E G C C C z z Z z z z Z z b F F F H H H F X.X.+.5.i.k.S.S.k.S.S.S.S.F.H.G.k.B.S.S.g.s.k.:.X.+.%.:.X.X.%.+.&.:.%.X.X.X.K K t.t.p.i.u.l.k.:.t.o.t.t.u.h.g.l.k.g.f.g.f.l.l.l.S.S.H.B.A.oXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXu X.%.C.I.k.k.S.F.k.l.k.k.s.s.d.a.i.u.a.+.U o.t.U o.U t.y.U o.i.a.F.U.G.k.l.D.h.p.p.t.U o.K L L o.L o.o.U t.U o.o.o.o.o.t.t.d.u.t.t.u.u.u.d.t.o.W o.:.u.@.%.:.#.t.o.u.u.l.l.X.X.%.O.J J K U X.X.U U L A G A D A A Z Z A L A A V V Z S J J X.I J J U K A A J E A @.s.:.E z f x C x f G G C f f C F F C C C C f z z z h h h z m Z Z S F E J E E E :.S.F.S.H.I.G.G.I.G.F.k.H.G.B.k.B.B.S.g.s.i.O.o.t.%.X.+.X.%.S.S.k.i.i.+.X.X.X.t.a.g.g.S.S.s.t.t.t.t.W t.p.l.l.k.k.s.k.l.l.k.k.S.H.S.J.z.oXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXH H i.F.F.k.k.k.C.k.k.k.s.i.s.d.a.t.%.t.o.o.+.o.U U U p.p.o.y.g.J./.^.l.k.g.p.p.p.t.t.t.t.o.L o.U o.L U L L L L o.W o.o.o.t.p.t.t.p.i.i.i.5.u.%.W K :.%.X.%.%.X.o.o.u.u.u.l.f.X.X.X.J I I L U U K D L A A A Z Z Z V Z A A A A Z A Z S D D J U D D D K L A J u.W i.i.5.:.Z x C f f x f f x C f f x C C f x C f b h h h h h h z Z S A Z J J X.J H X.g.D.S.H.F.G.F.F.H.H.k.S.H.S.k.k.k.S.g.s.s.i.&.i.a.s.:.X.i.S.i.+.a.f.%.+.i.g.u.i.S.S.k.H.k.p.t.W t.i.t.p.l.U.I.l.k.s.l.C.l.g.S.D.S.F.K.oXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoX< X.E k.k.l.H.F.k.k.k.k.k.g.i.i.s.s.t.o.t.o.t.+.%.o.K t.p.y.a.S.F.F.J.G.l.h.i.p.t.t.K o.t.U K o.o.o.L o.L L L L U L t.t.o.o.K t.p.i.p.i.u.:.%.:.%.#.W @.@.W %.@.W +.t.t.u.+.i.g.+.X.U J S S S D D D G A A A A B B s B B Z Z B A Z A Z Z A A A K K D D A G S G W %.u.:.%.%.E x C x f x C x f C f x f C f C C x h Z z g h s h h h Z H m m Z J E J J J X.a.F.G.I.J.l.l.F.S.k.l.S.k.k.S.g.k.f.s.f.g.S.S.B.p.%.g.g.a.i.p.g.+.O.i.g.H.k.a.S.J.H.I.H.u.t.u.i.h.t.t.~.I.G.G.l.k.k.l.l.g.D.B.B.S.P.2.oXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoX1 u @.%.C.k.k.J.S.k.f.k.k.k.d.i.i.i.i.%.t.o.t.U t.a.t.+.t.t.o.h.H.S.k.f.d.d.t.u.t.o.o.L t.t.o.L +.p.o.U U o.o.U L o.o.o.o.t.o.t.t.t.p.a.d.i.:.%.@.%.:.#.@.%.%.$.W W @.u.:.+.o.t.+.X.I I J J J S D Z A A A B A B B p s B B Z Z Z Z A A Z Z Z L A G D K D Z C Z G @.u.%.%.W E F z C f x C E F C x f f x C f C *.C S m b z b h h s h Z Z Z Z H X.@.K G J E +.F.'.`.I.k.g.g.g.k.l.S.k.g.k.k.k.k.f.k.S.S.J.f.5.i.F.F.f.a.g.i.U U 5.B.F.H.S.S.k.I.G.l.u.t.t.i.h.h.h.G.G.I.l.l.k.k.l.k.B.S.S.g.B.J.K.oXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXu a O.p.B.F.C.G.F.k.s.k.k.s.u.%.i.p.t.t.t.U +.t.t.p.t.t.u.:.#.k.k.f.p.t.t.X.o.+.U U t.t.o.U K o.t.D.U L L K K U U o.o.o.t.t.W t.t.t.p.p.s.:.%.%.#.:.j.f.d.s.i.%.W o.@.:.:.+.o.o.+.X.J X.@.@.W J G Z Z A B V Z B p B s B s B A V A A Z B Z Z A A A G L A Z Z J :.u.:.%.%.%.R F z f f C C E E C z f f f C G E E E G Z b b F Z Z h z C b Z Z F X.+.E F G J t.l._._.G.F.k.k.k.k.S.S.l.k.k.k.l.k.k.k.S.S.J.k.i.d.G.G.k.%.O.%.+.O.%.a.S.J.S.s.s.I.S.k.p.t.+.t.t.l.~.(.U.G.I.F.l.k.k.k.k.S.F.g.k.F.Y.oXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoX5 H $.i.B.k.F.G.S.k.k.f.d.k.d.%.p.y.t.p.t.t.t.t.t.t.t.u.d.i.%.d.f.i.p.t.A L L t.t.U t.p.t.t.o.o.o.o.L L L K L K L U U L K W t.o.t.t.p.d.u.:.%.@.%.u.k.F.l.k.k.5.+.@.#.:.u.%.t.o.%.%.X.+.X.X.X.X.K D Z Z B Z B B B V B B h B B A A A A B B Z B C A Z A K #.i.s.p.s.i.%.u.:.E F F C x f C C F x z x C f C C C G E J Z b b Z Z Z Z Z Z m b Z Z J E H Z J G W +.F.I.G.F.k.k.S.S.S.k.f.f.k.l.S.F.l.l.S.H.I.I.f.g.G.I.I.F.s.i.a.J.B.i.k.k.F.S.k.S.k.a.p.f.u.t.i.i.D.(.I.G.G.G.F.l.k.l.B.F.I.B.S.k.J.b.oXoXoXoXoXoXoX", +"oXoXoXoXoXoXoX2 t O.%.i.g.k.B.J.S.k.k.s.d.f.s.i.y.+.t.a.y.t.+.t.u.u.t.p.k.d.W i.g.i.i.W A A L +.h.o.t.D.t.t.o.U L U o.U U t.L L L L L L K o.o.+.t.t.p.t.:.%.%.#.#.%.g.k.k.s.k.:.u.u.i.s.u.t.#.o.+.y.%.%.@.i.i.%.X.X.A Z B B B B V V B s B h B A A A V B B Z B Z A A A X.S.I.F.B.k.s.s.u.s.:.W R x f f C x C f z f C C C C *.C G J E b b b m S G G H Z b Z b F Z Z F E J J %.l.S.F.G.k.j.S.S.B.k.l.g.l.F.H.~.^.G.G.G.I.'./.H.I.~.Q.Q.J.i.i.F.J.k.k.k.S.I.k.k.u.i.p.d.u.t.t.t.d.I.U.G.I.U.P.F.F.F.F.S.J.J.S.F.S.m.oXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXr S %.+.5.k.k.k.F.S.k.k.s.s.k.d.p.y.t.t.y.a.p.y.y.u.u.:.d.k.t.#.s.k.d.t.G A A A K t.L t.t.t.o.t.o.K L L L t.U L L L o.U L W t.t.t.t.t.i.u.:.%.%.u.%.@.s.l.s.s.s.i.u.i.s.s.s.s.:.o.X.t.a.i.%.g.u.+.X.X.S Z Z B L A B B V V V V V Z V V h B k h Z S Z C K i.I.'.I.B.k.s.5.@.%.W E E C C f x C C x z f f x C C C C G H H b h g h Z Z A S Z b F F F J F S F Z K u.a.g.S.G.F.k.J.B.J.S.F.F.J.I.H.I././.I.D.G./._.^.G.I.Q.E.F.D.S.F.F.S.k.p.k.S.S.k.u.i.t.t.u.W +.t.p.l.U.G.I.I.U.F.G.F.H.S.H.I.S.g.B.A.oXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXa J @.+.a.k.S.g.k.k.k.s.s.i.d.s.t.y.p.t.t.g.d.i.i.u.u.u.s.g.u.i.g.d.p.o.L W L G G A L K W o.t.U K L L L L L L L L L o.K o.o.o.t.o.%.%.i.i.+.%.%.u.:.:.i.s.s.s.s.f.s.s.d.f.s.s.u.:.%.%.k.a.i.a.u.%.+.X.W D B B A B B B B B B B C L Z C h h h Z J I W %.g.D.J.I.F.k.s.i.i.%.@.Z Z F F C x C C C z f x z 0 E z Z F F F F R z h h z m Z Z Z z Z Z F F E H H F J @.d.l.l.F.G.l.F.l.l.l.l.S.D.J.J.^.(.'.^.J.J.I.~.I.J.J.E.E.H.S.g.F.J.H.g.%.d.F.F.B.s.s.p.+.t.+.W t.i.p.I.J.I.I.H.k.F.I.J.S.J.J.H.l.g.C.b.oXoXoXoXoXoX", +"oXoXoXoXoXoXoXr X.X.i.B.i.S.k.B.B.k.g.s.p.d.d.t.i.a.i.i.a.d.i.p.u.s.i.g.k.s.i.g.p.p.o.K L W L L L A L K K K K U o.U t.o.K L L K L L K o.o.o.o.W O.+.X.+.O.&.;.:.:.i.i.:.u.:.u.u.s.f.k.f.d.d.f.i.+.X.l.S.k.p.:.%.i.i.u.W B B B B B B B p B B B K W :.F F E %.&.+.W +.t.p.h.l.k.i.W W :.s.$.F z F F z f C f x f f 0 0 z 0 T Z Z F F E C z z Z Z b Z b m F Z Z H Z H { E Z J X.%.S.G.F.l.k.l.l.l.k.k.l.S.H.J.I.^.(./.I.H.H.I.J.I.~.E.I.I.H.g.g.S.k.I.f.g.F.F.k.f.u.u.o.+.t.o.o.t.p.l.S.F.H.H.F.G.I.J.F.H.J.J.H.S.F.L.oXoXoXoXoXoX", +"oXoXoXoXoXoX, h J O.S.d.%.B.k.B.k.k.g.p.i.s.d.t.t.a.p.t.u.f.a.g.s.s.s.k.s.u.s.d.p.p.o.W W d.W L A K X.o.o.L L L U t.o.o.K L K U L K L L t.K o.o.@.X.@.X.@.%.%.%.%.%.%.%.:.%.u.s.k.d.s.u.s.s.f.p.t.u.h.l.H.a.u.%.p.S.d.+.W B f B p B p p p p B B D X.X.%.5.5.%.K W W o.W W t.u.#.W W i.k.s.E F F E 0 f f C f f x C C 0 R C F F F E C Z b Z Z b Z F H F b Z H H H F H X.G J J J i.F.k.k.F.F.l.G.l.k.l.F.H.I.J.I.I.I.F.D.S.S.J.G.G.I.^.E.H.g.g.J.J.J.k.g.J.H.k.f.p.p.W o.t.t.W o.p.k.k.F.l.S.H.I.G.I.I.J.J.J.J.S.k.A.oXoXoXoXoXoX", +"oXoXoXoXoXoXe H X.i.F.s.:.B.B.B.k.B.k.g.s.k.p.u.y.t.t.+.+.g.S.k.s.s.s.s.s.u.i.i.p.o.W W u.t.L L L A L X.K K K K L o.K U L L K L L L L K L t.W t.O.X.X.X.X.X.%.%.:.$.@.@.%.u.s.p.d.k.k.s.s.s.p.k.p.a.d.D.S.a.i.:.i.i.u.+.X.A B h p p B p i i p B A K X.X.+.+.X.D +.@.W K C K %.X.%.:.l.k.X.F F F E F C C C x 9 C C C z C E W E F F Z F F z z H H G J S F H H H Z F F E J H F J X.s.s.l.A.l.l.U.J.k.l.l.l.G.F.J.J.J.S.B.D.S.S.J.G.I.I.D.S.S.S.F.J.H.S.S.H.F.F.s.a.u.@.W o.W +.o.p.k.S.F.H.H.S.I.I.I.J.J.I.J.J.k.g.N.<.oXoXoXoXoX", +"oXoXoXoXoXO t I X.g.S.g.u.l.l.k.g.k.f.s.g.l.u.t.+.o.o.X.+.g.J.B.s.s.g.k.d.k.p.d.t.o.o.t.t.W L L L L L L K L K L L K o.L L A L K L L K W K W W W +.%.:.@.I U X.O.%.@.%.@.#.u.u.p.s.d.u.g.k.d.k.l.d.p.u.p.s.s.i.i.i.i.+.@.%.W Z A Z B f A K s B Z S G X.W X.+.J Z J A W J Z J %.%.5.%.g.5.:.W E E G E E E G f x x C C C F E W W G F E Z Z b z b F E E J G H F F Z b F H [ E G G A W u.f.S.l.G.l.l.l.l.k.k.l.l.F.D.E.J.k.l.l.S.S.S.D.J.I.J.J.I.F.I.I.g.h.F.F.S.g.a.g.5.i.u.o.+.u.h.k.l.F.S.F.S.I.~.~.I.I.J.J.I.S.k.S.w.oXoXoXoXoX", +"oXoXoXoXoX@ k X.o.k.g.i.u.l.k.k.f.g.k.s.d.i.t.o.#.G K #.i.g.k.k.k.k.k.k.k.l.d.p.t.W t.t.K K K K K L K L U L L L L K U K L L L K L L K W K K K o.X.X.@.:.X.J I X.X.%.@.X.t.u.i.i.s.p.u.f.d.k.k.d.t.p.t.W i.d.s.a.f.g.s.%.+.W W D L A Z K p.G J L K o.#.J X.o.F F J W W W K X.t.i.a.i.k.k.k.j.s.s.:.*.W G G F C x x C C C C E E R F F R z h b b b H { { R H S H H F F F H E E E E %.u.u.k.l.l.l.l.l.S.F.k.k.l.S.J.^.I.h.i.k.F.l.i.t.l.J.I.I.I.E.I.S.i.t.l.k.k.g.D.S.g.k.d.p.+.u.g.k.l.F.l.H.S.G.I.I.~.I.I.J.I.F.S.S.V.oXoXoXoXoX", +"oXoXoXoXoX, N U %.k.p.u.k.k.d.k.f.l.f.d.p.t.o.X.X.J G X.f.k.B.g.s.g.g.g.d.k.l.p.o.K W K G W K L K K o.t.K L L W o.K U U K K K K L J K K K K K o.X.W W p.5.X.{ X.X.X.X.X.@.t.s.s.p.s.u.d.k.p.t.%.X.K K X.i.a.a.S.F.F.k.s.t.+.W t.L Z L D K K K G J X.U J X.X.J %.t.@.W F S X.%.%.u.s.d.k.k.g.s.s.s.:.@.W E F F F C C x F F F F F Z Z C C b b b F H G J E E H Z E @.H H E E E E W %.d.k.s.k.k.k.l.l.l.F.S.k.F.S.S.S.l.h.p.g.h.h.%.i.g.S.S.J.J.I.J.B.i.o.u.g.F.g.g.S.F.g.g.a.%.u.d.k.l.l.F.H.F.J.I.J.I.I.G.J./.H.F.F.Y.oXoXoXoXoX", +"oXoXoXoXoXl J O.u.k.u.u.l.k.d.k.d.k.f.d.u.o.o.J K W X.+.g.k.g.k.g.k.g.s.d.k.l.t.o.K K L L L G L K K K W K K K K U K K o.o.K U K K K L K K K G L J J J %.i.%.J J I +.O.+.t.u.i.p.u.u.u.g.p.u.+.W W L A L +.g.g.g.H.J.g.s.t.t.t.W W W X.X.C A W W X.X.X.X.#.#.@.i.:.E C f F X.u.u.i.p.s.k.S.C.k.5.d.d.:.@.*.F F C C F x F F F F R C F C F F b b H Z Z F F F J H G @.@.E J J H E W %.%.u.u.u.k.k.l.k.k.F.G.F.S.S.k.g.a.i.t.t.t.t.o.t.t.g.D.D.F.H.F.k.O.+.t.g.S.g.d.l.l.g.S.k.i.g.d.l.C.l.l.F.S.J.I.I./.I.G.H./.I.J.F.W.q.oXoXoXoX", +"oXoXoXoXoXk I &.&.s.i.k.k.k.f.f.i.p.p.p.+.W X.J X.+.%.f.k.k.k.f.k.k.d.s.s.B.S.p.X.K L K G A L G L K K K K L L J K J L W t.o.U K K K K K K G A A G A L D K L A G D o.+.y.i.p.p.i.t.t.u.t.+.o.o.G A A K J o.D.S.k.g.g.g.a.a.%.+.X.W o.X.W C K +.X.G J Z S A W %.%.%.G z Z Z H @.%.u.%.W %.k.k.s.@.i.u.u.:.$.W *.E R F R C R E E E E 0 E E E C C R 0 E 0 E E R W W E W E E E E E %.:.u.:.:.:.u.k.k.k.l.g.F.G.S.S.g.p.t.t.t.t.t.%.o.t.t.h.^.J.S.J.D.B.k.%.o.d.l.d.%.i.p.i.a.S.g.I.k.k.l.l.S.F.S.I.I.^.^.I.G.H./.I.H.G.I.e.oXoXoXoX", +"oXoXoXoX< Z X.+.+.%.s.l.l.k.g.g.p.u.p.u.W G J U O.+.i.g.k.k.g.f.k.d.p.s.p.g.k.u.U U L A A Z A L G A L K K L K K L K K K X.X.t.L W W W K K J K A Z Z V A A C G A D X.i.t.+.t.p.t.o.t.t.W +.o.@.K D A K %.y.g.g.g.g.g.s.s.s.i.t.t.%.#.G C S X.+.Z h V G G J @.i.s.s.@.E @.X.E X.+.W :.u.%.p.l.X.G @.5.:.:.5.:.u.#.W W E C C E R E 0 T C 0 0 R C E W W E E #.@.#.s.@.#.u.%.%.@.E E %.i.:.%.%.%.u.j.k.l.g.k.S.l.s.%.t.W K t.o.+.%.t.t.p.p.l.S.~.J.J.J.I.g.t.t.g.%.+.t.y.y.p.S.D.J.S.l.F.S.S.S.F.I././.I.U.I.G.^.I.F.H.H.V.oXoXoXoX", +"oXoXoXoX: V +.%.5.t.d.g.k.d.g.g.p.t.t.t.W K K X.X.X.5.g.k.g.k.s.s.s.s.p.d.%.t.p.o.L Z Z h B A Z B Z L A W L K L L K K K K K o.X.K t.W K L K G C Z Z Z Z A A G A G t.%.+.+.t.t.t.W t.t.t.X.#.+.#.+.W X.t.i.a.g.a.g.k.g.s.p.t.y.%.X.X.X.K A +.%.J Z A X.@.%.i.k.l.k.s.s.u.%.{ { X.#.W u.p.k.k.%.@.u.s.s.s.i.i.5.%.%.$.@.E E E C E C C C C E 0 E 0 G W E T E *.j.l.s.@.@.@.@.@.#.W @.@.X.@.@.%.:.s.f.d.i.d.g.g.u.u.X.K o.W X.t.+.%.t.t.t.p.h.~.~.~.I.I.F.S.i.d.p.u.i.t.u.g.S.S.S.H.J.G.S.S.H.H.I.Q.I.~./.G.G./.I.P.H.G.Z.oXoXoXoX", +"oXoXoXoXr J O.%.i.u.a.k.l.s.d.g.p.t.+.X.K K X.X.O.u.a.D.k.k.k.g.u.p.u.p.a.i.d.h.o.A Z B B h B C B C B A A A G K K L L W L K K W K K o.W G K A F A C B A A A G D I i.+.X.t.t.o.t.t.W o.W X.%.%.#.+.o.X.t.i.D.S.S.B.g.a.s.i.t.i.t.u.u.u.G A X.:.J S A J X.i.l.I.G.k.s.s.5.O.X.X.J %.#.:.u.p.k.k.s.s.s.k.j.5.u.:.%.%.$.E *.E E E E E E R E W E E R G E W W s.g.k.l.l.k.s.s.#.@.@.@.X.%.%.%.%.%.i.i.d.f.i.a.a.i.t.%.K o.o.o.X.K t.%.+.y.u.t.a.D.G.~.J.S.k.l.g.l.G.J.l.u.i.g.B.S.k.S.I./.P.F.G.I.I.I.H.I./.I.H.Q./.I.G.F.F.q.oXoXoX", +"oXoXoXoXa H O.%.i.i.d.d.s.f.k.p.d.t.t.o.J X.O.+.%.d.S.J.S.l.k.f.p.s.p.p.p.h.d.d.+.A B h z h h C B B Z Z Z B A L L G L W W W L X.X.U U K K K A J J S Z D A S A A X.i.+.O.+.+.5.i.t.o.X.#.%.:.%.W o.W K o.d.S.S.J.l.l.g.d.a.p.p.p.i.%.E W +.O.X.X.X.X.X.#.i.I.I.F.k.i.%.%.@.J F E W i.i.u.s.d.k.k.k.k.k.k.s.s.s.:.:.:.u.s.E E @.:.%.*.@.@.:.W E R E E @.:.g.l.l.l.I.l.P.l.u.W @.E X.u.:.%.@.%.i.i.i.g.p.s.u.t.%.+.t.t.o.X.U X.O.+.%.y.y.%.o.t.l.~.H.F.k.g.g.k.l.D.G.s.a.l.F.H.F.B.J././.I.I.U.~./.I.G.Q.E.F.P._.I.H.F.P.e.oXoXoX", +"oXoXoX@ k H O.%.k.d.k.k.u.d.d.s.p.t.+.X.X.+.%.:.5.p.g.F.S.S.B.a.p.p.p.p.p.d.t.p.K Z B h h h h C Z A A A A A C A G L W L W W X.W o.U K K K K J K J J J D A A S G J t.p.%.%.+.y.%.u.u.:.u.u.s.u.#.u.a.i.u.l.^.F.D.D.S.l.h.p.p.t.t.#.J Z o.p.+.X.X.X.X.X.#.i.S.I.D.k.%.X.%.@.G H @.u.s.d.k.k.s.k.k.S.S.H.k.s.s.s.s.s.u.s.g.E W *.@.:.:.%.@.#.@.E E @.#.u.s.g.l.l.l.I.J.l.k.s.@.@.@.:.u.i.%.%.O.+.:.u.s.i.u.:.:.+.u.h.u.X.U X.X.X.+.%.%.y.+.o.o.t.l.S.F.l.k.f.h.h.d.F.d.a.S.H.H.I.F.S.I././.E./././.U.I.Q.Q.H.I.I.J.F.S.H.N.oXoXoX", +"oXoXoX: S b O.&.d.l.j.k.p.d.d.i.i.+.o.X.+.%.:.u.i.a.S.S.F.S.k.a.d.d.u.o.W o.K W A A B h k b h C B V B A Z A V B B C L A J K W W L K W K o.L K L A J D S D J D J J #.i.i.u.+.%.%.u.u.s.s.i.s.s.:.u.s.i.i.f.G.I.H.I.I.G.l.i.u.t.o.J J J @.%.+.o.o.U I X.X.t.u.u.t.W W %.@.E Z F J %.i.d.k.k.k.s.s.k.k.F.k.k.k.j.s.s.s.u.r.@.:.i.#.@.;.:.;.@.@.W u.k.l.l.l.k.l.)._.J.I.k.:.@.#.@.W %.:.u.u.%.@.+.5.:.u.u.k.l.g.a.S.g.i.O.X.U J X.+.+.+.%.X.W K K t.d.h.g.f.d.g.d.d.F.l.s.S.G.J.I.I.I.H.I././.Q./././.I././.I.I.I.I.G.H.I.Z.oXoXoX", +"oXoXoXr J S +.i.k.l.k.k.d.d.j.s.y.o.X.o.&.f.u.u.+.f.S.S.S.F.S.g.g.p.+.L K L L L A A Z Z h h h h s B Z Z V A A Z Z Z C G A A G K K L K o.K L L K S S J Z S J X.X.X.J o.t.%.%.%.p.u.u.s.u.i.s.:.%.i.g.g.g.k.l.J.G.J.D.l.l.h.h.a.a.:.u.u.O.+.X.K L U D A J K J G G J W %.W G F Z G W Z W k.l.k.k.k.s.k.S.P.k.k.g.f.s.s.u.u.s.U.].j.:.%.u.s.E @.%.j.l.l.l.l.l.l.l.l.I.U.k.s.u.@.W W @.%.u.t.;.%.%.%.:.:.:.S.P.F.B.g.f.i.X.X.J E X.+.O.X.X.U K K L K t.d.p.p.p.g.l.l.F.D.g.l.F.G.I.J.I.I.I.I.(./.(./.Q.Q._._.I.I.Q.I.G.H.G.Y.^ oXoX", +"oXoXoXa S X.O.i.k.k.k.k.s.s.s.s.t.K +.o.p.g.u.u.i.f.k.k.B.S.S.D.h.t.t.K K A A L A Z B h h h Z h h Z Z A G A Z Z G A C A A D D D K W K A G G J J D S J Z J S J I J U X.%.i.i.i.f.g.d.s.s.g.s.i.i.p.g.g.k.l.l.l.G.S.l.k.l.k.g.p.d.i.i.i.i.+.K A A A Z Z D A Z Z Z G J W #.W J J W W W %.l.l.l.l.k.j.l.l.l.l.k.k.k.s.r.:.:.:.l.U.k.k.i.i.i.E $.k.k.S.k.S.S.H.H.I.I.I.^.l.d.:.%.W @.%.:.:.:.i.%.%.i.u.:.u.l./.S.k.s.i.i.#.X.{ X.+.X.X.U O.U D J U D K t.u.t.u.p.d.D.B.B.B.l.l.I.~.G.I.I.~.I.~.(.(.(.Q.E.`.`.U.I././.H.H.F.L.<.oXoX", +"oXoXoX5 k U %.i.k.i.k.s.s.s.u.#.o.U t.X.h.h.s.u.g.g.k.g.B.J.H.D.p.o.K U K L L L D Z V h b V Z b h Z L G A Z V Z J A A Z A J D J K J A Z D J G J I A J A S S Z A J X.+.B.i.p.i.p.d.k.a.g.g.i.i.i.s.g.p.k.G.l.I.l.S.l.g.k.p.i.u.%.%.i.i.t.+.D A Z A A A D A F J F J J G W W K J E W #.i.s.k.l.k.k.l.l.k.s.l.k.k.j.k.l.i.s.:.r.s.s.k.k.s.:.$.%.j.G.F.S.F.H.G.I.G.I.l.U.l.:.u.s.:.:.u.:.u.u.s.g.f.d.u.u.u.f.I.S.k.s.i.:.+.@.X.X.O.U U X.O.U I U L Z L o.t.t.t.u.p.l.S.S.S.k.F.P./.I.I.I.^.~./.(._._.(.(.]._.Q.I.U.I.F.F.F.H.w.oXoX", +"oXoXoX5 S X.&.i.i.s.k.p.p.i.u.W U o.o.X.i.d.p.u.D.B.B.k.g.H.D.h.K K o.K K W K L L G C h h b b b C C G D Z h Z z A J A S A G J D K G F S Z H J U I J S V D S Z D J X.u.s.i.i.p.f.i.p.a.g.p.i.u.i.f.d.p.l.G.k.l.l.S.g.g.d.t.@.X.o.o.%.t.W X.D A A A A G D F Z F Z C C A A Z G D W W o.+.+.%.u.s.g.l.^.P.j.l.l.l.k.g.g.s.s.i.g.g.s.s.s.k.l.j.k.k.l.F.F.I././.I.I.I.I.I.l.j.k.f.f.s.u.u.:.f.g.g.h.l.k.s.:.i.l.B.k.k.s.5.%.%.X.I U X.U U X.U U U D A K +.u.s.u.u.u.d.S.H.F.B.k.G.G.I.I.I.I./././.(._./.(.`.[./.Q.I.I.F.S.S.F.w.oXoX", +"oXoXl 4 S X.+.i.s.i.s.s.i.p.i.W L U K o.+.u.p.g.S.B.B.S.g.g.S.y.o.K K o.W K K K L L Z C Z Z Z S A Z Z Z Z B h Z G W A A D D K D G L J Z Z S J J D U I J D S Z D G X.u.u.&.a.p.i.i.i.i.g.s.i.i.s.f.d.d.l.d.s.l.k.l.g.f.d.p.t.+.W X.X.K G A A G A A A Z Z Z C s d f 0 f C C Z J W W X.#.#.%.u.u.f.l.l.G.k.l.G.l.l.s.s.g.s.s.s.g.s.s.j.s.l.l.l.l.l.F.S.I.[._._.E.I.U.U.l.l.l.f.f.i.s.u.u.f.S.g.S.H.F.l.s.g.S.k.k.k.f.i.:.X.X.{ O.X.X.o.+.O.U U U o.X.#.i.k.k.t.t.p.k.B.J.J.F.G.I.F.G.I.I./.I./.'.`./.(.].].]./.P.G.l.F.H.F.e.oXoX", +"oXoXg 4 H O.+.%.p.f.k.p.i.t.t.W K K K X.+.5.i.S.B.S.F.C.k.S.g.o.L L L L W X.U K L A S h Z Z Z G S Z h h Z z z Z A W A G A G K G A A F Z D D D U I J J J D Z S D D o.%.:.i.p.i.i.i.p.i.a.a.i.d.u.+.d.g.g.s.k.k.k.k.k.k.k.d.p.u.%.+.K D A Z D D A Z A V V B h h h f 0 9 d s C A W @.W W @.%.u.s.k.l.l.l.l.l.l.U.k.j.l.l.l.k.j.g.j.k.j.k.k.k.G.G.G.G.G.I.U././././.I.l.F.k.k.k.k.s.s.i.p.g.S.S.D.F.S.k.C.k.H.S.l.k.s.5.:.X.@.+.+.+.O.X.%.i.U U K t.a.g.D.S.p.%.+.a.g.F.F.G.J.I.I.G.I.Q./.`././.`.`.E.(.`.[.[._.H.F.S.S.J.F.N.oXoX", +"oXoXt , J U U O.u.p.g.d.i.t.t.t.X.D D X.O.+.+.a.S.S.S.S.B.D.y.U K L L L K +.t.L J S Z b b Z Z S C Z h C Z C Z C F W G F A A A J G A C C D K D K I I D D I S D A D @.%.:.i.i.p.i.i.p.d.d.g.d.u.K W u.a.i.d.l.d.d.d.s.k.k.k.f.u.u.t.o.K G D D D J V Z A V C B h k h f i d s B H J @.W X.:.i.s.d.k.l.G.G.G.l.l.l.l.l.l.l.l.l.k.l.l.J.J.l.k.k.l.G.G.F.G.I.U.Q.E././.I.U.G.G.k.j.k.k.s.s.f.k.F.J.J.H.H.F.S.S.H.H.k.k.:.%.%.@.+.#.+.+.U X.X.I U K K o.d.S.I.S.k.s.+.d.D.J.I.G.F.J.I.I././.(.`././.].[.(./.(.].|.).F.G.I.F.I.F.C.M oX", +"oXoXh 4 J J J X.:.s.p.h.t.t.W t.K D J U X.+.$.i.g.S.B.S.S.S.+.K L A G L L D K L D Z Z h b k h k b b h Z J Z C Z Z Z G G A J D J K A Z G K D D D D I D D D I U D U i.:.i.s.s.s.p.p.i.i.p.h.a.+.K o.+.o.%.d.k.k.k.k.s.k.s.f.p.u.u.W W K A D D D X.D Z A V Z B h p i i 0 i h A J E W %.:.u.s.f.l.l.l.l.P.l.l.U._.l.l.l.l.l.l.U.l.U.J.l.G.l.l.G.F.F.F.F.I.Q./.I.Q._.U.G.I.G.k.k.d.k.k.g.g.S.J././.^.'.I.F.F.F.F.k.k.s.i.:.%.+.@.+.O.U X.X.U D K U o.p.F.G.S.k.k.i.g.J.I.J.J.S.F.I.I.I.I././._._.[.}._.Q./.].|.).H.I.H.H.I.H.C.>.oX", +"oXoXm g G S G X.i.d.p.p.i.W K L D S S J X.O.+.a.k.B.S.F.D.S.t.U L L K G D A A A A C h h h Z h h z h z C C z C G F F F G A K G K o.K D J D D L D D I I I J I U I X.%.%.%.5.p.p.f.%.t.i.i.t.o.U A D A K X.d.k.s.i.d.k.k.i.d.u.u.u.W K D L G D J U D A A A Z C B f f p a s Z S J X.o.u.i.i.s.f.k.l.G.U.U.I.l.U.l.l.U.U.U.U.l.l.l.l.l.U.P.l.l.G.F.G.F.F.I.U./.I.Q./.U./.U.I.l.k.k.k.S.B.S.S.F././.^.(.I.F.F.F.G.F.l.k.s.i.:.:.%.%.o.O.O.X.U +.t.%.X.s.H.I.H.l.k.f.g.H.I.I.F.F.G.G.I.I.~.^./././.[.|.{.(./.[.[._.H.I.H.F.I.G.S.w.oX", +"oXoXa Z S Z S W i.d.a.u.t.W Z Z A A V K U U +.a.l.S.S.F.H.D.p.U G G A B A A A B Z h h z Z b h h h h h z h z Z Z Z Z Z Z E F A D K G G G L D G D K G L W W X.W W E K o.#.o.t.t.t.t.o.X.t.X.A Z D A D K K :.S.g.i.i.k.k.s.u.@.#.+.K G G K W J J K A A Z Z A Z Z B B h b S A E W @.#.u.i.d.j.l.l.k.l.U.I.^.I.I.U.I.I.G.G.F.F.F.I.F.G._.G.l.G.l.G.U.l.G.U.U.(.`.[./.E.E.J.J.F.k.B.H.J.D.S.F.J.I.I.J.I.I.G.G.F.G.H.H.l.k.s.u.:.u.i.%.+.%.:.%.f.a.k.g.g.B.I.E.F.F.g.s.k.F.I.H.G.H.I.J.G.I.I.^./.^.[.XX}.(./.`.{.Q.J.F.F.F.G.G.F.6.oX", +"oXoXg S S h S J a.t.i.+.o.K B C V V S D U U O.B.S.l.g.k.S.F.g.+.W G A A A B B B z h h h h h h h h h h h k h h b b Z b b Z Z F G J A G A A A A K G D J W W #.%.@.W W W W W W W +.K A J X.D V Z A A A A L +.s.d.i.p.f.l.k.f.u.:.W A A A A K W W G A A Z B B B Z A A S D J W W @.%.s.s.W #.d.l.l.l.I.U.U.^.I.U./.I.I.I.G.F.F.S.G.l.l.l.F.F.U.U.l.G.U.J.I._._.[.[.[.Q.E.E.J.J.F.D.J.J.H.J.I.I.I.^.~.~.^.I.I.I.I.I.I.G.l.j.s.u.s.s.u.%.s.g.p.i.f.g.D.F.S.J.I.S.S.k.a.g.S.S.G.I.H.S.B.F.F.J.I.I./.[. X].Q./.(._.Q.F.C.F.H.G.F.P.w.oX", +"oXoXa J Z h Z G p.u.t.+.o.L B h V Z Z J U O.y.H.S.l.g.p.g.D.D.i.W K L L L B B B h s h h h s h h h b h k b h b b b b b b Z h Z Z G A D A A A A G G J J W #.:.:.%.@.X.J A J L A A Z A D L A Z Z A Z A A D %.p.d.s.f.l.F.S.f.s.u.:.G G J C G W W L A V Z h s s S D A A E X.%.%.#.%.#.t.W u.l.l.J.I.G.U././.^.U./.^.I.~.I.F.F.k.S.F.I.I.P.G.P.J.l.G.I.G.G.I./.`.[.[.`./.Q.E.E.E./././.I.~.^.^.I.~.I.I.~.I.I.~.~.^.I.G.l.l.k.s.i.:.:.%.s.k.u.%.%.u.l.D.F.B.S.S.S.g.s.s.d.k.F.F.l.B.S.S.S.J.J.J.(.(.[.`.Q.Q./.(.E.S.B.H.H.H.F.F.e.oX", +"oXoXh { Z s h J +.t.t.t.W A h B V V Z J U %.i.S.S.g.l.a.g.S.H.S.t.K L G A A B B h s Z h h B z Z b b b b h k b b b F F b z z Z b Z A J A A A A A G A J W :.s.:.:.#.X.J G J L A B A A A D D A Z A Z A D J %.s.a.s.d.g.k.g.p.p.u.%.W #.K J W J L Z Z A V h s B B C Z Z X.#.:.:.X.#.t.t.W d.l.l.l.I.G.I.~.^.^./._.^./.^.I.l.k.k.S.F.F.G.l.F.l.l.l.G.G.G.G.G.^.[.}._.`./.^.E.E././././.I.~.I.~.~.I.J.I.I.G.~.~./.'./.P.G.G.G.F.s.i.g.i.k.k.u.%.+.t.g.B.S.g.B.S.g.k.s.g.l.k.l.F.S.F.S.F.H.J.D.J././.`.`.E.^./.Q.E.J.S.F.G.F.F.S.N.oX", +"oXoXH I S d h D X.U X.o.K V V Z V Z H G X.i.a.k.l.a.l.g.p.h.D.D.p.W L L A L C B h h z Z V B Z B z Z Z Z b b Z b Z Z b F Z z b Z S G J D A A A A G K K %.f.s.d.:.X.X.X.J W K G Z V A A A A S A A A A X.J :.a.g.s.p.d.s.i.s.s.i.@.@.W W J W K J G A A Z Z Z G J J J J X.+.u.u.%.%.o.t.:.u.l.l.G.I.G.G.U.^././.^./.U.U.G.F.C.l.F.F.l.F.l.F.G.F.l.F.l.I.l.I.^._._./.(.E.I.E.I./././.I.J.J.J.~././.^./.I.I./.I.(.[.'.Q.I.I.G.C.k.k.k.k.P.k.:.+.i.a.g.S.S.g.D.S.k.F.k.g.F.l.k.k.G.J.F.J.G.I.F.F.I.~./.(.Q./.(.^.E.H.H.F.H.S.B.B.N.oX", +"oXoXk I Z a k D K K L K U D Z G Z Z J X.+.S.a.k.g.a.d.p.p.p.h.l.l.o.G L L A C B h h Z Z A Z C h S Z S Z Z Z Z b Z Z Z Z Z C Z F S G X.X.G G A A D D J :.f.s.u.%.U U I J K G A Z B A A A J D B A A J %.K %.g.f.i.i.u.u.i.i.i.s.%.@.W W W L G A A D D A J @.%.O.+.#.X.X.%.u.s.:.u.s.u.u.d.l.l.I.l.G.G.G.I././.~.^.I.U.F.G.F.G.G.F.G.U.F.l.F.G.G.l.G.J.U.J.I._.^.U.E.J.J.I.I././.(.E.I.I.G.I./.'.'.`./././.~./.[.[._./.Q.I.l.S.H.S.S.Q.P.u.i.p.p.g.S.F.B.B.H.H.J.B.g.S.B.k.S.H.I.F.H.I.J.S.G.J.I././.Q.(.(.Q.E.E.I.H.S.S.k.g.N.oX", +"oXoXb S S s k D X.K U K o.X.D L Z S :.p.p.g.a.B.l.S.h.a.p.p.d.l.l.h.t.t.t.K C B Z B A G Z B V C C Z S A Z Z b Z b S S Z b Z F H S S H X.+.K K D G K J @.d.s.t.W J J J J K K A A V Z A G U J V A A A D D %.k.g.s.i.:.%.u.u.:.5.%.%.%.u.o.J Z B A G D X.%.%.%.%.%.%.O.+.%.p.u.:.s.k.k.d.l.d.k.l.l.F.I.G.U.I.I.I.^./.I.I.G.G.G.F.F.G.l.l.G.F.P.G.^.U.U.I.G.I._.U.I.J.I.I.J.I.~.(.[.`.~.I.J.~./.'.[.[._././.I./.`._.]._.Q.I.G.G.G.I.S.I.J.k.f.i.a.g.H.H.S.B.g.D.S.B.S.F.F.H.S.J.J.B.S.^.J.F.F.J.I./././.(./.E.E.E.Q.H.S.S.k.g.N.oX", +"oX< Z B F h V J X.K U J o.o.U L Z S %.a.f.a.a.k.h.l.D.h.p.p.p.h.l.h.t.t.o.W A A A A K L A B V h C Z S A S Z Z b z z Z Z Z F H Z Z V Z X.%.X.X.K G A J W W W W J J I J D J K A A Z D J G X.U Z B A D W X.:.k.s.u.i.u.:.u.%.#.X.X.@.W W W K L W A G X.+.i.%.%.%.+.%.%.i.a.f.d.d.k.l.l.l.l.k.k.k.k.l.F.G.G.I.G.J.^.I.I.U.G.F.C.l.l.G.l.J.P.l.l.F.H.l.l.l.G.I.U.G.I.J.I.J.F.G.I./.[.(.I.I.I.~.^._.|.|.`._.Q./.(.'._.|._.Q.I.I.G.I.I.I.I.I.H.B.s.a.k.F.H.H.S.B.H.S.B.S.S.S.S.S.S.I.J.F.I.F.S.F.I.I./.(.^.^.^.Q.I.^.^.H.F.D.S.C.B.) ", +"oX8 h V J z Z G X.U X.U U o.U U A Z U a.k.g.g.g.g.g.g.g.p.t.p.h.p.h.t.W K K A A A L L G Z k V Z Z J A S S J G Z z Z b Z F F F Z b z Z S E W W K G A G D G G W G G X.U G I I D D D D X.U K +.A B Z J +.g.l.l.f.u.s.k.s.u.i.o.{ J J A A K K J o.X.X.+.i.i.i.i.%.5.p.p.s.a.f.g.D.S.H.H.S.k.s.f.k.k.l.l.l.I.G.G.G.G.I.G.U.I.F.F.l.l.F.G.G.S.S.H.H.H.F.S.k.F.G.G.I.G.I.H.S.F.I.I.I.U.I.G.I./.U.I.^.[.]._._.I.I._._._.[.`./.~.I.I.G.I.I.I.I.I.S.k.l.h.l.H.G.G.S.H.S.S.B.B.B.g.S.F.F.J.G.H.l.C.G.I.I./.^.Q.^./.Q.J.E.E.H.F.S.S.S.a.^ ", +"oXg a Z X.C S G X.U L t.U U o.U U D X.a.a.f.g.k.s.g.a.g.p.p.p.h.h.p.p.K A Z B L A L G J S V Z S S D S Z Z S S z Z k b Z F J F b S A A Z G G J W K J L G L A L A D K X.J J J U D J K U U J #.A C G X.%.g.g.f.p.s.s.p.u.s.%.X.X.J C C C G W W X.X.+.f.i.a.i.g.g.i.s.f.f.i.s.g.S.J.I.G.l.k.k.l.F.l.G.G.l.G.G.G.G.F.F.F.l.F.l.l.F.F.G.G.P.l.S.k.k.k.S.S.k.F.F.F.G.H.J.I.H.P.I.I./.U.I.I.G.G.I.^.~./._._._._.~.~._._.(.(./.(.I.H.G.I.G.I.I.J.S.k.S.S.l.F.G.G.S.H.H.D.B.B.D.S.S.F.J.G.F.S.S.S.G.I.U.^.^./.^.(.E.F.J.S.S.k.B.S.F.N.,.", +"< t i Z W A D D K U K o.U L U U %.+.X.5.i.i.i.k.p.p.p.p.p.t.t.h.p.t.o.o.Z Z A A K G A A Z A S J G A Z Z Z S H Z b b b Z F J G C G G A F Z C Z W X.J G D A Z A A J J J S S J X.I J I D I X.O.D S A E E %.k.f.i.5.%.:.:.%.J G G Z h f f A o.K X.X.%.5.5.a.d.g.S.S.g.s.a.p.p.g.S.H.I.G.l.k.k.l.k.l.F.U.I.l.I.G.G.F.F.F.l.l.k.F.l.F.G.G.P.F.H.S.k.S.I.F.F.S.k.F.F.F.F.I.I.I.I.I./.U.I.G.G.I.I.~.I.U.~.^.~.~.I.^.^.U././.I.I.I.F.I.I.G.I.I.S.S.S.g.g.l.F.G.I.G.H.H.B.S.l.J.J.S.D.J.J.S.l.l.l.G.I.^.I.J.E.E.(.I.F.H.S.B.a.S.S.D.N.c.", +"oXi i Z Z S D D L U K K U K K O.:.+.J J +.i.i.s.p.p.y.t.p.t.t.h.h.p.o.L B C A A L A C A S D A D D A Z Z Z H J Z Z b Z Z A E G A A A Z C C C Z G W o.K G A A A A D J I J J J X.U I G D I %.%.U G J G J %.g.s.:.%.:.:.u.:.K D C d i 0 0 B G A K X.%.i.i.i.s.g.k.F.S.a.a.s.f.g.B.J.I.G.l.k.k.l.l.l.F.U.U.G.I.I.F.G.G.F.G.l.l.S.l.S.F.l.l.l.S.J.S.H.G.H.G.F.C.l.H.I.H.G.I._.].I.I.G.G.H.H.G.I.I.G.I.I.I.I.^.U.^.~.I.I.I.J.I.G.H.F.H.I.I.U.S.S.S.S.g.l.F.I./.F.H.D.S.l.S.D.J.F.F.H.G.H.S.G.H.F.G.I.G.D.I.^.!.H.F.S.F.S.F.S.H.D.B.v.", +"oXi f Z F Z G G L K K K U K U X.t.i.J F K :.i.i.i.t.p.p.p.i.u.u.p.p.o.K Z B A A L G Z A D X.J S A S Z Z b F F b h Z Z D D X.W J L G C B Z Z Z G K +.o.J A A A A Z A D U J J I I X.J I X.:.%.X.U J E { :.:.:.X.X.@.t.t.u.W B p i 0 i f s B A J #.5.s.s.i.i.g.f.S.g.s.s.%.i.i.s.D.G.F.l.l.k.k.k.S.S.H.I.G.G.P.G.G.G.F.l.k.k.k.l.G.G.l.l.l.F.l.G.P.F.I.H.F.S.F.G.U.^./.Q.U./.I.I.I.F.F.l.H.J.J.l.I.I.J.I.~._.I.~.I.I.I.l.I.G.G.G.G.G././.H.H.S.l.S.F.F.G.I.F.H.F.S.S.B.F.J.J.J.S.F.H.G.I.G.J.J.I.H.F.I././.J.S.S.S.B.F.B.D.F.F.8.", +"oX8 z J f h G L A K L K U K I U X.X.Z Z A E X.:.i.i.p.t.i.a.u.+.t.t.W K A A Z A Z A Z A J I J J D F Z b Z b h b b b S G S G J J J A Z Z C Z G C S J @.X.J J A A A D J K J J I I I J X.X.:.%.X.{ E X.%.s.s.#.X.D L W L G A C h d 0 0 i p B D o.+.i.S.s.:.i.i.g.S.k.k.s.@.O.i.s.s.k.k.k.l.k.k.F.F.l.F.G.l.F.G.H.F.F.F.F.l.l.l.l.U.P.P.G.l.l.I.J.G.S.I.G.F.S.S.F.F./. X X[.I.J.G.H.G.C.F.F.l.G.U.U.I.J.J.J.l.I.I.I.l.J.J.I.G.G.G.I.I.(.`.I.F.S.S.S.G.I.I.I.F.F.F.S.F.B.S.J.E.J.J.J.G.I.G.I.J.J.H.F.S.J././.E.S.S.B.S.F.S.F.H.C./ ", +"oX8 z J p h A D A L L L J I J U X.W Z Z F S A %.%.p.a.i.p.p.i.t.t.d.t.K A G Z A A A A G J J J S G S Z Z Z b z h b Z H S S A Z G W G L J Z C C C z Z D X.W J J J D D D J J D U U I J U I X.%.%.@.@.@.i.i.:.W J G J K A G D G A Z f 9 0 B A W t.t.:.s.i.i.:.i.s.g.s.k.s.%.%.s.s.s.p.k.f.k.k.l.S.S.F.G.G.F.S.F.F.F.G.G.F.S.l.l.S.G.G.l.l.G.F.G.F.G.I.I.G.G.l.F.l.F.I.`.}.[.U.F.H.G.G.F.F.G.I.G.J.U.J.I.J.l.l.I.l.I.l.U.I.l.I.l.I.I.I.[.].I.H.F.S.F.I.I.U.I.H.H.S.S.S.S.F.I.`.Q.J.J.G.G.F.H.J.H.S.B.D.J./.^.J.S.C.B.F.J.H.S.H.F./ ", +"oXoXH S a h A A A L L L K U U J D A Z z Z b X.i.u.u.g.a.p.u.g.g.p.l.p.t.A A A Z C A A K U U J J D S z Z F b b b Z H G S S Z A A J J A G G G A C h Z D X.@.W G J J D D D J I U X.U J I J { X.%.%.X.:.g.i.X.J G J W W K G D D A Z h i s A J X.o.t.%.i.:.u.s.s.i.s.s.k.k.s.s.s.s.f.k.f.k.k.l.S.S.F.G.F.G.G.l.F.F.G.U.I.G.F.l.k.l.H.l.l.G.I.l.G.F.l.G.I.F.G.S.l.l.G.I.U._./.U.H.G.I.F.F.l.l.l.G.J.J.l.G.G.G.J.l.I._._.l.J.l.G.I.I.I.I././.I.F.F.F.H.H.G.I.I.H.H.S.k.S.H.J.I./.I.F.J.H.H.H.J.F.F.B.k.H.H.^.^.J.S.S.S.S.F.H.H.J.C.8.", +"@ @ F F i B B A A A L A L U K U F b Z b Z b G y.s.i.u.i.p.p.d.p.p.l.p.t.L A B A A V A J U U K K A A m Z Z m H H F G E K J W D D G G C G G J J C C V G J K X.W J W L J J G W E W @.W W W W W @.#.#.s.s.W E E E W W W W G A A A A C i f A o.@.u.s.s.u.u.k.k.d.s.u.u.u.p.l.l.G.k.s.p.p.k.l.S.l.S.F.S.k.l.F.S.S.H.H.I./.H.l.l.l.k.l.l.H.H.F.G.G.F.F.G.G.S.G.G.H.G.I.I.I.^._.U.G.F.J.F.C.l.k.k.I.G.G.F.H.F.S.F.F.H.I.I.I.F.F.G.G.I.I.I.(./.^.F.H.G.I.I.G.G.I.I.H.S.k.S.H.J.J.E.H.D.H.G.F.F.G.H.S.l.k.F.H.I.^.I.k.k.S.B.S.H.J.J.C.6.", +"oXa h J p B B L Z A L A A U U K F b b Z Z Z G %.d.d.p.d.p.u.p.t.t.p.t.t.K A A A A Z A U X.J K U A Z Z Z Z Z J J G G W W K W K D L L A W W W W G S S G A J X.#.#.W W G L W E E E W W W W @.#.@.#.s.s.@.E W E W W W W L A A A A G Z h B G W X.i.s.s.s.k.l.k.g.d.s.t.t.p.g.l.F.d.u.t.u.p.p.k.k.k.F.F.S.S.B.F.S.S.H.I.`.H.F.G.S.k.F.F.G.H.F.G.I.H.F.G.l.l.P.I.J.G.F.I.I.U._.U.G.F.I.F.F.S.k.k.H.H.G.G.F.S.I.B.S.F.I.G.H.F.F.F.G.G.I.I././.I.F.J.H.J.I.I.I./.J.S.H.S.k.S.S.F.J.H.D.H.G.F.F.G.H.F.S.l.J.G.I.U.I.S.S.S.k.S.S.S.H.B.j.", +"oX5 s D s s B B B A A A A D U U Z Z Z F F b F W t.i.p.d.i.t.t.t.t.t.+.W o.G A B Z Z S J K I U D A A Z F F G J F G F G J D W U J W G A L J W %.W J E J K W X.W X.@.o.W A W W E W #.W @.@.@.:.@.#.u.#.E E E W @.@.W W W G L E L G A V h C A W :.u.u.k.l.U.l.l.f.d.s.i.i.p.s.s.:.#.t.t.t.t.s.p.s.l.D.F.F.k.S.l.l.H.J.J.S.F.G.S.S.F.F.G.I.I.U.G.I.G.S.k.k.S.I.J.H.F.G.G.I.U.U.I.G.I.I.I.l.l.S.F.F.I.U.G.S.S.l.S.l.I.I.H.G.H.G.G.I.I.^./.Q.E.I.^.J.I.G.I.G.I.I.F.D.F.g.k.k.S.H.J.H.F.G.H.F.H.F.F.G.H.J.I.I./.P.F.B.S.S.k.S.S.H.g.,.", +"oX= s h s s B Z Z A A Z A L U U Z Z Z S A m z F W t.p.p.u.t.W t.t.K K t.t.G A B V A S J J X.X.J D A S E J H { S Z F A W J K G J L C A K G G W W X.X.@.W J J A D K W @.W W J E W @.#.@.W W :.:.@.:.#.@.W E @.#.@.#.#.W W W W G G A A G F W :.@.%.u.s.k.U.l.l.f.i.d.f.g.i.i.i.#.o.t.W t.t.u.p.l.G.S.G.J.F.S.F.H.F.F.F.S.l.F./.G.G.I.I./.(.U.G.F.F.B.k.l.H.F.F.F.S.l.l.G.G.G.l.G.^.I.F.l.l.k.k.F.G./.I.S.S.l.F.l.l.F.I.G.H.F.F.J.I.^././.E.E.^.J.F.H.I.G.G.J.I.F.F.S.k.k.S.S.D.H.J.G.G.H.F.S.S.I.I.I.I.I.I.I.S.k.S.S.B.S.F.F.f. .", +"oX= i d i p p B Z V A Z V L U L Z Z F F F F Z Z E t.i.p.t.t.W o.t.o.t.W K A B A V A D K U U +.X.X.K G J I { H H F Z J i.X.G A J C A A L W X.W J G W t.+.W W A G A F @.X.W @.E W :.:.W W @.:.#.:.g.i.u.u.@.#.:.@.#.#.W W W W W G A A X.W @.X.W @.:.s.k.k.k.k.d.d.k.g.p.%.u.#.+.%.+.o.t.t.p.l.h.D.F.B.D.S.S.F.F.l.G.F.H.l.S.H.I.I.I.~./.(.E.I.F.F.F.S.S.J.J.J.S.S.l.F.F.C.F.G.G.G.F.k.k.k.k.S.J.D.G.H.S.S.S.l.l.k.H.H.l.F.F.G.^.^.I././.E.J.J.J.F.F.G.G.G.H.F.l.l.B.S.S.S.S.S.H.I.J.F.H.F.S.S.J.J.I.I.I.I.H.k.B.S.S.D.H.S.H.g.,.", +"oX% 7 0 i p p B B B A A V A L D Z Z F F J F z z Z #.t.p.t.o.t.t.p.p.t.p.t.A A B Z D J K D I U I X.J D D H J J H W E D W J A G G A C W L K W K G S S X.u.t.W K J A A E #.%.@.E W :.:.#.#.:.s.:.:.i.g.g.s.:.#.#.@.#.#.W @.W G A A A K @.#.X.E X.#.%.u.k.s.p.s.s.d.i.%.%.%.%.X.X.%.+.t.t.t.d.h.d.h.S.g.g.l.l.S.G.H.I.G.F.l.l.F.I.I./.(.}.`./.I.S.F.S.F.H.J.H.B.S.S.F.I.l.k.l.F.G.l.l.l.F.k.l.l.F.S.F.F.H.S.H.H.l.k.l.l.k.l.l.l.I././.`.(.I.H.H.F.F.F.F.H.H.F.l.F.l.B.S.S.S.B.S.F.J.I.H.H.F.F.S.F.J.U.G.I./.H.F.S.S.B.S.S.H.H.N./ ", +"oX@ 6 t i i p s A V Z Z Z A D D S Z F F G F C C C W p.t.o.W t.t.t.t.t.t.K L Z Z V A A D D I I D J S D J J J J J E W E J J X.W W F F W W J D A G J S F J t.W K J J E E X.u.@.E @.u.:.t.#.s.g.s.s.u.u.:.u.:.:.:.W W @.W @.E G G G C E X.X.E J W X.X.%.:.:.u.s.s.u.;.X.@.:.%.X.W X.p.t.t.W p.p.p.p.g.g.l.g.k.l.l.H.G.F.S.k.l.l.S.U.^.(.[./.E.I.C.S.S.S.S.B.S.l.S.F.I.G.l.k.F.G.G.G.l.l.F.k.k.g.S.F.G.G.l.H.H.F.g.k.l.l.k.g.k.l.F.I.(.(.(.I.H.D.S.H.l.F.H.F.F.S.F.k.S.S.S.S.B.S.S.H.J.H.H.S.S.S.D.I.Q.H.I.I.H.F.F.F.S.B.S.H.H.g.M ", +"oXoX6 a e i p B B B B A A A S D S H H H A Z Z G A L t.i.p.o.t.t.t.L L t.U K A Z Z V A J I I D J J J J D G G G J E J Z W @.@.@.J W G E W X.K D A X.H G J J W W G A X.W E #.%.@.W :.@.%.:.s.g.j.s.u.*.@.s.u.:.:.@.@.W @.#.E E G E G G E R Z C C E W X.W @.%.t.u.u.%.#.E @.X.X.J U K t.W t.t.p.p.p.p.h.l.g.k.l.k.l.G.S.l.l.l.F.F.G.I.(._./.I.H.F.F.J.B.B.B.S.S.k.S.G.l.l.F.l.G.G.I.l.k.f.l.k.g.g.F.F.F.l.S.H.S.g.k.k.k.k.k.F.F.F.G./././.E.H.J.H.H.F.F.H.F.S.k.S.l.S.S.S.S.l.g.S.H.J.F.H.H.S.H.H.^.~.I.I.I.G.H.F.S.S.B.F.I.B.j.M ", +"8 oXe i t i i s V B B Z D V D U S Z F H Z Z F J G G W i.t.t.t.t.W L L u.W W W G Z Z A L J D I J J J E H S Z B Z F F Z Z J W X.J E W G W W W W W W W W :.J G t.W G X.@.W @.#.u.%.t.#.:.:.s.i.s.k.s.%.:.:.i.:.:.@.@.@.#.#.@.E E 0 G C Z F z b F R E @.@.o.o.@.%.%.#.%.@.E W W W J X.U U %.p.u.p.t.p.d.d.k.k.k.k.l.F.F.F.S.F.G.F.F.G./.'./.G.l.k.F.I.S.k.S.l.l.l.C.l.l.l.l.F.l.G.G.l.k.k.l.k.f.k.F.F.S.B.S.J.S.k.l.k.k.l.l.l.F.H.G./.Q.^.^.J.F.D.S.S.S.F.B.F.B.B.S.S.S.S.S.g.B.S.H.F.F.J.H.H.H.J.I.I.I.I.E.J.J.F.B.B.S.J.J.S.B./ ", +"oX= 4 6 0 s V i V V B V V V Z D F Z Z F F S W J G L L W t.o.o.o.W A L W W L W A A A A D J J J I I I E F S S V Z Z Z F F Z F J J G G G W #.W #.W E W g.G.#.G W t.X.E @.o.W W %.s.r.s.u.u.i.s.s.s.s.s.s.:.s.u.:.@.@.:.#.#.@.E E E h z z Z b b C F E W E W W K W E X.+.i.J E W D J G J D o.p.p.p.p.d.d.d.g.k.k.g.h.k.l.I.P.F.G.G.G.F.H.I.^.G.F.S.S.F.H.S.H.G.F.G.l.l.l.k.l.l.l.F.l.k.l.l.F.F.S.l.F.F.F.k.S.J.S.k.l.k.k.l.D.F.G.F.I./.E.J.J.S.S.S.S.S.H.S.B.F.S.B.S.S.S.S.k.B.S.J.H.S.F.J.H.J.J.J.I.I.^.I.I.I.I.J.S.S.H.I.I.S.N.! ", +"oX@ 3 6 6 s D s h B s V A k V A Z Z C Z F F J X.G W W L W o.W W K A L W K K W K D D D J J X.X.J U +.X.E A A A Z Z z Z F Z Z F A G W W W W W W W G G #.d.W G G o.%.W W W W W %.s.s.s.s.s.i.s.g.s.s.i.s.s.s.:.:.:.:.:.#.:.@.@.E E z F F z z h Z Z F J E W W G J G J J %.X.J J J G I G K #.u.p.i.p.p.d.k.k.l.l.g.g.k.k.l.S.F.S.G.G.F.H.H.I.G.F.S.H.S.B.k.S.G.G.F.k.k.l.l.C.l.P._.P.l.k.k.l.F.D.S.S.H.J.S.S.F.F.l.k.k.l.l.l.F.H.H.G.E.I.J.H.D.H.F.F.F.J.H.S.B.S.S.F.F.H.F.h.S.F.J.F.B.F.S.S.F.J.J.J.I.I.I.I.I.J.F.S.B.S.I.^.F.N.) ", +"oX. 4 t e i h h s V h V V V B A S C z Z Z F J E W G G G L W o.K L L G W K W J K W D D D J y.O.J U X.@.X.J A A D Z Z z Z F Z S Z Z W W t.u.W W Z Z G A J G G G J %.X.W K X.#.:.u.s.s.s.s.:.:.s.k.g.i.s.j.s.:.s.s.:.:.s.:.@.E E C Z E Z z d f z F F G @.W F C Z C S W o.o.W J J J J D X.X.+.a.i.i.p.p.d.k.l.F.l.f.s.k.S.S.k.k.G.I.I.F.F.J.G.S.k.S.S.k.l.l.C.F.l.l.C.S.l.G.l.G.I.G.G.F.k.k.l.F.C.S.F.J.H.S.S.S.l.l.k.f.f.g.S.l.S.F.J.J.H.F.F.E.^.J.J.J.H.H.F.S.B.F.B.H.S.a.B.S.F.S.F.H.S.D.H.J.J.J.I.^.E.I.J.F.S.S.B.S.I.I.g.9.oX", +"oX+ 5 i 6 i s s s V V V V B h Z A S Z b C Z J J W G L G L K W J D J G X.J G K X.X.{ { G I U X.X.X.J W X.W A A A S Z Z Z Z Z C z C A A W W W E F A A A J G G E W X.@.@.X.X.%.:.u.:.i.:.:.:.u.d.k.s.:.s.d.s.k.s.s.:.:.*.@.@.@.@.E E F 9 d d d f F J G E W Z z F Z S W %.%.@.J E E J D X.O.+.p.i.f.d.d.k.k.k.l.l.k.k.k.S.S.l.k.S.F.D.S.S.S.G.F.l.S.S.g.l.l.l.I.l.l.H.F.F.I.F.I.l.l.G.F.k.k.k.l.l.l.H.I.F.S.S.k.k.S.k.d.a.h.F.F.S.S.J.J.J.S.D.H.H.F.J.I.J.J.J.C.g.S.S.H.D.g.S.H.J.F.F.H.D.H.J.J.I.^.I.I./.I.I.I.S.S.S.H.J.H.g.4.oX", +"oXoX- 9 i h i p s s B V B h B Z J J Z b Z S J W W W G L J K W W D G J D J K X.X.@.%.O.J J I I %.+.E E W X.D J F F J A Z Z A A C C Z Z A W W G Z J J J W J G E W W X.%.:.@.%.:.s.u.u.i.s.i.s.i.j.s.:.s.s.s.s.s.r.s.:.:.@.;.%.@.$.E Z x 9 8 9 i C F J F J E S F H Z S $.i.:.%.W E U X.X.%.s.a.k.g.k.k.k.k.l.g.l.k.k.l.k.l.k.k.k.k.k.D.S.l.F.S.I.H.k.g.h.g.l.l.G.G.G.l.l.F.G.l.l.k.F.l.S.k.k.l.k.k.F.S.S.S.S.k.k.F.l.a.g.l.l.F.S.F.E.^.J.S.h.B.S.D.J.I.H.D.F.S.D.S.g.S.S.g.D.J.F.S.F.H.H.J.I.I.I.I.I.E.I.I.J.H.S.S.S.H.E.g.B.4.oX", +"oXoX: 5 S V i i s s h B B B B Z G X.S Z Z Z D W G W J K K L A J D D D D J X.X.X.X.+.U I J J J +.5.o.W E K J E E X.G J D A A F G A Z G J W W W W W @.W W @.W E J J J @.:.%.%.:.i.u.s.s.s.s.s.i.s.s.s.:.s.:.s.:.u.i.u.:.u.@.%.%.W z z f d 9 9 z C z h Z Z R G F E A J X.:.u.%.X.X.%.p.i.f.g.d.g.g.k.k.l.k.l.k.k.k.k.k.k.F.D.l.k.k.h.l.h.S.l.S.H.F.l.g.d.h.k.l.F.G.l.l.P./.U.G.l.k.l.P.G.l.k.F.l.S.H.S.S.S.S.k.g.k.g.g.g.g.l.F.F.F.Q.E.J.F.k.B.H.H.J.I.I.H.F.S.F.F.S.l.S.B.J.I.B.H.F.H.J.I.I.I.I.I.^.I.E.E.I.F.l.S.D.J.J.g.B.4.oX", +"oXoX> 6 S V i s s s B B V s Z Z A D A Z z C D J K W G J J A J G D D G J U U O.X.U U J J J I U X.i.i.W J A Z S J J G G X.%.X.E E E A E #.W W #.i.u.%.%.@.W @.W E J E X.:.:.u.:.:.i.s.s.s.s.d.:.i.s.s.:.s.s.:.u.s.g.s.s.u.:.u.i.W C x 9 x 9 9 i h z z Z J X.X.E X.@.%.+.%.s.:.i.s.g.B.k.f.s.f.g.k.k.k.k.k.k.F.k.l.F.H.S.k.l.l.F.l.h.a.p.g.g.l.D.I.l.l.d.l.l.l.l.F.G.G.U._.U.G.l.l.l.l.G.F.k.l.F.H.I.H.J.J.G.F.l.k.S.g.g.d.l.G.G.I./.J.H.F.k.k.H.J.I.I.J.J.F.F.F.l.S.S.S.D.I.I.S.S.H.I.~.J.I.I.J.I./.E.^./.J.S.g.B.I.I.H.l.N.8.oX", +"oXoX> t Z S i a a s B B B s A A A A A B B B Z A L K W K J J J W W J J W W W @.W K G G A L J K #.+.+.L J A C Z S G A F X.p.u.:.W E W @.%.X.A K +.X.X.X.X.E J E J W %.i.i.s.s.u.s.k.s.f.f.s.s.i.k.s.s.s.s.s.s.s.s.s.:.u.:.#.#.#.@.E R 0 0 0 0 0 C R C E E E @.+.%.u.:.t.t.s.s.g.f.l.l.k.s.s.k.k.k.k.k.l.k.k.k.k.k.l.S.J.S.g.D.S.B.g.d.i.p.a.h.S.F.D.g.B.S.l.k.l.G.G.G.^.[./.G.S.S.B.h.S.S.S.S.S.H.J.H.I./.I.I.F.k.l.g.g.l.G.^.I.^.(.I.G.F.g.k.F.I.^.~.G.F.S.I.F.l.S.h.S.J.J.F.F.F.H.^.I.H.I.I.~.I./././.^.H.B.k.S.E.J.F.g.f.| oX", +"oXoX< 9 Z X.h i i s B s p B V A A A A A Z A A A G K W W J G L W W K E W W J W W L G G G D K W o.X.U K A C Z z Z F S Z J k.l.s.:.%.#.%.#.K D L X.X.X.@.X.%.X.J J X.%.s.i.i.g.k.k.k.s.f.k.k.j.s.s.s.s.s.s.s.s.s.s.:.#.:.:.#.@.W @.$.W E z z z 0 z C C E #.@.E X.:.i.%.u.s.i.u.p.f.k.d.s.s.k.k.k.l.k.k.l.l.k.g.a.f.g.F.F.B.a.g.F.a.a.p.p.p.p.h.S.S.S.g.a.S.k.k.l.G.F.S.H.I.F.S.S.S.S.D.B.B.S.S.S.B.H.G.G.G.F.G.l.l.S.g.h.S.J.I.J.^.'.G.F.I.S.F.G.I.I.~.H.l.l.H.l.l.S.g.S.J.I.S.H.D.G.I.G.G./.^.I.I./././.E.F.B.k.S.E.J.H.k.g.| oX", +"oXoX% 4 V X.h 0 i p s B B s V D A C A Z A A V A A J W o.W J W W J W E W W K W W D G L A G J W X.K J J A Z Z Z Z Z F H J %.i.i.u.u.#.@.W U K X.K X.X.:.:.W %.%.W %.:.i.5.5.s.k.k.k.k.k.k.l.l.s.u.d.d.:.:.:.:.:.:.@.W W #.:.@.W W $.#.E E R C F E G C C E @.G J :.:.:.k.j.j.d.d.s.s.k.d.k.k.k.l.l.F.l.l.l.k.g.S.g.g.S.S.g.g.g.g.g.d.s.l.d.p.g.h.l.g.f.g.g.k.k.l.F.F.S.F.l.k.k.k.S.h.h.D.S.H.I.F.H.H.I.G.I.G.S.k.l.S.S.g.S.I.G.G.(./.J.H.I.F.D.G.~.G.I.l.l.S.S.C.l.B.g.J.I.I.F.J.F.G.G.F.I.I.I.G.I./.(./.E.F.S.B.J.^.J.H.l.N.>.oX", +"oXoXoX> h G Z i p p s B s B B A A C B C C Z A Z S A J W W G W W W W W W W W W W G K K Z G K L K K D D Z Z S Z S H H F J J #.#.%.+.%.t.W K J X.o.+.+.u.p.u.%.:.:.:.p.s.i.i.g.k.k.k.k.k.k.k.k.s.i.s.s.r.s.s.s.u.#.E G W #.@.W E @.W %.W E C E E E E E C R J W %.5.s.k.l.k.d.d.s.k.k.k.s.k.k.k.l.F.G.G.F.l.S.S.B.g.a.g.S.F.S.k.g.g.d.g.h.g.g.g.D.D.g.g.D.F.k.l.l.G.G.G.F.l.k.f.S.l.a.B.J.B.H.I.D.H.I.I.I.F.G.F.S.l.H.S.k.k.S.S.J.^.I.G.F.G.S.S.I.~.G.G.l.l.S.S.S.F.k.S.J.I.H.J.H.H.I.G.G.I.G.G.I.I./.(.E.J.J.H.F.J.E.H.J.S.A.oXoX", +"oXoXoX> 6 a p i i p p B B B V A A A C C Z Z C C Z S J W X.E W W o.o.W W W W W K A D D J J J J K K G A Z D J A A J H F S E o.%.o.o.#.o.W X.X.X.+.u.t.u.u.p.p.u.s.s.i.p.f.a.k.S.l.k.k.B.k.s.s.u.s.d.:.s.s.s.s.:.@.W W W @.#.W @.E W #.W W W W G E E W E E E E %.s.k.k.k.k.s.j.k.F.l.l.l.k.k.F.C.G.I.F.F.F.S.B.g.s.d.g.k.D.g.k.k.f.k.d.g.a.p.k.F.F.S.g.l.l.l.S.S.D./.F.S.l.g.g.g.l.B.B.F.S.H.H.F.H.I./.G.F.G.I.S.k.S.F.k.B.l.l.J.I.G.G.G.H.F.F.F.J.S.S.F.F.F.F.l.k.k.B.H.H.H.S.F.I.G.G.F.G.I.I.I.~./.(.I.J.S.S.F.F.H.F.J.F.j.oXoX", +"oXoXoX- 4 4 t i i i p s B V V A G A Z Z A Z C C Z F J W W W W W @.W W W W W W J o.X.K K J J U J J G A B C Z Z Z F J G J X.%.t.t.o.o.t.L K L L o.u.t.t.u.u.p.k.l.S.k.k.g.S.F.I.J.k.B.D.S.k.g.s.s.s.s.g.s.:.:.:.@.#.W W @.W E C C E E W $.W E E E E W E E E E @.s.j.k.s.i.u.k.l.I.U.l.l.k.l.U.G.G.I.H.S.k.k.g.k.d.i.i.d.h.k.f.l.l.k.d.d.g.f.l.F.H.S.g.g.g.l.S.G.l.F.k.l.g.h.g.g.k.B.H.B.B.B.S.J.F.F./.I.G.G.I.S.g.l.S.k.D.S.S.G.I.I.I.I.I.F.F.S.H.l.l.H.I.G.k.k.l.F.F.F.H.S.k.S.J.G.H.G.G.D.H.I.I././.I.J.F.I.F.S.S.S.F.F.8.oXoX", +"oXoXoX- 7 6 6 6 0 i s s B V A A K A Z Z C Z Z C C J E E J W W W :.W W W W o.o.K X.o.K J K J K X.G K G A A A A A S X.X.D @.X.%.i.%.+.t.t.X.K K U p.t.u.i.t.i.p.f.k.B.B.S.F.S.S.C.C.S.J.I.P.G.F.l.d.g.g.s.s.:.:.#.W #.@.W E C E E F E #.W E F E W G G F E { %.@.:.i.s.i.:.%.s.l.^.U.I.G.l.l.l.l.l.k.F.S.l.k.g.k.k.i.i.i.i.g.d.g.k.D.k.l.F.l.F.D.l.k.g.g.k.S.S.l.l.k.k.p.p.a.g.g.g.D.H.S.H.S.S.J.D.S.G.G.F.F.S.k.g.g.k.g.S.S.F.J.^.U.I.I.I.S.S.F.F.l.k.F.F.F.k.k.l.J.J.J.F.g.g.C.F.G.I.I.G.F.H.I.^.(./.I.J.F.P.S.S.C.S.F.J.w.oXoX", +"oXoXoX@ 4 6 6 i p 0 p s s B B D D A C C C C C Z z G X.E W J J W W @.+.%.+.W W W X.o.#.o.X.D J J K K K A A C C A S J I { E G X.a.t.W K K K o.U o.t.i.s.p.u.p.i.i.S.k.S.B.S.k.f.k.S.H.I.`./././.I.l.g.s.s.:.:.:.@.W E E C E E C E E #.u.W R E G G G F E F J @.@.:.s.:.:.$.:.k.l.J.l.G.l.j.l.l.G.l.k.l.F.k.a.g.s.d.i.i.p.u.l.g.f.d.l.l.S.l.l.l.k.k.l.k.k.k.l.g.S.l.l.l.k.g.a.a.a.h.B.B.S.S.F.B.F.F.H.G.I.H.I.F.g.d.g.k.g.l.l.S.I./.^.I./.I.H.F.S.D.P.G.l.l.k.k.l.H.J.J.J.F.g.k.k.S.F.I.G.H.F.J.I./.Q.I.J.J.J.F.S.D.S.D.F.P.e.oXoX", +"oXoXoXO 7 6 6 p A i i p B B B B J C C C Z Z Z C Z H X.X.J J U X.t.W t.t.t.o.K K o.t.i.o.J D D G E W W A A D A Z A J W W +.o.o.t.o.W K G L D K o.o.u.k.u.s.g.u.i.g.i.:.g.k.g.s.S.l.l.~._._._._._.l.s.:.u.s.s.:.@.E 0 0 f C E E Z E %.@.@.W i.#.E E E E E E W W :.:.i.%.i.s.d.k.k.l.k.k.d.k.l.G.l.S.S.k.f.f.i.p.f.a.i.u.d.k.k.p.d.f.g.l.S.S.h.d.d.k.D.l.k.g.k.J.k.l.l.l.k.p.s.d.f.l.l.S.F.I.S.H.H.I.I.G.Q.I.k.k.g.H.H.S.H.S.l.S.G.G././.G.I.J.F.D.S.F.S.S.k.k.S.D.I.I.J.F.B.F.S.S.S.H.J.H.F.J.E.^.I.I.J.J.F.l.S.S.D.S.J.H.oXoXoX", +"oXoXoX+ 4 7 3 0 A i 0 p B p B A G C C C F Z Z Z Z F X.X.K X.X.+.t.W t.p.o.K t.t.+.t.+.o.X.I J J F A A Z D J A A G E J K W W W W W o.L Z D X.t.%.%.p.l.s.u.u.t.u.s.i.%.i.f.s.p.g.l.~.~.~.~.[.l.l.k.u.@.:.:.:.:.@.E E C C C E E E W E E E $.5.W E E E @.E E W #.:.:.u.:.d.k.k.s.k.k.k.k.k.k.l.G.l.F.F.f.p.a.f.i.i.i.p.p.p.k.f.f.p.a.g.l.g.a.d.d.p.g.l.F.l.F.G.J.S.G.U.l.s.p.p.g.g.g.l.l.S.D.F.H.F.I.G.I.I.I.S.S.k.S.g.D.J.S.k.S.J.I././.I.G.F.S.l.l.F.S.S.S.S.C.F.I.J.F.S.g.S.S.B.S.H.H.H.I.^.^.I.J.~.J.H.S.S.g.S.S.J.E.A.oXoXoX", +"oXoXoXoX% 3 3 6 p p i B p B B B G F z Z Z F Z F F H { J J o.o.%.t.t.o.t.t.L W t.t.t.t.+.+.X.K J G A Z S Z A A A E W K G L G L G o.t.o.K +.u.t.u.p.f.d.s.g.t.t.%.%.:.s.k.f.i.i.g.G.^./.~._._.l._.l.s.u.%.;.:.@.W C C C z z Z E @.@.E F E E E W J E E @.@.W W W u.i.u.d.k.l.C.k.k.l.l.l.l.l.l.l.l.S.S.f.i.p.i.i.p.d.d.f.f.k.g.f.g.i.s.k.g.g.g.g.f.f.S.I.F.~./.G.F.G.U.l.k.s.p.p.k.k.S.l.S.F.F.J.H.I.I.I.F.S.S.D.g.S.k.F.I.G.l.S.~.I.(.I.H.G.l.F.k.S.F.k.k.S.l.S.I./.I.F.S.k.B.B.B.F.J.J.I.~.I.E.I.^.~.D.J.F.S.g.H.F.J.Q.L.oXoXoX", +"oXoXoXoX 3 7 0 0 i p p p B B B G W z F z F F F E E J U D U U o.t.t.t.o.t.K W W t.t.p.t.+.#.X.W A S C m Z A J W E u.K G K A A G W W o.+.t.t.#.s.k.k.k.i.d.g.f.s.s.i.s.g.k.f.f.f.D.^._._._.~.U._.l.s.u.@.@.%.@.@.W :.E E R E E E W } E E E G W E E E W @.@.W @.u.i.j.l.l.F.l.l.l.l.l.k.j.k.l.l.l.k.S.k.i.i.i.i.i.i.d.g.k.l.l.l.g.g.a.g.g.g.l.g.f.g.l.G.J.I.I.F.S.l.G.G.F.d.d.g.l.l.S.l.H.H.S.H.J././.I.F.k.J.I.l.g.g.S.D.D.D.S.^.(./.I.S.G.G.S.k.k.B.k.S.l.l.G.I.E.J.S.k.S.S.B.S.I.I.~./.^.I.I.I.J.I.J.H.H.F.B.F.F.E.E.V.oXoXoX", +"oXoXoXoX 3 7 6 0 i p s B B B B C E Z z Z F G H J E F X.A L L L K t.t.o.#.t.W t.t.t.t.t.%.+.@.W G Z Z Z A A G G G W J G A G G W t.W o.t.t.+.u.k.G.F.k.u.%.u.s.k.g.k.s.f.k.k.f.f.l.J./.`._.l._.l.g.:.u.#.%.%.%.:.j.:.$.E E E E E E E F F A J G E R W W E E E W :.s.l.I.l.G.k.F.I.l.I.l.k.g.k.l.k.k.l.k.a.s.s.i.p.d.g.k.S.k.F.F.g.g.a.a.a.k.l.l.k.l.I.I._./.J.l.g.l.S.J.S.k.g.g.l.g.S.g.D.E.J.J.I.~.U.I.F.l.J.H.l.B.l.l.l.F.F.S.I.~.I.I.F.F.H.l.l.S.k.B.k.S.F.I.I.H.S.S.k.J.F.k.F.I././.I.I.I.I.I.J.I.J.J.J.D.S.D.H.I.H.3.oXoXoX", +"oXoXoXoX% 3 t i 7 0 s B B B B B z C z z Z J E E E J J O.A B A L K t.t.t.t.t.W t.t.t.t.%.t.u.%.@.H Z Z Z G W K C Z Z A G Z J J W L K W W #.o.u.l.I.G.k.p.u.s.s.k.k.l.k.k.g.g.f.k.D.^./.^._.l.l.s.:.:.:.:.@.@.@.$.W W E E C E R z z Z Z Z G G G E E E E E E @.@.@.s.l.l.P._.U.F.G.I.l.l.k.g.f.k.l.S.l.k.S.k.k.s.d.k.S.S.k.s.g.l.l.D.g.g.g.g.g.g.F.D.~.I.~.I.F.l.k.S.S.D.S.k.d.g.g.h.S.D.J.^.D.I.^.I././.H.J.F.S.S.g.S.l.l.S.F.F.D.I.(.I.F.G.l.k.S.F.S.B.S.H.J.I.I.F.S.k.l.S.B.S.J.I.^.~.I.I.I.G.G.J.I.I.I.H.H.H.D.H.I.A.! oXoXoX", +"oXoXoXoXoXo i 0 7 0 i B A G A A f z z z b F F J Z J #.+.A A K X.t.i.t.t.p.t.t.#.W t.W %.t.#.@.E G D J J X.%.i.J W K W W F C C Z A L L K o.t.g.l.k.k.l.l.l.l.k.k.F.H.G.k.f.d.f.k.l.G.G.l.l.g.d.u.:.*.:.@.%.@.W %.#.W W E F E E F F E G J W W E E E W W #.$.@.@.%.k.l.l.U.I.I.G.G.l.l.k.g.f.l.g.k.S.S.F.F.S.F.l.S.F.H.F.g.d.d.g.g.S.l.g.h.l.g.g.l.F.F.l.l.S.S.S.l.k.k.S.F.S.h.h.g.g.S.D.H.I.I.^.~.~.(.^.I.F.H.S.g.S.S.S.l.S.S.F.I.^._.I.S.F.k.l.S.F.F.S.F.I.I.I.H.S.F.S.k.h.S.F.J.~.I.I.I.I.G.G.G.J.I.I.J.J.I.J.H.J.^.V.oXoXoXoX", +"oXoXoXoXoXo 3 i 7 6 p s A L L B f f x z z F Z Z b J o.X.+.L D o.t.l.h.l.k.s.i.u.t.#.:.%.@.@.@.W E E { J J E @.W W G A A C z A W A K o.o.o.p.i.u.u.s.u.f.f.k.k.S.G.G.I.k.d.d.k.k.k.l.l.l.g.i.i.s.:.:.:.:.%.:.:.:.%.%.%.#.W E F E G E W W W W E E E %.W u.:.:.%.s.l.l.G.G.G.P.l.k.l.l.k.k.k.k.d.k.k.l.F.I.G.S.l.k.k.S.S.k.a.g.g.g.l.l.F.S.l.h.h.h.l.l.l.k.l.F.J.S.h.g.B.D.g.g.h.p.h.g.S.H.I.^.(././.I.I.~.J.J.S.k.S.S.D.l.D.F.D.I.~./.H.l.F.F.G.F.S.S.J.J.I.G.G.H.F.S.S.l.B.S.H.I.I.I.G.J.I.G.F.G.~.I.I.J.I.J.J.H.J.E.V.oXoXoXoX", +"oXoXoXoXoX% > t 7 7 0 B A X.J f f x z z C z T C C E W G L Z A W o.i.a.^.J.f.u.i.i.:.:.#.#.#.@.E E E W G E W E G A Z C Z Z A K W W W G W W t.t.t.o.%.s.s.i.s.B.S.S.F.S.g.s.k.k.k.k.k.j.s.u.%.:.s.i.:.s.s.#.@.:.:.W #.s.:.:.:.@.E E E W E E @.E E :.j.@.:.s.s.s.s.l.j.l.l.k.S.k.f.f.f.s.s.k.f.l.k.s.g.k.I.F.k.k.k.k.k.k.k.k.d.i.s.l.S.S.F.S.a.h.h.h.h.l.l.l.B.B.a.g.g.g.l.g.g.k.g.h.k.l.F.I.^././.'.I.I.I.I.I.k.l.l.l.S.l.I.H.I.I.I.I.H.l.l.I.^.H.k.H.I.G.G.J.I.J.H.F.S.k.S.D.J.I.I.J.I.I.H.H.H.J.~.I.H.H.J.J.J.J.^.H.v.oXoXoXoX", +"oXoXoXoXoXoX> 4 3 4 0 s Z X.X.h f f z Z C z C C C C K J W K A K X.t.i.S.F.f.%.:.:.i.%.W W W E E E E E Z Z J J C Z J L J E @.#.W A A L J W W K A X.%.g.B.k.a.i.s.g.k.k.g.d.d.k.s.k.k.s.u.s.%.:.s.s.:.i.:.:.@.@.:.:.#.:.:.:.#.@.:.@.E E W @.E E :.5.@.@.i.:.7.s.i.s.s.d.g.s.a.g.s.s.i.s.k.f.k.d.k.g.k.k.k.k.k.k.l.k.f.p.f.k.k.k.d.g.h.l.S.l.h.h.a.g.l.g.h.l.h.g.h.l.f.g.l.l.l.a.g.D.l.S.J.I.^.I.I./.I.H.F.S.S.l.l.F.S.S.H.^.~.~.I.I.S.l.l.C.G.I.I.F.I.G.I.H.I.J.I.E.H.B.S.H.H.I.J.H.H.H.S.D.H.J.I.~.~.H.D.H.J.J.I.J.R.oXoXoXoXoX", +"oXoXoXoXoXoX$ - - 3 9 a V X.X.g 0 x f z z z z z C C G J L A A L X.o.%.a.k.i.5.$.%.u.:.:.%.$.@.W E E E G G J G J E X.X.J A F Z Z B C K J t.u.W A X.a.k.k.p.s.g.s.s.k.k.k.f.d.f.f.k.j.s.i.s.s.:.s.s.:.:.@.#.@.@.@.#.@.@.@.#.:.i.:.s.@.:.*.@.@.#.s.s.@.W #.@.u.:.#.W %.:.#.:.d.l.g.:.u.u.s.u.s.d.d.g.g.g.k.k.f.d.l.l.k.u.k.k.F.l.g.a.g.k.D.S.S.S.B.h.k.B.g.a.h.g.l.k.k.k.k.l.g.g.l.l.l.S.J.^.J.H.H.I.G.F.F.S.S.k.S.S.l.k.I./.I.H.I.I.k.k.F.l.G.U.G.I.G.I.I.J.J.J.^.^.F.B.H.H.H.J.J.H.H.D.S.H.H.^.H.I.H.B.S.F.J.J.I.E.V.oXoXoXoXoX", +"oXoXoXoXoXoX $ - 3 6 i s Z Z i z z z z z z z z z F J W A A A L X.X.+.f.d.F.].P.s.i.i.s.i.:.#.@.W W E E K E W W X.X.J G C z C h C C W o.g.u.W K %.i.%.p.i.s.B.k.k.g.k.g.f.k.k.f.s.s.s.d.g.s.;.:.d.r.@.:.:.:.:.:.:.@.@.:.s.i.i.:.s.:.:.:.u.@.@.@.%.:.i.:.@.:.W E E E E E #.:.u.s.:.@.X.X.W #.:.s.i.s.g.k.j.u.u.d.l.l.u.g.l.G.D.l.g.k.g.F.F.D.F.F.S.a.a.a.a.h.l.S.l.l.S.S.S.k.l.h.l.S.l.S.I.J.D.H.I.G.I.I.H.S.k.S.G.I.F.I.I.J.F.I.I.k.l.l.F.I.U.F.G.I.G.F.I.I.J.I.J.F.D.B.B.S.J.H.H.H.H.S.B.H.~.I.H.H.S.S.I.J.J.I.E.8.oXoXoXoXoX", +"oXoXoXoXoXoXo % - - 9 0 i a s h C z f z f z z z Z A K W L Z L K K o.%.k.H.U..X|.k.:.u.u.%.#.W :.$.$.:.%.#.@.W W E E E E Z Z Z Z Z G W t.u.u.W J o.%.+.%.s.s.k.S.B.f.f.i.s.i.s.i.:.u.f.l.k.s.@.:.g.s.:.:.s.g.s.i.i.:.#.g.l.g.:.:.r.s.:.:.u.:.#.@.#.:.%.$.@.:.%.X.G G K J W #.u.%.%.W W W @.%.u.i.@.u.g.f.a.5.X.%.u.p.h.d.l.l.F.l.l.S.D.S.S.H.F.F.S.d.p.p.h.h.S.D.F.l.S.H.I.S.S.S.k.l.l.l.J.J.D.E.I.H.J.J.G.S.S.D.G.I.F.G.E.J.G.I.F.k.S.H.G.U.G.F.G.G.F.F.J.J.I.I.H.H.S.B.S.S.H.S.D.J.H.D.J.I.J.I.J.D.S.H.H.H.J.~.P.oXoXoXoXoXoX", +"oXoXoXoXoXoXoX- 3 - 9 i i i d z C z z F z f h z z A Z Z Z A L W K X.+.i.s.C.].[.j.@.:.@.@.#.@.#.%.:.:.:.:.@.E E G W W @.G A J J J Z C J W %.W J D X.X.X.:.%.:.u.s.f.i.%.u.;.i.:.u.s.f.g.f.s.;.:.g.g.s.s.s.g.j.g.s.s.s.l.U.l.g.s.i.s.i.s.:.u.u.u.X.%.:.$.E E :.@.W W J W D K W W J K W L J W :.k.s.i.i.s.g.y.U U W o.d.g.g.l.l.l.B.D.F.S.H.H.H.F.h.h.h.h.p.a.h.D.H.S.J.J.I.H.S.g.g.l.l.S.F.F.H.J.I.G.J.D.G.H.H.I.H.G.H.I.J.J.I.E.H.k.S.S.I.I.G.G.I.G.l.F.S.F.J.J.H.H.D.D.D.B.B.H.H.I.J.H.J.I.J.J.H.D.H.J.J.H.J.I.L.oXoXoXoXoXoX", +"oXoXoXoXoXoXoX# 3 - 5 i f f h C Z C C C z h z h z Z C C C A G K W X.+.:.g.k.U.S.t.@.:.@.#.:.#.@.$.@.$.:.:.W W W W X.@.%.X.E J D A Z C A J #.W A S G E E J X.%.:.5.+.@.%.u.%.%.@.%.i.s.j.s.s.u.s.s.g.k.s.g.g.k.k.s.s.s.h.l.l.g.s.s.s.:.:.u.s.s.:.:.s.f.j.s.X.E E u.:.W J S A K J J J J G G W u.k.s.i.s.g.g.%.J J J K u.d.l.k.g.l.l.D.F.S.D.H.F.F.h.a.a.d.g.g.l.D.D.S.J.I.I.H.S.a.g.S.F.F.S.S.F.E.E.F.D.J.I.I.I.I.H.H.I.I.H.J.^.^.S.l.S.H.l.F.I.G.P.G.G.F.H.S.S.J.H.S.S.S.B.h.D.D.H.D.H.J.I.I.I.I.H.H.C.I.J.J.^.R.8.oXoXoXoXoXoX", +"oXoXoXoXoXoXoX. - 3 3 i s B Z C z F F z z z h h z F C C G G G L X.J X.#.s.k.H.:.#.#.#.W W W @.@.W E W %.:.%.%.:.:.:.u.:.%.%.J G Z L Z C K #.W Z C S E J E @.+.@.#.@.X.i.%.@.W %.:.s.s.s.7.k.l.k.i.u.j.s.s.k.k.k.d.s.#.r.d.s.s.s.s.s.s.:.:.s.s.u.u.g.k.s.:.%.E J W W G C C Z A D W G G J G W W %.i.d.i.s.u.@.K D K W X.u.g.g.k.k.S.S.D.S.B.S.S.S.l.g.h.a.h.g.S.S.S.F.D.~.~.J.S.l.h.D.I.~.F.D.H.^.I.J.J.I.I.H.F.I.F.F.I.U.J.J.I.J.I.H.S.F.k.l.G.G.I.I.F.l.H.k.B.H.H.H.S.S.S.B.S.S.D.H.J.J.I.I.I./.E.S.D.I.H.I.^.Q.=.oXoXoXoXoXoX", +"oXoXoXoXoXoXoX. $ - 6 f z F W Z Z F S h B m H b b Z b b m A A J A D o.o.%.F.s.%.@.W %.W E E { X.E E E W +.$.#.u.%.t.i.t.5.g.%.K L A G A X.J S G S Z D Z J 5.k.%.E @.i.@.E W E @.:.u.i.:.7.k.S.B.s.:.s.s.*.i.k.k.s.:.#.:.#.#.t.u.u.u.i.u.:.:.i.:.s.d.k.k.u.@.E X.X.@.J S B f B A A G C A A L G K X.+.+.+.U I U X.%.%.X.%.s.g.g.a.k.k.l.F.F.F.F.H.S.l.g.g.g.l.D.D.l.F.J.^./.I.S.S.J.^.^.^.I.J.I.^.E.I.I.J.I.G.H.G.F.F.J.I.J.I.I.I.P.l.D.H.k.F.I./.E.J.J.D.g.a.S.D.S.S.S.k.S.D.D.C.H.H.E.J.J.J.I.^.J.F.D.H.I.I.Q.L.oXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoX+ $ 7 C G Z X.X.C Z z s s z Z Z b z h b Z S G G S S X.+.+.g.i.@.%.@.@.@.W W } { E R R W X.X.@.@.t.i.y.%.+.S.k.X.W G W W X.J G Z Z S Z D X.@.%.@.@.@.$.E E @.:.#.:.:.:.i.s.s.f.f.s.@.:.:.@.:.s.g.k.s.:.W W W W o.@.@.@.u.i.u.s.i.u.u.u.s.s.:.:.u.%.%.+.{ A h B A Z Z C A A A A K I U { X.K O.+.%.f.s.X.@.i.g.d.d.g.l.k.l.l.l.l.H.D.l.k.k.l.l.l.S.S.F.I.E.(./.I.G.(.^./.^.E.I.^./.I.I.J.J.I.I.G.I.H.F.^.^.I.I.H.J.F.k.F.F.S.I./.(.^.E.I.J.F.k.S.S.S.S.S.S.B.H.S.D.S.H.J.H.H.J.~.I.J.J.H.H.J.I.Q.w.oXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoX$ . 3 s E F A #.J C Z h h h z b b z g b b b F F Z H J X.+.:.i.%.@.X.W X.X.X.E J G E F G { O.@.X.o.%.t.+.X.i.s.%.#.#.u.t.+.X.X.F D Z Z J { J E X.@.:.@.E E :.l.g.:.$.s.s.7.5.s.s.s.u.i.:.:.:.s.s.k.:.:.:.#.W J G W %.@.%.i.i.i.i.d.u.u.u.u.s.i.s.s.:.X.J Z Z C Z G W Z A A A K K I I J X.+.%.+.+.:.#.X.W i.g.k.g.f.g.k.S.F.l.l.H.S.l.l.S.S.g.g.S.H.J.J.I././.^.^.E.^.^.^.^.^./.^.I.J.I.I.I.I.H.G.H.J.I.U./.I.J.I.F.l.F.H.G.U.^.^.^.^.E.F.S.B.S.S.S.S.l.S.H.D.S.D.H.H.H.H.H.J.I.J.J.J.H.H.I.I.).=.oXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoX $ a W W F J E G z b z h z Z Z Z h h b b Z Z H H J E O.%.O.X.X.X.} X.W E E J Z F E E $.%.X.X.X.#.+.X.X.+.i.%.W #.:.s.:.@.%.@.J S D J X.X.E X.@.E E E E %.l.j.:.s.s.7.i.:.%.i.s.u.s.;.:.:.:.i.s.s.s.i.s.#.W A E @.@.W #.i.i.i.d.u.u.u.i.u.i.s.s.s.#.G F G Z C A J K W p.E F A J J X.+.g.i.X.X.#.u.X.+.i.g.k.S.l.l.l.S.F.G.l.S.S.S.S.S.D.g.g.S.S.D.I./.^.~.^.J.E.^./.^.I.I.^.J.J.^.^.^.~.U.G.I.F.J./._.`.E.E.J.l.F.G.G.I.I.I.G.E.(.J.S.g.S.H.S.h.h.F.J.H.S.S.J.J.H.H.H.J.J.J.H.H.J.J.J.^./.R.oXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoX+ . 6 A A K A J @.Z z h z h z Z m h h b b S Z G A J E %.{ { E E E X.E { H H H F F F H E @.X.X.X.X.O.X.X.+.%.X.W #.:.u.u.i.:.:.X.J { J +.@.E { E E E F W :.d.s.:.s.s.u.%.@.@.:.s.u.s.:.%.%.i.i.u.i.:.:.%.%.W K E E W W W p.s.d.k.p.i.s.i.i.d.k.s.s.%.X.%.#.G F G W W W u.E C Z G D J o.p.h.%.o.#.X.J K u.F.S.F.G.F.D.B.F.F.G.F.S.G.I.S.S.B.a.g.S.l.D.^.~.I./.F.J.^.(.^.J.I.^.~./././.I./.I.I.I.G.I.^./._.I.P.F.l.G.J.J.I.I.I.G.I./.F.g.S.F.H.k.a.B.D.S.F.S.H.H.J.J.D.A.H.H.J.J.J.J.I.^./.Q.K.oXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoX$ . > h h S Z G :.J h h z z f h Z h h F F Z Z D S J E { E J J E E { X.E E H H F F J F H X.X.@.+.X.X.O.X.O.%.+.@.%.%.:.i.s.i.:.%.O.{ J X.J E E E E E :.i.j.i.:.5.:.:.%.@.X.W %.i.:.s.:.$.W @.u.#.i.W W W W @.W W R W W W u.s.i.p.f.s.s.i.i.g.k.g.s.d.%.:.#.u.%.%.W W E G F Z C Z S U X.o.t.X.G A S A X.p.l.S.l.D.J.B.k.l.G.I.l.S.F.H.J.S.a.a.g.S.S.I.I.I.J.^.^.^.(.^.J.~.^././.^.I.I.I.G.G.G.H.G.^.G.I.I.~.G.l.k.I.l.G.I.I.I.F.F.J.B.B.S.S.k.k.k.S.S.H.S.H.H.H.H.H.B.D.H.H.I.J.J.J.I.^./.W.=.oXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoX# $ 0 d h C A D G z f f f z Z F h b H F z g Z S Z F H F J H J E E R { H H F E F F F J E E J E { X.+.+.O.X.O.#.%.@.:.u.i.s.s.s.5.@.{ { E @.@.E E W j.:.:.5.:.:.%.X.W X.@.@.#.:.%.%.:.i.@.#.W W :.$.E W J o.o.W E W W %.t.u.i.s.s.p.u.u.i.S.l.F.I.g.s.s.s.s.k.s.:.@.E G F F Z C F o.%.K K D S Z V Z X.i.g.F.S.B.S.k.k.k.U.I.G.F.F.l.G.S.g.g.g.g.l.I.^.I.I.^.I.~./.J.E.I.^././.^.J.I.I.I.I.G.G.I.G.l.I.I.I.I.l.G.I.F.U.U.I.F.F.S.S.B.S.S.S.k.S.S.F.H.J.H.J.I.H.D.D.S.D.H.H.I.J.D.I.^././.L.oXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoX% o 4 h i C C Z C h z z z f Z F h b z b h z h C m Z H F H F H G Z F H Z Z Z F E E Z H H H E J J X.O.+.O.X.X.%.:.:.:.u.u.u.i.p.f.s.@.@.:.@.E E W u.u.$.$.%.%.%.W W W W X.@.%.@.@.W W %.W W W :.:.W E J G D D G W #.#.i.t.#.:.u.s.u.s.s.s.d.l.S.S.s.s.s.s.d.s.s.i.i.W E F E b Z A D K A A Z S h h Z K t.g.k.l.F.B.k.g.k.S.l.k.F.l.l.S.F.l.h.g.h.S.I.I.^./.^.I.J./.J.^.^.I.^./.^.^././.Q./.U.I.U.G.F.G.G.I.I.l.I.I.I.I.F.l.k.F.S.k.k.B.S.S.F.F.H.H.F.F.H.I.J.D.D.H.H.H.J.I.J.J.J.^././._.N.oXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoX. = C i Z G A C f h Z z h b G Z b z z h h z b F Z F F F F J J H H F Z Z H H E H Z H H H J J J J J X.#.%.%.:.i.s.i.s.s.s.:.s.l.k.j.:.:.;.@.@.s.@.@.@.$.@.@.E E E F W W W #.W W W E E @.E E W W W W G G G G E :.k.s.u.O.+.+.%.i.i.i.i.i.p.p.a.s.i.i.i.p.B.k.k.g.g.s.:.E X.Z z b Z G A C Z Z V V Z A o.i.s.f.S.g.k.k.k.f.f.k.k.S.S.S.F.k.k.S.k.F.I./././././.Q./.I.^.^.J./.^.I.(.(.(././././.I.F.H.J.I.I.J.J.I.I.H.H.H.F.G.S.k.k.l.k.l.S.F.I.J.H.D.S.H.J.H.J.I.J.H.D.I.I.I.J.J.I.^./.W.oXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoX= X 9 0 C o.W D f s S b z Z H Z z F h h z b z b F J H F Z H H b Z S H H E [ H J H J J H Z S J J W X.X.@.:.p.g.s.p.i.k.k.s.j.k.k.l.s.i.s.:.:.$.#.*.@.:.:.W E W E E E E W #.%.W %.#.#.#.W E @.W W E E A G K W %.%.u.s.5.X.O.+.%.i.i.i.%.5.f.g.:.:.%.i.f.g.k.S.S.S.s.#.E E J Z b Z F Z C z z B Z Z V G +.u.u.i.s.s.g.k.k.k.k.k.S.l.S.F.F.S.F.k.H.I.I./.^.I.^.(.E./.^.I.I.^.~././.~././.I.~.^.J.J.E.I.E.E.I.J.I.E.D.G.F.G.I.l.k.k.k.l.l.k.H.U.J.S.S.F.H.H.J.J.J.H.H.H.J.S.H.J.~.I./.(.V.oXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoX= 3 9 i A E +.A f h h z F E z h z f g z b b b F F Z Z Z F S Z b Z Z H F J F F F F H G Z Z J W K E W J @.@.:.g.l.j.g.k.l.l.k.l.l.k.s.s.:.@.E #.@.@.%.s.@.E W @.E E E %.%.%.@.u.u.:.%.$.:.%.W E E A A Z A S A A @.s.:.X.J X.+.5.t.%.y.y.y.5.%.o.X.%.i.s.i.i.g.k.d.@.X.E J G F Z J J F Z Z D X.A Z A K o.X.@.:.:.i.d.k.s.p.s.k.S.I.F.F.I.I.F.G.G.I.J.I.I.E.E.I./.E.S.I.^./.~.~.~.G.I.I.I.E.I.E./.E.I.E.Q.E.Q.I.J.J.F.S.G.l.k.k.S.S.S.H.I.G.S.S.J.J.D.^.^.J.J.J.H.H.H.S.F.I.I.I.^.E.=.oXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoX4 & 6 i C J t.u.Z s k k Z E z g z f d z b b Z z m S Z Z b F H F F S H H G G F H H H H S Z A K X.W D E W X.@.f.S.S.g.k.l.k.k.l.l.l.s.@.$.W @.W @.E @.%.%.@.@.W @.W #.#.#.:.%.s.s.%.%.W :.%.@.W E C Z A G Z Z A W X.%.O.J { O.X.X.U J U X.X.t.X.J X.+.O.X.@.+.g.g.%.E X.E J J A W o.K J G J K J A C A L W X.5.i.i.%.u.%.:.%.s.S.D.F.J.I.I.P.I.G.I.J.J.J.^.Q.I./.I.F.J././.^.~.I.F.I.J.E.I.I.Q./.E.I.I././.^.J.I.J.F.l.F.k.k.l.H.G.I.G.G.F.S.H.J.I.I.I.J.F.H.J.H.F.F.H.J.J.I.I.(.Z.oXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoX- 4 9 h G #.E X.z h h C W E 0 z z z z z z z z z Z C F Z F F F H Z Z F { J F F J E H G F F H E J E J J J X.:.j.k.k.l.l.l.P.U.l.l.k.5.@.@.W W @.$.W #.@.#.W W W #.s.u.@.@.@.%.:.%.%.X.%.%.@.#.W G G F C A G L A J +.&.+.X.I U I A S D J W W W X.J X.+.X.X.I X.i.+.X.W W I X.K X.X.W K J J X.U J Z B S X.#.p.f.%.W #.%.%.%.g.S.S.k.S.I.I.I.I.I.^.I.F.H./.`._.(.Q.~.J.E.I.I.H.I.J.I.I.E.I.I./.Q.I.I.J.I.(.^.^.^.^.J.S.B.k.k.F.H.F.G.I.P.F.S.H.J.I.J.J.J.F.D.J.H.D.D.J.I.I.E.^.Q.w.oXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoX> 3 7 Z X.X.z Z A s H #.W C R z z z z z z f z z Z G C b b Z F Z Z Z Z G S H J H H E [ J F J E W E J W @.%.u.s.s.k.~.I.l.l.l.I.k.k.s.%.@.E E W #.i.u.#.#.%.%.%.:.%.@.E J W @.W E E J W W E E W @.#.E G A G K D J X.:.i.X.J S I D S D A A G K W X.X.{ J J J J &.i.X.J K D J X.U K K J J J U I J Z B Z K @.s.d.@.@.E W :.u.d.l.S.k.k.k.I.E.I.^.I.S.S.F./.`.`._.(.I.I.I.I.G.I.^./.I.I.^.^./././.~.J.J.I././.(.E.I.H.J.F.B.F.H.G.I.G.H.G.F.H.H.J.J.H.J.J.F.H.H.S.D.D.J.J.I.E./.Y.oXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoX- - 7 h D X.S h z z F i.#.E 0 z z f z f z h z z C G R m Z b F H b b h Z S H { J E O.{ E H H F E E E %.@.%.s.f.k.j.l.l.G.G.J.l.l.k.s.:.@.E E E E ;.i.@.W W W W %.W E E G G W W A E E @.@.W E E W E W :.X.K A J J S X.X.J J S D D J D A A A A J J +.+.@.J G J X.X.S W W X.K K X.K Z V Z D K X.U A B Z D W #.@.@.@.X.W @.%.t.s.k.B.k.S.I.I.I./.F.l.G.I.`._./.]._.I.I.^.I.I././././.E././.(./.~.I.J.I.^./.E./.I.J.J.J.F.D.I.G.G.I.G.G.G.F.S.F.J.H.J.J.J.J.J.J.F.J.G.J.I.I.I.E.Z.oXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoX& 8 t Z X.J s h b h #.#.@.R 0 z z x f f f z C z C F Z Z Z S H Z m Z b Z H H H J X.J H F h z Z Z A E E %.u.p.k.k.l.j.k.l.l.l.l.k.k.k.@.E E R E W W W W E G G E F F E E J W G W %.@.#.%.$.E Z G G F W X.G A A G J G D J J D J X.D D A A A K W J %.%.5.#.D U J S Z J W X.U L D V h h Z K D D D A B Z D F W @.W E E X.W #.%.t.d.B.F.G.I./.Q.Q.I.I.~.U.[.`.`.[._./.I.Q././.I.I.Q.E././././.^.J.I.J.I.^./.Q.I.J.I.J.J.S.J.H.I.U.I.F.F.l.F.S.J.J.I.I.E.J.J.J.J.J.J.I.I.I./.E.Y.oXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXX - i f A E z s h h C W W C C R 0 0 f z f z C C F C b b Z Z Z b b k h z F F b F H J F F z h Z Z H E #.%.#.%.s.k.k.k.k.d.k.d.k.l.l.k.:.W E E E E @.} W E G W u.W G G A E #.J %.S.:.%.%.W A Z A K W J K A Z A V A L G A A A J D A D K A A A A W u.i.i.X.K K X.G F A X.U U J Z s d s G X.X.S S S Z b h C Z D K J W W o.W X.t.p.l.G.I.I.E.E.E.E.^./._.[.[.].[././.I.E././.I././.E.^././.(.E.I.I.I.~./.Q.I.I.I.I.I.H.J.F.H.^./.J.F.S.l.H.H.J.J.J.I.I.J.J.G.G.I.I.I.I.E.E.Q.v.oXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoX- 4 h Z J Z i h b C 0 E C C 0 C C f z f x f z C C b z b z b b b h g h b Z b b F E b b z g z F E X.@.E E #.s.k.j.k.j.s.i.t.i.l.J.k.s.@.G F R E X.E E E Z E @.W F G J G E G J %.u.:.W W J o.:.@.W E A Z A A A A A L Z S S A D A D D A B A A W u.%.:.X.W D J J J W W J K A A Z h z X.X.J S G E F Z Z C Z Z J A G W W X.X.%.s.k.H.I.I.E.^.E./.U./.[. X|.|.|.Q.E.E./.Q./.~./.(.E./.(././.E.^.I.E.(./.(.Q.I.I.Q.I.I.J.J.~./.I.J.F.F.H.G.H.H.H.H.J.J.J.H.H.J.J.G.I.I.E.I.R.oXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoX5 6 i h C F g d g 0 0 E R C z 0 0 d z x f f f z f g h h s h b b z z z b Z h Z Z F Z b b b b Z G J E F E :.u.u.:.s.s.:.s.s.:.:.d.k.d.s.E E E E { { W E E F A C C G @.5.J F S A W X.E G G %.u.%.X.W G A Z Z Z A G G J I D Z A D D L D G D A J u.:.%.O.X.K J G W @.W D J A D S z Z G J A A X.X.H A F Z C Z A C A E W W @.W u.k.S.I.I./././.^././.XX.X|.|.}._.Q./._././././.(./.^.(./.E.E.E.^././.Q.E.I.I.I.I.E.I.I.I.I.I.J.F.J.J.F.S.S.S.H.H.H.I.J.H.I.J.I.I.J.I.E.Q.n.oXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXt 6 i g S h d s 0 C z F C z z z d f z f z z f x i h g i g h z b Z F b b Z m Z F b b b b m Z Z G E E @.%.:.@.@.@.$.%.i.s.W W W W u.k.:.G E E { J E @.E R G C C Z X.i.@.A Z S J W W G G t.p.@.%.X.L A C s h Z A A D J J A A Z A D K L A D X.@.@.#.+.%.X.J W @.E G W X.H F D Z h B Z Z Z S F H F A F S A A G A A W u.u.@.s.k.S.I.I.^.Q.^././.'. X X{.}.{._.(.]._.Q.U._./././././.E.J.I./.E.E.I./.I.I.U.G.G.I./.E.I.I.G.J.J.J.F.G.F.D.J.J.I.I.I.J.G.I.I.I.E.I.Q./.W.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXt 9 9 t C C f z 0 C 0 W E 0 0 z f f f f f Z h g g g f g g h h z C E F Z Z b Z z z z z z z z z F E @.:.@.E E E @.E @.X.W J E @.W :.l.u.E $.%.X.E E J E E D A D J U %.B.:.H Z J W u.u.u.#.i.i.s.@.K A V h B h V Z Z Z Z S A A A A G o.X.X.#.X.W X.X.@.W o.i.@.G F G X.J F Z Z S Z Z C C C B Z Z C Z A J W Z Z G W u.s.i.h.D.H.I.I.I./././.(.`.[.|.].[.[.[.`.`.Q.(.U./._./.^././.E.I.E./.Q.E.E.E.I.I./.G.I.^.U.^.G.F.H.I.H.H.H.H.H.H.J.I.I.E.J.F.J.I.I.~.I./.Q./.e.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXi h i f i s z C 0 G 0 E E T 0 i f z f f Z z h h g s s d h h Z F G R F b h b Z Z Z b z z f h b E X.@.E F X.X.X.:.X.$.@.G A A E @.s.@.J E J E E E R F E X.W E W { X.5.:.E J F X.s.s.%.@.5.g.k.i.J A V A Z V V V k Z A V Z A D G G G X.t.:.X.X.W E G G W u.u.E G F E E F Z Z B C Z A Z A C B Z Z C F D A A Z Z W u.f.g.l.S.F.I.E.^./.(.(.'.[.[.[.[.[.[.].`.[.`._._._._././././.I././.Q.E.I.E.I.E././.I.^.U.^.I.F.J.J.J.G.H.F.F.S.D.I.^.I.I.I.J.J.J.I.I.E././.R.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXu b b f f 0 z C 0 0 T E E 0 0 g z b b g z h h h g h h z h z z Z F F b b h Z b z z Z z z z Z F G F F F E W W X.@.@.:.%.@.W E G E W @.W X.X.E J G F E E E X.E J I J { J J J J E %.%.:.p.s.i.B.g.o.G A A L A Z V B Z S V Z A J { K X.W K D K W J E J K W @.%.W @.E J F Z A A B Z D A J A V h Z Z Z A A A J G W @.W s.k.k.S.F.I.E././.E.(._.[.[.[.].[.`.(._.`.`.`.`.`./././.(./.I./.E.Q./././.`./.U.I.U./.^.U.I.^.I.I.I.H.F.J.J.H.J.J.J.J.I.J.J.J.J.I.E.Q.Q.Q.n.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXg z C f 0 0 C C 0 0 C W 0 0 h b Z b z z h h g f z f h g z z Z F F b h h Z Z Z Z z z d z F E J F F Z F E E @.X.X.%.%.@.#.@.W %.u.W J E { H F F F F F E X.X.G G J I J J E J W X.%.u.f.g.g.g.k.%.X.D A A Z A Z Z V B h Z G @.p.t.X.A A A G W W K J E W W W E W +.{ J F A A A A W A E J Z A Z Z Z C B A G W p.s.s.k.l.F.S.F.I./.(.(./././._._._.].[.].`.`.(.`.Q._.'._._.(././.I.E././.Q.(././.Q.I.G./._.^.I.I.I.I.I.G.F.H.J.F.F.J.I.I.I.J.J.J.J.I.E.I.Q./.L.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXZ F Z d d b J g g z Z g d s b Z h h b h g g s f z h g b b h h b Z z h h b Z H b z z Z Z S Z F m Z F Z z F J F #.i.X.O.%.@.X.X.J H F F F Z H F F F G G J G H H J J A A J X.#.:.f.B.H.k.s.k.g.%.H D Z V Z Z B C b Z F J i.S.i.W E E A C E W W W G E W W W W X.J I X.U X.X.u.i.%.G C G A G G L C B Z J X.s.:.k.l.l.F.I.G.^././.^./.'./.(.E.E._.[.`.`._./._./._._._._./././.Q./.E.I.I.E././.I.^.U._._.I.I.~.I.I.I.F.H.G.F.F.I.I.I.U.G.I.H.G.G.I./././.Q.=.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXr g F S d b @.h i d Z s h b Z Z h b Z h g g h g z h h b H h g z b b h Z H m Z Z Z b m z Z F F Z S F Z z b S z S %.X.#.i.J Z F F F A F F b b Z Z Z F G F J J H J J G Z Z J X.%.s.J.J.f.u.s.B.p.J H Z A A o.K Z S Z J E %.k.l.s.t.W E A E W W G E E W W W @.X.J X.O.X.X.X.o.:.o.Z B C C C A A L Z Z J :.s.s.k.l.k.F.G.I.^././.E.^.(./.(./.Q._.'.`.]._./._._._._._._.(.E.E./.Q.I.J./.Q./././.^.U.(././././.I.H.I.G.G.I.G.U.I.I.^.I.G.I.H.G.I.I./.U./.Z.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXf z J Z m E { h d z h a z h b h z b b k h k h k h h h J h g b b Z Z Z S Z z S J J Z Z Z Z b b F F Z b b z z s Z J E %.{ Z Z Z z Z F z z b Z b b Z Z F F H E E G J G C F A X.:.s.s.:.s.:.k.k.i.W Z h D W W J G G X.%.u.k.I.l.d.u.E A E E G G E E W W W W X.E I U X.X.L W o.E C C C B B C G Z J W @.%.%.%.:.k.l.F.J.I././.I.I.E.(.].`.`.`._._._.`._._._./._.`._.(.Q.E.E.(./.I.E.Q.U.U.Q./.I.^./.U./.U.I.I.G.G.G.I.I.U./.^.I.I.I.G.I.I.I.I./.I.Q.W.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXr t F F Z z F h s h h a g h z h b b Z k b b h h h h h Z b h b b z z z z Z S G G F Z S H b Z b b z b b b h z h h Z Z F X.E Z z z z F Z b b b b k h Z Z Z H { %.%.W A E G A W W #.:.:.:.%.p.s.g.:.G Z B Z F b Z J %.i.i.s.k.l.l.g.W G F E W W W W W E W W X.E J S D Z A A G F C C B B C A A J W u.o.W W @.@.s.F.F.G.^.^./././.(./.`.[.`.`._._.`._.].[./._._._././.E.E.E./.I.E.Q.Q./././././._././././.I.I.P.F.F.I.^.^.I.^.I./.G.I.^././.(.E./.).w.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX, g F Z h h b g h h a g g h h b b b k b b h h b h h Z Z b A Z b b Z S H H b F b b b b Z Z S b b b b b h b h g h b b Z J H b b z Z b b b h b h h z Z F F J W %.%.W K J J #.X.o.u.u.d.%.#.@.@.X.J Z C F Z z z X.S.g.:.s.l.k.k.l.s.@.W W W W W W W @.W W @.X.E E E C C C C C C G C C C Z J %.#.u.%.%.:.@.X.k.J.F.F.I.I.^./.`._._._.`.`.`._._.(._.`._./._./.(././././.E./././.Q.I./._._._._.U.U.(.`.`.Q.I.G.I.U.I.I.U.I.G.~.I.I.I.^.I././._._.L.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXz Z D S h Z g h g g s b h h b h h z b Z b h h b z h Z Z A S J H F R J Z b F Z b b b H H H b h k b b z b b h h z h h Z Z S S Z Z b b h h h b b z F Z F J W W W K K %.%.:.K o.#.@.o.X.X.W W W W W E O.@.J Z J :.i.%.i.l.k.k.k.s.u.@.E W W W t.i.s.:.@.@.@.W J J Z G Z Z F C F G C Z A W W @.u.$.@.@.@.+.l.F.G.I.G.G.G./.(._.'.(.(.`.`.(./././.^.U._././././././.Q.E./.Q./././.'.`._.I.G.F.I.P./.Q.I.I.I.G.I.G.H.I.P.G.I.I.U./.I.~.I./.`.).1.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXb b G J Z Z b J b b b b k h b s h Z h b b h z b Z Z Z F b Z J F F J H F F b Z b b Z J X.H Z h h h h h b b Z b Z h g g b Z J H Z Z b h z s h h b S Z Z F A J G A A o.i.+.K X.W W J J J E E X.%.%.X.J X.W G E E X.%.i.:.u.s.s.u.W W W W @.p.h.l.k.s.:.%.X.@.X.E J E F A F Z C F F F E W #.u.t.$.:.:.i.l.l.l.H.F.G.G.H./.`._.`.`.'.]._./.(.I./././.Q._.^.^.^.I.I.E./././.E././.`._.I.F.F.H.G.I./.I.U.I.U.G.G.G.F.H.G.G.I.I.Q./.Q.E.Q._.].V.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXg Z J J S b +.X.F h b b b b g h h h h h b k b m Z Z F m h F b b Z Z F F Z F b Z b Z { G Z h h z b b Z Z H b Z b g d d h Z X.J Z Z b b h h h h h C G G G G G L Z G X.J G G J E A A J W #.W W E X.D W %.@.X.:.%.:.i.%.u.g.:.i.#.#.W W t.k.l.l.k.j.:.X.E @.X.W E F A G F C C C E C W u.t.#.u.k.S.S.l.l.l.S.G.F.I.I.E./._.(./.(.].`._.U.I.I./.U.I.U.U.^.^.I.^.E./.^.^./.^.`./._./.I.P.I.Q./.I.H.G.I.I.I.I.I.G.I.I.I.I.I.I./././.E./._.L.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXx H z J H z h :.J b b b G Z z z h h Z h h h h b Z J J F Z S E b Z Z Z Z G Z Z Z z Z F F Z b b b b F F b z z z Z z f d f Z X.J F E Z b z b F z z Z A B A B A A A A S G J J J J S V S F X.G J X.X.J D J J K #.u.i.i.k.k.g.i.:.:.W E @.;.g.l.l.k.i.:.$.@.$.@.E E G W E T C 0 E G E W u.i.s.k.k.l.l.l.G.G.J.I./.I.I.I.I.Q./.`.`.`.`._._.U.I.^.I.I.I.I.I.J.J.^.Q.^.E././.(.`._.(./.I.I.Q./.I.S.H.H.G.G.U.G.G.G.U.I.G.I.G.I./._._.Q._.!.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXb Z E H z F X.H Z H X.W z z g g h h b h h Z Z E :.W Z b J H Z F F Z S A Z b b Z m Z b b z h k b Z Z z f z z f h d d z F { J b F Z b Z E Z Z F C A B B A A A C Z G J D D D S V Z z z Z J X.S Z Z Z C Z A W E u.g.s.s.j.k.s.@.@.@.@.W W @.W $.:.s.s.X.X.W W W W E E E G F E E W o.u.l.k.s.f.k.l.G.P.S.I.I.I.I.I.I.I.E././.`.].`./.^.I.G.I.I.G.G.D.J.^.I.E.^./././.(.`.`./.Q.Q.I.I.I.F.H.G.I.G.H.P.G.G.H.I.I.I.G.I.I.I./.Q._.).oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXx G X.X.E G J H b J { F C z h h g h Z B Z m F :.i.J A b Z Z Z Z m Z S Z Z H Z Z b b Z b b z h b Z F z z z z Z F z h Z b H J Z z z z Z X.X.X.J B A C B B A A B V A A D X.K S h b Z z b Z b h h V Z C Z A @.X.X.:.#.:.:.u.s.:.#.:.:.u.@.W W E W E @.X.@.@.%.:.%.%.@.@.@.W W @.@.t.:.u.u.s.k.H.S.k.k.k.S.I.U.I.I.I.E.E./././././.I.G.I.I./._.U.G.I.J.E.^.^./././.^./.`./.E./.Q.E.U.U.H.I.U.I.I.I.G.I.I.G.G.I.I.I.I.I.^._./._.K.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXb J R { $.X.H { X.E E @.G z h a g b Z B Z Z @.:.G S m z h b b b h h b Z F F Z Z F Z Z b b Z F b z z z z C z d i f Z F b Z h b z z J W Z S K K A B B A L C B h V V K X.J Z S b Z Z b b h s h s h C Z Z Z C Z E :.:.s.j.s.s.:.:.:.s.u.:.%.#.W W X.X.X.E W @.W W @.@.@.u.i.%.u.k.l.l.F.G.I.G.F.k.S.H.I.Q./.U.Q././.(.(._.(.`.I.G.G.^.`.`.`._.U.G.I.J.J.E.Q.^./.^././.^.I.I./.I.U.I.H.I.I.G.I.I.F.F.I.I.I.G.^.I.I.U./._.`.).oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXh b J :.%.F E :.E E :.:.F b Z z g z h z b S G F Z Z m h h k z b h h h b Z F S S Z b h Z Z b b z h b m S z h i a a Z z C G H h g G X.S G J t.X.B Z B B L C B A A Z Z V h Z F Z Z Z z s h s h S C z z B Z A @.g.s.s.s.s.s.s.i.;.:.;.:.:.i.:.i.:.%.:.@.E X.W E E W @.@.;.%.i.l.I.G.I.U.I.I.I.I.I.I.I./.[././././.Q././.(.(.I.J.I.[.`.].{._./.I.G.I.I./././.E.Q.I.I.I.I./.E.E.I.I.U.U.U.I.G.l.F.G.P.I.I.~.I.I.I.Q.Q.`.).w.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX, i b O.5.@.H $.@.@.:.@.W J E @.Z d h b b z Z b Z Z Z V h h b Z Z b g h Z b S F Z Z Z h z z b b h z Z A z z f g d h Z h C b h h b Z Z A A A A A A B B A A V V h B h V Z S Z F b Z Z h h A U X.J h z A %.t.s.s.:.:.s.k.s.i.$.@.@.@.;.:.k.k.k.s.j.s.:.:.:.5.@.:.u.:.:.:.:.k.F.F.l.H.G.U.I.U./.U.I.I.I.G.H.G.I.I.Q.I.U.I.I.I.J./.'.'.].`._./.I.I.I././././.^.I.I.I.J.I.Q.E./.U.I.I.I.I.G.G.G.G.I.I.I.I./.I.I.Q./._.{.T.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX= 5 J O.;.%.%.%.i.i.:.:.%.X.E Z z z h s b b h g h h h s s h h h h h h g h Z Z S Z Z m B b b b h h b H b z Z h h z Z Z Z b h h Z F Z Z C Z Z K L A A Z B A A C B A A B A W Z F Z C S B C t.p.%.Z A o.%.%.s.u.@.E %.s.g.%.@.E E W W @.:.s.%.$.@.%.s.k.j.k.j.k.l.l.k.l.l._.U.G.I.I.]._.U.U._.Q.I.I.G.G.H.G.I.I.E.Q.I.I./.I.J.E.}.[.(./.I.I.I.I.E././././.I.I.I.I.I.^.Q.I.E.I.I.G.P.I.G.G.I.I.U.~.I.I.^.I.U./._.].W.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX+ t J X.:.i.5.5.u.i.s.%.X.J G X.G Z k b F Z h i g h h g h g g g g h s h b Z b Z S S Z b Z b b z h b k h h h X.J Z C S G b h Z F Z b Z A A J K L A A B Z A J W D K Z Z G S F F Z Z Z +.u.d.i.E J i.%.@.i.;.E E E %.:.%.W E E R E E $.E E W W W @.W W :.U.).l.l.l._.~._.).Q._.`.[._.Q._./.Q._.Q._.`.`././././._.`.(.I.I.F.J.(.]./.E.J.I.I.I././././././.I.E.I.^.E.I.H.I././.U.U.I.G.G.G.I.~.I.~.I.~./.I./.[.).oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX# - h F E :.s.7.:.s.s.W :.W J G E Z F Z Z H Z h i i b z g h g s h h g h h k Z k S Z m Z Z z z z h h h b b b Z C C A A h Z Z b b b Z H A J C C D W G C 0 W W W W E A A G W W E C G G W O.+.J Z J i.s.i.s.s.u.@.W #.@.%.@.E H J F H H H F E E E W E E W s.k.j.k.k.l.~._.I.I./.U._.U.U.U.P.U._.I.U._.U.U.I.U.^._._.U.I.I.G.S.G.G.I.I.I.I././././././.`./.U.(.^.~.I.I.F.I././.I.I.I.I.H.G.I.I.I.I.I.I.U./.`.].r.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX% 5 F @.:.i.u.i.7.s.u.u.k.t.@.@.E W J H Z h z f d g h g g h h z h h b b h h b b Z Z Z h Z Z b b b h z b b z h h Z Z C k b Z b z Z H F Z z F W L G A E 0 G W W 0 A W W t.g.u.W 0 B G D D Z B L i.i.u.i.s.l.u.s.#.J W u.u.E E E H E J E G G E E G W W #.u.i.d.k.k.l.l.S.H.I.G.G.l.l.l.l.l.J.l.l.l.J.I._.^.U.^.U.U./.I.I.I.I.I.I.E./.Q.E./././.`.(./.E.)./././.I.I.H.I.I.U.I.I.I.I.I.I.I.I.I.I.I.I./.`.`.n.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX, t R j.s.%.s.i.i.:.%.f.d.l.s.u.%.O.E J Z b F z g g g g h h b Z b b b h h z h h b H J Z F F b b h h b J { Z C h Z Z Z b { b b Z Z F Z J @.%.X.X.o.W W E R A W G W t.p.g.l.u.G Z W G J A Z W d.s.g.s.g.s.s.:.:.W W i.i.E E X.X.X.{ F W W W E W :.u.i.s.i.j.j.s.i.k.S.G./.H.l.l.l.l.l.l.P.I.I.l.J.I._.I.I.~.^.U./.I.I.^.I.I./.I.I./.E././.^./.(./././.I.I.I.G.I.I./._./.I.I.G.I.U.I.I./.I.Q.^./._.).n.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX- i E :.s.:.s.:.i.%.u.j.l.F.u.:.:.@.E E H F Z b h i s h h h z b h h s h h h h b H O.J G Z H G b b Z J X.G C z C Z z b b h b Z z F F G %.d.s.g.D.d.#.W W #.p.p.W u.W %.p.%.W W i.+.Z G J u.l.l.S.s.s.s.s.:.#.@.W E W X.E %.:.u.O.E E W E W :.s.d.s.d.d.i.:.%.u.j.F.F.G.l.U.l.k.k.U.U.l.I.l.l.J.I.I.^.^.U.U././.E./._./.Q.I.^.Q.I.E././././._./././.Q.U.^.I.I.I.U.Q./.I.Q.^.U./.I.I.I./.Q.U./._.n.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXH X.i.i.:.s.:.s.s.s.s.l.k.i.u.:.W E E J F Z Z h g g g h z b b g g g h b h b F X.@.X.J J E b h b J m z h z z z Z Z b z z z h C G G :.u.i.g.S.g.:.g.s.s.s.:.E K A L X.W p.s.d.E b Z G J y.i.p.g.l.l.s.@.@.#.i.%.:.%.%.k.F.j.u.u.:.:.@.W E @.s.s.k.j.:.W :.:.s.k.j.k.G.l.G.l.l.U.l.l.l.l.I.U.I.I.I.~.^.^._.U.U./._._._./.~.U./././././._.`./.~.I.I.I.I.I.Q./.I./.Q././.(._./.Q.I././.I.Q._.L.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX= H @.7.$.i.%.:.k.s.s.g.k.k.g.d.@.E S F Z F b Z h h h h Z b h h g g h h b Z E @.F F E W { Z k b Z Z z h h Z h Z b Z Z Z h z F G F W %.%.:.s.j.s.k.k.s.s.:.@.G C A Z W W W E Z G b H %.o.X.t.u.g.s.:.%.i.i.t.%.:.;.s.k.l.k.k.j.W W i.#.u.s.g.k.k.i.i.#.#.%.i.l.f.l.l.l.G.J.I.U.U.l.l._._.I.I.I.U.I.I.I.U.~.~.U././._.U.I.U.^._./._.^./././.I.I.I.H.G.I.I.I./.`._.]._._./.Q.I./.E.I.Q._.V.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX8 F $.@.@.:.5.s.s.p.g.B.F.k.k.k.u.X.J Z b m S b h z g b Z h b h g g s s h Z J Z Z b H @.X.{ J Z Z Z Z S H Z Z F Z A W B h z C z F W %.%.u.g.k.l.l.g.s.g.:.X.K K Z B A C C J { A S U D A A E g.g.%.:.W W E J @.:.:.%.:.:.:.s.u.u.W E :.k.l.s.d.#.W W $.%.u.s.k.l.F.U.U.U.P.l.l.l.U.l.I.I.l.~.U.I.I.J.J._.~.U.I./.`./.I.I.G.I.U./././.U./././.I.I.I.~.I.I._.]._./._._.U.I././.I.Q.(.Z.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX8 g F O.@.%.5.s.s.i.s.g.J.H.k.s.s.:.E F z C h b b b b b b h h h b h h h g f Z Z z z b J H { @.J b S Z Z H H X.X.S C J F C Z F E E %.@.:.i.s.l.l.l.l.l.k.s.i.d.u.@.Z C C C Z h s h k J A h 0 W #.t.W E E W J J A J W @.%.:.u.u.E E W s.l.g.W W W %.:.W u.k.g.l.G.F.G.l.k.G.).l.~.l.U.~.U.I.l.U.l.J.J.J.l.U.I./.I.I.`./.H.G.I.I.I.^./.U.U././././.I.I.I./._.(.Q././._././._././.!.V.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXa b E @.W s.s.u.s.s.k.H.S.S.s.s.%.E H Z Z z z z Z Z b b z h h h h h g h h Z h b z h Z Z b S b Z Z S S Z Z Z C C C z G @.%.u.u.%.#.%.i.j.k.d.g.l.l.g.s.i.f.f.g.%.Z C h d g h h h Z D h h h V G J Z G J J K X.%.o.i.g.s.u.@.E T E #.t.W W @.u.u.@.E :.l.l.l.l.l.l.l.U.U.l.l.l.l.U._.U.l.l.l._._.l._._.I.U.G.l.I./.U.I.G.G.I.I.G.I./.I.I./.(.(./.~.I.^./.Q.Q.(.(././.Q.^./.Q.R.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXg z ;.E X.:.g.s.s.f.k.k.k.l.s.s.E X.E J X.C Z h z b b z h h g h h h h g h h h h h h h h h h z b Z S G Z A A A A F J X.%.%.%.#.#.:.:.s.d.g.s.s.u.:.s.l.l.l.s.:.F b z g h b h h Z D V h s s s h k S G J X.5.p.s.%.f.f.s.@.R E E W E W @.:.s.u.@.#.j.l.U.U.U.I.U.l.U.l.l.k.k.l.U.l.U.l.l._._.l.U.l.l._.F.l.F.G.U.I.U.G.F.F.G.G.I./.^.I.(./.(.`././.`._.(.`.`.Q./.Q.U./._.R.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX@ = a :.#.O.:.g.f.g.s.s.l.k.k.k.s.@.E J :.E z z b z z f f f h h h g g h g h g s s z h h h k B B Z Z F Z W W W W @.%.@.@.@.%.$.:.i.i.s.s.s.s.k.g.s.g.k.l.l.p.:.z s h s z Z Z h h s h h h h h h V A J X.+.%.f.g.s.s.g.l.:.R E G @.W E #.s.r.h.l.l.l.l.l.l.l.l.l.l.U.U.l.s.l._.U.U.l._._.l._._.U.U.l.l.G.l.F.G.I./.U.I.I.G.G.G.I.U.I.U.I.I./.^./._._._._._././.E.E.Q.`.W.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX> g %.O.%.5.f.s.s.i.f.k.j.k.k.u.J E E E F E s.E z h d d h h h h h h h h h z h g h h h h h C Z V C C E W W @.@.%.:.:.%.%.:.s.i.i.u.s.s.i.k.l.l.j.s.f.u.W J h h h Z z Z F k h h b h h k V V A D U &.p.i.f.s.s.k.S.l.k.W E E 0 E C @.#.g.k.s.s.:.s.l.l.l.l.U.U.l.l.g.k.U.l.l.l.l.l.l.l.l.l.U.l.l.U.G.l.F.H.I././.I.F.G.F.H.I.^.I.I.I.I.~.I.^.(._.(._././././.E.).V.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX, i X.@.%.s.d.s.i.s.j.j.k.l.p.%.E W @.X.#.f.i.W F f z z F b z g s b Z z b b Z h h h h h G X.{ F C C C E W W W %.%.i.:.5.k.s.i.s.s.k.k.s.k.l.l.d.p.@.Z f f f h Z C h C h h h B k V B V Z h D D X.X.W t.%.s.k.C.U.l.j.@.E E E W W @.:.:.:.:.s.s.l.U.l.l.k.s.:.s.k.l.).l.U._.l.U.l._.l._.l.I.l.l.l.l.G.G.I.U._.I.F.F.l.H.I.I.G.I.~.I.I.I.I.I.^./././.E.I.Q.Q.j.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX5 k H @.i.f.k.s.s.p.F.F.k.f.s.s.:.:.:.%.u.:.%.%.@.W E E :.F k k h b h b k Z b F Z z S X.:.@.E E E C E W W E E @.5.i.%.:.:.i.s.u.s.s.k.s.s.g.:.W A C h h h B h z C z Z h B s h V V J A B S A D J J W i.i.s.l.l.s.s.:.@.:.#.*.W @.:.g.l.l.l.l.l.l.U.l.s.s.r.g.l.l.l.l.l.l.l.l.l.).l.l.l.l.U.I.C.F.G.G.I.I./.I.G.G.F.C.F.I.I.I.I.G.G.I.I./.I.I.I.J.J.E.Q.e.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXt g z W i.u.s.s.s.k.l.l.l.s.s.k.l.7.s.s.:.%.5.s.%.@.E E E F F J b b Z Z G { E J Z F E :.u.%.@.t.t.G W W E @.u.u.i.:.:.u.i.u.s.u.s.s.l.l.s.E G A A Z Z C B z h C Z A C h A Z B V Z Z B A D D K L o.d.l.f.k.k.:.:.E :.s.:.E E :.g.l.l.l.U.l.l.k.s.d.k.l.l.l.U.l.l.l.l.l.l.U.l.l.l.U.l.U.l.P.l.I.F.P.G.G.^./.G.F.S.F.l.I.G.I.G.I.G.I././.I.I.I.G.G.R.N.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX5 g h J :.u.s.s.j.l.l.k.k.s.:.k.S.l.l.:.u.:.:.i.#.#.W X.X.X.E J S G G H H F F A J E :.:.s.%.t.k.W W W #.u.s.s.i.:.:.i.s.s.s.s.s.k.U._.s.W W A K A A C B B B B C Z h V Z B Z B V Z Z A D J o.t.o.i.f.p.f.k.k.s.:.@.E @.#.@.l.l.l.U.l.l.l.g.:.#.g.U.l.U.U.U.l.l.k.l.l.k.j.l.l.l.l.l.l.G.G.I.^.l.J.G.H.I.U.G.l.F.F.S.G.U.G.G.I.I.I.I.I.I.G.H.P.E.V.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXz h g G +.i.$.X.i.g.S.S.k.:.W :.l.k.j.i.i.u.i.u.:.%.W W %.%.@.E F E F Z z C C A G +.g.k.s.@.#.:.C C %.u.s.s.i.@.W :.s.l.l.k.j.k.l.k.s.%.W K G B Z Z B B Z J J C C B Z A A A B A L K K L o.#.o.t.u.d.k.l.k.l.l.F.j.k.k.k.l.F.k.k.k.S.C.k.j.s.l.l.P._.l.l.l.l.l._.l.k.k.k.k.l.l.l.l.l.l.l.F.F.F.l.H.G./.G.G.G.G.G.G.I.I.I.I.I.I.I.I.G.I.I.U.e.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX> h g Z +.o.Z Z :.S.F.k.:.E F E X.u.f.g.k.k.k.i.i.%.:.@.:.:.#.#.W W F z Z C A A G +.u.g.s.i.:.:.W %.#.#.:.u.:.@.%.u.k.k.k.l.k.k.k.j.u.X.J G A Z Z B B Z J W J L B Z A A A A A K X.K K o.d.i.t.t.d.l.k.k.l.l.l.l.k.S.S.l.k.k.H.F.l.l.k.l.l.l.I.l.I.P._.l.l.I.l.l.l.k.j.l.l.).l.l.).l.F.l.F.S.S.F.G.U.I.G.G.P.G.G.U.I.I.J.I.I.I.I.I.U.W.r.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXH i G @.{ Z X.5.k.l.7.G F F Z F %.S.I.I.F.k.i.i.u.:.:.:.:.:.#.W E G F G A A L J E #.u.s.@.@.W W J @.W :.u.i.s.u.i.k.l.I.U._.l.l.s.s.%.K A A Z Z A Z A G A J Z A A L A Z L L K %.t.d.l.d.u.t.u.k.k.k.l.l.k.k.k.s.k.k.S.S.F.C.k.k.l.C.l.P.l.l.U.l.l.l.l.l.l.).l.l.l.l.l.l.s.k.l.k.l.l.S.S.H.H.H.I.I.I.G.I.I.U.I.I.I.I.G.I.I.Q._.L.*.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX5 t G @.%.+.%.:.k.k.:.b z z z F i.I.I.G.k.k.i.k.k.u.s.s.s.%.#.u.W W W G K W J E :.s.s.:.@.W W L W #.%.i.u.u.:.u.k.l.~.I.U._.l.s.s.#.K A A G J A L W K W W W L A A B B C A K X.W t.p.u.u.p.#.t.u.j.S.l.k.k.i.:.:.s.S.S.l.k.k.S.l.F.G.G.I.l.l.l.l.l.l.U.l._.l.l.l.l.l.l.k.k.k.k.l.l.C.H.H.S.l.G.U.I.F.G.F.G.G.G.G.F.P.I.I.Q.A.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX3 4 Z X.%.%.%.%.k.k.@.z i f f C u.I.I.F.k.f.s.S.f.f.d.k.s.j.s.:.5.:.+.@.@.%.:.s.s.g.g.k.g.%.W W u.u.u.s.g.u.i.k.l.l.l.U.l.l.f.u.@.E W J G W L J W W W W W W G A B B A L W W W t.t.t.u.s.i.k.f.f.l.k.j.s.i.s.s.k.F.F.S.l.G.G.G.G.l.l.l.l.l.F.).k.l.U.l._.l.l.l.U.l.l.l.l.k.j.l.k.S.S.l.k.l.F.I.G.H.S.H.F.G.G.H.G.I.U.P.7.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX, 6 k G O.:.%.:.l.k.:.F i 0 i F i.l.P.F.k.k.S.k.k.f.d.k.k.j.k.k.k.k.d.f.d.s.s.:.s.g.j.g.u.u.@.u.p.i.i.k.s.s.g.g.l.l.l.l.k.g.i.s.:.:.W W W W o.W o.#.W W W t.o.o.o.+.o.o.W t.t.t.u.d.i.j.l.l.l.k.d.d.l.G.l.S.F.F.S.S.C.I.I.U.G.G.G.P._.U.F.l.l.l.l.U.l.l.l.l.l.l.P.k.k.l.l.l.l.l.S.S.F.l.S.G.I.G.H.H.G.G.I.G.I.Q.P.e.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX> 9 Z J W %.@.i.k.k.j.#.C z E i.k.k.B.B.k.k.g.s.s.k.k.k.k.k.k.l.l.k.k.d.s.k.s.s.s.g.g.g.g.#.K i.:.t.g.s.g.g.k.s.l.l.l.l.k.k.f.d.j.i.s.s.+.K L G G L W t.p.p.p.p.g.u.p.p.d.p.d.i.s.k.l.l.f.s.f.d.k.k.k.l.F.C.I.F.S.S.F.I.U.l.l.J.I.I.F.F.).U.l.U.l._.l.).U.l.l.l.l.l.l.l.F.C.l.k.l.l.l.F.G.G.G.G.H.G.P.I.I.Q.L.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXh H A W #.#.u.d.d.s.j.s.:.:.s.k.f.g.j.k.l.k.k.k.k.l.U.G.G.U.I.l.k.d.g.s.g.s.s.g.k.g.k.d.i.i.s.i.g.s.k.k.g.s.j.l.l.l.k.f.k.F.G.F.k.d.+.W o.K A A G W t.u.u.u.%.%.p.d.j.s.k.d.d.k.l.k.p.s.k.k.l.l.l.I.H.k.S.S.G.I.I.I.U.G.l.P.l.k.l.l.l.l.U.l.l.l.l.l.l.l.l.l.l.l.l.l.G.l.l.k.l.F.l.G.G.I.H.I.I.I.I.I.Q.j.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXt F z b %.i.g.:.:.i.s.s.s.5.s.s.s.s.g.k.k.F.B.B.F.F.G.I._._.I.l.j.d.k.k.p.s.i.g.k.f.g.u.s.s.s.u.s.k.k.d.k.g.k.l.l.l.S.P.I.I.~.U.l.g.g.k.i.u.u.i.d.l.d.u.o.W k.k.s.k.l.k.k.l.k.l.:.i.l.l.l.l.k.j.k.S.S.F.C.S.I.F.I.P.G.G.F.F.l.k.k.l.k.k.k.k.k.k.k.l.L.l.l.k.k.k.l.l.l.l.l.l.F.F.G.U.I.I.I.I.Q./.!.e.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXz b z $.f.i.%.:.:.i.k.f.s.p.i.f.j.k.k.k.g.B.k.k.l.F.I.I.F.S.S.l.k.k.d.d.i.i.s.p.f.d.k.s.d.s.s.g.k.k.g.g.k.l.l.k.l.l.F.l.l.k.k.l.j.k.i.g.g.l.P.~.F.k.s.d.k.k.s.l.l.s.s.l.l.j.#.%.i.d.d.i.k.k.l.k.k.S.S.S.S.G.G.F.F.l.F.l.k.k.l.S.k.j.k.k.k.k.k.l.l.l.l.l.l.l.l.J.l.I.I.F.G.G.G.I.I.I.I.E.Q.W.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXa t H @.%.&.5.:.s.s.k.s.g.f.f.k.k.k.k.s.f.s.s.f.k.k.k.s.s.s.k.k.k.d.d.s.i.i.s.s.k.k.i.s.s.u.s.g.k.d.g.s.k.g.k.l.k.:.%.:.i.:.i.s.g.k.g.k.l.l.I.l.l.l.J.l.k.k.s.i.s.i.t.#.#.#.W #.W u.d.l.l.l.B.S.H.F.G.F.F.l.F.l.F.k.j.s.k.l.l.k.s.k.k.k.f.k.k.k.G.G.l.j.l.l.I.I.l.J.G.G.G.I.^.U.U.).W.j.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXt b H O.%.%.%.i.s.f.f.B.k.f.k.k.k.f.k.s.:.:.s.s.s.s.s.s.k.d.j.s.j.k.s.k.d.k.d.k.s.s.d.d.s.d.s.j.g.g.k.l.k.k.F.k.k.l.F.G.l.k.k.l.i.k.l.I.l.l.J.I.l.l.j.i.s.:.:.%.t.t.W W t.#.t.u.s.j.l.l.S.S.F.F.l.F.C.l.l.F.l.k.s.s.k.j.s.j.k.k.k.k.k.g.F.A.l.l.l.l.I.U.U.~.l.I.I.J.G.I.U._.`.R.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXt b X.%.o.X.5.f.5.s.k.g.k.S.k.f.s.g.s.:.:.i.s.k.g.s.k.d.j.k.d.k.j.l.k.l.l.l.s.s.s.k.j.k.d.l.l.l.U.l.G.l.G.G.I.I.I.G.I.l.U.~.~._.U.l._.I.G.I.G.l.l.l.l.j.t.:.:.%.t.t.t.u.k.d.k.j.l.l.l.l.l.j.k.k.k.k.k.k.k.k.k.k.s.s.i.f.k.k.k.l.l.l.l.k.k.d.k.l.I.~.l.U.I.I.I.I.I.I.Q.Q.e.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX[ J +.O.X.%.i.i.i.s.k.s.i.g.s.k.S.s.s.s.:.s.k.k.k.d.l.l.k.k.k.l.l.k.k.k.k.s.d.k.l.l.l.I.U.U.U.l.l.G.F.I./.G.l.k.l.l.I.l.l.l.l._._.~._./.I.l.k.k.l.l.j.:.u.k.g.d.d.l.l.l.l.l.l.l.l.k.k.s.s.s.k.j.k.k.k.k.k.k.s.d.g.k.l.l.l.k.k.f.s.j.d.k.l.l.I.U.~.l.J.J.J.I.U.W.e.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX5 Z X.+.%.i.p.s.i.i.s.i.i.s.i.i.s.i.u.u.i.S.S.k.k.k.F.s.l.l.G.l.l.j.k.l.G.l.I.G.I.U.U.G.G.G.U.I.I.G.I././._._.P.I._.l.l.l.)._.U._._._.G.k.k.s.k.l.l.l.d.i.j.k.k.l.l.J.l.J.G.l.k.s.%.:.i.s.i.i.s.s.d.f.k.s.d.s.p.f.f.s.u.i.p.i.s.d.k.l.I.I.I.l.I.l.l.P.U.U.V.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX1 > t O.%.:.:.:.i.s.l.k.s.k.s.@.:.#.G @.k.k.k.k.l.l.l.k.G.F.l.P.U.l.l.l.l.l.l.I.I.l.G.l.l.G.G.G.S.G.^.U.U.U._._.U._._._._.].U.I.G.G.G.j.s.k.l.l.l.P.d.u.k.d.j.k.l.l.G.J.l.k.j.s.i.k.s.u.u.i.u.s.u.u.:.u.d.s.u.t.+.t.%.t.u.i.j.k.l.I.l.~._.~.I.I.).G.j.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX4 > g X.i.i.%.%.i.f.k.s.f.s.u.s.%.@.%.u.k.l.l.l.k.k.k.G.)._.l.l.U.l.U._.U.l.U.l.U.l.l.l.l.l.G.P.I.I.U.l.l.U.G.F._._._._.l.).l.l.l.k.j.l.l.J.l.l.j.i.s.s.k.k.l.l.l.l.k.d.k.s.k.k.i.i.s.u.i.5.+.%.i.s.k.f.u.p.u.i.i.i.d.g.B.J.I.J.F.E.E.P.I.P.e.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX$ 4 6 h $.5.%.%.:.:.i.f.d.s.u.i.i.s.s.j.G.F.C.C.F.l.l.l.l.U._._._._.l._.l.l.U.l._.l.U.l.l.I.l.l.I.l.k.G.U.J.P.l.l.l.l.U.l.l.k.k.l.l.I._.U.l.k.l.k.d.k.k.k.l.l.k.k.j.d.k.s.k.s.i.s.d.s.i.i.p.i.a.g.s.g.d.u.p.p.l.S.G.J.I.I.I.J.I.I.E.E.P.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXh z d h { %.O.+.%.u.k.f.u.u.f.s.k.s.k.l.F.l.F.G.G.l.l.l._._.l._.l.l.l.l.l.l.U.l.l.l.l.l.G.l.l.l.j.l.P.l.I.).k.l.l.k.k.l.l.k.l.l.k.l.l.i.W u.k.d.k.k.l.J.l.k.k.k.k.k.l.k.k.g.g.s.s.p.s.s.s.g.g.k.g.f.g.l.l.D.G.J.I.I.I.J.I.E.Q.H.7.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX@ 5 J { +.%.o.u.s.:.#.d.k.g.k.k.k.k.k.F.I.I.).U._._._._._._._._.).l.l.U.l.l.j.l.G.P.l.l.l.l.l.l.J.l.l.l.l.l.k.k.l.l.l.l.l.k.l.l.d.i.d.k.k.k.k.k.k.l.l.l.l.k.i.u.k.k.l.k.k.f.s.s.g.g.S.F.k.C.S.S.F.G.H.J.J.H.S.H.E.Q.N.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXt a k [ :.:.:.i.:.%.i.f.k.^.J.k.k.k.F.I._.U.U._.U._.].)._.).U.U.).l.l.k.k.k.l.k.k.k.k.k.k.k.l.k.l.j.g.l.k.l.G.l.l.P.l.i.k.d.d.k.k.k.d.k.k.s.s.s.f.g.k.s.u.#.t.p.k.S.l.k.g.B.g.S.B.S.B.B.H.S.S.H.F.F.H.J.I.P.A.;.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXb z z F @.s.s.i.s.7.j.l.G.l.B.k.k.j.k.l._.].U.)._._.U._.U.U.l._.l.l.F.l.l.G.F.F.H.S.l.l.l.k.;.@.i.l.l.l.l.l.l.l.l.j.d.s.g.s.d.d.i.i.u.W %.u.p.d.k.d.g.d.k.l.k.k.k.s.g.C.S.F.S.B.S.S.S.l.B.S.F.F.Q.R.N.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXm b F W :.:.s.5.i.s.i.f.f.g.g.s.g.l.l.l.U.l.).l.U.l.G.l.l.U.l.l.l.k.l.l.F.C.k.l.l.l.l.s.s.g.l.I.l.l.l.l.l.g.k.g.k.g.s.s.d.%.E W W W u.d.d.k.k.F.F.l.l.l.l.f.f.F.J.F.F.S.S.D.S.S.C.F.J.H.A.f.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXf f R R :.i.i.:.f.s.i.i.j.k.g.s.l.l.l.l.l.j.k.k.k.s.g.j.f.s.k.g.j.s.s.s.j.g.k.k.s.k.l.l.l.l.P.A.l.l.k.l.g.k.k.k.k.f.i.:.:.#.u.s.d.k.k.k.l.F.l.k.f.f.l.F.F.B.B.B.B.k.k.C.I.J.C.S.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX- h H X.t.p.i.:.:.%.%.i.i.g.f.f.f.s.s.:.:.:.s.k.j.g.s.f.f.f.g.k.k.k.k.j.k.f.g.k.l.l._._.l.l.U.l.l.C.F.l.l.k.s.k.k.S.k.B.S.B.k.k.C.f.k.k.s.s.s.k.k.f.g.k.B.S.F.H.B.f.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX> 5 m O.&.%.@.%.%.&.5.s.f.s.i.s.u.s.s.s.s.s.g.g.f.s.f.f.f.f.k.f.g.f.s.g.i.%.:.j.k.l.g.k.k.j.l.S.H.k.k.k.k.F.k.k.B.B.B.B.k.k.k.d.g.k.k.k.d.k.d.k.B.F.F.N.f.4.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXX.X.O.%.+.5.5.5.5.i.s.s.u.s.s.i.s.u.i.i.f.f.g.f.g.f.s.s.s.s.i.5.i.5.t.t.i.i.k.l.l.l.B.k.k.S.l.l.l.k.k.g.s.f.g.g.g.g.g.k.k.l.l.l.k.F.F.f.5.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX$.$.%.i.5.i.%.:.u.s.:.u.r.s.i.i.i.5.f.s.s.f.f.f.f.i.i.s.f.f.g.i.j.g.l.l.l.l.l.k.k.k.k.k.k.k.k.k.k.k.k.g.k.F.F.l.F.S.S.k.j.7.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXh +.5.;.%.%.u.s.i.s.i.&.i.f.f.f.k.B.k.k.k.s.k.B.B.k.B.k.k.s.k.l.j.g.g.g.B.k.g.g.g.g.S.F.F.D.B.J.J.P.F.B.k.f.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXR W E E @.+.$.%.5.%.5.s.5.u.s.s.s.g.f.f.g.j.s.k.k.l.l.k.j.B.S.B.k.k.B.S.C.C.C.N.f.f.9.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXb I { { { O.$.X.%.%.@.:.i.i.s.s.:.i.j.l.k.k.g.s.k.g.f.4.$.$.{ oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX", +"oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX{ { F m J [ } $.$.H z 7.oXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX" +}; diff -Nru xsnow-3.1.1/src/Pixmaps/polarbear.xpm xsnow-3.3.2/src/Pixmaps/polarbear.xpm --- xsnow-3.1.1/src/Pixmaps/polarbear.xpm 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/polarbear.xpm 2021-11-04 14:24:27.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/Pixmaps/RegularSanta1.xpm xsnow-3.3.2/src/Pixmaps/RegularSanta1.xpm --- xsnow-3.1.1/src/Pixmaps/RegularSanta1.xpm 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/RegularSanta1.xpm 2021-11-04 14:24:28.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/Pixmaps/RegularSanta2.xpm xsnow-3.3.2/src/Pixmaps/RegularSanta2.xpm --- xsnow-3.1.1/src/Pixmaps/RegularSanta2.xpm 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/RegularSanta2.xpm 2021-11-04 14:24:28.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/Pixmaps/RegularSanta3.xpm xsnow-3.3.2/src/Pixmaps/RegularSanta3.xpm --- xsnow-3.1.1/src/Pixmaps/RegularSanta3.xpm 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/RegularSanta3.xpm 2021-11-04 14:24:28.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/Pixmaps/RegularSanta4.xpm xsnow-3.3.2/src/Pixmaps/RegularSanta4.xpm --- xsnow-3.1.1/src/Pixmaps/RegularSanta4.xpm 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/RegularSanta4.xpm 2021-11-04 14:24:28.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/Pixmaps/RegularSantaRudolf1.xpm xsnow-3.3.2/src/Pixmaps/RegularSantaRudolf1.xpm --- xsnow-3.1.1/src/Pixmaps/RegularSantaRudolf1.xpm 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/RegularSantaRudolf1.xpm 2021-11-04 14:24:27.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/Pixmaps/RegularSantaRudolf2.xpm xsnow-3.3.2/src/Pixmaps/RegularSantaRudolf2.xpm --- xsnow-3.1.1/src/Pixmaps/RegularSantaRudolf2.xpm 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/RegularSantaRudolf2.xpm 2021-11-04 14:24:28.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/Pixmaps/RegularSantaRudolf3.xpm xsnow-3.3.2/src/Pixmaps/RegularSantaRudolf3.xpm --- xsnow-3.1.1/src/Pixmaps/RegularSantaRudolf3.xpm 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/RegularSantaRudolf3.xpm 2021-11-04 14:24:28.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/Pixmaps/RegularSantaRudolf4.xpm xsnow-3.3.2/src/Pixmaps/RegularSantaRudolf4.xpm --- xsnow-3.1.1/src/Pixmaps/RegularSantaRudolf4.xpm 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/RegularSantaRudolf4.xpm 2021-11-04 14:24:27.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/Pixmaps/rendier.xpm xsnow-3.3.2/src/Pixmaps/rendier.xpm --- xsnow-3.1.1/src/Pixmaps/rendier.xpm 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/rendier.xpm 2021-11-04 14:24:28.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/Pixmaps/snowtree.xpm xsnow-3.3.2/src/Pixmaps/snowtree.xpm --- xsnow-3.1.1/src/Pixmaps/snowtree.xpm 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/snowtree.xpm 2021-11-04 14:24:28.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/Pixmaps/star.xbm xsnow-3.3.2/src/Pixmaps/star.xbm --- xsnow-3.1.1/src/Pixmaps/star.xbm 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/star.xbm 2021-11-04 14:24:28.000000000 +0000 @@ -2,7 +2,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/Pixmaps/tannenbaum.xpm xsnow-3.3.2/src/Pixmaps/tannenbaum.xpm --- xsnow-3.1.1/src/Pixmaps/tannenbaum.xpm 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/tannenbaum.xpm 2021-11-04 14:24:27.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by @@ -23,7 +23,7 @@ /* columns rows colors chars-per-pixel */ "56 56 2 1 ", " c None", -". c green", +". c black", /* pixels */ " ", " . ", diff -Nru xsnow-3.1.1/src/Pixmaps/tree-1_100px.xpm xsnow-3.3.2/src/Pixmaps/tree-1_100px.xpm --- xsnow-3.1.1/src/Pixmaps/tree-1_100px.xpm 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/tree-1_100px.xpm 2021-11-04 14:24:28.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/Pixmaps/tree.xpm xsnow-3.3.2/src/Pixmaps/tree.xpm --- xsnow-3.1.1/src/Pixmaps/tree.xpm 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/tree.xpm 2021-11-04 14:24:27.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by Binary files /tmp/tmp_vg_k98t/gt84z0ejWB/xsnow-3.1.1/src/Pixmaps/xsnow.jpg and /tmp/tmp_vg_k98t/ieXM30xdW7/xsnow-3.3.2/src/Pixmaps/xsnow.jpg differ Binary files /tmp/tmp_vg_k98t/gt84z0ejWB/xsnow-3.1.1/src/Pixmaps/xsnow.png and /tmp/tmp_vg_k98t/ieXM30xdW7/xsnow-3.3.2/src/Pixmaps/xsnow.png differ diff -Nru xsnow-3.1.1/src/Pixmaps/xsnow.xpm xsnow-3.3.2/src/Pixmaps/xsnow.xpm --- xsnow-3.1.1/src/Pixmaps/xsnow.xpm 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/Pixmaps/xsnow.xpm 2021-11-04 14:24:28.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/pixmaps.c xsnow-3.3.2/src/pixmaps.c --- xsnow-3.1.1/src/pixmaps.c 2020-10-13 12:50:56.000000000 +0000 +++ xsnow-3.3.2/src/pixmaps.c 2021-11-04 14:24:27.000000000 +0000 @@ -2,7 +2,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by @@ -173,6 +173,11 @@ birdd1_xpm, birdd2_xpm, birdd3_xpm, birdd4_xpm, birdd5_xpm, birdd6_xpm, birdd7_xpm, birdd8_xpm }; +#include "Pixmaps/moon1.xpm" +XPM_TYPE **moons_xpm[]= +{ + moon1_xpm +}; #define SNOW(x) snow##x##_xpm, XPM_TYPE **snow_xpm[] = @@ -188,4 +193,4 @@ * NULL * } * */ -#undef SNOW +#include "undefall.inc" diff -Nru xsnow-3.1.1/src/pixmaps.h xsnow-3.3.2/src/pixmaps.h --- xsnow-3.1.1/src/pixmaps.h 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/pixmaps.h 2021-11-04 14:24:28.000000000 +0000 @@ -2,7 +2,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by @@ -19,16 +19,14 @@ #-# */ #pragma once -#define XPM_TYPE const char #include "xsnow.h" -#include "snow.h" -#include "stars.h" -//extern SnowMap snowPix[]; extern StarMap starPix; -extern const char ***Santas[][2]; -extern const char **xpmtrees[]; -extern const char **xsnow_logo; -extern const char **birds_xpm[]; -extern const char **snow_xpm[]; +extern XPM_TYPE ***Santas[][2]; +extern XPM_TYPE **xpmtrees[]; +extern XPM_TYPE **xsnow_logo; +extern XPM_TYPE **birds_xpm[]; +extern XPM_TYPE **snow_xpm[]; +extern XPM_TYPE **moons_xpm[]; + diff -Nru xsnow-3.1.1/src/Santa.c xsnow-3.3.2/src/Santa.c --- xsnow-3.1.1/src/Santa.c 2020-10-13 12:50:56.000000000 +0000 +++ xsnow-3.3.2/src/Santa.c 2021-11-04 14:24:27.000000000 +0000 @@ -2,7 +2,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by @@ -33,41 +33,29 @@ #include "utils.h" #include "wind.h" #include "ixpm.h" -#include "varia.h" +#include "moon.h" #define NOTACTIVE \ (Flags.BirdsOnly || !WorkspaceActive()) -static int do_santa(gpointer data); -static int do_santa1(gpointer data); -static int do_usanta(gpointer data); -static void EraseSanta(int x, int y); -static void DrawSanta(void); -static void DrawSanta1(void); -static void InitSantaPixmaps(void); +static int do_usanta(void *); +//static void InitSantaPixmaps(void); static void init_Santa_surfaces(void); static Region RegionCreateRectangle(int x, int y, int w, int h); static void ResetSanta(void); -static void SetSantaSpeed(void); +static void SetSantaSizeSpeed(void); +static void setSantaRegions(void); -static int CurrentSanta; -static GC ESantaGC = NULL; -static int OldSantaX = 0; // the x value of Santa when he was last drawn -static int OldSantaY = 0; // the y value of Santa when he was last drawn -static GC SantaGC = NULL; -static Pixmap SantaMaskPixmap[PIXINANIMATION]; -static Pixmap SantaPixmap[PIXINANIMATION]; -static Region SantaRegion; -static float SantaSpeed; -static float SantaXr; -static float SantaYr; -static int SantaYStep; - -float ActualSantaSpeed; -Region SantaPlowRegion; -int SantaHeight; -int SantaWidth; -int SantaX; // should always be lrintf(SantaYr) -int SantaY; // should always be lrintf(SantaYr) +static int CurrentSanta; +static Pixmap SantaMaskPixmap[PIXINANIMATION]; +static Pixmap SantaPixmap[PIXINANIMATION]; +static Region SantaRegion = 0; +static float SantaSpeed; +static float SantaXr; +static float SantaYr; +static int SantaYStep; +static int OldSantaX = 0; // the x value of Santa when he was last drawn +static int OldSantaY = 0; // the y value of Santa when he was last drawn +static const float LocalScale = 0.6; static cairo_surface_t *Santa_surfaces[MAXSANTA+1][2][PIXINANIMATION]; @@ -79,53 +67,45 @@ SANTASPEED4, /* Santa 4 */ }; -int Santa_ui() +void Santa_ui() { - int changes = 0; - if (Flags.SantaSize != OldFlags.SantaSize || - Flags.NoRudolf != OldFlags.NoRudolf) - { - EraseSanta(OldSantaX,OldSantaY); - InitSantaPixmaps(); - OldFlags.SantaSize = Flags.SantaSize; - OldFlags.NoRudolf = Flags.NoRudolf; - changes++; - P("changes: %d\n",changes); - if(Flags.Noisy) - printf("Santa: %d Rudolph: %d\n",Flags.SantaSize, !Flags.NoRudolf); // this for testing, see test2.sh and test3.sh - } - if (Flags.NoSanta != OldFlags.NoSanta) - { - //P("do_ui_check\n"); - if (Flags.NoSanta) - EraseSanta(OldSantaX, OldSantaY); - OldFlags.NoSanta = Flags.NoSanta; - changes++; - P("changes: %d\n",changes); - } - if(Flags.SantaSpeedFactor != OldFlags.SantaSpeedFactor) + UIDO(SantaSize, SetSantaSizeSpeed();); + UIDO(Rudolf, SetSantaSizeSpeed();); + UIDO(NoSanta, ); + UIDO(SantaSpeedFactor, SetSantaSizeSpeed();); + + static int prev = 100; + if(ScaleChanged(&prev)) { - SetSantaSpeed(); - OldFlags.SantaSpeedFactor = Flags.SantaSpeedFactor; - changes++; - P("changes: %d\n",changes); + P("%d Santa_scale \n",global.counter); + SetSantaSizeSpeed(); } - - return changes; } int Santa_draw(cairo_t *cr) { - P("Santa_draw %d\n",counter++); if (Flags.NoSanta) return TRUE; + P("Santa_draw %d\n",global.counter++); cairo_surface_t *surface; - surface = Santa_surfaces[Flags.SantaSize][!Flags.NoRudolf][CurrentSanta]; - cairo_set_source_surface (cr, surface, SantaX, SantaY); + surface = Santa_surfaces[Flags.SantaSize][Flags.Rudolf][CurrentSanta]; + cairo_set_source_surface (cr, surface, global.SantaX, global.SantaY); my_cairo_paint_with_alpha(cr,ALPHA); + OldSantaX = global.SantaX; + OldSantaY = global.SantaY; return TRUE; } +void Santa_erase(cairo_t *cr) +{ + P("Santa_erase %d %d\n",OldSantaX,OldSantaY); + (void)cr; + myXClearArea(global.display, global.SnowWin, + OldSantaX, OldSantaY, + global.SantaWidth+1,global.SantaHeight, + global.xxposures); +} + void Santa_init() { P("Santa_init\n"); @@ -135,28 +115,17 @@ SantaPixmap[i] = 0; SantaMaskPixmap[i] = 0; } - InitSantaPixmaps(); + int j,k; + for (i=0; i3*SantaSpeed) - ActualSantaSpeed = 3*SantaSpeed; - else if (ActualSantaSpeed < -2*SantaSpeed) - ActualSantaSpeed = -2*SantaSpeed; - SantaXr += dt*ActualSantaSpeed; - if (SantaXr >= SnowWinWidth) + double santayrmin = 0; + double santayrmax = global.SnowWinHeight*0.33; + + global.ActualSantaSpeed += dt*(SANTASENS*global.NewWind+SantaSpeed - global.ActualSantaSpeed); + if (global.ActualSantaSpeed>3*SantaSpeed) + global.ActualSantaSpeed = 3*SantaSpeed; + else if (global.ActualSantaSpeed < -2*SantaSpeed) + global.ActualSantaSpeed = -2*SantaSpeed; + + SantaXr += dt*global.ActualSantaSpeed; + P("SantaXr: %ld global.SnowWinWidth: %d\n",lrint(SantaXr),global.SnowWinWidth); + if (SantaXr >= global.SnowWinWidth) { ResetSanta(); - oldx = SantaX; - oldy = SantaY; + oldx = global.SantaX; + oldy = global.SantaY; } - if (SantaXr < -SantaWidth-ActualSantaSpeed) SantaXr = -SantaWidth - ActualSantaSpeed; - SantaX = lrintf(SantaXr); + if (SantaXr < -global.SantaWidth-global.ActualSantaSpeed) + SantaXr = -global.SantaWidth - global.ActualSantaSpeed; + global.SantaX = lrintf(SantaXr); dtt += dt; - if (dtt > 0.1 && fabs(ActualSantaSpeed) > 3) + if (dtt > 0.1 && fabs(global.ActualSantaSpeed) > 3) { dtt = 0; CurrentSanta++; if (CurrentSanta >= PIXINANIMATION) CurrentSanta = 0; } - yspeed = ActualSantaSpeed/4; + yspeed = global.ActualSantaSpeed/4; sdt += dt; - if (sdt > 2.0) + if (sdt > 2.0*50.0/SantaSpeed || sdt > 2.0) { // time to change yspeed sdt = 0; yspeeddir = randint(3)-1; // -1, 0, 1 + if (SantaYr < santayrmin + 20) + yspeeddir = 2; + + if (SantaYr > santayrmax - 20) + yspeeddir = -2; + int mooncy = global.moonY+Flags.MoonSize/2; + if (Flags.ShowBirds && Flags.Moon && + global.SantaX+global.SantaWidth < global.moonX+Flags.MoonSize && + global.SantaX+global.SantaWidth > global.moonX-300) // Santa likes to hover the moon + { + int dy = global.SantaY+global.SantaHeight/2 - mooncy; + if (dy < 0) + yspeeddir = 1; + else + yspeeddir = -1; + if (dy < -global.moonR/2) // todo + yspeeddir = 3; + else if (dy > Flags.MoonSize/2) + yspeeddir = -3; + P("moon seeking %f %f %d %f\n",SantaYr, moonY, yspeeddir,SantaSpeed); + } } SantaYr += dt*yspeed*yspeeddir; - if (SantaYr < 0) + if (SantaYr < santayrmin) SantaYr = 0; - if (SantaYr > SnowWinHeight*0.33) - SantaYr = SnowWinHeight*0.33; + if (SantaYr > santayrmax) + SantaYr = santayrmax; - SantaY = lrintf(SantaYr); - XOffsetRegion(SantaRegion, SantaX - oldx, SantaY - oldy); - XOffsetRegion(SantaPlowRegion, SantaX - oldx, SantaY - oldy); + global.SantaY = lrintf(SantaYr); + XOffsetRegion(SantaRegion, global.SantaX - oldx, global.SantaY - oldy); + XOffsetRegion(global.SantaPlowRegion, global.SantaX - oldx, global.SantaY - oldy); RETURN; } void ResetSanta() { - SantaX = -SantaWidth - ActualSantaSpeed; - SantaXr = SantaX; - SantaY = randint(SnowWinHeight / 3)+40; - SantaYr = SantaY; + global.SantaX = -global.SantaWidth - global.ActualSantaSpeed; + SantaXr = global.SantaX; + global.SantaY = randint(global.SnowWinHeight / 3)+40; + if (Flags.Moon && Flags.ShowBirds && global.moonX < 400) + { + P("moon seeking at start\n"); + global.SantaY = randint(Flags.MoonSize + 40)+global.moonY-20; + } + else + global.SantaY = randint(global.SnowWinHeight / 3)+40; + SantaYr = global.SantaY; SantaYStep = 1; CurrentSanta = 0; - XDestroyRegion(SantaRegion); + SetSantaSizeSpeed(); +} + +void setSantaRegions() +{ + P("setSantaRegions %d %d %d %d\n",global.SantaX,global.SantaY,global.SantaWidth,global.SantaHeight); + if(SantaRegion) + XDestroyRegion(SantaRegion); SantaRegion = RegionCreateRectangle( - SantaX,SantaY,SantaHeight,SantaWidth); + global.SantaX,global.SantaY,global.SantaWidth,global.SantaHeight); - XDestroyRegion(SantaPlowRegion); - SantaPlowRegion = RegionCreateRectangle( - SantaX + SantaWidth, SantaY, 1, SantaHeight); + if(global.SantaPlowRegion) + XDestroyRegion(global.SantaPlowRegion); + global.SantaPlowRegion = RegionCreateRectangle( + global.SantaX + global.SantaWidth, global.SantaY, 1, global.SantaHeight); } Region RegionCreateRectangle(int x, int y, int w, int h) { XPoint p[5]; - p[0].x = x; p[0].y = y; + p[0].x = x; p[0].y = y; p[1].x = x+w; p[1].y = y; p[2].x = x+w; p[2].y = y+h; - p[3].x = x; p[3].y = y+h; - p[4].x = x; p[4].y = y; + p[3].x = x; p[3].y = y+h; + p[4].x = x; p[4].y = y; return XPolygonRegion(p, 5, EvenOddRule); } diff -Nru xsnow-3.1.1/src/Santa.h xsnow-3.3.2/src/Santa.h --- xsnow-3.1.1/src/Santa.h 2020-10-13 12:50:56.000000000 +0000 +++ xsnow-3.3.2/src/Santa.h 2021-11-04 14:24:27.000000000 +0000 @@ -1,9 +1,8 @@ -#pragma once /* -copyright- #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by @@ -19,17 +18,12 @@ #-# along with this program. If not, see . #-# */ -#include "xsnow.h" +#pragma once + +#include + extern int Santa_draw(cairo_t *cr); -extern void Santa_HandleCpuFactor(void); +extern void Santa_erase(cairo_t *cr); extern void Santa_init(void); -extern void Santa_set_gc(void); -extern int Santa_ui(void); - -extern float ActualSantaSpeed; -extern Region SantaPlowRegion; -extern int SantaHeight; -extern int SantaWidth; -extern int SantaX; -extern int SantaY; +extern void Santa_ui(void); diff -Nru xsnow-3.1.1/src/scenery.c xsnow-3.3.2/src/scenery.c --- xsnow-3.1.1/src/scenery.c 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/scenery.c 2021-11-04 14:24:28.000000000 +0000 @@ -2,7 +2,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by @@ -19,8 +19,14 @@ #-# */ +#define DEFAULTTREETYPE 2 + #define NOTACTIVE \ (Flags.BirdsOnly || !WorkspaceActive()) + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif #include #include #include @@ -36,122 +42,94 @@ #include "fallensnow.h" #include "csvpos.h" #include "treesnow.h" -#include "varia.h" - -static int do_drawtree(Treeinfo *tree); -static int do_initbaum(gpointer data); -static void ReInitTree0(void); -static void InitTreePixmaps(void); -static void RedrawTrees(void); -static void create_tree_surface(int tt,int flip, const char **xpm); -static int NtreeTypes = 0; -static int TreeRead = 0; -static char **TreeXpm = NULL; -static Pixmap TreePixmap[MAXTREETYPE+1][2]; -static Pixmap TreeMaskPixmap[MAXTREETYPE+1][2]; -static int TreeWidth[MAXTREETYPE+1], TreeHeight[MAXTREETYPE+1]; -static int *TreeType = NULL; -static int NTrees = 0; // actual number of trees -static GC TreeGC; -static Treeinfo **Trees = NULL; -Region TreeRegion; +static int do_initbaum(void *); +static void ReInitTree0(void); +static void InitTreePixmaps(void); +static void RedrawTrees(void); +static cairo_surface_t *tree_surface(int flip, const char **xpm, float scale); +static void create_tree_surfaces(void); +static void create_tree_dimensions(int tt); +static int compartrees(const void *a, const void *b); +static void setTreeScale(void); + +static int NtreeTypes = 0; +static int TreeRead = 0; +static char **TreeXpm = NULL; +static Pixmap TreePixmap[MAXTREETYPE+1][2]; +static Pixmap TreeMaskPixmap[MAXTREETYPE+1][2]; +static int TreeWidth[MAXTREETYPE+1], TreeHeight[MAXTREETYPE+1]; +static int *TreeType = NULL; +static int NTrees = 0; // actual number of trees +static int Newtrees = 1; // switch to determine if trees are to be repositioned +static Treeinfo **Trees = NULL; + +static float treeScale = 1.0; +static const float LocalScale = 0.7; // correction scale: if scenery is always too smnall, enlarge this and vice versa +static float MinScale = 0.6; // scale for items with low y-coordinate -static cairo_surface_t *tree_surfaces[MAXTREETYPE+1][2]; void scenery_init() { - TreeGC = XCreateGC(display, SnowWin, 0, NULL); - TreeRegion = XCreateRegion(); + P("treecolor: %s\n",Flags.TreeColor); + setTreeScale(); + P("treeScale: %f\n",treeScale); + //global.TreeRegion = XCreateRegion(); + global.TreeRegion = cairo_region_create(); InitTreePixmaps(); - add_to_mainloop(PRIORITY_DEFAULT, time_initbaum, (GSourceFunc)do_initbaum ,NULL); + add_to_mainloop(PRIORITY_DEFAULT, time_initbaum, do_initbaum); +} + +void setTreeScale() +{ + treeScale = LocalScale*0.01*Flags.Scale*global.WindowScale; } -void scenery_set_gc() +int compartrees(const void *a, const void *b) { - XSetFunction(display, TreeGC, GXcopy); - XSetForeground(display, TreeGC, BlackPix); - XSetFillStyle(display, TreeGC, FillStippled); + Treeinfo *ta = *(Treeinfo **)a; + Treeinfo *tb = *(Treeinfo **)b; + P("compartrees %d %d %d %d\n",ta->y, tb->y, ta->h, tb->h); + return ta->y + ta->h*ta->scale - tb->y - tb->h*tb->scale; } int scenery_draw(cairo_t *cr) { int i; - + if(Flags.NoTrees) + return TRUE; for (i=0; itype][tree->rev]; - cairo_set_source_surface (cr, surface, tree->x, tree->y); + P("scenery: %d\n",tree->y+tree->h); + cairo_set_source_surface (cr, tree->surface, tree->x, tree->y); my_cairo_paint_with_alpha(cr,ALPHA); } return TRUE; } -int scenery_ui() +void scenery_ui() { - int changes = 0; + UIDOS(TreeType , RedrawTrees();); + UIDO (DesiredNumberOfTrees , RedrawTrees();); + UIDO (TreeFill , RedrawTrees();); + UIDO (NoTrees , if(!global.IsDouble) RedrawTrees();); + UIDOS(TreeColor , ReInitTree0();); + UIDO (Overlap , RedrawTrees();); - if(strcmp(Flags.TreeType, OldFlags.TreeType)) + static int prev = 100; + if(ScaleChanged(&prev)) { - P("Treetype %s %s\n",Flags.TreeType,OldFlags.TreeType); + setTreeScale(); RedrawTrees(); - free(OldFlags.TreeType); - OldFlags.TreeType = strdup(Flags.TreeType); - changes++; - P("changes: %d\n",changes); - } - if(Flags.DesiredNumberOfTrees != OldFlags.DesiredNumberOfTrees) - { - RedrawTrees(); - OldFlags.DesiredNumberOfTrees = Flags.DesiredNumberOfTrees; - changes++; - P("NTREES: %d %d\n",OldFlags.DesiredNumberOfTrees,Flags.DesiredNumberOfTrees); - P("changes: %d\n",changes); - } - if(Flags.TreeFill != OldFlags.TreeFill) - { - RedrawTrees(); - OldFlags.TreeFill = Flags.TreeFill; - changes++; - P("changes: %d\n",changes); - } - if(Flags.NoTrees != OldFlags.NoTrees) - { - RedrawTrees(); - OldFlags.NoTrees = Flags.NoTrees; - changes++; - P("changes: %d\n",changes); - } - if(strcmp(Flags.TreeColor, OldFlags.TreeColor)) - { - P("%s %s\n",Flags.TreeColor,OldFlags.TreeColor); - ReInitTree0(); - free(OldFlags.TreeColor); - OldFlags.TreeColor = strdup(Flags.TreeColor); - changes++; - P("changes: %d\n",changes); } - return changes; } void RedrawTrees() { - // remove trees from timeout callbacks: - int i; - for (i=0; i 2) + global.RemoveFluff = 0; + + if (Flags.NoTrees || Newtrees == 0) return TRUE; + + Newtrees = 0; + int i,h,w; - XDestroyRegion(SnowOnTreesRegion); - cairo_region_destroy(gSnowOnTreesRegion); - XDestroyRegion(TreeRegion); - - SnowOnTreesRegion = XCreateRegion(); - gSnowOnTreesRegion = cairo_region_create(); - TreeRegion = XCreateRegion(); + for (i=0; i= Flags.DesiredNumberOfTrees) break; int tt = TreeType[randint(NtreeTypes)]; - h = TreeHeight[tt]; w = TreeWidth[tt]; + h = TreeHeight[tt]; - int y1 = SnowWinHeight - MaxScrSnowDepth - h; - int y2 = SnowWinHeight*(1.0 - 0.01*Flags.TreeFill); + int y1 = global.SnowWinHeight - global.MaxScrSnowDepth - h*treeScale; + int y2 = global.SnowWinHeight*(1.0 - 0.01*Flags.TreeFill); if (y2>y1) y1=y2+1; - int x = randint(SnowWinWidth-w); + int x = randint(global.SnowWinWidth-w*treeScale); int y = y1 - randint(y1-y2); - int in = XRectInRegion(TreeRegion,x,y,w,h); - if (in == RectangleIn || in == RectanglePart) - continue; + float myScale = (1-MinScale)*(y - y2)/(y1 - y2) + MinScale; + P("%d myScale: %d %d %d %f\n",global.counter++,y,y1,y2,myScale); + myScale *=treeScale; + cairo_rectangle_int_t grect = {x-1,y-1,myScale*w+2,myScale*h+2}; + cairo_region_overlap_t in = cairo_region_contains_rectangle(global.TreeRegion,&grect); + + // no overlap considerations if: + + if(!global.IsDouble || !Flags.Overlap) + if (in == CAIRO_REGION_OVERLAP_IN || in == CAIRO_REGION_OVERLAP_PART) + { + P("skiptree\n"); + continue; + } int flop = (drand48()>0.5); Treeinfo *tree = (Treeinfo *)malloc(sizeof(Treeinfo)); - tree->x = x; - tree->y = y; - tree->type = tt; - tree->rev = flop; + tree->x = x; + tree->y = y; + tree->w = w; + tree->h = h; + tree->type = tt; + tree->rev = flop; + tree->scale = myScale; + tree->surface = NULL; P("tree: %d %d %d %d %d %p\n",tree->x, tree->y, tree->type, tree->rev, NTrees,(void *)tree); - add_to_mainloop(PRIORITY_DEFAULT, time_tree, (GSourceFunc)do_drawtree, tree); - - Region r; + cairo_region_t *r; switch(tt) { case -SOMENUMBER: - r = regionfromxpm((const char **)TreeXpm,tree->rev); + r = gregionfromxpm((const char **)TreeXpm,tree->rev,tree->scale); break; default: - r = regionfromxpm(xpmtrees[tt],tree->rev); + r = gregionfromxpm(xpmtrees[tt],tree->rev,tree->scale); break; } - XOffsetRegion(r,x,y); - XUnionRegion(r,TreeRegion,TreeRegion); - XDestroyRegion(r); + cairo_region_translate(r,x,y); + cairo_region_union(global.TreeRegion,r); + cairo_region_destroy(r); NTrees++; Trees = (Treeinfo **)realloc(Trees,NTrees*sizeof(Treeinfo*)); Trees[NTrees-1] = tree; } - OnTrees = 0; + + // sort using y+h values of trees, so that higher trees are painted first + P("%d qsort: %d %ld\n",counter++,NTrees,sizeof(*Trees)); + qsort(Trees,NTrees,sizeof(*Trees),compartrees); + create_tree_surfaces(); + ReInitTree0(); + + global.OnTrees = 0; return TRUE; } +void create_tree_surfaces() +{ + int i; + for (i=0; isurface) + cairo_surface_destroy(tree->surface); + if(TreeRead) + tree->surface = tree_surface(tree->rev, (const char **)TreeXpm,tree->scale); + else + tree->surface = tree_surface(tree->rev, (const char **)xpmtrees[tree->type],tree->scale); + } +} + void InitTreePixmaps() { XpmAttributes attributes; attributes.valuemask = XpmDepth; - attributes.depth = SnowWinDepth; + attributes.depth = global.SnowWinDepth; char *path = NULL; FILE *f = HomeOpen("xsnow/pixmaps/tree.xpm","r",&path); if (f) @@ -346,11 +392,12 @@ int i; for(i=0; i<2; i++) { - iXpmCreatePixmapFromData(display, SnowWin, (const char **)TreeXpm, + iXpmCreatePixmapFromData(global.display, global.SnowWin, (const char **)TreeXpm, &TreePixmap[0][i], &TreeMaskPixmap[0][i], &attributes,i); - create_tree_surface(0,i,(const char **)TreeXpm); + create_tree_dimensions(0); } sscanf(*TreeXpm,"%d %d", &TreeWidth[0],&TreeHeight[0]); + P("treexpm %d %d\n",TreeWidth[0],TreeHeight[0]); printf("using external tree: %s\n",path); if (!Flags.NoMenu) printf("Disabling menu.\n"); @@ -371,17 +418,16 @@ int tt; for (tt=0; tt<=MAXTREETYPE; tt++) { - iXpmCreatePixmapFromData(display, SnowWin, xpmtrees[tt], + iXpmCreatePixmapFromData(global.display, global.SnowWin, xpmtrees[tt], &TreePixmap[tt][i],&TreeMaskPixmap[tt][i],&attributes,i); sscanf(xpmtrees[tt][0],"%d %d",&TreeWidth[tt],&TreeHeight[tt]); - create_tree_surface(tt,i,(const char **)xpmtrees[tt]); + create_tree_dimensions(tt); } } - ReInitTree0(); } if(path) free(path); - OnTrees = 0; + global.OnTrees = 0; } @@ -389,13 +435,13 @@ // apply TreeColor to xpmtree[0] and xpmtree[1] void ReInitTree0() { + P("Reinittree0 %s\n",Flags.TreeColor); XpmAttributes attributes; attributes.valuemask = XpmDepth; - attributes.depth = SnowWinDepth; + attributes.depth = global.SnowWinDepth; int i; int n = TreeHeight[0]+3; - //char *xpmtmp[n]; - char **xpmtmp = (char **)alloca(n*sizeof(char *)); + char **xpmtmp = (char **)malloc(n*sizeof(char *)); int j; for (j=0; j<2; j++) xpmtmp[j] = strdup(xpmtrees[0][j]); @@ -404,33 +450,26 @@ strcat(xpmtmp[2],Flags.TreeColor); for(j=3; jtype %d\n",tree->type); + if (tree->type == 0) + { + tree->surface = tree_surface(tree->rev,(const char **)xpmtmp,tree->scale); + } } + for (j=0; jx; int y = tree->y; int t = tree->type; int r = tree->rev; - P("t = %d %d\n",t,(int)wallclock()); - if (t<0) t=0; - XSetClipMask(display, TreeGC, TreeMaskPixmap[t][r]); - XSetClipOrigin(display, TreeGC, x, y); - XCopyArea(display, TreePixmap[t][r], SnowWin, TreeGC, - 0,0,TreeWidth[t],TreeHeight[t], x, y); - return TRUE; -} diff -Nru xsnow-3.1.1/src/scenery.h xsnow-3.3.2/src/scenery.h --- xsnow-3.1.1/src/scenery.h 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/scenery.h 2021-11-04 14:24:28.000000000 +0000 @@ -1,9 +1,8 @@ -#pragma once /* -copyright- #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by @@ -19,28 +18,12 @@ #-# along with this program. If not, see . #-# */ +#pragma once -#include "xsnow.h" #include -typedef struct Treeinfo { - int x; // x position - int y; // y position -#ifdef NO_USE_BITS - unsigned int type ; // type (TreeType, -treetype) - unsigned int rev ; // reversed -#else - unsigned int type: 8; // type (TreeType, -treetype) - unsigned int rev : 1; // reversed -#endif -} Treeinfo; - extern void scenery_init(void); -extern int scenery_ui(void); -extern void EraseTrees(void); -extern void scenery_set_gc(void); -extern int scenery_draw(cairo_t *cr); - -extern int KillTrees; // 1: signal to trees to kill themselves -extern Region TreeRegion; +extern void scenery_ui(void); +extern void EraseTrees(void); +extern int scenery_draw(cairo_t *cr); diff -Nru xsnow-3.1.1/src/snow.c xsnow-3.3.2/src/snow.c --- xsnow-3.1.1/src/snow.c 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/snow.c 2021-11-04 14:24:28.000000000 +0000 @@ -2,7 +2,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by @@ -23,6 +23,7 @@ #include #include #include +#include #include "debug.h" #include "xsnow.h" #include "pixmaps.h" @@ -39,53 +40,46 @@ #include "ui.h" #include "blowoff.h" #include "treesnow.h" -#include "varia.h" #define NOTACTIVE \ (Flags.BirdsOnly || !WorkspaceActive() || Flags.NoSnowFlakes) #define EXTRA_FLAKES 300 -static cairo_surface_t **snow_surfaces; -static float FlakesPerSecond; -static int KillFlakes = 0; // 1: signal to flakes to kill themselves, and do not generate flakes -static float SnowSpeedFactor; -static GC *ESnowGC; -static GC *SnowGC; - -static SnowMap *snowPix; -static char ***xsnow_xpm = NULL; -static int NFlakeTypesVintage; -static int MaxFlakeTypes; - -static int do_genflakes(gpointer data); -static void InitFlake(Snow *flake); -static void InitFlakesPerSecond(void); -static void InitSnowColor(void); -static void InitSnowSpeedFactor(void); -static int do_show_flakecount(gpointer data); -static void init_snow_surfaces(void); -static void init_snow_pix(void); -static void EraseSnowFlake(Snow *flake); -static void DelFlake(Snow *flake); -static void DrawSnowFlake(Snow *flake); -static void genxpmflake(char ***xpm, int w, int h); -static void add_random_flakes(int n); - - -Region NoSnowArea_dynamic; -Pixel SnowcPix; -unsigned int MaxSnowFlakeHeight = 0; /* Highest flake */ -unsigned int MaxSnowFlakeWidth = 0; /* Widest flake */ -int FlakeCount = 0; /* # active flakes */ -int UseVintageFlakes = 0; /* whether to use only vintage flakes */ -int FluffCount = 0; +#define add_flake_to_mainloop(f) add_to_mainloop1(PRIORITY_HIGH,time_snowflakes,(GSourceFunc)do_UpdateSnowFlake,f) + +//static cairo_surface_t **snow_surfaces; +static float FlakesPerSecond; +static int KillFlakes = 0; // 1: signal to flakes to kill themselves, and do not generate flakes +static float SnowSpeedFactor; + +static SnowMap *snowPix; +static char ***xsnow_xpm = NULL; +static int NFlakeTypesVintage; +static int MaxFlakeTypes; + +static int do_genflakes(void *); +static void InitFlake(Snow *flake); +static void InitFlakesPerSecond(void); +static void InitSnowColor(void); +static void InitSnowSpeedFactor(void); +static int do_show_flakecount(void *); +static void init_snow_pix(void); +static void EraseSnowFlake1(Snow *flake); +static void DelFlake(Snow *flake); +static void genxpmflake(char ***xpm, int w, int h); +static void add_random_flakes(int n); +static void SetSnowSize(void); +static int do_UpdateSnowFlake(Snow *flake); +static int do_SwitchFlakes(void *); + +static const float LocalScale = 0.8; + void snow_init() { int i; - MaxFlakeTypes = 0; while(snow_xpm[MaxFlakeTypes]) MaxFlakeTypes++; @@ -97,30 +91,24 @@ snowPix = (SnowMap *)malloc(MaxFlakeTypes*sizeof(SnowMap)); - snow_surfaces = (cairo_surface_t **)malloc(MaxFlakeTypes*sizeof(cairo_surface_t*)); - ESnowGC = (GC *)malloc(MaxFlakeTypes*sizeof(GC)); - SnowGC = (GC *)malloc(MaxFlakeTypes*sizeof(GC)); P("MaxFlakeTypes: %d\n",MaxFlakeTypes); for (i=0; iwidth = w; rp->height = h; - if(rp->pixmap) - XFreePixmap(display,rp->pixmap); - /* - * running under valgrind: XCreateBitmapFromData() often gives - * Syscall param writev(vector[...]) points to uninitialised byte(s) - * and - * Address 0xc60f5b1 is 1 bytes inside a block of size 36 alloc'd - * at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so) - * by 0x581C3FC: _XAllocScratch (in /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0) - * by 0x580E30A: ??? (in /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0) - * by 0x580EAAD: XPutImage (in /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0) - * by 0x57F715B: XCreateBitmapFromData (in /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0) - * - * bits is initialised, I tested that. So, I guess there is - * something not cosher in XCreateBitmapFromData() maybe.... - */ - rp->pixmap = XCreateBitmapFromData(display, SnowWin, - (const char*)bits, rp->width, rp->height); - if (rp->height > MaxSnowFlakeHeight) MaxSnowFlakeHeight = rp->height; - if (rp->width > MaxSnowFlakeWidth ) MaxSnowFlakeWidth = rp->width; - free(bits); + char **x; + int lines; + xpm_set_color(xsnow_xpm[flake], &x, &lines, Flags.SnowColor); + GdkPixbuf *pixbuf = gdk_pixbuf_new_from_xpm_data((const char **)x); + if (w<1) w=1; + if (h<1) h=1; + if (w == 1 && h == 1) h = 2; + GdkPixbuf *pixbufscaled = gdk_pixbuf_scale_simple(pixbuf,w,h,GDK_INTERP_HYPER); + xpm_destroy(x); + if (rp->surface) + cairo_surface_destroy(rp->surface); + rp->surface = gdk_cairo_surface_create_from_pixbuf (pixbufscaled, 0, NULL); + g_clear_object(&pixbuf); + g_clear_object(&pixbufscaled); } } @@ -280,27 +184,45 @@ { if (Flags.NoSnowFlakes) return TRUE; + P("snow_draw %d\n",counter++); set_begin(); Snow *flake; while( (flake = (Snow *)set_next()) ) { P("snow_draw %d %f\n",counter++,ALPHA); - cairo_set_source_surface (cr, snow_surfaces[flake->whatFlake], flake->rx, flake->ry); + //cairo_set_source_surface (cr, snow_surfaces[flake->whatFlake], flake->rx, flake->ry); + cairo_set_source_surface (cr, snowPix[flake->whatFlake].surface, flake->rx, flake->ry); double alpha = ALPHA; if (flake->fluff) - //alpha *= flake->flufftimer>0?flake->flufftimer/FLUFFTIME:0; alpha *= (1-flake->flufftimer/flake->flufftime); if (alpha < 0) alpha = 0; - my_cairo_paint_with_alpha(cr,alpha); - //if (flake->testing) P("testing flake: alpha: %f\n",alpha); - //if (flake->whatFlake == 2) P("%d %d %d %f %f %f %f %f %f\n",counter++,flake->fluff,flake->freeze,flake->rx, flake->ry, flake->flufftimer, flake->flufftime,flake->vx, flake->vy); + if (global.IsDouble || !(flake->freeze || flake->fluff)) + my_cairo_paint_with_alpha(cr,alpha); + flake->ix = lrint(flake->rx); + flake->iy = lrint(flake->ry); + } + return TRUE; +} + +int snow_erase(int force) +{ + if (!force && Flags.NoSnowFlakes) + return TRUE; + set_begin(); + Snow *flake; + int n = 0; + while( (flake = (Snow *)set_next()) ) + { + EraseSnowFlake1(flake); + n++; } + P("snow_erase %d %d\n",counter++,n); return TRUE; } -int do_genflakes(UNUSED gpointer data) +int do_genflakes(void *d) { if (Flags.Done) return FALSE; @@ -331,7 +253,7 @@ if (dt < 0 || dt > 10*time_genflakes) RETURN; int desflakes = lrint((dt+sumdt)*FlakesPerSecond); - P("desflakes: %lf %lf %d %lf %d\n",dt,sumdt,desflakes,FlakesPerSecond,FlakeCount); + P("desflakes: %lf %lf %d %lf %d\n",dt,sumdt,desflakes,FlakesPerSecond,global.FlakeCount); if(desflakes == 0) // save dt for use next time: happens with low snowfall rate sumdt += dt; else @@ -343,6 +265,7 @@ MakeFlake(-1); } RETURN; + (void)d; #undef RETURN } @@ -351,22 +274,28 @@ if(NOTACTIVE) return TRUE; //P(" ");printflake(flake); - + + if ((flake->freeze || flake->fluff) && global.RemoveFluff) + { + P("removefluff\n"); + DelFlake(flake); + EraseSnowFlake1(flake); + return FALSE; + } double FlakesDT = time_snowflakes; float NewX = flake->rx + (flake->vx*FlakesDT)*SnowSpeedFactor; float NewY = flake->ry + (flake->vy*FlakesDT)*SnowSpeedFactor; // handle fluff and KillFlakes - //if (flake->testing == 2)P("%d hoppa %d %f\n",counter++,flake->fluff,flake->flufftimer); if (KillFlakes || (flake->fluff && flake->flufftimer > flake->flufftime)) { - EraseSnowFlake(flake); DelFlake(flake); + EraseSnowFlake1(flake); return FALSE; } if (flake->fluff) { - if (switches.UseGtk && !flake->freeze) + if (!flake->freeze) { flake->rx = NewX; flake->ry = NewY; @@ -375,18 +304,12 @@ return TRUE; } - int fckill = FlakeCount - FluffCount >= Flags.FlakeCountMax; + int fckill = global.FlakeCount - global.FluffCount >= Flags.FlakeCountMax; if ( (fckill && !flake->cyclic && drand48() > 0.3) || // high probability to remove blown-off flake (fckill && drand48() > 0.9) // low probability to remove other flakes ) { - //if (flake->fluff)P("%d hoppa %d %d %f\n",counter++,flake->fluff,flake->whatFlake,flake->flufftimer); - /* - EraseSnowFlake(flake); - DelFlake(flake); - return FALSE; - */ fluffify(flake,0.51); return TRUE; } @@ -396,9 +319,9 @@ // if (!Flags.NoWind) { - flake->vx += FlakesDT*flake->wsens*(NewWind - flake->vx)/flake->m; + flake->vx += FlakesDT*flake->wsens*(global.NewWind - flake->vx)/flake->m; static float speedxmaxes[] = {100.0, 300.0, 600.0,}; - float speedxmax = speedxmaxes[Wind]; + float speedxmax = speedxmaxes[global.Wind]; if(flake->vx > speedxmax) flake->vx = speedxmax; if(flake->vx < -speedxmax) flake->vx = -speedxmax; } @@ -406,11 +329,8 @@ flake->vy += INITIALYSPEED * (drand48()-0.4)*0.1 ; if (flake->vy > flake->ivy*1.5) flake->vy = flake->ivy*1.5; - - if (flake->freeze) { - DrawSnowFlake(flake); return TRUE; } @@ -419,21 +339,19 @@ if(flake->cyclic) { - if (NewX < -flakew) NewX += SnowWinWidth-1; - if (NewX >= SnowWinWidth) NewX -= SnowWinWidth; + if (NewX < -flakew) NewX += global.SnowWinWidth-1; + if (NewX >= global.SnowWinWidth) NewX -= global.SnowWinWidth; } - else if (NewX < 0 || NewX >= SnowWinWidth) + else if (NewX < 0 || NewX >= global.SnowWinWidth) { // not-cyclic flakes die when going left or right out of the window - EraseSnowFlake(flake); DelFlake(flake); return FALSE; } // remove flake if it falls below bottom of screen: - if (NewY >= SnowWinHeight) + if (NewY >= global.SnowWinHeight) { - EraseSnowFlake(flake); DelFlake(flake); return FALSE; } @@ -448,13 +366,13 @@ // the bottom pixels of the snowflake are at y = NewY + (height of flake) // the bottompixels are at x values NewX .. NewX+(width of flake)-1 - FallenSnow *fsnow = FsnowFirst; + FallenSnow *fsnow = global.FsnowFirst; int found = 0; // investigate if flake is in a not-hidden fallensnowarea on current workspace while(fsnow && !found) { if(!fsnow->win.hidden) - if(fsnow->win.id == 0 ||(fsnow->win.ws == CWorkSpace || fsnow->win.sticky)) + if(fsnow->win.id == 0 ||(fsnow->win.ws == global.CWorkSpace || fsnow->win.sticky)) { if (nx >= fsnow->x && nx <= fsnow->x + fsnow->w && ny < fsnow->y+2) @@ -474,14 +392,14 @@ // always erase flake, but repaint it on top of // the correct position on fsnow (if !NoFluffy)) if (Flags.NoFluffy) - EraseSnowFlake(flake); // flake is removed from screen, but still available + { + } else { // x-value: NewX; // y-value of top of fallen snow: fsnow->y - fsnow->acth[i] - flake->rx = NewX; - flake->ry = fsnow->y - fsnow->acth[i] - 0.8*drand48()*flakeh; - DrawSnowFlake(flake); + //flake->rx = NewX; + //flake->ry = fsnow->y - 0.5*fsnow->acth[i] - 0.8*drand48()*flakeh ; fluffify(flake,0.1); } if (flake->fluff) @@ -504,24 +422,17 @@ int x = lrintf(flake->rx); int y = lrintf(flake->ry); - // check if flake is in nowsnowarea - if (!switches.UseGtk) // we can skip this when using gtk - { - int in = XRectInRegion(NoSnowArea_dynamic,x, y, flakew, flakeh); - int b = (in == RectangleIn || in == RectanglePart); // true if in nosnowarea_dynamic - // - // if (b): no erase, no draw, no move - if(b) - return TRUE; - } - - if(Wind !=2 && !Flags.NoKeepSnowOnTrees && !Flags.NoTrees) + if(global.Wind !=2 && !Flags.NoKeepSnowOnTrees && !Flags.NoTrees) { - // check if flake is touching or in SnowOnTreesRegion + // check if flake is touching or in gSnowOnTreesRegion // if so: remove it - int in = XRectInRegion(SnowOnTreesRegion,x,y,flakew,flakeh); - if (in == RectanglePart || in == RectangleIn) + + cairo_rectangle_int_t grec = {x,y,flakew,flakeh}; + cairo_region_overlap_t in = cairo_region_contains_rectangle(global.gSnowOnTreesRegion,&grec); + + if (in == CAIRO_REGION_OVERLAP_PART || in == CAIRO_REGION_OVERLAP_IN) { + P("part or in\n"); if (Flags.NoFluffy) { DelFlake(flake); @@ -531,15 +442,15 @@ { fluffify(flake,0.4); flake->freeze=1; - DrawSnowFlake(flake); return TRUE; } } // check if flake is touching TreeRegion. If so: add snow to - // SnowOnTreesRegion. - in = XRectInRegion(TreeRegion,x,y,flakew,flakeh); - if (in == RectanglePart) + // gSnowOnTreesRegion. + cairo_rectangle_int_t grect = {x,y,flakew,flakeh}; + in = cairo_region_contains_rectangle(global.TreeRegion,&grect); + if (in == CAIRO_REGION_OVERLAP_PART) { // so, part of the flake is in TreeRegion. // For each bottom pixel of the flake: @@ -556,41 +467,41 @@ if(found) break; int ybot = y+flakeh; int xbot = x+i; - int in = XRectInRegion(TreeRegion,xbot,ybot,1,1); - if (in != RectangleIn) // if bottom pixel not in TreeRegion, skip + //int in = XRectInRegion(global.TreeRegion,xbot,ybot,1,1); + cairo_rectangle_int_t grect = {xbot,ybot,1,1}; + cairo_region_overlap_t in = cairo_region_contains_rectangle(global.TreeRegion,&grect); + //if (in != RectangleIn) // if bottom pixel not in TreeRegion, skip + if (in != CAIRO_REGION_OVERLAP_IN) // if bottom pixel not in TreeRegion, skip continue; // move upwards, until pixel is not in TreeRegion int j; for (j=ybot-1; j >= y; j--) { - int in = XRectInRegion(TreeRegion,xbot,j,1,1); - if (in != RectangleIn) + //int in = XRectInRegion(global.TreeRegion,xbot,j,1,1); + cairo_rectangle_int_t grect = {xbot,j,1,1}; + cairo_region_overlap_t in = cairo_region_contains_rectangle(global.TreeRegion,&grect); + //if (in != RectangleIn) + if (in != CAIRO_REGION_OVERLAP_IN) { // pixel (xbot,j) is snow-on-tree found = 1; - XRectangle rec; - rec.x = xbot; - int p = 1+drand48()*3; - rec.y = j-p+1; - rec.width = p; - rec.height = p; - XUnionRectWithRegion(&rec, SnowOnTreesRegion, SnowOnTreesRegion); cairo_rectangle_int_t grec; - grec.x = rec.x; - grec.y = rec.y; - grec.width = rec.width; - grec.height = rec.height; - cairo_region_union_rectangle(gSnowOnTreesRegion,&grec); + grec.x = xbot; + int p = 1+drand48()*3; + grec.y = j-p+1; + grec.width = p; + grec.height = p; + cairo_region_union_rectangle(global.gSnowOnTreesRegion,&grec); - if(!Flags.NoBlowSnow && OnTrees < Flags.MaxOnTrees) + if(Flags.BlowSnow && global.OnTrees < Flags.MaxOnTrees) { - SnowOnTrees[OnTrees].x = rec.x; - SnowOnTrees[OnTrees].y = rec.y; - OnTrees++; - //P("%d %d %d\n",OnTrees,rec.x,rec.y); + global.SnowOnTrees[global.OnTrees].x = grec.x; + global.SnowOnTrees[global.OnTrees].y = grec.y; + global.OnTrees++; + //P("%d %d %d\n",global.OnTrees,rec.x,rec.y); } - xfound = rec.x; - yfound = rec.y; + xfound = grec.x; + yfound = grec.y; break; } } @@ -600,46 +511,23 @@ { flake->freeze = 1; fluffify(flake,0.6); - DrawSnowFlake(flake); - Snow *newflake = MakeFlake(1); + Snow *newflake; + if(Flags.VintageFlakes) + newflake = MakeFlake(0); + else + newflake = MakeFlake(-1); newflake->freeze = 1; newflake->rx = xfound; newflake->ry = yfound-snowPix[1].height*0.3f; fluffify(newflake,8); - DrawSnowFlake(newflake); return TRUE; } } } - // prevent snow erase on a tree - // we can skip this when using gtk - if (!switches.UseGtk) - { - int in = XRectInRegion(TreeRegion,x, y, flakew, flakeh); - int b = (in == RectangleIn || in == RectanglePart); // true if in TreeRegion - // if(b): erase: no, move: yes - // erase this flake - if(!b) - { - EraseSnowFlake(flake); - } - } flake->rx = NewX; flake->ry = NewY; - // prevent drawing a flake on a tree - // we can skip this when using gtk - if (!switches.UseGtk) - { - int in = XRectInRegion(TreeRegion,nx, ny, flakew, flakeh); - int b = (in == RectangleIn || in == RectanglePart); // true if in TreeRegion - // if b: draw: no - if (!b) - { - DrawSnowFlake(flake); - } - } return TRUE; } @@ -648,41 +536,34 @@ Snow *MakeFlake(int type) { Snow *flake = (Snow *)malloc(sizeof(Snow)); - FlakeCount++; + global.FlakeCount++; if (type < 0) { - if (UseVintageFlakes) + if (Flags.VintageFlakes) type = drand48()*NFlakeTypesVintage; else type = NFlakeTypesVintage + drand48()*(MaxFlakeTypes - NFlakeTypesVintage); } - //if(type > 0 && type <7)P("type: %d\n",type); flake -> whatFlake = type; InitFlake(flake); add_flake_to_mainloop(flake); return flake; } -void EraseSnowFlake(Snow *flake) + +void EraseSnowFlake1(Snow *flake) { - if(switches.UseGtk || Flags.NoSnowFlakes) + P("Erasesnowflake1\n"); + if(global.IsDouble) return; - int x = lrintf(flake->rx); - int y = lrintf(flake->ry); - int flakew = snowPix[flake->whatFlake].width; - int flakeh = snowPix[flake->whatFlake].height; - if(switches.Trans|Flags.UseBG) - { - XSetTSOrigin(display, ESnowGC[flake->whatFlake], - x + flakew, y + flakeh); - XFillRectangle(display, SnowWin, ESnowGC[flake->whatFlake], - x, y, flakew, flakeh); - } - else - XClearArea(display, SnowWin, - x, y, - flakew, flakeh, - switches.Exposures); + int x = flake->ix-1; + int y = flake->iy-1; + int flakew = snowPix[flake->whatFlake].width+2; + int flakeh = snowPix[flake->whatFlake].height+2; + myXClearArea(global.display, global.SnowWin, + x, y, + flakew, flakeh, + global.xxposures); } // a call to this function must be followed by 'return FALSE' to remove this @@ -690,35 +571,18 @@ void DelFlake(Snow *flake) { if (flake->fluff) - FluffCount--; + global.FluffCount--; set_erase(flake); free(flake); - FlakeCount--; -} - - -void DrawSnowFlake(Snow *flake) // draw snowflake using flake->rx and flake->ry -{ - if(Flags.NoSnowFlakes) return; - if (switches.UseGtk) - return; // will be picked up by snow_draw() - P("DrawSnowFlake X11 %d\n",counter++); - int x = lrintf(flake->rx); - int y = lrintf(flake->ry); - int flakew = snowPix[flake->whatFlake].width; - int flakeh = snowPix[flake->whatFlake].height; - XSetTSOrigin(display, SnowGC[flake->whatFlake], - x + flakew, y + flakeh); - XFillRectangle(display, SnowWin, SnowGC[flake->whatFlake], - x, y, flakew, flakeh); + global.FlakeCount--; } void InitFlake(Snow *flake) { int flakew = snowPix[flake->whatFlake].width; int flakeh = snowPix[flake->whatFlake].height; - flake->rx = randint(SnowWinWidth - flakew); - flake->ry = -randint(SnowWinHeight/10)-flakeh; + flake->rx = randint(global.SnowWinWidth - flakew); + flake->ry = -randint(global.SnowWinHeight/10)-flakeh; flake->cyclic = 1; flake->fluff = 0; flake->flufftimer = 0; @@ -727,7 +591,7 @@ if(Flags.NoWind) flake->vx = 0; else - flake->vx = randint(NewWind)/2; + flake->vx = randint(global.NewWind)/2; flake->ivy = INITIALYSPEED * sqrt(flake->m); flake->vy = flake->ivy; flake->wsens = drand48()*MAXWSENS; @@ -735,23 +599,18 @@ flake->freeze = 0; set_insert(flake); // will be picked up by snow_draw() P("wsens: %f\n",flake->wsens); - //P("%f %f\n",flake->rx, flake->ry); } void InitFlakesPerSecond() { - FlakesPerSecond = SnowWinWidth*0.0015*Flags.SnowFlakesFactor* + FlakesPerSecond = global.SnowWinWidth*0.0015*Flags.SnowFlakesFactor* 0.001*FLAKES_PER_SEC_PER_PIXEL*SnowSpeedFactor; P("snowflakesfactor: %d %f %f\n",Flags.SnowFlakesFactor,FlakesPerSecond,SnowSpeedFactor); } void InitSnowColor() { - int i; - SnowcPix = IAllocNamedColor(Flags.SnowColor, White); - for (i=0; i 0) + if (global.FlakeCount > 0) return TRUE; // signal that flakes may be generated KillFlakes = 0; return FALSE; // stop callback + (void)d; } -int do_show_flakecount(UNUSED gpointer data) +int do_show_flakecount(void *d) { if (Flags.Done) return FALSE; if (!Flags.NoMenu) - ui_show_nflakes(FlakeCount); + ui_show_nflakes(global.FlakeCount); return TRUE; + (void)d; } // generate random xpm for flake with dimensions wxh @@ -891,6 +752,7 @@ if (nw == 1 && nh == 1) nh = 2; + assert(nh>0); P("allocating %d\n",(nh+3)*sizeof(char*)); *xpm = (char **)malloc((nh+3)*sizeof(char*)); @@ -905,6 +767,7 @@ int offset = 3; P("allocating %d\n",nw+1); + assert(nw>=0); for (i=0; iflufftime = t; else flake->flufftime = 0.01; - FluffCount ++; + global.FluffCount ++; +} + +int do_SwitchFlakes(void *d) +{ + (void)d; + static int prev = 0; + if (Flags.VintageFlakes != prev) + { + P("SwitchFlakes\n"); + set_begin(); + Snow *flake; + while( (flake = (Snow *)set_next()) ) + { + if (Flags.VintageFlakes) + { + flake->whatFlake = drand48()*NFlakeTypesVintage; + } + else + { + flake->whatFlake = NFlakeTypesVintage + drand48()*(MaxFlakeTypes - NFlakeTypesVintage); + } + } + prev = Flags.VintageFlakes; + } + return TRUE; } void printflake(Snow *flake) diff -Nru xsnow-3.1.1/src/snow.h xsnow-3.3.2/src/snow.h --- xsnow-3.1.1/src/snow.h 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/snow.h 2021-11-04 14:24:28.000000000 +0000 @@ -2,7 +2,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by @@ -20,62 +20,15 @@ */ #pragma once -#define add_flake_to_mainloop(f) add_to_mainloop(PRIORITY_HIGH,time_snowflakes,(GSourceFunc)do_UpdateSnowFlake,f) - #include -#include - -extern int UseVintageFlakes; // whether to use the not-generated flakes - -typedef struct _Snow { - float rx; // x position - float ry; // y position - float vx; // speed in x-direction, pixels/second - float vy; // speed in y-direction, pixels/second - float m; // mass of flake - float ivy; // initial speed in y direction - float wsens; // wind dependency factor - float flufftimer; // fluff timeout timer - float flufftime; // fluff timeout - unsigned int whatFlake; // snowflake index -#ifdef NO_USE_BITS - unsigned int cyclic ; // flake is cyclic - unsigned int fluff ; // flake is in fluff state - unsigned int freeze ; // flake does not move - unsigned int testing ; // for testing purposes -#else - unsigned int cyclic : 1; // flake is cyclic - unsigned int fluff : 1; // flake is in fluff state - unsigned int freeze : 1; // flake does not move - unsigned int testing : 2; // for testing purposes -#endif - -} Snow; +#include "xsnow.h" -typedef struct _SnowMap { - Pixmap pixmap; -#ifdef NO_USE_BITS - unsigned int width ; - unsigned int height ; -#else - unsigned int width : 16; - unsigned int height : 16; -#endif -} SnowMap; - -extern Region NoSnowArea_dynamic; -extern Pixel SnowcPix; -extern unsigned int MaxSnowFlakeHeight; /* Biggest flake */ -extern unsigned int MaxSnowFlakeWidth; /* Biggest flake */ -extern int FlakeCount; /* number of flakes */ -extern int FluffCount; /* number of fluff flakes */ - -extern int do_initsnow(gpointer data); -extern int do_UpdateSnowFlake(Snow *flake); +extern int do_initsnow(void *); extern Snow *MakeFlake(int type); extern int snow_draw(cairo_t *cr); extern void snow_init(void); -extern void snow_set_gc(void); -extern int snow_ui(); +extern void snow_ui(void); extern void fluffify(Snow *flake, float t); extern void printflake(Snow *flake); +extern int snow_erase(int force); + diff -Nru xsnow-3.1.1/src/snow_includes.h xsnow-3.3.2/src/snow_includes.h --- xsnow-3.1.1/src/snow_includes.h 2020-10-13 14:45:49.000000000 +0000 +++ xsnow-3.3.2/src/snow_includes.h 2021-11-04 14:24:36.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/stars.c xsnow-3.3.2/src/stars.c --- xsnow-3.1.1/src/stars.c 2020-10-13 12:50:56.000000000 +0000 +++ xsnow-3.3.2/src/stars.c 2021-11-04 14:24:27.000000000 +0000 @@ -2,7 +2,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by @@ -28,7 +28,6 @@ #include "windows.h" #include "pixmaps.h" #include "utils.h" -#include "varia.h" #define NOTACTIVE \ (Flags.BirdsOnly || !WorkspaceActive()) @@ -36,13 +35,14 @@ static int NStars; // is copied from Flags.NStars in init_stars. We cannot have that // // NStars is changed outside init_stars -static Pixel StarcPix[STARANIMATIONS]; -static GC StarGC[STARANIMATIONS]; static Skoordinaten *Stars = NULL; static char *StarColor[STARANIMATIONS] = { (char *)"gold", (char *)"gold1", (char *)"gold4", (char *)"orange" }; -static int do_stars(gpointer data); -static int do_ustars(gpointer data); +static int do_ustars(void *); +static void set_star_surfaces(void); + +static const int StarSize = 9; +static const float LocalScale = 0.8; static cairo_surface_t *surfaces[STARANIMATIONS]; @@ -50,39 +50,40 @@ { int i; init_stars(); - { - for(i=0; ix = randint(SnowWinWidth); - star->y = randint(SnowWinHeight/4); + star->x = randint(global.SnowWinWidth); + star->y = randint(global.SnowWinHeight/4); star->color = randint(STARANIMATIONS); P("stars_init %d %d %d\n",star->x,star->y,star->color); } + //set_star_surfaces(); } void stars_draw(cairo_t *cr) { + if (!Flags.Stars) + return; int i; cairo_save(cr); cairo_set_line_width(cr,1); @@ -121,48 +126,38 @@ cairo_restore(cr); } -int stars_ui() +void stars_erase() { - int changes = 0; - if(Flags.NStars != OldFlags.NStars) - { - P("changes NStars: %d %d %d\n",changes,OldFlags.NStars,Flags.NStars); - OldFlags.NStars = Flags.NStars; - init_stars(); - ClearScreen(); - changes++; - } - return changes; -} - - -int do_stars(UNUSED gpointer data) -{ - if (Flags.Done) - return FALSE; - if (NOTACTIVE) - return TRUE; - if (switches.UseGtk) - return TRUE; - P("do_stars %d %d\n",NStars,counter++); + if (!Flags.Stars) + return; int i; for (i=0; ix; int y = star->y; - int k = star->color; - int w = starPix.width; - int h = starPix.height; - P("dostars %d %d %d %d %d %d\n",NStars,x,y,k,w,h); - XSetTSOrigin(display, StarGC[k],x+w, y+h); - XFillRectangle(display,SnowWin,StarGC[k],x,y,w,h); + myXClearArea(global.display,global.SnowWin,x,y,StarSize,StarSize,global.xxposures); + } +} + +void stars_ui() +{ + UIDO(NStars, init_stars(); ClearScreen();); + UIDO(Stars, ClearScreen();); + + static int prev = 100; + P("stars_ui %d\n",prev); + if(ScaleChanged(&prev)) + { + set_star_surfaces(); + init_stars(); + P("stars_ui changed\n"); } - XFlush(display); - return TRUE; } -int do_ustars(UNUSED gpointer data) + +int do_ustars(void *d) { if (Flags.Done) return FALSE; @@ -173,17 +168,6 @@ if (drand48() > 0.8) Stars[i].color = randint(STARANIMATIONS); return TRUE; -} - -void stars_set_gc() -{ - int i; - for (i=0; i +#include #define STARANIMATIONS 4 -typedef struct _StarMap { - unsigned char *starBits; - Pixmap pixmap; - int width; - int height; -} StarMap; - -typedef struct _Skoordinaten { - int x; - int y; - int color; -} Skoordinaten; - -extern void init_stars(void); -extern void stars_draw(cairo_t *cr); -extern void stars_init(void); -extern void stars_set_gc(void); -extern int stars_ui(void); +extern void init_stars(void); +extern void stars_draw(cairo_t *cr); +extern void stars_erase(void); +extern void stars_init(void); +extern void stars_ui(void); diff -Nru xsnow-3.1.1/src/test1.sh xsnow-3.3.2/src/test1.sh --- xsnow-3.1.1/src/test1.sh 2020-10-13 12:50:56.000000000 +0000 +++ xsnow-3.3.2/src/test1.sh 2021-11-04 14:24:27.000000000 +0000 @@ -3,7 +3,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by diff -Nru xsnow-3.1.1/src/test2.sh xsnow-3.3.2/src/test2.sh --- xsnow-3.1.1/src/test2.sh 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/test2.sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,55 +0,0 @@ -#!/bin/sh -# -copyright- -#-# -#-# xsnow: let it snow on your desktop -#-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin -#-# -#-# This program is free software: you can redistribute it and/or modify -#-# it under the terms of the GNU General Public License as published by -#-# the Free Software Foundation, either version 3 of the License, or -#-# (at your option) any later version. -#-# -#-# This program is distributed in the hope that it will be useful, -#-# but WITHOUT ANY WARRANTY; without even the implied warranty of -#-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -#-# GNU General Public License for more details. -#-# -#-# You should have received a copy of the GNU General Public License -#-# along with this program. If not, see . -#-# - -XSNOW=xsnow -if [ -x ./xsnow ]; then - XSNOW=./xsnow -fi -logfile=xsnow_out_2 ->$logfile -# open Santa tab, click on train with Rudolph -xdo="xdotool mousemove --sync 200 50 click 1 mousemove --sync 470 320 click 1" -# testing without a compositing X window manager -xvfb-run -a -s "-screen 0 1920x1080x24" sh -c "$XSNOW -defaults -noisy -stopafter 5 >$logfile 2>&1& sleep 2; $xdo; sleep 8" -if [ "$?" -ne 0 ] ; then - echo "Problem in 'xvfb-run' command" 1>&2 - cat $logfile 1>&2 - exit 1 -fi -grep -q "Halting because of flag -stopafter" $logfile -if [ "$?" -ne 0 ] ; then - echo "xsnow did not end as expected" 1>&2 - cat $logfile 1>&2 - exit 1 -fi -grep -q "no birds will fly" $logfile -if [ "$?" -ne 0 ] ; then - echo "xsnow did not start as expected" 1>&2 - cat $logfile 1>&2 - exit 1 -fi -grep -q "Santa: 4 Rudolph: 1" $logfile -if [ "$?" -ne 0 ] ; then - echo "xsnow did not react to mouse as expected" 1>&2 - cat $logfile 1>&2 - exit 77 -fi -exit 0 diff -Nru xsnow-3.1.1/src/test3.sh xsnow-3.3.2/src/test3.sh --- xsnow-3.1.1/src/test3.sh 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/test3.sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,55 +0,0 @@ -#!/bin/sh -# -copyright- -#-# -#-# xsnow: let it snow on your desktop -#-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin -#-# -#-# This program is free software: you can redistribute it and/or modify -#-# it under the terms of the GNU General Public License as published by -#-# the Free Software Foundation, either version 3 of the License, or -#-# (at your option) any later version. -#-# -#-# This program is distributed in the hope that it will be useful, -#-# but WITHOUT ANY WARRANTY; without even the implied warranty of -#-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -#-# GNU General Public License for more details. -#-# -#-# You should have received a copy of the GNU General Public License -#-# along with this program. If not, see . -#-# - -XSNOW=xsnow -if [ -x ./xsnow ]; then - XSNOW=./xsnow -fi -logfile=xsnow_out_3 ->$logfile -# open Santa tab, click on train with Rudolph -xdo="xdotool mousemove --sync 200 50 click 1 mousemove --sync 470 320 click 1" -# testing with a compositing X window manager -xvfb-run -a -s "-screen 0 1920x1080x24" sh -c "xcompmgr & sleep 2; $XSNOW -defaults -noisy -stopafter 5 >$logfile 2>&1& sleep 2; $xdo; sleep 8" -if [ "$?" -ne 0 ] ; then - echo "Problem in 'xvfb-run' command" 1>&2 - cat $logfile 1>&2 - exit 1 -fi -grep -q "Halting because of flag -stopafter" $logfile -if [ "$?" -ne 0 ] ; then - echo "xsnow did not end as expected" 1>&2 - cat $logfile 1>&2 - exit 1 -fi -grep -q "birds can fly" $logfile -if [ "$?" -ne 0 ] ; then - echo "xsnow did not start as expected" 1>&2 - cat $logfile 1>&2 - exit 1 -fi -grep -q "Santa: 4 Rudolph: 1" $logfile -if [ "$?" -ne 0 ] ; then - echo "xsnow did not react to mouse as expected" 1>&2 - cat $logfile 1>&2 - exit 77 -fi -exit 0 diff -Nru xsnow-3.1.1/src/transparent.c xsnow-3.3.2/src/transparent.c --- xsnow-3.1.1/src/transparent.c 2020-10-13 12:50:56.000000000 +0000 +++ xsnow-3.3.2/src/transparent.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,346 +0,0 @@ -/* -copyright- -#-# -#-# xsnow: let it snow on your desktop -#-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin -#-# -#-# This program is free software: you can redistribute it and/or modify -#-# it under the terms of the GNU General Public License as published by -#-# the Free Software Foundation, either version 3 of the License, or -#-# (at your option) any later version. -#-# -#-# This program is distributed in the hope that it will be useful, -#-# but WITHOUT ANY WARRANTY; without even the implied warranty of -#-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -#-# GNU General Public License for more details. -#-# -#-# You should have received a copy of the GNU General Public License -#-# along with this program. If not, see . -#-# -*/ -/** - * Original code by: Mike - http://plan99.net/~mike/blog (now a dead link--unable to find it). - * Modified by karlphillip for StackExchange: - * (https://stackoverflow.com/questions/3908565/how-to-make-gtk-window-background-transparent) - * Re-worked for Gtk 3 by Louis Melahn, L.C., January 30, 2014. - */ -// Thanks to: -// https://stackoverflow.com/questions/16832581/how-do-i-make-a-gtkwindow-background-transparent-on-linux] -// and -// https://github.com/anko/hudkit -// -// This is probably the most frequent changed file in xsnow - -#include -#include -#include -#include -#include "varia.h" -#include "windows.h" - -#include "transparent.h" - -#ifdef DEBUG -#undef DEBUG -#endif -//#define DEBUG -#include "debug.h" - -// USEDRAW should NOT be set, it is here for historical reasons -//#define USEDRAW -//USEDRAW1 should certainly be set, see comment below at draw1() -#define USEDRAW1 - -static void screen_changed(GtkWidget *widget, GdkScreen *old_screen, gpointer user_data); -#ifdef USEDRAW -static gboolean draw(GtkWidget *widget, cairo_t *cr, gpointer user_data); -#endif -#ifdef USEDRAW1 -static gboolean draw1(GtkWidget *widget, cairo_t *cr, gpointer user_data); -#endif - -static gboolean supports_alpha = FALSE; -static int below1; - -static GdkRectangle workarea; - -// -// create transparent click-through window without any decorations -// input: -// below: 1: place transparent window below all windows -// 0: place transparent window above all windows -// NOTE: this is applied in draw1() -// allworkspaces: 1: make window visible on all workspaces -// name: use this as name for the window -// gtkwin GtkWindow to transform into transparent -// width: width of desired window -// height: height of desired window -// output: -// xwin will receive id of created X11-window, 0 if transparency is not possible -// 0 if no transparent window is possible -// -// NOTE: in FVWM, combined with xcompmgr or compton, it seems not be possible to put a window below: -// reason (I guess): _NET_WM_ALLOWED_ACTIONS(ATOM) (from xprop) does not include _NET_WM_ACTION_BELOW -// -int create_transparent_window(int allworkspaces, int below, - Window *xwin, const char *name, GtkWidget *gtkwin, unsigned int width, unsigned int height) -{ - below1 = below; - workarea.width = width; - workarea.height = height; - - // see https://specifications.freedesktop.org/wm-spec/1.3/ar01s05.html : - // following prevents above/below: - //gtk_window_set_type_hint (GTK_WINDOW(gtkwin),GDK_WINDOW_TYPE_HINT_DESKTOP); - // following prevents gtk_window_set_skip_taskbar_hint from working: - gtk_window_set_type_hint (GTK_WINDOW(gtkwin),GDK_WINDOW_TYPE_HINT_NORMAL); - // always above: - //gtk_window_set_type_hint (GTK_WINDOW(gtkwin),GDK_WINDOW_TYPE_HINT_DIALOG); - // always above: - //gtk_window_set_type_hint (GTK_WINDOW(gtkwin),GDK_WINDOW_TYPE_HINT_MENU); - // always above: - //gtk_window_set_type_hint (GTK_WINDOW(gtkwin),GDK_WINDOW_TYPE_HINT_TOOLBAR); - // no taskbar_hint: - //gtk_window_set_type_hint (GTK_WINDOW(gtkwin),GDK_WINDOW_TYPE_HINT_SPLASHSCREEN); - // always above: - //gtk_window_set_type_hint (GTK_WINDOW(gtkwin),GDK_WINDOW_TYPE_HINT_UTILITY); - // no taskbar_hint: - //gtk_window_set_type_hint (GTK_WINDOW(gtkwin),GDK_WINDOW_TYPE_HINT_DOCK); - - - - gtk_window_set_decorated (GTK_WINDOW(gtkwin),FALSE); - - // try to prevent window from showing up in taskbar: - gtk_window_set_skip_taskbar_hint(GTK_WINDOW(gtkwin),TRUE); - // try to do something alike: - gtk_window_set_skip_pager_hint (GTK_WINDOW(gtkwin),TRUE); - - gtk_window_set_accept_focus (GTK_WINDOW(gtkwin), FALSE); - - gtk_window_set_position (GTK_WINDOW(gtkwin), GTK_WIN_POS_CENTER); - - P("create_transparent_window %p\n",(void *)gtkwin); - gtk_window_set_title(GTK_WINDOW(gtkwin), name); - gtk_widget_set_app_paintable(gtkwin, TRUE); - // this callback we do not need: -#ifdef USEDRAW - g_signal_connect(G_OBJECT(gtkwin), "draw", G_CALLBACK(draw), NULL); -#endif -#ifdef USEDRAW1 - g_signal_connect(G_OBJECT(gtkwin), "draw", G_CALLBACK(draw1), NULL); -#endif - - g_signal_connect(G_OBJECT(gtkwin), "screen-changed", G_CALLBACK(screen_changed), NULL); - gtk_widget_add_events(gtkwin, GDK_BUTTON_PRESS_MASK); - screen_changed(gtkwin, NULL, NULL); - if (!supports_alpha) - { - P("No alpha\n"); - *xwin = 0; - return FALSE; - } - - gtk_widget_show_all(gtkwin); - - GdkWindow *gdk_window = gtk_widget_get_window(GTK_WIDGET(gtkwin)); - P("gdk_window %p\n",(void *)gdk_window); - // keep xsnow visible after 'show desktop', and as a bonus, keep - // xsnow visible on all workspaces in some desktops: - - gdk_window_hide (GDK_WINDOW(gdk_window)); - - gtk_window_set_resizable (GTK_WINDOW(gtkwin), FALSE); - - // see comment at draw1() - cairo_region_t *cairo_region = cairo_region_create(); - gdk_window_input_shape_combine_region(GDK_WINDOW(gdk_window), cairo_region, 0,0); - P("shape stuff: %p %p\n",(void *)gtkwin,(void*)gdk_window); - cairo_region_destroy(cairo_region); - //gdk_window_set_pass_through(gdk_window,TRUE); // does not work as expected - - gdk_window_show (GDK_WINDOW(gdk_window)); - - usleep(200000); // seems to be necessary with nvidia, not sure if this is indeed the case - - - // xsnow visible on all workspaces: - if (allworkspaces) - gtk_window_stick(GTK_WINDOW(gtkwin)); - - // the X11 window: - *xwin = gdk_x11_window_get_xid(gdk_window); - - return TRUE; -} - -#if 1 -static void size_to_screen(GtkWindow *window) -{ - // see https://stackoverflow.com/questions/43225956/how-to-get-the-size-of-the-screen-with-gtk: - // also gdk_monitor_get_workarea is not always available ... - /* GdkRectangle workarea = {0}; - gdk_monitor_get_workarea( - gdk_display_get_primary_monitor(gdk_display_get_default()), - &workarea); - */ - - //printf ("W: %u x H:%u\n", workarea.width, workarea.height); - gtk_window_set_default_size(window, workarea.width, workarea.height); - gtk_window_resize (window, workarea.width, workarea.height); - gtk_window_set_resizable (window, FALSE); -} -#else -// sometimes (e.g. in slackware) gdkmonitor.h is missing, so we use a simpler solution -// see above -static int get_monitor_rects(GdkDisplay *display, GdkRectangle **rectangles) { - int n = gdk_display_get_n_monitors(display); - GdkRectangle *new_rectangles = (GdkRectangle*)malloc(n * sizeof(GdkRectangle)); - for (int i = 0; i < n; ++i) { - GdkMonitor *monitor = gdk_display_get_monitor(display, i); - gdk_monitor_get_geometry(monitor, &new_rectangles[i]); - } - *rectangles = new_rectangles; - return n; -} -static void size_to_screen(GtkWindow *window) { - //GdkScreen *screen = gtk_widget_get_screen(GTK_WIDGET(window)); - - // Get total screen size. This involves finding all physical monitors - // connected, and examining their positions and sizes. This is as complex - // as it is because monitors can be configured to have relative - // positioning, causing overlapping areas and a non-rectangular total - // desktop area. - // - // We want our window to cover the minimum axis-aligned bounding box of - // that total desktop area. This means it's too large (even large bits of - // it may be outside the accessible desktop) but it's easier to manage than - // multiple windows. - - // TODO Find the min x and y too, just in case someone's weird setup - // has something other than 0,0 as top-left. - - GdkDisplay *display = gdk_display_get_default(); - GdkRectangle *rectangles = NULL; - int nRectangles = get_monitor_rects(display, &rectangles); - - int width = 0, height = 0; - for (int i = 0; i < nRectangles; ++i) { - GdkRectangle rect = rectangles[i]; - int actualWidth = rect.x + rect.width; - int actualHeight = rect.y + rect.height; - if (width < actualWidth) width = actualWidth; - if (height < actualHeight) height = actualHeight; - } - free(rectangles); - - gtk_window_set_default_size(window, width, height); - gtk_window_resize(window, width, height); - gtk_window_set_resizable(window, FALSE); -} -#endif - -static void screen_changed(GtkWidget *widget, UNUSED GdkScreen *old_screen, UNUSED gpointer userdata) -{ - static int msg1 = 0, msg2 = 0; - /* To check if the display supports alpha channels, get the visual */ - GdkScreen *screen = gtk_widget_get_screen(widget); - - if (gdk_screen_is_composited(screen)) - { - if(!msg1) - printf("Your screen supports alpha channel, good.\n"); - msg1 = 1; - supports_alpha = TRUE; - } - else - { - if(!msg2) - printf("Your screen does not support transparency.\n"); - msg2 = 1; - supports_alpha = FALSE; - } - - // Ensure the widget (the window, actually) can take RGBA - gtk_widget_set_visual(widget, gdk_screen_get_rgba_visual(screen)); - size_to_screen(GTK_WINDOW(widget)); -} - -#ifdef USEDRAW -static gboolean draw(GtkWidget *widget, cairo_t *cr, UNUSED gpointer userdata) -{ - gtk_window_set_accept_focus(GTK_WINDOW(widget),FALSE); - cairo_save (cr); - - if (supports_alpha) - { - //cairo_set_source_rgba (cr, 0.5, 1.0, 0.50, 0.5); /* transparent */ - cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.0); /* transparent */ - P("Draw: transparent %d\n",++counter); - } - else - { - cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* opaque white */ - P("Draw: not transparent %d\n",++counter); - } - - /* draw the background */ - cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); - cairo_paint (cr); - - cairo_restore (cr); - - return FALSE; -} -#endif - -#ifdef USEDRAW1 -// Two windows have been dreated: SnowWina and SnowWinb. -// Both windows must be made click-through. -// Fot this, gdk_window_input_shape_combine_region() is used. -// This works fine in e.g. xfce (compositing ON), Gnome, KDE. -// -// However: in e.g. LXDE with xcompmgr running, somebody loses the click-through -// properties: when running with settings "Below windows" off, snow and birds -// are flying over your windows, but you cannot click: the windows are not -// click-through. -// Maybe this has something to do with the mainloop of GTK running or not? -// -// Hence this callback: the gdk_window_input_shape_combine_region() trick is done -// if a widget appears that has not been seen yet. This results in three calls -// to gdk_window_input_shape_combine_region(): for SnowWina, then for SnowWinb -// and then for SnowWina again (probably superfluous). -// This seems to fix the problem in some cases. -// Problem remains in fvwm and others in combination with xcompmgr or compton. -// -// Also, the 'below' paarmeter is applied here, this seems to be the only -// safe place to do it. Maybe because it is in the gtk_main loop? -// -// NOTE: this code assumes that no more than two windows are created. If there are -// more, some trivial changes in keeping track of these windows. -// -static gboolean draw1(GtkWidget *widget, UNUSED cairo_t *cr, UNUSED gpointer userdata) -{ - static GtkWidget *prev_widget[2] = {NULL,NULL}; - - P("draw1 %d %p\n",counter++,(void *)widget); - if (prev_widget[0] != widget && prev_widget[1]!= widget) - { - prev_widget[0] = prev_widget[1]; - prev_widget[1] = widget; - GdkWindow *gdk_window1 = gtk_widget_get_window(widget); - cairo_region_t *cairo_region1 = cairo_region_create(); - gdk_window_input_shape_combine_region(gdk_window1, cairo_region1, 0,0); - cairo_region_destroy(cairo_region1); - // gdk_window_set_pass_through(gdk_window1,TRUE); // does not work as expected - P("draw1 %d widget: %p gdkwin: %p passthru: %d\n",counter++,(void *)widget,(void *)gdk_window1,gdk_window_get_pass_through(gdk_window1)); - - if(below1) - setbelow(GTK_WINDOW(widget)); // see windows.c - else - setabove(GTK_WINDOW(widget)); // see windows.c - } - return FALSE; -} -#endif - diff -Nru xsnow-3.1.1/src/transparent.h xsnow-3.3.2/src/transparent.h --- xsnow-3.1.1/src/transparent.h 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/transparent.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,25 +0,0 @@ -/* -copyright- -#-# -#-# xsnow: let it snow on your desktop -#-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin -#-# -#-# This program is free software: you can redistribute it and/or modify -#-# it under the terms of the GNU General Public License as published by -#-# the Free Software Foundation, either version 3 of the License, or -#-# (at your option) any later version. -#-# -#-# This program is distributed in the hope that it will be useful, -#-# but WITHOUT ANY WARRANTY; without even the implied warranty of -#-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -#-# GNU General Public License for more details. -#-# -#-# You should have received a copy of the GNU General Public License -#-# along with this program. If not, see . -#-# - */ -#pragma once -#include -#include -extern int create_transparent_window(int allworkspaces, int below, - Window *w, const char *name, GtkWidget *gtkwin,unsigned int width, unsigned int height); diff -Nru xsnow-3.1.1/src/transwindow.c xsnow-3.3.2/src/transwindow.c --- xsnow-3.1.1/src/transwindow.c 1970-01-01 00:00:00.000000000 +0000 +++ xsnow-3.3.2/src/transwindow.c 2021-11-04 14:24:27.000000000 +0000 @@ -0,0 +1,235 @@ +/* -copyright- +#-# +#-# xsnow: let it snow on your desktop +#-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen +#-# 2019,2020,2021 Willem Vermin +#-# +#-# This program is free software: you can redistribute it and/or modify +#-# it under the terms of the GNU General Public License as published by +#-# the Free Software Foundation, either version 3 of the License, or +#-# (at your option) any later version. +#-# +#-# This program is distributed in the hope that it will be useful, +#-# but WITHOUT ANY WARRANTY; without even the implied warranty of +#-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +#-# GNU General Public License for more details. +#-# +#-# You should have received a copy of the GNU General Public License +#-# along with this program. If not, see . +#-# + */ +#include +#include +#include +#include "transwindow.h" +#include "debug.h" + + +static int setvaria(GtkWidget *widget); + +/* + * creates transparent window using gtk3/cairo. + * transwindow: (input) GtkWidget to create transparent window in + * fullscreen: (input) full-screen or not full screen + * sticky: (input) visible on all workspaces or not + * below: (input) 1: below all other windows 2: above all other windows 0: no action + * dock: (input) make it a 'dock' window: no decoration and not interfering with xsnow, xpenguins + * NOTE: with dock=1, gtk ignores the value of below: window is above all other windows + * NOTE: with decorations set to TRUE (see gtk_window_set_decorated()), + * the window is not click-through in Gnome + * So: dock = 1 is good for Gnome, or call gtk_window_set_decorated(w,FALSE) + * before this function + * gdk_window: (output) GdkWindow created + * x11_window: (output) Window X11 window created + */ +int make_trans_window(GtkWidget *transwindow, int fullscreen, int sticky, int below, int dock, + GdkWindow **gdk_window, Window *x11_window) +{ + if(gdk_window) + *gdk_window = NULL; + if(x11_window) + *x11_window = 0; + + // We take full responsibility for drawing background etc. + // Also, this is essential to obtain the desired effect. + gtk_widget_set_app_paintable(transwindow, TRUE); + + // essential in Gnome: + gtk_window_set_decorated(GTK_WINDOW(transwindow),FALSE); + // essential everywhere: + gtk_window_set_accept_focus(GTK_WINDOW(transwindow), FALSE); + + // take care that 'below' and 'sticky' are taken care of in gtk_main loop: + g_signal_connect(transwindow, "draw", G_CALLBACK(setvaria), NULL); + + // remove our things from transwindow: + g_object_steal_data(G_OBJECT(transwindow),"trans_sticky"); + g_object_steal_data(G_OBJECT(transwindow),"trans_below"); + g_object_steal_data(G_OBJECT(transwindow),"trans_nobelow"); + g_object_steal_data(G_OBJECT(transwindow),"trans_done"); + + + static char somechar; + if (sticky) + g_object_set_data(G_OBJECT(transwindow),"trans_sticky",&somechar); + + switch(below) + { + case 0: + g_object_set_data(G_OBJECT(transwindow),"trans_nobelow",&somechar); + break; + case 1: + g_object_set_data(G_OBJECT(transwindow),"trans_below",&somechar); + break; + } + + /* To check if the display supports alpha channels, get the visual */ + GdkScreen *screen = gtk_widget_get_screen(transwindow); + + if (!gdk_screen_is_composited(screen)) + { + P("No alpha\n"); + gtk_window_close(GTK_WINDOW(transwindow)); + return FALSE; + } + + // Ensure the widget (the window, actually) can take RGBA + gtk_widget_set_visual(transwindow, gdk_screen_get_rgba_visual(screen)); + + // set full screen if so desired: + if(fullscreen) + { + P("fullscreen\n"); + XWindowAttributes attr; + Display *display = XOpenDisplay(NULL); + XGetWindowAttributes(display,DefaultRootWindow(display),&attr); + gtk_widget_set_size_request(GTK_WIDGET(transwindow),attr.width,attr.height); + XCloseDisplay(display); + } + else + { + P("NOT fullsscreen\n"); + } + + gtk_widget_show_all(transwindow); + GdkWindow *gdkwin = gtk_widget_get_window(GTK_WIDGET(transwindow)); + + // so that apps like xsnow will ignore this window: + if(dock) + gdk_window_set_type_hint(gdkwin,GDK_WINDOW_TYPE_HINT_DOCK); + + gdk_window_hide(gdkwin); + if(fullscreen) + gdk_window_move(gdkwin,0,0); + gdk_window_show(gdkwin); + + if (x11_window) + *x11_window = gdk_x11_window_get_xid(gdkwin); + if (gdk_window) + *gdk_window = gdkwin; + + usleep(200000); // seems sometimes to be necessary with nvidia + + // just to be sure all settings are communicated with the server + gtk_widget_hide(transwindow); + gtk_widget_show_all(transwindow); + + // set some things, but note that this has to be repeated in the gkt_main loop. + + P("explicitly call setvaria\n"); + setvaria(transwindow); + P("end explicit call\n"); + g_object_steal_data(G_OBJECT(transwindow),"trans_done"); + + return TRUE; +} + +// for some reason, in some environments the 'below' and 'stick' properties +// disappear. It works again, if we express our wishes after starting gtk_main +// and the best place is in the draw event. +// +int setvaria(GtkWidget *widget) +{ + // We want to reset the settings at least once to be sure. + // Things like sticky and below should be stored in the widget beforehand. + // Use the value of p itself, not what it points to. + // Following the C standard, we have to use an array to subtract pointers. + enum {rep = 1,nrep}; // must be >= 0, and is equal to the number of times the settings + // will be done when called more than once + static char something[nrep]; + char *p = (char *)g_object_get_data(G_OBJECT(widget),"trans_done"); + if (!p) + p = &something[0]; + P("setvaria %p %p %d\n",p,&something,(int)(p-&something[0])); + if (p - &something[0] >= rep) + return FALSE; + p++; + g_object_set_data(G_OBJECT(widget),"trans_done",p); + + P("setvaria %p %p %d\n",p, (void *)widget,(int)(p - &something[0])); + + + GdkWindow *gdk_window1 = gtk_widget_get_window(widget); + const int Usepassthru = 0; + if(Usepassthru) + gdk_window_set_pass_through(gdk_window1,TRUE); // does not work as expected + else + { + cairo_region_t *cairo_region1 = cairo_region_create(); + gdk_window_input_shape_combine_region(gdk_window1, cairo_region1, 0,0); + cairo_region_destroy(cairo_region1); + } + P("setvaria %d widget: %p gdkwin: %p passthru: %d\n",counter++,(void *)widget,(void *)gdk_window1,gdk_window_get_pass_through(gdk_window1)); + + + if(!g_object_get_data(G_OBJECT(widget),"trans_nobelow")) + { + if(g_object_get_data(G_OBJECT(widget),"trans_below")) + setbelow(GTK_WINDOW(widget)); + else + setabove(GTK_WINDOW(widget)); + } + + if(1) + { + if(g_object_get_data(G_OBJECT(widget),"trans_sticky")) + gtk_window_stick(GTK_WINDOW(widget)); + else + gtk_window_unstick(GTK_WINDOW(widget)); + } + + return FALSE; +} + + +// Force window below or above other windows. +// It appears that, to get a window below other windows, it can be necessary +// to do first the opposite, and then vice-versa. +// These codes are probably somewhat too exuberant .... +void setbelow(GtkWindow *w) +{ + gtk_window_set_keep_above(GTK_WINDOW(w), TRUE); + gtk_window_set_keep_below(GTK_WINDOW(w), TRUE); + GdkWindow *gdkw = gtk_widget_get_window(GTK_WIDGET(w)); + Window xwin = gdk_x11_window_get_xid(gdkw); + XWindowChanges changes; + changes.stack_mode = Below; + Display *display = XOpenDisplay(NULL); + XConfigureWindow(display,xwin,CWStackMode,&changes); + P("setbelow %#lx\n",xwin); + XCloseDisplay(display); +} + +void setabove(GtkWindow *w) +{ + gtk_window_set_keep_below(GTK_WINDOW(w), TRUE); + gtk_window_set_keep_above(GTK_WINDOW(w), TRUE); + GdkWindow *gdkw = gtk_widget_get_window(GTK_WIDGET(w)); + Window xwin = gdk_x11_window_get_xid(gdkw); + XWindowChanges changes; + changes.stack_mode = Above; + Display *display = XOpenDisplay(NULL); + XConfigureWindow(display,xwin,CWStackMode,&changes); + P("setabove %#lx\n",xwin); + XCloseDisplay(display); +} diff -Nru xsnow-3.1.1/src/transwindow.h xsnow-3.3.2/src/transwindow.h --- xsnow-3.1.1/src/transwindow.h 1970-01-01 00:00:00.000000000 +0000 +++ xsnow-3.3.2/src/transwindow.h 2021-11-04 14:24:27.000000000 +0000 @@ -0,0 +1,29 @@ +/* -copyright- +#-# +#-# xsnow: let it snow on your desktop +#-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen +#-# 2019,2020,2021 Willem Vermin +#-# +#-# This program is free software: you can redistribute it and/or modify +#-# it under the terms of the GNU General Public License as published by +#-# the Free Software Foundation, either version 3 of the License, or +#-# (at your option) any later version. +#-# +#-# This program is distributed in the hope that it will be useful, +#-# but WITHOUT ANY WARRANTY; without even the implied warranty of +#-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +#-# GNU General Public License for more details. +#-# +#-# You should have received a copy of the GNU General Public License +#-# along with this program. If not, see . +#-# + */ +#pragma once + +#include +#include + +extern int make_trans_window(GtkWidget *Transwindow, int Fullscreen, int sticky, int below, int dock, + GdkWindow **gdk_window, Window *x11_window); +extern void setbelow(GtkWindow *w); +extern void setabove(GtkWindow *w); diff -Nru xsnow-3.1.1/src/treesnow.c xsnow-3.3.2/src/treesnow.c --- xsnow-3.1.1/src/treesnow.c 2020-10-13 12:50:56.000000000 +0000 +++ xsnow-3.3.2/src/treesnow.c 2021-11-04 14:24:27.000000000 +0000 @@ -2,7 +2,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by @@ -33,119 +33,57 @@ #include "snow.h" #include "blowoff.h" #include "treesnow.h" -#include "varia.h" #define NOTACTIVE \ (Flags.BirdsOnly || !WorkspaceActive() || Flags.NoSnowFlakes || Flags.NoKeepSnowOnTrees || Flags.NoTrees) -// we need both type of regions because the region is painted to -cairo_region_t *gSnowOnTreesRegion; -Region SnowOnTreesRegion; - -static GC SnowOnTreesGC; -XPoint *SnowOnTrees = NULL; -int OnTrees = 0; -static int do_snow_on_trees(gpointer data); -static void ConvertOnTreeToFlakes(void); +static int do_snow_on_trees(void *); +static void ConvertOnTreeToFlakes(void); void treesnow_init() { - SnowOnTreesGC = XCreateGC(display, SnowWin, 0, NULL); - SnowOnTreesRegion = XCreateRegion(); - gSnowOnTreesRegion = cairo_region_create(); - add_to_mainloop(PRIORITY_DEFAULT, time_snow_on_trees, do_snow_on_trees ,NULL); + global.gSnowOnTreesRegion = cairo_region_create(); + add_to_mainloop(PRIORITY_DEFAULT, time_snow_on_trees, do_snow_on_trees); } void treesnow_draw(cairo_t *cr) { -#define testj -#ifdef testje - cairo_region_t *region = cairo_region_create(); - cairo_rectangle_int_t rect; - int i; - for (i=0; i<5; i++) - { - rect.x=1000+100*i; - rect.y=500+100*i; - rect.width = 100+10*i; - rect.height = 20+10*i; - cairo_region_union_rectangle(region,&rect); - } - gdk_cairo_region(cr,region); - cairo_set_source_rgba(cr,1,0,1,0.5); - cairo_fill(cr); - cairo_region_destroy(region); -#endif if (NOTACTIVE) return; GdkRGBA color; gdk_rgba_parse(&color,Flags.SnowColor); cairo_set_source_rgba(cr,color.red,color.green,color.blue,ALPHA); - gdk_cairo_region(cr,gSnowOnTreesRegion); + gdk_cairo_region(cr,global.gSnowOnTreesRegion); cairo_fill(cr); } -int treesnow_ui() +void treesnow_ui() { - int changes = 0; - if(Flags.MaxOnTrees != OldFlags.MaxOnTrees) - { - OldFlags.MaxOnTrees = Flags.MaxOnTrees; - ClearScreen(); - changes++; - P("changes: %d\n",changes); - } - if(Flags.NoKeepSnowOnTrees != OldFlags.NoKeepSnowOnTrees) - { - OldFlags.NoKeepSnowOnTrees = Flags.NoKeepSnowOnTrees; - ClearScreen(); - changes++; - P("changes: %d\n",changes); - } - return changes; + UIDO(MaxOnTrees , ClearScreen(); ); + UIDO(NoKeepSnowOnTrees , ClearScreen(); ); } -int do_snow_on_trees(UNUSED gpointer data) +int do_snow_on_trees(void *d) { + P("do_snow_on_trees %d\n",counter++); if (Flags.Done) return FALSE; if (NOTACTIVE) return TRUE; - if (Wind == 2) + if (global.Wind == 2) ConvertOnTreeToFlakes(); - static int second = 0; - - if (switches.UseGtk) - { - // for gtk, drawing is done in treesnow_draw() - } - else - { - if (second) - { - second = 1; - XSetForeground(display, SnowOnTreesGC, ~BlackPix); - XFillRectangle(display, SnowWin, SnowOnTreesGC, 0,0,SnowWinWidth,SnowWinHeight); - } - XSetRegion(display, SnowOnTreesGC, SnowOnTreesRegion); - XSetForeground(display, SnowOnTreesGC, SnowcPix); - XFillRectangle(display, SnowWin, SnowOnTreesGC, 0,0,SnowWinWidth,SnowWinHeight); - } return TRUE; + (void)d; } -void treesnow_set_gc() -{ - XSetFunction(display, SnowOnTreesGC, GXcopy); -} - // blow snow off trees void ConvertOnTreeToFlakes() { + P("ConvertOnTreeToFlakes %d\n",global.OnTrees); int i; - for (i=0; irx = SnowOnTrees[i].x; - flake->ry = SnowOnTrees[i].y-5*j; + flake->rx = global.SnowOnTrees[i].x; + flake->ry = global.SnowOnTrees[i].y-5*j; flake->vy = 0; + flake->vx = global.NewWind/2; flake->cyclic = 0; } } } - OnTrees = 0; + global.OnTrees = 0; reinit_treesnow_region(); } void reinit_treesnow_region() { - XDestroyRegion(SnowOnTreesRegion); - SnowOnTreesRegion = XCreateRegion(); - cairo_region_destroy(gSnowOnTreesRegion); - gSnowOnTreesRegion = cairo_region_create(); + cairo_region_destroy(global.gSnowOnTreesRegion); + global.gSnowOnTreesRegion = cairo_region_create(); } void InitSnowOnTrees() { - SnowOnTrees = (XPoint *)realloc(SnowOnTrees,sizeof(*SnowOnTrees)*Flags.MaxOnTrees); - if (OnTrees > Flags.MaxOnTrees) - OnTrees = Flags.MaxOnTrees; + // Flags.MaxOnTrees+1: prevent allocation of zero bytes + global.SnowOnTrees = (XPoint *)realloc(global.SnowOnTrees,sizeof(*global.SnowOnTrees)*(Flags.MaxOnTrees+1)); + if (global.OnTrees > Flags.MaxOnTrees) + global.OnTrees = Flags.MaxOnTrees; } diff -Nru xsnow-3.1.1/src/treesnow.h xsnow-3.3.2/src/treesnow.h --- xsnow-3.1.1/src/treesnow.h 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/treesnow.h 2021-11-04 14:24:28.000000000 +0000 @@ -2,7 +2,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by @@ -19,14 +19,12 @@ #-# */ -extern Region SnowOnTreesRegion; -extern cairo_region_t *gSnowOnTreesRegion; -extern XPoint *SnowOnTrees; -extern int OnTrees; +#pragma once -extern void treesnow_set_gc(void); -extern void reinit_treesnow_region(void); -extern void InitSnowOnTrees(void); -extern void treesnow_init(void); -extern void treesnow_draw(cairo_t *cr); -extern int treesnow_ui(void); +#include + +extern void reinit_treesnow_region(void); +extern void InitSnowOnTrees(void); +extern void treesnow_init(void); +extern void treesnow_draw(cairo_t *cr); +extern void treesnow_ui(void); diff -Nru xsnow-3.1.1/src/ui.c xsnow-3.3.2/src/ui.c --- xsnow-3.1.1/src/ui.c 2020-10-13 12:50:56.000000000 +0000 +++ xsnow-3.3.2/src/ui.c 2021-11-04 14:24:27.000000000 +0000 @@ -2,7 +2,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by @@ -18,6 +18,119 @@ #-# along with this program. If not, see . #-# */ + +/* How to implement a new button + * + * The generation of code to add a button and/or a flag is dependent + * on definitions in 'doit.h' and 'buttons.h'. + * + * doit.h + * definition of names of flags, together with default values and vintage values + * example: + * DOIT_I(HaloBright ,25 ,25 ) + * + * DOIT_I: for flags with an integer value + * DOIT_L: for flags with a large value (for example a window-id) + * DOIT_S: for flags with a char* value (colors, mostly) + * + * Macro DOIT will call macro's that are not meant for read/write from .xsnowrc + * Macro DOIT_ALL calls all DOIT_* macro's + * This will result in: + * see flags.h: + * creation of member HaloBright in type FLAGS (see flags.h) + * see flags.c: + * definition of default value in DefaultFlags.HaloBright (25) + * definition of vintage value in VintageFlags.Halobright (0) + * definition of WriteFlags() to write the flags to .xsnowrc + * definition of ReadFlags() to read flags from .xsnowrc + * + * + * buttons.h + * definition of button-related entities. + * example: + * BUTTON(scalecode ,xsnow_celestials ,HaloBright ,1 ) + * this takes care that flag 'HaloBright' is associated with a button + * in the 'celestials' tab with the glade-id 'id-HaloBright' and that a value + * of 1 is used in the expansion of scalecode. + * In this case, the button should be a GtkScale button. + * + * The macro ALL_BUTTONS takes care that scalecode is called as + * scalecode(xsnow_celestials,HaloBright,1) + * and that all other BUTTON macro's are called + * + * The following types of buttons are implemented: + * GtkScale (macro scalecode) + * GtkToggle(macro togglecode) + * GtkColor (macro colorcode) + * + * In this way, the following items are generated: + * + * ui.c: + * define type Buttons, containing all flags in buttons.h + * associate the elements of Buttons with the corresponding + * glade-id's + * define call-backs + * these call backs have names like 'button_xsnow_celestials_HaloBright' + * the code ensures that for example Flags.HaloBright gets the value + * of the corresponding button. + * create a function settings1(), that sets all buttons in the state + * defined by the corresponding Flags. For example, if + * Flags.HaloBright = 40, the corresponding GtkScale button will be set + * to this value. + * connects signals of buttons to the corresponding call-backs, for example, + * button with glade-id 'id-HaloBright', when changed, will result in + * a call of button_xsnow_celestials_HaloBright(). + * create function set_default_tab(int tab, int vintage) that gives the + * buttons in the given tab (for example 'xsnow_celestials') and the + * corresponding flags their default (vintage = 0) or vintage (vintage=1) + * value. One will notice, that some buttons need extra care, for example + * flag TreeType in xsnow_scenery. + * + * glade, ui.xml + * + * Glade is used to maintain 'ui.xml', where the creation of the tabs and the + * placement of the buttons is arranged. +* For the buttons in 'buttons.h' a callback is arranged in 'ui.c', so in general +* there is no need to do something with the 'signals' properties of these buttons. +* Things that are needed: +* - button text, maybe using a GtkLabel +* - tooltip +* - for scale buttons: a GtkScale, defining for example min and max values +* - placement +* - for few buttons: a css class. Example: BelowConfirm +* In Makefile.am, ui.xml is converted to an include file: ui_xml.h +* So, when compiled, the program does not need an external file for it's GtkBuilder. +* +* +* Handling of changed flags. +* +* In 'flags.h' the macros UIDO and UIDOS are defined. They take care of the +* standard action to be used when a flag has been changed: simply copy +* the new value to OldFlags and increment Flags.Changes. OldFlags is initialized +* at the start of the program, and is used to check if a flag has been changed. +* +* UIDO (for integer valued flags) and UIDOS (for char* valued flags) take +* two parameters: +* - the name of the flag to check +* - C-code to execute if the value of the flag has been changed. +* +* In main.c the flags in the 'settings' tab are handled, and calls are +* made to for example scenery_ui() which is supposed to handle flags related +* with the 'scenery' tab. +* If Flags.Changes > 0, the flags are written to .xsnowrc. +* +* Documentation of flags +* +* This is take care of in 'docs.c'. +* +*/ + +#include "buttons.h" +// undef NEWLINE if one wants to examine the by cpp generated code: +// cpp ui.c | sed 's/NEWLINE/\n/g' +#define NEWLINE +//#undef NEWLINE +#ifdef NEWLINE #include #include #include @@ -25,6 +138,7 @@ #include #include #include +#include #include "birds.h" #include "clocks.h" @@ -35,7 +149,6 @@ #include "ui.h" #include "ui_xml.h" #include "utils.h" -#include "varia.h" #include "version.h" #include "windows.h" #include "xsnow.h" @@ -46,6 +159,7 @@ #undef DEBUG #include "debug.h" +#endif /* NEWLINE */ #ifdef __cplusplus #define MODULE_EXPORT extern "C" G_MODULE_EXPORT @@ -56,122 +170,67 @@ #define PREFIX_SANTA "santa-" #define PREFIX_TREE "tree-" -#define PREFIX_WW "ww-" #define SANTA2(x) SANTA(x) SANTA(x ## r) #define SANTA_ALL SANTA2(0) SANTA2(1) SANTA2(2) SANTA2(3) SANTA2(4) #define TREE_ALL TREE(0) TREE(1) TREE(2) TREE(3) TREE(4) TREE(5) TREE(6) TREE(7) - -// create function _name() to handle Flags._flag, handled by widget whose value -// can be accessed with gtk_range_get_value(). -// In general, the widget is a GtkScale. -#define HANDLE_RANGE(_name,_flag,_value) \ - MODULE_EXPORT void _name(GtkWidget *w, UNUSED gpointer d)\ -{\ - if(!human_interaction) return;\ - gdouble value;\ - value = gtk_range_get_value(GTK_RANGE(w));\ - Flags._flag = lrint(_value);\ - P(#_name ": %d\n",Flags._flag);\ -} typedef int dummytype // to request a ; - -#define HANDLE_TOGGLE(_name,_flag,_t,_f) \ - MODULE_EXPORT \ - void _name(GtkWidget *w, UNUSED gpointer d) \ -{ \ - if(!human_interaction) return; \ - gint active = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w)); \ - if(active) \ - Flags._flag = _t; \ - else \ - Flags._flag = _f; \ - P(#_name ": %d\n",Flags._flag); \ -} typedef int dummytype // to request a ; - -#define HANDLE_COLOR(_name,_flag) \ - MODULE_EXPORT \ - void _name(GtkWidget *w, UNUSED gpointer d) \ -{ \ - if(!human_interaction) return; \ - GdkRGBA color; \ - gtk_color_chooser_get_rgba(GTK_COLOR_CHOOSER(w),&color); \ - free(Flags._flag); \ - rgba2color(&color,&Flags._flag); \ - P(#_name ": %s\n",Flags._flag); \ -} typedef int dummytype // to request a ; - -#define HANDLE_SET_COLOR(_button,_flag) \ - do { \ - GdkRGBA color; \ - gdk_rgba_parse(&color,Flags._flag); \ - gtk_color_chooser_set_rgba(GTK_COLOR_CHOOSER(_button),&color); \ - } while(0) - -#define HANDLE_INIT(_button,_id) \ - do {_button = GTK_WIDGET(gtk_builder_get_object(builder,#_id));} while(0) - -#define HANDLE_SET_RANGE(_button,_flag,_fun) \ - do {gtk_range_set_value(GTK_RANGE(_button), _fun((gdouble)Flags._flag));} while(0) - -#define HANDLE_SET_TOGGLE_(_button,_x) \ - do {gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(_button),_x);} while(0) - -#define HANDLE_SET_TOGGLE(_button,_flag)\ - HANDLE_SET_TOGGLE_(_button,Flags._flag) - -#define HANDLE_SET_TOGGLE_I(_button,_flag) \ - do {gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(_button),!Flags._flag); } while (0) - -#define self(x) (x) +#define DEFAULT(name) DefaultFlags.name +#define VINTAGE(name) VintageFlags.name static GtkBuilder *builder; static GtkWidget *mean_distance; static GtkWidget *range; static GtkWidget *desktop_type; static GtkContainer *birdsgrid; +static GtkContainer *moonbox; #define nsbuffer 512 static char sbuffer[nsbuffer]; static void set_buttons(void); static void set_santa_buttons(void); static void set_tree_buttons(void); -static void set_star_buttons(void); -static void set_meteo_buttons(void); -static void apply_standard_css(void); +static void handle_css(void); static void birdscb(GtkWidget *w, void *m); -static int below_confirm_ticker(UNUSED gpointer data); +static int below_confirm_ticker(void *); static void show_bct_countdown(void); +static void yesyes(GtkWidget *w, gpointer data); +static void nono(GtkWidget *w, gpointer data); +static void activate (GtkApplication *app); +static void set_default_tab(int tab, int vintage); +static void set_belowall_default(); +static void handle_theme(void); static int human_interaction = 1; GtkWidget *nflakeslabel; -static int bct_id; +static guint bct_id = 0; static int bct_countdown; -// Set the style provider for the widgets -static void apply_css_provider (GtkWidget *widget, GtkCssProvider *cssstyleProvider) -{ - P("apply_css_provider %s\n",gtk_widget_get_name(GTK_WIDGET(widget))); +static GtkWidget *hauptfenster; +static GtkStyleContext *hauptfenstersc; - gtk_style_context_add_provider ( gtk_widget_get_style_context(widget), - GTK_STYLE_PROVIDER(cssstyleProvider) , - GTK_STYLE_PROVIDER_PRIORITY_USER ); +void ui_ui() +{ + UIDO (ThemeXsnow, handle_theme();); +} - // For container widgets, apply to every child widget on the container - if (GTK_IS_CONTAINER (widget)) +void handle_theme() +{ + if (Flags.ThemeXsnow) { - gtk_container_forall( GTK_CONTAINER (widget), - (GtkCallback)apply_css_provider , - cssstyleProvider); + gtk_style_context_add_class(hauptfenstersc,"xsnow"); + } + else + { + gtk_style_context_remove_class(hauptfenstersc,"xsnow"); } } -static GtkWidget *hauptfenster; MODULE_EXPORT -void button_iconify(UNUSED GtkWidget *w, UNUSED gpointer p) +void button_iconify() { P("button_iconify\n"); gtk_window_iconify(GTK_WINDOW(hauptfenster)); @@ -186,53 +245,45 @@ #define NBUTTONS (2*(MAXSANTA+1)) // NBUTTONS is number of Santa's too choose from -#define SANTA(x) santa_button santa_ ## x; +#define SANTA(x) NEWLINE santa_button santa_ ## x; static struct _santa_buttons { SANTA_ALL - - santa_button santa_show; - santa_button santa_speed; } santa_buttons; -#undef SANTA +#include "undefall.inc" -#define SANTA(x) &santa_buttons.santa_ ## x, +#define SANTA(x) NEWLINE &santa_buttons.santa_ ## x, static santa_button *santa_barray[NBUTTONS]= { SANTA_ALL }; -#undef SANTA +#include "undefall.inc" static void init_santa_buttons() { #define SANTA(x) \ - santa_buttons.santa_ ## x.button = GTK_WIDGET(gtk_builder_get_object(builder,PREFIX_SANTA #x)); + NEWLINE santa_buttons.santa_ ## x.button = GTK_WIDGET(gtk_builder_get_object(builder,PREFIX_SANTA #x)); SANTA_ALL; -#undef SANTA +#include "undefall.inc" #define SANTA(x) \ - gtk_widget_set_name(santa_buttons.santa_ ## x.button,PREFIX_SANTA #x); + NEWLINE gtk_widget_set_name(santa_buttons.santa_ ## x.button,PREFIX_SANTA #x); SANTA_ALL; -#undef SANTA +#include "undefall.inc" - HANDLE_INIT(santa_buttons.santa_show.button ,santa-show); - HANDLE_INIT(santa_buttons.santa_speed.button ,santa-speed); } static void set_santa_buttons() { int n = 2*Flags.SantaSize; - if (!Flags.NoRudolf) + if (Flags.Rudolf) n++; if (nbutton,TRUE); - - HANDLE_SET_TOGGLE(santa_buttons.santa_show.button,NoSanta); - HANDLE_SET_RANGE(santa_buttons.santa_speed.button,SantaSpeedFactor,log10); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(santa_barray[n]->button),TRUE); } MODULE_EXPORT -void button_santa(GtkWidget *w, UNUSED gpointer d) +void button_santa(GtkWidget *w) { if(!human_interaction) return; if(!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w))) return; @@ -241,42 +292,21 @@ int have_rudolf = ('r' == s[strlen(s)-1]); P("button_santa: Santa %d Rudolf %d s: %s name: %s\n",santa_type,have_rudolf,s,gtk_widget_get_name(w)); Flags.SantaSize = santa_type; - Flags.NoRudolf = !have_rudolf; -} - -HANDLE_TOGGLE(button_santa_show, NoSanta, 1, 0); - -HANDLE_RANGE(button_santa_speed, SantaSpeedFactor, pow(10.0,value)); - -void santa_default(int vintage) -{ - int h = human_interaction; - human_interaction = 0; - Flags.SantaSize = DEFAULT_SantaSize; - Flags.NoRudolf = DEFAULT_NoRudolf; - Flags.SantaSpeedFactor = DEFAULT_SantaSpeedFactor; - Flags.NoSanta = DEFAULT_NoSanta; - if(vintage) - { - Flags.SantaSize = VINTAGE_SantaSize; - Flags.NoRudolf = VINTAGE_NoRudolf; - } - set_santa_buttons(); - human_interaction = h; + Flags.Rudolf = have_rudolf; } MODULE_EXPORT -void button_defaults_santa(UNUSED GtkWidget *w, UNUSED gpointer d) +void button_defaults_santa() { P("button_defaults_santa defaults\n"); - santa_default(0); + set_default_tab(xsnow_santa,0); } MODULE_EXPORT -void button_vintage_santa(UNUSED GtkWidget *w, UNUSED gpointer d) +void button_vintage_santa() { P("button_defaults_santa vintage\n"); - santa_default(1); + set_default_tab(xsnow_santa,1); } typedef struct _tree_button @@ -284,37 +314,119 @@ GtkWidget *button; }tree_button; -#define TREE(x) tree_button tree_ ## x; +#define TREE(x) NEWLINE tree_button tree_ ## x; static struct _tree_buttons { TREE_ALL - - tree_button desired_trees; - tree_button tree_fill; - tree_button show; - tree_button color; } tree_buttons; -#undef TREE +#include "undefall.inc" -typedef struct _star_button -{ - GtkWidget *button; -} star_button; - -static struct _star_buttons -{ - star_button nstars; -} star_buttons; -typedef struct _meteo_button -{ - GtkWidget *button; -} meteo_button; +// creating type Buttons: Button.NStars etc. -static struct _meteo_buttons -{ - meteo_button show; -} meteo_buttons; +#define togglecode(type,name,m) NEWLINE GtkWidget *name; +#define scalecode togglecode +#define colorcode togglecode +static struct _Button +{ + ALL_BUTTONS +} Button; +#include "undefall.inc" + +// create init_buttons: connect with glade-id +// glade-id will be: "id-name", eg: "id-SnowFlakesFactor" +#define ID "id" + +#define togglecode(type,name,m) \ + NEWLINE P("%s %s\n",#name,#type); \ + NEWLINE Button.name = GTK_WIDGET(gtk_builder_get_object(builder,ID "-" #name)); +#define scalecode togglecode +#define colorcode togglecode + +static void init_buttons1() +{ + P("\nstart init_buttons1\n\n"); + ALL_BUTTONS + P("\nend init_buttons1\n\n"); +} +#include "undefall.inc" + +// define call backs + +#define buttoncb(type,name) button_##type##_##name +#define togglecode(type,name,m) \ + NEWLINE MODULE_EXPORT void buttoncb(type,name)(GtkWidget *w) \ + NEWLINE { \ + NEWLINE if(!human_interaction) return; \ + NEWLINE gint active = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w)); \ + NEWLINE if(active) Flags.name = TRUE; else Flags.name = FALSE; \ + NEWLINE if(m<0) Flags.name = !Flags.name; \ + NEWLINE } + +#define scalecode(type,name,m) \ + NEWLINE MODULE_EXPORT void buttoncb(type,name)(GtkWidget *w)\ + NEWLINE {\ + NEWLINE if(!human_interaction) return; \ + NEWLINE gdouble value; \ + NEWLINE value = gtk_range_get_value(GTK_RANGE(w)); \ + NEWLINE Flags.name = m*lrint(value); \ + NEWLINE } + +#define colorcode(type,name,m) \ + NEWLINE MODULE_EXPORT void buttoncb(type,name)(GtkWidget *w) \ + NEWLINE { \ + NEWLINE if(!human_interaction) return; \ + NEWLINE GdkRGBA color; \ + NEWLINE gtk_color_chooser_get_rgba(GTK_COLOR_CHOOSER(w),&color); \ + NEWLINE free(Flags.name); \ + NEWLINE rgba2color(&color,&Flags.name); \ + NEWLINE } + +ALL_BUTTONS +#include "undefall.inc" + +// define set_buttons +// +#define togglecode(type,name,m)\ + NEWLINE P("toggle %s %s %d %d\n",#name,#type,m,Flags.name); \ +NEWLINE if (m) { \ + NEWLINE if(m>0) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(Button.name),Flags.name);\ + NEWLINE else gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(Button.name),!Flags.name);\ + NEWLINE } +#define scalecode(type,name,m) \ + NEWLINE P("range %s %s %d %d\n",#name,#type,m,Flags.name); \ +NEWLINE gtk_range_set_value(GTK_RANGE(Button.name), m*((gdouble)Flags.name)); +#define colorcode(type,name,m) \ + NEWLINE P("color %s %s %d %s\n",#name,#type,m,Flags.name); \ +NEWLINE gdk_rgba_parse(&color,Flags.name); \ +NEWLINE gtk_color_chooser_set_rgba(GTK_COLOR_CHOOSER(Button.name),&color); + +static void set_buttons1() +{ + GdkRGBA color; + ALL_BUTTONS +} +#include "undefall.inc" + +// define signal_connect + +#define togglecode(type,name,m) \ + NEWLINE P("%s %s\n",#name,#type); \ + NEWLINE g_signal_connect(G_OBJECT(Button.name),"toggled", G_CALLBACK(buttoncb(type,name)),NULL); +#define scalecode(type,name,m) \ + NEWLINE P("%s %s\n",#name,#type); \ + NEWLINE g_signal_connect(G_OBJECT(Button.name),"value-changed", G_CALLBACK(buttoncb(type,name)),NULL); +#define colorcode(type,name,m) \ + NEWLINE P("%s %s\n",#name,#type); \ + NEWLINE g_signal_connect(G_OBJECT(Button.name),"color-set", G_CALLBACK(buttoncb(type,name)),NULL); + +static void connect_signals() +{ + P("\nstart connect_signals\n\n"); + ALL_BUTTONS + P("\nend connect_signals\n\n"); +} +#include "undefall.inc" static void report_tree_type(int p, gint active) { @@ -361,8 +473,7 @@ P("Tree_Type set to %s\n",Flags.TreeType); } - MODULE_EXPORT -void button_tree(GtkWidget *w, UNUSED gpointer d) +MODULE_EXPORT void button_tree(GtkWidget *w) { if(!human_interaction) return; gint active; @@ -373,45 +484,19 @@ P("button_tree: tree: %d active: %d\n",p,active); } -void scenery_default(int vintage) -{ - int h = human_interaction; - human_interaction = 0; - Flags.DesiredNumberOfTrees = DEFAULT_DesiredNumberOfTrees; - free(Flags.TreeType); - Flags.TreeType = strdup(DEFAULT_TreeType); - Flags.NStars = DEFAULT_NStars; - Flags.NoMeteorites = DEFAULT_NoMeteorites; - Flags.NoTrees = DEFAULT_NoTrees; - Flags.TreeFill = DEFAULT_TreeFill; - free(Flags.TreeColor); - Flags.TreeColor = strdup(DEFAULT_TreeColor); - if (vintage) - { - Flags.DesiredNumberOfTrees = VINTAGE_DesiredNumberOfTrees; - free(Flags.TreeType); - Flags.TreeType = strdup(VINTAGE_TreeType); - Flags.NStars = VINTAGE_NStars; - Flags.NoMeteorites = VINTAGE_NoMeteorites; - } - set_tree_buttons(); - set_star_buttons(); - set_meteo_buttons(); - human_interaction = h; -} MODULE_EXPORT -void button_defaults_scenery(UNUSED GtkWidget *w, UNUSED gpointer d) +void button_defaults_scenery() { P("button_defaults_scenery\n"); - scenery_default(0); + set_default_tab(xsnow_scenery,0); } MODULE_EXPORT -void button_vintage_scenery(UNUSED GtkWidget *w, UNUSED gpointer d) +void button_vintage_scenery() { P("button_vintage_scenery\n"); - scenery_default(1); + set_default_tab(xsnow_scenery,1); } @@ -419,24 +504,20 @@ { #define TREE(x) \ - tree_buttons.tree_##x.button = GTK_WIDGET(gtk_builder_get_object(builder,PREFIX_TREE #x)); + NEWLINE tree_buttons.tree_##x.button = GTK_WIDGET(gtk_builder_get_object(builder,PREFIX_TREE #x)); TREE_ALL; -#undef TREE +#include "undefall.inc" #define TREE(x) \ - gtk_widget_set_name(tree_buttons.tree_##x.button,PREFIX_TREE #x); + NEWLINE gtk_widget_set_name(tree_buttons.tree_##x.button,PREFIX_TREE #x); TREE_ALL; -#undef TREE - HANDLE_INIT(tree_buttons.desired_trees.button,tree-ntrees); - HANDLE_INIT(tree_buttons.tree_fill.button,tree-fill); - HANDLE_INIT(tree_buttons.show.button,tree-show); - HANDLE_INIT(tree_buttons.color.button,tree-treecolor0); +#include "undefall.inc" } static void init_santa_pixmaps() { -#define SANTA(x) santa_buttons.santa_ ## x.imid = (char *)PREFIX_SANTA # x "-imid"; +#define SANTA(x) NEWLINE santa_buttons.santa_ ## x.imid = (char *)PREFIX_SANTA # x "-imid"; SANTA_ALL; -#undef SANTA +#include "undefall.inc" int i; GtkImage *image; @@ -455,13 +536,13 @@ GtkImage *image; GdkPixbuf *pixbuf; #define TREE(x) \ - pixbuf = gdk_pixbuf_new_from_xpm_data ((const char **)xpmtrees[x]);\ - image = GTK_IMAGE(gtk_builder_get_object(builder,"treeimage" # x));\ - gtk_image_set_from_pixbuf(image,pixbuf); \ - g_object_unref(pixbuf); + NEWLINE pixbuf = gdk_pixbuf_new_from_xpm_data ((const char **)xpmtrees[x]);\ + NEWLINE image = GTK_IMAGE(gtk_builder_get_object(builder,"treeimage" # x));\ + NEWLINE gtk_image_set_from_pixbuf(image,pixbuf); \ + NEWLINE g_object_unref(pixbuf); TREE_ALL; -#undef TREE +#include "undefall.inc" } static void init_hello_pixmaps() @@ -491,75 +572,30 @@ init_hello_pixmaps(); } -HANDLE_RANGE(button_ntrees,DesiredNumberOfTrees,value); - -HANDLE_RANGE(button_tree_fill, TreeFill, value); - -HANDLE_TOGGLE(button_show_trees,NoTrees,0,1); - -static void rgba2color(GdkRGBA *c, char **s) -{ - *s = (char *)malloc(8); - sprintf(*s,"#%02lx%02lx%02lx",lrint(c->red*255),lrint(c->green*255),lrint(c->blue*255)); -} - - -HANDLE_COLOR(button_tree_color,TreeColor); - static void set_tree_buttons() { #define TREE(x)\ - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(tree_buttons.tree_##x.button),FALSE); + NEWLINE gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(tree_buttons.tree_##x.button),FALSE); TREE_ALL; -#undef TREE +#include "undefall.inc" int i; int *a,n; csvpos(Flags.TreeType,&a,&n); for (i=0; i GTK_MAJOR) + return 1; + if ((int)gtk_get_major_version() < GTK_MAJOR) + return 0; + if ((int)gtk_get_minor_version() > GTK_MINOR) + return 1; + if ((int)gtk_get_minor_version() < GTK_MINOR) + return 0; + if ((int)gtk_get_micro_version() >= GTK_MICRO) + return 1; + return 0; +} + +// to be used if gtk version is too low +// returns 1: user clicked 'Run with ...' +// returns 0: user clicked 'Quit' +static int RC; +int ui_run_nomenu() +{ + GtkApplication *app; + app = gtk_application_new ("nl.ratrabbit.example", G_APPLICATION_FLAGS_NONE); + g_signal_connect (app, "activate", G_CALLBACK (activate), NULL); + g_application_run (G_APPLICATION (app), 0, NULL); + g_object_unref (app); + return RC; +} + +static void activate (GtkApplication *app) +{ + GtkWidget *window; + GtkWidget *grid; + GtkWidget *button; + GtkWidget *label; + + + /* create a new window, and set its title */ + window = gtk_application_window_new (app); + gtk_window_set_position (GTK_WINDOW(window), GTK_WIN_POS_CENTER); + gtk_window_set_title (GTK_WINDOW (window), "Xsnow"); + gtk_window_set_decorated (GTK_WINDOW(window), FALSE); + gtk_window_set_keep_above (GTK_WINDOW(window), TRUE); + gtk_container_set_border_width (GTK_CONTAINER (window), 10); + + /* Here we construct the container that is going pack our buttons */ + grid = gtk_grid_new (); + + /* Pack the container in the window */ + gtk_container_add (GTK_CONTAINER (window), grid); + + snprintf(sbuffer,nsbuffer, + "You are using GTK-%s, but you need at least GTK-%s to view\n" + "the user interface.\n" + "Use the option '-nomenu' to disable the user interface.\n" + "If you want to try the user interface anyway, use the flag '-checkgtk 0'.\n\n" + "See 'man xsnow' or 'xsnow -h' to see the command line options.\n" + "Alternatively, you could edit ~/.xsnowrc to set options.\n", + ui_gtk_version(),ui_gtk_required()); + label = gtk_label_new(sbuffer); + + /* Place the label in cell (0,0) and make it fill 2 cells horizontally */ + + gtk_grid_attach(GTK_GRID(grid),label,0,0,2,1); + button = gtk_button_new_with_label ("Run without user interface"); + g_signal_connect(button,"clicked",G_CALLBACK(yesyes),window); + + /* Place the first button in the grid cell (0, 1), and make it fill + * just 1 cell horizontally and vertically (ie no spanning) + */ + gtk_grid_attach (GTK_GRID (grid), button, 0, 1, 1, 1); + + button = gtk_button_new_with_label ("Quit"); + g_signal_connect(button, "clicked", G_CALLBACK (nono), window); + + /* Place the second button in the grid cell (1, 1), and make it fill + * just 1 cell horizontally and vertically (ie no spanning) + */ + gtk_grid_attach (GTK_GRID (grid), button, 1, 1, 1, 1); + + /* Now that we are done packing our widgets, we show them all + * in one go, by calling gtk_widget_show_all() on the window. + * This call recursively calls gtk_widget_show() on all widgets + * that are contained in the window, directly or indirectly. + */ + gtk_widget_show_all (window); +} + +void yesyes(GtkWidget *w, gpointer window) +{ + RC = (w != NULL); + gtk_widget_destroy(GTK_WIDGET(window)); +} + +void nono(GtkWidget *w, gpointer window) +{ + RC = (w == NULL); + gtk_widget_destroy(GTK_WIDGET(window)); } // next function is not used, I leave it here as a template, who knows... // see also ui.xml -void ui_error_x11(UNUSED int *argc, UNUSED char **argv[]) +void ui_error_x11() { GtkWidget *errorfenster; GObject *button; diff -Nru xsnow-3.1.1/src/ui.h xsnow-3.3.2/src/ui.h --- xsnow-3.1.1/src/ui.h 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/ui.h 2021-11-04 14:24:28.000000000 +0000 @@ -2,7 +2,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by @@ -19,17 +19,28 @@ #-# */ #pragma once -extern void ui (int *argc, char **argv[]); -extern void ui_error_x11(int *argc, char **argv[]); -extern void ui_show_nflakes(int n); -extern void ui_set_birds_header(const char *text); -//extern void ui_set_vd_scale(void); -extern void ui_show_range_etc(void); -extern void ui_show_desktop_type(const char *s); -extern void ui_set_sticky(int x); -extern void ui_background(int m); -extern void ui_gray_ww(const int m); -extern void ui_gray_erase(const int m); -extern void ui_gray_below(const int m); -extern void ui_gray_birds(int m); +// required GTK version for running the ui. (from ui.xml, made using glade) +#define GTK_MAJOR 3 +#define GTK_MINOR 20 +#define GTK_MICRO 0 + +extern void ui (void); +extern void ui_error_x11(void); +extern void ui_show_nflakes(int n); +extern void ui_set_birds_header(const char *text); +extern void ui_set_celestials_header(const char *text); +extern void ui_show_range_etc(void); +extern void ui_show_desktop_type(const char *s); +extern void ui_set_sticky(int x); +extern void ui_background(int m); +extern void ui_ui(void); + +extern void ui_gray_ww(const int m); +extern void ui_gray_erase(const int m); +extern void ui_gray_below(const int m); +extern void ui_gray_birds(int m); +extern int ui_checkgtk(void); +extern char *ui_gtk_version(void); +extern char *ui_gtk_required(void); +extern int ui_run_nomenu(void); diff -Nru xsnow-3.1.1/src/ui.xml xsnow-3.3.2/src/ui.xml --- xsnow-3.1.1/src/ui.xml 2020-10-13 12:50:56.000000000 +0000 +++ xsnow-3.3.2/src/ui.xml 2021-11-04 14:24:27.000000000 +0000 @@ -4,7 +4,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by @@ -45,9 +45,10 @@ 10 + 1 400 50 - 10 + 5 10 @@ -174,6 +175,11 @@ 1 10 + + 75 + 1 + 10 + 100 1 @@ -186,8 +192,21 @@ 1 10 + + 20 + 500 + 100 + 1 + 10 + + + 720 + 120 + 10 + 10 + - 30 + 60 10 1 1 @@ -217,11 +236,17 @@ 10 - 1 - 3 + 20 + 400 2 - 0.01 - 0.10000000000000001 + 5 + 5 + + + 30 + 300 + 1 + 10 10 @@ -677,13 +702,12 @@ True False - center True False - 60 - gtk-missing-image + 64 + applications-games False @@ -697,6 +721,7 @@ False 24 24 + True Welcome at xsnow! @@ -712,7 +737,8 @@ True False - gtk-missing-image + 64 + applications-games False @@ -734,7 +760,8 @@ True False - gtk-missing-image + 64 + applications-games False @@ -747,6 +774,7 @@ True False start + True Vintage preferences: the look and feel of the original xsnow, created in 1993 by Rick Jansen. fill True @@ -762,7 +790,8 @@ True False - gtk-missing-image + 64 + applications-games False @@ -880,7 +909,7 @@ 0.5 0.5 @@ -1010,163 +1039,140 @@ True False - Blow off + center + Blow off: + 0.89999997615814209 0 - 6 + 4 True False - On windows + On windows: + 0.89999997615814209 0 - 8 + 5 True False - On bottom + On bottom: + 0.89999997615814209 0 - 9 + 6 True False - On scenery + On scenery: + 0.89999997615814209 0 - 10 + 7 - - Show flakes + + Show snow True True True If set, show snowflakes. - start center - - 2 - 4 - 2 + 3 + 2 - + Show True True True If set, show snow blowing away. - start center - - 2 - 6 - 2 + 3 + 4 - + Show True True True If set, show fallen snow on windows. - start - + center - 2 - 8 - 2 + 3 + 5 - + Show True True True If set, show fallen snow on bottom of the desktop. - start - + center - 2 - 9 - 2 + 3 + 6 - + Show True True True If set, snow will collect on the trees. - start - - - - 2 - 10 - 2 - - - - - Show fluff - True - True - True - If set, try to show fluff on fallen snow and trees if possible. - start - 8 - + center - 2 - 5 + 3 + 7 - + True True - When windy, snow will blow of trees and windows. The higher this setting, the more blown-off snow. + The higher this setting, the more snow will be generated because of Santa ploughing, wind or disappearing windows. center snow-blow-adjustment 1 0 False - + left 1 - 6 + 4 - + True True The higher this setting, the more snow will collect on the windows. @@ -1175,15 +1181,15 @@ 1 0 False - + left 1 - 8 + 5 - + True True The higher this setting, the more snow will collect on the bottom of the desktop. @@ -1191,15 +1197,15 @@ 1 0 False - + left 1 - 9 + 6 - + True True The higher this setting, the more snow will collect on the trees. @@ -1207,18 +1213,19 @@ 1 0 False - + left 1 - 10 + 7 True False - 8 + 12 + 40 Choose your favorite snow @@ -1240,7 +1247,7 @@ 0 - 12 + 11 @@ -1285,7 +1292,7 @@ 0 - 13 + 12 2 @@ -1312,7 +1319,7 @@ 0 - 14 + 13 2 @@ -1358,7 +1365,7 @@ 2 - 13 + 12 2 @@ -1385,181 +1392,12 @@ 2 - 14 + 13 2 - - True - False - center - - - - - - 100 - True - True - Size of snowflakes, works only for non-vintage snow flakes. - center - snow-size-adjustment - 0 - 0 - False - - - - False - True - 1 - - - - - 100 - True - True - Speed of the snowflakes. - center - snow-speed-adjustment - 0 - 0 - False - - - - False - True - 2 - - - - - 100 - True - True - Maximum amount of snowflakes. - center - flake-count-max-adjustment - 0 - 0 - False - - - - - False - True - 3 - - - - - 100 - True - False - label - - - False - True - 4 - - - - - - - - - - - 0 - 2 - 4 - - - - - True - False - center - - - - - - 100 - True - False - Size - - - False - True - 1 - - - - - 100 - True - False - Speed - - - False - True - 2 - - - - - 100 - True - False - Max # flakes - right - - - False - True - 3 - - - - - 100 - True - False - end - Actual # flakes - - - False - True - 4 - - - - - - - - - - - 0 - 3 - 4 - - - - + 100 True True @@ -1569,52 +1407,55 @@ 1 0 False - + left 1 - 4 + 2 True False - Intensity + center + Intensity: + 0.89999997615814209 0 - 4 + 2 True False - Color + center + Color: + 0.89999997615814209 0 - 5 + 3 - + True True True The color of the snow. - start + center center True - 1 - 5 + 3 @@ -1626,7 +1467,148 @@ 1 - 12 + 11 + + + + + 100 + True + False + center + Size: + 0.89999997615814209 + + + 0 + 8 + + + + + 100 + True + True + Size of snowflakes, works only for non-vintage snow flakes. + center + snow-size-adjustment + 0 + 0 + False + left + + + 1 + 8 + + + + + True + False + center + Speed: + 0.89999997615814209 + + + 2 + 8 + + + + + 100 + True + True + Speed of the snowflakes. + end + center + snow-speed-adjustment + 0 + 0 + False + left + + + 3 + 8 + + + + + 100 + True + False + Max # flakes: + right + 0.89999997615814209 + + + 0 + 9 + + + + + 100 + True + True + Maximum amount of snowflakes. + center + flake-count-max-adjustment + 0 + 0 + False + left + + + + 1 + 9 + + + + + 60 + True + False + center + # Flakes: + 0.89999997615814209 + + + 2 + 9 + + + + + 100 + True + False + start + center + label + + + 3 + 9 + + + + + Show fluff + True + True + True + If set, try to show fluff on fallen snow and trees if possible. + center + + + 3 + 3 @@ -1674,6 +1656,9 @@ + + + page2 @@ -1994,7 +1979,8 @@ True False - 8 + 12 + 40 Choose your favorite Santa @@ -2019,34 +2005,14 @@ - - No Santa - True - True - False - end - 8 - True - False - santa-0 - - - - 0 - 8 - 2 - - - True False end center 8 - 8 - 8 - Santa speed + Speed: + 0.89999997615814209 2 @@ -2054,7 +2020,7 @@ - + True True Santa's speed. @@ -2062,10 +2028,10 @@ 8 8 santaspeedadjustment - 3 + 1000 2 False - + left 3 @@ -2219,6 +2185,22 @@ + + Show + True + True + True + end + 8 + 1 + + + 0 + 8 + 2 + + + @@ -2262,76 +2244,7 @@ 8 8 - - True - False - end - Number of items - True - 10 - - - 0 - 6 - - - - - 100 - True - True - Desired number of scenery items. - start - vertical - ntreesadjustment - True - 100 - 0 - 0 - False - right - - - - 1 - 6 - - - - - True - False - start - % Window fill - - - 3 - 6 - - - - - True - True - Bottom percentage of screen available for scenery. - end - vertical - treewindowfilladjustment - True - 100 - 0 - 0 - False - left - - - - 2 - 6 - - - - + Show scenery True True @@ -2339,7 +2252,6 @@ To show or not to show scenery. center center - 4 @@ -2488,7 +2400,7 @@ - + True True True @@ -2496,7 +2408,6 @@ center center True - 1 @@ -2515,52 +2426,45 @@ - + True - True - Number of stars to twinkle. - center - staradjustment - 1 - 0 - False - + False + - 1 - 1 + 0 + 2 True False - center - 7 - Number of stars - True - 8 + 12 + 40 + Compose your favorite scenery + + + 0 - 1 + 0 + 6 - - Show meteorites + True - True - True - To show or not to show meteorites, - center - center - 8 - + False + Try and click any picture! + + + - 4 - 1 + 2 + 3 2 @@ -2568,54 +2472,12 @@ True False + True 0 - 2 - - - - - True - False - 8 - Compose your favorite scenery - - - - - - 0 - 0 - 6 - - - - - True - False - Try clicking any picture! - - - - - - 2 - 3 - 2 - - - - - True - False - True - - - - 0 - 7 + 8 @@ -2623,7 +2485,7 @@ True True True - Moose. + Polar bear. @@ -2680,7 +2542,7 @@ 0 - 10 + 11 3 @@ -2707,7 +2569,7 @@ 0 - 11 + 12 3 @@ -2753,7 +2615,7 @@ 3 - 10 + 11 4 @@ -2780,11 +2642,134 @@ 3 - 11 + 12 4 + + True + False + + + True + False + end + # Items: + True + 10 + 0.89999997615814209 + + + False + True + 0 + + + + + 100 + True + True + Desired number of scenery items. + start + 8 + ntreesadjustment + 100 + 0 + 0 + False + left + + + False + True + 1 + + + + + True + False + start + 12 + % Window fill: + + + False + True + 2 + + + + + 100 + True + True + Bottom percentage of screen available for scenery. + end + 8 + treewindowfilladjustment + 100 + 0 + 0 + False + left + + + False + True + 3 + + + + + Allow overlap + True + True + True + To allow overlap or not when placing scenery. + center + center + + + False + True + 4 + + + + + 0 + 7 + 7 + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -2912,18 +2897,18 @@ - + True False center 8 8 - + True False - 83 - Compose here your favorite wind conditions + 50 + Compose here your favorite celestial conditions @@ -2935,101 +2920,6 @@ - - Windy - True - True - True - If set, there will be wind. - center - - - - 0 - 1 - - - - - 107 - True - True - The higher this setting, the more the wind will whirl. - center - vertical - whirl-adjustment - True - 0 - 0 - False - left - - - - 1 - 1 - - - - - True - False - center - Whirl - - - 1 - 2 - - - - - True - True - This setting determines how many seconds pass between two gusts of wind. - center - vertical - wind-timer-adjustment - True - 0 - 0 - False - right - - - - 2 - 1 - - - - - True - False - center - Timer - - - 2 - 2 - - - - - Gust wind now! - True - True - True - Force a gust of wind immediately. - center - - - - 3 - 1 - - - True False @@ -3038,7 +2928,7 @@ 0 - 3 + 9 @@ -3055,7 +2945,7 @@ Apply default values for the preferences in this tab. end center - + False @@ -3072,7 +2962,7 @@ Apply vintage values for the preferences in this tab. start center - + False @@ -3083,7 +2973,7 @@ 0 - 4 + 10 2 @@ -3129,7 +3019,7 @@ 2 - 4 + 10 2 @@ -3156,7 +3046,7 @@ 0 - 5 + 11 2 @@ -3183,33 +3073,532 @@ 2 - 5 + 11 2 - - - - - - - - - - - - - - - - - page4 - wind - 4 - - - + + True + False + + + 80 + True + False + center + Wind + center + 0.60000002384185791 + + + + + + False + True + 0 + + + + + Windy + 80 + True + True + True + If set, there will be wind. + center + + + False + True + 1 + + + + + 80 + True + False + center + Whirl: + 0.89999997615814209 + + + False + True + 2 + + + + + 100 + True + True + The higher this setting, the more the wind will whirl. + center + whirl-adjustment + 0 + 0 + False + left + + + False + True + 3 + + + + + 60 + True + False + center + Timer: + 7 + 0.89999997615814209 + + + False + True + 4 + + + + + 100 + True + True + This setting determines how many seconds pass between two gusts of wind. + center + wind-timer-adjustment + 0 + 0 + False + left + + + False + True + 5 + + + + + Gust! + True + True + True + Force a gust of wind immediately. + center + + + + False + True + 6 + + + + + 0 + 3 + 4 + + + + + True + False + + + 80 + True + False + center + Stars + 0.60000002384185791 + + + + + + False + True + 0 + + + + + Show + 80 + True + True + True + To show or not show stars. + center + + + False + True + 1 + + + + + 80 + True + False + center + Number: + 0.89999997615814209 + + + False + True + 2 + + + + + 100 + True + True + Number of twinkling stars. + center + staradjustment + 0 + 0 + False + left + + + False + True + 3 + + + + + 0 + 4 + 4 + + + + + True + False + + + + + + + + + + + + + + + + + + + + + + + + 0 + 5 + 4 + + + + + True + False + 1 + + + 80 + True + False + center + Meteo + 0.60000002384185791 + + + + + + False + True + 0 + + + + + Show + 80 + True + True + True + To show or not to show meteorites, + center + center + + + False + True + 1 + + + + + + + + 0 + 7 + 4 + + + + + True + False + + + 80 + True + False + center + Moon + 0.60000002384185791 + + + + + + 0 + 0 + + + + + Show + 80 + True + True + True + To show or not show moon + center + center + + + 1 + 0 + + + + + 80 + True + False + center + Speed: + 0.89999997615814209 + + + 2 + 0 + + + + + 100 + True + True + Speed of moon in pixels/minute + center + moonspeedadjustment + 0 + 0 + False + left + + + 3 + 0 + + + + + Show + 80 + True + True + True + To show or not to show halo around moon. + center + center + + + 1 + 1 + + + + + True + False + center + Halo + 0.60000002384185791 + + + + + + 0 + 1 + + + + + 100 + True + True + Relative size of the moon + center + moonsizeadjustment + 0 + 0 + False + left + + + 5 + 0 + + + + + 60 + True + False + center + Size: + 6 + 0.89999997615814209 + + + 4 + 0 + + + + + True + False + center + Bright: + 0.89999997615814209 + + + 2 + 1 + + + + + True + True + Brightness of moon's halo. + center + halobrightadjustment + 0 + 0 + False + left + + + 3 + 1 + + + + + + + + + + + 0 + 6 + 4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + page4 + celestials + 4 + + + True False @@ -3220,7 +3609,8 @@ True False - 8 + 12 + 40 Birds settings @@ -3375,7 +3765,7 @@ - + Show birds True True @@ -3383,7 +3773,6 @@ If set: show birds. center center - 0 @@ -3391,7 +3780,7 @@ - + Birds only True True @@ -3399,7 +3788,6 @@ If set: show no Santa, snow or scenery. center center - 1 @@ -3410,9 +3798,9 @@ True False - end center - Preferred distance + Preferred distance: + 0.89999997615814209 0 @@ -3420,7 +3808,7 @@ - + 100 True True @@ -3429,7 +3817,7 @@ 0 0 False - + left 1 @@ -3449,7 +3837,7 @@ - + Restart True True @@ -3468,9 +3856,9 @@ True False - end center - Viewing distance + Viewing distance: + 0.89999997615814209 0 @@ -3478,7 +3866,7 @@ - + True True Viewing distance. @@ -3487,7 +3875,7 @@ 0 0 False - + left 1 @@ -3528,140 +3916,149 @@ True False - start center - Speed + Focus to +attraction point: + 0.89999997615814209 - 3 - 6 + 0 + 7 - - 100 + True True - Speed of birds in arbitrary units. - birds-speed-adjustment + Eagerness to concentrate on common attraction point + birds-attraction-adjustment 0 0 False - - - - 2 - 6 - - - - - True - False - end - center - Focus to attraction -point + left - 0 + 1 7 - + + 100 True True - Eagerness to concentrate on common attraction point - birds-attraction-adjustment + Desired number of birds. If zero, no birds are shown. + birds-nbirds-adjustment 0 0 False - + left + 1 - 7 + 3 + + + + + True + False + center + # Birds: + 0.89999997615814209 + + + 0 + 3 - + 100 True True - Eagerness to keep desired distance to neighbours. - birds-distance-weight-adjustment + Number of nearest neighbours the birds should look at. + birds-neighbours-adjustment 0 0 False - + left - 2 - 4 + 1 + 5 True False - start center - Distance weight + Neighbours: + 0.89999997615814209 - 3 - 4 + 0 + 5 - - 100 + True True - Desired number of birds. If zero, no birds are shown. - birds-nbirds-adjustment - 0 - 0 - False - - + True + Give the birds a fancy color. + center + center + rgb(0,0,0) + True 1 - 3 + 8 True False - end center - Number of birds + Bird color + + + 0 + 8 + + + + + True + False + 0 - 3 + 2 True False - start center - Anarchy + Anarchy: + 0.89999997615814209 - 3 + 2 3 - + 100 True True @@ -3670,41 +4067,41 @@ 0 0 False - + left - 2 + 3 3 - - 100 + True - True - Number of nearest neighbours the birds should look at. - birds-neighbours-adjustment - 0 - 0 - False - + False + center + Distance weight: + 0.89999997615814209 - 1 - 5 + 2 + 4 - + + 100 True - False - end - center - Neighbours + True + Eagerness to keep desired distance to neighbours. + birds-distance-weight-adjustment + 0 + 0 + False + left - 0 - 5 + 3 + 4 @@ -3713,15 +4110,16 @@ False center Adjust speed to -neighbours +neighbours: + 0.89999997615814209 - 3 + 2 5 - + 100 True True @@ -3730,74 +4128,58 @@ 0 0 False - + left - 2 + 3 5 - - True - True - True - Give the birds a fancy color. - center - center - rgb(0,0,0) - True - - - - 1 - 8 - - - True False - end center - Bird color + Speed: + 0.89999997615814209 - 0 - 8 + 2 + 6 - - Show -attr point + 100 True True - True - Show the point where the birds want to go. - + Speed of birds in arbitrary units. + birds-speed-adjustment + 0 + 0 + False + left - 2 - 7 + 3 + 6 True False - start center - Drawing scale + Drawing scale: + 0.89999997615814209 - 3 - 8 + 2 + 7 - + 100 True True @@ -3806,26 +4188,30 @@ 0 0 False - + left - 2 - 8 + 3 + 7 - + + Show +attr point + 100 True - False - + True + True + Show the point where the birds want to go. - 0 - 2 + 2 + 8 - + Follow Santa 100 @@ -3833,11 +4219,10 @@ True True Birds are attracted by an attraction point. Here you can choose to let Santa be the attraction point. - 3 - 7 + 8 @@ -3902,7 +4287,7 @@ 8 8 - + True False version @@ -3917,7 +4302,8 @@ True False - 8 + 8 + 20 Settings @@ -3930,37 +4316,16 @@ - - True - False - Advanced snow settings - - - - - - 0 - 8 - 16 - - - + 200 True False center - - On all -workspaces + True - True - True - Use all workspaces to snow in. -NOTE: this doesn't work properly in enlightenment. - start - center - + False + Transparency False @@ -3969,17 +4334,19 @@ - - Full -screen + True True - True - Xsnow will take as much of the desktop as it can. Depending on the desktop environment, in full-screen mode panels, taskbars etc. can become inaccessible. -NOTE: this doesn't work properly in enlightenment. - start - center - + Transparency of painted items: +0: no transparency. +100: fully transparent, you will see nothing! + vertical + general-transparency-adjuspment + True + 0 + 0 + False + right False @@ -3988,128 +4355,75 @@ - - Below -windows - True - True - True - When activated, it will be snowing below your windows, else it will be snowing upon you windows too. -On some desktop environments, when snowing above your windows you will not be able to click on any window. -Therefore, you will be asked to click a button, to be sure that things are OK. - center - center - - - - - False - True - 2 - - - - - Click to -confirm - True - True - True - - - - - False - True - 3 - - - True False end - cpu - factor - 6 + center + Lift snow +on bottom False True - 4 + 2 - - general-cpuload - 90 + True True - The higher, the smoother xsnow will run, but will also use more cpu power. - start - cpuload-adjustment + Use this if snow falls below the bottom of your screen, +or fallen snow hides something that should not be hidden. + vertical + lift-window-adjustment + True + False 0 0 False - - + right False True - 5 + 3 - - - 0 - 4 - 16 - - - - - True - False - center True False - Transparency + end + center + Lift snow +on windows False True - 0 + 4 - + True True - Transparency of painted items: -0: no transparency. -100: fully transparent, you will see nothing! + Use this if no snow collects on your windows, or if snow collects separated from your windows. +Some basic window managers need this setting (e.g. TWM needs in general a value of 25 .. 28). vertical - general-transparency-adjuspment + lift-windows-adjustment True + False 0 0 False right - False True - 1 + 5 @@ -4117,79 +4431,71 @@ True False end - center - Lift snow -on bottom + Cpu factor + 6 + 0.89999997615814209 False True - 2 + 6 - - 80 + + general-cpuload True True - Use this if snow falls below the bottom of your screen, -or fallen snow hides something that should not be hidden. - start - center + The higher, the smoother xsnow will run, but will also use more cpu power. vertical - lift-window-adjustment + cpuload-adjustment True False 0 0 False right - + False True - 3 + 7 - - True - False - end - center - Lift snow -on windows + + True + False + Scale False True - 4 + 8 - - 80 + + general-scale True True - Use this if no snow collects on your windows, or if snow collects separated from your windows. -Some basic window managers need this setting (e.g. TWM needs in general a value of 25 .. 28). - start - center + Overll drawing scale vertical - lift-windows-adjustment + scale-adjustment True False 0 0 False right - False True - 5 + 9 @@ -4200,66 +4506,6 @@ - - True - False - - - 0 - 9 - 16 - - - - - True - False - start - vertical - - - 0 - 10 - 7 - - - - - True - False - end - vertical - - - 16 - 10 - 7 - - - - - True - False - start - - - 0 - 17 - 16 - - - - - True - False - - - - 2 - 10 - - - True False @@ -4268,7 +4514,7 @@ 2 - 17 + 11 @@ -4294,7 +4540,7 @@ 0 - 19 + 13 8 @@ -4320,8 +4566,8 @@ - 9 - 19 + 8 + 13 8 @@ -4365,7 +4611,7 @@ 0 - 18 + 12 8 @@ -4408,87 +4654,49 @@ - 9 - 18 + 8 + 12 8 - - True - False - - - - 2 - 14 - - - True False - center + True - + True False - Painting method: + start + center + 4 + 4 + window type etc. False - True + False 0 - - - GTK/Cairo - True - True - False - Use transparent GTK window and Cairo for drawing non-birds, i.e. use a double -buffer and paint this at about 25 times per second, along with the birds. - True - False - - - - False - True - 1 - - - - - - - - X11 - True - True - False - Use transparent X11 window for Santa, snow and scenery. -Drawing and erasing will be done by X11 functions. - True - False - general-ww-0 - - - - False - True - 3 - - - - 2 - 13 - 14 + 3 + 10 + 13 + + + + + True + False + True + + + + 0 + 9 @@ -4497,10 +4705,15 @@ False center - + + Xsnow +colors True - False - How to erase: + True + True + Toggle between xsnow's own colors and standard colors. +Activated: use xsnow colors. +Deactivated: use default colors. False @@ -4509,13 +4722,16 @@ - - Use color + + On all +workspaces True True True - Use the specified color to erase. - + Use all workspaces to snow in. +NOTE: this doesn't work properly in enlightenment. + start + center False @@ -4524,64 +4740,61 @@ - + + + + + Below +windows True True True - Use this color for erasing. - start + When activated, it will be snowing below your windows, else it will be snowing upon you windows too. +On some desktop environments, when snowing above your windows you will not be able to click on any window. +Therefore, you will be asked to click a button, to be sure that things are OK. + center center - True - + False True - 2 + 3 - - Use exposures + + Click to +confirm True True True - If set, xsnow will ask the X server to generate exposure events when painting or erasing. - center - + To make sure you can click. + False True - 3 + 4 - - - - 2 - 15 - 14 - - - - - True - False - 0 - 16 + 8 + 17 True False - + + 0 @@ -4589,81 +4802,6 @@ - - True - False - True - - - True - False - start - center - 4 - 4 - window type etc. - - - False - False - 0 - - - - - 3 - 11 - 13 - - - - - True - False - - - - 2 - 12 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff -Nru xsnow-3.1.1/src/undefall.inc xsnow-3.3.2/src/undefall.inc --- xsnow-3.1.1/src/undefall.inc 1970-01-01 00:00:00.000000000 +0000 +++ xsnow-3.3.2/src/undefall.inc 2021-11-04 14:24:27.000000000 +0000 @@ -0,0 +1,30 @@ +/* -copyright- +#-# +#-# xsnow: let it snow on your desktop +#-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen +#-# 2019,2020,2021 Willem Vermin +#-# +#-# This program is free software: you can redistribute it and/or modify +#-# it under the terms of the GNU General Public License as published by +#-# the Free Software Foundation, either version 3 of the License, or +#-# (at your option) any later version. +#-# +#-# This program is distributed in the hope that it will be useful, +#-# but WITHOUT ANY WARRANTY; without even the implied warranty of +#-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +#-# GNU General Public License for more details. +#-# +#-# You should have received a copy of the GNU General Public License +#-# along with this program. If not, see . +#-# +*/ +#undef colorcode +#undef scalecode +#undef togglecode +#undef DOITB +#undef DOIT_I +#undef DOIT_L +#undef DOIT_S +#undef SANTA +#undef SNOW +#undef TREE diff -Nru xsnow-3.1.1/src/utils.c xsnow-3.3.2/src/utils.c --- xsnow-3.1.1/src/utils.c 2020-10-13 12:50:56.000000000 +0000 +++ xsnow-3.3.2/src/utils.c 2021-11-04 14:24:27.000000000 +0000 @@ -2,7 +2,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by @@ -19,17 +19,29 @@ #-# */ #include -#include #include #include #include #include +#include "xsnow.h" +#include "utils.h" #include "windows.h" #include "meteo.h" #include "debug.h" +#include "version.h" +#include "flags.h" -Pixel Black, White; +#ifdef TRACEBACK_AVAILALBLE +void traceback() +{ + // see man backtrace +#define BT_BUF_SIZE 100 + void *buffer[BT_BUF_SIZE]; + int nptrs = backtrace(buffer, BT_BUF_SIZE); + backtrace_symbols_fd(buffer, nptrs, STDOUT_FILENO); +} +#endif FILE *HomeOpen(const char *file,const char *mode, char **path) { @@ -49,12 +61,25 @@ void ClearScreen() { // remove all our snow-related drawings - XClearArea(display, SnowWin, 0,0,0,0,True); + XClearArea(global.display, global.SnowWin, 0,0,0,0,True); // Yes this is hairy: also remove meteorite. // It could be that a meteor region is still hanging around meteo_erase(); - XFlush(display); + XFlush(global.display); + +} +void myXClearArea(Display*dsp, Window win, int x, int y, int w, int h, int exposures) +{ + if (w == 0 || h == 0 || w<0 || h<0 || w>20000 || h>20000) + { + P("myXClearArea: %d %d %d %d %d\n",x,y,w,h,exposures); +#ifdef TRACEBACK_AVAILALBLE + traceback(); +#endif + return; + } + XClearArea(dsp, win, x,y,w,h,exposures); } float sq3(float x, float y, float z) @@ -80,7 +105,8 @@ { XColor scrncolor; XColor exactcolor; - if (XAllocNamedColor(display, DefaultColormap(display, screen), + int scrn = DefaultScreen(global.display); + if (XAllocNamedColor(global.display, DefaultColormap(global.display, scrn), colorName, &scrncolor, &exactcolor)) return scrncolor.pixel; else @@ -99,7 +125,7 @@ return drand48()*m; } // https://www.alanzucconi.com/2015/09/16/how-to-sample-from-a-gaussian-distribution/ - +// Interesting but not used now in xsnow double gaussian (double mean, double std, double min, double max) { double x; @@ -120,14 +146,21 @@ srand48(seed); } -guint add_to_mainloop(gint prio,float time,GSourceFunc func,gpointer datap) +guint add_to_mainloop(gint prio,float time,GSourceFunc func) { - return g_timeout_add_full(prio,(int)1000*(time),(GSourceFunc)func,datap,NULL); + return g_timeout_add_full(prio,(int)1000*(time),func,NULL,NULL); } -void remove_from_mainloop(guint tag) +guint add_to_mainloop1(gint prio,float time,GSourceFunc func,gpointer datap) { - g_source_remove(tag); + return g_timeout_add_full(prio,(int)1000*(time),func,datap,NULL); +} + +void remove_from_mainloop(guint *tag) +{ + if (*tag) + g_source_remove(*tag); + *tag = 0; } int is_little_endian(void) @@ -144,3 +177,35 @@ cairo_paint_with_alpha(cr,alpha); P("%d alpha %f\n",counter++,alpha); } + +void PrintVersion() +{ + printf("%s\n%s\n", + PACKAGE_STRING, VERSIONBY); +} + +void rgba2color(GdkRGBA *c, char **s) +{ + *s = (char *)malloc(8); + sprintf(*s,"#%02lx%02lx%02lx",lrint(c->red*255),lrint(c->green*255),lrint(c->blue*255)); +} + +void Thanks(void) +{ + if (global.HaltedByInterrupt) + printf("\nXsnow: Caught signal %d\n",global.HaltedByInterrupt); + if (strlen(global.Message)) + printf("\n%s\n",global.Message); + printf("\nThank you for using xsnow\n"); +} + +int ScaleChanged(int *prevscale) +{ + int newscale; + if (*prevscale != (newscale=(int)(Flags.Scale*global.WindowScale))) + { + *prevscale = newscale; + return TRUE; + } + return FALSE; +} diff -Nru xsnow-3.1.1/src/utils.h xsnow-3.3.2/src/utils.h --- xsnow-3.1.1/src/utils.h 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/utils.h 2021-11-04 14:24:28.000000000 +0000 @@ -2,7 +2,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by @@ -17,23 +17,33 @@ #-# You should have received a copy of the GNU General Public License #-# along with this program. If not, see . #-# - */ +*/ #pragma once -//#define add_to_mainloop(prio,time,func,datap) g_timeout_add_full(prio,(int)1000*(time),(GSourceFunc)func,datap,0) #define SOMENUMBER 42 #define PRIORITY_DEFAULT G_PRIORITY_LOW #define PRIORITY_HIGH G_PRIORITY_DEFAULT -#include + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include -#include #include -extern guint add_to_mainloop(gint prio,float time,GSourceFunc func,gpointer datap); -extern void remove_from_mainloop(guint tag); +#ifdef HAVE_EXECINFO_H +#ifdef HAVE_BACKTRACE +#include +#define TRACEBACK_AVAILALBLE +#endif +#endif + +extern guint add_to_mainloop(gint prio,float time,GSourceFunc func); +extern guint add_to_mainloop1(gint prio,float time,GSourceFunc func,gpointer datap); +extern void remove_from_mainloop(guint *tag); extern void ClearScreen(void); extern float fsignf(float x); extern FILE *HomeOpen(const char *file,const char *mode,char **path); @@ -43,12 +53,19 @@ extern Pixel AllocNamedColor(const char *colorName, Pixel dfltPix); extern int randint(int m); extern void my_cairo_paint_with_alpha(cairo_t *cr, double alpha); +extern void rgba2color(GdkRGBA *c, char **s); +extern void Thanks(void); +extern void myXClearArea(Display*display, Window win, int x, int y, int w, int h, int exposures); +extern int ScaleChanged(int *prev); +#ifdef TRACEBACK_AVAILALBLE +extern void traceback(void); +#endif // obtain normally distributed number. The number will be between min and max: extern double gaussian (double mean, double standard_deviation, double min, double max); // seed the random generator (alternatively, srand48() can be used): extern void sgaussian(long int seed); -extern Pixel Black, White; - extern int is_little_endian(void); +extern void PrintVersion(void); + diff -Nru xsnow-3.1.1/src/varia.h xsnow-3.3.2/src/varia.h --- xsnow-3.1.1/src/varia.h 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/varia.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,22 +0,0 @@ -/* -copyright- -#-# -#-# xsnow: let it snow on your desktop -#-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin -#-# -#-# This program is free software: you can redistribute it and/or modify -#-# it under the terms of the GNU General Public License as published by -#-# the Free Software Foundation, either version 3 of the License, or -#-# (at your option) any later version. -#-# -#-# This program is distributed in the hope that it will be useful, -#-# but WITHOUT ANY WARRANTY; without even the implied warranty of -#-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -#-# GNU General Public License for more details. -#-# -#-# You should have received a copy of the GNU General Public License -#-# along with this program. If not, see . -#-# - */ -#pragma once -#define UNUSED __attribute__ ((unused)) diff -Nru xsnow-3.1.1/src/version.h xsnow-3.3.2/src/version.h --- xsnow-3.1.1/src/version.h 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/version.h 2021-11-04 14:24:28.000000000 +0000 @@ -2,7 +2,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by @@ -19,4 +19,20 @@ #-# */ #pragma once -#define VERSION "3.1.1" + +// VERSION is defined via the AC_INIT line in configure.ac + +#ifdef HAVE_CONFIG_H +#include "config.h" +#else +#ifndef VERSION +#define VERSION "unknown" +#endif +#ifndef PACKAGE_STRING +#define PACKAGE_STRING "xsnow " VERSION +#endif +#endif + +#define VERSIONBY \ + "December 14th 2001 by Rick Jansen \n" \ + "August 2021 by Willem Vermin" diff -Nru xsnow-3.1.1/src/vroot.h xsnow-3.3.2/src/vroot.h --- xsnow-3.1.1/src/vroot.h 1970-01-01 00:00:00.000000000 +0000 +++ xsnow-3.3.2/src/vroot.h 2021-03-24 16:24:27.000000000 +0000 @@ -0,0 +1,122 @@ +/*****************************************************************************/ +/** Copyright 1991 by Andreas Stolcke **/ +/** Copyright 1990 by Solbourne Computer Inc. **/ +/** Longmont, Colorado **/ +/** **/ +/** All Rights Reserved **/ +/** **/ +/** Permission to use, copy, modify, and distribute this software and **/ +/** its documentation for any purpose and without fee is hereby **/ +/** granted, provided that the above copyright notice appear in all **/ +/** copies and that both that copyright notice and this permis- **/ +/** sion notice appear in supporting documentation, and that the **/ +/** name of Solbourne not be used in advertising **/ +/** in publicity pertaining to distribution of the software without **/ +/** specific, written prior permission. **/ +/** **/ +/** ANDREAS STOLCKE AND SOLBOURNE COMPUTER INC. DISCLAIMS ALL WARRANTIES **/ +/** WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF **/ +/** MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL ANDREAS STOLCKE **/ +/** OR SOLBOURNE BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL **/ +/** DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA **/ +/** OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER **/ +/** TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE **/ +/** OR PERFORMANCE OF THIS SOFTWARE. **/ +/*****************************************************************************/ +/* + * vroot.h -- Virtual Root Window handling header file + * + * This header file redefines the X11 macros RootWindow and DefaultRootWindow, + * making them look for a virtual root window as provided by certain `virtual' + * window managers like swm and tvtwm. If none is found, the ordinary root + * window is returned, thus retaining backward compatibility with standard + * window managers. + * The function implementing the virtual root lookup remembers the result of + * its last invocation to avoid overhead in the case of repeated calls + * on the same display and screen arguments. + * The lookup code itself is taken from Tom LaStrange's ssetroot program. + * + * Most simple root window changing X programs can be converted to using + * virtual roots by just including + * + * #include + * + * after all the X11 header files. It has been tested on such popular + * X clients as xphoon, xfroot, xloadimage, and xaqua. + * It also works with the core clients xprop, xwininfo, xwd, and editres + * (and is necessary to get those clients working under tvtwm). + * It does NOT work with xsetroot; get the xsetroot replacement included in + * the tvtwm distribution instead. + * + * Andreas Stolcke , 9/7/90 + * - replaced all NULL's with properly cast 0's, 5/6/91 + * - free children list (suggested by Mark Martin ), 5/16/91 + * - include X11/Xlib.h and support RootWindowOfScreen, too 9/17/91 + */ +#pragma once + +#ifndef _VROOT_H_ +#define _VROOT_H_ + +#define USE_VROOT + +#include +#include +#include + +#ifdef USE_VROOT +static Window VirtualRootWindowOfScreen(Screen *screen) +{ + static Screen *save_screen = (Screen *)0; + static Window root = (Window)0; + + if (screen != save_screen) { + Display *dpy = DisplayOfScreen(screen); + Atom __SWM_VROOT = None; + int i; + Window rootReturn, parentReturn, *children; + unsigned int numChildren; + + root = RootWindowOfScreen(screen); + + /* go look for a virtual root */ + __SWM_VROOT = XInternAtom(dpy, "__SWM_VROOT", False); + if (XQueryTree(dpy, root, &rootReturn, &parentReturn, + &children, &numChildren)) { + for (i = 0; i < (int)numChildren; i++) { + Atom actual_type; + int actual_format; + unsigned long nitems, bytesafter; + Window *newRoot = (Window *)0; + + if (XGetWindowProperty(dpy, children[i], + __SWM_VROOT, 0, 1, False, XA_WINDOW, + &actual_type, &actual_format, + &nitems, &bytesafter, + (unsigned char **) &newRoot) == Success + && newRoot) { + root = *newRoot; + break; + } + } + if (children) + XFree((char *)children); + } + + save_screen = screen; + } + + return root; +} + +#undef RootWindowOfScreen +#define RootWindowOfScreen(s) VirtualRootWindowOfScreen(s) + +#undef RootWindow +#define RootWindow(dpy,screen) VirtualRootWindowOfScreen(ScreenOfDisplay(dpy,screen)) + +#undef DefaultRootWindow +#define DefaultRootWindow(dpy) VirtualRootWindowOfScreen(DefaultScreenOfDisplay(dpy)) + +#endif +#endif /* _VROOT_H_ */ diff -Nru xsnow-3.1.1/src/wind.c xsnow-3.3.2/src/wind.c --- xsnow-3.1.1/src/wind.c 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/wind.c 2021-11-04 14:24:29.000000000 +0000 @@ -2,7 +2,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by @@ -30,63 +30,35 @@ #include "windows.h" #include "clocks.h" #include "xsnow.h" -#include "varia.h" #define NOTACTIVE \ (Flags.BirdsOnly || !WorkspaceActive()) -int Wind = 0; -int Direction = 0; -double WindTimer; -double WindTimerStart; -float Whirl; -float WindMax = 100.0; static void SetWhirl(void); static void SetWindTimer(void); -static int do_wind(gpointer data); -static int do_newwind(gpointer data); +static int do_wind(void *); +static int do_newwind(void *); void wind_init() { SetWhirl(); SetWindTimer(); - add_to_mainloop(PRIORITY_DEFAULT, time_newwind, do_newwind ,NULL); - add_to_mainloop(PRIORITY_DEFAULT, time_wind, do_wind ,NULL); + add_to_mainloop(PRIORITY_DEFAULT, time_newwind, do_newwind ); + add_to_mainloop(PRIORITY_DEFAULT, time_wind, do_wind ); } -int wind_ui() +void wind_ui() { - int changes = 0; - if(Flags.NoWind != OldFlags.NoWind) - { - OldFlags.NoWind = Flags.NoWind; - Wind = 0; - NewWind = 0; - changes++; - P("changes: %d\n",changes); - } - if(Flags.WhirlFactor != OldFlags.WhirlFactor) - { - OldFlags.WhirlFactor = Flags.WhirlFactor; - SetWhirl(); - changes++; - P("changes: %d\n",changes); - } - if(Flags.WindTimer != OldFlags.WindTimer) - { - OldFlags.WindTimer = Flags.WindTimer; - SetWindTimer(); - changes++; - P("changes: %d\n",changes); - } + UIDO(NoWind, global.Wind = 0; global.NewWind = 0;); + UIDO(WhirlFactor, SetWhirl();); + UIDO(WindTimer, SetWindTimer();); if(Flags.WindNow) { Flags.WindNow = 0; - Wind = 2; - P("changes: %d\n",changes); + global.Wind = 2; + P("Gust: %d\n",Flags.Changes); } - return changes; } void draw_wind() @@ -94,7 +66,7 @@ // Nothing to draw } -int do_newwind(UNUSED gpointer data) +int do_newwind(void *d) { P("newwind\n"); if (Flags.Done) @@ -114,26 +86,27 @@ } float r; - switch (Wind) + switch (global.Wind) { case(0): default: - r = drand48()*Whirl; - NewWind += r - Whirl/2; - if(NewWind > WindMax) NewWind = WindMax; - if(NewWind < -WindMax) NewWind = -WindMax; + r = drand48()*global.Whirl; + global.NewWind += r - global.Whirl/2; + if(global.NewWind > global.WindMax) global.NewWind = global.WindMax; + if(global.NewWind < -global.WindMax) global.NewWind = -global.WindMax; break; case(1): - NewWind = Direction*0.6*Whirl; + global.NewWind = global.Direction*0.6*global.Whirl; break; case(2): - NewWind = Direction*1.2*Whirl; + global.NewWind = global.Direction*1.2*global.Whirl; break; } return TRUE; + (void)d; } -int do_wind(UNUSED gpointer data) +int do_wind(void *d) { P("wind\n"); if (Flags.Done) @@ -154,48 +127,51 @@ // on the average, this function will do something // after WindTimer secs - if ((TNow - prevtime) < 2*WindTimer*drand48()) return TRUE; + if ((TNow - prevtime) < 2*global.WindTimer*drand48()) return TRUE; prevtime = TNow; if(drand48() > 0.65) // Now for some of Rick's magic: { if(drand48() > 0.4) - Direction = 1; + global.Direction = 1; else - Direction = -1; - Wind = 2; - WindTimer = 5; + global.Direction = -1; + global.Wind = 2; + global.WindTimer = 5; // next time, this function will be active // after on average 5 secs } else { - if(Wind == 2) + if(global.Wind == 2) { - Wind = 1; - WindTimer = 3; + global.Wind = 1; + global.WindTimer = 3; // next time, this function will be active // after on average 3 secs } else { - Wind = 0; - WindTimer = WindTimerStart; + global.Wind = 0; + global.WindTimer = global.WindTimerStart; // next time, this function will be active // after on average WindTimerStart secs } } return TRUE; + (void)d; } + void SetWhirl() { - Whirl = 0.01*Flags.WhirlFactor*WHIRL; + global.Whirl = 0.01*Flags.WhirlFactor*WHIRL; } + void SetWindTimer() { - WindTimerStart = Flags.WindTimer; - if (WindTimerStart < 3) - WindTimerStart = 3; - WindTimer = WindTimerStart; + global.WindTimerStart = Flags.WindTimer; + if (global.WindTimerStart < 3) + global.WindTimerStart = 3; + global.WindTimer = global.WindTimerStart; } diff -Nru xsnow-3.1.1/src/wind.h xsnow-3.3.2/src/wind.h --- xsnow-3.1.1/src/wind.h 2020-10-13 12:50:56.000000000 +0000 +++ xsnow-3.3.2/src/wind.h 2021-11-04 14:24:27.000000000 +0000 @@ -2,7 +2,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by @@ -20,20 +20,5 @@ */ #pragma once -extern int Wind; -// Wind = 0: no wind -// Wind = 1: wind only affecting snow -// Wind = 2: wind affecting snow and santa -// Direction = 0: no wind direction I guess -// Direction = 1: wind from left to right -// Direction = -1: wind from right to left -extern int Direction; -extern float Whirl; -extern double WindTimer; -extern double WindTimerStart; -extern float NewWind; -extern float WindMax; - - extern void wind_init(void); -extern int wind_ui(void); +extern void wind_ui(void); diff -Nru xsnow-3.1.1/src/windows.c xsnow-3.3.2/src/windows.c --- xsnow-3.1.1/src/windows.c 2020-10-13 12:50:56.000000000 +0000 +++ xsnow-3.3.2/src/windows.c 2021-11-04 14:24:27.000000000 +0000 @@ -2,7 +2,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by @@ -21,6 +21,7 @@ #include #include +#include #include #include #include "debug.h" @@ -30,40 +31,22 @@ #include "xsnow.h" #include "wmctrl.h" #include "fallensnow.h" -#include "transparent.h" +#include "transwindow.h" #include "dsimple.h" -#include "varia.h" -static int do_wupdate(gpointer data); -static void UpdateFallenSnowRegions(void); -static Window XWinInfo(char **name); +#include "vroot.h" +static int do_wupdate(void *); +static int do_sendevent(void *); +static long TransWorkSpace = -SOMENUMBER; // workspace on which transparent window is placed static WinInfo *Windows = NULL; static int NWindows; -char *SnowWinName = NULL; -int SnowWinX; -int SnowWinY; -Window RootWindow; -unsigned int Wroot; -unsigned int Hroot; -int Xroot; -int Yroot; -GtkWidget *TransA = NULL; -GtkWidget *TransB = NULL; -Window SnowWin = 0; -Window SnowWina = 0; -Window SnowWinb = 0; - -struct _switches switches; - -int windows_ui() +void windows_ui() { - int changes = 0; - return changes; } -void windows_draw(UNUSED cairo_t *cr) +void windows_draw() { // nothing to draw } @@ -71,35 +54,62 @@ void DestroyWindow(Window w) { return; - if (w && w != RootWindow) - XDestroyWindow(display,w); + if (w && w != global.Rootwindow) + XDestroyWindow(global.display,w); } void windows_init() { - if (switches.Desktop) - add_to_mainloop(PRIORITY_DEFAULT, time_wupdate, do_wupdate, NULL); + if (global.Desktop) + add_to_mainloop(PRIORITY_DEFAULT, time_wupdate, do_wupdate); + if (!global.IsDouble) + add_to_mainloop(PRIORITY_DEFAULT, 0.5, do_sendevent); } int WorkspaceActive() { - P("switches.UseGtk etc %d %d %d %d\n",Flags.AllWorkspaces,switches.UseGtk,CWorkSpace == TransWorkSpace, - Flags.AllWorkspaces || !switches.UseGtk || CWorkSpace == TransWorkSpace); + P("global.Trans etc %d %d %d %d\n",Flags.AllWorkspaces,global.Trans,global.CWorkSpace == TransWorkSpace, + Flags.AllWorkspaces || !global.Trans || global.CWorkSpace == TransWorkSpace); // ah, so difficult ... - return Flags.AllWorkspaces || !switches.UseGtk || CWorkSpace == TransWorkSpace; + return Flags.AllWorkspaces || !global.Trans || global.CWorkSpace == TransWorkSpace; +} + +int do_sendevent(void *dummy) +{ + P("do_sendevent %d\n",counter++); + XExposeEvent event; + + event.type = Expose; + event.send_event = True; + event.display = global.display; + event.window = global.SnowWin; + event.x = 0; + event.y = 0; + event.width = global.SnowWinWidth; + event.height = global.SnowWinHeight; + + XSendEvent(global.display, global.SnowWin, True, Expose, (XEvent *) &event); + return TRUE; + (void)dummy; } -int do_wupdate(UNUSED gpointer data) +int do_wupdate(void *dummy) { - P("do_wupdate %d\n",counter++); + P("do_wupdate %d %d\n",counter++,global.WindowsChanged); if (Flags.Done) return FALSE; if(Flags.NoKeepSWin) return TRUE; + + if (!global.WindowsChanged) + return TRUE; + + global.WindowsChanged = 0; + long r; r = GetCurrentWorkspace(); if(r>=0) - CWorkSpace = r; + global.CWorkSpace = r; else { I("Cannot get current workspace\n"); @@ -107,8 +117,23 @@ return TRUE; } + + P("Update windows\n"); + if(Windows) free(Windows); + // special hack too keep global.SnowWin below (needed for example in FVWM/xcompmgr, + // where global.SnowWin is not click-through) + { + P("keep below %#lx\n",global.SnowWin); + if(Flags.BelowAll) + { + XWindowChanges changes; + changes.stack_mode = Below; + XConfigureWindow(global.display,global.SnowWin,CWStackMode,&changes); + } + } + if (GetWindows(&Windows, &NWindows)<0) { I("Cannot get windows\n"); @@ -117,17 +142,17 @@ } //P("%d:\n",counter++);printwindows(display,Windows,NWindows); - //P("%d:\n",counter++);PrintFallenSnow(FsnowFirst); + //P("%d:\n",counter++);PrintFallenSnow(global.FsnowFirst); // Take care of the situation that the transparent window changes from workspace, // which can happen if in a dynamic number of workspaces environment // a workspace is emptied. WinInfo *winfo; - winfo = FindWindow(Windows,NWindows,SnowWin); + winfo = FindWindow(Windows,NWindows,global.SnowWin); // check also on valid winfo: after toggling 'below' // winfo is nil sometimes - if(switches.UseGtk && winfo) + if(global.Trans && winfo) { // in xfce and maybe others, workspace info is not to be found // in our transparent window. winfo->ws will be 0, and we keep @@ -137,27 +162,29 @@ { TransWorkSpace = winfo->ws; } - P("TransWorkSpace %#lx %#lx %#lx %#lx\n",TransWorkSpace,winfo->ws,SnowWin,GetCurrentWorkspace()); + P("TransWorkSpace %#lx %#lx %#lx %#lx\n",TransWorkSpace,winfo->ws,global.SnowWin,GetCurrentWorkspace()); } - P("do_wupdate: %p %p\n",(void *)TransA,(void *)winfo); - if (SnowWin != RootWindow) - if (!TransA && !winfo) + P("do_wupdate: %d %p\n",global.Trans,(void *)winfo); + if (global.SnowWin != global.Rootwindow) + //if (!TransA && !winfo) // let op + if (!global.Trans && !winfo) { - I("No transparent window & no SnowWin %#lx found\n",SnowWin); + I("No transparent window & no SnowWin %#lx found\n",global.SnowWin); Flags.Done = 1; } UpdateFallenSnowRegions(); return TRUE; + (void)dummy; } // Have a look at the windows we are snowing on // Also update of fallensnow area's void UpdateFallenSnowRegions() { - typeof(Windows) w; - typeof(FsnowFirst) f; + WinInfo *w; + FallenSnow *f; int i; // add fallensnow regions: w = Windows; @@ -165,13 +192,16 @@ { //P("%d %#lx\n",i,w->id); { - f = FindFallen(FsnowFirst,w->id); + f = FindFallen(global.FsnowFirst,w->id); P("%#lx %d\n",w->id,w->dock); if(f) { f->win = *w; // update window properties - if ((!f->win.sticky) && f->win.ws != CWorkSpace) + if ((!f->win.sticky) && f->win.ws != global.CWorkSpace) + { + P("CleanFallenArea\n"); CleanFallenArea(f,0,f->w); + } } if (!f) { @@ -180,21 +210,37 @@ // and also not if this window has y <= 0 // and also not if this window is a "dock" P(" %#lx %d\n",w->id,w->dock); - if (w->id != SnowWina && w->id != SnowWinb && w->y > 0 && !(w->dock)) - PushFallenSnow(&FsnowFirst, w, - w->x+Flags.OffsetX, w->y+Flags.OffsetY, w->w+Flags.OffsetW, - Flags.MaxWinSnowDepth); - //P("UpdateFallenSnowRegions:\n");PrintFallenSnow(FsnowFirst); + // if (w->id != SnowWin_a && w->id != SnowWinb && w->y > 0 && !(w->dock)) // let op + if (w->id != global.SnowWin && w->y > 0 && !(w->dock)) + { + if((int)(w->w) == global.SnowWinWidth && w->x == 0 && w->y <100) //maybe a transparent xpenguins window? + { + P("skipping: %d %#lx %d %d %d\n",global.counter++, w->id, w->w, w->x, w->y); + } + else + { + PushFallenSnow(&global.FsnowFirst, w, + w->x+Flags.OffsetX, w->y+Flags.OffsetY, w->w+Flags.OffsetW, + Flags.MaxWinSnowDepth); + } + } + //P("UpdateFallenSnowRegions:\n");PrintFallenSnow(global.FsnowFirst); } } w++; } // remove fallensnow regions - f = FsnowFirst; int nf = 0; while(f) { nf++; f = f->next; } - long int *toremove = (long int *)malloc(sizeof(*toremove)*nf); + f = global.FsnowFirst; + int nf = 0; + while(f) + { + nf++; + f = f->next; + } + // nf+1: prevent allocation of zero bytes + long int *toremove = (long int *)malloc(sizeof(*toremove)*(nf+1)); int ntoremove = 0; - f = FsnowFirst; - //Atom wmState = XInternAtom(display, "_NET_WM_STATE", True); + f = global.FsnowFirst; while(f) { if (f->win.id != 0) // f->id=0: this is the snow at the bottom @@ -214,6 +260,7 @@ { P("%#lx is hidden %d\n",f->win.id, counter++); CleanFallenArea(f,0,f->w); + P("CleanFallenArea\n"); } } f = f->next; @@ -225,7 +272,7 @@ w = Windows; for(i=0; iid); + f = FindFallen(global.FsnowFirst,w->id); if (f) { if ((unsigned int)f->w == w->w+Flags.OffsetW) // width has not changed @@ -233,10 +280,11 @@ if (f->x != w->x + Flags.OffsetX || f->y != w->y + Flags.OffsetY) { CleanFallenArea(f,0,f->w); + P("CleanFallenArea\n"); f->x = w->x + Flags.OffsetX; f->y = w->y + Flags.OffsetY; DrawFallen(f); - XFlush(display); + XFlush(global.display); } } else @@ -250,7 +298,7 @@ for (i=0; i. #-# */ +#pragma once + #include #include -extern Display *display; -extern int screen; -extern Window SnowWin; // window to snow in -extern Window SnowWina; // SnowWin is either SnowWina -extern Window SnowWinb; // or SnowWinb -extern int SnowWinWidth; -extern int SnowWinHeight; -extern int SnowWinBorderWidth; -extern int SnowWinDepth; -extern char *DesktopSession; -extern int IsCompiz; -extern int IsWayland; -extern GtkWidget *drawing_area; -extern GdkWindow *gdkwindow; -extern Pixel ErasePixel; -extern int Exposures; -extern Pixel BlackPix; -extern GtkWidget *TransA; -extern GtkWidget *TransB; -extern int CWorkSpace; // int? Yes, in compiz we take the placement of the desktop -// which can easily be > 16 bits -extern long TransWorkSpace; // workspace on which transparent window is placed -extern char *SnowWinName; -extern Window RootWindow; -extern int Xroot; -extern int Yroot; -extern unsigned int Wroot; -extern unsigned int Hroot; -extern int SnowWinX; -extern int SnowWinY; -extern int windows_ui(void); -extern void windows_draw(cairo_t *cr); +extern void windows_ui(void); +extern void windows_draw(void); extern void windows_init(void); extern int WorkspaceActive(void); // defined in main.c extern int DetermineWindow(Window *xtrans, char **xtransname, GtkWidget **gtrans,const char *transname, int *IsDesktop); extern void InitDisplayDimensions(void); extern void DestroyWindow(Window w); -extern void setbelow(GtkWindow *w); extern void setabove(GtkWindow *w); extern void DisplayDimensions(void); +extern Window XWinInfo(char **name); +extern void UpdateFallenSnowRegions(void); -static const int UW_DEFAULT = 0; -static const int UW_TRANSPARENT = 2; - -#define ALPHA (0.01*(100 - Flags.Transparency)) - -extern struct _switches -{ -#ifdef NO_USE_BITS - unsigned int UseGtk ; - unsigned int Trans ; - unsigned int Root ; - unsigned int DrawBirds ; - unsigned int Exposures ; - unsigned int Desktop ; -#else - unsigned int UseGtk :1; - unsigned int Trans :1; - unsigned int Root :1; - unsigned int DrawBirds :1; - unsigned int Exposures :1; - unsigned int Desktop :1; -#endif -} switches; diff -Nru xsnow-3.1.1/src/wmctrl.c xsnow-3.3.2/src/wmctrl.c --- xsnow-3.1.1/src/wmctrl.c 2020-10-13 12:50:57.000000000 +0000 +++ xsnow-3.3.2/src/wmctrl.c 2021-11-04 14:24:28.000000000 +0000 @@ -2,7 +2,7 @@ #-# #-# xsnow: let it snow on your desktop #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen -#-# 2019,2020 Willem Vermin +#-# 2019,2020,2021 Willem Vermin #-# #-# This program is free software: you can redistribute it and/or modify #-# it under the terms of the GNU General Public License as published by @@ -38,19 +38,20 @@ #include "dsimple.h" #include "debug.h" +#include "vroot.h" + static void FindWindows(Display *display,Window window, long unsigned int *nwindows,Window **windows); static void FindWindows_r(Display *display,Window window,long unsigned int *nwindows,Window **windows); +/* this one is not needed any more, but I keep the source */ void FindWindows(Display *display,Window window,long unsigned int *nwindows,Window **windows) { *nwindows = 0; *windows = NULL; FindWindows_r(display,window,nwindows,windows); - /* int i; for (i=0; i<(int)(*nwindows); i++) - printf("window: %#lx\n",(*windows)[i]); - */ + P("window: %#lx\n",(*windows)[i]); } void FindWindows_r(Display *display,Window window,long unsigned int *nwindows,Window **windows) { @@ -82,19 +83,34 @@ int GetCurrentWorkspace() { - Atom atom, type; + Atom type; int format; unsigned long nitems,b; unsigned char *properties; int r; + Display *getdisplay; + + static Atom atom_net_desktop_viewport; + static Atom atom_net_current_desktop; + static Atom atom_win_workspace; + + int firstcall = 1; + if (firstcall) + { + firstcall = 0; + getdisplay = global.display; + + atom_net_desktop_viewport = XInternAtom(getdisplay, "_NET_DESKTOP_VIEWPORT" ,False); + atom_net_current_desktop = XInternAtom(getdisplay, "_NET_CURRENT_DESKTOP" ,False); + atom_win_workspace = XInternAtom(getdisplay, "_WIN_WORKSPACE" ,False); + } - P("GetCurrentWorkspace %p %d\n",(void *)display,counter++); - if (IsCompiz) + P("GetCurrentWorkspace %p %d\n",(void *)getdisplay,counter++); + if (global.IsCompiz) { P("compiz\n"); properties = NULL; - atom = XInternAtom(display,"_NET_DESKTOP_VIEWPORT",False); - XGetWindowProperty(display, DefaultRootWindow(display), atom, 0, 2, False, + XGetWindowProperty(getdisplay, DefaultRootWindow(getdisplay), atom_net_desktop_viewport, 0, 2, False, AnyPropertyType, &type, &format, &nitems, &b, &properties); if (type != XA_CARDINAL || nitems != 2) { @@ -111,22 +127,20 @@ else { properties = NULL; - atom = XInternAtom(display,"_NET_CURRENT_DESKTOP",False); - XGetWindowProperty(display, DefaultRootWindow(display), atom, 0, 1, False, + XGetWindowProperty(getdisplay, DefaultRootWindow(getdisplay), atom_net_current_desktop, 0, 1, False, AnyPropertyType, &type, &format, &nitems, &b, &properties); P("type: %ld %ld\n",type,XA_CARDINAL); P("properties: %d %d %d %ld\n",properties[0],properties[1],format,nitems); if(type != XA_CARDINAL) { - P("nog eens %ld ...\n",type); + P("and again %ld ...\n",type); if(properties) XFree(properties); - atom = XInternAtom(display,"_WIN_WORKSPACE",False); - XGetWindowProperty(display, DefaultRootWindow(display), atom, 0, 1, False, + XGetWindowProperty(getdisplay, DefaultRootWindow(getdisplay), atom_win_workspace, 0, 1, False, AnyPropertyType, &type, &format, &nitems, &b, &properties); } if(type != XA_CARDINAL) { - if (IsWayland) + if (global.IsWayland) // in Wayland, the actual number of current workspace can only // be obtained if user has done some workspace-switching // we return zero if the workspace number cannot be determined @@ -150,71 +164,154 @@ int GetWindows(WinInfo **windows, int *nwin) { - Atom atom, type; + Atom type; int format; - unsigned long nitems,b; + unsigned long b; unsigned char *properties = NULL; - long *r; (*windows) = NULL; - atom = XInternAtom(display,"_NET_CLIENT_LIST",False); - XGetWindowProperty(display, DefaultRootWindow(display), atom, 0, 1000000, False, - AnyPropertyType, &type, &format, &nitems, &b, &properties); - if(type != XA_WINDOW) + static Display *getdisplay;; + Window *children; + long unsigned int nchildren; + + static Atom atom_gtk_frame_extents; + static Atom atom_net_client_list; + static Atom atom_net_frame_extents; + static Atom atom_net_showing_desktop; + static Atom atom_net_wm_desktop; + static Atom atom_net_wm_state; + static Atom atom_net_wm_window_type; + static Atom atom_win_client_list; + static Atom atom_win_workspace; + static Atom atom_wm_state; + + static int firstcall = 1; + if(firstcall) + { + firstcall = 0; + getdisplay = global.display; + + atom_gtk_frame_extents = XInternAtom(getdisplay, "_GTK_FRAME_EXTENTS" ,False); + atom_net_client_list = XInternAtom(getdisplay, "_NET_CLIENT_LIST" ,False); + atom_net_frame_extents = XInternAtom(getdisplay, "_NET_FRAME_EXTENTS" ,False); + atom_net_showing_desktop = XInternAtom(getdisplay, "_NET_SHOWING_DESKTOP" ,False); + atom_net_wm_desktop = XInternAtom(getdisplay, "_NET_WM_DESKTOP" ,False); + atom_net_wm_state = XInternAtom(getdisplay, "_NET_WM_STATE" ,False); + atom_net_wm_window_type = XInternAtom(getdisplay, "_NET_WM_WINDOW_TYPE" ,False); + atom_win_client_list = XInternAtom(getdisplay, "_WIN_CLIENT_LIST" ,False); + atom_win_workspace = XInternAtom(getdisplay, "_WIN_WORKSPACE" ,False); + atom_wm_state = XInternAtom(getdisplay, "WM_STATE" ,False); + } + + XGetWindowProperty(getdisplay, DefaultRootWindow(getdisplay), atom_net_client_list, 0, 1000000, False, + AnyPropertyType, &type, &format, &nchildren, &b, (unsigned char**)&children); + if(type == XA_WINDOW) + { + P("_NET_CLIENT_LIST succeeded\n"); + } + else { P("No _NET_CLIENT_LIST, trying _WIN_CLIENT_LIST\n"); - if(properties) XFree(properties); - atom = XInternAtom(display,"_WIN_CLIENT_LIST",False); - XGetWindowProperty(display, DefaultRootWindow(display), atom, 0, 1000000, False, - AnyPropertyType, &type, &format, &nitems, &b, &properties); + if(children) + { + XFree(children); + children = NULL; + } + XGetWindowProperty(getdisplay, DefaultRootWindow(getdisplay), atom_win_client_list, 0, 1000000, False, + AnyPropertyType, &type, &format, &nchildren, &b, (unsigned char**)&children); + if(type == XA_WINDOW) + { + P("_WIN_CLIENT_LIST succeeded\n"); + } } if(type != XA_WINDOW) { P("No _WIN_CLIENT_LIST, trying XQueryTree\n"); - FindWindows(display,RootWindow(display,DefaultScreen(display)),&nitems,(Window **)&properties); + if(children) + { + XFree(children); + children = NULL; + } + if(0) + { + FindWindows(getdisplay,RootWindow(getdisplay,DefaultScreen(getdisplay)),&nchildren,(Window **)&properties); + } + else + { + Window dummy; + unsigned int n; + XQueryTree(getdisplay,DefaultRootWindow(getdisplay),&dummy,&dummy,&children,&n); + nchildren = n; + } } - //printf("wmctrl: %d: %ld\n",__LINE__,nitems); - (*nwin) = nitems; - r = (long*)properties; - (*windows) = (WinInfo *)malloc(nitems*sizeof(WinInfo)); - int i; + P("----------------------------------------- nchildren: %ld\n",nchildren); + (*nwin) = nchildren; + (*windows) = NULL; + if(nchildren>0) + (*windows) = (WinInfo *)malloc(nchildren*sizeof(WinInfo)); WinInfo *w = (*windows); - static Atom net_atom = 0, gtk_atom = 0; - if(gtk_atom == 0) gtk_atom = XInternAtom(display, "_GTK_FRAME_EXTENTS", True); - if(net_atom == 0) net_atom = XInternAtom(display, "_NET_FRAME_EXTENTS", True); int k = 0; - for (i=0; (unsigned long)i