#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include <X11/IntrinsicP.h>
#include <X11/StringDefs.h>
#include <X11/Xmu/Drawing.h>
#include <X11/Xmu/SysUtil.h>
#include <X11/Xaw/SimpleP.h>
#include <X11/Xaw/XawInit.h>
#include "Private.h"
#ifndef OLDXAW
#include <X11/Xaw/Tip.h>
#endif
static Bool ChangeSensitive(Widget);
static void XawSimpleClassInitialize(void);
static void XawSimpleClassPartInitialize(WidgetClass);
#ifndef OLDXAW
static void XawSimpleInitialize(Widget, Widget, ArgList, Cardinal*);
static void XawSimpleDestroy(Widget);
static void XawSimpleExpose(Widget, XEvent*, Region);
#endif
static void XawSimpleRealize(Widget, Mask*, XSetWindowAttributes*);
static Boolean XawSimpleSetValues(Widget, Widget, Widget, ArgList, Cardinal*);
static void ConvertCursor(Widget);
#ifndef OLDXAW
static XtActionsRec actions[] = {
{"set-values", XawSetValuesAction},
{"get-values", XawGetValuesAction},
{"declare", XawDeclareAction},
{"call-proc", XawCallProcAction},
};
#endif
#define offset(field) XtOffsetOf(SimpleRec, simple.field)
static XtResource resources[] = {
{
XtNcursor,
XtCCursor,
XtRCursor,
sizeof(Cursor),
offset(cursor),
XtRImmediate,
(XtPointer)None
},
{
XtNinsensitiveBorder,
XtCInsensitive,
XtRPixmap,
sizeof(Pixmap),
offset(insensitive_border),
XtRImmediate,
NULL
},
{
XtNpointerColor,
XtCForeground,
XtRPixel,
sizeof(Pixel),
offset(pointer_fg),
XtRString,
XtDefaultForeground
},
{
XtNpointerColorBackground,
XtCBackground,
XtRPixel,
sizeof(Pixel),
offset(pointer_bg),
XtRString,
XtDefaultBackground
},
{
XtNcursorName,
XtCCursor,
XtRString,
sizeof(String),
offset(cursor_name),
XtRString,
NULL
},
{
XtNinternational,
XtCInternational,
XtRBoolean,
sizeof(Boolean),
offset(international),
XtRImmediate,
(XtPointer)False
},
#ifndef OLDXAW
{
XawNdisplayList,
XawCDisplayList,
XawRDisplayList,
sizeof(XawDisplayList*),
offset(display_list),
XtRImmediate,
NULL
},
{
XtNtip,
XtCTip,
XtRString,
sizeof(String),
offset(tip),
XtRImmediate,
NULL
},
#endif
#undef offset
};
SimpleClassRec simpleClassRec = {
{
(WidgetClass)&widgetClassRec,
"Simple",
sizeof(SimpleRec),
XawSimpleClassInitialize,
XawSimpleClassPartInitialize,
False,
#ifndef OLDXAW
XawSimpleInitialize,
#else
NULL,
#endif
NULL,
XawSimpleRealize,
#ifndef OLDXAW
actions,
XtNumber(actions),
#else
NULL,
0,
#endif
resources,
XtNumber(resources),
NULLQUARK,
True,
True,
True,
False,
#ifndef OLDXAW
XawSimpleDestroy,
#else
NULL,
#endif
NULL,
#ifndef OLDXAW
XawSimpleExpose,
#else
NULL,
#endif
XawSimpleSetValues,
NULL,
XtInheritSetValuesAlmost,
NULL,
NULL,
XtVersion,
NULL,
NULL,
XtInheritQueryGeometry,
XtInheritDisplayAccelerator,
NULL,
},
{
ChangeSensitive,
},
};
WidgetClass simpleWidgetClass = (WidgetClass)&simpleClassRec;
static void
XawSimpleClassInitialize(void)
{
static XtConvertArgRec convertArg[] = {
{
XtWidgetBaseOffset,
(XtPointer)XtOffsetOf(WidgetRec, core.screen),
sizeof(Screen *)
},
{
XtResourceString,
(XtPointer)XtNpointerColor,
sizeof(Pixel)
},
{
XtResourceString,
(XtPointer)XtNpointerColorBackground,
sizeof(Pixel)
},
{
XtWidgetBaseOffset,
(XtPointer)XtOffsetOf(WidgetRec, core.colormap),
sizeof(Colormap)
},
};
XawInitializeWidgetSet();
XtSetTypeConverter(XtRString, XtRColorCursor, XmuCvtStringToColorCursor,
convertArg, XtNumber(convertArg), XtCacheByDisplay, NULL);
}
static void
XawSimpleClassPartInitialize(WidgetClass cclass)
{
SimpleWidgetClass c = (SimpleWidgetClass)cclass;
SimpleWidgetClass super = (SimpleWidgetClass)c->core_class.superclass;
if (c->simple_class.change_sensitive == NULL) {
char buf[BUFSIZ];
(void)XmuSnprintf(buf, sizeof(buf),
"%s Widget: The Simple Widget class method "
"'change_sensitive' is undefined.\nA function "
"must be defined or inherited.",
c->core_class.class_name);
XtWarning(buf);
c->simple_class.change_sensitive = ChangeSensitive;
}
if (c->simple_class.change_sensitive == XtInheritChangeSensitive)
c->simple_class.change_sensitive = super->simple_class.change_sensitive;
}
#ifndef OLDXAW
static void
XawSimpleInitialize(Widget request, Widget cnew,
ArgList args, Cardinal *num_args)
{
SimpleWidget simple = (SimpleWidget)cnew;
if (simple->simple.tip)
simple->simple.tip = XtNewString(simple->simple.tip);
}
static void
XawSimpleDestroy(Widget w)
{
SimpleWidget simple = (SimpleWidget)w;
if (simple->simple.tip)
XtFree((XtPointer)simple->simple.tip);
}
#endif
static void
XawSimpleRealize(Widget w, Mask *valueMask, XSetWindowAttributes *attributes)
{
#ifndef OLDXAW
XawPixmap *pixmap;
#endif
Pixmap border_pixmap = CopyFromParent;
if (!XtIsSensitive(w))
{
if (((SimpleWidget)w)->simple.insensitive_border == None)
((SimpleWidget)w)->simple.insensitive_border =
XmuCreateStippledPixmap(XtScreen(w),
w->core.border_pixel,
w->core.background_pixel,
w->core.depth);
border_pixmap = w->core.border_pixmap;
attributes->border_pixmap =
w->core.border_pixmap = ((SimpleWidget)w)->simple.insensitive_border;
*valueMask |= CWBorderPixmap;
*valueMask &= ~CWBorderPixel;
}
ConvertCursor(w);
if ((attributes->cursor = ((SimpleWidget)w)->simple.cursor) != None)
*valueMask |= CWCursor;
XtCreateWindow(w, InputOutput, (Visual *)CopyFromParent,
*valueMask, attributes);
if (!XtIsSensitive(w))
w->core.border_pixmap = border_pixmap;
#ifndef OLDXAW
if (w->core.background_pixmap > XtUnspecifiedPixmap) {
pixmap = XawPixmapFromXPixmap(w->core.background_pixmap, XtScreen(w),
w->core.colormap, w->core.depth);
if (pixmap && pixmap->mask)
XawReshapeWidget(w, pixmap);
}
if (((SimpleWidget)w)->simple.tip)
XawTipEnable(w);
#endif
}
static void
ConvertCursor(Widget w)
{
SimpleWidget simple = (SimpleWidget) w;
XrmValue from, to;
Cursor cursor = None;
if (simple->simple.cursor_name == NULL)
return;
from.addr = (XPointer)simple->simple.cursor_name;
from.size = strlen((char *)from.addr) + 1;
to.size = sizeof(Cursor);
to.addr = (XPointer)&cursor;
if (XtConvertAndStore(w, XtRString, &from, XtRColorCursor, &to))
simple->simple.cursor = cursor;
else
XtAppErrorMsg(XtWidgetToApplicationContext(w),
"convertFailed","ConvertCursor","XawError",
"Simple: ConvertCursor failed.",
NULL, NULL);
}
static Boolean
XawSimpleSetValues(Widget current, Widget request, Widget cnew,
ArgList args, Cardinal *num_args)
{
SimpleWidget s_old = (SimpleWidget)current;
SimpleWidget s_new = (SimpleWidget)cnew;
Bool new_cursor = False;
s_new->simple.international = s_old->simple.international;
if (XtIsSensitive(current) != XtIsSensitive(cnew))
(*((SimpleWidgetClass)XtClass(cnew))->simple_class.change_sensitive)
(cnew);
if (s_old->simple.cursor != s_new->simple.cursor)
new_cursor = True;
if (s_old->simple.pointer_fg != s_new->simple.pointer_fg ||
s_old->simple.pointer_bg != s_new->simple.pointer_bg ||
s_old->simple.cursor_name != s_new->simple.cursor_name) {
ConvertCursor(cnew);
new_cursor = True;
}
if (new_cursor && XtIsRealized(cnew)) {
if (s_new->simple.cursor != None)
XDefineCursor(XtDisplay(cnew), XtWindow(cnew), s_new->simple.cursor);
else
XUndefineCursor(XtDisplay(cnew), XtWindow(cnew));
}
#ifndef OLDXAW
if (s_old->core.background_pixmap != s_new->core.background_pixmap) {
XawPixmap *opix, *npix;
opix = XawPixmapFromXPixmap(s_old->core.background_pixmap,
XtScreen(s_old), s_old->core.colormap,
s_old->core.depth);
npix = XawPixmapFromXPixmap(s_new->core.background_pixmap,
XtScreen(s_new), s_new->core.colormap,
s_new->core.depth);
if ((npix && npix->mask) || (opix && opix->mask))
XawReshapeWidget(cnew, npix);
}
if (s_old->simple.tip != s_new->simple.tip) {
if (s_old->simple.tip)
XtFree((XtPointer)s_old->simple.tip);
if (s_new->simple.tip)
s_new->simple.tip = XtNewString(s_new->simple.tip);
}
if (s_old->simple.tip && !s_new->simple.tip)
XawTipDisable(cnew);
else if (!s_old->simple.tip && s_new->simple.tip)
XawTipEnable(cnew);
if (s_old->simple.display_list != s_new->simple.display_list)
return (True);
#endif
return (False);
}
#ifndef OLDXAW
static void
XawSimpleExpose(Widget w, XEvent *event, Region region)
{
SimpleWidget xaw = (SimpleWidget)w;
if (xaw->simple.display_list)
XawRunDisplayList(w, xaw->simple.display_list, event, region);
}
#endif
static Bool
ChangeSensitive(Widget w)
{
if (XtIsRealized(w)) {
if (XtIsSensitive(w))
if (w->core.border_pixmap != XtUnspecifiedPixmap)
XSetWindowBorderPixmap(XtDisplay(w), XtWindow(w),
w->core.border_pixmap);
else
XSetWindowBorder(XtDisplay(w), XtWindow(w),
w->core.border_pixel);
else {
if (((SimpleWidget)w)->simple.insensitive_border == None)
((SimpleWidget)w)->simple.insensitive_border =
XmuCreateStippledPixmap(XtScreen(w),
w->core.border_pixel,
w->core.background_pixel,
w->core.depth);
XSetWindowBorderPixmap(XtDisplay(w), XtWindow(w),
((SimpleWidget)w)->simple.insensitive_border);
}
}
return (False);
}