From http://www.jwz.org/xscreensaver/xscreensaver-5.39.tar.gz
[xscreensaver] / README.hacking
index 2b0db90af7cebe9386a807363a5db2da4320d622..6fc2fe583c40370f0fc96f3dce9830d79ae170a7 100644 (file)
@@ -5,6 +5,19 @@
 
 ==========================================================================
 
+Any program that can be made to render on an X window created by another
+process can be used as a screen saver.  Just get the window ID out of
+$XSCREENSAVER_WINDOW, draw on that, and you're done.
+
+In theory, you can write a screen saver in any language you like.  In
+practice, however, languages other than C or C++ tend not to allow you to
+draw to windows that they did not create themselves.  Unfortunately, this
+means that if you want to write a screen saver, you must write it in C.
+
+Given that you're going to be writing in C, you might as well take
+advantage of the various utility functions that I have written to make
+that easier.  Writing a new screen saver in C using the frameworks
+included with xscreensaver simplifies things enormously.
 
 Generally, the best way to learn how to do something is to find a similar
 program, and play around with it until you understand it.  Another
@@ -14,8 +27,8 @@ xscreensaver demos, included in the "hacks/" directory, rename the file,
 and edit it until it does what you want.
 
 The "Greynetic" and "Deluxe" hacks are probably good ones to start with,
-since they are so very simple.  For GL programs, "DangerBall" is a good
-example.
+since they are so very simple.  For OpenGL programs, "DangerBall" is a
+good example.
 
 
 ==========================================================================
@@ -56,9 +69,13 @@ The XScreenSaver API
       yoursavername_free     -- Free everything you've allocated.
       yoursavername_reshape  -- Called when the window is resized.
       yoursavername_event    -- Called when a keyboard or mouse event happens.
-                                The "reshape" and "event" functions are only
-                                called when running in a window (not as a
-                                screen saver). It's ok for them to do nothing.
+
+      The "event" function will only be called when running in a window
+      (not as a screen saver).  The "reshape" event will be called when the
+      window size changes, or (as a screen saver) when the display size
+      changes as a result of a RANDR event (e.g., plugging in a new monitor).
+
+      It's ok for both the "event" and "resize" functions to do nothing.
 
   - All other functions should be static.
 
@@ -75,7 +92,7 @@ The XScreenSaver API
   You may not store global state in global variables, or in function-local
   static variables.  All of your runtime state must be encapsulted in the
   "state" object created by your "init" function.  If you use global or
-  static variables, your screen saver will not work properly on MacOS.
+  static variables, your screen saver will not work properly on macOS.
 
   Do not call XSync() or XFlush().  If you think you need to do that, it
   probably means that you are you are relying on the speed of the graphics
@@ -84,29 +101,46 @@ The XScreenSaver API
 
 
 ==========================================================================
-The XLockMore API
+The xlockmore API
 ==========================================================================
 
   Some of the display modes that come with xscreensaver were ported from
-  XLock, and so, for historical reasons, they follow a slightly different
+  xlock, and so, for historical reasons, they follow a slightly different
   programming convention.  For newly-written Xlib programs, you'd be
   better off following the pattern used in hacks like "Deluxe" than in
-  hacks like "Flag".  The XLockMore ones are the ones that begin with
+  hacks like "Flag".  The xlockmore ones are the ones that begin with
   "#ifdef STANDALONE" and #include "xlockmore.h".
 
-  All of the OpenGL screen savers follow the XLockMore API.
+  But, all OpenGL screen savers have to follow the xlockmore API.
 
-  The XLockMore API is similar to the XScreenSaver API, in that you define
+  The xlockmore API is similar to the XScreenSaver API, in that you define
   (roughly) the same set of functions, but the naming conventions are
   slightly different.  Instead of "hackname_init", it's "init_hackname",
   and it should be preceeded with the pseudo-declaration ENTRYPOINT.
 
-  One annoying mis-feature of the XLockMore API is that it *requires* you
+  One annoying mis-feature of the xlockmore API is that it *requires* you
   to make use of global variables for two things: first, for each of your
   command line options; and second, for an array that holds your global
   state objects.  These are the only exceptions to the "never use global
   variables" rule.
 
+  There are a few important differences between the original xlockmore API
+  and XScreenSaver's implementation:
+
+  - XScreenSaver does not use refresh_hackname or change_hackname.
+
+  - XScreenSaver provides two additional hooks not present in xlockmore:
+    reshape_hackname, and hackname_handle_event. These are respectively
+    equivalent to hackname_reshape and hackname_event in the XScreenSaver
+    API.
+
+  - Under Xlib, MI_CLEARWINDOW doesn't clear the window immediately.
+    Instead, due to double buffering on macOS/iOS/Android, it waits until
+    after init_hackname or draw_hackname returns before clearing. Make
+    sure not to issue any Xlib drawing calls immediately after a call to
+    MI_CLEARWINDOW, as these will be erased. To clear the window
+    immediately, just use XClearWindow.
+
 
 ==========================================================================
 Programming Tips
@@ -122,15 +156,18 @@ Programming Tips
   - Don't make assumptions about the depth of the display, or whether it
     is colormapped.  You must allocate all your colors explicitly: do not
     assume you can construct an RGB value and use that as a pixel value
-    directly.  Use the utility routines provided by "utils/colors.h" to
-    simplify color allocation.
+    directly.  In particular, you can't make assumptions about whether
+    pixels are RGB, RGBA, ARGB, ABGR, or even whether they are 32, 24,
+    16 or 8 bits.  Use the utility routines provided by "utils/colors.h"
+    to simplify color allocation.
 
   - It is better to eliminate flicker by double-buffering to a Pixmap
     than by erasing and re-drawing objects.  Do not use drawing tricks
     involving XOR.
 
-  - If you use double-buffering, have a resource to turn it off. (MacOS
-    has double-buffering built in, so you'd be triple-buffering.)
+  - If you use double-buffering, have a resource to turn it off. (MacOS,
+    iOS and Android have double-buffering built in, so you'd end up
+    triple-buffering.)
 
   - Understand the differences between Pixmaps and XImages, and keep in
     mind which operations are happening in client memory and which are in
@@ -143,21 +180,19 @@ Programming Tips
 
 
 ==========================================================================
-The MacOS X Port
+macOS, iOS and Android
 ==========================================================================
 
   Though XScreenSaver started its life as an X11 program, it also now runs
-  on MacOS X.  If you do your development on an X11 system, and follow the
+  on macOS, iOS and Android, due to a maniacal collection of compatibility
+  shims.  If you do your development on an X11 system, and follow the
   usual XScreenSaver APIs, you shouldn't need to do anything special for
-  it to also work on MacOS.
+  it to also work on macOS and on phones.
 
-  The preprocessor macro HAVE_COCOA will be defined when being compiled in
-  a MacOS (Cocoa/Quartz) environment, and will be undefined when compiling
-  against "real" Xlib.
+  See the READMEs in the OSX/ and android/ directories for instructions on
+  compiling for those platforms.
 
-  To compile on MacOS, use the XCode project included in the source
-  distribution.  You shouldn't need to have X11 installed, and shouldn't
-  need to run "configure" first.  MacOS 10.4.0 and XCode 2.2 or newer are
-  required.
+  To check that an X11 saver will fit well on a mobile device, test it
+  with -geometry 640x1136 and 640x960.  That's a good first step, anyway.
 
 ==========================================================================