(3)

NAME
XfwfIcon

DESCRIPTION
The XfwfIcon widget displays an image. The preferred width and height of the widget will be set to the width and height of the loaded image, plus space for the frame. The widget has a callback activateCallback, that is by default bound to a click of the left mouse button. The image is a Pixmap, optionally accompanied by a mask, to make parts of the image transparent. When the image has a mask, the frame around the widget will not be shown.

  Public variables
XfwfIcon
Name | Class | Type | Default
XtNimage | XtCImage | Icon * | NULL
XtNactivate | XtCActivate | Callback | NULL

XtNimage
    The image must be in Pixmap format. The width and height of the image will be used to set the width and height of the widget. There is a converter for strings, which will try to interpret a string as a file name and load the file. The file must be in XPM format. The converter also knows about some built-in images, called "FATAL", "ERROR", "WARNING", "QUESTION", "INFO" and "NONE".
    Icon * image = NULL

XtNactivate
    The callback is called by the activate action, which is by default bound to a click of mouse button 1.
    <Callback> XtCallbackList  activate = NULL

XtNframeWidth
    By default, icons do not have a frame.
     frameWidth = 0
    XfwfBoard
    Name | Class | Type | Default
    XtNabs_x | XtCAbs_x | Int | 0
    XtNrel_x | XtCRel_x | Float | "0.0"
    XtNabs_y | XtCAbs_y | Int | 0
    XtNrel_y | XtCRel_y | Float | "0.0"
    XtNabs_width | XtCAbs_width | Int | 0
    XtNrel_width | XtCRel_width | Float | "1.0"
    XtNabs_height | XtCAbs_height | Int | 0
    XtNrel_height | XtCRel_height | Float | "1.0"
    XtNhunit | XtCHunit | Float | "1.0"
    XtNvunit | XtCVunit | Float | "1.0"
    XtNlocation | XtCLocation | String | NULL
    XfwfFrame
    Name | Class | Type | Default
    XtNcursor | XtCCursor | Cursor | None
    XtNframeType | XtCFrameType | FrameType | XfwfRaised
    XtNframeWidth | XtCFrameWidth | Dimension | 0
    XtNframeOffset | XtCFrameOffset | Dimension | 0
    XtNshadowScheme | XtCShadowScheme | ShadowScheme | XfwfAuto
    XtNlightColor | XtCLightColor | Pixel | XtDefaultBackground
    XtNdarkColor | XtCDarkColor | Pixel | XtDefaultForeground
    XtNlightStipple | XtCLightStipple | Bitmap | NULL
    XtNdarkStipple | XtCDarkStipple | Bitmap | NULL
    XfwfCommon
    Name | Class | Type | Default
    XtNtraversalOn | XtCTraversalOn | Boolean | True
    XtNhighlightThickness | XtCHighlightThickness | Dimension | 2
    XtNhighlightColor | XtCHighlightColor | Pixel | XtDefaultForeground
    XtNhighlightPixmap | XtCHighlightPixmap | Pixmap | None
    XtNnextTop | XtCNextTop | Callback | NULL
    XtNuserData | XtCUserData | Pointer | NULL
    Composite
    Name | Class | Type | Default
    XtNchildren | XtCChildren | WidgetList | NULL
    insertPosition | XtCInsertPosition | XTOrderProc | NULL
    numChildren | XtCNumChildren | Cardinal | 0
    Core
    Name | Class | Type | Default
    XtNx | XtCX | Position | 0
    XtNy | XtCY | Position | 0
    XtNwidth | XtCWidth | Dimension | 0
    XtNheight | XtCHeight | Dimension | 0
    borderWidth | XtCBorderWidth | Dimension | 0
    XtNcolormap | XtCColormap | Colormap | NULL
    XtNdepth | XtCDepth | Int | 0
    destroyCallback | XtCDestroyCallback | XTCallbackList | NULL
    XtNsensitive | XtCSensitive | Boolean | True
    XtNtranslations | XtCTranslations | XTTranslations | NULL
    ancestorSensitive | XtCAncestorSensitive | Boolean | False
    accelerators | XtCAccelerators | XTTranslations | NULL
    borderColor | XtCBorderColor | Pixel | 0
    borderPixmap | XtCBorderPixmap | Pixmap | NULL
    background | XtCBackground | Pixel | 0
    backgroundPixmap | XtCBackgroundPixmap | Pixmap | NULL
    mappedWhenManaged | XtCMappedWhenManaged | Boolean | True
    XtNscreen | XtCScreen | Screen * | NULL

  Exports
The header file for the XPM format must be included.
incl
 <X11/xpm.h>
The Icon type is a convenient combination of a pixmap, a mask and the pixmaps's attributes.
type
 Icon = struct _Icon {
    Pixmap pixmap;
    Pixmap mask;
    XpmAttributes attributes;
}
The converter from a string to an image recognizes the built-in icons FATAL, ERROR, WARNING, QUESTION, INFO and NONE, other names are interpreted as names of files in XPM format. The only information about the images that we are interested in is the size. Therefore the valuemask is set to just XpmSize. def done(type, value) = do {
      if (to->addr != NULL) {
      if (to->size < sizeof(type)) {
          to->size = sizeof(type);
          return False;
      }
      *(type*)(to->addr) = (value);
      } else {
      static type static_val;
      static_val = (value);
      to->addr = (XtPointer)static_val;
      }
      to->size = sizeof(type);
      return True;
  }while (0 )
Boolean  cvtStringToIcon(Display * display, XrmValuePtr  args, Cardinal * num_args, XrmValuePtr  from, XrmValuePtr  to, XtPointer * converter_data)
{
    int status;
    Cardinal one = 1;
    String *data = NULL;
    Icon *view;
    XImage *im, *shape;
    if (*num_args != 0)
    XtAppErrorMsg
        (XtDisplayToApplicationContext(display),
         "cvtStringToIcon", "wrongParameters",
         "XtToolkitError",
         "String to Icon type conversion needs no arguments",
         (String*) NULL, (Cardinal*) NULL);
    view = (Icon*) XtMalloc(sizeof(*view));
    view->attributes.valuemask = XpmSize;
    if (strcmp("QUESTION", (String) from->addr) == 0) data = QUESTION;
    else if (strcmp("FATAL", (String) from->addr) == 0) data = FATAL;
    else if (strcmp("ERROR", (String) from->addr) == 0) data = ERROR;
    else if (strcmp("WARNING", (String) from->addr) == 0) data = WARNING;
    else if (strcmp("INFO", (String) from->addr) == 0) data = INFO;
    else if (strcmp("NONE", (String) from->addr) == 0) data = NONE;
    if (data != NULL)
    status = XpmCreatePixmapFromData
        (display, DefaultRootWindow(display), data,
         view->pixmap, view->mask, view->attributes);
    else
    status = XpmReadFileToPixmap
        (display, DefaultRootWindow(display), (String) from->addr,
         view->pixmap, view->mask, view->attributes);
    switch (status) {
    case XpmOpenFailed:
    case XpmFileInvalid:
    case XpmNoMemory:
    XtAppWarningMsg
        (XtDisplayToApplicationContext(display),
         "cvtStringToIcon", "fileError", "XtToolkitError",
         "Failed to create image \"%s\"",
         from->addr, one);
    break;
    case XpmColorError:
    case XpmColorFailed:
    XtAppWarningMsg
        (XtDisplayToApplicationContext(display),
         "cvtStringToIcon", "allocColor", "XtToolkitError",
         "Could not get (all) colors for image \"%s\"",
         from->addr, one);
    case XpmSuccess:
    ; /* skip */
    }
    done(Icon*, view); }

  Translations
By default, the activate action is bound to a mouse click and to the Return key.
<Btn1Down>,<Btn1Up>: activate()
<Key>Return: activate()

  Actions

activate
    The activate action just calls the activate callback functions, passing the XEvent pointer in the call_data argument.
    void activate($, XEvent* event, String* params, Cardinal* num_params)
    {
        XtCallCallbackList($, $activate, event);
    }

Importss
incl
 <X11/shape.h>
incl
 <stdio.h>
incl
 "FATAL.xpm"
incl
 "ERROR.xpm"
incl
 "WARNING.xpm"
incl
 "QUESTION.xpm"
incl
 "INFO.xpm"
incl
 "NONE.xpm"

  Private variables
The GC for drawing the image.
GC  image_gc

  Methods
The type converter is installed by the class_initialize method.
class_initialize()
{
    XtSetTypeConverter(XtRString, "Icon", cvtStringToIcon,
		       NULL, 0, XtCacheNone, NULL);
}
The initialize sets the (desired and actual) size of the widget to the size of the image. The GC is initialized.
initialize(Widget  request, $, ArgList  args, Cardinal * num_args)
{
    Dimension dummy1, dummy2;
    Position x, y;
    $image_gc = NULL;
    create_image_gc($);
    if ($image  ($image->attributes.valuemask  XpmSize) != 0) {
	$compute_inside($, x, y, dummy1, dummy2);
	XtVaSetValues($, XtNwidth, $image->attributes.width + 2*x,
		      XtNheight, $image->attributes.height + 2*y, NULL);
    }
}
The expose method simply draws the image (if any) against the top left corner of the widget. The window is first masked with the image's mask. After that the images is drawn with a call to XFillRectangle. The GC is queried first, to see if the origin needs changing. Unfortunately, this involves a round trip to the server. Finally, expose calls the superclass's expose method to draw the frame.
expose($, XEvent * event, Region  region)
{
    Dimension wd, ht;
    Position x, y;
    if (! XtIsRealized($)) return;
    if ($image  $image->pixmap != None) {
	$compute_inside($, x, y, wd, ht);
	XFillRectangle(XtDisplay($), XtWindow($), $image_gc, x, y, wd, ht);
    }
    #expose($, event, region);
}
A change of image also causes a change in size.
Boolean  set_values(Widget  old, Widget  request, $, ArgList  args, Cardinal * num_args)
{
    Dimension dummy1, dummy2;
    Position x, y;
    Boolean need_redraw = False;
    if ($old$frameWidth != $frameWidth
	|| $old$frameOffset != $frameOffset
	|| $old$image != $image) {
	create_image_gc($);
	need_redraw = True;
    }
    if ($old$image != $image  $image) {
	$compute_inside($, x, y, dummy1, dummy2);
	if (($image->attributes.valuemask  XpmSize) != 0)
	    $set_abs_location($, CWWidth | CWHeight, 0, 0,
			      $image->attributes.width + 2*x,
			      $image->attributes.height + 2*y);
	if ($image->mask != None  XtIsRealized($))
	    XShapeCombineMask(XtDisplay($), XtWindow($), ShapeBounding,
			      x, y, $image->mask, ShapeSet);
	need_redraw = True;
    }
    return need_redraw;
}
When the Widget is realized, the window is immediately combined with the icon's mask.
realize($, XtValueMask * mask, XSetWindowAttributes * attributes)
{
    Dimension wd, ht;
    Position x, y;
    #realize($, mask, attributes);
    $compute_inside($, x, y, wd, ht);
    if ($image  $image->mask != None)
	XShapeCombineMask(XtDisplay($), XtWindow($), ShapeBounding,
			  x, y, $image->mask, ShapeSet);
}

Utilities
The GC is created by a utility function. It sets the fill style to FillTiled and the origin to the coordinates just inside the widget's frame
create_image_gc($)
{
    Dimension wd, ht;
    Position x, y;
    XtGCMask mask = GCFillStyle | GCTileStipXOrigin | GCTileStipYOrigin;
    XGCValues values;
    XtReleaseGC($, $image_gc);
    $compute_inside($, x, y, wd, ht);
    if ($image  $image->pixmap != None) {
	values.tile = $image->pixmap;
	mask |= GCTile;
    }
    values.fill_style = FillTiled;
    values.ts_x_origin = x;
    values.ts_y_origin = y;
    $image_gc = XtGetGC($, mask, values);
}