XMRESOLVEALLPARTOFFSETS(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

✨ XmResolveAllPartOffsets πŸ’…

okay bestie, so we're looking at XmResolveAllPartOffsets, and it lives in the library call section of the manual. It's a function that lets you write upward-compatible applications and widgets β€” yes, the iconic kind that don't break the second somebody adds a field. 🫢


🌸 SYNOPSIS 🌸

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

πŸŽ€ DESCRIPTION πŸŽ€

Note: this routine is obsolete, bestie. It's still here for compatibility with previous releases only. You should be calling XmeResolvePartOffsets instead. Not me telling you twice. πŸ’€

So here's the tea about offset records: using them means you need two extra global variables per widget class. Those variables are just pointers to arrays of offsets into the widget record and the constraint record, for each part of the widget structure. What XmResolveAllPartOffsets does is allocate those offset records so an application can guarantee upward-compatible access to widget instance and constraint records β€” for both applications and widgets. The widget uses these offset records to get at all of its own variables. And a widget has to take the following steps, periodt.

  • Instead of making a resource list, the widget makes an offset resource list. To do that, use the XmPartResource structure and 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. You put this structure into the class record as if it were a normal resource list. And instead of using XtOffset for the offset, the widget uses XmPartOffset.
  • If the widget is a subclass of the Constraint class and it defines additional constraint resources, make an offset resource list for the constraint part too. And instead of using XtOffset for the offset, the widget uses XmConstraintPartOffset in the constraint resource list.
XmPartResource resources[] = {
        {       BarNxyz, BarCXyz, XmRBoolean, sizeof(Boolean),
                XmPartOffset(Bar,xyz), XmRImmediate, (XtPointer)False } };
XmPartResource constraints[] = {
        {       BarNmaxWidth, BarNMaxWidth,
          XmRDimension, sizeof(Dimension),
          XmConstraintPartOffset(Bar,max_width),
          XmRImmediate, (XtPointer)100 } };
  • Instead of putting the widget size in the class record, the widget puts the widget part size in that same field. And if the widget is a subclass of the Constraint class, instead of putting the widget constraint record size in the class record, the widget puts the widget constraint part size in that same field. πŸ‘‘
  • Instead of putting XtVersion in the class record, the widget puts XtVersionDontCheck in the class record.
  • Define a variable of type XmOffsetPtr to point to the offset record. If the widget is a subclass of the Constraint class, also define a variable of type XmOffsetPtr to point to the constraint offset record. These can live in the widget's class record or be separate global variables β€” your call, bestie.
  • In class initialization, the widget calls XmResolveAllPartOffsets, handing it pointers to the class record, the address of the offset record, and the address of the constraint offset record. If the widget is not a subclass of the Constraint class, it should pass NULL as the address of the constraint offset record.

And this call does several things, no cap:

  • Adds the superclass (which, by definition, has already been initialized) size field to the part size field
  • If the widget is a subclass of the Constraint class, adds the superclass constraint size field to the constraint size field
  • Allocates an array based upon the number of superclasses
  • If the widget is a subclass of the constraint class, allocates an array for the constraint offset record
  • Fills in the offsets of all the widget parts and constraint 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 will be the index to its part structure in the offsets array. That value should be 1 greater than the index of the widget's superclass. Constants defined for all Xm widgets can be found in XmP.h. 🌈

#define BarIndex (XmBulletinBIndex + 1)

Instead of accessing fields directly, the widget must always go through the offset table. The XmField and XmConstraintField macros are your besties for accessing these fields. But here's the catch β€” because the XmPartOffset, XmConstraintPartOffset, XmField, and XmConstraintField macros concatenate things, you must make sure there is no space after the part argument. For example, the following macros do not work because of the space after the part (Label) argument:

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

So you must not have any spaces after the part (Label) argument, as illustrated here:

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

You can define macros for each field to make this easier, though. Assume an integer field xyz:

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

And for constraint field max_width:

#define BarMaxWidth(w) \
        XmConstraintField(w,constraint_offsets,Bar,max_width,Dimension)

πŸ¦‹ The Parameters πŸ¦‹

The parameters for XmResolveAllPartOffsets are:

  • widget_class β€” Specifies the widget class pointer for the created widget
  • offset β€” Returns the offset record
  • constraint_offset β€” Returns the constraint offset record

XmResolvePartOffsets(3).


and that's the whole page, bestie! πŸ’œ this one's straight out of the XmResolveAllPartOffsets(library call) pages β€” no date stamp on it, so don't come for me about timestamps. go slay your offset records, mwah πŸŽ€βœ¨