X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=hacks%2Fscreenhack.c;h=089e76b44b9dfed76537cd3ae1a52062c2e59cb6;hb=4ade52359b6eba3621566dac79793a33aa4c915f;hp=f4db428a2d9db1a8fbc130cf1e5b65bf3d87ec71;hpb=49f5b54f312fe4ac2e9bc47581a72451bd0e8439;p=xscreensaver diff --git a/hacks/screenhack.c b/hacks/screenhack.c index f4db428a..089e76b4 100644 --- a/hacks/screenhack.c +++ b/hacks/screenhack.c @@ -1,4 +1,4 @@ -/* xscreensaver, Copyright (c) 1992-2006 Jamie Zawinski +/* xscreensaver, Copyright (c) 1992-2013 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,10 +110,7 @@ #include "screenhackI.h" #include "version.h" #include "vroot.h" -#include "change_locale.h" -#if HAVE_SETLOCALE -#include -#endif +#include "fps.h" #ifndef _XSCREENSAVER_VROOT_H_ # error Error! You have an old version of vroot.h! Check -I args. @@ -140,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" }, @@ -152,6 +156,8 @@ static char *default_defaults[] = { "*geometry: 600x480", /* this should be .geometry, but nooooo... */ "*mono: false", "*installColormap: false", + "*doFPS: false", + "*multiSample: false", "*visualID: default", "*windowID: ", "*desktopGrabber: xscreensaver-getimage %s", @@ -162,26 +168,6 @@ static XrmOptionDescRec *merged_options; static int merged_options_size; static char **merged_defaults; -static void -reset_locale (void) -{ -#ifdef HAVE_SETLOCALE - const char *current_locale = setlocale(LC_ALL, ""); - const char *cmp_locale; - int j = 0; - - while ((cmp_locale = change_locale[j])) - { - if (!strncmp(current_locale, cmp_locale, strlen(cmp_locale))) - { - setlocale(LC_ALL, "C"); - break; - } - j++; - } -#endif /* HAVE_SETLOCALE */ -} - static void merge_options (void) @@ -236,6 +222,8 @@ merge_options (void) strcat (newr, oldr); *s = newr; } + else + *s = strdup (*s); } } @@ -432,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, @@ -516,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 @@ -525,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))) @@ -542,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 ) { @@ -556,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 @@ -576,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, @@ -592,38 +531,51 @@ 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); #ifdef DEBUG_PAIR - unsigned long delay2; + unsigned long delay2 = 0; 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 } @@ -639,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; @@ -709,7 +656,7 @@ init_window (Display *dpy, Widget toplevel, const char *title) window = XtWindow (toplevel); XGetWindowAttributes (dpy, window, &xgwa); XSelectInput (dpy, window, - (xgwa.your_event_mask | KeyPressMask | + (xgwa.your_event_mask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask)); XChangeProperty (dpy, window, XA_WM_PROTOCOLS, XA_ATOM, 32, PropModeReplace, @@ -738,7 +685,6 @@ main (int argc, char **argv) char version[255]; fix_fds(); - reset_locale(); progname = argv[0]; /* reset later */ progclass = ft->progclass; @@ -781,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); } @@ -863,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; @@ -908,6 +864,8 @@ main (int argc, char **argv) window = VirtualRootWindowOfScreen (XtScreen (toplevel)); XtDestroyWidget (toplevel); XGetWindowAttributes (dpy, window, &xgwa); + /* With RANDR, the root window can resize! */ + XSelectInput (dpy, window, xgwa.your_event_mask | StructureNotifyMask); visual_warning (xgwa.screen, window, xgwa.visual, xgwa.colormap, False); } else