638 lines
16 KiB
C
638 lines
16 KiB
C
/*
|
|
* Copyright (c) 1999 by The XFree86 Project, Inc.
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
* copy of this software and associated documentation files (the "Software"),
|
|
* to deal in the Software without restriction, including without limitation
|
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
* and/or sell copies of the Software, and to permit persons to whom the
|
|
* Software is furnished to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be included in
|
|
* all copies or substantial portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
* THE XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
|
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
* SOFTWARE.
|
|
*
|
|
* Except as contained in this notice, the name of the XFree86 Project shall
|
|
* not be used in advertising or otherwise to promote the sale, use or other
|
|
* dealings in this Software without prior written authorization from the
|
|
* XFree86 Project.
|
|
*
|
|
* Author: Paulo César Pereira de Andrade
|
|
*/
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include <config.h>
|
|
#endif
|
|
#include <X11/IntrinsicP.h>
|
|
#include <X11/StringDefs.h>
|
|
#include <X11/Xos.h>
|
|
#include <X11/Xaw/TipP.h>
|
|
#include <X11/Xaw/XawInit.h>
|
|
#include <X11/Xmu/Converters.h>
|
|
#include "Private.h"
|
|
|
|
#define TIP_EVENT_MASK (ButtonPressMask | \
|
|
ButtonReleaseMask | \
|
|
PointerMotionMask | \
|
|
ButtonMotionMask | \
|
|
KeyPressMask | \
|
|
KeyReleaseMask | \
|
|
EnterWindowMask | \
|
|
LeaveWindowMask)
|
|
|
|
/*
|
|
* Types
|
|
*/
|
|
typedef struct _XawTipInfo {
|
|
Screen *screen;
|
|
TipWidget tip;
|
|
Widget widget;
|
|
Bool mapped;
|
|
struct _XawTipInfo *next;
|
|
} XawTipInfo;
|
|
|
|
/*
|
|
* Class Methods
|
|
*/
|
|
static void XawTipClassInitialize(void);
|
|
static void XawTipInitialize(Widget, Widget, ArgList, Cardinal*);
|
|
static void XawTipDestroy(Widget);
|
|
static void XawTipExpose(Widget, XEvent*, Region);
|
|
static void XawTipRealize(Widget, Mask*, XSetWindowAttributes*);
|
|
static Boolean XawTipSetValues(Widget, Widget, Widget, ArgList, Cardinal*);
|
|
|
|
/*
|
|
* Prototypes
|
|
*/
|
|
static void TipEventHandler(Widget, XtPointer, XEvent*, Boolean*);
|
|
static void TipShellEventHandler(Widget, XtPointer, XEvent*, Boolean*);
|
|
static XawTipInfo *CreateTipInfo(Widget);
|
|
static XawTipInfo *FindTipInfo(Widget);
|
|
static void ResetTip(XawTipInfo*, Bool);
|
|
static void TipTimeoutCallback(XtPointer, XtIntervalId*);
|
|
static void TipLayout(XawTipInfo*);
|
|
static void TipPosition(XawTipInfo*);
|
|
|
|
/*
|
|
* Initialization
|
|
*/
|
|
#define offset(field) XtOffsetOf(TipRec, tip.field)
|
|
static XtResource resources[] = {
|
|
{
|
|
XtNforeground,
|
|
XtCForeground,
|
|
XtRPixel,
|
|
sizeof(Pixel),
|
|
offset(foreground),
|
|
XtRString,
|
|
XtDefaultForeground,
|
|
},
|
|
{
|
|
XtNfont,
|
|
XtCFont,
|
|
XtRFontStruct,
|
|
sizeof(XFontStruct*),
|
|
offset(font),
|
|
XtRString,
|
|
XtDefaultFont
|
|
},
|
|
{
|
|
XtNfontSet,
|
|
XtCFontSet,
|
|
XtRFontSet,
|
|
sizeof(XFontSet),
|
|
offset(fontset),
|
|
XtRString,
|
|
XtDefaultFontSet
|
|
},
|
|
{
|
|
XtNtopMargin,
|
|
XtCVerticalMargins,
|
|
XtRDimension,
|
|
sizeof(Dimension),
|
|
offset(top_margin),
|
|
XtRImmediate,
|
|
(XtPointer)2
|
|
},
|
|
{
|
|
XtNbottomMargin,
|
|
XtCVerticalMargins,
|
|
XtRDimension,
|
|
sizeof(Dimension),
|
|
offset(bottom_margin),
|
|
XtRImmediate,
|
|
(XtPointer)2
|
|
},
|
|
{
|
|
XtNleftMargin,
|
|
XtCHorizontalMargins,
|
|
XtRDimension,
|
|
sizeof(Dimension),
|
|
offset(left_margin),
|
|
XtRImmediate,
|
|
(XtPointer)6
|
|
},
|
|
{
|
|
XtNrightMargin,
|
|
XtCHorizontalMargins,
|
|
XtRDimension,
|
|
sizeof(Dimension),
|
|
offset(right_margin),
|
|
XtRImmediate,
|
|
(XtPointer)6
|
|
},
|
|
{
|
|
XtNbackingStore,
|
|
XtCBackingStore,
|
|
XtRBackingStore,
|
|
sizeof(int),
|
|
offset(backing_store),
|
|
XtRImmediate,
|
|
(XtPointer)(Always + WhenMapped + NotUseful)
|
|
},
|
|
{
|
|
XtNtimeout,
|
|
XtCTimeout,
|
|
XtRInt,
|
|
sizeof(int),
|
|
offset(timeout),
|
|
XtRImmediate,
|
|
(XtPointer)500
|
|
},
|
|
{
|
|
XawNdisplayList,
|
|
XawCDisplayList,
|
|
XawRDisplayList,
|
|
sizeof(XawDisplayList*),
|
|
offset(display_list),
|
|
XtRImmediate,
|
|
NULL
|
|
},
|
|
};
|
|
#undef offset
|
|
|
|
TipClassRec tipClassRec = {
|
|
/* core */
|
|
{
|
|
(WidgetClass)&widgetClassRec, /* superclass */
|
|
"Tip", /* class_name */
|
|
sizeof(TipRec), /* widget_size */
|
|
XawTipClassInitialize, /* class_initialize */
|
|
NULL, /* class_part_initialize */
|
|
False, /* class_inited */
|
|
XawTipInitialize, /* initialize */
|
|
NULL, /* initialize_hook */
|
|
XawTipRealize, /* realize */
|
|
NULL, /* actions */
|
|
0, /* num_actions */
|
|
resources, /* resources */
|
|
XtNumber(resources), /* num_resources */
|
|
NULLQUARK, /* xrm_class */
|
|
True, /* compress_motion */
|
|
True, /* compress_exposure */
|
|
True, /* compress_enterleave */
|
|
False, /* visible_interest */
|
|
XawTipDestroy, /* destroy */
|
|
NULL, /* resize */
|
|
XawTipExpose, /* expose */
|
|
XawTipSetValues, /* set_values */
|
|
NULL, /* set_values_hook */
|
|
XtInheritSetValuesAlmost, /* set_values_almost */
|
|
NULL, /* get_values_hook */
|
|
NULL, /* accept_focus */
|
|
XtVersion, /* version */
|
|
NULL, /* callback_private */
|
|
NULL, /* tm_table */
|
|
XtInheritQueryGeometry, /* query_geometry */
|
|
XtInheritDisplayAccelerator, /* display_accelerator */
|
|
NULL, /* extension */
|
|
},
|
|
/* tip */
|
|
{
|
|
NULL, /* extension */
|
|
},
|
|
};
|
|
|
|
WidgetClass tipWidgetClass = (WidgetClass)&tipClassRec;
|
|
|
|
static XawTipInfo *first_tip;
|
|
|
|
/*
|
|
* Implementation
|
|
*/
|
|
static void
|
|
XawTipClassInitialize(void)
|
|
{
|
|
XawInitializeWidgetSet();
|
|
XtAddConverter(XtRString, XtRBackingStore, XmuCvtStringToBackingStore,
|
|
NULL, 0);
|
|
XtSetTypeConverter(XtRBackingStore, XtRString, XmuCvtBackingStoreToString,
|
|
NULL, 0, XtCacheNone, NULL);
|
|
}
|
|
|
|
/*ARGSUSED*/
|
|
static void
|
|
XawTipInitialize(Widget req, Widget w, ArgList args, Cardinal *num_args)
|
|
{
|
|
TipWidget tip = (TipWidget)w;
|
|
XGCValues values;
|
|
|
|
if (!tip->tip.font) XtError("Aborting: no font found\n");
|
|
if (tip->tip.international && !tip->tip.fontset)
|
|
XtError("Aborting: no fontset found\n");
|
|
|
|
tip->tip.timer = 0;
|
|
|
|
values.foreground = tip->tip.foreground;
|
|
values.background = tip->core.background_pixel;
|
|
values.font = tip->tip.font->fid;
|
|
values.graphics_exposures = False;
|
|
|
|
tip->tip.gc = XtAllocateGC(w, 0, GCForeground | GCBackground | GCFont |
|
|
GCGraphicsExposures, &values, GCFont, 0);
|
|
}
|
|
|
|
static void
|
|
XawTipDestroy(Widget w)
|
|
{
|
|
XawTipInfo *info = FindTipInfo(w);
|
|
TipWidget tip = (TipWidget)w;
|
|
|
|
if (tip->tip.timer)
|
|
XtRemoveTimeOut(tip->tip.timer);
|
|
|
|
XtReleaseGC(w, tip->tip.gc);
|
|
|
|
XtRemoveEventHandler(XtParent(w), KeyPressMask, False, TipShellEventHandler,
|
|
(XtPointer)NULL);
|
|
if (info == first_tip)
|
|
first_tip = first_tip->next;
|
|
else {
|
|
XawTipInfo *p = first_tip;
|
|
|
|
while (p && p->next != info)
|
|
p = p->next;
|
|
if (p)
|
|
p->next = info->next;
|
|
}
|
|
XtFree((char*)info);
|
|
}
|
|
|
|
static void
|
|
XawTipRealize(Widget w, Mask *mask, XSetWindowAttributes *attr)
|
|
{
|
|
TipWidget tip = (TipWidget)w;
|
|
|
|
if (tip->tip.backing_store == Always ||
|
|
tip->tip.backing_store == NotUseful ||
|
|
tip->tip.backing_store == WhenMapped) {
|
|
*mask |= CWBackingStore;
|
|
attr->backing_store = tip->tip.backing_store;
|
|
}
|
|
else
|
|
*mask &= ~CWBackingStore;
|
|
*mask |= CWOverrideRedirect;
|
|
attr->override_redirect = True;
|
|
|
|
XtWindow(w) = XCreateWindow(DisplayOfScreen(XtScreen(w)),
|
|
RootWindowOfScreen(XtScreen(w)),
|
|
XtX(w), XtY(w),
|
|
XtWidth(w) ? XtWidth(w) : 1,
|
|
XtHeight(w) ? XtHeight(w) : 1,
|
|
XtBorderWidth(w),
|
|
DefaultDepthOfScreen(XtScreen(w)),
|
|
InputOutput,
|
|
(Visual *)CopyFromParent,
|
|
*mask, attr);
|
|
}
|
|
|
|
static void
|
|
XawTipExpose(Widget w, XEvent *event, Region region)
|
|
{
|
|
TipWidget tip = (TipWidget)w;
|
|
GC gc = tip->tip.gc;
|
|
char *nl, *label = tip->tip.label;
|
|
Position y = tip->tip.top_margin + tip->tip.font->max_bounds.ascent;
|
|
int len;
|
|
|
|
if (tip->tip.display_list)
|
|
XawRunDisplayList(w, tip->tip.display_list, event, region);
|
|
|
|
if (tip->tip.international == True) {
|
|
Position ksy = tip->tip.top_margin;
|
|
XFontSetExtents *ext = XExtentsOfFontSet(tip->tip.fontset);
|
|
|
|
ksy += XawAbs(ext->max_ink_extent.y);
|
|
|
|
while ((nl = index(label, '\n')) != NULL) {
|
|
XmbDrawString(XtDisplay(w), XtWindow(w), tip->tip.fontset,
|
|
gc, tip->tip.left_margin, ksy, label,
|
|
(int)(nl - label));
|
|
ksy += ext->max_ink_extent.height;
|
|
label = nl + 1;
|
|
}
|
|
len = strlen(label);
|
|
if (len)
|
|
XmbDrawString(XtDisplay(w), XtWindow(w), tip->tip.fontset, gc,
|
|
tip->tip.left_margin, ksy, label, len);
|
|
}
|
|
else {
|
|
while ((nl = index(label, '\n')) != NULL) {
|
|
if (tip->tip.encoding)
|
|
XDrawString16(XtDisplay(w), XtWindow(w), gc,
|
|
tip->tip.left_margin, y,
|
|
(XChar2b*)label, (int)(nl - label) >> 1);
|
|
else
|
|
XDrawString(XtDisplay(w), XtWindow(w), gc,
|
|
tip->tip.left_margin, y, label, (int)(nl - label));
|
|
y += tip->tip.font->max_bounds.ascent +
|
|
tip->tip.font->max_bounds.descent;
|
|
label = nl + 1;
|
|
}
|
|
len = strlen(label);
|
|
if (len) {
|
|
if (tip->tip.encoding)
|
|
XDrawString16(XtDisplay(w), XtWindow(w), gc,
|
|
tip->tip.left_margin, y, (XChar2b*)label, len >> 1);
|
|
else
|
|
XDrawString(XtDisplay(w), XtWindow(w), gc,
|
|
tip->tip.left_margin, y, label, len);
|
|
}
|
|
}
|
|
}
|
|
|
|
/*ARGSUSED*/
|
|
static Boolean
|
|
XawTipSetValues(Widget current, Widget request, Widget cnew,
|
|
ArgList args, Cardinal *num_args)
|
|
{
|
|
TipWidget curtip = (TipWidget)current;
|
|
TipWidget newtip = (TipWidget)cnew;
|
|
Boolean redisplay = False;
|
|
|
|
if (curtip->tip.font->fid != newtip->tip.font->fid ||
|
|
curtip->tip.foreground != newtip->tip.foreground) {
|
|
XGCValues values;
|
|
|
|
values.foreground = newtip->tip.foreground;
|
|
values.background = newtip->core.background_pixel;
|
|
values.font = newtip->tip.font->fid;
|
|
values.graphics_exposures = False;
|
|
XtReleaseGC(cnew, curtip->tip.gc);
|
|
newtip->tip.gc = XtAllocateGC(cnew, 0, GCForeground | GCBackground |
|
|
GCFont | GCGraphicsExposures, &values,
|
|
GCFont, 0);
|
|
redisplay = True;
|
|
}
|
|
if (curtip->tip.display_list != newtip->tip.display_list)
|
|
redisplay = True;
|
|
|
|
return (redisplay);
|
|
}
|
|
|
|
static void
|
|
TipLayout(XawTipInfo *info)
|
|
{
|
|
XFontStruct *fs = info->tip->tip.font;
|
|
int width = 0, height;
|
|
char *nl, *label = info->tip->tip.label;
|
|
|
|
if (info->tip->tip.international == True) {
|
|
XFontSet fset = info->tip->tip.fontset;
|
|
XFontSetExtents *ext = XExtentsOfFontSet(fset);
|
|
|
|
height = ext->max_ink_extent.height;
|
|
if ((nl = index(label, '\n')) != NULL) {
|
|
/*CONSTCOND*/
|
|
while (True) {
|
|
int w = XmbTextEscapement(fset, label, (int)(nl - label));
|
|
|
|
if (w > width)
|
|
width = w;
|
|
if (*nl == '\0')
|
|
break;
|
|
label = nl + 1;
|
|
if (*label)
|
|
height += ext->max_ink_extent.height;
|
|
if ((nl = index(label, '\n')) == NULL)
|
|
nl = index(label, '\0');
|
|
}
|
|
}
|
|
else
|
|
width = XmbTextEscapement(fset, label, strlen(label));
|
|
}
|
|
else {
|
|
height = fs->max_bounds.ascent + fs->max_bounds.descent;
|
|
if ((nl = index(label, '\n')) != NULL) {
|
|
/*CONSTCOND*/
|
|
while (True) {
|
|
int w = info->tip->tip.encoding ?
|
|
XTextWidth16(fs, (XChar2b*)label, (int)(nl - label) >> 1) :
|
|
XTextWidth(fs, label, (int)(nl - label));
|
|
if (w > width)
|
|
width = w;
|
|
if (*nl == '\0')
|
|
break;
|
|
label = nl + 1;
|
|
if (*label)
|
|
height += fs->max_bounds.ascent + fs->max_bounds.descent;
|
|
if ((nl = index(label, '\n')) == NULL)
|
|
nl = index(label, '\0');
|
|
}
|
|
}
|
|
else
|
|
width = info->tip->tip.encoding ?
|
|
XTextWidth16(fs, (XChar2b*)label, strlen(label) >> 1) :
|
|
XTextWidth(fs, label, strlen(label));
|
|
}
|
|
XtWidth(info->tip) = width + info->tip->tip.left_margin +
|
|
info->tip->tip.right_margin;
|
|
XtHeight(info->tip) = height + info->tip->tip.top_margin +
|
|
info->tip->tip.bottom_margin;
|
|
}
|
|
|
|
#define DEFAULT_TIP_Y_OFFSET 12
|
|
static void
|
|
TipPosition(XawTipInfo *info)
|
|
{
|
|
Window r, c;
|
|
int rx, ry, wx, wy;
|
|
unsigned mask;
|
|
Position x, y;
|
|
|
|
XQueryPointer(XtDisplay((Widget)info->tip), XtWindow((Widget)info->tip),
|
|
&r, &c, &rx, &ry, &wx, &wy, &mask);
|
|
x = rx - (XtWidth(info->tip) >> 1);
|
|
y = ry + DEFAULT_TIP_Y_OFFSET;
|
|
|
|
if (x >= 0) {
|
|
int scr_width = WidthOfScreen(XtScreen(info->tip));
|
|
|
|
if (x + XtWidth(info->tip) + XtBorderWidth(info->tip) > scr_width)
|
|
x = scr_width - XtWidth(info->tip) - XtBorderWidth(info->tip);
|
|
}
|
|
if (x < 0)
|
|
x = 0;
|
|
if (y >= 0) {
|
|
int scr_height = HeightOfScreen(XtScreen(info->tip));
|
|
|
|
if (y + XtHeight(info->tip) + XtBorderWidth(info->tip) > scr_height)
|
|
y -= XtHeight(info->tip) + XtBorderWidth(info->tip) +
|
|
(DEFAULT_TIP_Y_OFFSET << 1);
|
|
}
|
|
if (y < 0)
|
|
y = 0;
|
|
|
|
XMoveResizeWindow(XtDisplay(info->tip), XtWindow(info->tip),
|
|
(int)(XtX(info->tip) = x), (int)(XtY(info->tip) = y),
|
|
(unsigned)XtWidth(info->tip), (unsigned)XtHeight(info->tip));
|
|
}
|
|
|
|
static XawTipInfo *
|
|
CreateTipInfo(Widget w)
|
|
{
|
|
XawTipInfo *info = XtNew(XawTipInfo);
|
|
Widget shell = w;
|
|
|
|
info->screen = XtScreen(w);
|
|
|
|
while (XtParent(shell))
|
|
shell = XtParent(shell);
|
|
|
|
info->tip = (TipWidget)XtCreateWidget("tip", tipWidgetClass, shell, NULL, 0);
|
|
XtRealizeWidget((Widget)info->tip);
|
|
info->widget = NULL;
|
|
info->mapped = False;
|
|
info->next = NULL;
|
|
XtAddEventHandler(shell, KeyPressMask, False, TipShellEventHandler,
|
|
(XtPointer)NULL);
|
|
|
|
return (info);
|
|
}
|
|
|
|
static XawTipInfo *
|
|
FindTipInfo(Widget w)
|
|
{
|
|
XawTipInfo *ptip, *tip = first_tip;
|
|
Screen *screen = XtScreenOfObject(w);
|
|
|
|
if (tip == NULL)
|
|
return (first_tip = tip = CreateTipInfo(w));
|
|
|
|
for (ptip = tip; tip; ptip = tip, tip = tip->next)
|
|
if (tip->screen == screen)
|
|
return (tip);
|
|
|
|
return (ptip->next = CreateTipInfo(w));
|
|
}
|
|
|
|
static void
|
|
ResetTip(XawTipInfo *info, Bool add_timeout)
|
|
{
|
|
if (info->tip->tip.timer) {
|
|
XtRemoveTimeOut(info->tip->tip.timer);
|
|
info->tip->tip.timer = 0;
|
|
}
|
|
if (info->mapped) {
|
|
XtRemoveGrab(XtParent((Widget)info->tip));
|
|
XUnmapWindow(XtDisplay((Widget)info->tip), XtWindow((Widget)info->tip));
|
|
info->mapped = False;
|
|
}
|
|
if (add_timeout) {
|
|
info->tip->tip.timer =
|
|
XtAppAddTimeOut(XtWidgetToApplicationContext((Widget)info->tip),
|
|
info->tip->tip.timeout, TipTimeoutCallback,
|
|
(XtPointer)info);
|
|
}
|
|
}
|
|
|
|
static void
|
|
TipTimeoutCallback(XtPointer closure, XtIntervalId *id)
|
|
{
|
|
XawTipInfo *info = (XawTipInfo*)closure;
|
|
Arg args[3];
|
|
|
|
info->tip->tip.label = NULL;
|
|
info->tip->tip.international = False;
|
|
info->tip->tip.encoding = 0;
|
|
info->tip->tip.timer = 0;
|
|
XtSetArg(args[0], XtNtip, &info->tip->tip.label);
|
|
XtSetArg(args[1], XtNinternational, &info->tip->tip.international);
|
|
XtSetArg(args[2], XtNencoding, &info->tip->tip.encoding);
|
|
XtGetValues(info->widget, args, 3);
|
|
|
|
if (info->tip->tip.label) {
|
|
TipLayout(info);
|
|
TipPosition(info);
|
|
XMapRaised(XtDisplay((Widget)info->tip), XtWindow((Widget)info->tip));
|
|
XtAddGrab(XtParent((Widget)info->tip), True, True);
|
|
info->mapped = True;
|
|
}
|
|
}
|
|
|
|
/*ARGSUSED*/
|
|
static void
|
|
TipShellEventHandler(Widget w, XtPointer client_data, XEvent *event,
|
|
Boolean *continue_to_dispatch)
|
|
{
|
|
ResetTip(FindTipInfo(w), False);
|
|
}
|
|
|
|
/*ARGSUSED*/
|
|
static void
|
|
TipEventHandler(Widget w, XtPointer client_data, XEvent *event,
|
|
Boolean *continue_to_dispatch)
|
|
{
|
|
XawTipInfo *info = FindTipInfo(w);
|
|
Boolean add_timeout;
|
|
|
|
if (info->widget != w) {
|
|
ResetTip(info, False);
|
|
info->widget = w;
|
|
}
|
|
|
|
switch (event->type) {
|
|
case EnterNotify:
|
|
add_timeout = True;
|
|
break;
|
|
case MotionNotify:
|
|
/* If any button is pressed, timer is 0 */
|
|
if (info->mapped)
|
|
return;
|
|
add_timeout = info->tip->tip.timer != 0;
|
|
break;
|
|
default:
|
|
add_timeout = False;
|
|
break;
|
|
}
|
|
ResetTip(info, add_timeout);
|
|
}
|
|
|
|
/*
|
|
* Public routines
|
|
*/
|
|
void
|
|
XawTipEnable(Widget w)
|
|
{
|
|
XtAddEventHandler(w, TIP_EVENT_MASK, False, TipEventHandler,
|
|
(XtPointer)NULL);
|
|
}
|
|
|
|
void
|
|
XawTipDisable(Widget w)
|
|
{
|
|
XawTipInfo *info = FindTipInfo(w);
|
|
|
|
XtRemoveEventHandler(w, TIP_EVENT_MASK, False, TipEventHandler,
|
|
(XtPointer)NULL);
|
|
if (info->widget == w)
|
|
ResetTip(info, False);
|
|
}
|