home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / evbl0627.zip / everblue_20010627.zip / x11 / Xcms_Cmap.c < prev    next >
C/C++ Source or Header  |  1999-11-02  |  13KB  |  505 lines

  1. /* $XConsortium: cmsCmap.c,v 1.17 95/04/27 18:28:37 converse Exp $ */
  2.  
  3. /*
  4.  * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc.
  5.  *     All Rights Reserved
  6.  * 
  7.  * This file is a component of an X Window System-specific implementation
  8.  * of Xcms based on the TekColor Color Management System.  Permission is
  9.  * hereby granted to use, copy, modify, sell, and otherwise distribute this
  10.  * software and its documentation for any purpose and without fee, provided
  11.  * that this copyright, permission, and disclaimer notice is reproduced in
  12.  * all copies of this software and in supporting documentation.  TekColor
  13.  * is a trademark of Tektronix, Inc.
  14.  * 
  15.  * Tektronix makes no representation about the suitability of this software
  16.  * for any purpose.  It is provided "as is" and with all faults.
  17.  * 
  18.  * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE,
  19.  * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
  20.  * PARTICULAR PURPOSE.  IN NO EVENT SHALL TEKTRONIX BE LIABLE FOR ANY
  21.  * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
  22.  * RESULTING FROM LOSS OF USE, DATA, OR PROFITS, WHETHER IN AN ACTION OF
  23.  * CONTRACT, NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  24.  * CONNECTION WITH THE USE OR THE PERFORMANCE OF THIS SOFTWARE.
  25.  *
  26.  *
  27.  *    NAME
  28.  *        XcmsCmap.c - Client Colormap Management Routines
  29.  *
  30.  *    DESCRIPTION
  31.  *        Routines that store additional information about
  32.  *        colormaps being used by the X Client.
  33.  *
  34.  *
  35.  */
  36.  
  37. #define NEED_EVENTS
  38. #define NEED_REPLIES
  39. #include "Xlib_private.h"
  40. #include "Xcmsint.h"
  41. #include "Xutil.h"
  42.  
  43. /*
  44.  *      FORWARD DECLARATIONS
  45.  */
  46. XcmsCmapRec *_XcmsAddCmapRec();
  47. static void _XcmsFreeClientCmaps();
  48.  
  49.  
  50. /************************************************************************
  51.  *                                    *
  52.  *            PRIVATE INTERFACES                *
  53.  *                                    *
  54.  ************************************************************************/
  55.  
  56. /*
  57.  *    NAME
  58.  *        CmapRecForColormap
  59.  *
  60.  *    SYNOPSIS
  61.  */
  62. static XcmsCmapRec *
  63. CmapRecForColormap(dpy, cmap)
  64.     Display *dpy;
  65.     Colormap cmap;
  66. /*
  67.  *    DESCRIPTION
  68.  *        Find the corresponding XcmsCmapRec for cmap.  In not found
  69.  *        this routines attempts to create one.
  70.  *
  71.  *    RETURNS
  72.  *        Returns NULL if failed; otherwise the address to
  73.  *        the corresponding XcmsCmapRec.
  74.  *
  75.  */
  76. {
  77.     DBUG_ENTER("CmapRecForColormap")
  78.     XcmsCmapRec *pRec;
  79.     int nScrn;
  80.     int i, j;
  81.     XVisualInfo visualTemplate;    /* Template of the visual we want */
  82.     XVisualInfo *visualList;    /* List for visuals that match */
  83.     int nVisualsMatched;    /* Number of visuals that match */
  84.     Window tmpWindow;
  85.     Visual *vp;
  86.     unsigned long border = 0;
  87. #if 0
  88.     _XAsyncHandler async;
  89.     _XAsyncErrorState async_state;
  90. #endif
  91.  
  92.     for (pRec = (XcmsCmapRec *)dpy->cms.clientCmaps; pRec != NULL;
  93.         pRec = pRec->pNext) {
  94.     if (pRec->cmapID == cmap) {
  95.         DBUG_RETURN(pRec);
  96.     }
  97.     }
  98.  
  99.     /*
  100.      * Can't find an XcmsCmapRec associated with cmap in our records.
  101.      * Let's try to see if its a default colormap
  102.      */
  103.     nScrn = ScreenCount(dpy);
  104.     for (i = 0; i < nScrn; i++) {
  105.     if (cmap == DefaultColormap(dpy, i)) {
  106.         /* It is ... lets go ahead and store that info */
  107.         if ((pRec = _XcmsAddCmapRec(dpy, cmap, RootWindow(dpy, i),
  108.             DefaultVisual(dpy, i))) == NULL) {
  109.         DBUG_RETURN((XcmsCmapRec *)NULL);
  110.         }
  111.         pRec->ccc = XcmsCreateCCC(
  112.             dpy,
  113.             i,            /* screenNumber */
  114.             DefaultVisual(dpy, i),
  115.             (XcmsColor *)NULL,    /* clientWhitePt */
  116.             (XcmsCompressionProc)NULL,  /* gamutCompProc */
  117.             (XPointer)NULL,    /* gamutCompClientData */
  118.             (XcmsWhiteAdjustProc)NULL,  /* whitePtAdjProc */
  119.             (XPointer)NULL    /* whitePtAdjClientData */
  120.             );
  121.         DBUG_RETURN(pRec);
  122.     }
  123.     }
  124.  
  125.     /*
  126.      * Nope, its not a default colormap, so it's probably a foreign color map
  127.      * of which we have no specific details.  Let's go through the
  128.      * rigorous process of finding this colormap:
  129.      *        for each screen
  130.      *            for each screen's visual types
  131.      *                create a window with cmap specified as the colormap
  132.      *                if successful
  133.      *                    Add a CmapRec
  134.      *                    Create an XcmsCCC
  135.      *                    return the CmapRec
  136.      *                else
  137.      *                    continue
  138.      */
  139. #if 0
  140.     async_state.error_code = 0; /* don't care */
  141.     async_state.major_opcode = X_CreateWindow;
  142.     async_state.minor_opcode = 0;
  143.     for (i = 0; i < nScrn; i++) {
  144.     visualTemplate.screen = i;
  145.     visualList = XGetVisualInfo(dpy, VisualScreenMask, &visualTemplate,
  146.         &nVisualsMatched);
  147.     if (nVisualsMatched == 0) {
  148.         continue;
  149.     }
  150.  
  151.     /*
  152.      * Attempt to create a window with cmap
  153.      */
  154.     j = 0;
  155.     do {
  156.         vp = (visualList+j)->visual;
  157.         LockDisplay(dpy);
  158.         {
  159.         register xCreateWindowReq *req;
  160.  
  161.         GetReq(CreateWindow, req);
  162.         async_state.min_sequence_number = dpy->request;
  163.         async_state.max_sequence_number = dpy->request;
  164.         async_state.error_count = 0;
  165.         async.next = dpy->async_handlers;
  166.         async.handler = _XAsyncErrorHandler;
  167.         async.data = (XPointer)&async_state;
  168.         dpy->async_handlers = &async;
  169.         req->parent = RootWindow(dpy, i);
  170.         req->x = 0;
  171.         req->y = 0;
  172.         req->width = 1;
  173.         req->height = 1;
  174.         req->borderWidth = 0;
  175.         req->depth = (visualList+j)->depth;
  176.         req->class = CopyFromParent;
  177.         req->visual = vp->visualid;
  178.         tmpWindow = req->wid = XAllocID(dpy);
  179.         req->mask = CWBorderPixel | CWColormap;
  180.         req->length += 2;
  181.         Data32 (dpy, (long *) &border, 4);
  182.         Data32 (dpy, (long *) &cmap, 4);
  183.         }
  184.         {
  185.         xGetInputFocusReply rep;
  186.         register xReq *req;
  187.  
  188.         GetEmptyReq(GetInputFocus, req);
  189.         (void) _XReply (dpy, (xReply *)&rep, 0, xTrue);
  190.         }
  191.         DeqAsyncHandler(dpy, &async);
  192.         UnlockDisplay(dpy);
  193.         SyncHandle();
  194.     } while (async_state.error_count > 0 && ++j < nVisualsMatched);
  195.  
  196.     Xfree((char *)visualList);
  197.  
  198.     /*
  199.      * if successful
  200.      */
  201.     if (j < nVisualsMatched) {
  202.         if ((pRec = _XcmsAddCmapRec(dpy, cmap, tmpWindow, vp)) == NULL)
  203.         DBUG_RETURN((XcmsCmapRec *)NULL);
  204.         pRec->ccc = XcmsCreateCCC(
  205.             dpy,
  206.             i,            /* screenNumber */
  207.             vp,
  208.             (XcmsColor *)NULL,    /* clientWhitePt */
  209.             (XcmsCompressionProc)NULL,  /* gamutCompProc */
  210.             (XPointer)NULL,    /* gamutCompClientData */
  211.             (XcmsWhiteAdjustProc)NULL,  /* whitePtAdjProc */
  212.             (XPointer)NULL    /* whitePtAdjClientData */
  213.             );
  214.         XDestroyWindow(dpy, tmpWindow);
  215.         DBUG_RETURN(pRec);
  216.     }
  217.     }
  218. #endif
  219.     DBUG_RETURN(NULL);
  220. }
  221.  
  222.  
  223.  
  224. /************************************************************************
  225.  *                                    *
  226.  *            API PRIVATE INTERFACES                *
  227.  *                                    *
  228.  ************************************************************************/
  229.  
  230. /*
  231.  *    NAME
  232.  *        _XcmsAddCmapRec
  233.  *
  234.  *    SYNOPSIS
  235.  */
  236. XcmsCmapRec *
  237. _XcmsAddCmapRec(dpy, cmap, windowID, visual)
  238.     Display *dpy;
  239.     Colormap cmap;
  240.     Window windowID;
  241.     Visual *visual;
  242. /*
  243.  *    DESCRIPTION
  244.  *        Create an XcmsCmapRec for the specified cmap, windowID,
  245.  *        and visual, then adds it to its list of CmapRec's.
  246.  *
  247.  *    RETURNS
  248.  *        Returns NULL if failed; otherwise the address to
  249.  *        the added XcmsCmapRec.
  250.  *
  251.  */
  252. {
  253.     DBUG_ENTER("_XcmsAddCmapRec")
  254.     XcmsCmapRec *pNew;
  255.  
  256.     if ((pNew = (XcmsCmapRec *) Xcalloc(1, (unsigned) sizeof(XcmsCmapRec)))
  257.         == NULL) {
  258.     DBUG_RETURN((XcmsCmapRec *)NULL);
  259.     }
  260.  
  261.     pNew->cmapID = cmap;
  262.     pNew->dpy = dpy;
  263.     pNew->windowID = windowID;
  264.     pNew->visual = visual;
  265.     pNew->pNext = (XcmsCmapRec *)dpy->cms.clientCmaps;
  266.     dpy->cms.clientCmaps = (XPointer)pNew;
  267.     dpy->free_funcs->clientCmaps = _XcmsFreeClientCmaps;
  268.  
  269.     /*
  270.      * Note, we don't create the XcmsCCC for pNew->ccc here because
  271.      * it may require the use of XGetWindowAttributes (a round trip request)
  272.      * to determine the screen.
  273.      */
  274.     DBUG_RETURN(pNew);
  275. }
  276.  
  277.  
  278. /*
  279.  *    NAME
  280.  *        _XcmsCopyCmapRecAndFree
  281.  *
  282.  *    SYNOPSIS
  283.  */
  284. XcmsCmapRec *
  285. _XcmsCopyCmapRecAndFree(dpy, src_cmap, copy_cmap)
  286.     Display *dpy;
  287.     Colormap src_cmap;
  288.     Colormap copy_cmap;
  289. /*
  290.  *    DESCRIPTION
  291.  *        Augments Xlib's XCopyColormapAndFree() to copy
  292.  *        XcmsCmapRecs.
  293.  *
  294.  *    RETURNS
  295.  *        Returns NULL if failed; otherwise the address to
  296.  *        the copy XcmsCmapRec.
  297.  *
  298.  */
  299. {
  300.     DBUG_ENTER("_XcmsCopyCmapRecAndFree")
  301.     XcmsCmapRec *pRec_src;
  302.     XcmsCmapRec *pRec_copy;
  303.  
  304.     if ((pRec_src = CmapRecForColormap(dpy, src_cmap)) != NULL) {
  305.     pRec_copy =_XcmsAddCmapRec(dpy, copy_cmap, pRec_src->windowID,
  306.         pRec_src->visual);
  307.     if (pRec_copy != NULL && pRec_src->ccc) {
  308.         pRec_copy->ccc = (XcmsCCC)Xcalloc(1, (unsigned) sizeof(XcmsCCCRec));
  309.         memcpy((char *)pRec_copy->ccc, (char *)pRec_src->ccc,
  310.            sizeof(XcmsCCCRec));
  311.     }
  312.     DBUG_RETURN(pRec_copy);
  313.     }
  314.     DBUG_RETURN((XcmsCmapRec *)NULL);
  315. }
  316.  
  317.  
  318. /*
  319.  *    NAME
  320.  *        _XcmsDeleteCmapRec
  321.  *
  322.  *    SYNOPSIS
  323.  */
  324. void
  325. _XcmsDeleteCmapRec(dpy, cmap)
  326.     Display *dpy;
  327.     Colormap cmap;
  328. /*
  329.  *    DESCRIPTION
  330.  *        Removes and frees the specified XcmsCmapRec structure
  331.  *        from the linked list of structures.
  332.  *
  333.  *    RETURNS
  334.  *        void
  335.  *
  336.  */
  337. {
  338.     DBUG_ENTER("_XcmsDeleteCmapRec")
  339.     XcmsCmapRec **pPrevPtr;
  340.     XcmsCmapRec *pRec;
  341.     int scr;
  342.  
  343.     /* If it is the default cmap for a screen, do not delete it,
  344.      * because the server will not actually free it */
  345.     for (scr = ScreenCount(dpy); --scr >= 0; ) {
  346.     if (cmap == DefaultColormap(dpy, scr))
  347.         DBUG_VOID_RETURN;
  348.     }
  349.  
  350.     /* search for it in the list */
  351.     pPrevPtr = (XcmsCmapRec **)&dpy->cms.clientCmaps;
  352.     while ((pRec = *pPrevPtr) && (pRec->cmapID != cmap)) {
  353.     pPrevPtr = &pRec->pNext;
  354.     }
  355.  
  356.     if (pRec) {
  357.     if (pRec->ccc) {
  358.         XcmsFreeCCC(pRec->ccc);
  359.     }
  360.     *pPrevPtr = pRec->pNext;
  361.     Xfree((char *)pRec);
  362.     }
  363.     DBUG_VOID_RETURN;
  364. }
  365.  
  366.  
  367. /*
  368.  *    NAME
  369.  *        _XcmsFreeClientCmaps
  370.  *
  371.  *    SYNOPSIS
  372.  */
  373. static void
  374. _XcmsFreeClientCmaps(dpy)
  375.     Display *dpy;
  376. /*
  377.  *    DESCRIPTION
  378.  *        Frees all XcmsCmapRec structures in the linked list
  379.  *        and sets dpy->cms.clientCmaps to NULL.
  380.  *
  381.  *    RETURNS
  382.  *        void
  383.  *
  384.  */
  385. {
  386.     DBUG_ENTER("_XcmsFreeClientCmaps")
  387.     XcmsCmapRec *pRecNext, *pRecFree;
  388.  
  389.     pRecNext = (XcmsCmapRec *)dpy->cms.clientCmaps;
  390.     while (pRecNext != NULL) {
  391.     pRecFree = pRecNext;
  392.     pRecNext = pRecNext->pNext;
  393.     if (pRecFree->ccc) {
  394.         /* Free the XcmsCCC structure */
  395.         XcmsFreeCCC(pRecFree->ccc);
  396.     }
  397.     /* Now free the XcmsCmapRec structure */
  398.     Xfree((char *)pRecFree);
  399.     }
  400.     dpy->cms.clientCmaps = (XPointer)NULL;
  401.     DBUG_VOID_RETURN;
  402. }
  403.  
  404.  
  405.  
  406. /************************************************************************
  407.  *                                    *
  408.  *            PUBLIC INTERFACES                *
  409.  *                                    *
  410.  ************************************************************************/
  411.  
  412. /*
  413.  *    NAME
  414.  *        XcmsCCCOfColormap
  415.  *
  416.  *    SYNOPSIS
  417.  */
  418. XcmsCCC 
  419. XcmsCCCOfColormap(dpy, cmap)
  420.     Display *dpy;
  421.     Colormap cmap;
  422. /*
  423.  *    DESCRIPTION
  424.  *        Finds the XcmsCCC associated with the specified colormap.
  425.  *
  426.  *    RETURNS
  427.  *        Returns NULL if failed; otherwise the address to
  428.  *        the associated XcmsCCC structure.
  429.  *
  430.  */
  431. {
  432.     DBUG_ENTER("XcmsCCCOfColormap")
  433.     XWindowAttributes windowAttr;
  434.     XcmsCmapRec *pRec;
  435.     int nScrn;
  436.     int i;
  437.     nScrn = ScreenCount(dpy);
  438.  
  439.     if ((pRec = CmapRecForColormap(dpy, cmap)) != NULL) {
  440.     if (pRec->ccc) {
  441.         /* XcmsCmapRec already has a XcmsCCC */
  442.         DBUG_RETURN(pRec->ccc);
  443.     }
  444.  
  445.     /*
  446.      * The XcmsCmapRec does not have a XcmsCCC yet, so let's create
  447.      * one.  But first, we need to know the screen associated with
  448.      * cmap, so use XGetWindowAttributes() to extract that
  449.      * information.  Unless, of course there is only one screen!!
  450.      */
  451.     if (nScrn == 1) {
  452.         /* Assume screenNumber == 0 */
  453.         DBUG_RETURN(pRec->ccc = XcmsCreateCCC(
  454.             dpy,
  455.             0,            /* screenNumber */
  456.             pRec->visual,
  457.             (XcmsColor *)NULL,    /* clientWhitePt */
  458.             (XcmsCompressionProc)NULL,  /* gamutCompProc */
  459.             (XPointer)NULL,    /* gamutCompClientData */
  460.             (XcmsWhiteAdjustProc)NULL,  /* whitePtAdjProc */
  461.             (XPointer)NULL    /* whitePtAdjClientData */
  462.             ));
  463.     } else {
  464.         if (XGetWindowAttributes(dpy, pRec->windowID, &windowAttr)) {
  465.         for (i = 0; i < nScrn; i++) {
  466.             if (ScreenOfDisplay(dpy, i) == windowAttr.screen) {
  467.             DBUG_RETURN(pRec->ccc = XcmsCreateCCC(
  468.                 dpy,
  469.                 i,           /* screenNumber */
  470.                 pRec->visual,
  471.                 (XcmsColor *)NULL, /* clientWhitePt */
  472.                 (XcmsCompressionProc)NULL, /* gamutCompProc */
  473.                 (XPointer)NULL,       /* gamutCompClientData */
  474.                 (XcmsWhiteAdjustProc)NULL, /* whitePtAdjProc */
  475.                 (XPointer)NULL       /* whitePtAdjClientData */
  476.                 ));
  477.             }
  478.         }
  479.         }
  480.     }
  481.     }
  482.  
  483.     /*
  484.      * No such cmap
  485.      */
  486.     DBUG_RETURN(NULL);
  487. }
  488.  
  489. XcmsCCC XcmsSetCCCOfColormap(dpy, cmap, ccc)
  490.     Display *dpy;
  491.     Colormap cmap;
  492.     XcmsCCC ccc;
  493. {
  494.     DBUG_ENTER("XcmsSetCCCOfColormap")
  495.     XcmsCCC prev_ccc = NULL;
  496.     XcmsCmapRec *pRec;
  497.  
  498.     pRec = CmapRecForColormap(dpy, cmap);
  499.     if (pRec) {
  500.     prev_ccc = pRec->ccc;
  501.     pRec->ccc = ccc;
  502.     }
  503.     DBUG_RETURN(prev_ccc);
  504. }
  505.