X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=utils%2Ffade.c;h=18e940680a1fb8d607118d66ac68e57058a12f23;hb=bbd0773f2adde4927a6196361d4061e70bf48cd9;hp=00eb9d1ad0610aec7c0fc5a94b72602f6fe0ea5e;hpb=8eb2873d7054e705c4e83f22d18c40946a9e2529;p=xscreensaver diff --git a/utils/fade.c b/utils/fade.c index 00eb9d1a..18e94068 100644 --- a/utils/fade.c +++ b/utils/fade.c @@ -1,4 +1,4 @@ -/* xscreensaver, Copyright (c) 1992-2001 Jamie Zawinski +/* xscreensaver, Copyright (c) 1992-2003 Jamie Zawinski * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -73,24 +73,28 @@ blacken_colormap (Screen *screen, Colormap cmap) static void fade_screens_1 (Display *dpy, Colormap *cmaps, - Window *black_windows, int seconds, int ticks, + Window *black_windows, int nwindows, + int seconds, int ticks, Bool out_p, Bool clear_windows); #ifdef HAVE_SGI_VC_EXTENSION static int sgi_gamma_fade (Display *dpy, - Window *black_windows, int seconds, int ticks, + Window *black_windows, int nwindows, + int seconds, int ticks, Bool out_p, Bool clear_windows); #endif /* HAVE_SGI_VC_EXTENSION */ #ifdef HAVE_XF86VMODE_GAMMA static int xf86_gamma_fade (Display *dpy, - Window *black_windows, int seconds, int ticks, + Window *black_windows, int nwindows, + int seconds, int ticks, Bool out_p, Bool clear_windows); #endif /* HAVE_XF86VMODE_GAMMA */ void -fade_screens (Display *dpy, Colormap *cmaps, Window *black_windows, +fade_screens (Display *dpy, Colormap *cmaps, + Window *black_windows, int nwindows, int seconds, int ticks, Bool out_p, Bool clear_windows) { @@ -116,7 +120,8 @@ fade_screens (Display *dpy, Colormap *cmaps, Window *black_windows, #ifdef HAVE_SGI_VC_EXTENSION /* First try to do it by fading the gamma in an SGI-specific way... */ - if (0 == sgi_gamma_fade(dpy, black_windows, seconds, ticks, out_p, + if (0 == sgi_gamma_fade(dpy, black_windows, nwindows, + seconds, ticks, out_p, clear_windows)) ; else @@ -124,7 +129,8 @@ fade_screens (Display *dpy, Colormap *cmaps, Window *black_windows, #ifdef HAVE_XF86VMODE_GAMMA /* Then try to do it by fading the gamma in an XFree86-specific way... */ - if (0 == xf86_gamma_fade(dpy, black_windows, seconds, ticks, out_p, + if (0 == xf86_gamma_fade(dpy, black_windows, nwindows, + seconds, ticks, out_p, clear_windows)) ; else @@ -132,7 +138,8 @@ fade_screens (Display *dpy, Colormap *cmaps, Window *black_windows, /* Else, do it the old-fashioned way, which (somewhat) loses if there are TrueColor windows visible. */ - fade_screens_1 (dpy, cmaps, black_windows, seconds, ticks, + fade_screens_1 (dpy, cmaps, black_windows, nwindows, + seconds, ticks, out_p, clear_windows); /* If we were supposed to be fading in, do so now (we just faded out, @@ -168,7 +175,8 @@ fade_screens (Display *dpy, Colormap *cmaps, Window *black_windows, what is implemented in sgi_gamma_fade(), so we use that if we can. */ static void -fade_screens_1 (Display *dpy, Colormap *cmaps, Window *black_windows, +fade_screens_1 (Display *dpy, Colormap *cmaps, + Window *black_windows, int nwindows, int seconds, int ticks, Bool out_p, Bool clear_windows) { @@ -286,7 +294,7 @@ fade_screens_1 (Display *dpy, Colormap *cmaps, Window *black_windows, installed = True; if (black_windows && !out_p) - for (j = 0; j < nscreens; j++) + for (j = 0; j < nwindows; j++) if (black_windows[j]) { XUnmapWindow (dpy, black_windows[j]); @@ -341,7 +349,7 @@ fade_screens_1 (Display *dpy, Colormap *cmaps, Window *black_windows, */ if (out_p && black_windows) { - for (i = 0; i < nscreens; i++) + for (i = 0; i < nwindows; i++) { if (clear_windows) XClearWindow (dpy, black_windows[i]); @@ -400,7 +408,8 @@ static void sgi_whack_gamma(Display *dpy, int screen, static int sgi_gamma_fade (Display *dpy, - Window *black_windows, int seconds, int ticks, + Window *black_windows, int nwindows, + int seconds, int ticks, Bool out_p, Bool clear_windows) { int steps = seconds * ticks; @@ -472,17 +481,18 @@ sgi_gamma_fade (Display *dpy, way down to 0, then take the windows off the screen. */ if (!out_p) - for (screen = 0; screen < nscreens; screen++) - { + { + for (screen = 0; screen < nscreens; screen++) sgi_whack_gamma(dpy, screen, &info[screen], 0.0); + + for (screen = 0; screen < nwindows; screen++) if (black_windows && black_windows[screen]) { XUnmapWindow (dpy, black_windows[screen]); XClearWindow (dpy, black_windows[screen]); XSync(dpy, False); } - } - + } /* Iterate by steps of the animation... */ for (i = (out_p ? steps : 0); @@ -536,7 +546,7 @@ sgi_gamma_fade (Display *dpy, if (out_p && black_windows) { - for (screen = 0; screen < nscreens; screen++) + for (screen = 0; screen < nwindows; screen++) { if (clear_windows) XClearWindow (dpy, black_windows[screen]); @@ -618,7 +628,8 @@ static Bool xf86_whack_gamma (Display *dpy, int screen, static int xf86_gamma_fade (Display *dpy, - Window *black_windows, int seconds, int ticks, + Window *black_windows, int nwindows, + int seconds, int ticks, Bool out_p, Bool clear_windows) { int steps = seconds * ticks; @@ -698,17 +709,17 @@ xf86_gamma_fade (Display *dpy, way down to 0, then take the windows off the screen. */ if (!out_p) - for (screen = 0; screen < nscreens; screen++) - { + { + for (screen = 0; screen < nscreens; screen++) xf86_whack_gamma(dpy, screen, &info[screen], 0.0); + for (screen = 0; screen < nwindows; screen++) if (black_windows && black_windows[screen]) { XUnmapWindow (dpy, black_windows[screen]); XClearWindow (dpy, black_windows[screen]); XSync(dpy, False); } - } - + } /* Iterate by steps of the animation... */ for (i = (out_p ? steps : 0); @@ -762,7 +773,7 @@ xf86_gamma_fade (Display *dpy, if (out_p && black_windows) { - for (screen = 0; screen < nscreens; screen++) + for (screen = 0; screen < nwindows; screen++) { if (clear_windows) XClearWindow (dpy, black_windows[screen]); @@ -799,27 +810,66 @@ xf86_gamma_fade (Display *dpy, } +/* This bullshit is needed because the VidMode extension doesn't work + on remote displays -- but if the remote display has the extension + at all, XF86VidModeQueryExtension returns true, and then + XF86VidModeQueryVersion dies with an X error. Thank you XFree, + may I have another. + */ + +static Bool error_handler_hit_p = False; + +static int +ignore_all_errors_ehandler (Display *dpy, XErrorEvent *error) +{ + error_handler_hit_p = True; + return 0; +} + +static Bool +safe_XF86VidModeQueryVersion (Display *dpy, int *majP, int *minP) +{ + Bool result; + XErrorHandler old_handler; + XSync (dpy, False); + error_handler_hit_p = False; + old_handler = XSetErrorHandler (ignore_all_errors_ehandler); + + result = XF86VidModeQueryVersion (dpy, majP, minP); + + XSync (dpy, False); + XSetErrorHandler (old_handler); + XSync (dpy, False); + + return (error_handler_hit_p + ? False + : result); +} + + + /* VidModeExtension version 2.0 or better is needed to do gamma. 2.0 added gamma values; 2.1 added gamma ramps. */ -# define XF86_VIDMODE_NAME "XFree86-VidModeExtension" # define XF86_VIDMODE_GAMMA_MIN_MAJOR 2 # define XF86_VIDMODE_GAMMA_MIN_MINOR 0 # define XF86_VIDMODE_GAMMA_RAMP_MIN_MAJOR 2 # define XF86_VIDMODE_GAMMA_RAMP_MIN_MINOR 1 + + /* Returns 0 if gamma fading not available; 1 if only gamma value setting is available; 2 if gamma ramps are available. */ static int xf86_check_gamma_extension (Display *dpy) { - int op, event, error, major, minor; + int event, error, major, minor; - if (!XQueryExtension (dpy, XF86_VIDMODE_NAME, &op, &event, &error)) + if (!XF86VidModeQueryExtension (dpy, &event, &error)) return 0; /* display doesn't have the extension. */ - if (!XF86VidModeQueryVersion (dpy, &major, &minor)) + if (!safe_XF86VidModeQueryVersion (dpy, &major, &minor)) return 0; /* unable to get version number? */ if (major < XF86_VIDMODE_GAMMA_MIN_MAJOR ||