This is a very basic proof-of-concept demo of an XScreenSaver hack implemented in Clojure. It relies on JNA to to write to the hack window.
Build with lein uberjar
or download clj-xscreensaver-basic-demo-0.0.1-standalone.jar
.
Stop XScreenSaver with xscreensaver-command -exit
.
Edit your ~/.xscreensaver
config file and add this to the list of hacks, adjusting
the path as necessary:
"arcs" java -jar ./clj-xscreensaver-basic-demo-0.0.1-standalone.jar \n\
Start XScreenSaver with xscreensaver &
. You’ll now find a hack named "arcs" in the list when
you start xscreensaver-demo
.
XScreenSaver hacks work by drawing on a window created by the main daemon. The window id
is passed both as the XSCREENSAVER_WINDOW
environment variable and on command line to
the hack.
AWT does not support using remote window IDs in any way (I’ve tried). But JNA supports X11, which provides enough of the necessary X11 functions to get around that limiation.
Roughly, this demo follows these steps:
-
Connect to the
$DISPLAY
-
Create a new
Window
with thewindow id
of a foreign window -
Get the
XWindowAttributes
of the window -
Create an
XGCValues
to get the graphics context of that window -
Create a Java
BufferedImage
and draw on it -
Create a JNA
Memory
"buffer" -
Create an
XImage
pointing to that buffer
Then in a loop:
-
Draw on the
BufferedImage
using standard Java2D or AWT methods -
Copy the
BufferedImage
data to theMemory
buffer -
Write the image (from the buffer) to the window with
XPutImage
X related resources are freed in a shutdown hook.
I’m not sure I’ve handled the bit depth correctly. This might be using more memory than necessary.
Only 32 and 24 bit depths are currently handled.