As I’m no doubt you all remember *cough* *cough* I hacked up an Emacs-based screensaver the other year because XScreenSaver twaddles the DPMS too much. (Yes really! I mean probably! I didn’t actually look at the source code.)
My er solution used a transparent X frame to catch the mouse/keyboard so that it knew when to wake up, but did the display in Emacs itself. (Which I used to display album covers in an Emacs buffer.) This turned out to work, like, 90% of the time, but sometimes the display would just stop updating… probably because of confusion as to what was on top: Emacs or the transparent frame?
So today I finally sat down and poked around in the xelb source code to see how you put a bitmap into a window, and… it’s easy? You just basically send a xcb:PutImage message to the X server with the image data.
Easy peasy. Just look how fast it is!
OK, that’s painful to watch, right? Why not just blop it all onto the screen at once? Because if I use a width/height in the XPutImage message that’s bigger than 255, the X server just says “nuh-uh”. And that’s even after enabling big requests with:
(xcb:+request+reply x (make-instance 'xcb:bigreq:Enable))
As expected, there’s zero hits on that Google thing for this stuff, because… well… nobody does this stuff. But on the off chance they have done this… does anybody know of how to make it possible to blob over larger bitmaps into a window?
The source code is on Microsoft Github, if anybody wants to poke around…
But if it has to be done in a bitwise fashion, I can probably speed it up: It’s implemented in the most naive, slow fashion possibly. The stuff that converts a PPM image into the 255×255 32-bit blocks is what takes all the time, really, but I didn’t want to spend time doing something clever about that if there was a way to un-blockify the transfer.
So… anybody know? *crosses finger*
Hm… well, if I randomise the placement of the tiles, it’s at least a bit more fun, I guess:
Yeah, OK, I have to reimplement that…
[edit: My benchmarking was way off — the thing that takes most of the time is the xcb:PutImage transfer itself. I guess the xcb library doesn’t really … like sending off (what?) 30MB worth of data over the network connection. There’s a xcb:shm:PutImage, where you just stash the data in memory somewhere, and then out the memory location into the message, and the X server will peek into the process’ memory… I think… but I have no idea how to get the memory location on the Lisp side of Emacs.]
2 thoughts on “More Emacs Screensaver Fun”