Skip to content

AFNI/NIfTI Server

Sections
Personal tools
You are here: Home » AFNI » Documentation

Doxygen Source Code Documentation


Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals   Search  

LiteClue.c

Go to the documentation of this file.
00001 /* 
00002 LiteClue.c - LiteClue widget
00003         See LiteClue documentation
00004         Version 1.4
00005 
00006 Copyright 1996 COMPUTER GENERATION, INC.,
00007 
00008 The software is provided "as is", without warranty of any kind, express
00009 or implied, including but not limited to the warranties of
00010 merchantability, fitness for a particular purpose and noninfringement.
00011 In no event shall Computer Generation, inc. nor the author be liable for
00012 any claim, damages or other liability, whether in an action of contract,
00013 tort or otherwise, arising from, out of or in connection with the
00014 software or the use or other dealings in the software.
00015 
00016 Permission to use, copy, modify, and distribute this software and its
00017 documentation for any purpose and without fee is hereby granted,
00018 provided that the above copyright notice appear in all copies and that
00019 both that copyright notice and this permission notice appear in
00020 supporting documentation.
00021 
00022 Author:
00023 Gary Aviv 
00024 Computer Generation, Inc.,
00025 gary@compgen.com
00026 www.compgen.com/widgets
00027 
00028 Thanks to Contributers:
00029 J Satchell, Eric Marttila 
00030 */
00031 /* Revision History:
00032 $Log: LiteClue.c,v $
00033 Revision 1.16  2003/12/19 22:39:00  rwcox
00034 Cput
00035 
00036 Revision 1.15  2003/12/16 16:13:12  rhammett
00037 Cput
00038 
00039 Revision 1.14  2003/08/05 17:20:46  rwcox
00040 Cput
00041 
00042 Revision 1.13  2000/12/21 16:10:54  cox
00043 AFNI
00044 
00045 Revision 1.3  1997/11/06 16:26:48  cox
00046 Fixes so it won't crash so easily
00047 
00048 Revision 1.2  1997/11/05 21:28:04  cox
00049 *** empty log message ***
00050 
00051 Revision 1.13  1997/07/07 14:55:04  gary
00052 Cancel timeouts when XcgLiteClueDeleteWidget is called to prevent
00053 errant timeout event on deleted widget.
00054 
00055 Revision 1.12  1997/06/20 20:09:09  gary
00056 Add XcgLiteClueDispatchEvent to enable clues for insensitive widgets.
00057 
00058 Revision 1.11  1997/06/15 14:10:24  gary
00059 Add XcgLiteClueDispatchEvent to enable clues for insensitive widgets.
00060 
00061 Revision 1.10  1997/04/14 13:02:33  gary
00062 Attempt to fix problem when we get multiple enter events bu no leave event.
00063 
00064 Revision 1.9  1997/03/10 14:42:41  gary
00065 Attempt to fix problem when we get multiple enter events bu no leave event.
00066 Add C++ wrapper to allow linking with C++ programs. (In HView.h)
00067 
00068 Revision 1.8  1997/01/17 13:44:14  gary
00069 Support of cancelWaitPeriod resource: this is a period from the point
00070 a help popdown occurs in which the normal waitPeriod is suspended
00071 for the next popup
00072 
00073 Revision 1.7  1996/12/16 22:35:38  gary
00074 Fix double entry problem
00075 
00076 Revision 1.6  1996/11/18 14:52:21  gary
00077 remove some compile warnings pointed out by a user
00078 
00079 Revision 1.5  1996/11/12 20:56:43  gary
00080 remove some compile warnings
00081 
00082 Revision 1.4  1996/10/20  13:38:16  gary
00083 Version 1.2 freeze
00084 
00085 Revision 1.3  1996/10/19 16:16:30  gary
00086 Compile warning removed with cast
00087 
00088 Revision 1.2  1996/10/19 16:07:38  gary
00089 a) R4 back compatibility
00090 b) Delay before pop up of help, waitPeriod resource (def 500 ms).
00091         Thanks to J Satchell for this.
00092 c) Button press in watched widget pops down help
00093 
00094 Revision 1.1  1996/10/18 23:14:58  gary
00095 Initial
00096 
00097 
00098 $log
00099 Cancel timeouts when XcgLiteClueDeleteWidget is called to prevent
00100 errant timeout event on deleted widget.
00101 $log
00102 */
00103 
00104 /******************************************************************
00105   Modified by RWCox of MCW, to draw a rectangle around the text,
00106   and to make the widget popup on screen if it would go off.
00107   These changes can be found by searching for the string "RWC".
00108   These modifications are released to the public domain.
00109 *******************************************************************/
00110 
00111 #include <unistd.h>
00112 #include <signal.h>
00113 /* #include <Xm/XmP.h> */
00114 #include <X11/IntrinsicP.h> 
00115 #include <X11/StringDefs.h>
00116 extern void RWC_xineramize( Display *,int,int,int,int,int *,int *) ;
00117 
00118 #include "LiteClueP.h"
00119 
00120 #include <stdio.h>
00121 
00122 #if 0
00123 #define CheckWidgetClass(routine) \
00124         if (XtClass(w) != xcgLiteClueWidgetClass) \
00125                 wrong_widget(routine)
00126 
00127 #else
00128 #define CheckWidgetClass(routine) \
00129         if (XtClass(w) != xcgLiteClueWidgetClass) \
00130                 return BADVALUE
00131 #endif
00132 
00133 /* extern _XmSelectColorDefault(); */ /* cgi */
00134 static Boolean setValues( Widget _current, Widget _request, Widget _new, ArgList args, Cardinal * num_args);
00135 static void Initialize(Widget treq, Widget tnew, ArgList args, Cardinal *num_args);
00136 struct liteClue_context_str * alloc_liteClue_context(void);
00137 
00138 /* keep information about each widget we are keeping track of */
00139 struct liteClue_context_str
00140 {
00141         ListThread next;        /* next in list */
00142         Widget watched_w;       /* the widget we are watching */
00143         XcgLiteClueWidget cw;   /* pointer back to the liteClue widget */
00144         Position  abs_x, abs_y;
00145         Boolean sensitive;      /* if False, liteClue is suppressed */
00146         char * text;            /* text to display */
00147         short text_size;        /* its size */
00148 };
00149 
00150 void free_widget_context(XcgLiteClueWidget cw, struct liteClue_context_str * obj);
00151 /*
00152 Widget resources: eg to set LiteClue box background:
00153  *XcgLiteClue.background: yellow
00154        
00155 */
00156 #define offset(field) XtOffsetOf(LiteClueRec, field)
00157 static XtResource resources[] =
00158 {
00159         {XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel),
00160                 offset(liteClue.foreground), XtRString, "black"},
00161 #if XtSpecificationRelease < 5
00162         {XtNfont, XtCFont, XtRFontStruct, sizeof(XFontStruct *),
00163                 offset(liteClue.font), XtRString, 
00164           "-adobe-new century schoolbook-bold-r-normal-*-14-*-*-*-*-*-*-*"},
00165 #else
00166         {XtNfontSet, XtCFontSet, XtRFontSet, sizeof(XFontSet),
00167                 offset(liteClue.fontset), XtRString, "-adobe-new century schoolbook-bold-r-normal-*-12-*"},
00168 #endif
00169         {XgcNwaitPeriod, XgcCWaitPeriod, XtRInt , sizeof(int),
00170                 offset(liteClue.waitPeriod),XtRString, "500" },
00171 
00172         {XgcNcancelWaitPeriod, XgcCCancelWaitPeriod, XtRInt , sizeof(int),
00173                 offset(liteClue.cancelWaitPeriod),XtRString, "2000" },
00174 };
00175 
00176 #undef offset
00177 
00178 #if 0
00179 static XtActionsRec actions[] = 
00180 }; /* actions */
00181 #endif
00182 
00183 
00184 LiteClueClassRec xcgLiteClueClassRec =
00185 {
00186     {
00187         (WidgetClass)&overrideShellClassRec,    /* superclass */
00188         "XcgLiteClue",                          /* class_name */
00189         (Cardinal)sizeof(LiteClueRec),          /* widget size */
00190         NULL,   /* classInit, */                /* class_init */
00191         (XtWidgetClassProc)NULL, /* classPartInit, */   /* class_part_init */
00192         (XtEnum)FALSE,                          /* class_inited */
00193         (XtInitProc)Initialize,                 /* initialize */
00194         (XtArgsProc)NULL,                       /* init_hook */
00195         XtInheritRealize,                       /* realize */
00196         (XtActionList)0,                        /* actions */
00197         (Cardinal)0,                    /* num_actions */
00198         (XtResourceList)resources,              /* resources */
00199         (Cardinal)XtNumber(resources),          /* num_resources */
00200         NULLQUARK,                              /* xrm_class */
00201         TRUE,                                   /* compress_motion */
00202         (XtEnum)FALSE,                          /* compress_exposur */
00203         TRUE,                                   /* compress enterleave */
00204         FALSE,                                  /* visibility_interest */
00205         (XtWidgetProc)NULL,     /* destroy, */                  /* destroy */
00206         XtInheritResize,
00207         XtInheritExpose,        /* expose, */
00208         (XtSetValuesFunc)setValues,             /* set_values */
00209         (XtArgsFunc)NULL,                       /* set_values_hook */
00210         XtInheritSetValuesAlmost,               /* set_values_almost */
00211         (XtArgsProc)NULL,                       /* get_values_hook */
00212         XtInheritAcceptFocus,           /* accept_focus */
00213         XtVersion,                              /* version */
00214         (XtPointer)NULL,                        /* callback_private */
00215         XtInheritTranslations,
00216         XtInheritQueryGeometry,                 /* query_geometry */
00217         XtInheritDisplayAccelerator,            /* display_accelerator */
00218         (XtPointer)0,                   /* extension */
00219     },
00220     { /*** composite-Class ***/
00221         XtInheritGeometryManager,       /* geometry_manager     */      
00222         XtInheritChangeManaged, /* change_managed               */      
00223         XtInheritInsertChild,   /* insert_child         */      
00224         XtInheritDeleteChild,   /* delete_child         */      
00225         NULL    /* extension            */      
00226     }, 
00227         { /* Shell */
00228         (XtPointer) NULL,       /* pointer to extension record      */
00229         },
00230         /* Override Shell */
00231         {
00232         0,
00233         },
00234         /* LiteClue */
00235         {
00236         0,
00237         },
00238 };
00239 
00240 WidgetClass xcgLiteClueWidgetClass = (WidgetClass) & xcgLiteClueClassRec;
00241 
00242 /* doubly linked list processing */
00243 
00244 /*
00245          initialize header - both pointers point to it
00246 */
00247 static void xcgListInit(ListThread *newbuf)
00248 {
00249         newbuf->back = newbuf;
00250         newbuf->forw = newbuf;
00251 }
00252 
00253 
00254 /*
00255          insert newbuf before posbuf
00256 */
00257 static void xcgListInsertBefore(ListThread *newlist, ListThread *poslist)
00258 {
00259         ListThread *prevbuf;
00260 
00261         prevbuf = poslist->back;
00262 
00263         poslist->back = newlist;
00264         newlist->forw = poslist;
00265         newlist->back = prevbuf;
00266         prevbuf->forw = newlist;
00267 }
00268 
00269 
00270 /*
00271         remove rembuf from queue
00272 */
00273 static ListThread * xcgListRemove(ListThread *rembuf)
00274 {
00275         ListThread *prevbuf, *nextbuf;
00276 
00277         prevbuf = rembuf->back;
00278         nextbuf = rembuf->forw;
00279 
00280         prevbuf->forw = nextbuf;
00281         nextbuf->back = prevbuf;                
00282 
00283         rembuf->back = (ListThread *) NULL;     /* for safety to cause trap if ..*/
00284         rembuf->forw = (ListThread *) NULL;     /* .. mistakenly refed */
00285         return rembuf;
00286 }
00287 
00288 /*
00289 The font_information is derived 
00290 */
00291 
00292 #if XtSpecificationRelease >= 5
00293 /* R5 and above code */
00294 static void compute_font_info(XcgLiteClueWidget cw)
00295 {
00296         XRectangle ink;
00297         XRectangle logical;
00298 
00299         if (!cw->liteClue.fontset)
00300                 return;
00301         XmbTextExtents(cw->liteClue.fontset, "1", 1,&ink, &logical);
00302 
00303         cw->liteClue.font_baseline = -logical.y;        /* y offset from top to baseline, 
00304                         don't know why this is returned as negative */
00305         cw->liteClue.font_width = logical.width;        /* the width and height of the object */
00306         cw->liteClue.font_height = logical.height;
00307 }
00308 
00309 #else
00310 /* R4 and below code */
00311 static void compute_font_info(XcgLiteClueWidget cw)
00312 {
00313         int direction_return;
00314         int font_ascent_return, font_descent_return; 
00315         XCharStruct oret;
00316         if ( cw->liteClue.font == NULL )
00317                 return;
00318         XTextExtents( cw->liteClue.font, "1", 1,
00319                 &direction_return,
00320                 &font_ascent_return, &font_descent_return, &oret);
00321 
00322         cw->liteClue.font_baseline = oret.ascent;       /* y offset from top to baseline, 
00323                         don't know why this is returned as negative */
00324         cw->liteClue.font_width = oret.width;   /* the width and height of the object */
00325         cw->liteClue.font_height = oret.ascent+oret.descent;
00326 }
00327 #endif
00328 
00329 /*
00330  Creates the various graphic contexts we will need 
00331 */
00332 static void create_GC(XcgLiteClueWidget cw )
00333 {
00334         XtGCMask valuemask;
00335         XGCValues myXGCV;
00336 
00337 
00338         valuemask = GCForeground | GCBackground | GCFillStyle ;
00339         myXGCV.foreground = cw->liteClue.foreground;
00340         myXGCV.background = cw->core.background_pixel;
00341         myXGCV.fill_style = FillSolid; 
00342 
00343 #if XtSpecificationRelease < 5          /* R4 hack */
00344         myXGCV.font = cw->liteClue.font->fid; 
00345 #endif  /* end R4 hack */
00346 
00347         if (cw->liteClue.text_GC )
00348                 XtReleaseGC((Widget) cw, cw->liteClue.text_GC );
00349         cw->liteClue.text_GC = XtGetGC((Widget)cw, valuemask, &myXGCV);
00350 }
00351 
00352 
00353 /* a routine to halt execution and force  
00354 a core dump for debugging analysis      
00355 when a public routine is called with the wrong class of widget
00356 */
00357 static void wrong_widget(char * routine)
00358 {
00359         int mypid = getpid(); 
00360         fprintf(stderr, "Wrong class of widget passed to %s\n", routine);
00361         fflush(stderr); 
00362         kill(mypid, SIGABRT); 
00363 }
00364 
00365 /*
00366 Find the target in the widget list. Return context pointer if found,
00367 NULL if not
00368 */
00369 static struct liteClue_context_str * find_watched_widget(XcgLiteClueWidget cw,
00370         Widget target)
00371 {
00372         struct liteClue_context_str * obj;
00373 
00374         for (obj = (struct liteClue_context_str *) cw->liteClue.widget_list.forw; 
00375                 obj != (struct liteClue_context_str *) & cw->liteClue.widget_list; 
00376                 obj = (struct liteClue_context_str *)obj->next.forw )
00377         {
00378                 if (target == obj->watched_w)
00379                         return obj;
00380         }
00381         return NULL;
00382 }
00383 
00384 /*
00385         allocate and initialize a widget context
00386 */
00387 struct liteClue_context_str * alloc_liteClue_context(void)
00388 {
00389         struct liteClue_context_str * out;
00390         out = (struct liteClue_context_str *) XtMalloc(sizeof(struct liteClue_context_str));
00391         memset(out, 0, sizeof(struct liteClue_context_str));
00392         xcgListInit(&out->next);        
00393         return out ;
00394 }
00395 
00396 /*
00397         allocate, initialize and link a liteClue context to the list
00398 */
00399 static struct liteClue_context_str * alloc_link_liteClue_context(XcgLiteClueWidget cw )
00400 {
00401         struct liteClue_context_str * out = alloc_liteClue_context();
00402 
00403         /* link as new last */
00404         xcgListInsertBefore(&out->next, &cw->liteClue.widget_list);
00405         out->cw = cw;   /* initialize this emeber - its always the same */
00406         return out;
00407 }
00408 
00409 /*
00410         free a widget context
00411 */
00412 void free_widget_context(XcgLiteClueWidget cw, struct liteClue_context_str * obj)
00413 {
00414         xcgListRemove((ListThread *)obj);
00415         /* free up all things object points to */
00416         obj->sensitive = False;
00417         if (obj->text )
00418                 XtFree(obj->text);
00419         XtFree((char *) obj);
00420 }
00421 
00422 
00423 /* -------------------- Widget Methods ---------------------- */
00424 /* Initialize method */
00425 static void Initialize(Widget treq, Widget tnew, ArgList args, 
00426 Cardinal *num_args)
00427 {
00428         XcgLiteClueWidget cw = (XcgLiteClueWidget) tnew;
00429 
00430 
00431         cw->liteClue.text_GC = NULL;
00432         cw->liteClue.HelpIsUp = False;
00433         cw->liteClue.HelpPopDownTime = 0;
00434         cw->liteClue.interval_id = (XtIntervalId)0;
00435         xcgListInit(&cw->liteClue.widget_list); /* initialize empty list */
00436         compute_font_info(cw);
00437         create_GC(cw );
00438 }
00439 
00440 static Boolean setValues( Widget _current, Widget _request, Widget _new, ArgList args, Cardinal * num_args)
00441 {
00442         XcgLiteClueWidget cw_new = (XcgLiteClueWidget) _new;
00443         XcgLiteClueWidget cw_cur = (XcgLiteClueWidget) _current;
00444 
00445         /* values of cw_new->liteClue.cancelWaitPeriod and
00446            cw_new->liteClue.waitPeriod are accepted without checking */
00447 
00448         if (cw_new->liteClue.foreground != cw_cur->liteClue.foreground 
00449         ||  cw_new->core.background_pixel != cw_cur->core.background_pixel )
00450         {
00451                 create_GC(cw_new);
00452         }
00453 
00454         return FALSE;
00455 }
00456 
00457 /* ----------------- Event handlers ------------------------*/
00458 
00459 /* At this point the help may be popup 
00460 */
00461 static void timeout_event( XtPointer client_data, XtIntervalId *id)
00462 {
00463 #define BorderPix 3
00464         struct liteClue_context_str * obj = (struct liteClue_context_str *) client_data;
00465         XcgLiteClueWidget cw = obj->cw;
00466         Position  abs_x, abs_y;
00467 
00468         XRectangle ink;
00469         XRectangle logical;
00470         Position   w_height;    
00471         Widget w;
00472 
00473         int RWC_width , RWC_height ;
00474 
00475         if (cw->liteClue.interval_id == (XtIntervalId)0)
00476                 return; /* timeout was removed but callback happened anyway */
00477         cw->liteClue.interval_id = (XtIntervalId)0;
00478         if (obj->sensitive == False)
00479                 return;
00480 
00481         w = obj->watched_w;
00482         XtVaGetValues(w, XtNheight, &w_height, NULL );
00483         /* position just below the widget */
00484         XtTranslateCoords(w, 0, w_height, &abs_x, &abs_y);
00485 
00486 #if XtSpecificationRelease < 5          /* R4 hack */
00487         {
00488         int direction_return;
00489         int font_ascent_return, font_descent_return; 
00490         XCharStruct oret;
00491         XTextExtents( cw->liteClue.font ,obj->text , obj->text_size,
00492                 &direction_return,
00493                 &font_ascent_return, &font_descent_return, &oret); 
00494         logical.width = oret.width;
00495         }
00496 #else
00497         XmbTextExtents(cw->liteClue.fontset, obj->text , obj->text_size ,&ink, &logical);
00498 #endif
00499 
00500         RWC_width  = 2*BorderPix +logical.width ;
00501         RWC_height = 2*BorderPix + cw->liteClue.font_height ;
00502         XtResizeWidget((Widget) cw, RWC_width , RWC_height ,
00503                         cw->core.border_width );
00504 
00505 /** RWCox change to widget location **/
00506         { int scw = WidthOfScreen(XtScreen(cw)) , sch = HeightOfScreen(XtScreen(cw)) ;
00507           int newx = abs_x + 1 , newy = abs_y+1 ; int xx,yy ;
00508           if( newx + logical.width > scw ) newx = scw - logical.width - 2*BorderPix ;
00509           if( newx < 0 )                   newx = 0 ;
00510           if( newy + cw->liteClue.font_height + 2 >= sch )
00511              newy = newy - w_height - cw->liteClue.font_height - 2*BorderPix ;
00512           if( newy < 0 ) newy = 0 ;
00513 
00514 #if 1
00515           RWC_xineramize( XtDisplay(w) ,      /* 27 Sep 2000 - see xutil.[ch] */
00516                           newx,newy , RWC_width,RWC_height , &xx,&yy ) ;
00517           if( yy < newy )
00518              yy = newy - w_height - cw->liteClue.font_height - 2*BorderPix ;
00519           XtMoveWidget((Widget) cw, xx,yy);
00520 #else
00521           XtMoveWidget((Widget) cw, newx,newy);
00522 #endif
00523         }
00524 
00525         XtPopup((Widget) cw, XtGrabNone);
00526         cw->liteClue.HelpIsUp = True;
00527 
00528 #if XtSpecificationRelease < 5          /* R4 hack */
00529         XDrawImageString(XtDisplay((Widget) cw), XtWindow((Widget) cw), 
00530                 cw->liteClue.text_GC , BorderPix, 
00531                 BorderPix + cw->liteClue.font_baseline, obj->text , obj->text_size);
00532 #else
00533         XmbDrawImageString(XtDisplay((Widget) cw), XtWindow((Widget) cw), 
00534                 cw->liteClue.fontset,
00535                 cw->liteClue.text_GC , BorderPix, 
00536                 BorderPix + cw->liteClue.font_baseline, obj->text , obj->text_size);
00537 #endif
00538 
00539 /** RWCox change to add a rectangle **/
00540         XDrawRectangle( XtDisplay((Widget) cw) , XtWindow((Widget) cw) ,
00541                         cw->liteClue.text_GC ,
00542                         0,0 , RWC_width-1,RWC_height-1 ) ;
00543 }
00544 
00545 /*
00546 Pointer enters watched widget, set a timer at which time it will
00547 popup the help
00548 */
00549 static void Enter_event(Widget w, XtPointer client_data, XEvent * xevent, Boolean * continue_to_dispatch )
00550 {
00551         struct liteClue_context_str * obj = (struct liteClue_context_str *) client_data;
00552         XcgLiteClueWidget cw = obj->cw;
00553         XEnterWindowEvent * event = & xevent->xcrossing;
00554         int current_waitPeriod ;
00555 
00556         if (obj->sensitive == False)
00557                 return;
00558         /* check for two enters in a row - happens when widget is
00559            exposed under a pop-up */
00560         if (cw->liteClue.interval_id != (XtIntervalId)0) 
00561                 return;
00562         if(event->mode != NotifyNormal)
00563                 return;
00564 
00565         /* if a help was recently popped down, don't delay in poping up
00566            help for next watched widget
00567         */
00568         if ((event->time -  cw->liteClue.HelpPopDownTime) > 
00569                         cw->liteClue.cancelWaitPeriod ) 
00570                 current_waitPeriod = cw->liteClue.waitPeriod,timeout_event;
00571         else
00572                 current_waitPeriod = 0;
00573 
00574         cw->liteClue.interval_id = XtAppAddTimeOut(
00575                         XtWidgetToApplicationContext(w),
00576                         current_waitPeriod, timeout_event, client_data);
00577 }
00578 
00579 /*
00580 Remove timer, if its pending. Then popdown help.
00581 */
00582 static void Leave_event(Widget w, XtPointer client_data, XEvent * xevent, Boolean * continue_to_dispatch )
00583 {
00584         struct liteClue_context_str * obj = (struct liteClue_context_str *) client_data;
00585         XcgLiteClueWidget cw = obj->cw;
00586         XEnterWindowEvent * event = & xevent->xcrossing;
00587 
00588         if (cw->liteClue.interval_id != (XtIntervalId)0) 
00589         {
00590                 XtRemoveTimeOut(cw->liteClue.interval_id);
00591                 cw->liteClue.interval_id= (XtIntervalId)0;
00592         }
00593 
00594         if (obj->sensitive == False)
00595                 return;
00596         if (cw->liteClue.HelpIsUp)
00597         {
00598                 XtPopdown((Widget) cw);
00599                 cw->liteClue.HelpIsUp = False;
00600                 cw->liteClue.HelpPopDownTime = event->time;
00601         }
00602 }
00603 
00604 /* ---------------- Widget API ---------------------------- */
00605 
00606 /*
00607 ;+
00608 XcgLiteClueAddWidget -- Add a widget to be watched. LiteClue will be given for this widget
00609 
00610 Func:   A widget will be added to the LiteClue watched list. Clues are given for
00611         sensitive watched widgets when the pointer enters its window. If the
00612         widget is already watched, the passed text replaces its current clue
00613         text. If text is null, the widget is still added, if it is not already
00614         in the list, but no clue will appear. Text may be specified with
00615         XcgLiteClueAddWidget in a subsequent call. When text is null and the
00616         widget is already in the list, its text is not changed. When a widget
00617         will is added to the watched list, it automatically becomes sensitive.
00618         Otherwise, its sensitivity is not changed. A watched widget which is not
00619         sensitive retains its context but clues are suppressed.
00620         None of this affects the behaviour of the watched widget itself.
00621         LiteClue monitors enter and leave events of the watched widget's
00622         window passively.
00623 
00624 Input:  w - LiteClue widget
00625         watch - the widget to give liteClues for
00626         text - pointer to liteClue text. (May be NULL)
00627         size - size of text. May be zero
00628                 in which case a strlen will be done.
00629         option - option mask, future use, zero for now.
00630 Output: 
00631 
00632 Return: 
00633 
00634 ;-
00635 */
00636 void XcgLiteClueAddWidget(Widget w, Widget watch,  char * text, int size, int option )
00637 {
00638 #       define ROUTINE "XcgLiteClueAddWidget"
00639 #       define BADVALUE /* nada */
00640         XcgLiteClueWidget cw = (XcgLiteClueWidget) w;
00641         struct liteClue_context_str * obj;
00642         Boolean exists = False;
00643 
00644         CheckWidgetClass(ROUTINE);      /* make sure we are called with a LiteClue widget */
00645 
00646         obj = find_watched_widget(cw, watch);
00647         if (obj)
00648         {
00649                 exists = True;
00650                 if (text)
00651                 {
00652                         if(obj->text)
00653                                 XtFree(obj->text);
00654                         obj->text = NULL;
00655                 }
00656         }
00657         else
00658         {
00659                 obj = alloc_link_liteClue_context(cw );
00660                 obj->watched_w = watch;
00661         }
00662         if (text && !(obj->text))
00663         {
00664                 if (!size)
00665                         size = strlen(text);
00666                 obj->text = (char*) XtMalloc(size+1);
00667                 memcpy(obj->text, text, size);
00668                 obj->text[size] = 0;
00669                 obj->text_size = size;
00670         }
00671         if (!exists)    /* was created */
00672         {
00673                 XtAddEventHandler(watch, EnterWindowMask, False, 
00674                         Enter_event, (XtPointer) obj);
00675                 XtAddEventHandler(watch, LeaveWindowMask|ButtonPressMask, 
00676                         False, Leave_event, (XtPointer) obj);
00677                 obj->sensitive = True;
00678         }
00679 
00680 #       undef ROUTINE
00681 #       undef BADVALUE
00682 }
00683 
00684 
00685 /*
00686 ;+
00687 XcgLiteClueDeleteWidget -- Delete a widget that is watched. 
00688 
00689 Func:   A widget is deleted from the watched list and its resources are
00690         freed. LiteClue is no longer given for the widget.
00691         If the widget is not watched, nothing is done.
00692 
00693 Input:  w - LiteClue widget
00694         watch - the widget to delete
00695 Output: 
00696 
00697 Return: 
00698 
00699 ;-
00700 */
00701 void XcgLiteClueDeleteWidget(Widget w, Widget watch)
00702 {
00703 #       define ROUTINE "XcgLiteClueDeleteWidget"
00704 #       define BADVALUE  /* nada */
00705         XcgLiteClueWidget cw = (XcgLiteClueWidget) w;
00706         struct liteClue_context_str * obj;
00707 
00708         CheckWidgetClass(ROUTINE);      /* make sure we are called with a LiteClue widget */
00709         obj = find_watched_widget(cw, watch);
00710         if (obj)
00711         {
00712                 XtRemoveEventHandler(watch, EnterWindowMask, False, 
00713                         Enter_event, (XtPointer) obj);
00714                 XtRemoveEventHandler(watch, LeaveWindowMask|ButtonPressMask, 
00715                         False, Leave_event, (XtPointer) obj);
00716                 if (cw->liteClue.interval_id != (XtIntervalId)0) 
00717                 {
00718                         XtRemoveTimeOut(cw->liteClue.interval_id);
00719                         cw->liteClue.interval_id= (XtIntervalId)0;
00720                 }
00721                 free_widget_context(cw, obj);
00722         }
00723 
00724 #       undef ROUTINE
00725 #       undef BADVALUE
00726 }
00727 
00728 
00729 /*
00730 ;+
00731 XcgLiteClueSetSensitive -- Enable/disable sensitivity for watched widget. 
00732 
00733 Func:   When a watched widget is sensitive, a clue is poped up when the pointer
00734         enters its window. When a watched widget is insensitive, the widget is
00735         retained in the watched list but no clue is poped. The sensitivity of a
00736         watched widget relative to clues is set or reset by this function. The
00737         Xt sensitivity of the watched widget is not altered by this function.
00738 
00739 Input:  w - LiteClue widget
00740         watch - the widget to make sensitive or insensitive or NULL
00741                 to change all watched widgets
00742         sensitive - True or False
00743 Output: 
00744 
00745 Return: 
00746 
00747 ;-
00748 */
00749 void XcgLiteClueSetSensitive(Widget w, Widget watch, Boolean sensitive)
00750 {
00751 #       define ROUTINE "XcgLiteClueSetSensitive"
00752 #       define BADVALUE  /* nada */
00753         XcgLiteClueWidget cw = (XcgLiteClueWidget) w;
00754         struct liteClue_context_str * obj;
00755 
00756         CheckWidgetClass(ROUTINE);      /* make sure we are called with a LiteClue widget */
00757         if (watch)
00758         {
00759                 obj = find_watched_widget(cw, watch);
00760                 if (obj)
00761                 {
00762                         obj->sensitive = sensitive;
00763                         return;
00764                 }
00765                 else
00766                         return;
00767         }
00768 
00769         /* do them all */
00770         for (obj = (struct liteClue_context_str *) cw->liteClue.widget_list.forw; 
00771                 obj != (struct liteClue_context_str *) & cw->liteClue.widget_list; 
00772                 obj = (struct liteClue_context_str *)obj->next.forw )
00773         {
00774                 obj->sensitive = sensitive;
00775         }
00776 
00777 #       undef ROUTINE
00778 #       undef BADVALUE
00779 }
00780 
00781 /*
00782 ;+
00783 XcgLiteClueGetSensitive -- Get sensitivity mode for watched widget. 
00784 
00785 Func:   When a watched widget is sensitive, a clue is poped up when the pointer
00786         enters its window. When a watched widget is insensitive, the widget is
00787         retained in the watched list but no clue is poped. The sensitivity state
00788         of a watched widget relative to clues is returned by this function. The
00789         Xt sensitivity of a widget is a totally independent concept.
00790 
00791 Input:  w - LiteClue widget
00792         watch - the widget for which to get sensitivity state. If NULL
00793                 first watched widget is used. If there are no watched widgets,
00794                 False is returned.
00795 Output: 
00796 
00797 Return: sensitive - True or False
00798 
00799 ;-
00800 */
00801 Boolean XcgLiteClueGetSensitive(Widget w, Widget watch)
00802 {
00803 #       define ROUTINE "XcgLiteClueGetSensitive"
00804 #       define BADVALUE  False
00805 
00806         XcgLiteClueWidget cw = (XcgLiteClueWidget) w;
00807         struct liteClue_context_str * obj;
00808 
00809         CheckWidgetClass(ROUTINE);      /* make sure we are called with a LiteClue widget */
00810         if (watch)
00811         {
00812                 obj = find_watched_widget(cw, watch);
00813                 if (obj)
00814                         return obj->sensitive;
00815                 else
00816                         return False;
00817         }
00818         /* do the first one */
00819         obj = (struct liteClue_context_str *) cw->liteClue.widget_list.forw; 
00820         if (obj != (struct liteClue_context_str *) & cw->liteClue.widget_list)
00821                 return obj->sensitive;
00822         else
00823                 return False;
00824 
00825 #       undef ROUTINE
00826 #       undef BADVALUE
00827 }
00828 
00829 
00830 /*
00831 ;+
00832 XcgLiteClueDispatchEvent -- Dispatch event from main X event loop
00833 
00834 Func:   This function may be used to enable clues for insensitive
00835         watched widgets. Normally, XtAppMainLoop (which calls
00836         XtDispatchEvent) will not deliver EnterNotify and LeaveNotify
00837         events to widgets that are not sensitive (XtSetSensitive). This
00838         prevents clues from poping up for these widgets. To bypass this
00839         limitation, you can break out XtAppMainLoop and add a call to
00840         XcgLiteClueDispatchEvent ass follows:
00841 
00842         MyXtAppMainLoop(XtAppContext app) 
00843         {
00844             XEvent event;
00845 
00846             for (;;) {
00847                 XtAppNextEvent(app, &event);
00848                 XcgLiteClueDispatchEvent(w, event) ;
00849                 XtDispatchEvent(&event);
00850             }
00851         } 
00852 
00853 Input:  w - LiteClue widget
00854         event - received event, normally from call to XtAppNextEvent.
00855 
00856 Output: void
00857 
00858 Return: True - event was dispatched to non-sensitive watched widget.
00859         False - not a EnterNotify or LeaveNotify event or window in
00860                 event is not a non-sensitive watched widget.
00861 
00862 ;-
00863 */
00864 Boolean XcgLiteClueDispatchEvent(Widget w, XEvent  *event)
00865 {
00866 #       define ROUTINE "XcgLiteClueDispatchEvent"
00867 #       define BADVALUE  False
00868 
00869         XcgLiteClueWidget cw = (XcgLiteClueWidget) w;
00870         struct liteClue_context_str * obj;
00871         Boolean continue_to_dispatch;
00872 
00873         if (event->type != EnterNotify && event->type != LeaveNotify)
00874                 return False;
00875         CheckWidgetClass(ROUTINE);      /* make sure we are called with a LiteClue widget */
00876 
00877         /* scan list */
00878         for (obj = (struct liteClue_context_str *) cw->liteClue.widget_list.forw; 
00879                 obj != (struct liteClue_context_str *) & cw->liteClue.widget_list; 
00880                 obj = (struct liteClue_context_str *)obj->next.forw )
00881         {
00882                 if ((XtWindow(obj->watched_w) != event->xany.window)
00883                 ||  (XtIsSensitive(obj->watched_w)) )
00884                         continue;
00885                 /* found one */
00886                 if (event->type == EnterNotify )
00887                         Enter_event(obj->watched_w, obj, event,  &continue_to_dispatch);
00888                 else
00889                         Leave_event(obj->watched_w, obj, event,  &continue_to_dispatch);
00890                 return True;
00891         }
00892         return False;
00893 
00894 #       undef ROUTINE
00895 #       undef BADVALUE
00896 }
00897 
 

Powered by Plone

This site conforms to the following standards: