gecko-dev/cmd/xfe/XfeWidgets/XfeToolTip/ToolTip.c

2019 строки
49 KiB
C

/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/*----------------------------------------------------------------------*/
/* */
/* Name: <Xfe/ToolTip.c> */
/* Description: XfeToolTip - TipString / DocString support. */
/* Author: Ramiro Estrugo <ramiro@netscape.com> */
/* */
/*----------------------------------------------------------------------*/
#include <Xfe/ToolTipP.h>
#include <Xfe/ToolTipShell.h>
#include <Xfe/Linked.h>
#include <Xm/LabelGP.h>
#include <Xm/PushBGP.h>
#define TOOL_TIP_SHELL_NAME "ToolTipShell"
#define TOOL_TIP_INTERVAL 1000
#define TOOL_TIP_EVENT_MASK \
( EnterWindowMask | \
LeaveWindowMask | \
ButtonPressMask | \
ButtonReleaseMask | \
KeyPressMask | \
KeyReleaseMask )
#if 0
#define DEBUG_TOOL_TIPS yes
#endif
/*----------------------------------------------------------------------*/
/* */
/* _XfeTipItemInfoRec */
/* */
/*----------------------------------------------------------------------*/
typedef struct
{
/* Item */
Widget item;
/* Does the item have tip string support ? */
Boolean tip_string_installed;
/* Does the item have doc string support ? */
Boolean doc_string_installed;
/* TipString */
Boolean tip_string_enabled;
XfeTipStringObtainCallback tip_string_obtain_callback;
XtPointer tip_string_obtain_data1;
XtPointer tip_string_obtain_data2;
/* DocString */
Boolean doc_string_enabled;
XfeTipStringObtainCallback doc_string_obtain_callback;
XtPointer doc_string_obtain_data1;
XtPointer doc_string_obtain_data2;
/* DocString callback */
XfeDocStringCallback doc_string_callback;
XtPointer doc_string_data1;
XtPointer doc_string_data2;
} _XfeTipItemInfoRec,*_XfeTipItemInfo;
/*----------------------------------------------------------------------*/
/*----------------------------------------------------------------------*/
/* */
/* _XfeTipManagerInfoRec */
/* */
/*----------------------------------------------------------------------*/
typedef struct
{
Widget manager;
XfeLinked children_list;
} _XfeTipManagerInfoRec,*_XfeTipManagerInfo;
/*----------------------------------------------------------------------*/
/*----------------------------------------------------------------------*/
/* */
/* Gadget phony input functions */
/* */
/*----------------------------------------------------------------------*/
static void GadgetHackInputDispatch (Widget);
static void GadgetPhonyInputDispatch (Widget,XEvent *,Mask);
static void GadgetSaveRealInputDispatchMethod (Widget);
static XmWidgetDispatchProc GadgetGetRealInputDispatchMethod (Widget);
/*----------------------------------------------------------------------*/
/* */
/* Manager functions */
/* */
/*----------------------------------------------------------------------*/
static _XfeTipManagerInfo ManagerGetInfo (Widget);
static _XfeTipManagerInfo ManagerAddInfo (Widget);
static void ManagerRemoveInfo (Widget,_XfeTipManagerInfo);
static _XfeTipManagerInfo ManagerAllocateInfo (Widget);
static void ManagerFreeInfo (_XfeTipManagerInfo);
static void ManagerDestroyCB (Widget,XtPointer,XtPointer);
/*----------------------------------------------------------------------*/
/* */
/* Widget functions */
/* */
/*----------------------------------------------------------------------*/
static void WidgetAddStageOneEH (Widget);
static void WidgetRemoveStageOneEH (Widget);
static _XfeTipItemInfo WidgetAddTipString (Widget);
static void WidgetRemoveTipString (Widget);
static _XfeTipItemInfo WidgetAddDocString (Widget);
static void WidgetRemoveDocString (Widget);
static _XfeTipItemInfo WidgetGetInfo (Widget);
static void WidgetAddInfo (Widget,_XfeTipItemInfo);
static void WidgetRemoveInfo (Widget,_XfeTipItemInfo);
/*----------------------------------------------------------------------*/
/* */
/* Gadget functions */
/* */
/*----------------------------------------------------------------------*/
static _XfeTipItemInfo GadgetAddTipString (Widget);
static void GadgetRemoveTipString (Widget);
static _XfeTipItemInfo GadgetAddDocString (Widget);
static void GadgetRemoveDocString (Widget);
static _XfeTipItemInfo GadgetGetInfo (Widget);
static void GadgetAddInfo (Widget w,
_XfeTipManagerInfo,
_XfeTipItemInfo);
/*----------------------------------------------------------------------*/
/* */
/* Item (Widget or Gadget) functions */
/* */
/*----------------------------------------------------------------------*/
static void ItemDestroyCB (Widget,XtPointer,XtPointer);
static void ItemFreeInfo (_XfeTipItemInfo);
static _XfeTipItemInfo ItemAllocateInfo (Widget);
static _XfeTipItemInfo ItemGetInfo (Widget);
static void ItemGetTipString (Widget,XmString *,Boolean *);
static void ItemGetDocString (Widget,XmString *,Boolean *);
static void ItemPostToolTip (Widget);
static void ItemUnPostToolTip (Widget);
/*----------------------------------------------------------------------*/
/* */
/* TipString enter / leave / cancel functions */
/* */
/*----------------------------------------------------------------------*/
static void TipStringEnterItem (Widget,_XfeTipItemInfo);
static void TipStringLeaveItem (Widget,_XfeTipItemInfo);
static void TipStringCancelItem (Widget,_XfeTipItemInfo);
/*----------------------------------------------------------------------*/
/* */
/* DocString enter / leave / cancel functions */
/* */
/*----------------------------------------------------------------------*/
static void DocStringEnterItem (Widget,_XfeTipItemInfo);
static void DocStringLeaveItem (Widget,_XfeTipItemInfo);
/*----------------------------------------------------------------------*/
/* */
/* Manager XfeLinked children list functions */
/* */
/*----------------------------------------------------------------------*/
static void ChildrenListDestroyProc (XtPointer,XtPointer);
static Boolean ChildrenListTestFunc (XtPointer,XtPointer);
/*----------------------------------------------------------------------*/
/* */
/* Event handlers */
/* */
/*----------------------------------------------------------------------*/
static void WidgetStageOneEH (Widget,XtPointer,XEvent *,Boolean *);
/*----------------------------------------------------------------------*/
/* */
/* State Two timeout functions */
/* */
/*----------------------------------------------------------------------*/
static void StageTwoTimeout (XtPointer,XtIntervalId *);
static void StageTwoAddTimeout (Widget);
static void StageTwoRemoveTimeout (Widget);
/*----------------------------------------------------------------------*/
/* */
/* Gadget phony input functions */
/* */
/*----------------------------------------------------------------------*/
static void
GadgetPhonyInputDispatch(Widget w,
XEvent * event,
Mask event_mask)
{
XmWidgetDispatchProc input_dispatch = NULL;
assert( XmIsGadget(w) );
input_dispatch = GadgetGetRealInputDispatchMethod(w);
assert( input_dispatch != NULL );
/* Do the tip magic only if tip or doc strings are globally enabled */
if (XfeTipStringGlobalGetEnabledState() ||
XfeDocStringGlobalGetEnabledState())
{
_XfeTipManagerInfo manager_info = NULL;
Widget pw = XtParent(w);
/* Look for the manager info on the gadget's parent */
manager_info = ManagerGetInfo(pw);
/* Make sure the manager info exist */
if (manager_info != NULL)
{
XfeLinkNode node = XfeLinkedFind(manager_info->children_list,
ChildrenListTestFunc,
(XtPointer) w);
if (node != NULL)
{
_XfeTipItemInfo info = (_XfeTipItemInfo) XfeLinkNodeItem(node);
assert( info != NULL );
if (info != NULL)
{
Boolean do_tip_string =
XfeTipStringGlobalGetEnabledState() &&
info->tip_string_enabled;
Boolean do_doc_string =
XfeDocStringGlobalGetEnabledState() &&
info->doc_string_enabled;
/* Enter */
if (event_mask & XmENTER_EVENT)
{
if (do_tip_string)
{
TipStringEnterItem(w,info);
}
if (do_doc_string)
{
DocStringEnterItem(w,info);
}
}
/* Leave */
else if (event_mask & XmLEAVE_EVENT)
{
if (do_tip_string)
{
TipStringLeaveItem(w,info);
}
if (do_doc_string)
{
DocStringLeaveItem(w,info);
}
}
/*
* XmARM_EVENT
* XmMULTI_ARM_EVENT
* XmACTIVATE_EVENT
* XmMULTI_ACTIVATE_EVENT
* XmHELP_EVENT
* XmENTER_EVENT
* XmLEAVE_EVENT
* XmFOCUS_IN_EVENT
* XmFOCUS_OUT_EVENT
* XmBDRAG_EVENT
*/
else
{
if (do_tip_string)
{
TipStringCancelItem(w,info);
}
}
} /* info != NULL */
} /* node != NULL */
} /* manager_info != NULL */
} /* XfeTipStringGlobalGetEnabledState() == True */
/* Invoke the original InputDispatch() method */
(*input_dispatch)(w,event,event_mask);
}
/*----------------------------------------------------------------------*/
static void
GadgetHackInputDispatch(Widget g)
{
XmGadgetClass gadget_class = NULL;
assert( XmIsGadget(g) );
gadget_class = (XmGadgetClass) XtClass(g);
/* Override the original input dispatch with the phony one */
gadget_class->gadget_class.input_dispatch = GadgetPhonyInputDispatch;
}
/*----------------------------------------------------------------------*/
static XmWidgetDispatchProc _xm_real_pbg_input_dispatch = NULL;
static XmWidgetDispatchProc _xm_real_lg_input_dispatch = NULL;
static XmWidgetDispatchProc
GadgetGetRealInputDispatchMethod(Widget g)
{
XmWidgetDispatchProc id = NULL;
assert( _XfeIsAlive(g) ) ;
assert( XmIsGadget(g) ) ;
if (XmIsPushButtonGadget(g))
{
assert( _xm_real_pbg_input_dispatch != NULL );
id = _xm_real_pbg_input_dispatch;
}
else if (XmIsLabelGadget(g))
{
assert( _xm_real_lg_input_dispatch != NULL );
id = _xm_real_lg_input_dispatch;
}
#ifdef DEBUG_ramiro
else
{
assert( 0 );
}
#endif
return id;
}
/*----------------------------------------------------------------------*/
static void
GadgetSaveRealInputDispatchMethod(Widget w)
{
assert( _XfeIsAlive(w) ) ;
assert( XmIsGadget(w) ) ;
if (XmIsPushButtonGadget(w))
{
/* Save the original XmPushButtonGadget input dispatch method */
if (_xm_real_pbg_input_dispatch == NULL)
{
_xm_real_pbg_input_dispatch =
xmPushButtonGadgetClassRec.gadget_class.input_dispatch;
}
}
else if (XmIsLabelGadget(w))
{
/* Save the original XmLabelGadget input dispatch method */
if (_xm_real_lg_input_dispatch == NULL)
{
_xm_real_lg_input_dispatch =
xmLabelGadgetClassRec.gadget_class.input_dispatch;
}
}
#ifdef DEBUG_ramiro
else
{
assert( 0 );
}
#endif
}
/*----------------------------------------------------------------------*/
/*----------------------------------------------------------------------*/
/* */
/* Manager functions */
/* */
/*----------------------------------------------------------------------*/
static XContext _xfe_tt_item_context = None;
static XContext _xfe_tt_manager_context = None;
/*----------------------------------------------------------------------*/
static _XfeTipManagerInfo
ManagerGetInfo(Widget w)
{
_XfeTipManagerInfo manager_info = NULL;
assert( _XfeIsAlive(w) );
assert( _XfeIsRealized(w) );
assert( XmIsManager(w) );
/* Make sure the manager context has been allocated */
if (_xfe_tt_manager_context != None)
{
int find_result = XFindContext(XtDisplay(w),
XtWindow(w),
_xfe_tt_manager_context,
(XPointer *) &manager_info);
if (find_result != 0)
{
manager_info = NULL;
}
}
return manager_info;
}
/*----------------------------------------------------------------------*/
static _XfeTipManagerInfo
ManagerAllocateInfo(Widget w)
{
_XfeTipManagerInfo manager_info = NULL;
assert( _XfeIsAlive(w) );
assert( _XfeIsRealized(w) );
assert( XmIsManager(w) );
manager_info = (_XfeTipManagerInfo)
XtMalloc(sizeof(_XfeTipManagerInfoRec) * 1);
manager_info->manager = w;
manager_info->children_list = XfeLinkedConstruct();
XtAddCallback(w,
XmNdestroyCallback,
ManagerDestroyCB,
(XtPointer) manager_info);
assert( manager_info != NULL );
return manager_info;
}
/*----------------------------------------------------------------------*/
static void
ManagerFreeInfo(_XfeTipManagerInfo manager_info)
{
assert( manager_info != NULL );
/* Destroy the children list if needed */
if (manager_info->children_list)
{
XfeLinkedDestroy(manager_info->children_list,
ChildrenListDestroyProc,
NULL);
}
XtFree((char *) manager_info);
}
/*----------------------------------------------------------------------*/
static _XfeTipManagerInfo
ManagerAddInfo(Widget w)
{
_XfeTipManagerInfo manager_info = NULL;
int save_result;
assert( _XfeIsAlive(w) );
assert( _XfeIsRealized(w) );
assert( XmIsManager(w) );
/* Allocate the gadget context only once */
if (_xfe_tt_manager_context == None)
{
_xfe_tt_manager_context = XUniqueContext();
}
assert( XFindContext(XtDisplay(w),
XtWindow(w),
_xfe_tt_manager_context,
(XPointer *) &manager_info) != 0);
/* Allocate the manager info */
manager_info = ManagerAllocateInfo(w);
save_result = XSaveContext(XtDisplay(w),
XtWindow(w),
_xfe_tt_manager_context,
(XPointer) manager_info);
assert( save_result == 0 );
assert( manager_info != NULL );
return manager_info;
}
/*----------------------------------------------------------------------*/
static void
ManagerRemoveInfo(Widget w,_XfeTipManagerInfo manager_info)
{
int delete_result;
assert( manager_info != NULL );
assert( _xfe_tt_manager_context != None );
delete_result = XDeleteContext(XtDisplay(w),
XtWindow(w),
_xfe_tt_manager_context);
assert( delete_result == 0 );
}
/*----------------------------------------------------------------------*/
static void
ManagerDestroyCB(Widget w,XtPointer client_data,XtPointer call_data)
{
_XfeTipManagerInfo manager_info = (_XfeTipManagerInfo) client_data;
assert( manager_info != NULL );
ManagerRemoveInfo(w,manager_info);
ManagerFreeInfo(manager_info);
}
/*----------------------------------------------------------------------*/
/*----------------------------------------------------------------------*/
/* */
/* Widget functions */
/* */
/*----------------------------------------------------------------------*/
static void
WidgetAddStageOneEH(Widget w)
{
assert( _XfeIsAlive(w) );
assert( XtIsWidget(w) );
assert( _XfeIsRealized(w) );
/* Remove the event handler so that we start with a clean item */
XtRemoveEventHandler(w,
TOOL_TIP_EVENT_MASK,
FALSE,
WidgetStageOneEH,
NULL);
/* Insert the tool tip event handler */
XtInsertEventHandler(w,
TOOL_TIP_EVENT_MASK,
FALSE,
WidgetStageOneEH,
NULL,
XtListHead);
}
/*----------------------------------------------------------------------*/
static void
WidgetRemoveStageOneEH(Widget w)
{
assert( _XfeIsAlive(w) );
assert( XtIsWidget(w) );
/* assert( _XfeIsRealized(w) ); */
/* Remove the event handler so that we start with a clean item */
XtRemoveEventHandler(w,
TOOL_TIP_EVENT_MASK,
FALSE,
WidgetStageOneEH,
NULL);
}
/*----------------------------------------------------------------------*/
static _XfeTipItemInfo
WidgetAddTipString(Widget w)
{
_XfeTipItemInfo info = NULL;
assert( _XfeIsAlive(w) );
assert( XtIsWidget(w) );
/* Try to find the info */
info = WidgetGetInfo(w);
/* If the info is not found, allocate it and add it to the item */
if (info == NULL)
{
info = ItemAllocateInfo(w);
WidgetAddInfo(w,info);
}
assert( info != NULL );
/* If the tip string info was already installed, we are done */
if (info->tip_string_installed)
{
return info;
}
/* Mark the tip string info as installed */
info->tip_string_installed = True;
/* Add the stage one event handler */
WidgetAddStageOneEH(w);
return info;
}
/*----------------------------------------------------------------------*/
static void
WidgetRemoveTipString(Widget w)
{
_XfeTipItemInfo info = NULL;
assert( _XfeIsAlive(w) );
assert( XtIsWidget(w) );
/* Add the item info the the widget */
info = WidgetGetInfo(w);
assert( info != NULL );
/* Mark the tip string info as not installed */
info->tip_string_installed = False;
/* Reset all the tip string members */
info->tip_string_enabled = False;
info->tip_string_obtain_callback = NULL;
info->tip_string_obtain_data1 = NULL;
info->tip_string_obtain_data2 = NULL;
/* If the doc string is installed, leave info and event handlers alone */
if (info->doc_string_installed)
{
return;
}
/* Remove the info from the widget */
WidgetRemoveInfo(w,info);
/* Free the info */
ItemFreeInfo(info);
/* Remove stage one event handler */
WidgetRemoveStageOneEH(w);
}
/*----------------------------------------------------------------------*/
static _XfeTipItemInfo
WidgetAddDocString(Widget w)
{
_XfeTipItemInfo info = NULL;
assert( _XfeIsAlive(w) );
assert( XtIsWidget(w) );
/* Try to find the info */
info = WidgetGetInfo(w);
/* If the info is not found, allocate it and add it to the item */
if (info == NULL)
{
info = ItemAllocateInfo(w);
WidgetAddInfo(w,info);
}
assert( info != NULL );
/* If the doc string info was already installed, we are done */
if (info->doc_string_installed)
{
return info;
}
/* Mark the doc string info as installed */
info->doc_string_installed = True;
/* Add the stage one event handler */
WidgetAddStageOneEH(w);
return info;
}
/*----------------------------------------------------------------------*/
static void
WidgetRemoveDocString(Widget w)
{
_XfeTipItemInfo info = NULL;
assert( _XfeIsAlive(w) );
assert( XtIsWidget(w) );
/* Add the item info the the widget */
info = WidgetGetInfo(w);
assert( info != NULL );
/* Mark the doc string info as not installed */
info->doc_string_installed = False;
/* Reset all the doc string members */
info->doc_string_enabled = False;
info->doc_string_obtain_callback = NULL;
info->doc_string_obtain_data1 = NULL;
info->doc_string_obtain_data2 = NULL;
info->doc_string_callback = NULL;
info->doc_string_data1 = NULL;
info->doc_string_data2 = NULL;
/* If the tip string is installed, leave info and event handlers alone */
if (info->tip_string_installed)
{
return;
}
/* Remove the info from the widget */
WidgetRemoveInfo(w,info);
/* Free the info */
ItemFreeInfo(info);
/* Remove stage one event handler */
WidgetRemoveStageOneEH(w);
}
/*----------------------------------------------------------------------*/
static _XfeTipItemInfo
WidgetGetInfo(Widget w)
{
_XfeTipItemInfo info = NULL;
assert( _XfeIsAlive(w) );
assert( _XfeIsRealized(w) );
assert( XtIsWidget(w) );
/* Make sure the item context has been allocated */
if (_xfe_tt_item_context != None)
{
int find_result = XFindContext(XtDisplay(w),
XtWindow(w),
_xfe_tt_item_context,
(XPointer *) &info);
if (find_result != 0)
{
info = NULL;
}
}
return info;
}
/*----------------------------------------------------------------------*/
static void
WidgetAddInfo(Widget w,_XfeTipItemInfo info)
{
int save_result;
assert( _XfeIsAlive(w) );
assert( _XfeIsRealized(w) );
assert( XtIsWidget(w) );
assert( info != NULL );
/* Allocate the unique context only once */
if (_xfe_tt_item_context == None)
{
_xfe_tt_item_context = XUniqueContext();
}
/* Make sure the info is not already installed */
assert( XFindContext(XtDisplay(w),
XtWindow(w),
_xfe_tt_item_context,
(XPointer *) &info) != 0);
save_result = XSaveContext(XtDisplay(w),
XtWindow(w),
_xfe_tt_item_context,
(XPointer) info);
assert( save_result == 0 );
}
/*----------------------------------------------------------------------*/
static void
WidgetRemoveInfo(Widget w,_XfeTipItemInfo info)
{
int delete_result;
assert( info != NULL );
assert( _xfe_tt_item_context != None );
delete_result = XDeleteContext(XtDisplay(w),
XtWindow(w),
_xfe_tt_item_context);
assert( delete_result == 0 );
}
/*----------------------------------------------------------------------*/
/*----------------------------------------------------------------------*/
/* */
/* Gadget functions */
/* */
/*----------------------------------------------------------------------*/
static _XfeTipItemInfo
GadgetAddTipString(Widget w)
{
Widget pw = NULL;
_XfeTipManagerInfo manager_info = NULL;
_XfeTipItemInfo info = NULL;
assert( _XfeIsAlive(w) );
assert( XmIsGadget(w) );
pw = XtParent(w);
/* Look for the manager info */
manager_info = ManagerGetInfo(pw);
/* Add the manager info if needed */
if (manager_info == NULL)
{
manager_info = ManagerAddInfo(pw);
}
assert( manager_info != NULL );
/* Try to find the info */
info = GadgetGetInfo(w);
/* If the info is not found, allocate it and add it to the item */
if (info == NULL)
{
info = ItemAllocateInfo(w);
GadgetAddInfo(w,manager_info,info);
}
assert( info != NULL );
/* If the tip string info was already installed, we are done */
if (info->tip_string_installed)
{
return info;
}
/* Mark the tip string info as installed */
info->tip_string_installed = True;
GadgetSaveRealInputDispatchMethod(w);
GadgetHackInputDispatch(w);
return info;
}
/*----------------------------------------------------------------------*/
static void
GadgetRemoveTipString(Widget w)
{
Widget pw = NULL;
_XfeTipManagerInfo manager_info = NULL;
_XfeTipItemInfo info = NULL;
XfeLinkNode node;
assert( XmIsGadget(w) );
pw = XtParent(w);
/* Look for the manager info */
manager_info = ManagerGetInfo(pw);
assert( manager_info != NULL );
node = XfeLinkedFind(manager_info->children_list,
ChildrenListTestFunc,
(XtPointer) w);
assert( node != NULL );
info = (_XfeTipItemInfo) XfeLinkNodeItem(node);
assert( info != NULL );
/* Mark the tip string info as not installed */
info->tip_string_installed = False;
/* Reset all the tip string members */
info->tip_string_enabled = False;
info->tip_string_obtain_callback = NULL;
info->tip_string_obtain_data1 = NULL;
info->tip_string_obtain_data2 = NULL;
/* If the doc string is installed, leave info and event handlers alone */
if (info->doc_string_installed)
{
return;
}
/* Remove the item info from the list */
info = (_XfeTipItemInfo)
XfeLinkedRemoveNode(manager_info->children_list,node);
assert( info != NULL );
/* Free the item info */
ItemFreeInfo(info);
}
/*----------------------------------------------------------------------*/
static _XfeTipItemInfo
GadgetAddDocString(Widget w)
{
Widget pw = NULL;
_XfeTipManagerInfo manager_info = NULL;
_XfeTipItemInfo info = NULL;
assert( _XfeIsAlive(w) );
assert( XmIsGadget(w) );
pw = XtParent(w);
/* Look for the manager info */
manager_info = ManagerGetInfo(pw);
/* Add the manager info if needed */
if (manager_info == NULL)
{
manager_info = ManagerAddInfo(pw);
}
assert( manager_info != NULL );
/* Try to find the info */
info = GadgetGetInfo(w);
/* If the info is not found, allocate it and add it to the item */
if (info == NULL)
{
info = ItemAllocateInfo(w);
GadgetAddInfo(w,manager_info,info);
}
assert( info != NULL );
/* If the doc string info was already installed, we are done */
if (info->doc_string_installed)
{
return info;
}
/* Mark the doc string info as installed */
info->doc_string_installed = True;
GadgetSaveRealInputDispatchMethod(w);
GadgetHackInputDispatch(w);
return info;
}
/*----------------------------------------------------------------------*/
static void
GadgetRemoveDocString(Widget w)
{
Widget pw = NULL;
_XfeTipManagerInfo manager_info = NULL;
_XfeTipItemInfo info = NULL;
XfeLinkNode node;
assert( XmIsGadget(w) );
pw = XtParent(w);
/* Look for the manager info */
manager_info = ManagerGetInfo(pw);
assert( manager_info != NULL );
node = XfeLinkedFind(manager_info->children_list,
ChildrenListTestFunc,
(XtPointer) w);
assert( node != NULL );
info = (_XfeTipItemInfo) XfeLinkNodeItem(node);
assert( info != NULL );
/* Mark the doc string info as not installed */
info->doc_string_installed = False;
/* Reset all the doc string members */
info->doc_string_enabled = False;
info->doc_string_obtain_callback = NULL;
info->doc_string_obtain_data1 = NULL;
info->doc_string_obtain_data2 = NULL;
info->doc_string_callback = NULL;
info->doc_string_data1 = NULL;
info->doc_string_data2 = NULL;
/* If the doc string is installed, leave info and event handlers alone */
if (info->doc_string_installed)
{
return;
}
/* Remove the item info from the list */
info = (_XfeTipItemInfo)
XfeLinkedRemoveNode(manager_info->children_list,node);
assert( info != NULL );
/* Free the item info */
ItemFreeInfo(info);
}
/*----------------------------------------------------------------------*/
static _XfeTipItemInfo
GadgetGetInfo(Widget w)
{
_XfeTipItemInfo info = NULL;
Widget pw = NULL;
_XfeTipManagerInfo manager_info = NULL;
assert( XmIsGadget(w) );
pw = XtParent(w);
/* Look for the manager info */
manager_info = ManagerGetInfo(pw);
if (manager_info != NULL)
{
XfeLinkNode node = XfeLinkedFind(manager_info->children_list,
ChildrenListTestFunc,
(XtPointer) w);
if (node != NULL)
{
info = (_XfeTipItemInfo) XfeLinkNodeItem(node);
}
}
return info;
}
/*----------------------------------------------------------------------*/
static void
GadgetAddInfo(Widget w,_XfeTipManagerInfo manager_info,_XfeTipItemInfo info)
{
assert( _XfeIsAlive(w) );
assert( XmIsGadget(w) );
assert( manager_info != NULL );
assert( info != NULL );
/* Make sure the item is not already on the list */
assert( XfeLinkedFind(manager_info->children_list,
ChildrenListTestFunc,
(XtPointer) w) == NULL);
/* Add this gadget to the tool tip children list */
XfeLinkedInsertAtTail(manager_info->children_list,info);
}
/*----------------------------------------------------------------------*/
/*----------------------------------------------------------------------*/
/* */
/* Item (Widget or Gadget) functions */
/* */
/*----------------------------------------------------------------------*/
static void
ItemDestroyCB(Widget w,XtPointer client_data,XtPointer call_data)
{
/* _XfeTipItemInfo info = (_XfeTipItemInfo) client_data; */
if (XmIsGadget(w))
{
GadgetRemoveTipString(w);
GadgetRemoveDocString(w);
}
else
{
WidgetRemoveTipString(w);
WidgetRemoveDocString(w);
}
}
/*----------------------------------------------------------------------*/
static _XfeTipItemInfo
ItemAllocateInfo(Widget w)
{
_XfeTipItemInfo info = NULL;
assert( _XfeIsAlive(w) );
assert( _XfeIsRealized(w) );
info = (_XfeTipItemInfo) XtMalloc(sizeof(_XfeTipItemInfoRec) * 1);
/* Initialize the members */
info->item = w;
info->tip_string_installed = False;
info->doc_string_installed = False;
/* TipString */
info->tip_string_enabled = False;
info->tip_string_obtain_callback = NULL;
info->tip_string_obtain_data1 = NULL;
info->tip_string_obtain_data2 = NULL;
/* DocString */
info->doc_string_enabled = False;
info->doc_string_obtain_callback = NULL;
info->doc_string_obtain_data1 = NULL;
info->doc_string_obtain_data2 = NULL;
info->doc_string_callback = NULL;
/* DocString callback */
info->doc_string_callback = NULL;
info->doc_string_data1 = NULL;
info->doc_string_data2 = NULL;
/* Garbage collection */
XtAddCallback(w,XmNdestroyCallback,ItemDestroyCB,(XtPointer) info);
return info;
}
/*----------------------------------------------------------------------*/
static void
ItemFreeInfo(_XfeTipItemInfo info)
{
assert( info != NULL );
XtFree((char *) info);
}
/*----------------------------------------------------------------------*/
static _XfeTipItemInfo
ItemGetInfo(Widget w)
{
_XfeTipItemInfo info = NULL;
assert( _XfeIsAlive(w) );
if (XmIsGadget(w))
{
info = GadgetGetInfo(w);
}
else
{
info = WidgetGetInfo(w);
}
return info;
}
/*----------------------------------------------------------------------*/
static void
ItemGetTipString(Widget w,XmString * xmstr_out,Boolean * need_to_free_out)
{
_XfeTipItemInfo info;
assert( xmstr_out != NULL );
assert( need_to_free_out != NULL );
*xmstr_out = NULL;
*need_to_free_out = False;
assert( _XfeIsAlive(w) );
info = ItemGetInfo(w);
assert( info != NULL );
/* Invoke the tip string obtain callback if present */
if (info->tip_string_obtain_callback != NULL)
{
(*info->tip_string_obtain_callback)(w,
info->tip_string_obtain_data1,
info->tip_string_obtain_data2,
xmstr_out,
need_to_free_out);
}
/* Check resources directly */
else
{
*xmstr_out = XfeSubResourceGetWidgetXmStringValue(w,
XmNtipString,
XmCTipString);
/*
* No need to free this string. The Xt resource destructor
* should take care of freeing this memory.
*/
*need_to_free_out = False;
}
}
/*----------------------------------------------------------------------*/
static void
ItemGetDocString(Widget w,XmString * xmstr_out,Boolean * need_to_free_out)
{
_XfeTipItemInfo info;
assert( xmstr_out != NULL );
assert( need_to_free_out != NULL );
*xmstr_out = NULL;
*need_to_free_out = False;
assert( _XfeIsAlive(w) );
info = ItemGetInfo(w);
assert( info != NULL );
/* Invoke the doc string obtain callback if present */
if (info->doc_string_obtain_callback != NULL)
{
(*info->doc_string_obtain_callback)(w,
info->doc_string_obtain_data1,
info->doc_string_obtain_data2,
xmstr_out,
need_to_free_out);
}
/* Check resources directly */
else
{
*xmstr_out =
XfeSubResourceGetWidgetXmStringValue(w,
XmNdocumentationString,
XmCDocumentationString);
/*
* No need to free this string. The Xt resource destructor
* should take care of freeing this memory.
*/
*need_to_free_out = False;
}
}
/*----------------------------------------------------------------------*/
/*----------------------------------------------------------------------*/
/* */
/* TipString enter / leave / cancel functions */
/* */
/*----------------------------------------------------------------------*/
static Widget _xfe_tt_stage_one_target = NULL;
static Widget _xfe_tt_stage_two_target = NULL;
static XtIntervalId _xfe_tt_timer_id = 0;
static void
TipStringEnterItem(Widget w,_XfeTipItemInfo info)
{
assert( _XfeIsAlive(w) );
if (_XfeToolTipIsLocked())
{
#ifdef DEBUG_TOOL_TIPS
printf("TipStringEnterItem(%s): tool tips are locked - abort\n",
XtName(w));
#endif
}
_XfeToolTipLock();
_xfe_tt_stage_one_target = w;
StageTwoAddTimeout(w);
#ifdef DEBUG_TOOL_TIPS
printf("TipStringEnterItem(%s)\n",XtName(w));
#endif
}
/*----------------------------------------------------------------------*/
static void
TipStringLeaveItem(Widget w,_XfeTipItemInfo info)
{
assert( _XfeIsAlive(w) );
/* Check for stage one */
/* If a target exists, reset it so that stage two aborts */
if (_XfeIsAlive(_xfe_tt_stage_one_target))
{
_xfe_tt_stage_one_target = NULL;
}
/* Remove the timeout if its still active */
StageTwoRemoveTimeout(w);
/* Check for stage two */
if (_XfeIsAlive(_xfe_tt_stage_two_target))
{
/* Set the stage two target */
_xfe_tt_stage_two_target = NULL;
ItemUnPostToolTip(w);
}
_XfeToolTipUnlock();
#ifdef DEBUG_TOOL_TIPS
printf("TipStringLeaveItem(%s)\n",XtName(w));
#endif
}
/*----------------------------------------------------------------------*/
static void
TipStringCancelItem(Widget w,_XfeTipItemInfo info)
{
#ifdef DEBUG_TOOL_TIPS
printf("TipStringCancelItem(%s)\n",XtName(w));
#endif
TipStringLeaveItem(w,info);
}
/*----------------------------------------------------------------------*/
/*----------------------------------------------------------------------*/
/* */
/* DocString enter / leave / cancel functions */
/* */
/*----------------------------------------------------------------------*/
static void
DocStringEnterItem(Widget w,_XfeTipItemInfo info)
{
XmString xmstr = NULL;
Boolean need_to_free = False;
assert( _XfeIsAlive(w) );
assert( info != NULL );
ItemGetDocString(w,&xmstr,&need_to_free);
#if DEBUG
if (xmstr == NULL)
{
xmstr = XmStringCreateLocalized("No doc string found. You Suck!");
need_to_free = True;
}
#endif
/* Invoke the doc string SET callback if present */
if (info->doc_string_callback != NULL)
{
(*info->doc_string_callback)(w,
info->doc_string_data1,
info->doc_string_data2,
XfeDOC_STRING_SET,
xmstr);
}
#ifdef DEBUG
else
{
printf("Widget '%s' has doc string support, but no callback\n",
XtName(w));
}
#endif
/* Free the string if needed */
if (need_to_free)
{
XmStringFree(xmstr);
}
#ifdef DEBUG_TOOL_TIPS
printf("DocStringEnterItem(%s)\n",XtName(w));
#endif
}
/*----------------------------------------------------------------------*/
static void
DocStringLeaveItem(Widget w,_XfeTipItemInfo info)
{
assert( _XfeIsAlive(w) );
assert( info != NULL );
/* Invoke the doc string CLEAR callback if present */
if (info->doc_string_callback != NULL)
{
(*info->doc_string_callback)(w,
info->doc_string_data1,
info->doc_string_data2,
XfeDOC_STRING_CLEAR,
NULL);
}
#ifdef DEBUG_TOOL_TIPS
printf("DocStringLeaveItem(%s)\n",XtName(w));
#endif
}
/*----------------------------------------------------------------------*/
/*----------------------------------------------------------------------*/
/* */
/* Item Post / UnPost ToolTip functions */
/* */
/*----------------------------------------------------------------------*/
static Boolean _xfe_tt_posted = False;
static void
ItemPostToolTip(Widget w)
{
Widget shell = NULL;
Widget label = NULL;
XmString xmstr = NULL;
Boolean need_to_free = False;
assert( _XfeIsAlive(w) );
shell =_XfeToolTipGetShell(w);
assert( _XfeIsAlive(shell) );
label = _XfeToolTipGetLabel(w);
assert( _XfeIsAlive(label) );
ItemGetTipString(w,&xmstr,&need_to_free);
#if DEBUG
if (xmstr == NULL)
{
xmstr = XmStringCreateLocalized("No tip string found. You Suck!");
need_to_free = True;
}
#endif
if (xmstr != NULL)
{
XfeLabelSetString(label,xmstr);
/* Free the string if needed */
if (need_to_free)
{
XmStringFree(xmstr);
}
XfeBypassShellUpdateSize(shell);
_xfe_tt_posted = True;
XtPopup(shell,XtGrabNone);
}
#ifdef DEBUG_TOOL_TIPS
printf("ItemPostToolTip(%s)\n",XtName(w));
#endif
}
/*----------------------------------------------------------------------*/
static void
ItemUnPostToolTip(Widget w)
{
if (_xfe_tt_posted)
{
Widget shell = _XfeToolTipGetShell(w);
_xfe_tt_posted = True;
if (_XfeIsAlive(shell))
{
XtPopdown(shell);
}
}
#ifdef DEBUG_TOOL_TIPS
printf("ItemUnPostToolTip(%s)\n",XtName(w));
#endif
}
/*----------------------------------------------------------------------*/
/*----------------------------------------------------------------------*/
/* */
/* Manager XfeLinked children list functions */
/* */
/*----------------------------------------------------------------------*/
static void
ChildrenListDestroyProc(XtPointer item,XtPointer client_data)
{
_XfeTipItemInfo info = (_XfeTipItemInfo) item;
assert( info != NULL );
ItemFreeInfo(info);
}
/*----------------------------------------------------------------------*/
static Boolean
ChildrenListTestFunc(XtPointer item,XtPointer client_data)
{
_XfeTipItemInfo info = (_XfeTipItemInfo) item;
Widget w = (Widget) client_data;
assert( info != NULL );
return (info->item == w);
}
/*----------------------------------------------------------------------*/
/*----------------------------------------------------------------------*/
/* */
/* State Two timeout functions */
/* */
/*----------------------------------------------------------------------*/
static void
StageTwoTimeout(XtPointer closure,XtIntervalId * id)
{
Widget w = (Widget) closure;
/*
* Always clear timer_id, so we don't kill someone else's timer
* by accident later.
*/
_xfe_tt_timer_id = 0;
/*
* Post the tooltip if a target is still alive.
*
* A dead or missing target means the tooltip operation was aborted.
* The user could have boinked or left the target.
*/
if (_XfeIsAlive(_xfe_tt_stage_one_target))
{
assert( w == _xfe_tt_stage_one_target);
/* Reset the stage one target */
_xfe_tt_stage_one_target = NULL;
/* Set the stage two target */
_xfe_tt_stage_two_target = w;
ItemPostToolTip(w);
}
}
/*----------------------------------------------------------------------*/
static void
StageTwoAddTimeout(Widget w)
{
assert( _XfeIsAlive(w) );
_xfe_tt_timer_id = XtAppAddTimeOut(XtWidgetToApplicationContext(w),
TOOL_TIP_INTERVAL,
StageTwoTimeout,
(XtPointer) w);
}
/*----------------------------------------------------------------------*/
static void
StageTwoRemoveTimeout(Widget w)
{
if (_xfe_tt_timer_id != 0)
{
XtRemoveTimeOut(_xfe_tt_timer_id);
_xfe_tt_timer_id = 0;
}
}
/*----------------------------------------------------------------------*/
/*----------------------------------------------------------------------*/
/* */
/* Event handlers */
/* */
/*----------------------------------------------------------------------*/
static void
WidgetStageOneEH(Widget w,
XtPointer client_data,
XEvent * event,
Boolean * cont)
{
/* Do the tip magic only if tip or doc strings are globally enabled */
if (XfeTipStringGlobalGetEnabledState() ||
XfeDocStringGlobalGetEnabledState())
{
_XfeTipItemInfo info = WidgetGetInfo(w);
assert( info != NULL );
if (info != NULL)
{
Boolean do_tip_string =
XfeTipStringGlobalGetEnabledState() &&
info->tip_string_enabled;
Boolean do_doc_string =
XfeDocStringGlobalGetEnabledState() &&
info->doc_string_enabled;
/* Enter */
if (event->type == EnterNotify)
{
if (do_tip_string)
{
TipStringEnterItem(w,info);
}
if (do_doc_string)
{
DocStringEnterItem(w,info);
}
}
/* Leave */
else if (event->type == LeaveNotify)
{
if (do_tip_string)
{
TipStringLeaveItem(w,info);
}
if (do_doc_string)
{
DocStringLeaveItem(w,info);
}
}
/* Cancel */
else
{
if (do_tip_string)
{
TipStringCancelItem(w,info);
}
}
} /* info != NULL */
}
*cont = True;
}
/*----------------------------------------------------------------------*/
/*----------------------------------------------------------------------*/
/* */
/* XfeToolTip Private Methods */
/* */
/*----------------------------------------------------------------------*/
/*----------------------------------------------------------------------*/
/* */
/* Tool tip shell access */
/* */
/*----------------------------------------------------------------------*/
static Widget _xfe_tt_shell = NULL;
/* extern */ Widget
_XfeToolTipGetShell(Widget w)
{
/* Create to global tool tip shell if needed */
if (!_xfe_tt_shell)
{
Widget aw = XfeAncestorFindApplicationShell(w);
assert( _XfeIsAlive(aw) );
_xfe_tt_shell = XfeCreateToolTipShell(aw,
TOOL_TIP_SHELL_NAME,
NULL,
0);
}
return _xfe_tt_shell;
}
/*----------------------------------------------------------------------*/
/* extern */ Widget
_XfeToolTipGetLabel(Widget w)
{
Widget shell = _XfeToolTipGetShell(w);
assert( _XfeIsAlive(shell) );
assert( _XfeIsAlive(XfeToolTipShellGetLabel(shell)) );
return XfeToolTipShellGetLabel(shell);
}
/*----------------------------------------------------------------------*/
/*----------------------------------------------------------------------*/
/* */
/* Lock / Unlock functions */
/* */
/*----------------------------------------------------------------------*/
static Boolean _xfe_tt_locked = False;
/* extern */ void
_XfeToolTipLock(void)
{
_xfe_tt_locked = True;
}
/*----------------------------------------------------------------------*/
/* extern */ void
_XfeToolTipUnlock(void)
{
_xfe_tt_locked = False;
}
/*----------------------------------------------------------------------*/
/* extern */ Boolean
_XfeToolTipIsLocked(void)
{
return _xfe_tt_locked;
}
/*----------------------------------------------------------------------*/
/*----------------------------------------------------------------------*/
/* */
/* TipString public methods */
/* */
/*----------------------------------------------------------------------*/
/* extern */ void
XfeTipStringAdd(Widget w)
{
_XfeTipItemInfo info = NULL;
assert( _XfeIsAlive(w) );
#ifdef DEBUG_TOOL_TIPS
printf("XfeTipStringAdd(%s)\n",XtName(w));
#endif
if (XmIsGadget(w))
{
info = GadgetAddTipString(w);
}
else
{
info = WidgetAddTipString(w);
}
assert( info != NULL );
/* Enable the tip string by default */
info->tip_string_enabled = True;
}
/*----------------------------------------------------------------------*/
/* extern */ void
XfeTipStringRemove(Widget w)
{
assert( _XfeIsAlive(w) );
#ifdef DEBUG_TOOL_TIPS
printf("XfeTipStringRemove(%s)\n",XtName(w));
#endif
if (XmIsGadget(w))
{
GadgetRemoveTipString(w);
}
else
{
WidgetRemoveTipString(w);
}
}
/*----------------------------------------------------------------------*/
/* extern */ void
XfeTipStringSetEnabledState(Widget w,Boolean state)
{
_XfeTipItemInfo info;
assert( _XfeIsAlive(w) );
info = ItemGetInfo(w);
assert( info != NULL );
if (info != NULL)
{
info->tip_string_enabled = state;
}
}
/*----------------------------------------------------------------------*/
/* extern */ Boolean
XfeTipStringGetEnabledState(Widget w)
{
_XfeTipItemInfo info;
assert( _XfeIsAlive(w) );
info = ItemGetInfo(w);
assert( info != NULL );
if (info != NULL)
{
return info->tip_string_enabled;
}
return False;
}
/*----------------------------------------------------------------------*/
/*----------------------------------------------------------------------*/
/* */
/* TipString callback functions */
/* */
/*----------------------------------------------------------------------*/
/* extern */ void
XfeTipStringSetObtainCallback(Widget w,
XfeTipStringObtainCallback callback,
XtPointer client_data1,
XtPointer client_data2)
{
_XfeTipItemInfo info;
assert( _XfeIsAlive(w) );
info = ItemGetInfo(w);
assert( info != NULL );
if (info != NULL)
{
info->tip_string_obtain_callback = callback;
info->tip_string_obtain_data1 = client_data1;
info->tip_string_obtain_data2 = client_data2;
}
}
/*----------------------------------------------------------------------*/
/* extern */ void
XfeTipStringClearObtainCallback(Widget w)
{
XfeTipStringSetObtainCallback(w,NULL,NULL,NULL);
}
/*----------------------------------------------------------------------*/
/*----------------------------------------------------------------------*/
/* */
/* TipString global enabled / disable functions */
/* */
/*----------------------------------------------------------------------*/
static Boolean _xfe_tip_string_global_enabled = False;
/* extern */ void
XfeTipStringGlobalSetEnabledState(Boolean state)
{
_xfe_tip_string_global_enabled = state;
}
/*----------------------------------------------------------------------*/
/* extern */ Boolean
XfeTipStringGlobalGetEnabledState(void)
{
return _xfe_tip_string_global_enabled;
}
/*----------------------------------------------------------------------*/
/*----------------------------------------------------------------------*/
/* */
/* Check whether the global tooltip is showing */
/* */
/*----------------------------------------------------------------------*/
extern Boolean
XfeTipStringIsShowing(void)
{
/* writeme */
assert( 0 );
return False;
}
/*----------------------------------------------------------------------*/
/*----------------------------------------------------------------------*/
/* */
/* DocString public methods */
/* */
/*----------------------------------------------------------------------*/
/* extern */ void
XfeDocStringAdd(Widget w)
{
_XfeTipItemInfo info = NULL;
assert( _XfeIsAlive(w) );
#ifdef DEBUG_TOOL_TIPS
printf("XfeDocStringAdd(%s)\n",XtName(w));
#endif
if (XmIsGadget(w))
{
info = GadgetAddDocString(w);
}
else
{
info = WidgetAddDocString(w);
}
assert( info != NULL );
/* Enable the doc string by default */
info->doc_string_enabled = True;
}
/*----------------------------------------------------------------------*/
/* extern */ void
XfeDocStringRemove(Widget w)
{
assert( _XfeIsAlive(w) );
#ifdef DEBUG_TOOL_TIPS
printf("XfeDocStringRemove(%s)\n",XtName(w));
#endif
if (XmIsGadget(w))
{
GadgetRemoveDocString(w);
}
else
{
WidgetRemoveDocString(w);
}
}
/*----------------------------------------------------------------------*/
/* extern */ void
XfeDocStringSetEnabledState(Widget w,Boolean state)
{
_XfeTipItemInfo info;
assert( _XfeIsAlive(w) );
info = ItemGetInfo(w);
assert( info != NULL );
if (info != NULL)
{
info->doc_string_enabled = state;
}
}
/*----------------------------------------------------------------------*/
/* extern */ Boolean
XfeDocStringGetEnabledState(Widget w)
{
_XfeTipItemInfo info;
assert( _XfeIsAlive(w) );
info = ItemGetInfo(w);
assert( info != NULL );
if (info != NULL)
{
return info->doc_string_enabled;
}
return False;
}
/*----------------------------------------------------------------------*/
/*----------------------------------------------------------------------*/
/* */
/* DocString callback functions */
/* */
/*----------------------------------------------------------------------*/
/* extern */ void
XfeDocStringSetObtainCallback(Widget w,
XfeTipStringObtainCallback callback,
XtPointer client_data1,
XtPointer client_data2)
{
_XfeTipItemInfo info;
assert( _XfeIsAlive(w) );
info = ItemGetInfo(w);
assert( info != NULL );
if (info != NULL)
{
info->doc_string_obtain_callback = callback;
info->doc_string_obtain_data1 = client_data1;
info->doc_string_obtain_data2 = client_data2;
}
}
/*----------------------------------------------------------------------*/
/* extern */ void
XfeDocStringClearObtainCallback(Widget w)
{
XfeDocStringSetObtainCallback(w,NULL,NULL,NULL);
}
/*----------------------------------------------------------------------*/
/* extern */ void
XfeDocStringSetCallback(Widget w,
XfeDocStringCallback callback,
XtPointer client_data1,
XtPointer client_data2)
{
_XfeTipItemInfo info;
assert( _XfeIsAlive(w) );
info = ItemGetInfo(w);
assert( info != NULL );
if (info != NULL)
{
info->doc_string_callback = callback;
info->doc_string_data1 = client_data1;
info->doc_string_data2 = client_data2;
}
}
/*----------------------------------------------------------------------*/
/* extern */ void
XfeDocStringClearCallback(Widget w)
{
XfeDocStringSetCallback(w,NULL,NULL,NULL);
}
/*----------------------------------------------------------------------*/
/*----------------------------------------------------------------------*/
/* */
/* DocString global enabled / disable functions */
/* */
/*----------------------------------------------------------------------*/
static Boolean _xfe_doc_string_global_enabled = False;
/* extern */ void
XfeDocStringGlobalSetEnabledState(Boolean state)
{
_xfe_doc_string_global_enabled = state;
}
/*----------------------------------------------------------------------*/
/* extern */ Boolean
XfeDocStringGlobalGetEnabledState(void)
{
return _xfe_doc_string_global_enabled;
}
/*----------------------------------------------------------------------*/