XMRESOLVEPARTOFFSETS(3)

πŸ“¦
version 2.5.2 Β· 2 versions
, in alpine 3.24, arch rolling, centos-stream 9, epel 10, fedora 43, fedora 44, nixos 26.05, nixpkgs unstable, opensuse-leap 16.0

✨ XmResolvePartOffsets ✨

okay bestie, gather round, because we're talking about XmResolvePartOffsets β€” that's a library call from the Xm fam, and she's literally the reason your app can be upward-compatible and not fall apart the second someone sneezes on a widget record πŸ’…


πŸŽ€ NAME πŸŽ€

XmResolvePartOffsets β€” a function that lets you write upward-compatible applications and widgets. she's giving future-proof queen energy, no cap ✨


🌸 SYNOPSIS 🌸

#include <Xm/Xm.h>
void XmResolvePartOffsets(
WidgetClass widget_class,
XmOffsetPtr * offset);

πŸ’– DESCRIPTION πŸ’–

so here's the tea β˜• β€” using offset records means you need one extra global variable per widget class. that variable is just a pointer to an array of offsets into the widget record, one for every part of the widget structure. and XmResolvePartOffsets is the function that allocates those offset records so your app is guaranteed upward-compatible access to widget instance records β€” for both applications and widgets. the widget uses these offset records to get at all of its variables. and a widget has to take the steps we're about to list, okay? stay with me 🫢

instead of making a resource list, the widget makes an offset resource list. to do that, you use the XmPartResource structure plus the XmPartOffset macro. the XmPartResource data structure looks exactly like a resource list, except instead of one integer for its offset it has two shorts. this structure goes into the class record just like it was a normal resource list. and instead of using XtOffset for the offset, the widget uses XmPartOffset. iconic behavior honestly πŸ’…

XmPartResource resources[] = {
  { BarNxyz, BarCXyz, XmRBoolean,
    sizeof(Boolean), XmPartOffset(Bar,xyz),
    XmRImmediate, (XtPointer)False }
};

instead of putting the widget size in the class record, the widget puts the widget part size in that same field.

instead of putting XtVersion in the class record, the widget puts XtVersionDontCheck in the class record.

the widget defines a variable, of type XmOffsetPtr, that points to the offset record. this can live in the widget's class record or be its own separate global variable β€” dealer's choice bestie 🌈

then, in class initialization, the widget calls XmResolvePartOffsets, passing it a pointer to contain the address of the offset record and the class record. and this does several things:

  • adds the superclass size field (which, by definition, has already been initialized) to the part size field
  • allocates an array based upon the number of superclasses
  • fills in the offsets of all the widget parts with the appropriate values, determined by examining the size fields of all superclass records
  • uses the part offset array to modify the offset entries in the resource list to be real offsets, in place

the widget also defines a constant that's the index to its part structure in the offsets array. the value should be 1 greater than the index of the widget's superclass. and the constants defined for all Xm widgets? those live in XmP.h πŸ“š

#define BarIndex (XmBulletinBIndex + 1)

instead of accessing fields directly, the widget must always go through the offset table. the XmField macro is your bestie for accessing these fields. but β€” and this is important, don't skip it β€” because the XmPartOffset and XmField macros concatenate things together, you must make sure there is no space after the part argument. for example, these macros do not work, because of the space after the part (Label) argument:

XmField(w, offset, Label, text, char *)
XmPartOffset(Label, text)

so yeah, no spaces after the part (Label) argument, mmkay? like this instead:

XmField(w, offset, Label, text, char *)

and you can define macros for each field to make this easier on yourself. assume an integer field xyz:

#define BarXyz(w) (*(int *)(((char *) w) + \
        offset[BarIndex] + XtOffset(BarPart,xyz)))

the parameters for XmResolvePartOffsets are:

  • widget_class β€” specifies the widget class pointer for the created widget
  • offset β€” returns the offset record

XmResolveAllPartOffsets(3) β€” go read her too, she's part of the lore πŸ’œ


okay that's the whole page, you ate it, go be upward-compatible and thriving πŸ¦‹

this was XmResolvePartOffsets, a library call β€” courtesy of the Xm manual set, no date on the tin but the vibes are timeless πŸ’–βœ¨πŸŽ€