home *** CD-ROM | disk | FTP | other *** search
/ Super Net 1 / SUPERNET_1.iso / PC / OTROS / UNIX / ARCHIE / CLIENTS / XARCHIE2.TAR / EzMenu / EzME.c next >
Encoding:
C/C++ Source or Header  |  1991-09-04  |  10.6 KB  |  406 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.  * gf: Modified by George Ferguson to not use whitespace to separate
  36.  *     parameters to action procedures, since they're too hard to escape.
  37.  * gf: Modified by George Ferguson to pass EzMEObject to action proc rather
  38.  *     than the parent menu (we can always call XtParentObject() later).
  39.  *
  40.  */
  41.  
  42. #include <stdio.h>
  43. #include <X11/IntrinsicP.h>
  44. #include <X11/StringDefs.h>
  45.  
  46. #include <X11/Xaw/XawInit.h>
  47. #include "EzMEP.h"
  48. #include "EzMenuP.h"
  49. #include <X11/Xaw/Cardinals.h>
  50.  
  51. #include <ctype.h>
  52.  
  53. #define offset(field) XtOffset(EzMEWidget, ezme.field)
  54. static XtResource resources[] = {
  55.  
  56.   {XtNaction, XtCAction, XtRString, sizeof(caddr_t),
  57.      offset(action), XtRString, (caddr_t)NULL},
  58.  
  59.   {XtNmenu, XtCMenu, XtRWidget, sizeof(Widget), 
  60.      offset(toPopUp), XtRWidget, (caddr_t) NULL }
  61. };   
  62. #undef offset
  63.  
  64. static char haveSubMenuTransString[] =
  65.     "<EnterWindow>:     highlight()             \n\
  66.      <LeaveWindow>:     unhighlight() \n\
  67.      <BtnMotion>:       highlight()             \n\
  68.      <BtnUp>:           notify() unhighlight() "; 
  69.  
  70. static XtTranslations haveSubMenuTrans;
  71.  
  72. static char haveNoSubMenuTransString[] =
  73.     "<EnterWindow>:     highlight()             \n\
  74.      <LeaveWindow>:     unhighlight() MenuPopdown() \n\
  75.      <BtnMotion>:       highlight()             \n\
  76.      <BtnUp>:           notify() unhighlight()"; 
  77.  
  78. static XtTranslations haveNoSubMenuTrans;
  79.  
  80. /*
  81.  * Semi Public function definitions. 
  82.  */
  83.  
  84. static void ClassInitialize();
  85. static void Initialize();
  86. static void Destroy();
  87. static Boolean SetValues();
  88. static void Notify();
  89. static void Highlight();
  90. static void UnHighlight();
  91.  
  92. #define superclass (&smeBSBClassRec)
  93.  
  94. EzMEClassRec ezMEClassRec = {
  95.   {
  96.     /* superclass         */    (WidgetClass) superclass,
  97.     /* class_name         */    "EzME",
  98.     /* size               */    sizeof(EzMERec),
  99.     /* class_initialize   */    ClassInitialize,
  100.     /* class_part_initialize*/    NULL,
  101.     /* Class init'ed      */    FALSE,
  102.     /* initialize         */    Initialize,
  103.     /* initialize_hook    */    NULL,
  104.     /* realize            */    NULL,
  105.     /* actions            */    NULL,
  106.     /* num_actions        */    ZERO,
  107.     /* resources          */    resources,
  108.     /* resource_count     */    XtNumber(resources),
  109.     /* xrm_class          */    NULLQUARK,
  110.     /* compress_motion    */    FALSE, 
  111.     /* compress_exposure  */    FALSE,
  112.     /* compress_enterleave*/     FALSE,
  113.     /* visible_interest   */    FALSE,
  114.     /* destroy            */    Destroy,
  115.     /* resize             */    NULL,
  116.     /* expose             */    XtInheritExpose,
  117.     /* set_values         */    SetValues,
  118.     /* set_values_hook    */    NULL,
  119.     /* set_values_almost  */    XtInheritSetValuesAlmost,  
  120.     /* get_values_hook    */    NULL,            
  121.     /* accept_focus       */    NULL,
  122.     /* intrinsics version */    XtVersion,
  123.     /* callback offsets   */    NULL,
  124.     /* tm_table          */    XtInheritTranslations,
  125.     /* query_geometry      */    XtInheritQueryGeometry,
  126.     /* display_accelerator*/    NULL,
  127.     /* extension      */    NULL
  128.   },{
  129.     /* Simple Menu Entry Fields */
  130.       
  131.     /* highlight */             Highlight,
  132.     /* unhighlight */           UnHighlight,
  133.     /* notify */        Notify,        
  134.     /* extension */             NULL                
  135.   },
  136.   {
  137.     /* extension */             NULL                
  138.   }
  139. };
  140.  
  141. WidgetClass ezMEObjectClass = (WidgetClass) &ezMEClassRec;
  142.  
  143. /************************************************************
  144.  *
  145.  * Semi-Public Functions.
  146.  *
  147.  ************************************************************/
  148.  
  149.  
  150. static void
  151. ClassInitialize()
  152. {
  153.   haveSubMenuTrans = XtParseTranslationTable( haveSubMenuTransString );
  154.   haveNoSubMenuTrans = XtParseTranslationTable( haveNoSubMenuTransString );
  155. }
  156.  
  157. /*      Function Name: Initialize
  158.  *      Description: Initializes the simple menu widget
  159.  *      Arguments: request - the widget requested by the argument list.
  160.  *                 new     - the new widget with both resource and non
  161.  *                           resource values.
  162.  *      Returns: none.
  163.  * 
  164.  * MENU ENTRIES CANNOT HAVE BORDERS.
  165.  */
  166.  
  167. #ifndef XtObjectParent
  168. #  define XtObjectParent(x) ( x -> object.parent )
  169. #endif
  170.  
  171. /* ARGSUSED */
  172. static void
  173. Initialize(request, new)
  174. Widget request, new;
  175. {
  176.   EzMEWidget r = (EzMEWidget) request;
  177.   EzMEWidget n = (EzMEWidget) new;
  178.  
  179.   n -> ezme.action = NULL;
  180.   if ( r -> ezme.action ) {
  181.     int len = strlen(r -> ezme.action);
  182.     n -> ezme.action = XtMalloc(len+1);
  183.     strcpy(n -> ezme.action, r -> ezme.action);
  184.   }
  185.  
  186. }
  187.  
  188. static void
  189. Destroy(w)
  190. Widget w;
  191. {
  192.   EzMEWidget n = (EzMEWidget) w;
  193.  
  194.   if ( n -> ezme.action ) {
  195.     XtFree( n -> ezme.action );
  196.   }
  197. }
  198.  
  199. static Boolean
  200. SetValues(current, request, new)
  201.      Widget current, request, new;
  202. {
  203.   EzMEWidget c = (EzMEWidget) current;
  204.   EzMEWidget r = (EzMEWidget) request;
  205.   EzMEWidget n = (EzMEWidget) new;
  206.  
  207.   if (( !c -> ezme.action && r -> ezme.action)
  208.       ||
  209.       (c ->ezme.action
  210.        && r -> ezme.action
  211.        && !strcmp(c->ezme.action, r -> ezme.action)))
  212.       {
  213.     int len = strlen(r -> ezme.action);
  214.     XtFree(c->ezme.action);
  215.     n -> ezme.action = XtMalloc(len+1);
  216.     strcpy(n -> ezme.action, r -> ezme.action);
  217.       }
  218. }
  219.  
  220. /*    Function Name: Notify
  221.  *    Description: calls the callback proceedures for this entry.
  222.  *    Arguments: w - the menu entry.
  223.  *    Returns: none.
  224.  */
  225.  
  226. #define SKIPWHITE(cp) while (cp && *cp && isspace(*cp)) cp++
  227.  
  228. static void
  229. Notify(w) 
  230. Widget w;
  231. {
  232.   EzMEWidget widget = (EzMEWidget) w;
  233.   Widget parent = XtObjectParent( widget );
  234.   
  235.   XtPopdown( parent );
  236.  
  237.   XtCallCallbacks(w, XtNcallback, NULL);
  238.   
  239.   if ( widget -> ezme.action ) {
  240.     char *action = widget -> ezme.action;
  241.     int actionLen = strlen( action );
  242.     
  243.     Bool doFree;
  244.     char stringCopy[1024];
  245.     char *allocatedStr;
  246.     char *str;
  247.     
  248.     char *actionProcName;
  249.     int num_params;
  250.     char *params[100];    /* lets hope they don't have more than that.. */
  251.     
  252.     if ( actionLen > 1023 ) {
  253.       allocatedStr = str = XtMalloc( actionLen + 2 );
  254.       doFree = True;
  255.     }
  256.     else {
  257.       str = stringCopy;
  258.       doFree = False;
  259.     }
  260.     
  261.     SKIPWHITE(str);
  262.     strcpy(str, action);
  263.     
  264.     for (;;) {
  265.       SKIPWHITE(str);
  266.       if ( str == 0 || *str == 0 ) break;
  267.  
  268.       /* skip to action procedure name */
  269.       SKIPWHITE(str);
  270.       actionProcName = str;
  271.       
  272.       /* find end of action procedure name- terminate by space or paren */
  273.       while (*str && !( isspace(*str) || *str == '(' )) str++;
  274.       /* terminate action procedure name string */
  275.       *(str++) = 0;
  276.       
  277.       /* skip past any openning paren, e.g. in case of 'foo (bar)' */
  278.  
  279.       SKIPWHITE(str);
  280.       if ( *str == '(') str++;
  281.       
  282.       /* now, scan to build a list of params */
  283.       num_params = 0;
  284.       while ( *str && *str != ')' && num_params < 100) {
  285.     SKIPWHITE(str);
  286.     params[num_params] = str;
  287.     /* gf: removed isspace(*str) from condition */
  288.     while (*str && !(*str == ',' || *str==')' )) {
  289.       if (*str == '\\') {
  290.         str++;
  291.         if ( *str == 0 ) str--;
  292.       }
  293.       str++;
  294.     }
  295.  
  296.     SKIPWHITE(str);
  297.  
  298.     /* terminate this parameter */
  299.     
  300.     num_params++;
  301.     if ( *str == 0 ) {
  302.       break;
  303.     } 
  304.     else if (*str == ')') {
  305.       *(str++) = 0;
  306.       break;
  307.     }
  308.     else {
  309.       *(str++) = 0;
  310.     }
  311.     
  312.     SKIPWHITE(str);
  313.       }
  314.  
  315.       SKIPWHITE(str);
  316.       if ( *str == ')') str++;
  317.       
  318.       /* gf: Pass object itself not XtObjectParent(widget) to action proc */
  319.       XtCallActionProc(widget,
  320.                actionProcName, NULL, params, num_params);
  321.     }
  322.     
  323.     if ( doFree ) {
  324.       XtFree( allocatedStr );
  325.     }
  326.   }
  327. }
  328.  
  329. static void
  330. Highlight(w, event, params, num_params)
  331. Widget w;
  332. XEvent * event;
  333. String * params;
  334. Cardinal * num_params;
  335. {
  336.   Arg argList[20];
  337.   int args = 0;
  338.   int root_x, root_y, child_x, child_y, buttons;
  339.   Dimension width;
  340.   Dimension height;
  341.   
  342.   EzMEWidget widget = (EzMEWidget) w;
  343.  
  344.   (*superclass -> sme_class.highlight) (w, event, params, num_params);
  345.   
  346.   if ( widget -> ezme.toPopUp ) {
  347.     Widget parent = XtObjectParent( widget );
  348.     Widget toPopUp = widget -> ezme.toPopUp;
  349.     
  350.     if ( toPopUp ) { 
  351.       
  352.       Window root, child;
  353.       Arg argList[20];
  354.       int args = 0;
  355.       int root_x, root_y, child_x, child_y, buttons;
  356.       Dimension width;
  357.       Dimension height;
  358.       
  359.       XQueryPointer(XtDisplay(parent),
  360.             XtWindow(parent), &root, &child,
  361.             &root_x, &root_y, &child_x, &child_y, &buttons);
  362.  
  363.       root_x -= 20;
  364.       root_y -= 20;    /* put the mouse solidly in the window */
  365.  
  366.       args = 0;
  367.       XtSetArg(argList[args], XtNtranslations, haveSubMenuTrans); args++;
  368.       XtSetValues(parent,argList,args);
  369.       
  370.       args = 0;
  371.       XtSetArg(argList[args], XtNx, root_x); args++;
  372.       XtSetArg(argList[args], XtNy, root_y); args++;
  373.       XtSetArg(argList[args], XtNtranslations, haveNoSubMenuTrans); args++;
  374.       XtSetValues(toPopUp,argList,args);
  375.       XtPopup(toPopUp, XtGrabExclusive);
  376.     }
  377.   }
  378. }
  379.  
  380. static void
  381. UnHighlight(w, event, params, num_params)
  382. Widget w;
  383. XEvent * event;
  384. String * params;
  385. Cardinal * num_params;
  386. {
  387.   Arg argList[20];
  388.   int args = 0;
  389.   int root_x, root_y, child_x, child_y, buttons;
  390.   Dimension width;
  391.   Dimension height;
  392.   
  393.   EzMEWidget widget = (EzMEWidget) w;
  394.  
  395.   (*superclass -> sme_class.unhighlight) (w, event, params, num_params);
  396.   
  397.   if ( widget -> ezme.toPopUp ) {
  398.     Widget parent = XtObjectParent( widget );
  399.  
  400.     args = 0;
  401.     XtSetArg(argList[args], XtNtranslations, haveNoSubMenuTrans); args++;
  402.     XtSetValues(parent,argList,args);
  403.  
  404.   }
  405. }
  406.