home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / s / stex2-18.zip / SeeTeX / Xtex / EzME.c < prev    next >
C/C++ Source or Header  |  1991-02-19  |  10KB  |  399 lines

  1. #if ( !defined(lint) && !defined(SABER) )
  2. static char Xrcsid[] = "$XConsortium: EzME.c,v 1.6 89/12/11 15:20:07 kit Exp $";
  3. #endif 
  4.  
  5. /*
  6.  * Copyright 1989 Massachusetts Institute of Technology
  7.  *
  8.  * Permission to use, copy, modify, distribute, and sell this software and its
  9.  * documentation for any purpose is hereby granted without fee, provided that
  10.  * the above copyright notice appear in all copies and that both that
  11.  * copyright notice and this permission notice appear in supporting
  12.  * documentation, and that the name of M.I.T. not be used in advertising or
  13.  * publicity pertaining to distribution of the software without specific,
  14.  * written prior permission.  M.I.T. makes no representations about the
  15.  * suitability of this software for any purpose.  It is provided "as is"
  16.  * without express or implied warranty.
  17.  *
  18.  * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
  19.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
  20.  * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  21.  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  22.  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 
  23.  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  24.  */
  25.  
  26. /*
  27.  * EzME.c - Source code for the generic menu entry
  28.  *
  29.  * Date:    September 26, 1989
  30.  *
  31.  * By:      Chris D. Peterson
  32.  *          MIT X Consortium 
  33.  *          kit@expo.lcs.mit.edu
  34.  */
  35.  
  36. #include <stdio.h>
  37. #include <X11/IntrinsicP.h>
  38. #include <X11/StringDefs.h>
  39.  
  40. #include <X11/Xaw/XawInit.h>
  41. #include "EzMEP.h"
  42. #include "EzMenuP.h"
  43. #include <X11/Xaw/Cardinals.h>
  44.  
  45. #include <ctype.h>
  46.  
  47. #define offset(field) XtOffset(EzMEWidget, ezme.field)
  48. static XtResource resources[] = {
  49.  
  50.   {XtNaction, XtCAction, XtRString, sizeof(caddr_t),
  51.      offset(action), XtRString, (caddr_t)NULL},
  52.  
  53.   {XtNmenu, XtCMenu, XtRWidget, sizeof(Widget), 
  54.      offset(toPopUp), XtRWidget, (caddr_t) NULL }
  55. };   
  56. #undef offset
  57.  
  58. static char haveSubMenuTransString[] =
  59.     "<EnterWindow>:     highlight()             \n\
  60.      <LeaveWindow>:     unhighlight() \n\
  61.      <BtnMotion>:       highlight()             \n\
  62.      <BtnUp>:           notify() unhighlight() "; 
  63.  
  64. static XtTranslations haveSubMenuTrans;
  65.  
  66. static char haveNoSubMenuTransString[] =
  67.     "<EnterWindow>:     highlight()             \n\
  68.      <LeaveWindow>:     unhighlight() MenuPopdown() \n\
  69.      <BtnMotion>:       highlight()             \n\
  70.      <BtnUp>:           notify() unhighlight()"; 
  71.  
  72. static XtTranslations haveNoSubMenuTrans;
  73.  
  74. /*
  75.  * Semi Public function definitions. 
  76.  */
  77.  
  78. static void ClassInitialize();
  79. static void Initialize();
  80. static void Destroy();
  81. static Boolean SetValues();
  82. static void Notify();
  83. static void Highlight();
  84. static void UnHighlight();
  85.  
  86. #define superclass (&smeBSBClassRec)
  87.  
  88. EzMEClassRec ezMEClassRec = {
  89.   {
  90.     /* superclass         */    (WidgetClass) superclass,
  91.     /* class_name         */    "EzME",
  92.     /* size               */    sizeof(EzMERec),
  93.     /* class_initialize   */    ClassInitialize,
  94.     /* class_part_initialize*/    NULL,
  95.     /* Class init'ed      */    FALSE,
  96.     /* initialize         */    Initialize,
  97.     /* initialize_hook    */    NULL,
  98.     /* realize            */    NULL,
  99.     /* actions            */    NULL,
  100.     /* num_actions        */    ZERO,
  101.     /* resources          */    resources,
  102.     /* resource_count     */    XtNumber(resources),
  103.     /* xrm_class          */    NULLQUARK,
  104.     /* compress_motion    */    FALSE, 
  105.     /* compress_exposure  */    FALSE,
  106.     /* compress_enterleave*/     FALSE,
  107.     /* visible_interest   */    FALSE,
  108.     /* destroy            */    Destroy,
  109.     /* resize             */    NULL,
  110.     /* expose             */    XtInheritExpose,
  111.     /* set_values         */    SetValues,
  112.     /* set_values_hook    */    NULL,
  113.     /* set_values_almost  */    XtInheritSetValuesAlmost,  
  114.     /* get_values_hook    */    NULL,            
  115.     /* accept_focus       */    NULL,
  116.     /* intrinsics version */    XtVersion,
  117.     /* callback offsets   */    NULL,
  118.     /* tm_table          */    XtInheritTranslations,
  119.     /* query_geometry      */    XtInheritQueryGeometry,
  120.     /* display_accelerator*/    NULL,
  121.     /* extension      */    NULL
  122.   },{
  123.     /* Simple Menu Entry Fields */
  124.       
  125.     /* highlight */             Highlight,
  126.     /* unhighlight */           UnHighlight,
  127.     /* notify */        Notify,        
  128.     /* extension */             NULL                
  129.   },
  130.   {
  131.     /* extension */             NULL                
  132.   }
  133. };
  134.  
  135. WidgetClass ezMEObjectClass = (WidgetClass) &ezMEClassRec;
  136.  
  137. /************************************************************
  138.  *
  139.  * Semi-Public Functions.
  140.  *
  141.  ************************************************************/
  142.  
  143.  
  144. static void
  145. ClassInitialize()
  146. {
  147.   haveSubMenuTrans = XtParseTranslationTable( haveSubMenuTransString );
  148.   haveNoSubMenuTrans = XtParseTranslationTable( haveNoSubMenuTransString );
  149. }
  150.  
  151. /*      Function Name: Initialize
  152.  *      Description: Initializes the simple menu widget
  153.  *      Arguments: request - the widget requested by the argument list.
  154.  *                 new     - the new widget with both resource and non
  155.  *                           resource values.
  156.  *      Returns: none.
  157.  * 
  158.  * MENU ENTRIES CANNOT HAVE BORDERS.
  159.  */
  160.  
  161. #ifndef XtObjectParent
  162. #  define XtObjectParent(x) ( x -> object.parent )
  163. #endif
  164.  
  165. /* ARGSUSED */
  166. static void
  167. Initialize(request, new)
  168. Widget request, new;
  169. {
  170.   EzMEWidget r = (EzMEWidget) request;
  171.   EzMEWidget n = (EzMEWidget) new;
  172.  
  173.   n -> ezme.action = NULL;
  174.   if ( r -> ezme.action ) {
  175.     int len = strlen(r -> ezme.action);
  176.     n -> ezme.action = XtMalloc(len+1);
  177.     strcpy(n -> ezme.action, r -> ezme.action);
  178.   }
  179.  
  180. }
  181.  
  182. static void
  183. Destroy(w)
  184. Widget w;
  185. {
  186.   EzMEWidget n = (EzMEWidget) w;
  187.  
  188.   if ( n -> ezme.action ) {
  189.     XtFree( n -> ezme.action );
  190.   }
  191. }
  192.  
  193. static Boolean
  194. SetValues(current, request, new)
  195.      Widget current, request, new;
  196. {
  197.   EzMEWidget c = (EzMEWidget) current;
  198.   EzMEWidget r = (EzMEWidget) request;
  199.   EzMEWidget n = (EzMEWidget) new;
  200.  
  201.   if (( !c -> ezme.action && r -> ezme.action)
  202.       ||
  203.       (c ->ezme.action
  204.        && r -> ezme.action
  205.        && !strcmp(c->ezme.action, r -> ezme.action)))
  206.       {
  207.     int len = strlen(r -> ezme.action);
  208.     XtFree(c->ezme.action);
  209.     n -> ezme.action = XtMalloc(len+1);
  210.     strcpy(n -> ezme.action, r -> ezme.action);
  211.       }
  212. }
  213.  
  214. /*    Function Name: Notify
  215.  *    Description: calls the callback proceedures for this entry.
  216.  *    Arguments: w - the menu entry.
  217.  *    Returns: none.
  218.  */
  219.  
  220. #define SKIPWHITE(cp) while (cp && *cp && isspace(*cp)) cp++
  221.  
  222. static void
  223. Notify(w) 
  224. Widget w;
  225. {
  226.   EzMEWidget widget = (EzMEWidget) w;
  227.   Widget parent = XtObjectParent( widget );
  228.   
  229.   XtPopdown( parent );
  230.  
  231.   XtCallCallbacks(w, XtNcallback, NULL);
  232.   
  233.   if ( widget -> ezme.action ) {
  234.     char *action = widget -> ezme.action;
  235.     int actionLen = strlen( action );
  236.     
  237.     Bool doFree;
  238.     char stringCopy[1024];
  239.     char *allocatedStr;
  240.     char *str;
  241.     
  242.     char *actionProcName;
  243.     int num_params;
  244.     char *params[100];    /* lets hope they don't have more than that.. */
  245.     
  246.     if ( actionLen > 1023 ) {
  247.       allocatedStr = str = XtMalloc( actionLen + 2 );
  248.       doFree = True;
  249.     }
  250.     else {
  251.       str = stringCopy;
  252.       doFree = False;
  253.     }
  254.     
  255.     SKIPWHITE(str);
  256.     strcpy(str, action);
  257.     
  258.     for (;;) {
  259.       SKIPWHITE(str);
  260.       if ( str == 0 || *str == 0 ) break;
  261.  
  262.       /* skip to action procedure name */
  263.       SKIPWHITE(str);
  264.       actionProcName = str;
  265.       
  266.       /* find end of action procedure name- terminate by space or paren */
  267.       while (*str && !( isspace(*str) || *str == '(' )) str++;
  268.       /* terminate action procedure name string */
  269.       *(str++) = 0;
  270.       
  271.       /* skip past any openning paren, e.g. in case of 'foo (bar)' */
  272.  
  273.       SKIPWHITE(str);
  274.       if ( *str == '(') str++;
  275.       
  276.       /* now, scan to build a list of params */
  277.       num_params = 0;
  278.       while ( *str && *str != ')' && num_params < 100) {
  279.     SKIPWHITE(str);
  280.     params[num_params] = str;
  281.     while (*str && !( isspace(*str) || *str == ',' || *str==')' )) {
  282.       if (*str == '\\') {
  283.         str++;
  284.         if ( *str == 0 ) str--;
  285.       }
  286.       str++;
  287.     }
  288.  
  289.     SKIPWHITE(str);
  290.  
  291.     /* terminate this parameter */
  292.     
  293.     num_params++;
  294.     if ( *str == 0 ) {
  295.       break;
  296.     } 
  297.     else if (*str == ')') {
  298.       *(str++) = 0;
  299.       break;
  300.     }
  301.     else {
  302.       *(str++) = 0;
  303.     }
  304.     
  305.     SKIPWHITE(str);
  306.       }
  307.  
  308.       SKIPWHITE(str);
  309.       if ( *str == ')') str++;
  310.       
  311.       XtCallActionProc(XtObjectParent(widget),
  312.                actionProcName, NULL, params, num_params);
  313.     }
  314.     
  315.     if ( doFree ) {
  316.       XtFree( allocatedStr );
  317.     }
  318.   }
  319. }
  320.  
  321. static void
  322. Highlight(w, event, params, num_params)
  323. Widget w;
  324. XEvent * event;
  325. String * params;
  326. Cardinal * num_params;
  327. {
  328.   Arg argList[20];
  329.   int args = 0;
  330.   int root_x, root_y, child_x, child_y, buttons;
  331.   Dimension width;
  332.   Dimension height;
  333.   
  334.   EzMEWidget widget = (EzMEWidget) w;
  335.  
  336.   (*superclass -> sme_class.highlight) (w, event, params, num_params);
  337.   
  338.   if ( widget -> ezme.toPopUp ) {
  339.     Widget parent = XtObjectParent( widget );
  340.     Widget toPopUp = widget -> ezme.toPopUp;
  341.     
  342.     if ( toPopUp ) { 
  343.       
  344.       Window root, child;
  345.       Arg argList[20];
  346.       int args = 0;
  347.       int root_x, root_y, child_x, child_y;
  348.       unsigned int buttons;
  349.       Dimension width;
  350.       Dimension height;
  351.       
  352.       XQueryPointer(XtDisplay(parent),
  353.             XtWindow(parent), &root, &child,
  354.             &root_x, &root_y, &child_x, &child_y, &buttons);
  355.  
  356.       root_x -= 20;
  357.       root_y -= 20;    /* put the mouse solidly in the window */
  358.  
  359.       args = 0;
  360.       XtSetArg(argList[args], XtNtranslations, haveSubMenuTrans); args++;
  361.       XtSetValues(parent,argList,args);
  362.       
  363.       args = 0;
  364.       XtSetArg(argList[args], XtNx, root_x); args++;
  365.       XtSetArg(argList[args], XtNy, root_y); args++;
  366.       XtSetArg(argList[args], XtNtranslations, haveNoSubMenuTrans); args++;
  367.       XtSetValues(toPopUp,argList,args);
  368.       XtPopup(toPopUp, XtGrabExclusive);
  369.     }
  370.   }
  371. }
  372.  
  373. static void
  374. UnHighlight(w, event, params, num_params)
  375. Widget w;
  376. XEvent * event;
  377. String * params;
  378. Cardinal * num_params;
  379. {
  380.   Arg argList[20];
  381.   int args = 0;
  382.   int root_x, root_y, child_x, child_y, buttons;
  383.   Dimension width;
  384.   Dimension height;
  385.   
  386.   EzMEWidget widget = (EzMEWidget) w;
  387.  
  388.   (*superclass -> sme_class.unhighlight) (w, event, params, num_params);
  389.   
  390.   if ( widget -> ezme.toPopUp ) {
  391.     Widget parent = XtObjectParent( widget );
  392.  
  393.     args = 0;
  394.     XtSetArg(argList[args], XtNtranslations, haveNoSubMenuTrans); args++;
  395.     XtSetValues(parent,argList,args);
  396.  
  397.   }
  398. }
  399.