home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / X / mit / extensions / lib / PEXlib / pl_sc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-08-26  |  11.1 KB  |  490 lines

  1. /* $XConsortium: pl_sc.c,v 1.7 92/08/26 13:06:21 mor Exp $ */
  2.  
  3. /******************************************************************************
  4. Copyright 1987,1991 by Digital Equipment Corporation, Maynard, Massachusetts
  5. Copyright 1992 by ShoGraphics, Inc., Mountain View, California
  6. Copyright 1992 by the Massachusetts Institute of Technology
  7.  
  8.                         All Rights Reserved
  9.  
  10. Permission to use, copy, modify, distribute, and sell this software and its
  11. documentation for any purpose is hereby granted without fee, provided that
  12. the above copyright notice appear in all copies and that both that copyright
  13. notice and this permission notice appear in supporting documentation, and that
  14. the name of Digital, ShowGraphics, or M.I.T. not be used in advertising or
  15. publicity pertaining to distribution of the software without specific, written
  16. prior permission.  Digital, ShowGraphics, and M.I.T. make no representations
  17. about the suitability of this software for any purpose.  It is provided "as is"
  18. without express or implied warranty.
  19.  
  20. DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  21. ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  22. DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  23. ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  24. WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  25. ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  26. SOFTWARE.
  27.  
  28. SHOGRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  29. ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  30. SHOGRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  31. ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  32. WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  33. ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  34. SOFTWARE.
  35. *************************************************************************/
  36.  
  37. #include "PEXlib.h"
  38. #include "PEXlibint.h"
  39.  
  40. static void _PEXGenerateSCList();
  41.  
  42.  
  43. PEXSearchContext
  44. PEXCreateSearchContext (display, valueMask, values)
  45.  
  46. INPUT Display        *display;
  47. INPUT unsigned long    valueMask;
  48. INPUT PEXSCAttributes    *values;
  49.  
  50. {
  51.     pexCreateSearchContextReq    *req;
  52.     PEXSearchContext        id;
  53.     int                convertFP;
  54.  
  55.  
  56.     /*
  57.      * Get a search context resource id from X.
  58.      */
  59.  
  60.     id = XAllocID (display);
  61.  
  62.  
  63.     /*
  64.      * Lock around the critical section, for multithreading.
  65.      */
  66.  
  67.     LockDisplay (display);
  68.  
  69.  
  70.     /*
  71.      * Put the request in the X request buffer.
  72.      */
  73.  
  74.     PEXGetFPReq (CreateSearchContext, req, convertFP);
  75.     req->sc = id;
  76.     req->itemMask = valueMask;
  77.  
  78.     _PEXGenerateSCList (display, (pexReq *) req, valueMask, values);
  79.  
  80.  
  81.     /*
  82.      * Done, so unlock and check for synchronous-ness.
  83.      */
  84.  
  85.     UnlockDisplay (display);
  86.     PEXSyncHandle (display);
  87.  
  88.     return (id);
  89. }
  90.  
  91.  
  92. void
  93. PEXFreeSearchContext (display, sc)
  94.  
  95. INPUT Display        *display;
  96. INPUT PEXSearchContext    sc;
  97.  
  98. {
  99.     pexFreeSearchContextReq    *req;
  100.  
  101.  
  102.     /*
  103.      * Lock around the critical section, for multithreading.
  104.      */
  105.  
  106.     LockDisplay (display);
  107.  
  108.  
  109.     /*
  110.      * Put the request in the X request buffer.
  111.      */
  112.  
  113.     PEXGetReq (FreeSearchContext, req);
  114.     req->id = sc;
  115.  
  116.  
  117.     /*
  118.      * Done, so unlock and check for synchronous-ness.
  119.      */
  120.  
  121.     UnlockDisplay (display);
  122.     PEXSyncHandle (display);
  123. }
  124.  
  125.  
  126. void
  127. PEXCopySearchContext (display, valueMask, srcSc, destSc)
  128.  
  129. INPUT Display        *display;
  130. INPUT unsigned long    valueMask;
  131. INPUT PEXSearchContext    srcSc;
  132. INPUT PEXSearchContext    destSc;
  133.  
  134. {
  135.     pexCopySearchContextReq    *req;
  136.  
  137.  
  138.     /*
  139.      * Lock around the critical section, for multithreading.
  140.      */
  141.  
  142.     LockDisplay (display);
  143.  
  144.  
  145.     /*
  146.      * Put the request in the X request buffer.
  147.      */
  148.  
  149.     PEXGetReq (CopySearchContext, req);
  150.     req->src = srcSc;
  151.     req->dst = destSc;
  152.     req->itemMask = valueMask;
  153.  
  154.  
  155.     /*
  156.      * Done, so unlock and check for synchronous-ness.
  157.      */
  158.  
  159.     UnlockDisplay (display);
  160.     PEXSyncHandle (display);
  161. }
  162.  
  163.  
  164. PEXSCAttributes *
  165. PEXGetSearchContext (display, sc, valueMask)
  166.  
  167. INPUT Display        *display;
  168. INPUT PEXSearchContext    sc;
  169. INPUT unsigned long    valueMask;
  170.  
  171. {
  172.     pexGetSearchContextReply    rep;
  173.     pexGetSearchContextReq    *req;
  174.     PEXSCAttributes        *scattr;
  175.     unsigned long        *pv, f;
  176.     int                tmp, i;
  177.     int                convertFP;
  178.  
  179.  
  180.     /*
  181.      * Lock around the critical section, for multithreading.
  182.      */
  183.  
  184.     LockDisplay (display);
  185.  
  186.  
  187.     /*
  188.      * Put the request in the X request buffer and get a reply.
  189.      */
  190.  
  191.     PEXGetFPReq (GetSearchContext, req, convertFP);
  192.     req->sc = sc;
  193.     req->itemMask = valueMask;
  194.  
  195.     if (_XReply (display, &rep, 0, xFalse) == 0)
  196.     {
  197.     UnlockDisplay (display);
  198.       PEXSyncHandle (display);
  199.      return (NULL);               /* return an error */
  200.     }
  201.  
  202.  
  203.     /*
  204.      * Allocate a scratch buffer and copy the reply data to the buffer.
  205.      */
  206.  
  207.     pv = (unsigned long *) _XAllocScratch (display,
  208.     (unsigned long) (rep.length << 2));
  209.  
  210.     _XRead (display, (char *) pv, (long) (rep.length << 2));
  211.  
  212.  
  213.     /*
  214.      * Allocate a buffer for the replies to pass back to the client.
  215.      */
  216.  
  217.     scattr = (PEXSCAttributes *)
  218.     PEXAllocBuf ((unsigned) (sizeof (PEXSCAttributes)));
  219.  
  220.     scattr->start_path.count = 0;
  221.     scattr->start_path.elements = NULL;
  222.     scattr->normal.count = 0;
  223.     scattr->normal.pairs = NULL;
  224.     scattr->inverted.count = 0;
  225.     scattr->inverted.pairs = NULL;
  226.  
  227.     for (i = 0; i < (PEXSCMaxShift + 1); i++)
  228.     {
  229.     f = (1L << i);
  230.     if (valueMask & f)
  231.     {
  232.         switch (f)
  233.         {
  234.         case PEXSCPosition:
  235.         scattr->position = *((PEXCoord *) pv);
  236.         pv = (unsigned long *) ((char *) pv + sizeof (PEXCoord));
  237.           break;
  238.         case PEXSCDistance:
  239.         scattr->distance = *((float *) pv);
  240.         pv = (unsigned long *) ((char *) pv + sizeof (float));
  241.         break;
  242.         case PEXSCCeiling:
  243.         scattr->ceiling = *pv;
  244.         pv++;
  245.         break;
  246.         case PEXSCModelClipFlag:
  247.         scattr->model_clip_flag = *pv;
  248.         pv++;
  249.         break;
  250.         case PEXSCStartPath:
  251.         tmp = *pv;
  252.         pv++;
  253.         scattr->start_path.count = tmp;
  254.         tmp *= sizeof (PEXElementRef);
  255.         scattr->start_path.elements =
  256.             (PEXElementRef *) PEXAllocBuf ((unsigned) tmp);
  257.         COPY_AREA ((char *) pv,
  258.             (char *) (scattr->start_path.elements), tmp);
  259.         pv = (unsigned long *) ((char *) pv + tmp);
  260.         break;
  261.         case PEXSCNormalList:
  262.         tmp = *pv;
  263.         pv++;
  264.         scattr->normal.count = tmp;
  265.         tmp *= sizeof (PEXNameSetPair);
  266.         scattr->normal.pairs =
  267.             (PEXNameSetPair *) PEXAllocBuf ((unsigned) tmp);
  268.         COPY_AREA ((char *) pv, (char *) (scattr->normal.pairs), tmp);
  269.         pv = (unsigned long *) ((char *) pv + tmp);
  270.         break;
  271.         case PEXSCInvertedList:
  272.         tmp = *pv;
  273.         pv++;
  274.         scattr->inverted.count = tmp;
  275.         tmp *= sizeof (PEXNameSetPair);
  276.         scattr->inverted.pairs =
  277.             (PEXNameSetPair *) PEXAllocBuf ((unsigned) tmp);
  278.         COPY_AREA ((char *) pv,
  279.             (char *) (scattr->inverted.pairs), tmp);
  280.         pv = (unsigned long *) ((char *) pv + tmp);
  281.         break;
  282.         }
  283.     }
  284.     }
  285.  
  286.  
  287.     /*
  288.      * Done, so unlock and check for synchronous-ness.
  289.      */
  290.  
  291.     UnlockDisplay (display);
  292.     PEXSyncHandle (display);
  293.  
  294.     return (scattr);
  295. }
  296.  
  297.  
  298. void
  299. PEXChangeSearchContext (display, sc, valueMask, values)
  300.  
  301. INPUT Display        *display;
  302. INPUT PEXSearchContext    sc;
  303. INPUT unsigned long    valueMask;
  304. OUTPUT PEXSCAttributes    *values;
  305.  
  306. {
  307.     pexChangeSearchContextReq    *req;
  308.     int                convertFP;
  309.  
  310.  
  311.     /*
  312.      * Lock around the critical section, for multithreading.
  313.      */
  314.  
  315.     LockDisplay (display);
  316.  
  317.  
  318.     /*
  319.      * Put the request in the X request buffer.
  320.      */
  321.  
  322.     PEXGetFPReq (ChangeSearchContext, req, convertFP);
  323.     req->sc = sc;
  324.     req->itemMask = valueMask;
  325.  
  326.     _PEXGenerateSCList (display, (pexReq *) req, valueMask, values);
  327.  
  328.  
  329.     /*
  330.      * Done, so unlock and check for synchronous-ness.
  331.      */
  332.  
  333.     UnlockDisplay (display);
  334.     PEXSyncHandle (display);
  335. }
  336.  
  337.  
  338. Status
  339. PEXSearchNetwork (display, sc, path_return)
  340.  
  341. INPUT Display            *display;
  342. INPUT PEXSearchContext        sc;
  343. OUTPUT PEXStructurePath        **path_return;
  344.  
  345. {
  346.     pexSearchNetworkReply    rep;
  347.     pexSearchNetworkReq        *req;
  348.  
  349.  
  350.     /*
  351.      * Lock around the critical section, for multithreading.
  352.      */
  353.  
  354.     LockDisplay (display);
  355.  
  356.  
  357.     /*
  358.      * Put the request in the X request buffer and get a reply.
  359.      */
  360.  
  361.     PEXGetReq (SearchNetwork, req);
  362.     req->id = sc;
  363.  
  364.     if (_XReply (display, &rep, 0, xFalse) == 0)
  365.     {
  366.         UnlockDisplay (display);
  367.         PEXSyncHandle (display);
  368.     *path_return = NULL;
  369.         return (0);               /* return an error */
  370.     }
  371.  
  372.  
  373.     /*
  374.      * Allocate a buffer for the path to pass back to the client.
  375.      */
  376.  
  377.     *path_return = (PEXStructurePath *)
  378.     PEXAllocBuf ((unsigned) (sizeof (PEXStructurePath)));
  379.  
  380.     (*path_return)->count = rep.numItems;
  381.     (*path_return)->elements = (PEXElementRef *)
  382.     PEXAllocBuf ((unsigned) (rep.numItems * sizeof (PEXElementRef)));
  383.  
  384.     _XRead (display, (char *) ((*path_return)->elements),
  385.     (long) (rep.length << 2));
  386.  
  387.  
  388.     /*
  389.      * Done, so unlock and check for synchronous-ness.
  390.      */
  391.  
  392.     UnlockDisplay (display);
  393.     PEXSyncHandle (display);
  394.  
  395.     return (1);
  396. }
  397.  
  398.  
  399. /*
  400.  * Routine to write a packed list of SC attributes into the transport buf.
  401.  */
  402.  
  403. static void
  404. _PEXGenerateSCList (display, req, valueMask, values)
  405.  
  406. INPUT Display        *display;
  407. INPUT pexReq        *req;
  408. INPUT unsigned long    valueMask;
  409. INPUT PEXSCAttributes    *values;
  410.  
  411. {
  412.     CARD32        *pv;
  413.     CARD32        *pvSend;
  414.     unsigned long       f;
  415.     int            length, tmp, i;
  416.  
  417.  
  418.     /*
  419.      * It's not worth the time of determining exactly how much
  420.      * scratch space to allocate, so assume worse case.
  421.      */
  422.  
  423.     f = sizeof (PEXCoord) +
  424.     sizeof (float) +
  425.     (5 * sizeof (CARD32)) +
  426.     (sizeof (PEXElementRef) * ((valueMask & PEXSCStartPath) ?
  427.         values->start_path.count : 0)) +
  428.     (sizeof (PEXNameSetPair) * ((valueMask & PEXSCNormalList) ?
  429.         values->normal.count : 0)) +
  430.     (sizeof (PEXNameSetPair) * ((valueMask & PEXSCInvertedList) ?
  431.         values->inverted.count : 0));
  432.  
  433.     pv = pvSend = (CARD32 *) _XAllocScratch (display, (unsigned long) f);
  434.  
  435.     for (i = 0; i < (PEXSCMaxShift + 1); i++)
  436.     {
  437.     f = (1L << i);
  438.     if (valueMask & f)
  439.     {
  440.         switch (f)
  441.         {
  442.         case PEXSCPosition:
  443.         *((PEXCoord *) pv) = values->position;
  444.         pv = (CARD32 *) ((char *) pv + sizeof (PEXCoord));
  445.         break;
  446.         case PEXSCDistance:
  447.         *((float *) pv) = values->distance;
  448.         pv = (CARD32 *) ((char *) pv + sizeof (float));
  449.         break;
  450.         case PEXSCCeiling:
  451.         *pv = values->ceiling;
  452.         pv++;
  453.         break;
  454.             case PEXSCModelClipFlag:
  455.         *pv = values->model_clip_flag;
  456.         pv++;
  457.         break;
  458.         case PEXSCStartPath:
  459.         tmp = *((CARD32 *) pv) = values->start_path.count;
  460.         pv++;
  461.         tmp *= sizeof (PEXElementRef);
  462.         COPY_AREA ((char *) (values->start_path.elements),
  463.             (char *) pv, tmp);
  464.         pv = (CARD32 *) ((char *) pv + tmp);
  465.         break;
  466.         case PEXSCNormalList:
  467.         tmp = *((CARD32 *) pv) = values->normal.count;
  468.         pv++;
  469.         tmp *= sizeof (PEXNameSetPair);
  470.         COPY_AREA ((char *) (values->normal.pairs), (char *) pv, tmp);
  471.         pv = (CARD32 *) ((char *) pv + tmp);
  472.         break;
  473.         case PEXSCInvertedList:
  474.         tmp = *((CARD32 *) pv) = values->inverted.count;
  475.         pv++;
  476.         tmp *= sizeof (PEXNameSetPair);
  477.         COPY_AREA ((char *) (values->inverted.pairs),
  478.             (char *) pv, tmp);
  479.         pv = (CARD32 *) ((char *) pv + tmp);
  480.         break;
  481.         }
  482.     }
  483.     }
  484.  
  485.     length = pv - pvSend;
  486.     req->length += length;
  487.  
  488.     Data (display, (char *) pvSend, (length << 2));
  489. }
  490.