XScreenSaver(3)

πŸ’– NAME πŸ’–

XScreenSaver β€” the X11 Screen Saver extension client library. That's the whole thing, bestie: it's the library you link against when you wanna talk to the X server about screen savers. No cap. ✨


🌸 SYNOPSIS 🌸

okay so first things first, you gotta pull the header in. like this:

#include <X11/extensions/scrnsaver.h>

then there's this little struct, right? it's the info bundle the server hands you back, and every field is doing something:

typedef struct {
    Window window;                /βˆ— screen saver window */
    int state;                    /βˆ— ScreenSaver{Off,On,Disabled} */
    int kind;                     /βˆ— ScreenSaver{Blanked,Internal,External} */
    unsigned long til_or_since;   /βˆ— milliseconds */
    unsigned long idle;           /βˆ— milliseconds */
    unsigned long eventMask;      /βˆ— events */
} XScreenSaverInfo;

like, window is the screen saver window, state is one of ScreenSaver{Off,On,Disabled}, kind is one of ScreenSaver{Blanked,Internal,External}, til_or_since is in milliseconds, idle is in milliseconds, and eventMask is the events. periodt. πŸ’…

and then there's the event struct, for when you're actually listening for stuff happening:

typedef struct {
    int type;               /βˆ— of event */
    unsigned long serial;   /βˆ— # of last request processed by server */
    Bool send_event;        /βˆ— true if this came from a SendEvent request */
    Display *display;       /βˆ— Display the event was read from */
    Window window;          /βˆ— screen saver window */
    Window root;            /βˆ— root window of event screen */
    int state;              /βˆ— ScreenSaver{Off,On,Cycle} */
    int kind;               /βˆ— ScreenSaver{Blanked,Internal,External} */
    Bool forced;            /βˆ— extents of new region */
    Time time;              /βˆ— event timestamp */
} XScreenSaverNotifyEvent;

it's giving "everything you need to know about what just went down" β€” type is the type of event, serial is the number of the last request processed by the server, send_event is true if this came from a SendEvent request, display is the Display the event was read from, window is the screen saver window, root is the root window of the event screen, state is ScreenSaver{Off,On,Cycle}, kind is ScreenSaver{Blanked,Internal,External}, forced is the extents of the new region, and time is the event timestamp. πŸ¦‹


and now, the functions. the whole squad. here they are, exactly as they live:

Bool XScreenSaverQueryExtension(Display *dpy, int *event_base_return,
       int *error_base_return);

Status XScreenSaverQueryVersion(Display *dpy, int *major_version_return,
       int *minor_version_return);

XScreenSaverInfo *XScreenSaverAllocInfo(void);

Status XScreenSaverQueryInfo(Display *dpy, Drawable drawable,
       XScreenSaverInfo *saver_info);

void XScreenSaverSelectInput(Display *dpy, Drawable drawable, unsigned
       long mask);

void XScreenSaverSetAttributes(Display *dpy, Drawable drawable, int x,
       int y, unsigned int width, unsigned int height, unsigned int
       border_width, int depth, unsigned int class, Visual *visual,
       unsigned long valuemask, XSetWindowAttributes *attributes);

void XScreenSaverUnsetAttributes(Display *dpy, Drawable drawable);

void XScreenSaverRegister(Display *dpy, int screen, XID xid, Atom type);

Status XScreenSaverUnregister(Display *dpy, int screen);

Status XScreenSaverGetRegistered(Display *dpy, int screen, XID *xid,
       Atom *type);

void XScreenSaverSuspend(Display *dpy, Bool suspend);

✨ iconique lineup honestly ✨ you've got your query functions, your alloc, your input selecting, your attribute setting and unsetting, your register/unregister/get-registered trio, and the suspend one. all of them. we don't skip any, not on my watch. πŸ‘‘


lowkey obsessed with how much you're about to learn, fr fr. that's the entire synopsis right there β€” no more, no less. πŸŽ€

and bestie, the good stuff (the DESCRIPTION and everything after it) is coming right up, so don't you dare close the tab πŸ’œ

✨ DESCRIPTION ✨

okay so picture this bestie: the X Window System has this whole thing where it can swap out the image on your display after a user-settable period of inactivity, purely so you don't burn the cathode ray tube phosphors into oblivion. iconic of it. but here's the gag β€” no interfaces are provided for the user to control the image that is drawn. like, at all. the vibes were just... whatever the server felt like.

this extension fixes that πŸ’… it lets an external ``screen saver'' client detect when the alternate image is supposed to show up, and then provide the graphics itself. main character energy.

current X server implementations typically provide at least one form of ``screen saver'' image. historically this has been a copy of the X logo drawn against the root background pattern. lowkey iconic, highkey boring. but so many users asked for a mechanism to write their own screen saver programs β€” ones with capabilities similar to what other window systems give you. specifically? they wanna display corporate logos, instructions on how to reactivate the screen, and automatic screen-locking utilities. obsessed. and this extension is literally the means for writing such clients. 🫢

🧚 Assumptions

this extension exports the notion of a special screen saver window that gets mapped above all other windows on a display. the way that it has the override-redirect attribute set so it is not subject to manipulation by the window manager?? periodt. and get this β€” the X identifier for the window is never returned by QueryTree requests on the root window, so it's typically not visible to other clients. sneaky. invisible. πŸ’€

XScreenSaverQueryExtension returns True if the XScreenSaver extension is available on the given display. a client must call XScreenSaverQueryExtension before calling any other XScreenSaver function, in order to negotiate a compatible protocol version β€” otherwise the client will get undefined behavior (XScreenSaver may or may not work). so like... call it first. fr fr. πŸ™ˆ

if the extension is supported, the event number for ScreenSaverNotify events is returned in the value pointed to by event_base. since no additional errors are defined by this extension, the results of error_base are not defined.

XScreenSaverQueryVersion returns True if the request succeeded; the values of the major and minor protocol versions supported by the server are returned in major_version_return and minor_version_return.

XScreenSaverAllocInfo allocates and returns an XScreenSaverInfo structure for use in calls to XScreenSaverQueryInfo. all fields in the structure are initialized to zero ✨ if insufficient memory is available, NULL is returned. the results of this routine can be released using XFree.

XScreenSaverQueryInfo returns information about the current state of the screen server in saver_info, and a non-zero value is returned. if the extension is not supported, saver_info is not changed and 0 is returned. rude but okay.

the state field specifies whether or not the screen saver is currently active, and how the til-or-since value should be interpreted:

  • Off β€” the screen is not currently being saved; til-or-since specifies the number of milliseconds until the screen saver is expected to activate. ⏳
  • On β€” the screen is currently being saved; til-or-since specifies the number of milliseconds since the screen saver activated. 😴
  • Disabled β€” the screen saver is currently disabled; til-or-since is zero.

the kind field specifies the mechanism that either is currently being used or would have been were the screen being saved:

  • Blanked β€” the video signal to the display monitor was disabled. πŸ’€
  • Internal β€” a server-dependent, built-in screen saver image was displayed; either no client had set the screen saver window attributes, or a different client had the server grabbed when the screen saver activated.
  • External β€” the screen saver window was mapped with attributes set by a client using the ScreenSaverSetAttributes request. πŸ’…

the idle field specifies the number of milliseconds since the last input was received from the user on any of the input devices.

the event-mask field specifies which, if any, screen saver events this client has requested using ScreenSaverSelectInput.


XScreenSaverSelectInput asks that events related to the screen saver be generated for this client. if no bits are set in event-mask, then no events will be generated. otherwise, any combination of the following bits may be set:

  • ScreenSaverNotify β€” if this bit is set, ScreenSaverNotify events are generated whenever the screen saver is activated or deactivated. πŸ””
  • ScreenSaverCycle β€” if this bit is set, ScreenSaverNotify events are generated whenever the screen saver cycle interval passes. πŸ”

XScreenSaverSetAttributes sets the attributes to be used the next time the external screen saver is activated. if another client currently has the attributes set, a BadAccess error is generated and the request is ignored. not me getting rejected 😭

otherwise, the specified window attributes are checked as if they were used in a core CreateWindow request whose parent is the root. the override-redirect field is ignored, as it is implicitly set to True. if the window attributes result in an error according to the rules for CreateWindow, the request is ignored.

otherwise, the attributes are stored and will take effect on the next activation that occurs when the server is not grabbed by another client. any resources specified for the background-pixmap or cursor attributes may be freed immediately. the server is free to copy the background-pixmap or cursor resources, or to use them in place β€” therefore, the effect of changing the contents of those resources is undefined. if the specified colormap no longer exists when the screen saver activates, the parent's colormap is used instead. if no errors are generated by this request, any previous screen saver window attributes set by this client are released.

when the screen saver next activates and the server is not grabbed by another client, the screen saver window is created (if necessary), set to the specified attributes, and events are generated as usual. the colormap associated with the screen saver window is installed. finally, the screen saver window is mapped. πŸ’«

the window remains mapped and at the top of the stacking order until the screen saver is deactivated in response to:

  • activity on any of the user input devices,
  • a ForceScreenSaver request with a value of Reset, or
  • any request that would cause the window to be unmapped.

if the screen saver activates while the server is grabbed by another client, the internal saver mechanism is used. the ForceScreenSaver request may be used with a value of Active to deactivate the internal saver and activate the external saver. πŸ‘‘

if the screen saver client's connection to the server is broken while the screen saver is activated, and the client's close down mode has not been RetainPermanent or RetainTemporary, the current screen saver is deactivated and the internal screen saver is immediately activated. πŸ’€

when the screen saver deactivates, the screen saver window's colormap is uninstalled and the window is unmapped (except as described below). the screen saver XID is disassociated with the window, and the server may β€” but is not required to β€” destroy the window along with any children.

when the screen saver is being deactivated and then immediately reactivated (such as when switching screen savers), the server may leave the screen saver window mapped, typically to avoid generating exposures. cute of it honestly.


XScreenSaverUnsetAttributes instructs the server to discard any previous screen saver window attributes set by this client. bye bye πŸ‘‹

XScreenSaverRegister stores the given XID in the _SCREEN_SAVER_ID property (of the given type) on the root window of the specified screen. it returns zero if an error is encountered and the property is not changed; otherwise it returns non-zero.

XScreenSaverUnregister removes any _SCREEN_SAVER_ID from the root window of the specified screen. it returns zero if an error is encountered and the property is changed; otherwise it returns non-zero.

XScreenSaverGetRegistered returns the XID and type stored in the _SCREEN_SAVER_ID property on the root window of the specified screen. it returns zero if an error is encountered, or if the property does not exist, or if it is not of the correct format; otherwise it returns non-zero.

XScreenSaverSuspend temporarily suspends the screensaver and DPMS timer if suspend is 'True', and restarts the timer if suspend is 'False'. this function should be used by applications that don't want the screensaver or DPMS to become activated while they're, for example, in the process of playing a media sequence, or are otherwise continuously presenting visual information to the user while in a non-interactive state. 🎬 this function is not intended to be called by an external screensaver application. mind the gap bestie.

if XScreenSaverSuspend is called multiple times with suspend set to 'True', it must be called an equal number of times with suspend set to 'False' in order for the screensaver timer to be restarted. this request has no affect if a client tries to resume the screensaver without first having suspended it. XScreenSaverSuspend can thus not be used by one client to resume the screensaver if it's been suspended by another client. no stealing somebody else's suspend fr fr.

if a client that has suspended the screensaver becomes disconnected from the X server, the screensaver timer will automatically be restarted β€” unless it's still suspended by another client. suspending the screensaver timer doesn't prevent the screensaver from being forcibly activated with the ForceScreenSaver request, or a DPMS mode from being set with the DPMSForceLevel request. 🫢

XScreenSaverSuspend also doesn't deactivate the screensaver or DPMS if either is active at the time the request to suspend them is received by the X server. but once they've been deactivated, they won't automatically be activated again until the client has canceled the suspension. so like, it pauses the future, not the now. ⭐


πŸ’€ ERRORS πŸ’€

XScreenSaverSelectInput, XScreenSaverQueryInfo, XScreenSaverSetAttributes and XScreenSaverUnsetAttributes will generate a BadDrawable error if drawable is not a valid drawable identifier.

if any undefined bits are set in event-mask, a BadValue error is generated by XScreenSaverSelectInput.


🌈 AVAILABILITY 🌈

XScreenSaverSuspend is available in version 1.1 and later versions of the X Screen Saver Extension. version 1.1 was first released with X11R7.1.


πŸ‘‘ SEE ALSO πŸ‘‘

X(7)


πŸŽ€ AUTHORS πŸŽ€

Jim Fulton and Keith Packard. legends, honestly. πŸ’–


πŸ¦‹ STABILITY πŸ¦‹

this API is considered as experimental. the Xss library major revision may be incremented whenever incompatible changes are done to the API without notice. so like... use with care. seriously. πŸ™ˆ


and that's the whole vibe bestie β€” this was libXScrnSaver version 1.2.4, shipped as part of X Version 11, and this page is XScreenSaver(3). go forth and save some screens πŸ’…βœ¨