Package: xsnow
Version: 1:1.42-8
Severity: minor
Tags: patch
xnow does not react to screen resolution changes (resulting in a
'bottom' that does not coincide with the display bottom any more), and
fails to detect when the entire root window is redrawn, e.g. after
quitting a full-screen application and also when switching VT or waking
from suspend (resulting in ugly snow-streaks).
Please find below the proposed patch to correct these issues. More
precisely, what follows is
- the detailed list of changes to the source of xsnow 1.42 (in square
brackets instructions on how to reproduce the bugs with the current version)
- the diff-patch for xsnow.c
- the diff-patch for xsnow.h
regards,
Adrian
p.s.
cc: to Rick Jansen because this issue has not been corrected upstream
------------ BEGIN: list of changes --------------
* to make xsnow aware of screen resolution changes:
[to see this bug with the original version: xrandr to a lower resolution;
launch xsnow; wait for some snow to accumulate at the bottom; switch
back to higher resolution: the bottom snow now accumulates at the
coordinate of the former display height, somewhere in mid-air]
- moved some display-size-dependent initalisation code from main() to
new function prepare(), which is then invoked at every display size
change
- make the main event loop listen to StructureNotify masked events, so
that changes in root window size generate a ConfigureNotify event
- call prepare() from within the main event loop on
ConfigureNotify events where display size has changed
* to erase bottom snow when full-screen app quits:
[to see this bug with the original version: launch xsnow and wait for
some snow to accumulate on bottom and/or windows (use -snowflakes 1000
to wait less long...); start full-screen app (e.g. "mplayer -fs
somemovie.avi") and quit it: the snow has disappeared because of the
resulting redraw, but xsnow still thinks there are thick layers of
snow around. Flakes falling through these layers produce strange
trails of free-standing snow...]
- modified the tests that MWR() uses to skip over some child windows.
These tests in particular would skip over any child window with the
top at y=0, such as full-screen-windows. Now skip only completely
invisible windows.
* to make xsnow's memory of accumulated snow match full background
window redraws in the absence of child window changes (such as
occuring when switching VT or waking from suspend)
[to see bug with the original version: same procedure as for
full-screen-app bug, but switch to console and back to X11 instead
of launching fs-app. Same observation.]
- immediately subtract newly exposed areas from the accumulated snow
region snscr (in the main event loop)
- as this places some additional load on the machine when windows are
moved around (was not able to measure the real impact reliably),
added "#define CLEANONEXPOSE 1" to xsnow.h and added preprocessor
instructions around the code in xsnow.c to conditionnally compile
according to the value of CLEANONEXPOSE in xsnow.h
* other minor changes
- removed declaration unused variable current_snow_height
- added a few comments here and there while figuring out xsnow's inner
workings
- corrected what seems like a typo: in MASR(), part of the code should
clearly depend on NoKeepSBot, not on NoKeepSWin; has no
effect in practice because snscr (initialised with the same code
without typo) is merged into sar afterwards.
------------ END: list of changes --------------
------------ BEGIN: diff-patch for xsnow.c --------------
--- xsnow-1.42/xsnow.c 2001-12-16 00:44:47.000000000 +0100
+++ xsnow-1.42resizeable/xsnow.c 2010-02-06 21:50:58.000000000 +0100
@@ -198,6 +198,10 @@
14DEC2001 KDE and other root window obstructors: sub borrowed from
xpenguins 2.2 to find the
current "root" window for this system.
Credit to Robin Hogan
<[email protected]>
+
+ 05FEB2010 Now reacts to a change of its root window size (e.g. mode
+ changes through xrandr) and erases bottom snow when full-screen-app
+ quits. [Adrian Daerr, no rights claimed on contribution - public domain]
*/
#define debug 0
@@ -211,7 +215,7 @@
Xsnow dos mil
etc.
*/
-#define VERSION "Xsnow-1.42, December 14th 2001 by Rick Jansen
([email protected])\n\
+#define VERSION "Xsnow-1.42resizeable, December 14th 2001 by Rick Jansen
([email protected])\n\
WWW: http://www.euronet.nl/~rja/Xsnow/\n"
#ifdef VMS
@@ -315,7 +319,6 @@
int wind = 0;
int direction=0;
int WindTimer=30;
-int current_snow_height;
int geta=0;
XRectangle AddRect;
unsigned int RunCounter = 0;
@@ -324,6 +327,7 @@
void Usage();
void SigHandler();
void SigHupHandler();
+void prepare(int,int);
void InitSnowflake();
void UpdateSnowflake();
void DrawSnowflake();
@@ -555,15 +559,6 @@
rootWin = ToonGetRootWindow(display, screen, &Parent);
black = BlackPixel(display, screen);
white = WhitePixel(display, screen);
- display_width = DisplayWidth(display, screen);
- display_height = DisplayHeight(display, screen);
- center_x = display_width / 2;
- center_y = display_height / 2;
- current_snow_height = display_height;
- if (MaxScrSnowDepth> (display_height-SNOWFREE)) {
- printf("** Maximum snow depth set to %d\n",
display_height-SNOWFREE);
- MaxScrSnowDepth = display_height-SNOWFREE;
- }
for (flake=0; flake<=SNOWFLAKEMAXTYPE; flake++) {
rp = &snowPix[flake];
rp->pixmap = XCreateBitmapFromData(display, rootWin,
@@ -620,29 +615,9 @@
XSetForeground(display,TreesGC,trPix);
XSetFillStyle(display, TreesGC, FillStippled);
-
-
-
- Wr = XCreateRegion();
- PrevWr = XCreateRegion();
- snscr = XCreateRegion();
- sar = XCreateRegion();
- WDR = XCreateRegion();
- CDR = XCreateRegion();
- rscrr = XCreateRegion();
- AddRect.x = 0;
- AddRect.y = display_height;
- AddRect.width = display_width - 1;
- AddRect.height = MaxYStep+MaxSnowFlakeHeight;
- if (!NoKeepSBot)
- XUnionRectWithRegion(&AddRect, snscr, snscr);
- for (i=0; i<maxSnowflakes; i++) InitSnowflake(i);
-rc = MWR(1);
- XUnionRegion(Wr,PrevWr, PrevWr);
- RCSR();
- MASR();
- ResetSanta();
- XSelectInput(display, rootWin, ExposureMask |
SubstructureNotifyMask);
+
+ prepare(DisplayWidth(display, screen), DisplayHeight(display,
screen));
+ XSelectInput(display, rootWin, ExposureMask |
SubstructureNotifyMask | StructureNotifyMask);
while (!done) {
@@ -657,16 +632,29 @@
switch (ev.type) {
case Expose:
#if
debug
-
printf("EXPOSE\n");
+
printf("EXPOSE in window %d: x=%d y=%d h=%d
w=%d\n",ev.xexpose.window,ev.xexpose.x,ev.xexpose.y,ev.xexpose.height,ev.xexpose.width);
#endif
Exposed = 1;
+ #if
CLEANONEXPOSE
+ //
erase memory of accumulated snow here
+// (xsnow usually tries to be smart and to look at child window
+// positions in order to decide where to erase snow, but hence misses
+// root window redraws due e.g. to VT switching or power suspend,
+// resulting in internal snow memory not being up-to-date with visible
+// snow, and ugly snow streaks on the display)
+ SubR =
XCreateRegion();
+
AddRect.x = ev.xexpose.x;
+
AddRect.y = ev.xexpose.y;
+
AddRect.width = ev.xexpose.width;
+
AddRect.height = ev.xexpose.height;
+
XUnionRectWithRegion(&AddRect, SubR,SubR);
+
XSubtractRegion(snscr,SubR, snscr);
+
XDestroyRegion(SubR);
+ #endif
if
(!DDLT()) {
stilltddr = 1;
continue;
}
- #if
debug
-
printf("expose x:%d y:%d h:%d
w:%d\n",ev.xexpose.x,ev.xexpose.y,ev.xexpose.height,ev.xexpose.width);
- #endif
break;
case ConfigureNotify:
#if
debug
@@ -680,12 +668,24 @@
ev.xconfigure.border_width,
(rootWin == ev.xconfigure.event)
);
+ #endif
+ if
(ev.xconfigure.window == rootWin) {// background window was modified
+ if
(ev.xconfigure.width != display_width ||
+
ev.xconfigure.height != display_height) {
+ #if
debug
+
printf("Screen resolution changed. Reinitializing...\n");
+ #endif
+
prepare(ev.xconfigure.width, ev.xconfigure.height);
+ }
+ } else
{
+ #if
debug
printf("ConfigureNotify calling DDLT\n");
#endif
if
(!DDLT()) {
stilltddr = 1;
continue;
}
+ }
break;
case ConfigureRequest:
#if
debug
@@ -860,6 +860,52 @@
#endif
}
/* ------------------------------------------------------------------ */
+
+/* called before setting up event loop and everytime screen resolution changes
*/
+void
+prepare(width, height)
+int width;
+int height;
+{
+ int i;
+ // clean up
+ if (Wr != NULL) { XDestroyRegion(Wr); Wr = NULL; }
+ if (PrevWr != NULL) { XDestroyRegion(PrevWr); PrevWr = NULL; }
+ if (snscr != NULL) { XDestroyRegion(snscr); snscr = NULL; }
+ if (sar != NULL) { XDestroyRegion(sar); sar = NULL; }
+ if (WDR != NULL) { XDestroyRegion(WDR); WDR = NULL; }
+ if (CDR != NULL) { XDestroyRegion(CDR); CDR = NULL; }
+ if (rscrr != NULL) { XDestroyRegion(rscrr); rscrr = NULL; }
+ XClearWindow(display, rootWin);
+ // initialise
+ Wr = XCreateRegion();
+ PrevWr = XCreateRegion();
+ snscr = XCreateRegion();
+ sar = XCreateRegion();
+ WDR = XCreateRegion();
+ CDR = XCreateRegion();
+ rscrr = XCreateRegion();
+ display_width = width;
+ display_height = height;
+ center_x = display_width / 2;
+ center_y = display_height / 2;
+ if (MaxScrSnowDepth> (display_height-SNOWFREE)) {
+ printf("** Maximum snow depth set to %d\n",
display_height-SNOWFREE);
+ MaxScrSnowDepth = display_height-SNOWFREE;
+ }
+ AddRect.x = 0;
+ AddRect.y = display_height;
+ AddRect.width = display_width - 1;
+ AddRect.height = MaxYStep+MaxSnowFlakeHeight;
+ if (!NoKeepSBot)
+ XUnionRectWithRegion(&AddRect, snscr, snscr);
+ for (i=0; i<maxSnowflakes; i++) InitSnowflake(i);
+ rc = MWR(1);
+ XUnionRegion(Wr,PrevWr, PrevWr);
+ RCSR();
+ MASR();
+ ResetSanta();
+}
int
SnowPtInRect(snx, sny, recx, recy, width, height)
@@ -1028,6 +1074,8 @@
False);
}
}
+
+/* unused (see changelog 20DEC93) */
void
PaintSnowAtBottom(depth)
int depth;
@@ -1329,10 +1377,7 @@
&winWidth,
&winHeight, &borderWidth, &depth);
/*if (winWidth == 1280)
continue; /* debug */
#if debug
- printf("\nw x:%d y:%d w:%d h:%d
- bw:%d d:%d \n", winX,winY,winWidth,winHeight,borderWidth,depth);
- #endif
- #if debug
- printf("MakeWrx:
(x;%d\ty:%d\tx+w%d\ty+h%d)\tbw:%d d:%d\n",
+ printf("MakeWr:
x=%d\ty=%d\tx+w=%d\ty+h=%d,\tbw:%d depth:%d\n",
winX,winY,winX+winWidth,winY+winHeight,borderWidth,depth);
#endif
if (errorVal) continue;
@@ -1340,11 +1385,17 @@
WinRect.y = winY;
WinRect.height = winHeight +
2*borderWidth;
WinRect.width = winWidth +
2*borderWidth;
+ // zap invisible windows
if (WinRect.x >= display_width)
continue;
if (WinRect.y >=
display_height) continue;
- if (WinRect.y <= 0) continue;
- if ((WinRect.x + WinRect.width)
< 0) continue;
+ if (WinRect.y < 0) continue;
+ if ((WinRect.x + WinRect.width)
<= 0) continue;
XUnionRectWithRegion(&WinRect,Wr, Wr);
+ #if debug
+ XClipBox( Wr, &WinRect );
+ printf("Wr now:
x=%d\ty=%d\tx+w=%d\ty+h=%d\n",
+
WinRect.x,WinRect.y,WinRect.x+WinRect.width,WinRect.y+WinRect.height);
+ #endif
}
}
XFree((char *)children);
@@ -1355,6 +1406,8 @@
#endif
return 1;
}
+/** add to the region snscr strips of height
+ MaxYStep+MaxSnowFlakeHeight below every window-top */
void RCSR() {
XDestroyRegion(rscrr);
rscrr = XCreateRegion();
@@ -1369,6 +1422,7 @@
XUnionRegion(rscrr,snscr, snscr);
if (SnowOffset != 0) XOffsetRegion(snscr,0,SnowOffset);
}
+/** create region 'sar' where snow may accumulate */
void MASR() {
XRectangle AllowRect;
XDestroyRegion(sar);
@@ -1378,7 +1432,7 @@
XOffsetRegion(sar, 0,-MaxWinSnowDepth);
XSubtractRegion(sar,Wr, sar);
}
- if (!NoKeepSWin) {
+ if (!NoKeepSBot) {
AllowRect.x = 0;
AllowRect.y = display_height - MaxScrSnowDepth;
AllowRect.width = display_width - 1;
@@ -1436,6 +1490,8 @@
#endif
return 1;
}
+/** clear a given rectangle and remove it (plus margins related to
+ flake-size and snow-movement) from the snow-region snscr */
void HEAr(int X,int Y,int W, int H) {
int AddX,AddY;
int ClearX, ClearY;
------------ END: diff-patch for xsnow.c --------------
------------ BEGIN: diff-patch for xsnow.h --------------
--- xsnow-1.42/xsnow.h 2000-12-19 21:24:58.000000000 +0100
+++ xsnow-1.42resizeable/xsnow.h 2010-02-06 20:58:21.000000000 +0100
@@ -9,6 +9,10 @@
#define INITIALSCRPAINTSNOWDEPTH 8 /* Painted in advance */
#define INITSCRSNOWDEPTH 50 /* Will build up to INITSCRSNOWDEPTH */
#define SNOWFREE 25 /* Must stay snowfree on display :) */
+#define CLEANONEXPOSE 1 /* clean memory of accumulated snow on expose
+ events without window change (e.g. VT
+ switching); increases server burden
+ during window movements */
/* ------------------------------------------------------------------ */
------------ END: diff-patch for xsnow.h --------------
-- System Information:
Debian Release: squeeze/sid
APT prefers unstable
APT policy: (500, 'unstable'), (500, 'testing')
Architecture: i386 (i686)
Kernel: Linux 2.6.32-trunk-686 (SMP w/1 CPU core)
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/bash
Versions of packages xsnow depends on:
ii libc6 2.10.2-5 Embedded GNU C Library: Shared lib
ii libx11-6 2:1.3.3-1 X11 client-side library
ii libxext6 2:1.1.1-2 X11 miscellaneous extension librar
ii libxpm4 1:3.5.8-1 X11 pixmap library
ii procps 1:3.2.8-5 /proc file system utilities
xsnow recommends no packages.
xsnow suggests no packages.
-- no debconf information
--
To UNSUBSCRIBE, email to [email protected]
with a subject of "unsubscribe". Trouble? Contact [email protected]