X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=hacks%2Fscreenhack.c;h=7199c77bc879aa703652f739804fe003ae0084be;hb=6afd6db0ae9396cd7ff897ade597cd5483f49b0e;hp=443d3f423745562b89165e8df92fa620caad08ec;hpb=de460e831dc8578acfa8b72251ab9346c99c1f96;p=xscreensaver diff --git a/hacks/screenhack.c b/hacks/screenhack.c index 443d3f42..7199c77b 100644 --- a/hacks/screenhack.c +++ b/hacks/screenhack.c @@ -1,4 +1,4 @@ -/* xscreensaver, Copyright (c) 1992-2008 Jamie Zawinski +/* xscreensaver, Copyright (c) 1992-2014 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 @@ -43,10 +43,16 @@ Called when a keyboard or mouse event arrives. Return True if you handle it in some way, False otherwise. - static void YOURNAME_event (Display *, Window, void *closure); + static void YOURNAME_free (Display *, Window, void *closure); Called when you are done: free everything you've allocated, - including your private `state' structure. + including your private `state' structure. + + NOTE: this is called in windowed-mode when the user typed + 'q' or clicks on the window's close box; but when + xscreensaver terminates this screenhack, it does so by + killing the process with SIGSTOP. So this callback is + mostly useless. static char YOURNAME_defaults [] = { "...", "...", ... , 0 }; @@ -68,7 +74,7 @@ - Do not use global variables: all such info must be stored in the private `state' structure. - - Do not static function-local variables, either. Put it in `state'. + - Do not use static function-local variables, either. Put it in `state'. Assume that there are N independent runs of this code going in the same address space at the same time: they must not affect each other. @@ -77,7 +83,6 @@ of your screen saver module. See .../hacks/config/README for details. */ -#define DEBUG_TIMING #define DEBUG_PAIR #include @@ -105,6 +110,7 @@ #include "screenhackI.h" #include "version.h" #include "vroot.h" +#include "fps.h" #ifndef _XSCREENSAVER_VROOT_H_ # error Error! You have an old version of vroot.h! Check -I args. @@ -136,6 +142,8 @@ static XrmOptionDescRec default_options [] = { { "-noinstall",".installColormap", XrmoptionNoArg, "False" }, { "-visual", ".visualID", XrmoptionSepArg, 0 }, { "-window-id", ".windowID", XrmoptionSepArg, 0 }, + { "-fps", ".doFPS", XrmoptionNoArg, "True" }, + { "-no-fps", ".doFPS", XrmoptionNoArg, "False" }, # ifdef DEBUG_PAIR { "-pair", ".pair", XrmoptionNoArg, "True" }, @@ -145,9 +153,11 @@ static XrmOptionDescRec default_options [] = { static char *default_defaults[] = { ".root: false", - "*geometry: 600x480", /* this should be .geometry, but nooooo... */ + "*geometry: 1280x720", /* this should be .geometry, but noooo... */ "*mono: false", "*installColormap: false", + "*doFPS: false", + "*multiSample: false", "*visualID: default", "*windowID: ", "*desktopGrabber: xscreensaver-getimage %s", @@ -158,6 +168,7 @@ static XrmOptionDescRec *merged_options; static int merged_options_size; static char **merged_defaults; + static void merge_options (void) { @@ -211,6 +222,8 @@ merge_options (void) strcat (newr, oldr); *s = newr; } + else + *s = strdup (*s); } } @@ -407,65 +420,6 @@ fix_fds (void) } -#ifdef DEBUG_TIMING - -static void -check_timing (unsigned long delay) -{ - static unsigned long frame_count = 0; - static unsigned long delay_sum = 0; - static struct timeval prev1 = { 0, }; - static struct timeval prev2 = { 0, }; - struct timeval now; - double uprev1, uprev2, unow; - -# ifdef GETTIMEOFDAY_TWO_ARGS - gettimeofday (&now, 0); -# else - gettimeofday (&now); -# endif - - if (prev1.tv_sec == 0) - prev1 = prev2 = now; - - frame_count++; - - uprev1 = prev1.tv_sec + ((double) prev1.tv_usec * 0.000001); - uprev2 = prev2.tv_sec + ((double) prev2.tv_usec * 0.000001); - unow = now.tv_sec + ((double) now.tv_usec * 0.000001); - - if (unow >= uprev1 + 1.5) - fprintf (stderr, - "%s: warning: blocked event processing for %.1f secs!\n", - progname, unow - uprev1); - prev1 = now; - - if (unow >= uprev2 + 10.0) - { - double fps = frame_count / (unow - uprev2); - double elapsed = unow - uprev2; - double slept = (delay_sum * 0.000001); - double sleep_ratio = slept / elapsed; - - if (sleep_ratio < 0.10) { - fprintf (stderr, - "%s: warning: only %.0f%% idle over the" - " last %2.0f secs (at %.1f FPS)\n", - progname, 100 * sleep_ratio, elapsed, fps); - } - - prev2 = now; - frame_count = 0; - delay_sum = 0; - } - - delay_sum += delay; -} - -#else /* !DEBUG_TIMING */ -# define check_timing(delay) /**/ -#endif /* !DEBUG_TIMING */ - static Boolean screenhack_table_handle_events (Display *dpy, const struct xscreensaver_function_table *ft, @@ -491,7 +445,7 @@ screenhack_table_handle_events (Display *dpy, ft->reshape_cb (dpy, window, closure, event.xconfigure.width, event.xconfigure.height); #ifdef DEBUG_PAIR - if (event.xany.window == window2) + if (window2 && event.xany.window == window2) ft->reshape_cb (dpy, window2, closure2, event.xconfigure.width, event.xconfigure.height); #endif @@ -500,7 +454,7 @@ screenhack_table_handle_events (Display *dpy, (! (event.xany.window == window ? ft->event_cb (dpy, window, closure, &event) #ifdef DEBUG_PAIR - : event.xany.window == window2 + : (window2 && event.xany.window == window2) ? ft->event_cb (dpy, window2, closure2, &event) #endif : 0))) @@ -517,9 +471,11 @@ screenhack_table_handle_events (Display *dpy, static Boolean usleep_and_process_events (Display *dpy, const struct xscreensaver_function_table *ft, - Window window, void *closure, unsigned long delay + Window window, fps_state *fpst, void *closure, + unsigned long delay #ifdef DEBUG_PAIR - , Window window2, void *closure2, unsigned long delay2 + , Window window2, fps_state *fpst2, void *closure2, + unsigned long delay2 #endif ) { @@ -531,13 +487,13 @@ usleep_and_process_events (Display *dpy, XSync (dpy, False); if (quantum > 0) - usleep (quantum); - - check_timing (quantum); - - /* The above isn't quite right in pair-mode: we always run both windows - with the timing of window 2. But, it's just a debugging hack, so - that doesn't really matter that much... */ + { + usleep (quantum); + if (fpst) fps_slept (fpst, quantum); +#ifdef DEBUG_PAIR + if (fpst2) fps_slept (fpst2, quantum); +#endif + } if (! screenhack_table_handle_events (dpy, ft, window, closure #ifdef DEBUG_PAIR @@ -551,6 +507,14 @@ usleep_and_process_events (Display *dpy, } +static void +screenhack_do_fps (Display *dpy, Window w, fps_state *fpst, void *closure) +{ + fps_compute (fpst, 0, -1); + fps_draw (fpst); +} + + static void run_screenhack_table (Display *dpy, Window window, @@ -567,16 +531,23 @@ run_screenhack_table (Display *dpy, void *(*init_cb) (Display *, Window, void *) = (void *(*) (Display *, Window, void *)) ft->init_cb; + void (*fps_cb) (Display *, Window, fps_state *, void *) = ft->fps_cb; + void *closure = init_cb (dpy, window, ft->setup_arg); + fps_state *fpst = fps_init (dpy, window); #ifdef DEBUG_PAIR void *closure2 = 0; + fps_state *fpst2 = 0; if (window2) closure2 = init_cb (dpy, window2, ft->setup_arg); + if (window2) fpst2 = fps_init (dpy, window2); #endif if (! closure) /* if it returns nothing, it can't possibly be re-entrant. */ abort(); + if (! fps_cb) fps_cb = screenhack_do_fps; + while (1) { unsigned long delay = ft->draw_cb (dpy, window, closure); @@ -585,20 +556,26 @@ run_screenhack_table (Display *dpy, if (window2) delay2 = ft->draw_cb (dpy, window2, closure2); #endif + if (fpst) fps_cb (dpy, window, fpst, closure); +#ifdef DEBUG_PAIR + if (fpst2) fps_cb (dpy, window, fpst2, closure); +#endif + if (! usleep_and_process_events (dpy, ft, - window, closure, delay + window, fpst, closure, delay #ifdef DEBUG_PAIR - , window2, closure2, delay2 + , window2, fpst2, closure2, delay2 #endif )) break; } ft->free_cb (dpy, window, closure); + if (fpst) fps_free (fpst); #ifdef DEBUG_PAIR - if (window2) - ft->free_cb (dpy, window2, closure2); + if (window2) ft->free_cb (dpy, window2, closure2); + if (fpst2) fps_free (fpst2); #endif } @@ -614,11 +591,6 @@ make_shell (Screen *screen, Widget toplevel, int width, int height) if (width <= 0) width = 600; if (height <= 0) height = 480; -# ifdef USE_GL - if (!validate_gl_visual (stderr, screen, "window", visual)) - exit (1); -# endif /* USE_GL */ - if (def_visual_p) { Window window; @@ -755,13 +727,17 @@ main (int argc, char **argv) { char *v = (char *) strdup(strchr(screensaver_id, ' ')); char *s1, *s2, *s3, *s4; + const char *ot = get_string_resource (dpy, "title", "Title"); s1 = (char *) strchr(v, ' '); s1++; s2 = (char *) strchr(s1, ' '); s3 = (char *) strchr(v, '('); s3++; s4 = (char *) strchr(s3, ')'); *s2 = 0; *s4 = 0; - sprintf (version, "%s: from the XScreenSaver %s distribution (%s.)", + if (ot && !*ot) ot = 0; + sprintf (version, "%.50s%s%s: from the XScreenSaver %s distribution (%s)", + (ot ? ot : ""), + (ot ? ": " : ""), progclass, s1, s3); free(v); } @@ -837,6 +813,12 @@ main (int argc, char **argv) exit (help_p ? 0 : 1); } + { + char **s; + for (s = merged_defaults; *s; s++) + free(*s); + } + free (merged_options); free (merged_defaults); merged_options = 0;