home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / X / mit / extensions / lib / PEX / input / sin.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-05-31  |  12.3 KB  |  398 lines

  1. /* $XConsortium: sin.c,v 5.1 91/02/16 09:49:38 rws Exp $ */
  2.  
  3. /***********************************************************
  4. Copyright 1989, 1990, 1991 by Sun Microsystems, Inc. and the X Consortium.
  5.  
  6.                         All Rights Reserved
  7.  
  8. Permission to use, copy, modify, and distribute this software and its 
  9. documentation for any purpose and without fee is hereby granted, 
  10. provided that the above copyright notice appear in all copies and that
  11. both that copyright notice and this permission notice appear in 
  12. supporting documentation, and that the names of Sun Microsystems,
  13. the X Consortium, and MIT not be used in advertising or publicity 
  14. pertaining to distribution of the software without specific, written 
  15. prior permission.  
  16.  
  17. SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 
  18. INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT 
  19. SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL 
  20. DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  21. WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  22. ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  23. SOFTWARE.
  24.  
  25. ******************************************************************/
  26.  
  27. /*
  28.  *    Top level routines for the SIN package.
  29.  */
  30.  
  31. #include "phg.h"
  32. #include "cp.h"
  33. #include "ws.h"
  34. #include "sin.h"
  35. #include "sin_priv.h"
  36. #include "alloc.h"
  37.  
  38. void
  39. phg_sin_close( iws )
  40.     Sin_input_ws     *iws;
  41. {
  42.     register int        i;
  43.  
  44.     phg_sin_dev_stop( iws );
  45.     phg_sin_ws_close_event_buf( iws );
  46.     phg_sin_dev_destroy_devices( iws );
  47.     phg_sin_cvs_close( iws );
  48.     for ( i = 0; i < 6; i++)
  49.     free( (char *)iws->devices[i] );
  50.     phg_sin_ws_free_notify_list( iws );
  51.     free((char *)iws);
  52. }
  53.  
  54. Sin_handle
  55. phg_sin_create( desc, erh )
  56.     Sin_desc        *desc;
  57.     Err_handle        erh;
  58. {
  59.     register Sin_input_ws    *iws;
  60.     Pint            err = ERR900;
  61.     ALLOC_DECLARE(20);
  62.  
  63.     if (!ALLOCATED( iws = (Sin_input_ws*)calloc( (unsigned)1,
  64.         sizeof(Sin_input_ws))) )
  65.     goto no_mem;
  66.     iws->erh = erh;
  67.     iws->queue = desc->queue;
  68.     iws->display = desc->display;
  69.     iws->output_window = desc->output_window;
  70.     iws->input_window = desc->input_window;
  71.     iws->shell = desc->shell;
  72.     iws->wsh = desc->wsh;
  73.     iws->ops.send_request = desc->send_request;
  74.     iws->ops.in_viewport = desc->in_viewport;
  75.  
  76.     iws->wsid = desc->wsh->id;
  77.     iws->idt = desc->idt;
  78.     iws->num_devs = desc->idt->num_devs;
  79.     if ( iws->num_devs.loc > 0)
  80.     if (!ALLOCATED(
  81.         iws->devices[SIN_CLASS_INDEX(SIN_LOCATOR)] = (Sin_input_device*)
  82.         calloc( (unsigned)iws->num_devs.loc, sizeof(Sin_input_device))))
  83.         goto no_mem;
  84.     if ( iws->num_devs.stroke > 0)
  85.     if (!ALLOCATED(
  86.         iws->devices[SIN_CLASS_INDEX(SIN_STROKE)] = (Sin_input_device*)
  87.         calloc( (unsigned)iws->num_devs.stroke, sizeof(Sin_input_device))))
  88.         goto no_mem;
  89.     if ( iws->num_devs.pick > 0)
  90.     if (!ALLOCATED(
  91.         iws->devices[SIN_CLASS_INDEX(SIN_PICK)] = (Sin_input_device*)
  92.         calloc( (unsigned)iws->num_devs.pick, sizeof(Sin_input_device))))
  93.         goto no_mem;
  94.     if ( iws->num_devs.val > 0)
  95.     if (!ALLOCATED(
  96.         iws->devices[SIN_CLASS_INDEX(SIN_VALUATOR)] = (Sin_input_device*)
  97.         calloc((unsigned)iws->num_devs.val, sizeof(Sin_input_device))))
  98.         goto no_mem;
  99.     if ( iws->num_devs.choice > 0)
  100.     if (!ALLOCATED(
  101.         iws->devices[SIN_CLASS_INDEX(SIN_CHOICE)] = (Sin_input_device*)
  102.         calloc( (unsigned)iws->num_devs.choice, sizeof(Sin_input_device))))
  103.         goto no_mem;
  104.     if ( iws->num_devs.string > 0)
  105.     if (!ALLOCATED(
  106.         iws->devices[SIN_CLASS_INDEX(SIN_STRING)] = (Sin_input_device*)
  107.         calloc( (unsigned)iws->num_devs.string, sizeof(Sin_input_device))))
  108.         goto no_mem;
  109.  
  110.     phg_sin_dev_init_devices( iws );
  111.     SIN_DISABLE_BREAK(iws);
  112.     if ( !phg_sin_ws_event_buf_init( iws ) )
  113.     goto no_mem;
  114.  
  115.     if ( !(iws->window_table = phg_sin_cvs_init( iws )) ) {
  116.     phg_sin_ws_close_event_buf( iws );
  117.     goto no_mem;
  118.     }
  119.  
  120.     if ( !phg_sin_dev_create_devices( iws ) ) {
  121.     phg_sin_ws_close_event_buf( iws );
  122.     phg_sin_cvs_close( iws );
  123.     goto no_mem;
  124.     }
  125.  
  126.     if ( !phg_sin_dev_start( iws ) ) {
  127.     phg_sin_ws_close_event_buf( iws );
  128.     phg_sin_dev_destroy_devices( iws );
  129.     phg_sin_cvs_close( iws );
  130.     goto no_mem;
  131.     }
  132.  
  133.     return((Sin_handle)iws);
  134.  
  135. no_mem:
  136.     ALLOC_FREE;
  137.     ERR_BUF( erh, err);
  138.     iws->devices[SIN_CLASS_INDEX(SIN_LOCATOR)] = (Sin_input_device*)    NULL;
  139.     iws->devices[SIN_CLASS_INDEX(SIN_STROKE)] = (Sin_input_device*)    NULL;
  140.     iws->devices[SIN_CLASS_INDEX(SIN_PICK)] = (Sin_input_device*)    NULL;
  141.     iws->devices[SIN_CLASS_INDEX(SIN_VALUATOR)] = (Sin_input_device*)    NULL;
  142.     iws->devices[SIN_CLASS_INDEX(SIN_CHOICE)] = (Sin_input_device*)    NULL;
  143.     iws->devices[SIN_CLASS_INDEX(SIN_STRING)] = (Sin_input_device*)    NULL;
  144.     return ((Sin_handle)NULL);
  145. }
  146.  
  147. #define SIN_COPY_LOC_INIT_DATA( _o, _n ) \
  148.     { \
  149.     (_n)->data.locator.cur_pos        = (_o)->data.locator.cur_pos; \
  150.     (_n)->data.locator.init_pos     = (_o)->data.locator.init_pos; \
  151.     (_n)->data.locator.wc_pt        = (_o)->data.locator.wc_pt; \
  152.     (_n)->data.locator.view        = (_o)->data.locator.view; \
  153.     (_n)->data.locator.resolve        = (_o)->data.locator.resolve; \
  154.     (_n)->data.locator.ln_bundl        = (_o)->data.locator.ln_bundl; \
  155.     }
  156.  
  157. #define SIN_COPY_PICK_INIT_DATA( _o, _n ) \
  158.     { \
  159.     (_n)->data.pick.init_pos         = (_o)->data.pick.init_pos; \
  160.     (_n)->data.pick.cur_pos        = (_o)->data.pick.cur_pos; \
  161.     (_n)->data.pick.init_pick        = (_o)->data.pick.init_pick; \
  162.     (_n)->data.pick.cur_pick        = (_o)->data.pick.cur_pick; \
  163.     (_n)->data.pick.client_data        = (_o)->data.pick.client_data; \
  164.     (_n)->data.pick.resolve        = (_o)->data.pick.resolve; \
  165.     }
  166.  
  167. #define SIN_COPY_CHOICE_INIT_DATA( _o, _n ) \
  168.     { \
  169.     (_n)->data.choice.init_choice    = (_o)->data.choice.init_choice; \
  170.     (_n)->data.choice.cur_choice    = (_o)->data.choice.cur_choice; \
  171.     }
  172.  
  173. #define SIN_COPY_VAL_INIT_DATA( _o, _n ) \
  174.     { \
  175.     (_n)->data.valuator.init_value    = (_o)->data.valuator.init_value; \
  176.     (_n)->data.valuator.low        = (_o)->data.valuator.low; \
  177.     (_n)->data.valuator.high        = (_o)->data.valuator.high; \
  178.     (_n)->data.valuator.label        = (_o)->data.valuator.label; \
  179.     (_n)->data.valuator.format        = (_o)->data.valuator.format; \
  180.     (_n)->data.valuator.low_label    = (_o)->data.valuator.low_label; \
  181.     (_n)->data.valuator.high_label    = (_o)->data.valuator.high_label; \
  182.     }
  183.  
  184. void
  185. phg_sin_init_device( iws, class, dev_num, new_data )
  186.     Sin_input_ws    *iws;
  187.     Sin_input_class    class;
  188.     int            dev_num;
  189.     Sin_dev_init_data    *new_data;
  190. {
  191.     Sin_input_device    *dev = SIN_DEV(iws, class, dev_num);
  192.  
  193.     if ( !dev->flags.exists )
  194.     return;
  195.  
  196.     /* Do anything that affects the whole workstation. */
  197.     /* nothing to do right now */
  198.  
  199.     /* Do the device specific stuff. */
  200.     if ( dev->dev_ops.init ) {
  201.     (dev->dev_ops.init)( dev, new_data );
  202.     }
  203.  
  204.     /* Update the Sin internal state. */
  205.     dev->client_data = new_data->client_data;
  206.     dev->pe_type = new_data->pe_type;
  207.     dev->echo_area = new_data->echo_area;
  208.     switch ( dev->class) {
  209.         case SIN_LOCATOR:
  210.         SIN_COPY_LOC_INIT_DATA( new_data, dev)
  211.             break;
  212.     case SIN_STROKE: {
  213.         /* Allocate room for request and sample event. */
  214.         /* TODO: detect allocation failure and free this at ws close. */
  215.         Ppoint3        *wc_pts;
  216.         if ( dev->data.stroke.buf_size < new_data->data.stroke.buf_size) {
  217.         if ( dev->data.stroke.wc_pts )
  218.             free( (char *)dev->data.stroke.wc_pts);
  219.         wc_pts = (Ppoint3*)
  220.             Malloc(new_data->data.stroke.buf_size * sizeof(Ppoint3));
  221.         } else
  222.         wc_pts = dev->data.stroke.wc_pts;
  223.  
  224.         if ( dev->data.stroke.init_pts )
  225.         free( (char *)dev->data.stroke.init_pts);
  226.         /* TODO: Make a macro to only copy the relevant fields. */
  227.         dev->data = new_data->data;
  228.         dev->data.stroke.wc_pts = wc_pts;
  229.         if ( new_data->data.stroke.count > 0 )
  230.         bcopy( new_data->data.stroke.wc_pts, wc_pts,
  231.             new_data->data.stroke.count * sizeof(Ppoint3) );
  232.             } break;
  233.     case SIN_VALUATOR:
  234.         SIN_COPY_VAL_INIT_DATA( new_data, dev)
  235.             dev->data.valuator.value = dev->data.valuator.init_value;
  236.         break;
  237.     case SIN_CHOICE:
  238.         SIN_COPY_CHOICE_INIT_DATA( new_data, dev)
  239.             dev->data.choice.cur_choice = dev->data.choice.init_choice;
  240.         switch ( dev->pe_type ) {
  241.         case 1:
  242.         case 3:
  243.             dev->data.choice.count = new_data->data.choice.count;
  244.             dev->data.choice.choices.strings =
  245.             new_data->data.choice.choices.strings;
  246.             break;
  247.         }
  248.         break;
  249.     case SIN_STRING: {
  250.         /* Allocate buffer. */
  251.         /* TODO: detect allocation failure and free this at ws close. */
  252.         char    *str;
  253.  
  254.         if ( dev->data.string.buf_size < new_data->data.string.buf_size) {
  255.         if ( dev->data.string.string )
  256.             free( dev->data.string.string);
  257.         str = Malloc(new_data->data.string.buf_size);
  258.         } else
  259.         str = dev->data.string.string;
  260.         dev->data = new_data->data;
  261.         dev->data.string.string = str;
  262.         } break;
  263.     case SIN_PICK:
  264.         SIN_COPY_PICK_INIT_DATA(new_data, dev)
  265.         break;
  266.     }
  267. }
  268.  
  269. void
  270. phg_sin_set_mode( iws, md, ed )
  271.     Sin_input_ws    *iws;
  272.     Sin_set_mode_data    *md;
  273.     Sin_enable_data    *ed;
  274. {
  275.     register Sin_input_device    *dev = SIN_DEV(iws, md->class, md->dev_num);
  276.  
  277.     if ( !dev->flags.exists )
  278.     return;
  279.  
  280.     /* Turn old device off if it's on. */
  281.     if ( dev->flags.on ) {
  282.     phg_sin_ws_disable_device( dev);
  283.         /* Allow the cancellation of REQUEST_PENDING. */
  284.         if ( dev->mode == SIN_REQUEST_PENDING ) {
  285.             dev->mode = SIN_REQUEST;
  286.             SIN_DISABLE_BREAK(dev->ws);
  287.         }
  288.     }
  289.  
  290.     dev->mode = md->mode;
  291.     dev->echo_sw = md->echo;
  292.     SIN_SET_ENABLE_DATA(dev, ed)
  293.  
  294.     /* turn device on if usable */
  295.     if ( dev->mode == SIN_EVENT || dev->mode == SIN_SAMPLE ) {
  296.     phg_sin_ws_reset_device( dev );
  297.     phg_sin_ws_enable_device( dev );
  298.     }
  299. }
  300.  
  301. void
  302. phg_sin_sample( iws, class, dev_num, event )
  303.     Sin_input_ws    *iws;
  304.     Sin_input_class    class;
  305.     int            dev_num;
  306.     Sin_input_event    *event;
  307. {
  308.     register Sin_input_device    *dev = SIN_DEV(iws, class, dev_num);
  309.  
  310.     if ( !dev->flags.exists )
  311.     return;
  312.  
  313.     if ( dev->dev_ops.sample ) {
  314.     (dev->dev_ops.sample)( dev );
  315.     }
  316.     phg_sin_ws_load_event( dev, event );
  317. }
  318.  
  319. void
  320. phg_sin_request( iws, class, dev_num, ed )
  321.     Sin_input_ws    *iws;
  322.     Sin_input_class    class;
  323.     int            dev_num;
  324.     Sin_enable_data    *ed;
  325. {
  326.     register Sin_input_device    *dev = SIN_DEV(iws, class, dev_num);
  327.  
  328.     if ( !dev->flags.exists )
  329.     return;
  330.  
  331.     SIN_SET_ENABLE_DATA(dev, ed)
  332.     dev->mode = SIN_REQUEST_PENDING;
  333.     SIN_ENABLE_BREAK(dev);
  334.     phg_sin_ws_reset_device( dev );
  335.     phg_sin_ws_enable_device( dev );
  336. }
  337.  
  338. void
  339. phg_sin_repaint( iws, num_rects, rects )
  340.     Sin_input_ws    *iws;
  341.     int            num_rects;
  342.     XRectangle        *rects;
  343. {
  344.     register Sin_input_device    *dev;
  345.     register int        i;
  346.  
  347.     /* Only repaint active devices. */
  348.  
  349.     dev = iws->devices[SIN_CLASS_INDEX(SIN_LOCATOR)];
  350.     for ( i = 0; i < iws->num_devs.loc; i++, dev++ ) {
  351.     if ( dev->flags.on && dev->dev_ops.repaint )
  352.         (dev->dev_ops.repaint)( dev, num_rects, rects );
  353.     }
  354.     dev = iws->devices[SIN_CLASS_INDEX(SIN_STROKE)];
  355.     for ( i = 0; i < iws->num_devs.stroke; i++, dev++ ) {
  356.     if ( dev->flags.on && dev->dev_ops.repaint )
  357.         (dev->dev_ops.repaint)( dev, num_rects, rects );
  358.     }
  359.     dev = iws->devices[SIN_CLASS_INDEX(SIN_PICK)];
  360.     for ( i = 0; i < iws->num_devs.pick; i++, dev++ ) {
  361.     if ( dev->flags.on && dev->dev_ops.repaint )
  362.         (dev->dev_ops.repaint)( dev, num_rects, rects );
  363.     }
  364.     dev = iws->devices[SIN_CLASS_INDEX(SIN_CHOICE)];
  365.     for ( i = 0; i < iws->num_devs.choice; i++, dev++ ) {
  366.     if ( dev->flags.on && dev->dev_ops.repaint )
  367.         (dev->dev_ops.repaint)( dev, num_rects, rects );
  368.     }
  369.     dev = iws->devices[SIN_CLASS_INDEX(SIN_VALUATOR)];
  370.     for ( i = 0; i < iws->num_devs.val; i++, dev++ ) {
  371.     if ( dev->flags.on && dev->dev_ops.repaint )
  372.         (dev->dev_ops.repaint)( dev, num_rects, rects );
  373.     }
  374.     dev = iws->devices[SIN_CLASS_INDEX(SIN_STRING)];
  375.     for ( i = 0; i < iws->num_devs.string; i++, dev++ ) {
  376.     if ( dev->flags.on && dev->dev_ops.repaint )
  377.         (dev->dev_ops.repaint)( dev, num_rects, rects );
  378.     }
  379. }
  380.  
  381. void
  382. phg_sin_resize_dev( ws, class, dev_num, ed, old_rect, new_rect )
  383.     Sin_input_ws        *ws;
  384.     Sin_input_class        class;
  385.     int                dev_num;
  386.     register Sin_enable_data    *ed;
  387.     XRectangle            *old_rect;
  388.     XRectangle            *new_rect;
  389. {
  390.     register Sin_input_device    *dev = SIN_DEV( ws, class, dev_num);
  391.  
  392.     if ( dev->flags.on ) {
  393.     SIN_SET_ENABLE_DATA( dev, ed)
  394.     if ( dev->dev_ops.resize )
  395.         (dev->dev_ops.resize)( dev, old_rect, new_rect );
  396.     }
  397. }
  398.