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

πŸ’– XmDrawnButton πŸ’–

okay bestie, welcome to the XmDrawnButton page β€” it's a library call, and it's genuinely one of the cutest little widgets in the whole Motif family. let's get into it. πŸŽ€


✨ NAME ✨

XmDrawnButton β€” The DrawnButton widget class


✨ SYNOPSIS ✨

#include <Xm/DrawnB.h>

✨ DESCRIPTION ✨

so like. picture this. the DrawnButton widget is literally an empty widget window that's surrounded by a shadow border. that's it. that's the whole vibe. it hands the application developer a graphics area β€” a little canvas, a blank stage, a moment of silence before the art β€” and that area gets PushButton input semantics. so you draw whatever you want in there, and it still behaves like a button. iconic behavior honestly. πŸ‘‘

callback types are defined for widget exposure and widget resize, so your app can redraw or reposition its graphics whenever it needs to. slay.

⚠️ important one, bestie: if the DrawnButton widget has a highlight and shadow thickness, the application should not draw in that area. periodt.

and the way to avoid drawing in the highlight and shadow area? create the graphics context with a clipping rectangle for drawing in the widget. the clipping rectangle should take into account the size of the widget's highlight thickness and shadow. that's the move. 🫢

DrawnButton uses the XmQTmenuSystem and XmQTspecifyRenderTable traits, and holds the XmQTactivatable trait.


🌸 Classes 🌸

DrawnButton inherits behavior, resources, and traits from the Core, Primitive, and XmLabel classes. (yes, it's a whole family tree and DrawnButton is the main character at the bottom of it.)

The class pointer is xmDrawnButtonWidgetClass.

The class name is XmDrawnButton.


🌈 New Resources 🌈

okay so here's the resource table, but make it group chat. the following set of widget resources is used by the programmer to specify data. the programmer can also set the resource values for the inherited classes to set attributes for this widget.

to reference a resource by name or by class in a .Xdefaults file, remove the XmN or XmC prefix and use the remaining letters. to specify one of the defined values for a resource in a .Xdefaults file, remove the Xm prefix and use the remaining letters (in either lowercase or uppercase, but include any underscores between words β€” yes, the underscores stay, don't come for them).

the codes in the access column indicate if the given resource can be set at creation time (C), set by using XtSetValues (S), retrieved by using XtGetValues (G), or is not applicable (N/A).

πŸ’… XmDrawnButton Resource Set πŸ’…

  • XmNactivateCallback β€” class XmCCallback, type XtCallbackList, default NULL, access C
  • XmNarmCallback β€” class XmCCallback, type XtCallbackList, default NULL, access C
  • XmNdisarmCallback β€” class XmCCallback, type XtCallbackList, default NULL, access C
  • XmNexposeCallback β€” class XmCCallback, type XtCallbackList, default NULL, access C
  • XmNmultiClick β€” class XmCMultiClick, type unsigned char, default dynamic, access CSG
  • XmNpushButtonEnabled β€” class XmCPushButtonEnabled, type Boolean, default False, access CSG
  • XmNresizeCallback β€” class XmCCallback, type XtCallbackList, default NULL, access C
  • XmNshadowType β€” class XmCShadowType, type unsigned char, default XmSHADOW_ETCHED_IN, access CSG

πŸ¦‹ and here's what each one actually does πŸ¦‹

  • XmNactivateCallback β€” Specifies the list of callbacks that is called when the widget becomes selected. The reason sent by the callback is XmCR_ACTIVATE. This callback uses the XmQTactivatable trait. ✨
  • XmNarmCallback β€” Specifies the list of callbacks that is called when the widget becomes armed. The reason sent by the callback is XmCR_ARM. πŸ”₯
  • XmNdisarmCallback β€” Specifies the list of callbacks that is called when the widget becomes disarmed. The reason sent by the callback is XmCR_DISARM.
  • XmNexposeCallback β€” Specifies the list of callbacks that is called when the widget receives an exposure event. The reason sent by the callback is XmCR_EXPOSE. πŸ‘€
  • XmNmultiClick β€” okay so this one is about double clicks, and the vibes are specific. If a button click is followed by another button click within the time span specified by the display's multiclick time, and this resource is set to XmMULTICLICK_DISCARD, the second click is not processed. If this resource is set to XmMULTICLICK_KEEP, the event is processed and click_count is incremented in the callback structure. When the button is not in a menu, the default value is XmMULTICLICK_KEEP.
  • XmNpushButtonEnabled β€” Enables or disables the 3-dimensional shadow drawing as in PushButton. that's literally it, it's the 3D toggle. πŸ’…
  • XmNresizeCallback β€” Specifies the list of callbacks that is called when the widget receives a resize event. The reason sent by the callback is XmCR_RESIZE. The event returned for this callback is NULL. (yeah, NULL. it's giving "no event for you." πŸ™ˆ)
  • XmNshadowType β€” Describes the drawing style for the DrawnButton. This resource can have the following values:
    • XmSHADOW_IN β€” Draws the DrawnButton so that the shadow appears inset. This means that the bottom shadow visuals and top shadow visuals are reversed.
    • XmSHADOW_OUT β€” Draws the DrawnButton so that the shadow appears outset.
    • XmSHADOW_ETCHED_IN β€” Draws the DrawnButton using a double line. This gives the effect of a line etched into the window. The thickness of the double line is equal to the value of XmNshadowThickness.
    • XmSHADOW_ETCHED_OUT β€” Draws the DrawnButton using a double line. This gives the effect of a line coming out of the window. The thickness of the double line is equal to the value of XmNshadowThickness.

πŸŽ€ Inherited Resources πŸŽ€

DrawnButton inherits behavior and resources from the superclasses described in the following tables. For a complete description of each resource, refer to the reference page for that superclass. (iykyk β€” we're going up the family tree from here. 🌳)

πŸŽ€ XmLabel Resource Set πŸŽ€

okay bestie, this is the full roster β€” every single resource this widget's label machinery knows about. name, class, type, default, and whether you can actually reach it through the standard access calls (that's the Access column, and N/A means not applicable, CSG means it's fair game for the usual get/set/whatever crowd). no skips, no "and so on", all nineteen of them, in order, periodt. πŸ’–

  • XmNaccelerator β€” class XmCAccelerator, type String, default NULL, access N/A.
  • XmNacceleratorText β€” class XmCAcceleratorText, type XmString, default NULL, access N/A.
  • XmNalignment β€” class XmCAlignment, type unsigned char, default dynamic, access CSG.
  • XmNfontList β€” class XmCFontList, type XmFontList, default dynamic, access CSG.
  • XmNlabelInsensitivePixmap β€” class XmCLabelInsensitivePixmap, type Pixmap, default XmUNSPECIFIED_PIXMAP, access CSG.
  • XmNlabelPixmap β€” class XmCLabelPixmap, type Pixmap, default XmUNSPECIFIED_PIXMAP, access CSG.
  • XmNlabelString β€” class XmCXmString, type XmString, default "\0", access CSG.
  • XmNlabelType β€” class XmCLabelType, type unsigned char, default XmSTRING, access CSG.
  • XmNmarginBottom β€” class XmCMarginBottom, type Dimension, default 0, access CSG.
  • XmNmarginHeight β€” class XmCMarginHeight, type Dimension, default 2, access CSG.
  • XmNmarginLeft β€” class XmCMarginLeft, type Dimension, default 0, access CSG.
  • XmNmarginRight β€” class XmCMarginRight, type Dimension, default 0, access CSG.
  • XmNmarginTop β€” class XmCMarginTop, type Dimension, default 0, access CSG.
  • XmNmarginWidth β€” class XmCMarginWidth, type Dimension, default 2, access CSG.
  • XmNmnemonic β€” class XmCMnemonic, type KeySym, default NULL, access N/A.
  • XmNmnemonicCharSet β€” class XmCMnemonicCharSet, type String, default XmFONTLIST_DEFAULT_TAG, access N/A.
  • XmNrecomputeSize β€” class XmCRecomputeSize, type Boolean, default True, access CSG.
  • XmNrenderTable β€” class XmCRenderTable, type XmRenderTable, default dynamic, access CSG.
  • XmNstringDirection β€” class XmCStringDirection, type XmStringDirection, default dynamic, access CSG.

a lil vibe check on that list ✨ β€” see how the margins are just vibing at 0 and 2, and three whole resources said "my default is dynamic, figure it out"? that's not me being vague, that's literally what the table says, and I refuse to elaborate further because I do not make the rules. 😭

and yes, XmNlabelString defaults to the extremely dramatic "\0" β€” an empty string, a blank canvas, a girl with nothing to say yet. character development pending. πŸ’…

heads up: the N/A in that Access column is doing real work, bestie β€” don't come for me later saying I didn't warn you that not every one of these is a normal read/write situation. 🫢

also XmFONTLIST_DEFAULT_TAG for XmNmnemonicCharSet and XmUNSPECIFIED_PIXMAP for both the pixmap resources β€” those aren't typos, that's genuinely the documented default, copy it exactly or the compiler will simply not. no cap. πŸ’€

next up, the fun stuff continues β€” don't go anywhere, we're so not done here πŸ¦‹

πŸŽ€ XmPrimitive Resource Set πŸŽ€

okay bestie, deep breath, because this is the big one β€” the full resource table for XmPrimitive, which XmDrawnButton inherits from like it's family money πŸ’…. Five columns, eighteen rows, no skips, no shortcuts. Here's how to read each line: the resource Name comes first, then its Class, then the Type, then the Default, and finally the Access column (which is literally just C, CSG, or CG β€” that's what's written, that's what you get 🫢).


  • XmNbottomShadowColor β€” class XmCBottomShadowColor, type Pixel, default dynamic, access CSG 🌸
  • XmNbottomShadowPixmap β€” class XmCBottomShadowPixmap, type Pixmap, default XmUNSPECIFIED_PIXMAP, access CSG ✨
  • XmNconvertCallback β€” class XmCCallback, type XtCallbackList, default NULL, access C πŸ’–
  • XmNforeground β€” class XmCForeground, type Pixel, default dynamic, access CSG 🌈
  • XmNhelpCallback β€” class XmCCallback, type XtCallbackList, default NULL, access C πŸ¦‹
  • XmNhighlightColor β€” class XmCHighlightColor, type Pixel, default dynamic, access CSG πŸ’œ
  • XmNhighlightOnEnter β€” class XmCHighlightOnEnter, type Boolean, default False, access CSG πŸ‘‘
  • XmNhighlightPixmap β€” class XmCHighlightPixmap, type Pixmap, default dynamic, access CSG πŸŽ€
  • XmNhighlightThickness β€” class XmCHighlightThickness, type Dimension, default 2, access CSG ⭐
  • XmNlayoutDirection β€” class XmCLayoutDirection, type XmDirection, default dynamic, access CG 🧚
  • XmNnavigationType β€” class XmCNavigationType, type XmNavigationType, default XmNONE, access CSG πŸ“
  • XmNpopupHandlerCallback β€” class XmCCallback, type XtCallbackList, default NULL, access C πŸ”₯
  • XmNshadowThickness β€” class XmCShadowThickness, type Dimension, default 2, access CSG πŸ’…
  • XmNtopShadowColor β€” class XmCTopShadowColor, type Pixel, default dynamic, access CSG 🌸
  • XmNtopShadowPixmap β€” class XmCTopShadowPixmap, type Pixmap, default dynamic, access CSG ✨
  • XmNtraversalOn β€” class XmCTraversalOn, type Boolean, default True, access CSG 🌈
  • XmNunitType β€” class XmCUnitType, type unsigned char, default dynamic, access CSG πŸ’–
  • XmNuserData β€” class XmCUserData, type XtPointer, default NULL, access CSG πŸ¦‹
not me counting them to make sure all eighteen made it πŸ’€ bestie there are literally eighteen and every single one is up there, defaults and access codes and all, no cap πŸ”₯

and yes, the <pink>dynamic</pink> defaults stay written as dynamic because that's exactly what the table says β€” don't come for me, I'm just the messenger 🫢

πŸ’… Core Resource Set πŸ’…

Okay bestie, here's the whole squad of core resources this widget rolls with. Same energy as every other widget in the fam, but here's the receipt anyway. For each one you get its name, its class, its type, its default, and its access β€” and yes, every single one is below, no skipping, no "you get the idea" nonsense. πŸ’–

  • XmNaccelerators β€” class XmCAccelerators, type XtAccelerators, default dynamic, access CSG
  • XmNancestorSensitive β€” class XmCSensitive, type Boolean, default dynamic, access G
  • XmNbackground β€” class XmCBackground, type Pixel, default dynamic, access CSG
  • XmNbackgroundPixmap β€” class XmCPixmap, type Pixmap, default XmUNSPECIFIED_PIXMAP, access CSG
  • XmNborderColor β€” class XmCBorderColor, type Pixel, default XtDefaultForeground, access CSG
  • XmNborderPixmap β€” class XmCPixmap, type Pixmap, default XmUNSPECIFIED_PIXMAP, access CSG
  • XmNborderWidth β€” class XmCBorderWidth, type Dimension, default 0, access CSG
  • XmNcolormap β€” class XmCColormap, type Colormap, default dynamic, access CG
  • XmNdepth β€” class XmCDepth, type int, default dynamic, access CG
  • XmNdestroyCallback β€” class XmCCallback, type XtCallbackList, default NULL, access C
  • XmNheight β€” class XmCHeight, type Dimension, default dynamic, access CSG
  • XmNinitialResourcesPersistent β€” class XmCInitialResourcesPersistent, type Boolean, default True, access C
  • XmNmappedWhenManaged β€” class XmCMappedWhenManaged, type Boolean, default True, access CSG
  • XmNscreen β€” class XmCScreen, type Screen *, default dynamic, access CG
  • XmNsensitive β€” class XmCSensitive, type Boolean, default True, access CSG
  • XmNtranslations β€” class XmCTranslations, type XtTranslations, default dynamic, access CSG
  • XmNwidth β€” class XmCWidth, type Dimension, default dynamic, access CSG
  • XmNx β€” class XmCPosition, type Position, default 0, access CSG
  • XmNy β€” class XmCPosition, type Position, default 0, access CSG
That access column? CSG, CG, C, G β€” literally what the table says, and I am not about to start guessing at extra lore for you. It's giving "look it up in the Intrinsics docs," bestie. πŸ™ˆ

πŸ“ž Callback Information πŸ“ž

When a callback fires, it gets handed a pointer to this little struct right here. Here's the exact shape of it, no notes:

typedef struct
{
        int reason;
        XEvent * event;
        Window window;
        int click_count;
} XmDrawnButtonCallbackStruct;

And here's what each field is actually doing:

  • reason β€” tells you why the callback got invoked in the first place. The whole plot, basically. πŸ’…
  • event β€” points at the XEvent that triggered the callback. Heads up though: this one is NULL for XmNresizeCallback. Yes, NULL. Don't come for me, that's just how it is. 😭
  • window β€” set to the window ID where the event went down.
  • click_count β€” holds the number of clicks in the last multiclick sequence if the XmNmultiClick resource is set to XmMULTICLICK_KEEP. Otherwise? It just contains 1. And the activate callback gets invoked for each click if XmNmultiClick is set to XmMULTICLICK_KEEP. So like, either you're getting the real count or you're getting a very confident 1. 🀷

⌨️ Translations ⌨️

XmDrawnButton pulls in translations from Primitive, and then it's got some extra XmDrawnButton translations of its own, all listed below. The key names here are written in the X standard key event translation table syntax β€” that's the format Motif uses to say which widget actions line up with which key. πŸŽ€

If you want the quick-and-dirty overview of that format, go peek at VirtualBindings(3). Want the complete breakdown? That's the X Toolkit Instrinsics Documentation, bestie. Go read it, it's all there. πŸ“š

c<Btn1Down>: ButtonTakeFocus()

okay bestie we're picking up right where we left off, no re-intros, let's go πŸ’– here's the rest of the bindings:

  • ∼c<Btn1Down>: β†’ Arm()
  • ∼c<Btn1Down>,∼c<Btn1Up>: β†’ Activate() Disarm()
  • ∼c<Btn1Down>(2+): β†’ MultiArm()
  • ∼c<Btn1Up>(2+): β†’ MultiActivate()
  • ∼c<Btn1Up>: β†’ Activate() Disarm()
  • :<Key><osfActivate>: β†’ PrimitiveParentActivate()
  • :<Key><osfCancel>: β†’ PrimitiveParentCancel()
  • :<Key><osfSelect>: β†’ ArmAndActivate()
  • :<Key><osfHelp>: β†’ Help()
  • ∼s ∼m ∼a <Key>Return: β†’ PrimitiveParentActivate()
  • ∼s ∼m ∼a <Key>space: β†’ ArmAndActivate()

🎬 Action Routines 🎬

The XmDrawnButton action routines are right here, babes:

  • Activate() β€” if XmNpushButtonEnabled is True, it redraws the shadow in the unselected state; otherwise it redraws the shadow according to XmNshadowType. And if the pointer is within the DrawnButton, it calls the XmNactivateCallback callbacks. slay ✨
  • Arm() β€” if XmNpushButtonEnabled is True, it redraws the shadow in the selected state; otherwise it redraws the shadow according to XmNshadowType. Then it calls the callbacks for XmNarmCallback.
  • ArmAndActivate() β€” if XmNpushButtonEnabled is True, it redraws the shadow in the selected state; otherwise it redraws the shadow according to XmNshadowType. Then it calls the callbacks for XmNarmCallback.

If XmNpushButtonEnabled is True, the shadow is redrawn in the unselected state; otherwise the shadow is redrawn according to XmNshadowType. The callbacks for XmNactivateCallback and XmNdisarmCallback are called. And bestie, listen β€” these actions happen either immediately or at a later time. both. it's giving mysterious πŸ’…

  • ButtonTakeFocus() β€” causes the PushButton to take keyboard focus when Ctrl<Btn1Down> is pressed, without activating the widget. focus only, no clicking, we're just looking respectfully πŸ‘€
  • Disarm() β€” marks the DrawnButton as unselected and calls the callbacks for XmNdisarmCallback.
  • Help() β€” calls the callbacks for XmNhelpCallback if any exist. And if there are no help callbacks for this widget, this action calls the help callbacks for the nearest ancestor that has them. it goes up the family tree, iconic 🫢
  • MultiActivate() β€” if XmNmultiClick is XmMULTICLICK_DISCARD, this action does nothing. periodt.

If XmNmultiClick is XmMULTICLICK_KEEP, this action increments click_count in the callback structure. If XmNpushButtonEnabled is True, this action redraws the shadow in the unselected state; otherwise it redraws the shadow according to XmNshadowType. And if the pointer is within the DrawnButton, this action calls the XmNactivateCallback callbacks and calls the callbacks for XmNdisarmCallback.

  • MultiArm() β€” if XmNmultiClick is XmMULTICLICK_DISCARD, this action does nothing.

If XmNmultiClick is XmMULTICLICK_KEEP and if XmNpushButtonEnabled is True, this action redraws the shadow in the selected state; otherwise it redraws the shadow according to XmNshadowType and calls the callbacks for XmNarmCallback.


✨ Additional Behavior ✨

This widget has the following additional behavior, no cap:

  • <EnterWindow> β€” draws the shadow in its selected state if XmNpushButtonEnabled is True and if the cursor leaves and re-enters the window while BSelect is pressed. 😭 she remembered you
  • <LeaveWindow> β€” draws the shadow in its unselected state if XmNpushButtonEnabled is True and if the cursor leaves the window while BSelect is pressed.

🌈 Virtual Bindings 🌈

The bindings for virtual keys are vendor specific β€” like, everyone's doing their own thing, iykyk. For information about bindings for virtual buttons and keys, see VirtualBindings(3).


the whole friend group, fr fr πŸ’œ


and that's the whole page, bestie, we ate and left no crumbs πŸŽ€ this one's the XmDrawnButton(library call) manpage β€” that's the footer, that's the credit, that's the whole vibe. go forth and draw those buttons, my little main character πŸ‘‘πŸ’