#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include <ctype.h>
#include <X11/IntrinsicP.h>
#include <X11/StringDefs.h>
#include <X11/Xmu/Drawing.h>
#include <X11/Xaw/ListP.h>
#include <X11/Xaw/XawInit.h>
#include "Private.h"
#define HeightLock 1
#define WidthLock 2
#define LongestLock 4
#define HeightFree(w) !(((ListWidget)(w))->list.freedoms & HeightLock)
#define WidthFree(w) !(((ListWidget)(w))->list.freedoms & WidthLock)
#define LongestFree(w) !(((ListWidget)(w))->list.freedoms & LongestLock)
#define MaxSize 32767
static void XawListDestroy(Widget);
static void XawListInitialize(Widget, Widget, ArgList, Cardinal*);
static XtGeometryResult XawListQueryGeometry(Widget, XtWidgetGeometry*,
XtWidgetGeometry*);
static void XawListRedisplay(Widget, XEvent*, Region);
static void XawListResize(Widget);
static Boolean XawListSetValues(Widget, Widget, Widget, ArgList, Cardinal*);
static void CalculatedValues(Widget);
static void ChangeSize(Widget, unsigned int, unsigned int);
static void ClipToShadowInteriorAndLongest(ListWidget, GC*, unsigned int);
static int CvtToItem(Widget, int, int, int*);
static void FindCornerItems(Widget, XEvent*, int*, int*);
static void GetGCs(Widget);
static void HighlightBackground(Widget, int, int, GC);
static Bool ItemInRectangle(Widget, int, int, int);
static Bool Layout(Widget, Bool, Bool, Dimension*, Dimension*);
static void PaintItemName(Widget, int);
static void ResetList(Widget, Bool, Bool);
static void Notify(Widget, XEvent*, String*, Cardinal*);
static void Set(Widget, XEvent*, String*, Cardinal*);
static void Unset(Widget, XEvent*, String*, Cardinal*);
static char defaultTranslations[] =
"<Btn1Down>:" "Set()\n"
"<Btn1Up>:" "Notify()\n"
;
#define offset(field) XtOffsetOf(ListRec, field)
static XtResource resources[] = {
{
XtNforeground,
XtCForeground,
XtRPixel,
sizeof(Pixel),
offset(list.foreground),
XtRString,
XtDefaultForeground
},
{
XtNcursor,
XtCCursor,
XtRCursor,
sizeof(Cursor),
offset(simple.cursor),
XtRString,
"left_ptr"
},
{
XtNfont,
XtCFont,
XtRFontStruct,
sizeof(XFontStruct*),
offset(list.font),
XtRString,
XtDefaultFont
},
{
XtNfontSet,
XtCFontSet,
XtRFontSet,
sizeof(XFontSet),
offset(list.fontset),
XtRString,
XtDefaultFontSet
},
{
XtNlist,
XtCList,
XtRPointer,
sizeof(char**),
offset(list.list),
#ifdef notyet
XtRStringArray,
#else
XtRString,
#endif
NULL
},
{
XtNdefaultColumns,
XtCColumns,
XtRInt,
sizeof(int),
offset(list.default_cols),
XtRImmediate,
(XtPointer)2
},
{
XtNlongest,
XtCLongest,
XtRInt,
sizeof(int),
offset(list.longest),
XtRImmediate,
(XtPointer)0
},
{
XtNnumberStrings,
XtCNumberStrings,
XtRInt,
sizeof(int),
offset(list.nitems),
XtRImmediate,
(XtPointer)0
},
{
XtNpasteBuffer,
XtCBoolean,
XtRBoolean,
sizeof(Boolean),
offset(list.paste),
XtRImmediate,
(XtPointer)False
},
{
XtNforceColumns,
XtCColumns,
XtRBoolean,
sizeof(Boolean),
offset(list.force_cols),
XtRImmediate,
(XtPointer)False
},
{
XtNverticalList,
XtCBoolean,
XtRBoolean,
sizeof(Boolean),
offset(list.vertical_cols),
XtRImmediate,
(XtPointer)False
},
{
XtNinternalWidth,
XtCWidth,
XtRDimension,
sizeof(Dimension),
offset(list.internal_width),
XtRImmediate,
(XtPointer)2
},
{
XtNinternalHeight,
XtCHeight,
XtRDimension,
sizeof(Dimension),
offset(list.internal_height),
XtRImmediate,
(XtPointer)2
},
{
XtNcolumnSpacing,
XtCSpacing,
XtRDimension,
sizeof(Dimension),
offset(list.column_space),
XtRImmediate,
(XtPointer)6
},
{
XtNrowSpacing,
XtCSpacing,
XtRDimension,
sizeof(Dimension),
offset(list.row_space),
XtRImmediate,
(XtPointer)2
},
{
XtNcallback,
XtCCallback,
XtRCallback,
sizeof(XtPointer),
offset(list.callback),
XtRCallback,
NULL
},
#ifndef OLDXAW
{
XtNshowCurrent,
XtCBoolean,
XtRBoolean,
sizeof(Boolean),
offset(list.show_current),
XtRImmediate,
(XtPointer)False
},
#endif
};
#undef offset
static XtActionsRec actions[] = {
{"Notify", Notify},
{"Set", Set},
{"Unset", Unset},
};
#define Superclass (&simpleClassRec)
ListClassRec listClassRec = {
{
(WidgetClass)Superclass,
"List",
sizeof(ListRec),
XawInitializeWidgetSet,
NULL,
False,
XawListInitialize,
NULL,
XtInheritRealize,
actions,
XtNumber(actions),
resources,
XtNumber(resources),
NULLQUARK,
True,
False,
True,
False,
XawListDestroy,
XawListResize,
XawListRedisplay,
XawListSetValues,
NULL,
XtInheritSetValuesAlmost,
NULL,
NULL,
XtVersion,
NULL,
defaultTranslations,
XawListQueryGeometry,
},
{
XtInheritChangeSensitive,
},
{
NULL,
},
};
WidgetClass listWidgetClass = (WidgetClass)&listClassRec;
static void
GetGCs(Widget w)
{
XGCValues values;
ListWidget lw = (ListWidget)w;
values.foreground = lw->list.foreground;
values.font = lw->list.font->fid;
if (lw->simple.international == True)
lw->list.normgc = XtAllocateGC(w, 0, GCForeground, &values, GCFont, 0);
else
lw->list.normgc = XtGetGC(w, GCForeground | GCFont, &values);
values.foreground = lw->core.background_pixel;
if (lw->simple.international == True)
lw->list.revgc = XtAllocateGC(w, 0, GCForeground, &values, GCFont, 0);
else
lw->list.revgc = XtGetGC(w, GCForeground | GCFont, &values);
values.tile = XmuCreateStippledPixmap(XtScreen(w),
lw->list.foreground,
lw->core.background_pixel,
lw->core.depth);
values.fill_style = FillTiled;
if (lw->simple.international == True)
lw->list.graygc = XtAllocateGC(w, 0, GCTile | GCFillStyle,
&values, GCFont, 0);
else
lw->list.graygc = XtGetGC(w, GCFont | GCTile | GCFillStyle, &values);
}
static void
CalculatedValues(Widget w)
{
int i, len;
ListWidget lw = (ListWidget)w;
if (lw->list.list == NULL) {
lw->list.list = &lw->core.name;
lw->list.nitems = 1;
}
if (lw->list.nitems == 0)
for (; lw->list.list[lw->list.nitems] != NULL ; lw->list.nitems++)
;
if (LongestFree(lw)) {
lw->list.longest = 0;
for (i = 0 ; i < lw->list.nitems; i++) {
if (lw->simple.international == True)
len = XmbTextEscapement(lw->list.fontset, lw->list.list[i],
strlen(lw->list.list[i]));
else
len = XTextWidth(lw->list.font, lw->list.list[i],
strlen(lw->list.list[i]));
if (len > lw->list.longest)
lw->list.longest = len;
}
}
lw->list.col_width = lw->list.longest + lw->list.column_space;
}
static void
ResetList(Widget w, Bool changex, Bool changey)
{
Dimension width = XtWidth(w);
Dimension height = XtHeight(w);
CalculatedValues(w);
if (Layout(w, changex, changey, &width, &height)) {
if (XtIsComposite(XtParent(w)))
ChangeSize(w, width, height);
else {
XtWidth(w) = width;
XtHeight(w) = height;
}
}
}
static void
ChangeSize(Widget w, unsigned int width, unsigned int height)
{
XtWidgetGeometry request, reply;
request.request_mode = CWWidth | CWHeight;
request.width = width;
request.height = height;
switch (XtMakeGeometryRequest(w, &request, &reply)) {
case XtGeometryYes:
case XtGeometryNo:
break;
case XtGeometryAlmost:
Layout(w, request.height != reply.height,
request.width != reply.width, &reply.width, &reply.height);
request = reply;
switch (XtMakeGeometryRequest(w, &request, &reply)) {
case XtGeometryYes:
case XtGeometryNo:
break;
case XtGeometryAlmost:
request = reply;
Layout(w, False, False, &request.width, &request.height);
request.request_mode = CWWidth | CWHeight;
XtMakeGeometryRequest(w, &request, &reply);
default:
break;
}
default:
break;
}
}
static void
XawListInitialize(Widget temp1, Widget cnew, ArgList args, Cardinal *num_args)
{
ListWidget lw = (ListWidget)cnew;
if (!lw->list.font) XtError("Aborting: no font found\n");
if (lw->simple.international && !lw->list.fontset)
XtError("Aborting: no fontset found\n");
lw->list.freedoms = ((XtWidth(lw) != 0) * WidthLock +
(XtHeight(lw) != 0) * HeightLock +
(lw->list.longest != 0) * LongestLock);
GetGCs(cnew);
if (lw->simple.international == True)
lw->list.row_height =
XExtentsOfFontSet(lw->list.fontset)->max_ink_extent.height +
lw->list.row_space;
else
lw->list.row_height = lw->list.font->max_bounds.ascent +
lw->list.font->max_bounds.descent +
lw->list.row_space;
ResetList(cnew, WidthFree(lw), HeightFree(lw));
lw->list.highlight = lw->list.is_highlighted = NO_HIGHLIGHT;
}
static int
CvtToItem(Widget w, int xloc, int yloc, int *item)
{
int one, another;
ListWidget lw = (ListWidget)w;
int ret_val = OKAY;
if (lw->list.vertical_cols) {
one = lw->list.nrows * ((xloc - (int)lw->list.internal_width)
/ lw->list.col_width);
another = (yloc - (int)lw->list.internal_height) / lw->list.row_height;
if (another >= lw->list.nrows) {
another = lw->list.nrows - 1;
ret_val = OUT_OF_RANGE;
}
}
else {
one = (lw->list.ncols * ((yloc - (int)lw->list.internal_height)
/ lw->list.row_height));
another = (xloc - (int)lw->list.internal_width) / lw->list.col_width;
if (another >= lw->list.ncols) {
another = lw->list.ncols - 1;
ret_val = OUT_OF_RANGE;
}
}
if (xloc < 0 || yloc < 0)
ret_val = OUT_OF_RANGE;
if (one < 0)
one = 0;
if (another < 0)
another = 0;
*item = one + another;
if (*item >= lw->list.nitems)
return (OUT_OF_RANGE);
return (ret_val);
}
static void
FindCornerItems(Widget w, XEvent *event, int *ul_ret, int *lr_ret)
{
int xloc, yloc;
xloc = event->xexpose.x;
yloc = event->xexpose.y;
CvtToItem(w, xloc, yloc, ul_ret);
xloc += event->xexpose.width;
yloc += event->xexpose.height;
CvtToItem(w, xloc, yloc, lr_ret);
}
static Bool
ItemInRectangle(Widget w, int ul, int lr, int item)
{
ListWidget lw = (ListWidget)w;
int mod_item;
int things;
if (item < ul || item > lr)
return (False);
if (lw->list.vertical_cols)
things = lw->list.nrows;
else
things = lw->list.ncols;
mod_item = item % things;
if ((mod_item >= ul % things) && (mod_item <= lr % things))
return (True);
return (False);
}
static void
HighlightBackground(Widget w, int x, int y, GC gc)
{
ListWidget lw = (ListWidget)w;
Dimension width = lw->list.col_width;
Dimension height = lw->list.row_height;
Dimension frame_limited_width = XtWidth(w) - lw->list.internal_width - x;
Dimension frame_limited_height= XtHeight(w) - lw->list.internal_height - y;
if (width > frame_limited_width)
width = frame_limited_width;
if (height > frame_limited_height)
height = frame_limited_height;
if (x < lw->list.internal_width) {
width = width - (lw->list.internal_width - x);
x = lw->list.internal_width;
}
if (y < lw->list.internal_height) {
height = height - (lw->list.internal_height - y);
y = lw->list.internal_height;
}
if (gc == lw->list.revgc && lw->core.background_pixmap != XtUnspecifiedPixmap)
XClearArea(XtDisplay(w), XtWindow(w), x, y, width, height, False);
else
XFillRectangle(XtDisplay(w), XtWindow(w), gc, x, y, width, height);
}
static void
ClipToShadowInteriorAndLongest(ListWidget lw, GC *gc_p, unsigned int x)
{
XRectangle rect;
rect.x = x;
rect.y = lw->list.internal_height;
rect.height = XtHeight(lw) - (lw->list.internal_height << 1);
rect.width = XtWidth(lw) - lw->list.internal_width - x;
if (rect.width > lw->list.longest)
rect.width = lw->list.longest;
XSetClipRectangles(XtDisplay((Widget)lw), *gc_p, 0, 0, &rect, 1, YXBanded);
}
static void
PaintItemName(Widget w, int item)
{
char *str;
GC gc;
int x, y, str_y;
ListWidget lw = (ListWidget)w;
XFontSetExtents *ext = XExtentsOfFontSet(lw->list.fontset);
if (!XtIsRealized(w) || item > lw->list.nitems)
return;
if (lw->list.vertical_cols) {
x = lw->list.col_width * (item / lw->list.nrows)
+ lw->list.internal_width;
y = lw->list.row_height * (item % lw->list.nrows)
+ lw->list.internal_height;
}
else {
x = lw->list.col_width * (item % lw->list.ncols)
+ lw->list.internal_width;
y = lw->list.row_height * (item / lw->list.ncols)
+ lw->list.internal_height;
}
if ( lw->simple.international == True )
str_y = y + XawAbs(ext->max_ink_extent.y);
else
str_y = y + lw->list.font->max_bounds.ascent;
if (item == lw->list.is_highlighted) {
if (item == lw->list.highlight) {
gc = lw->list.revgc;
HighlightBackground(w, x, y, lw->list.normgc);
}
else {
if (XtIsSensitive(w))
gc = lw->list.normgc;
else
gc = lw->list.graygc;
HighlightBackground(w, x, y, lw->list.revgc);
lw->list.is_highlighted = NO_HIGHLIGHT;
}
}
else {
if (item == lw->list.highlight) {
gc = lw->list.revgc;
HighlightBackground(w, x, y, lw->list.normgc);
lw->list.is_highlighted = item;
}
else {
if (XtIsSensitive(w))
gc = lw->list.normgc;
else
gc = lw->list.graygc;
}
}
x += lw->list.column_space >> 1;
str_y += lw->list.row_space >> 1;
str = lw->list.list[item];
ClipToShadowInteriorAndLongest(lw, &gc, x);
if (lw->simple.international == True)
XmbDrawString(XtDisplay(w), XtWindow(w), lw->list.fontset,
gc, x, str_y, str, strlen(str));
else
XDrawString(XtDisplay(w), XtWindow(w), gc, x, str_y, str, strlen(str));
XSetClipMask(XtDisplay(w), gc, None);
}
static void
XawListRedisplay(Widget w, XEvent *event, Region region)
{
int item;
int ul_item, lr_item;
ListWidget lw = (ListWidget)w;
if (event == NULL) {
ul_item = 0;
lr_item = lw->list.nrows * lw->list.ncols - 1;
XClearWindow(XtDisplay(w), XtWindow(w));
}
else
FindCornerItems(w, event, &ul_item, &lr_item);
if (Superclass->core_class.expose)
(Superclass->core_class.expose)(w, event, region);
for (item = ul_item; item <= lr_item && item < lw->list.nitems; item++)
if (ItemInRectangle(w, ul_item, lr_item, item))
PaintItemName(w, item);
}
static XtGeometryResult
XawListQueryGeometry(Widget w, XtWidgetGeometry *intended,
XtWidgetGeometry *requested)
{
Dimension new_width, new_height;
Bool change, width_req, height_req;
width_req = intended->request_mode & CWWidth;
height_req = intended->request_mode & CWHeight;
if (width_req)
new_width = intended->width;
else
new_width = XtWidth(w);
if (height_req)
new_height = intended->height;
else
new_height = XtHeight(w);
requested->request_mode = 0;
if (!width_req && !height_req)
return (XtGeometryYes);
change = Layout(w, !width_req, !height_req, &new_width, &new_height);
requested->request_mode |= CWWidth;
requested->width = new_width;
requested->request_mode |= CWHeight;
requested->height = new_height;
if (change)
return (XtGeometryAlmost);
return (XtGeometryYes);
}
static void
XawListResize(Widget w)
{
Dimension width, height;
width = XtWidth(w);
height = XtHeight(w);
if (Layout(w, False, False, &width, &height))
XtAppWarning(XtWidgetToApplicationContext(w),
"List Widget: Size changed when it shouldn't "
"have when resising.");
}
static Bool
Layout(Widget w, Bool xfree, Bool yfree, Dimension *width, Dimension *height)
{
ListWidget lw = (ListWidget)w;
Bool change = False;
unsigned long width2 = 0, height2 = 0;
if (lw->list.force_cols) {
lw->list.ncols = lw->list.default_cols;
if (lw->list.ncols <= 0)
lw->list.ncols = 1;
lw->list.nrows = ((lw->list.nitems - 1) / lw->list.ncols) + 1;
if (xfree) {
width2 = lw->list.ncols * lw->list.col_width +
(lw->list.internal_width << 1);
change = True;
}
if (yfree) {
height2 = lw->list.nrows * lw->list.row_height +
(lw->list.internal_height << 1);
change = True;
}
}
else if (xfree && yfree) {
lw->list.ncols = lw->list.default_cols;
if (lw->list.ncols <= 0) {
int wid = (int)XtWidth(lw) - (int)(lw->list.internal_width << 1)
+ (int)lw->list.column_space;
if (wid <= 0 || lw->list.col_width <= 0
|| (lw->list.ncols = wid / lw->list.col_width) <= 0)
lw->list.ncols = 1;
}
width2 = lw->list.ncols * lw->list.col_width
+ (lw->list.internal_width << 1);
height2 = (lw->list.nrows * lw->list.row_height)
+ (lw->list.internal_height << 1);
change = True;
}
else if (!xfree) {
lw->list.ncols = ((int)(*width - (lw->list.internal_width << 1))
/ (int)lw->list.col_width);
if (lw->list.ncols <= 0)
lw->list.ncols = 1;
lw->list.nrows = ((lw->list.nitems - 1) / lw->list.ncols) + 1;
if (yfree) {
height2 = lw->list.nrows * lw->list.row_height +
(lw->list.internal_height << 1);
change = True;
}
}
else if (!yfree) {
lw->list.nrows = ((int)(*height - (lw->list.internal_height << 1))
/ (int)lw->list.row_height);
if (lw->list.nrows <= 0)
lw->list.nrows = 1;
lw->list.ncols = ((lw->list.nitems - 1) / lw->list.nrows) + 1;
width2 = lw->list.ncols * lw->list.col_width +
(lw->list.internal_width << 1);
change = True;
}
if (!lw->list.force_cols && lw->list.nrows) {
while (1) {
lw->list.nrows = ((lw->list.nitems - 1) / lw->list.ncols) + 1;
width2 = lw->list.ncols * lw->list.col_width +
(lw->list.internal_width << 1);
height2 = lw->list.nrows * lw->list.row_height +
(lw->list.internal_height << 1);
if (width2 >= MaxSize && height2 >= MaxSize)
break;
if (height2 > MaxSize)
++lw->list.ncols;
else if (width2 > MaxSize && lw->list.ncols > 1)
--lw->list.ncols;
else
break;
}
}
if (width2)
*width = width2;
if (height2)
*height = height2;
return (change);
}
static void
Notify(Widget w, XEvent *event, String *params, Cardinal *num_params)
{
ListWidget lw = (ListWidget)w;
int item, item_len;
XawListReturnStruct ret_value;
if ((CvtToItem(w, event->xbutton.x, event->xbutton.y, &item) == OUT_OF_RANGE)
|| lw->list.highlight != item) {
#ifndef OLDXAW
if (!lw->list.show_current || lw->list.selected == NO_HIGHLIGHT)
XawListUnhighlight(w);
else
XawListHighlight(w, lw->list.selected);
#else
XawListUnhighlight(w);
#endif
return;
}
item_len = strlen(lw->list.list[item]);
if (lw->list.paste)
XStoreBytes(XtDisplay(w), lw->list.list[item], item_len);
#ifndef OLDXAW
lw->list.selected = item;
#endif
ret_value.string = lw->list.list[item];
ret_value.list_index = item;
XtCallCallbacks(w, XtNcallback, (XtPointer)&ret_value);
}
static void
Unset(Widget w, XEvent *event, String *params, Cardinal *num_params)
{
XawListUnhighlight(w);
}
static void
Set(Widget w, XEvent *event, String *params, Cardinal *num_params)
{
int item;
ListWidget lw = (ListWidget)w;
#ifndef OLDXAW
lw->list.selected = lw->list.highlight;
#endif
if (CvtToItem(w, event->xbutton.x, event->xbutton.y, &item) == OUT_OF_RANGE)
XawListUnhighlight(w);
else if (lw->list.is_highlighted != item)
XawListHighlight(w, item);
}
static Boolean
XawListSetValues(Widget current, Widget request, Widget cnew,
ArgList args, Cardinal *num_args)
{
ListWidget cl = (ListWidget)current;
ListWidget rl = (ListWidget)request;
ListWidget nl = (ListWidget)cnew;
Bool redraw = False;
XFontSetExtents *ext = XExtentsOfFontSet(nl->list.fontset);
if (XtWidth(nl) != XtWidth(cl))
nl->list.freedoms |= WidthLock;
if (XtWidth(nl) == 0)
nl->list.freedoms &= ~WidthLock;
if (XtHeight(nl) != XtHeight(cl))
nl->list.freedoms |= HeightLock;
if (XtHeight(nl) == 0)
nl->list.freedoms &= ~HeightLock;
if (nl->list.longest != cl->list.longest)
nl->list.freedoms |= LongestLock;
if (nl->list.longest == 0)
nl->list.freedoms &= ~LongestLock;
if (cl->list.foreground != nl->list.foreground ||
cl->core.background_pixel != nl->core.background_pixel ||
cl->list.font != nl->list.font) {
XGCValues values;
XGetGCValues(XtDisplay(current), cl->list.graygc, GCTile, &values);
XmuReleaseStippledPixmap(XtScreen(current), values.tile);
XtReleaseGC(current, cl->list.graygc);
XtReleaseGC(current, cl->list.revgc);
XtReleaseGC(current, cl->list.normgc);
GetGCs(cnew);
redraw = True;
}
if (cl->list.font != nl->list.font && cl->simple.international == False)
nl->list.row_height = nl->list.font->max_bounds.ascent
+ nl->list.font->max_bounds.descent
+ nl->list.row_space;
else if (cl->list.fontset != nl->list.fontset
&& cl->simple.international == True)
nl->list.row_height = ext->max_ink_extent.height + nl->list.row_space;
else if (cl->list.row_space != nl->list.row_space) {
if (cl->simple.international == True)
nl->list.row_height = ext->max_ink_extent.height + nl->list.row_space;
else
nl->list.row_height = nl->list.font->max_bounds.ascent
+ nl->list.font->max_bounds.descent
+ nl->list.row_space;
}
if (XtWidth(cl) != XtWidth(nl) || XtHeight(cl) != XtHeight(nl)
|| cl->list.internal_width != nl->list.internal_width
|| cl->list.internal_height != nl->list.internal_height
|| cl->list.column_space != nl->list.column_space
|| cl->list.row_space != nl->list.row_space
|| cl->list.default_cols != nl->list.default_cols
|| (cl->list.force_cols != nl->list.force_cols
&& rl->list.force_cols != nl->list.ncols)
|| cl->list.vertical_cols != nl->list.vertical_cols
|| cl->list.longest != nl->list.longest
|| cl->list.nitems != nl->list.nitems
|| cl->list.font != nl->list.font
|| cl->list.fontset != nl->list.fontset
|| cl->list.list != nl->list.list) {
CalculatedValues(cnew);
Layout(cnew, WidthFree(nl), HeightFree(nl),
&nl->core.width, &nl->core.height);
redraw = True;
}
if (cl->list.list != nl->list.list || cl->list.nitems != nl->list.nitems)
nl->list.is_highlighted = nl->list.highlight = NO_HIGHLIGHT;
if (cl->core.sensitive != nl->core.sensitive
|| cl->core.ancestor_sensitive != nl->core.ancestor_sensitive) {
nl->list.highlight = NO_HIGHLIGHT;
redraw = True;
}
return (redraw);
}
static void
XawListDestroy(Widget w)
{
ListWidget lw = (ListWidget)w;
XGCValues values;
XGetGCValues(XtDisplay(w), lw->list.graygc, GCTile, &values);
XmuReleaseStippledPixmap(XtScreen(w), values.tile);
XtReleaseGC(w, lw->list.graygc);
XtReleaseGC(w, lw->list.revgc);
XtReleaseGC(w, lw->list.normgc);
}
void
XawListChange(Widget w, char **list, int nitems, int longest,
#if NeedWidePrototypes
int resize_it
#else
Boolean resize_it
#endif
)
{
ListWidget lw = (ListWidget)w;
Dimension new_width = XtWidth(w);
Dimension new_height = XtHeight(w);
lw->list.list = list;
if (nitems <= 0)
nitems = 0;
lw->list.nitems = nitems;
if (longest <= 0)
longest = 0;
if (longest != 0)
lw->list.freedoms |= LongestLock;
else
lw->list.freedoms &= ~LongestLock;
if (resize_it)
lw->list.freedoms &= ~WidthLock & ~HeightLock;
lw->list.longest = longest;
CalculatedValues(w);
if (Layout(w, WidthFree(w), HeightFree(w), &new_width, &new_height))
ChangeSize(w, new_width, new_height);
lw->list.is_highlighted = lw->list.highlight = NO_HIGHLIGHT;
if (XtIsRealized(w))
XawListRedisplay(w, NULL, NULL);
}
void
XawListUnhighlight(Widget w)
{
ListWidget lw = (ListWidget)w;
lw->list.highlight = NO_HIGHLIGHT;
if (lw->list.is_highlighted != NO_HIGHLIGHT)
PaintItemName(w, lw->list.is_highlighted);
}
void
XawListHighlight(Widget w, int item)
{
ListWidget lw = (ListWidget)w;
if (XtIsSensitive(w)) {
lw->list.highlight = item;
if (lw->list.is_highlighted != NO_HIGHLIGHT)
PaintItemName(w, lw->list.is_highlighted);
PaintItemName(w, item);
}
}
XawListReturnStruct *
XawListShowCurrent(Widget w)
{
ListWidget lw = (ListWidget)w;
XawListReturnStruct *ret_val;
ret_val = (XawListReturnStruct *)XtMalloc(sizeof(XawListReturnStruct));
ret_val->list_index = lw->list.highlight;
if (ret_val->list_index == XAW_LIST_NONE)
ret_val->string = "";
else
ret_val->string = lw->list.list[ret_val->list_index];
return (ret_val);
}