OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [tags/] [start/] [insight/] [tk/] [generic/] [tkVisual.c] - Diff between revs 579 and 1765

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 579 Rev 1765
/*
/*
 * tkVisual.c --
 * tkVisual.c --
 *
 *
 *      This file contains library procedures for allocating and
 *      This file contains library procedures for allocating and
 *      freeing visuals and colormaps.  This code is based on a
 *      freeing visuals and colormaps.  This code is based on a
 *      prototype implementation by Paul Mackerras.
 *      prototype implementation by Paul Mackerras.
 *
 *
 * Copyright (c) 1994 The Regents of the University of California.
 * Copyright (c) 1994 The Regents of the University of California.
 * Copyright (c) 1994-1995 Sun Microsystems, Inc.
 * Copyright (c) 1994-1995 Sun Microsystems, Inc.
 *
 *
 * See the file "license.terms" for information on usage and redistribution
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 *
 * RCS: @(#) $Id: tkVisual.c,v 1.1.1.1 2002-01-16 10:25:53 markom Exp $
 * RCS: @(#) $Id: tkVisual.c,v 1.1.1.1 2002-01-16 10:25:53 markom Exp $
 */
 */
 
 
#include "tkInt.h"
#include "tkInt.h"
#include "tkPort.h"
#include "tkPort.h"
 
 
/*
/*
 * The table below maps from symbolic names for visual classes
 * The table below maps from symbolic names for visual classes
 * to the associated X class symbols.
 * to the associated X class symbols.
 */
 */
 
 
typedef struct VisualDictionary {
typedef struct VisualDictionary {
    char *name;                 /* Textual name of class. */
    char *name;                 /* Textual name of class. */
    int minLength;              /* Minimum # characters that must be
    int minLength;              /* Minimum # characters that must be
                                 * specified for an unambiguous match. */
                                 * specified for an unambiguous match. */
    int class;                  /* X symbol for class. */
    int class;                  /* X symbol for class. */
} VisualDictionary;
} VisualDictionary;
static VisualDictionary visualNames[] = {
static VisualDictionary visualNames[] = {
    {"best",            1,      0},
    {"best",            1,      0},
    {"directcolor",     2,      DirectColor},
    {"directcolor",     2,      DirectColor},
    {"grayscale",       1,      GrayScale},
    {"grayscale",       1,      GrayScale},
    {"greyscale",       1,      GrayScale},
    {"greyscale",       1,      GrayScale},
    {"pseudocolor",     1,      PseudoColor},
    {"pseudocolor",     1,      PseudoColor},
    {"staticcolor",     7,      StaticColor},
    {"staticcolor",     7,      StaticColor},
    {"staticgray",      7,      StaticGray},
    {"staticgray",      7,      StaticGray},
    {"staticgrey",      7,      StaticGray},
    {"staticgrey",      7,      StaticGray},
    {"truecolor",       1,      TrueColor},
    {"truecolor",       1,      TrueColor},
    {NULL,              0,       0},
    {NULL,              0,       0},
};
};
 
 
/*
/*
 * One of the following structures exists for each distinct non-default
 * One of the following structures exists for each distinct non-default
 * colormap allocated for a display by Tk_GetColormap.
 * colormap allocated for a display by Tk_GetColormap.
 */
 */
 
 
struct TkColormap {
struct TkColormap {
    Colormap colormap;          /* X's identifier for the colormap. */
    Colormap colormap;          /* X's identifier for the colormap. */
    Visual *visual;             /* Visual for which colormap was
    Visual *visual;             /* Visual for which colormap was
                                 * allocated. */
                                 * allocated. */
    int refCount;               /* How many uses of the colormap are still
    int refCount;               /* How many uses of the colormap are still
                                 * outstanding (calls to Tk_GetColormap
                                 * outstanding (calls to Tk_GetColormap
                                 * minus calls to Tk_FreeColormap). */
                                 * minus calls to Tk_FreeColormap). */
    int shareable;              /* 0 means this colormap was allocated by
    int shareable;              /* 0 means this colormap was allocated by
                                 * a call to Tk_GetColormap with "new",
                                 * a call to Tk_GetColormap with "new",
                                 * implying that the window wants it all
                                 * implying that the window wants it all
                                 * for itself.  1 means that the colormap
                                 * for itself.  1 means that the colormap
                                 * was allocated as a default for a particular
                                 * was allocated as a default for a particular
                                 * visual, so it can be shared. */
                                 * visual, so it can be shared. */
    struct TkColormap *nextPtr; /* Next in list of colormaps for this display,
    struct TkColormap *nextPtr; /* Next in list of colormaps for this display,
                                 * or NULL for end of list. */
                                 * or NULL for end of list. */
};
};


/*
/*
 *----------------------------------------------------------------------
 *----------------------------------------------------------------------
 *
 *
 * Tk_GetVisual --
 * Tk_GetVisual --
 *
 *
 *      Given a string identifying a particular kind of visual, this
 *      Given a string identifying a particular kind of visual, this
 *      procedure returns a visual and depth that matches the specification.
 *      procedure returns a visual and depth that matches the specification.
 *
 *
 * Results:
 * Results:
 *      The return value is normally a pointer to a visual.  If an
 *      The return value is normally a pointer to a visual.  If an
 *      error occurred in looking up the visual, NULL is returned and
 *      error occurred in looking up the visual, NULL is returned and
 *      an error message is left in interp->result.  The depth of the
 *      an error message is left in interp->result.  The depth of the
 *      visual is returned to *depthPtr under normal returns.  If
 *      visual is returned to *depthPtr under normal returns.  If
 *      colormapPtr is non-NULL, then this procedure also finds a
 *      colormapPtr is non-NULL, then this procedure also finds a
 *      suitable colormap for use with the visual in tkwin, and it
 *      suitable colormap for use with the visual in tkwin, and it
 *      returns that colormap in *colormapPtr unless an error occurs.
 *      returns that colormap in *colormapPtr unless an error occurs.
 *
 *
 * Side effects:
 * Side effects:
 *      A new colormap may be allocated.
 *      A new colormap may be allocated.
 *
 *
 *----------------------------------------------------------------------
 *----------------------------------------------------------------------
 */
 */
 
 
Visual *
Visual *
Tk_GetVisual(interp, tkwin, string, depthPtr, colormapPtr)
Tk_GetVisual(interp, tkwin, string, depthPtr, colormapPtr)
    Tcl_Interp *interp;                 /* Interpreter to use for error
    Tcl_Interp *interp;                 /* Interpreter to use for error
                                         * reporting. */
                                         * reporting. */
    Tk_Window tkwin;                    /* Window in which visual will be
    Tk_Window tkwin;                    /* Window in which visual will be
                                         * used. */
                                         * used. */
    char *string;                       /* String describing visual.  See
    char *string;                       /* String describing visual.  See
                                         * manual entry for details. */
                                         * manual entry for details. */
    int *depthPtr;                      /* The depth of the returned visual
    int *depthPtr;                      /* The depth of the returned visual
                                         * is stored here. */
                                         * is stored here. */
    Colormap *colormapPtr;              /* If non-NULL, then a suitable
    Colormap *colormapPtr;              /* If non-NULL, then a suitable
                                         * colormap for visual is placed here.
                                         * colormap for visual is placed here.
                                         * This colormap must eventually be
                                         * This colormap must eventually be
                                         * freed by calling Tk_FreeColormap. */
                                         * freed by calling Tk_FreeColormap. */
{
{
    Tk_Window tkwin2;
    Tk_Window tkwin2;
    XVisualInfo template, *visInfoList, *bestPtr;
    XVisualInfo template, *visInfoList, *bestPtr;
    long mask;
    long mask;
    Visual *visual;
    Visual *visual;
    int length, c, numVisuals, prio, bestPrio, i;
    int length, c, numVisuals, prio, bestPrio, i;
    char *p;
    char *p;
    VisualDictionary *dictPtr;
    VisualDictionary *dictPtr;
    TkColormap *cmapPtr;
    TkColormap *cmapPtr;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;
 
 
    /*
    /*
     * Parse string and set up a template for use in searching for
     * Parse string and set up a template for use in searching for
     * an appropriate visual.
     * an appropriate visual.
     */
     */
 
 
    c = string[0];
    c = string[0];
    if (c == '.') {
    if (c == '.') {
        /*
        /*
         * The string must be a window name.  If the window is on the
         * The string must be a window name.  If the window is on the
         * same screen as tkwin, then just use its visual.  Otherwise
         * same screen as tkwin, then just use its visual.  Otherwise
         * use the information about the visual as a template for the
         * use the information about the visual as a template for the
         * search.
         * search.
         */
         */
 
 
        tkwin2 = Tk_NameToWindow(interp, string, tkwin);
        tkwin2 = Tk_NameToWindow(interp, string, tkwin);
        if (tkwin2 == NULL) {
        if (tkwin2 == NULL) {
            return NULL;
            return NULL;
        }
        }
        visual = Tk_Visual(tkwin2);
        visual = Tk_Visual(tkwin2);
        if (Tk_Screen(tkwin) == Tk_Screen(tkwin2)) {
        if (Tk_Screen(tkwin) == Tk_Screen(tkwin2)) {
            *depthPtr = Tk_Depth(tkwin2);
            *depthPtr = Tk_Depth(tkwin2);
            if (colormapPtr != NULL) {
            if (colormapPtr != NULL) {
                /*
                /*
                 * Use the colormap from the other window too (but be sure
                 * Use the colormap from the other window too (but be sure
                 * to increment its reference count if it's one of the ones
                 * to increment its reference count if it's one of the ones
                 * allocated here).
                 * allocated here).
                 */
                 */
 
 
                *colormapPtr = Tk_Colormap(tkwin2);
                *colormapPtr = Tk_Colormap(tkwin2);
                for (cmapPtr = dispPtr->cmapPtr; cmapPtr != NULL;
                for (cmapPtr = dispPtr->cmapPtr; cmapPtr != NULL;
                        cmapPtr = cmapPtr->nextPtr) {
                        cmapPtr = cmapPtr->nextPtr) {
                    if (cmapPtr->colormap == *colormapPtr) {
                    if (cmapPtr->colormap == *colormapPtr) {
                        cmapPtr->refCount += 1;
                        cmapPtr->refCount += 1;
                        break;
                        break;
                    }
                    }
                }
                }
            }
            }
            return visual;
            return visual;
        }
        }
        template.depth = Tk_Depth(tkwin2);
        template.depth = Tk_Depth(tkwin2);
        template.class = visual->class;
        template.class = visual->class;
        template.red_mask = visual->red_mask;
        template.red_mask = visual->red_mask;
        template.green_mask = visual->green_mask;
        template.green_mask = visual->green_mask;
        template.blue_mask = visual->blue_mask;
        template.blue_mask = visual->blue_mask;
        template.colormap_size = visual->map_entries;
        template.colormap_size = visual->map_entries;
        template.bits_per_rgb = visual->bits_per_rgb;
        template.bits_per_rgb = visual->bits_per_rgb;
        mask = VisualDepthMask|VisualClassMask|VisualRedMaskMask
        mask = VisualDepthMask|VisualClassMask|VisualRedMaskMask
                |VisualGreenMaskMask|VisualBlueMaskMask|VisualColormapSizeMask
                |VisualGreenMaskMask|VisualBlueMaskMask|VisualColormapSizeMask
                |VisualBitsPerRGBMask;
                |VisualBitsPerRGBMask;
    } else if ((c == 0) || ((c == 'd') && (string[1] != 0)
    } else if ((c == 0) || ((c == 'd') && (string[1] != 0)
            && (strncmp(string, "default", strlen(string)) == 0))) {
            && (strncmp(string, "default", strlen(string)) == 0))) {
        /*
        /*
         * Use the default visual for the window's screen.
         * Use the default visual for the window's screen.
         */
         */
 
 
        if (colormapPtr != NULL) {
        if (colormapPtr != NULL) {
            *colormapPtr = DefaultColormapOfScreen(Tk_Screen(tkwin));
            *colormapPtr = DefaultColormapOfScreen(Tk_Screen(tkwin));
        }
        }
        *depthPtr = DefaultDepthOfScreen(Tk_Screen(tkwin));
        *depthPtr = DefaultDepthOfScreen(Tk_Screen(tkwin));
        return DefaultVisualOfScreen(Tk_Screen(tkwin));
        return DefaultVisualOfScreen(Tk_Screen(tkwin));
    } else if (isdigit(UCHAR(c))) {
    } else if (isdigit(UCHAR(c))) {
        int visualId;
        int visualId;
 
 
        /*
        /*
        * This is a visual ID.
        * This is a visual ID.
        */
        */
 
 
        if (Tcl_GetInt(interp, string, &visualId) == TCL_ERROR) {
        if (Tcl_GetInt(interp, string, &visualId) == TCL_ERROR) {
            Tcl_ResetResult(interp);
            Tcl_ResetResult(interp);
            Tcl_AppendResult(interp, "bad X identifier for visual: ",
            Tcl_AppendResult(interp, "bad X identifier for visual: ",
                    string, "\"", (char *) NULL);
                    string, "\"", (char *) NULL);
            return NULL;
            return NULL;
        }
        }
        template.visualid = visualId;
        template.visualid = visualId;
        mask = VisualIDMask;
        mask = VisualIDMask;
    } else {
    } else {
        /*
        /*
         * Parse the string into a class name (or "best") optionally
         * Parse the string into a class name (or "best") optionally
         * followed by whitespace and a depth.
         * followed by whitespace and a depth.
         */
         */
 
 
        for (p = string; *p != 0; p++) {
        for (p = string; *p != 0; p++) {
            if (isspace(UCHAR(*p)) || isdigit(UCHAR(*p))) {
            if (isspace(UCHAR(*p)) || isdigit(UCHAR(*p))) {
                break;
                break;
            }
            }
        }
        }
        length = p - string;
        length = p - string;
        template.class = -1;
        template.class = -1;
        for (dictPtr = visualNames; dictPtr->name != NULL; dictPtr++) {
        for (dictPtr = visualNames; dictPtr->name != NULL; dictPtr++) {
            if ((dictPtr->name[0] == c) && (length >= dictPtr->minLength)
            if ((dictPtr->name[0] == c) && (length >= dictPtr->minLength)
                    && (strncmp(string, dictPtr->name,
                    && (strncmp(string, dictPtr->name,
                    (size_t) length) == 0)) {
                    (size_t) length) == 0)) {
                template.class = dictPtr->class;
                template.class = dictPtr->class;
                break;
                break;
            }
            }
        }
        }
        if (template.class == -1) {
        if (template.class == -1) {
            Tcl_AppendResult(interp, "unknown or ambiguous visual name \"",
            Tcl_AppendResult(interp, "unknown or ambiguous visual name \"",
                    string, "\": class must be ", (char *) NULL);
                    string, "\": class must be ", (char *) NULL);
            for (dictPtr = visualNames; dictPtr->name != NULL; dictPtr++) {
            for (dictPtr = visualNames; dictPtr->name != NULL; dictPtr++) {
                Tcl_AppendResult(interp, dictPtr->name, ", ", (char *) NULL);
                Tcl_AppendResult(interp, dictPtr->name, ", ", (char *) NULL);
            }
            }
            Tcl_AppendResult(interp, "or default", (char *) NULL);
            Tcl_AppendResult(interp, "or default", (char *) NULL);
            return NULL;
            return NULL;
        }
        }
        while (isspace(UCHAR(*p))) {
        while (isspace(UCHAR(*p))) {
            p++;
            p++;
        }
        }
        if (*p == 0) {
        if (*p == 0) {
            template.depth = 10000;
            template.depth = 10000;
        } else {
        } else {
            if (Tcl_GetInt(interp, p, &template.depth) != TCL_OK) {
            if (Tcl_GetInt(interp, p, &template.depth) != TCL_OK) {
                return NULL;
                return NULL;
            }
            }
        }
        }
        if (c == 'b') {
        if (c == 'b') {
            mask = 0;
            mask = 0;
        } else {
        } else {
            mask = VisualClassMask;
            mask = VisualClassMask;
        }
        }
    }
    }
 
 
    /*
    /*
     * Find all visuals that match the template we've just created,
     * Find all visuals that match the template we've just created,
     * and return an error if there are none that match.
     * and return an error if there are none that match.
     */
     */
 
 
    template.screen = Tk_ScreenNumber(tkwin);
    template.screen = Tk_ScreenNumber(tkwin);
    mask |= VisualScreenMask;
    mask |= VisualScreenMask;
    visInfoList = XGetVisualInfo(Tk_Display(tkwin), mask, &template,
    visInfoList = XGetVisualInfo(Tk_Display(tkwin), mask, &template,
            &numVisuals);
            &numVisuals);
    if (visInfoList == NULL) {
    if (visInfoList == NULL) {
        interp->result = "couldn't find an appropriate visual";
        interp->result = "couldn't find an appropriate visual";
        return NULL;
        return NULL;
    }
    }
 
 
    /*
    /*
     * Search through the visuals that were returned to find the best
     * Search through the visuals that were returned to find the best
     * one.  The choice is based on the following criteria, in decreasing
     * one.  The choice is based on the following criteria, in decreasing
     * order of importance:
     * order of importance:
     *
     *
     * 1. Depth: choose a visual with exactly the desired depth,
     * 1. Depth: choose a visual with exactly the desired depth,
     *    else one with more bits than requested but as few bits
     *    else one with more bits than requested but as few bits
     *    as possible, else one with fewer bits but as many as
     *    as possible, else one with fewer bits but as many as
     *    possible.
     *    possible.
     * 2. Class: some visual classes are more desirable than others;
     * 2. Class: some visual classes are more desirable than others;
     *    pick the visual with the most desirable class.
     *    pick the visual with the most desirable class.
     * 3. Default: the default visual for the screen gets preference
     * 3. Default: the default visual for the screen gets preference
     *    over other visuals, all else being equal.
     *    over other visuals, all else being equal.
     */
     */
 
 
    bestPrio = 0;
    bestPrio = 0;
    bestPtr = NULL;
    bestPtr = NULL;
    for (i = 0; i < numVisuals; i++) {
    for (i = 0; i < numVisuals; i++) {
        switch (visInfoList[i].class) {
        switch (visInfoList[i].class) {
            case DirectColor:   prio = 5; break;
            case DirectColor:   prio = 5; break;
            case GrayScale:     prio = 1; break;
            case GrayScale:     prio = 1; break;
            case PseudoColor:   prio = 7; break;
            case PseudoColor:   prio = 7; break;
            case StaticColor:   prio = 3; break;
            case StaticColor:   prio = 3; break;
            case StaticGray:    prio = 1; break;
            case StaticGray:    prio = 1; break;
            case TrueColor:     prio = 5; break;
            case TrueColor:     prio = 5; break;
            default:            prio = 0; break;
            default:            prio = 0; break;
        }
        }
        if (visInfoList[i].visual
        if (visInfoList[i].visual
                == DefaultVisualOfScreen(Tk_Screen(tkwin))) {
                == DefaultVisualOfScreen(Tk_Screen(tkwin))) {
            prio++;
            prio++;
        }
        }
        if (bestPtr == NULL) {
        if (bestPtr == NULL) {
            goto newBest;
            goto newBest;
        }
        }
        if (visInfoList[i].depth < bestPtr->depth) {
        if (visInfoList[i].depth < bestPtr->depth) {
            if (visInfoList[i].depth >= template.depth) {
            if (visInfoList[i].depth >= template.depth) {
                goto newBest;
                goto newBest;
            }
            }
        } else if (visInfoList[i].depth > bestPtr->depth) {
        } else if (visInfoList[i].depth > bestPtr->depth) {
            if (bestPtr->depth < template.depth) {
            if (bestPtr->depth < template.depth) {
                goto newBest;
                goto newBest;
            }
            }
        } else {
        } else {
            if (prio > bestPrio) {
            if (prio > bestPrio) {
                goto newBest;
                goto newBest;
            }
            }
        }
        }
        continue;
        continue;
 
 
        newBest:
        newBest:
        bestPtr = &visInfoList[i];
        bestPtr = &visInfoList[i];
        bestPrio = prio;
        bestPrio = prio;
    }
    }
    *depthPtr = bestPtr->depth;
    *depthPtr = bestPtr->depth;
    visual = bestPtr->visual;
    visual = bestPtr->visual;
    XFree((char *) visInfoList);
    XFree((char *) visInfoList);
 
 
    /*
    /*
     * If we need to find a colormap for this visual, do it now.
     * If we need to find a colormap for this visual, do it now.
     * If the visual is the default visual for the screen, then
     * If the visual is the default visual for the screen, then
     * use the default colormap.  Otherwise search for an existing
     * use the default colormap.  Otherwise search for an existing
     * colormap that's shareable.  If all else fails, create a new
     * colormap that's shareable.  If all else fails, create a new
     * colormap.
     * colormap.
     */
     */
 
 
    if (colormapPtr != NULL) {
    if (colormapPtr != NULL) {
        if (visual == DefaultVisualOfScreen(Tk_Screen(tkwin))) {
        if (visual == DefaultVisualOfScreen(Tk_Screen(tkwin))) {
            *colormapPtr = DefaultColormapOfScreen(Tk_Screen(tkwin));
            *colormapPtr = DefaultColormapOfScreen(Tk_Screen(tkwin));
        } else {
        } else {
            for (cmapPtr = dispPtr->cmapPtr; cmapPtr != NULL;
            for (cmapPtr = dispPtr->cmapPtr; cmapPtr != NULL;
                    cmapPtr = cmapPtr->nextPtr) {
                    cmapPtr = cmapPtr->nextPtr) {
                if (cmapPtr->shareable && (cmapPtr->visual == visual)) {
                if (cmapPtr->shareable && (cmapPtr->visual == visual)) {
                    *colormapPtr = cmapPtr->colormap;
                    *colormapPtr = cmapPtr->colormap;
                    cmapPtr->refCount += 1;
                    cmapPtr->refCount += 1;
                    goto done;
                    goto done;
                }
                }
            }
            }
            cmapPtr = (TkColormap *) ckalloc(sizeof(TkColormap));
            cmapPtr = (TkColormap *) ckalloc(sizeof(TkColormap));
            cmapPtr->colormap = XCreateColormap(Tk_Display(tkwin),
            cmapPtr->colormap = XCreateColormap(Tk_Display(tkwin),
                    RootWindowOfScreen(Tk_Screen(tkwin)), visual,
                    RootWindowOfScreen(Tk_Screen(tkwin)), visual,
                    AllocNone);
                    AllocNone);
            cmapPtr->visual = visual;
            cmapPtr->visual = visual;
            cmapPtr->refCount = 1;
            cmapPtr->refCount = 1;
            cmapPtr->shareable = 1;
            cmapPtr->shareable = 1;
            cmapPtr->nextPtr = dispPtr->cmapPtr;
            cmapPtr->nextPtr = dispPtr->cmapPtr;
            dispPtr->cmapPtr = cmapPtr;
            dispPtr->cmapPtr = cmapPtr;
            *colormapPtr = cmapPtr->colormap;
            *colormapPtr = cmapPtr->colormap;
        }
        }
    }
    }
 
 
    done:
    done:
    return visual;
    return visual;
}
}


/*
/*
 *----------------------------------------------------------------------
 *----------------------------------------------------------------------
 *
 *
 * Tk_GetColormap --
 * Tk_GetColormap --
 *
 *
 *      Given a string identifying a colormap, this procedure finds
 *      Given a string identifying a colormap, this procedure finds
 *      an appropriate colormap.
 *      an appropriate colormap.
 *
 *
 * Results:
 * Results:
 *      The return value is normally the X resource identifier for the
 *      The return value is normally the X resource identifier for the
 *      colormap.  If an error occurs, None is returned and an error
 *      colormap.  If an error occurs, None is returned and an error
 *      message is placed in interp->result.
 *      message is placed in interp->result.
 *
 *
 * Side effects:
 * Side effects:
 *      A reference count is incremented for the colormap, so
 *      A reference count is incremented for the colormap, so
 *      Tk_FreeColormap must eventually be called exactly once for
 *      Tk_FreeColormap must eventually be called exactly once for
 *      each call to Tk_GetColormap.
 *      each call to Tk_GetColormap.
 *
 *
 *----------------------------------------------------------------------
 *----------------------------------------------------------------------
 */
 */
 
 
Colormap
Colormap
Tk_GetColormap(interp, tkwin, string)
Tk_GetColormap(interp, tkwin, string)
    Tcl_Interp *interp;                 /* Interpreter to use for error
    Tcl_Interp *interp;                 /* Interpreter to use for error
                                         * reporting. */
                                         * reporting. */
    Tk_Window tkwin;                    /* Window where colormap will be
    Tk_Window tkwin;                    /* Window where colormap will be
                                         * used. */
                                         * used. */
    char *string;                       /* String that identifies colormap:
    char *string;                       /* String that identifies colormap:
                                         * either "new" or the name of
                                         * either "new" or the name of
                                         * another window. */
                                         * another window. */
{
{
    Colormap colormap;
    Colormap colormap;
    TkColormap *cmapPtr;
    TkColormap *cmapPtr;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;
    Tk_Window other;
    Tk_Window other;
 
 
    /*
    /*
     * Allocate a new colormap, if that's what is wanted.
     * Allocate a new colormap, if that's what is wanted.
     */
     */
 
 
    if (strcmp(string, "new") == 0) {
    if (strcmp(string, "new") == 0) {
        cmapPtr = (TkColormap *) ckalloc(sizeof(TkColormap));
        cmapPtr = (TkColormap *) ckalloc(sizeof(TkColormap));
        cmapPtr->colormap = XCreateColormap(Tk_Display(tkwin),
        cmapPtr->colormap = XCreateColormap(Tk_Display(tkwin),
                RootWindowOfScreen(Tk_Screen(tkwin)), Tk_Visual(tkwin),
                RootWindowOfScreen(Tk_Screen(tkwin)), Tk_Visual(tkwin),
                AllocNone);
                AllocNone);
        cmapPtr->visual = Tk_Visual(tkwin);
        cmapPtr->visual = Tk_Visual(tkwin);
        cmapPtr->refCount = 1;
        cmapPtr->refCount = 1;
        cmapPtr->shareable = 0;
        cmapPtr->shareable = 0;
        cmapPtr->nextPtr = dispPtr->cmapPtr;
        cmapPtr->nextPtr = dispPtr->cmapPtr;
        dispPtr->cmapPtr = cmapPtr;
        dispPtr->cmapPtr = cmapPtr;
        return cmapPtr->colormap;
        return cmapPtr->colormap;
    }
    }
 
 
    /*
    /*
     * Use a colormap from an existing window.  It must have the same
     * Use a colormap from an existing window.  It must have the same
     * visual as tkwin (which means, among other things, that the
     * visual as tkwin (which means, among other things, that the
     * other window must be on the same screen).
     * other window must be on the same screen).
     */
     */
 
 
    other = Tk_NameToWindow(interp, string, tkwin);
    other = Tk_NameToWindow(interp, string, tkwin);
    if (other == NULL) {
    if (other == NULL) {
        return None;
        return None;
    }
    }
    if (Tk_Screen(other) != Tk_Screen(tkwin)) {
    if (Tk_Screen(other) != Tk_Screen(tkwin)) {
        Tcl_AppendResult(interp, "can't use colormap for ", string,
        Tcl_AppendResult(interp, "can't use colormap for ", string,
                ": not on same screen", (char *) NULL);
                ": not on same screen", (char *) NULL);
        return None;
        return None;
    }
    }
    if (Tk_Visual(other) != Tk_Visual(tkwin)) {
    if (Tk_Visual(other) != Tk_Visual(tkwin)) {
        Tcl_AppendResult(interp, "can't use colormap for ", string,
        Tcl_AppendResult(interp, "can't use colormap for ", string,
                ": incompatible visuals", (char *) NULL);
                ": incompatible visuals", (char *) NULL);
        return None;
        return None;
    }
    }
    colormap = Tk_Colormap(other);
    colormap = Tk_Colormap(other);
 
 
    /*
    /*
     * If the colormap was a special one allocated by code in this file,
     * If the colormap was a special one allocated by code in this file,
     * increment its reference count.
     * increment its reference count.
     */
     */
 
 
    for (cmapPtr = dispPtr->cmapPtr; cmapPtr != NULL;
    for (cmapPtr = dispPtr->cmapPtr; cmapPtr != NULL;
            cmapPtr = cmapPtr->nextPtr) {
            cmapPtr = cmapPtr->nextPtr) {
        if (cmapPtr->colormap == colormap) {
        if (cmapPtr->colormap == colormap) {
            cmapPtr->refCount += 1;
            cmapPtr->refCount += 1;
        }
        }
    }
    }
    return colormap;
    return colormap;
}
}


/*
/*
 *----------------------------------------------------------------------
 *----------------------------------------------------------------------
 *
 *
 * Tk_FreeColormap --
 * Tk_FreeColormap --
 *
 *
 *      This procedure is called to release a colormap that was
 *      This procedure is called to release a colormap that was
 *      previously allocated by Tk_GetColormap.
 *      previously allocated by Tk_GetColormap.
 *
 *
 * Results:
 * Results:
 *      None.
 *      None.
 *
 *
 * Side effects:
 * Side effects:
 *      The colormap's reference count is decremented.  If this was the
 *      The colormap's reference count is decremented.  If this was the
 *      last reference to the colormap, then the colormap is freed.
 *      last reference to the colormap, then the colormap is freed.
 *
 *
 *----------------------------------------------------------------------
 *----------------------------------------------------------------------
 */
 */
 
 
void
void
Tk_FreeColormap(display, colormap)
Tk_FreeColormap(display, colormap)
    Display *display;                   /* Display for which colormap was
    Display *display;                   /* Display for which colormap was
                                         * allocated. */
                                         * allocated. */
    Colormap colormap;                  /* Colormap that is no longer needed.
    Colormap colormap;                  /* Colormap that is no longer needed.
                                         * Must have been returned by previous
                                         * Must have been returned by previous
                                         * call to Tk_GetColormap, or
                                         * call to Tk_GetColormap, or
                                         * preserved by a previous call to
                                         * preserved by a previous call to
                                         * Tk_PreserveColormap. */
                                         * Tk_PreserveColormap. */
{
{
    TkDisplay *dispPtr;
    TkDisplay *dispPtr;
    TkColormap *cmapPtr, *prevPtr;
    TkColormap *cmapPtr, *prevPtr;
 
 
    /*
    /*
     * Find Tk's information about the display, then see if this
     * Find Tk's information about the display, then see if this
     * colormap is a non-default one (if it's a default one, there
     * colormap is a non-default one (if it's a default one, there
     * won't be an entry for it in the display's list).
     * won't be an entry for it in the display's list).
     */
     */
 
 
    dispPtr = TkGetDisplay(display);
    dispPtr = TkGetDisplay(display);
    if (dispPtr == NULL) {
    if (dispPtr == NULL) {
        panic("unknown display passed to Tk_FreeColormap");
        panic("unknown display passed to Tk_FreeColormap");
    }
    }
    for (prevPtr = NULL, cmapPtr = dispPtr->cmapPtr; cmapPtr != NULL;
    for (prevPtr = NULL, cmapPtr = dispPtr->cmapPtr; cmapPtr != NULL;
            prevPtr = cmapPtr, cmapPtr = cmapPtr->nextPtr) {
            prevPtr = cmapPtr, cmapPtr = cmapPtr->nextPtr) {
        if (cmapPtr->colormap == colormap) {
        if (cmapPtr->colormap == colormap) {
            cmapPtr->refCount -= 1;
            cmapPtr->refCount -= 1;
            if (cmapPtr->refCount == 0) {
            if (cmapPtr->refCount == 0) {
                XFreeColormap(display, colormap);
                XFreeColormap(display, colormap);
                if (prevPtr == NULL) {
                if (prevPtr == NULL) {
                    dispPtr->cmapPtr = cmapPtr->nextPtr;
                    dispPtr->cmapPtr = cmapPtr->nextPtr;
                } else {
                } else {
                    prevPtr->nextPtr = cmapPtr->nextPtr;
                    prevPtr->nextPtr = cmapPtr->nextPtr;
                }
                }
                ckfree((char *) cmapPtr);
                ckfree((char *) cmapPtr);
            }
            }
            return;
            return;
        }
        }
    }
    }
}
}


/*
/*
 *----------------------------------------------------------------------
 *----------------------------------------------------------------------
 *
 *
 * Tk_PreserveColormap --
 * Tk_PreserveColormap --
 *
 *
 *      This procedure is called to indicate to Tk that the specified
 *      This procedure is called to indicate to Tk that the specified
 *      colormap is being referenced from another location and should
 *      colormap is being referenced from another location and should
 *      not be freed until all extra references are eliminated.  The
 *      not be freed until all extra references are eliminated.  The
 *      colormap must have been returned by Tk_GetColormap.
 *      colormap must have been returned by Tk_GetColormap.
 *
 *
 * Results:
 * Results:
 *      None.
 *      None.
 *
 *
 * Side effects:
 * Side effects:
 *      The colormap's reference count is incremented, so
 *      The colormap's reference count is incremented, so
 *      Tk_FreeColormap must eventually be called exactly once for
 *      Tk_FreeColormap must eventually be called exactly once for
 *      each call to Tk_PreserveColormap.
 *      each call to Tk_PreserveColormap.
 *
 *
 *----------------------------------------------------------------------
 *----------------------------------------------------------------------
 */
 */
 
 
void
void
Tk_PreserveColormap(display, colormap)
Tk_PreserveColormap(display, colormap)
    Display *display;                   /* Display for which colormap was
    Display *display;                   /* Display for which colormap was
                                         * allocated. */
                                         * allocated. */
    Colormap colormap;                  /* Colormap that should be
    Colormap colormap;                  /* Colormap that should be
                                         * preserved. */
                                         * preserved. */
{
{
    TkDisplay *dispPtr;
    TkDisplay *dispPtr;
    TkColormap *cmapPtr;
    TkColormap *cmapPtr;
 
 
    /*
    /*
     * Find Tk's information about the display, then see if this
     * Find Tk's information about the display, then see if this
     * colormap is a non-default one (if it's a default one, there
     * colormap is a non-default one (if it's a default one, there
     * won't be an entry for it in the display's list).
     * won't be an entry for it in the display's list).
     */
     */
 
 
    dispPtr = TkGetDisplay(display);
    dispPtr = TkGetDisplay(display);
    if (dispPtr == NULL) {
    if (dispPtr == NULL) {
        panic("unknown display passed to Tk_PreserveColormap");
        panic("unknown display passed to Tk_PreserveColormap");
    }
    }
    for (cmapPtr = dispPtr->cmapPtr; cmapPtr != NULL;
    for (cmapPtr = dispPtr->cmapPtr; cmapPtr != NULL;
            cmapPtr = cmapPtr->nextPtr) {
            cmapPtr = cmapPtr->nextPtr) {
        if (cmapPtr->colormap == colormap) {
        if (cmapPtr->colormap == colormap) {
            cmapPtr->refCount += 1;
            cmapPtr->refCount += 1;
            return;
            return;
        }
        }
    }
    }
}
}
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.