Blame lib/Xm/ToolTip.c

Packit b099d7
/* 
Packit b099d7
 * Motif
Packit b099d7
 *
Packit b099d7
 * Copyright (c) 1987-2012, The Open Group. All rights reserved.
Packit b099d7
 *
Packit b099d7
 * These libraries and programs are free software; you can
Packit b099d7
 * redistribute them and/or modify them under the terms of the GNU
Packit b099d7
 * Lesser General Public License as published by the Free Software
Packit b099d7
 * Foundation; either version 2 of the License, or (at your option)
Packit b099d7
 * any later version.
Packit b099d7
 *
Packit b099d7
 * These libraries and programs are distributed in the hope that
Packit b099d7
 * they will be useful, but WITHOUT ANY WARRANTY; without even the
Packit b099d7
 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
Packit b099d7
 * PURPOSE. See the GNU Lesser General Public License for more
Packit b099d7
 * details.
Packit b099d7
 *
Packit b099d7
 * You should have received a copy of the GNU Lesser General Public
Packit b099d7
 * License along with these librararies and programs; if not, write
Packit b099d7
 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
Packit b099d7
 * Floor, Boston, MA 02110-1301 USA
Packit b099d7
*/
Packit b099d7
Packit b099d7
#ifdef HAVE_CONFIG_H
Packit b099d7
#include <config.h>
Packit b099d7
#endif
Packit b099d7
Packit b099d7
#include <Xm/LabelP.h>
Packit b099d7
#include <Xm/VendorSEP.h>
Packit b099d7
#include <Xm/GadgetP.h>
Packit b099d7
#include <Xm/SlideC.h>
Packit b099d7
#include <Xm/TraitP.h>
Packit b099d7
#include <Xm/ToolTipCT.h>
Packit b099d7
#include <Xm/ToolTipT.h>
Packit b099d7
#include "BaseClassI.h"
Packit b099d7
#include "ToolTipI.h"
Packit b099d7
#include "XmI.h"
Packit b099d7
Packit b099d7
#ifdef FIX_1388
Packit b099d7
static void ToolTipLabelDestroyCallback(Widget w, XtPointer client_data, XtPointer call_data)
Packit b099d7
{
Packit b099d7
    XmToolTipConfigTrait ttcp;
Packit b099d7
    
Packit b099d7
    ttcp = (XmToolTipConfigTrait) XmeTraitGet(w, XmQTtoolTipConfig);
Packit b099d7
    
Packit b099d7
    if (ttcp != NULL)
Packit b099d7
	if (ttcp->label != NULL) {
Packit b099d7
	    Widget shell = XtParent(ttcp->label);
Packit b099d7
	    XtDestroyWidget(ttcp->label);
Packit b099d7
	    ttcp->label = NULL;
Packit b099d7
	    XtDestroyWidget(shell);
Packit b099d7
	}
Packit b099d7
}
Packit b099d7
#endif /* FIX_1388 */
Packit b099d7
Packit b099d7
static XmToolTipConfigTrait
Packit b099d7
ToolTipGetData (Widget w)
Packit b099d7
{
Packit b099d7
   Widget top = w;
Packit b099d7
   XmToolTipConfigTrait ttp;
Packit b099d7
Packit b099d7
   while (XtParent (top))
Packit b099d7
   {
Packit b099d7
      top = XtParent (top);
Packit b099d7
   }
Packit b099d7
Packit b099d7
   ttp = (XmToolTipConfigTrait) XmeTraitGet (top, XmQTtoolTipConfig);
Packit b099d7
Packit b099d7
   if (ttp != NULL && ttp->label == NULL && !top->core.being_destroyed)
Packit b099d7
   {
Packit b099d7
      Widget shell;
Packit b099d7
Packit b099d7
      shell = XtVaCreateWidget ("TipShell",
Packit b099d7
                                transientShellWidgetClass, top,
Packit b099d7
                                XmNoverrideRedirect, True, NULL);
Packit b099d7
Packit b099d7
      ttp->label = XmCreateLabel (shell, "TipLabel", NULL, 0);
Packit b099d7
      XtManageChild (ttp->label);
Packit b099d7
#ifdef FIX_1388
Packit b099d7
      XtAddCallback(top, XmNdestroyCallback, (XtCallbackProc) ToolTipLabelDestroyCallback, (XtPointer) NULL);
Packit b099d7
#endif
Packit b099d7
   }
Packit b099d7
   return ttp;
Packit b099d7
}
Packit b099d7
Packit b099d7
static void
Packit b099d7
ToolTipUnpost (XtPointer client_data,
Packit b099d7
               XtIntervalId * id)
Packit b099d7
{
Packit b099d7
   XmToolTipConfigTrait ttp;
Packit b099d7
Packit b099d7
   ttp = (XmToolTipConfigTrait) client_data;
Packit b099d7
Packit b099d7
   if (ttp->duration_timer)
Packit b099d7
   {
Packit b099d7
      if (!id || (id && (*id != ttp->duration_timer)))
Packit b099d7
      {
Packit b099d7
         XtRemoveTimeOut (ttp->duration_timer);
Packit b099d7
      }
Packit b099d7
      ttp->duration_timer = (XtIntervalId) NULL;
Packit b099d7
   }
Packit b099d7
   if (ttp->slider)
Packit b099d7
   {
Packit b099d7
      XtDestroyWidget (ttp->slider);
Packit b099d7
      ttp->slider = NULL;
Packit b099d7
   }
Packit b099d7
Packit b099d7
   if (ttp->label != NULL && !XtParent (ttp->label)->core.being_destroyed)
Packit b099d7
   {
Packit b099d7
      XtPopdown (XtParent (ttp->label));
Packit b099d7
   }
Packit b099d7
Packit b099d7
}
Packit b099d7
Packit b099d7
static void
Packit b099d7
ToolTipPostFinish (Widget slide,
Packit b099d7
                   XtPointer client_data,
Packit b099d7
                   XtPointer call_data)
Packit b099d7
{
Packit b099d7
   XmToolTipConfigTrait ttp;
Packit b099d7
Packit b099d7
   ttp = (XmToolTipConfigTrait) client_data;
Packit b099d7
Packit b099d7
   if (ttp == NULL)
Packit b099d7
   {
Packit b099d7
      XtWarning ("ToolTipPostFinish() - ttp==NULL");
Packit b099d7
      return;
Packit b099d7
   }
Packit b099d7
Packit b099d7
   ttp->slider = NULL;
Packit b099d7
   if (ttp->post_duration > 0)
Packit b099d7
   {
Packit b099d7
      ttp->duration_timer =
Packit b099d7
         XtAppAddTimeOut (XtWidgetToApplicationContext (ttp->label),
Packit b099d7
                          (unsigned long) ttp->post_duration,
Packit b099d7
                          (XtTimerCallbackProc) ToolTipUnpost, client_data);
Packit b099d7
   }
Packit b099d7
}
Packit b099d7
Packit b099d7
static void
Packit b099d7
ToolTipPost (XtPointer client_data,
Packit b099d7
             XtIntervalId * id)
Packit b099d7
{
Packit b099d7
   Widget w = (Widget) client_data;
Packit b099d7
Packit b099d7
   int rx,
Packit b099d7
     ry,
Packit b099d7
     x,
Packit b099d7
     y;
Packit b099d7
   unsigned int key;
Packit b099d7
   Window root,
Packit b099d7
     child;
Packit b099d7
   XtWidgetGeometry geo;
Packit b099d7
   Position destX,
Packit b099d7
     destY;
Packit b099d7
Packit b099d7
   XmToolTipConfigTrait ttp; /* ToolTip pointer */
Packit b099d7
Packit b099d7
   ttp = ToolTipGetData (w);
Packit b099d7
Packit b099d7
   if (ttp == NULL)
Packit b099d7
   {
Packit b099d7
      XtWarning ("ToolTipGetData() returned NULL in ToolTipPost()");
Packit b099d7
      return;
Packit b099d7
   }
Packit b099d7
Packit b099d7
   ttp->timer = (XtIntervalId) NULL;
Packit b099d7
Packit b099d7
   XQueryPointer (XtDisplay (w),
Packit b099d7
                  XtWindow (w), &root, &child, &rx, &ry, &x, &y, &key);
Packit b099d7
Packit b099d7
   if (ttp->duration_timer != (XtIntervalId) NULL)
Packit b099d7
   {
Packit b099d7
      XtRemoveTimeOut (ttp->duration_timer);
Packit b099d7
      ttp->duration_timer = (XtIntervalId) NULL;
Packit b099d7
   }
Packit b099d7
Packit b099d7
   if (XmIsPrimitive(w) || XmIsGadget(w))
Packit b099d7
   {
Packit b099d7
      XtVaSetValues (ttp->label,
Packit b099d7
                     XmNlabelString,
Packit b099d7
                     XmGetToolTipString(w),
Packit b099d7
                     NULL);
Packit b099d7
   }
Packit b099d7
   else
Packit b099d7
   {
Packit b099d7
      XmString string;
Packit b099d7
Packit b099d7
      string = XmStringCreateLocalized (XtName (w));
Packit b099d7
      XtVaSetValues (ttp->label, XmNlabelString, string, NULL);
Packit b099d7
      XmStringFree (string);
Packit b099d7
   }
Packit b099d7
   XtQueryGeometry (ttp->label, NULL, &geo;;
Packit b099d7
Packit b099d7
   /* rws 25 Feb 2001
Packit b099d7
      Fix for Bug #1153
Packit b099d7
      Don't let the tip be off the right/bottom of the screen
Packit b099d7
    */
Packit b099d7
   destX = rx + (XmIsGadget (w) ? XtX (w) : 0) - x + XtWidth (w) / 2;
Packit b099d7
   if (destX + geo.width > WidthOfScreen (XtScreen (w)))
Packit b099d7
   {
Packit b099d7
      destX = WidthOfScreen (XtScreen (w)) - geo.width;
Packit b099d7
   }
Packit b099d7
   destY = ry + (XmIsGadget (w) ? XtY (w) : 0) - y + XtHeight (w);
Packit b099d7
   if (destY + geo.height > HeightOfScreen (XtScreen (w)))
Packit b099d7
   {
Packit b099d7
      destY = ry + (XmIsGadget (w) ? XtY (w) : 0) - y - geo.height;
Packit b099d7
   }
Packit b099d7
Packit b099d7
   XtVaSetValues (XtParent (ttp->label),
Packit b099d7
                  XmNx, rx + 1,
Packit b099d7
                  XmNy, ry + 1, XmNwidth, 1, XmNheight, 1, NULL);
Packit b099d7
   ttp->slider =
Packit b099d7
      XtVaCreateWidget ("ToolTipSlider", xmSlideContextWidgetClass,
Packit b099d7
                        XmGetXmDisplay (XtDisplay (w)), XmNslideWidget,
Packit b099d7
                        XtParent (ttp->label),
Packit b099d7
                        XmNslideDestX, destX,
Packit b099d7
                        XmNslideDestY, destY,
Packit b099d7
                        XmNslideDestWidth, geo.width,
Packit b099d7
                        XmNslideDestHeight, geo.height, NULL);
Packit b099d7
Packit b099d7
   XtAddCallback (ttp->slider, XmNslideFinishCallback,
Packit b099d7
                  (XtCallbackProc) ToolTipPostFinish, ttp);
Packit b099d7
Packit b099d7
   XtPopup (XtParent (ttp->label), XtGrabNone);
Packit b099d7
}
Packit b099d7
Packit b099d7
/*
Packit b099d7
=====================================
Packit b099d7
Publically available functions follow
Packit b099d7
=====================================
Packit b099d7
*/
Packit b099d7
Packit b099d7
void
Packit b099d7
_XmToolTipEnter (Widget wid,
Packit b099d7
                 XEvent * event,
Packit b099d7
                 String * params,
Packit b099d7
                 Cardinal * num_params)
Packit b099d7
{
Packit b099d7
   XmToolTipConfigTrait ttp;           /* ToolTip pointer */
Packit b099d7
Packit b099d7
   ttp = ToolTipGetData (wid);
Packit b099d7
Packit b099d7
   if (ttp == NULL)
Packit b099d7
   {
Packit b099d7
      XtWarning ("ToolTipGetData() returned NULL in _XmToolTipEnter()");
Packit b099d7
      return;
Packit b099d7
   }
Packit b099d7
   if ((XmIsPrimitive (wid) || XmIsGadget(wid)) && XmGetToolTipString(wid))
Packit b099d7
   {
Packit b099d7
      if (ttp->enable && !ttp->timer)
Packit b099d7
      {
Packit b099d7
         unsigned long delay;
Packit b099d7
Packit b099d7
         if (event &&
Packit b099d7
             (event->xcrossing.time - ttp->leave_time < ttp->post_delay))
Packit b099d7
         {
Packit b099d7
            delay = 0;
Packit b099d7
         }
Packit b099d7
         else
Packit b099d7
         {
Packit b099d7
            delay = (unsigned long) ttp->post_delay;
Packit b099d7
         }
Packit b099d7
         if (ttp->duration_timer)
Packit b099d7
         {
Packit b099d7
            XtRemoveTimeOut (ttp->duration_timer);
Packit b099d7
            ttp->duration_timer = (XtIntervalId) NULL;
Packit b099d7
         }
Packit b099d7
         ttp->timer =
Packit b099d7
            XtAppAddTimeOut (XtWidgetToApplicationContext (wid), delay,
Packit b099d7
                             (XtTimerCallbackProc) ToolTipPost, wid);
Packit b099d7
      }
Packit b099d7
   }
Packit b099d7
}
Packit b099d7
Packit b099d7
void
Packit b099d7
_XmToolTipLeave (Widget w,
Packit b099d7
                 XEvent * event,
Packit b099d7
                 String * params,
Packit b099d7
                 Cardinal * num_params)
Packit b099d7
{
Packit b099d7
   XmToolTipConfigTrait ttp = ToolTipGetData (w);
Packit b099d7
Packit b099d7
   if (!ttp)
Packit b099d7
   {
Packit b099d7
      XtWarning ("_XmToolTipLeave() - ttp == NULL.");
Packit b099d7
      return;
Packit b099d7
   }
Packit b099d7
Packit b099d7
Packit b099d7
   if (ttp->timer)
Packit b099d7
   {
Packit b099d7
      XtRemoveTimeOut (ttp->timer);
Packit b099d7
      ttp->timer = (XtIntervalId) NULL;
Packit b099d7
   }
Packit b099d7
   else
Packit b099d7
   {
Packit b099d7
      if (event && (ttp->duration_timer || ttp->post_duration == 0))
Packit b099d7
      {
Packit b099d7
         ttp->leave_time = event->xcrossing.time;
Packit b099d7
      }
Packit b099d7
      ToolTipUnpost (ttp, NULL);
Packit b099d7
   }
Packit b099d7
Packit b099d7
}
Packit b099d7
Packit b099d7
#ifdef FIX_1388
Packit b099d7
void _XmToolTipRemove(Widget w)
Packit b099d7
{
Packit b099d7
    XmToolTipTrait ttp;
Packit b099d7
    
Packit b099d7
    _XmToolTipLeave(w, NULL, NULL, NULL);
Packit b099d7
    ttp = (XmToolTipTrait) XmeTraitGet(w, XmQTtoolTip);
Packit b099d7
    if (ttp != NULL) {
Packit b099d7
	XmStringFree(ttp->tool_tip_string); 
Packit b099d7
	XmeTraitSet(w, XmQTtoolTip, (XtPointer) NULL); 
Packit b099d7
	XtFree((char*)ttp);
Packit b099d7
    }
Packit b099d7
}
Packit b099d7
#endif /* FIX_1388 */
Packit b099d7
Packit b099d7
Widget 
Packit b099d7
XmToolTipGetLabel(Widget wid)
Packit b099d7
{
Packit b099d7
    XmToolTipConfigTrait TipData = ToolTipGetData(wid);
Packit b099d7
    
Packit b099d7
#ifdef BUG1232
Packit b099d7
/* rws 25 Sep 2003
Packit b099d7
   protect against NULL TipData
Packit b099d7
 */
Packit b099d7
#endif
Packit b099d7
    return(TipData ? TipData->label : NULL);
Packit b099d7
}
Packit b099d7
Packit b099d7
XmString
Packit b099d7
XmGetToolTipString (Widget w)
Packit b099d7
{
Packit b099d7
    XmToolTipTrait ttp;
Packit b099d7
    ttp = (XmToolTipTrait)XmeTraitGet(w, XmQTtoolTip);
Packit b099d7
    return ttp ? ttp->tool_tip_string : NULL;    
Packit b099d7
}
Packit b099d7
Packit b099d7
void
Packit b099d7
XmSetToolTipString (Widget w,
Packit b099d7
                    XmString s)
Packit b099d7
{
Packit b099d7
    XmToolTipTrait ttp;
Packit b099d7
    ttp = (XmToolTipTrait)XmeTraitGet(w, XmQTtoolTip);
Packit b099d7
    if (!ttp) {
Packit b099d7
        ttp = (XmToolTipTrait)XtCalloc(1, sizeof(XmToolTipTraitRec));
Packit b099d7
        XmeTraitSet(w, XmQTtoolTip, ttp);
Packit b099d7
    }
Packit b099d7
    if (ttp->tool_tip_string)
Packit b099d7
        XmStringFree(ttp->tool_tip_string);
Packit b099d7
    ttp->tool_tip_string = XmStringCopy(s);
Packit b099d7
}