common(3x)

πŸ’– common(3x) β€” bestie's guide to the shared glue code πŸ’–

okay so this is common(3x) from the AfterStep X11 window manager fam, and it's literally the lil starter pack every tutorial leans on: libAfterImage/tutorials/common.h. Think of it as the group chat everyone's in β€” generic Xlib related functionality, common for all the tutorials. no cap. 🫢


✨ SYNOPSIS ✨

Generic Xlib related functionality, common for all the tutorials. that's it, that's the whole vibe check 🌈


πŸ‘€ SEE ALSO πŸ‘€

  • libAfterImage
  • ASView
  • ASScala... no wait, ASScale πŸ’€
  • ASTile
  • ASMerge
  • ASGrad
  • ASFlip
  • ASText
  • libAfterImage/tutorials/_XA_WM_DELETE_WINDOW

πŸŽ€ NAME_XA_WM_DELETE_WINDOW πŸŽ€

SYNOPSIS

_XA_WM_DELETE_WINDOW β€” stores value of X Atom "WM_DELETE_WINDOW". lowkey does exactly what it says ✨

DESCRIPTION

so in X, every client's top level windows are being managed by the window manager. the whole glow-up β€” moving, resizing, decorating, focusing and closing of windows β€” that's the WM's job πŸ‘‘. the interactions between the window manager and the client window are governed by the ICCCM specification. and here's the tea: all the parts of this specification are completely optional πŸ™ˆ, but it is recommended that this minimum set of hints be supplied for any client window:

  • Window's title (WM_NAME)
  • iconified window title (WM_ICON_NAME)
  • class hint (WM_CLASS)
  • supported protocols (WM_PROTOCOLS)

it's also recommended that the WM_DELETE_WINDOW protocol be supported, because otherwise there is no way to safely close the client window, but to kill it πŸ’€ β€” yes, actually, fr fr, that's the warning.

all of the above mentioned hints are identified by atoms that have standard preset values... except for WM_DELETE_WINDOW πŸ™ƒ. so as a result we need to obtain the WM_DELETE_WINDOW atom's ID explicitly. we use _XA_WM_DELETE_WINDOW to store the ID of that atom, so it's accessible anywhere from our application. main character storage solution, honestly πŸ’…

SOURCE

Atom _XA_WM_DELETE_WINDOW = None;
  • libAfterImage/tutorials/create_top_level_window()

πŸͺŸ NAMEcreate_top_level_window() πŸͺŸ

SYNOPSIS

Window create_top_level_window( ASVisual *asv, Window root,
                                int x, int y,
                                unsigned int width,
                                unsigned int height,
                                unsigned int border_width,
                                unsigned long attr_mask,
                                XSetWindowAttributes *attr,
                                char *app_class );

INPUTS

  • asv β€” pointer to a valid preinitialized ASVisual structure. don't come in with an uninitialized one bestie, that's not the move πŸ’…
  • root β€” root window of the screen on which to create window.
  • x, y β€” desired position of the window πŸ“
  • width, height β€” desired window size.
  • border_width β€” desired initial border width of the window (may not have any effect due to Window Manager intervention. β€” yeah, the WM might just do its own thing, iconic behaviour honestly)
  • attr_mask β€” mask of the attributes that has to be set on the window
  • attr β€” values of the attributes to be set.
  • app_class β€” title of the application to be used as its window Title and resources class.

RETURN VALUE

ID of the created window. 🎁

DESCRIPTION

create_top_level_window() is automating the process of creating a top level application window. it creates a window for the specified ASVisual, and then sets up the basic ICCCM hints for that window, such as WM_NAME, WM_ICON_NAME, WM_CLASS and WM_PROTOCOLS. she does it all so you don't have to ✨

SOURCE

Window create_top_level_window( ASVisual *asv, Window root, int x,
int y,
                                 unsigned int width, unsigned int height,
                                 unsigned int border_width,
                                 unsigned long attr_mask,
                                 XSetWindowAttributes *attr,
                                 const char *app_class, const char *app_name
) {
    Window w = None; #ifndef X_DISPLAY_MISSING
    char *tmp ;
    XTextProperty name;
    XClassHint class1;

    w = create_visual_window(asv, root, x, y, width, height,
border_width,
                             InputOutput, attr_mask, attr );

    tmp =
(app_name==NULL)?(char*)get_application_name():(char*)app_name;
    XStringListToTextProperty (&tmp, 1, &name);

    class1.res_name = tmp;  /* for future use */
    class1.res_class = (char*)app_class;
    XSetWMProtocols (asv->dpy, w, &_XA_WM_DELETE_WINDOW, 1);
    XSetWMProperties (asv->dpy, w, &name, &name, NULL, 0, NULL,
NULL, &class1);
    /* final cleanup */
    XFree ((char *) name.value);

#endif /* X_DISPLAY_MISSING */
    return w; }
  • libAfterImage/tutorials/set_window_background_and_free()

🌸 NAMEset_window_background_and_free() 🌸

SYNOPSIS

Pixmap set_window_background_and_free( Window w, Pixmap p );

INPUTS

  • w β€” ID of the window background of which we need to set.
  • p β€” Pixmap to set background to.

RETURN VALUE

None on success. Pixmap ID of original Pixmap on failure. (yep, she gives it back to you if it didn't work out πŸ₯²)

DESCRIPTION

set_window_background_and_free() will set window's background to the specified Pixmap, then refresh window contents so that the background is drawn by the server, flush all the requests to force it to be sent to the server to be processed as fast as possible. speed, bestie, speed ⚑

NOTES

after the Window's background has been set to Pixmap β€” the X server makes a hidden copy of this Pixmap for later window refreshing πŸ‘€. as the result, the original Pixmap is no longer needed and can be freed to conserve resources. so like, go ahead and release her, she's done her job πŸ’…

SOURCE

Pixmap set_window_background_and_free( Window w, Pixmap p ) {
#ifndef X_DISPLAY_MISSING
    if( p != None && w != None )
    {
        Display *dpy = get_default_asvisual()->dpy;

        if (dpy)
        {
            XSetWindowBackgroundPixmap( dpy, w, p );
            XClearWindow( dpy, w );
            XFlush( dpy );
            XFreePixmap( dpy, p );
            p = None ;
        }
    } #endif /* X_DISPLAY_MISSING */
    return p ; }
  • libAfterImage/tutorials/wait_closedown()

πŸ’€ NAMEwait_closedown() πŸ’€

SYNOPSIS

void wait_closedown( Window w );

INPUTS

  • w β€” ID of the window from which to wait for events.

DESCRIPTION

the user action requesting the window to be closed is generally received first by the Window Manager. the Window Manager then hands it down to the window by sending it a ClientMessage event with the first 32 bit word of data set to the value of the WM_DELETE_WINDOW Atom. so accordingly, all the client has to do is wait for such an event from the X server and, when it's received, it should destroy its window and generally exit. that's the whole quest 🫑

NOTES

it is recommended that XFlush() is issued right after XDestroyWindow(), as the Window Manager itself may attempt to do something with the window until it receives the DestroyNotify event. so flush, bestie, don't leave her hanging πŸ™ˆ

SEE ALSO

  • ICCCM
  • Window

SOURCE

void wait_closedown( Window w ) { #ifndef X_DISPLAY_MISSING
    Display *dpy = get_default_asvisual()->dpy;

    if(dpy)
    {
        if (w)
        {
            XSelectInput (dpy, w, ( StructureNotifyMask |
                                    ButtonPressMask|
                                    ButtonReleaseMask));

            while(w != None)
            {
                XEvent event ;

                XNextEvent (dpy, &event);
                switch(event.type)
                {
                    case ClientMessage:
                        if ((event.xclient.format != 32) ||
                            (event.xclient.data.l[0] !=
_XA_WM_DELETE_WINDOW))
                            break ;
                    case ButtonPress:
                        XDestroyWindow( dpy, w );
                        XFlush( dpy );
                        w = None ;
                        break ;
                }
            }
        }
        XCloseDisplay (dpy);
    } #endif }

and that's the whole page, bestie!! πŸŽ€βœ¨ this one's from AfterStep v.2.2.12 and it's a 3rd Berkeley Distribution situation β€” go forth and manage those windows, you absolute icon πŸ‘‘πŸ’–

πŸ“¦ where this page comes from