home *** CD-ROM | disk | FTP | other *** search
/ Education Sampler 1992 [NeXTSTEP] / Education_1992_Sampler.iso / Programming / Source / winterp-1.13 / src-server / w_txlations.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-10-04  |  14.4 KB  |  401 lines

  1. /* -*-C-*-
  2. ********************************************************************************
  3. *
  4. * File:         w_txlations.c
  5. * RCS:          $Header: w_txlations.c,v 1.3 91/03/14 03:14:20 mayer Exp $
  6. * Description:  Interfaces to Xtoolkit Translation Management Facilities
  7. * Author:       Niels Mayer, HPLabs
  8. * Created:      Wed Nov 22 02:08:31 1989
  9. * Modified:     Thu Oct  3 21:12:39 1991 (Niels Mayer) mayer@hplnpm
  10. * Language:     C
  11. * Package:      N/A
  12. * Status:       X11r5 contrib tape release
  13. *
  14. * WINTERP Copyright 1989, 1990, 1991 Hewlett-Packard Company (by Niels Mayer).
  15. * XLISP version 2.1, Copyright (c) 1989, by David Betz.
  16. *
  17. * Permission to use, copy, modify, distribute, and sell this software and its
  18. * documentation for any purpose is hereby granted without fee, provided that
  19. * the above copyright notice appear in all copies and that both that
  20. * copyright notice and this permission notice appear in supporting
  21. * documentation, and that the name of Hewlett-Packard and David Betz not be
  22. * used in advertising or publicity pertaining to distribution of the software
  23. * without specific, written prior permission.  Hewlett-Packard and David Betz
  24. * make no representations about the suitability of this software for any
  25. * purpose. It is provided "as is" without express or implied warranty.
  26. *
  27. * HEWLETT-PACKARD AND DAVID BETZ DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
  28. * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
  29. * IN NO EVENT SHALL HEWLETT-PACKARD NOR DAVID BETZ BE LIABLE FOR ANY SPECIAL,
  30. * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  31. * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  32. * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  33. * PERFORMANCE OF THIS SOFTWARE.
  34. *
  35. * See ./winterp/COPYRIGHT for information on contacting the authors.
  36. * Please send modifications, improvements and bugfixes to mayer@hplabs.hp.com
  37. * Post XLISP-specific questions/information to the newsgroup comp.lang.lisp.x
  38. **
  39. ********************************************************************************
  40. */
  41. static char rcs_identity[] = "@(#)$Header: w_txlations.c,v 1.3 91/03/14 03:14:20 mayer Exp $";
  42.  
  43. #include <stdio.h>
  44. #include <Xm/Xm.h>        /* Xm/Xm.h only needed for "winterp.h"*/
  45. #include "winterp.h"
  46. #include "user_prefs.h"
  47. #include "xlisp/xlisp.h"
  48.  
  49. extern Widget Wcls_Get_WIDGETOBJ_Argument_Returning_Validated_WidgetID(); /* w_classes.c */
  50.  
  51. static LVAL s_ACTION_WIDGET, s_ACTION_XEVENT, s_LISP_ACTION_PROC;
  52.  
  53.  
  54. /******************************************************************************
  55.  * Actions in winterp are added through this single action proc which will call
  56.  * the lisp evaluator upon invocation of this action.
  57.  *
  58.  * A translation/accelerator table using this proc may look like
  59.  * "<EnterWindow>: Lisp(lisp-function arg1 arg2 arg3)" in which case the
  60.  * form '(lisp-function arg1 arg2 arg3)' will be passed on to the evaluator.
  61.  *
  62.  * 
  63.  * In the lexical scope of the action invocation, ACTION_WIDGET gets bound  to
  64.  * the widget causing the action, and ACTION_XEVENT gets bound to the event.
  65.  *
  66.  * BUG: I haven't found a way of escaping characters passed on to the
  67.  * translation/action table parsers to allow lisp strings or lips lists to
  68.  * be passed on to the lisp evaluator that is called by this function. Using
  69.  * the evaluator through an action proc is still useful, just don't try to pass
  70.  * in very complex lisp forms.
  71.  * 
  72.  * NOTE: the action table for winterp is set in winterp.c.
  73.  ******************************************************************************/
  74. void Wtx_Winterp_Lisp_Action_Proc(widget, event, params, num_params)
  75.      Widget widget;
  76.      XEvent *event;
  77.      String *params;
  78.      Cardinal *num_params;
  79. {
  80.   register char c;
  81.   register LVAL new_elt, last_elt;
  82.   int param_count = *num_params;
  83.   char* par;            /* points to current parameter */
  84.   LVAL sexp_stream, parsed_sexp, oldenv;
  85.   CONTEXT cntxt;
  86.   extern LVAL Wcls_WidgetID_To_WIDGETOBJ(); /* w_classes.c */
  87.   extern LVAL xlenv;
  88.  
  89.   xlstkcheck(3);
  90.   xlsave(sexp_stream);
  91.   xlsave(parsed_sexp);
  92.   xlsave(oldenv);
  93.  
  94.   sexp_stream = newustream();    /* note - stream obj has ptrs for head and tail*/
  95.   last_elt = cons(cvchar('('), NIL); /* tack on an opening paren to beginning of form*/
  96.   sethead(sexp_stream, last_elt); /* make it the head of the stream */
  97.   
  98.   /* for each character in each param, append it onto sexp_stream */
  99.   while (param_count--) {    /* while there are more parameters */
  100.     par = *params++;        /* get current parameter string and increment to next */
  101.     while (c = *par++) {    /* go through each parameter char by char turning into a stream */
  102.       new_elt = cons(cvchar(c), NIL);
  103.       rplacd(last_elt, new_elt); /* add new elt to tail of list */
  104.       last_elt = new_elt;
  105.     }
  106.     new_elt = cons(cvchar(' '), NIL); /* put spaces between each param */
  107.     rplacd(last_elt, new_elt);
  108.     last_elt = new_elt;
  109.   }
  110.   new_elt = cons(cvchar(')'), NIL); /* tack on a closing paren to end of form */  
  111.   rplacd(last_elt, new_elt);
  112.   settail(sexp_stream, new_elt); /* streams are cdr-coded -- give ptr to tail */
  113.  
  114.   /*
  115.    * Most of the rest of this procedure looks alot like xleval.c:evfun(), which
  116.    * is what the evaluator calls when a functional form is to be evaluated. The
  117.    * main difference is that instead of calling xlabind() to bind the
  118.    * formal parameter symbols of a function to their values in the new
  119.    * lexical environment frame returned by xlframe(getenv(fun)), we 
  120.    * just bind ACTION_WIDGET and ACTION_XEVENT.
  121.    */
  122.  
  123.   /* create a new environment frame */
  124.   oldenv = xlenv;
  125.   xlenv = xlframe(xlenv);
  126.  
  127.   /* lexically bind ACTION_WIDGET and ACTION_EVENT to the widget/event that caused the callback */
  128.   xlpbind(s_ACTION_WIDGET, Wcls_WidgetID_To_WIDGETOBJ(widget), xlenv);
  129.   xlpbind(s_ACTION_XEVENT, (event) ? cv_xevent(event) : NIL, xlenv);
  130.  
  131.   /* setup the implicit block */
  132.   xlbegin(&cntxt, CF_RETURN, s_LISP_ACTION_PROC);
  133.   if (setjmp(cntxt.c_jmpbuf))
  134.     { }
  135.   else
  136.     if (xlread(sexp_stream, &parsed_sexp, FALSE)) /* if didn't hit EOF during read */
  137.       xleval(parsed_sexp);    /* then evaluate it -- we ignore evaluation result */
  138.  
  139.   xlend(&cntxt);
  140.  
  141.   /* restore the environment frame */
  142.   xlenv = oldenv;
  143.      
  144.   xlpopn(3);
  145. }
  146.  
  147.  
  148. /******************************************************************************
  149.  * (XT_PARSE_TRANSLATION_TABLE <string>)
  150.  * ==> returns a node of type XT_TRANSLATIONS, which is a compiled form of the
  151.  * <string> translation table given as argument.
  152.  *
  153.  * XtTranslations XtParseTranslationTable(source)
  154.  *     String source;
  155.  *
  156.  * NOTE: the memory allocated by XtParseTranslationTable() isn't freed anywhere
  157.  * yet -- I can't find  any documentation that says you're supposed to free
  158.  * this. For now this may be a memory leak.
  159.  ******************************************************************************/
  160. LVAL Wtx_Prim_XT_PARSE_TRANSLATION_TABLE()
  161. {
  162.   XtTranslations txl;
  163.   char* source = (char*) getstring(xlgastring());
  164.   xllastarg();
  165.   
  166.   txl = XtParseTranslationTable(source);
  167.  
  168.   return ( (txl) ? cv_xttranslations(txl) : NIL );
  169. }
  170.  
  171. /******************************************************************************
  172.  * (XT_PARSE_ACCELERATOR_TABLE <string>)
  173.  * ==> returns a node of type XT_ACCELERATORS, which is a compiled form of the
  174.  * <string> accelerator table given as argument.
  175.  *
  176.  * XtAccelerators XtParseAcceleratorTable (source)
  177.  *     String   source;
  178.  *
  179.  * NOTE: the memory allocated by XtParseAcceleratorTable() isn't freed anywhere
  180.  * yet -- I can't find  any documentation that says you're supposed to free
  181.  * this. For now this may be a memory leak.
  182.  ******************************************************************************/
  183. LVAL Wtx_Prim_XT_PARSE_ACCELERATOR_TABLE()
  184. {
  185.   XtAccelerators axl;
  186.   char* source = (char*) getstring(xlgastring());
  187.   xllastarg();
  188.   
  189.   axl = XtParseAcceleratorTable(source);
  190.  
  191.   return ( (axl) ? cv_xtaccelerators(axl) : NIL );
  192. }
  193.  
  194.  
  195. /******************************************************************************
  196.  * (send <widget> :OVERRIDE_TRANSLATIONS <translations>)
  197.  * ==> returns <widget>
  198.  * 
  199.  * This method destructively merges the new <translations> into <widget>'s
  200.  * existing translations -- event sequences in <translations> that already exist
  201.  * a previous translation will override.
  202.  *
  203.  * <translations> can be a string, in which case it
  204.  * is compiled into a translation table. Otherwise, we expect a node of
  205.  * type XT_TRANSLATIONS.
  206.  *
  207.  * void XtOverrideTranslations(widget, new)
  208.  *     Widget widget;
  209.  *     XtTranslations new;
  210.  ******************************************************************************/
  211. LVAL Widget_Class_Method_OVERRIDE_TRANSLATIONS()
  212. {
  213.   LVAL self, lval_txl;
  214.   Widget widget_id;
  215.   XtTranslations txl;
  216.  
  217.   widget_id = Wcls_Get_WIDGETOBJ_Argument_Returning_Validated_WidgetID(&self);
  218.   lval_txl = xlgetarg();
  219.   xllastarg();
  220.   
  221.   if (stringp(lval_txl))
  222.     txl = XtParseTranslationTable((char*) getstring(lval_txl));
  223.   else if (xttranslations_p(lval_txl))
  224.     txl = get_xttranslations(lval_txl);
  225.   else
  226.     xlerror("Bad argument type -- expected a string or XT_TRANSLATIONS.", lval_txl);
  227.  
  228.   XtOverrideTranslations(widget_id, txl);
  229.   return (self);
  230. }
  231.  
  232. /******************************************************************************
  233.  * (send <widget> :AUGMENT_TRANSLATIONS <translations>) 
  234.  * ==> returns <widget>.
  235.  *
  236.  * This method nondestructively merges the new <translations> into <widget>'s
  237.  * existing translations -- event sequences in <translations> that already exist
  238.  * a previous translation will be ignored.
  239.  *
  240.  * <translations> can be a string, in which case it
  241.  * is compiled into a translation table. Otherwise, we expect a node of
  242.  * type XT_TRANSLATIONS.
  243.  *
  244.  * void XtAugmentTranslations(widget, new)
  245.  *     Widget widget;
  246.  *     XtTranslations new;
  247.  ******************************************************************************/
  248. LVAL Widget_Class_Method_AUGMENT_TRANSLATIONS()
  249. {
  250.   LVAL self, lval_txl;
  251.   Widget widget_id;
  252.   XtTranslations txl;
  253.  
  254.   widget_id = Wcls_Get_WIDGETOBJ_Argument_Returning_Validated_WidgetID(&self);
  255.   lval_txl = xlgetarg();
  256.   xllastarg();
  257.   
  258.   if (stringp(lval_txl))
  259.     txl = XtParseTranslationTable((char*) getstring(lval_txl));
  260.   else if (xttranslations_p(lval_txl))
  261.     txl = get_xttranslations(lval_txl);
  262.   else
  263.     xlerror("Bad argument type -- expected a string or XT_TRANSLATIONS.", lval_txl);
  264.  
  265.   XtAugmentTranslations(widget_id, txl);
  266.   return (self);
  267. }
  268.  
  269. /******************************************************************************
  270.  * (send <widget> :UNINSTALL_TRANSLATIONS)
  271.  * ==>  returns <widget>
  272.  *
  273.  * This method removes all translations from <widget>.
  274.  *
  275.  * void XtUninstallTranslations(widget)
  276.  *     Widget widget;
  277.  ******************************************************************************/
  278. LVAL Widget_Class_Method_UNINSTALL_TRANSLATIONS()
  279. {
  280.   LVAL self;
  281.   Widget widget_id;
  282.  
  283.   widget_id = Wcls_Get_WIDGETOBJ_Argument_Returning_Validated_WidgetID(&self);
  284.   xllastarg();
  285.   
  286.   XtUninstallTranslations(widget_id);
  287.   return (self);
  288. }
  289.  
  290. /******************************************************************************
  291.  * (send <destination> :INSTALL_ACCELERATORS <source>)
  292.  * ==>  returns <destination>
  293.  * 
  294.  * This method installs the accelerators from widget <source> onto widget
  295.  * <destination> by augmenting the destination translations with the source
  296.  * accelerators.
  297.  * 
  298.  * void XtInstallAccelerators(destination,source)
  299.  *     Widget destination,source;
  300.  ******************************************************************************/
  301. LVAL Widget_Class_Method_INSTALL_ACCELERATORS()
  302. {
  303.   LVAL self, lval_src;
  304.   Widget widget_id, src;
  305.  
  306.   widget_id = Wcls_Get_WIDGETOBJ_Argument_Returning_Validated_WidgetID(&self);
  307.   src = Wcls_Get_WIDGETOBJ_Argument_Returning_Validated_WidgetID(&lval_src);
  308.   xllastarg();
  309.   
  310.   XtInstallAccelerators(widget_id, src);
  311.   return (self);
  312. }
  313.  
  314.  
  315. /******************************************************************************
  316.  * (send <destination> :INSTALL_ALL_ACCELERATORS <source>)
  317.  * ==>  returns <destination>
  318.  * 
  319.  * This method installs the accelerators from widget <source> and all it's 
  320.  * children onto widget <destination> by augmenting the destination translations
  321.  * with the source accelerators.
  322.  *
  323.  * void XtInstallAllAccelerators(destination,source)
  324.  *    Widget destination,source;
  325.  ******************************************************************************/
  326. LVAL Widget_Class_Method_INSTALL_ALL_ACCELERATORS()
  327. {
  328.   LVAL self, lval_src;
  329.   Widget widget_id, src;
  330.  
  331.   widget_id = Wcls_Get_WIDGETOBJ_Argument_Returning_Validated_WidgetID(&self);
  332.   src = Wcls_Get_WIDGETOBJ_Argument_Returning_Validated_WidgetID(&lval_src);
  333.   xllastarg();
  334.   
  335.   XtInstallAllAccelerators(widget_id, src);
  336.   return (self);
  337. }
  338.  
  339.  
  340. #ifdef WINTERP_MOTIF_11
  341. /******************************************************************************
  342.  * (send <widget> :CALL_ACTION_PROC <action> <event> [<param0> [<param1> [...] ]])
  343.  * ==>  returns <widget>
  344.  * 
  345.  *
  346.  * void XtCallActionProc(Widget        -* widget *-,
  347.  *             CONST String    -* action *-,
  348.  *             XEvent*    -* event *-,
  349.  *             String*    -* params *-,
  350.  *             Cardinal    -* num_params *-);
  351.  ******************************************************************************/
  352. LVAL Widget_Class_Method_CALL_ACTION_PROC()
  353. {
  354. #define PARAMS_SIZE_INCREMENT 5
  355.   LVAL self;
  356.   Widget widget_id;
  357.   String action;
  358.   XEvent* event;
  359.   String* params;
  360.   Cardinal num_params = 0;
  361.   Cardinal params_size;
  362.  
  363.   widget_id = Wcls_Get_WIDGETOBJ_Argument_Returning_Validated_WidgetID(&self); /* get <widget> */
  364.   action = (String) getstring(xlgastring()); /* get <action> */
  365.   event = get_xevent(xlga_xevent()); /* get <xevent> */
  366.  
  367.   /* get optional  [<param0> [<param1> [...] ]] */
  368.   if (moreargs()) {
  369.     params_size = PARAMS_SIZE_INCREMENT;
  370.     params = (String*) XtMalloc((unsigned) (params_size * sizeof(String)));
  371.     while (moreargs()) {
  372.       if (num_params >= params_size) { /* make sure it'll fit into allocated table */
  373.     params_size += PARAMS_SIZE_INCREMENT;
  374.     params = (String*) XtRealloc(params, (unsigned) (params_size * sizeof(String)));
  375.       }
  376.       params[num_params++] = (String) getstring(xlgastring());
  377.     }
  378.   }
  379.   xllastarg();
  380.   
  381.   XtCallActionProc(widget_id, action, event, params, num_params);
  382.  
  383.   if (num_params)
  384.     XtFree(params);
  385.   return (self);
  386. #undef PARAMS_SIZE_INCREMENT
  387. }
  388. #endif /* WINTERP_MOTIF_11 */
  389.  
  390.  
  391. /******************************************************************************
  392.  *
  393.  ******************************************************************************/
  394. Wtx_Init()
  395. {
  396.   s_ACTION_WIDGET = xlenter("ACTION_WIDGET");
  397.   s_ACTION_XEVENT = xlenter("ACTION_XEVENT");
  398.   s_LISP_ACTION_PROC = xlenter("LISP_ACTION_PROC");
  399. }
  400.