Annotation of researchv9/X11/src/X.V11R1/lib/X/Context.c, revision 1.1

1.1     ! root        1: /* $Header: Context.c,v 1.1 87/09/11 08:16:18 toddb Exp $ */
        !             2: #ifndef lint
        !             3: static char *sccsid = "@(#)Context.c   1.5     2/24/87";
        !             4: #endif lint
        !             5: 
        !             6: /*
        !             7:  * Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
        !             8:  * 
        !             9:  *                         All Rights Reserved
        !            10:  * 
        !            11:  * Permission to use, copy, modify, and distribute this software and its 
        !            12:  * documentation for any purpose and without fee is hereby granted, 
        !            13:  * provided that the above copyright notice appear in all copies and that
        !            14:  * both that copyright notice and this permission notice appear in 
        !            15:  * supporting documentation, and that the name of Digital Equipment
        !            16:  * Corporation not be used in advertising or publicity pertaining to
        !            17:  * distribution of the software without specific, written prior permission.  
        !            18:  * 
        !            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: 
        !            29: 
        !            30: /* Created by weissman, Thu Jun 26 15:18:59 1986 */
        !            31: 
        !            32: /* This module implements a simple sparse array.
        !            33: 
        !            34:    XSaveContext(a,b,c,d) will store d in position (a,b,c) of the array.
        !            35:    XFindContext(a,b,c,&d) will set d to be the value in position (a,b,c).
        !            36:    XDeleteContext(a,b,c) will delete the entry in (a,b,c).
        !            37: 
        !            38:    a is a display id, b is a window id, and c is a Context.  d is just a
        !            39:    caddr_t.  This code will work with any range of parameters, but is geared
        !            40:    to be most efficient with very few (one or two) different a's.
        !            41: 
        !            42: */
        !            43: 
        !            44: #include <stdio.h>
        !            45: #include "Xlib.h"
        !            46: #include "Xutil.h"
        !            47: #include "Xlibos.h"
        !            48: 
        !            49: #define INITHASHSIZE 1024 /* Number of entries originally in the hash table. */
        !            50: 
        !            51: 
        !            52: typedef struct _TableEntryRec {        /* Stores one entry. */
        !            53:     Window                     window;
        !            54:     XContext                   context;
        !            55:     caddr_t                    data;
        !            56:     struct _TableEntryRec      *next;
        !            57: } TableEntryRec, *TableEntry;
        !            58: 
        !            59: typedef struct _DspRec {       /* Stores hash table for one display. */
        !            60:     Display *display;          /* Which display this is a hash for. */
        !            61:     TableEntry *table;         /* Pointer to array of hash entries. */
        !            62:     int size;                  /* Current size of hash table. */
        !            63:     int numentries;            /* Number of entries currently in table. */
        !            64:     int maxentries;            /* How many entries we can take before
        !            65:                                   increasing table size. */
        !            66: } DspRec, *Dsp;
        !            67: 
        !            68: static Dsp *DspArray = NULL;   /* Pointer to array of display entries. */
        !            69: static int numDsp = 0;         /* How many display entries we have. */
        !            70: 
        !            71: 
        !            72: /* Assign dsp to be the Dsp entry that contains display. */
        !            73: 
        !            74: static Dsp lastdsp = NULL;
        !            75: #define FindCorrectDsp \
        !            76:        if (lastdsp && display == lastdsp->display) dsp = lastdsp; \
        !            77:        else dsp = lastdsp = FindDsp(display);
        !            78: 
        !            79: 
        !            80: /* Given a Window and a context, returns a value between 0 and HashSize-1.
        !            81:    Currently, this requires that HashSize be a power of 2.
        !            82: */
        !            83: 
        !            84: #define HashValue(window, context, HashSize) \
        !            85:     ((((int)window << 3) + (int)context) & ((HashSize) - 1))
        !            86: 
        !            87: 
        !            88: /* Resize the given dsp to have the given number of hash buckets. */
        !            89: 
        !            90: static int ResizeTable(dsp, NewSize)
        !            91: Dsp dsp;
        !            92: int NewSize;
        !            93: {
        !            94:     TableEntry *OldHashTable;
        !            95:     register TableEntry CurEntry, NextEntry;
        !            96:     register int i, OldHashSize, CurHash;
        !            97:     OldHashTable = dsp->table;
        !            98:     OldHashSize = dsp->size;
        !            99:     dsp->table = (TableEntry *) Xcalloc((unsigned)NewSize,sizeof(TableEntry));
        !           100:     if (dsp->table == NULL) {
        !           101:        dsp->table = OldHashTable;
        !           102:        return XCNOMEM;
        !           103:     }
        !           104:     dsp->size = NewSize;
        !           105:     dsp->maxentries = NewSize; /* When to next resize the hash table. */
        !           106:     if (OldHashTable != NULL) {
        !           107:        for (i=0 ; i<OldHashSize ; i++) {
        !           108:            CurEntry = OldHashTable[i] ;
        !           109:            while (CurEntry != NULL) {
        !           110:                (void) XDeleteContext(dsp->display,
        !           111:                                       CurEntry->window, CurEntry->context);
        !           112:                NextEntry = CurEntry->next;
        !           113:                CurHash = HashValue(CurEntry->window, CurEntry->context,
        !           114:                                    NewSize);
        !           115:                CurEntry->next = dsp->table[CurHash];
        !           116:                dsp->table[CurHash] = CurEntry;
        !           117:                CurEntry = NextEntry;
        !           118:            }
        !           119:        }
        !           120:        Xfree((char *) OldHashTable);
        !           121:     }
        !           122:     return 0;
        !           123: }
        !           124: 
        !           125: 
        !           126: /* Given a display, find the corresponding dsp. */
        !           127: 
        !           128: static Dsp FindDsp(display)
        !           129: Display *display;
        !           130: {
        !           131:     int i;
        !           132:     Dsp dsp;
        !           133:     for (i=0 ; i<numDsp ; i++)
        !           134:        if (DspArray[i]->display == display) return DspArray[i];
        !           135:     numDsp++;
        !           136:     if (DspArray == NULL)
        !           137:        DspArray = (Dsp *) Xmalloc(sizeof(Dsp));
        !           138:     else
        !           139:        DspArray = (Dsp *) Xrealloc(
        !           140:                (char *)DspArray, (unsigned) sizeof(Dsp) * numDsp);
        !           141:     dsp = DspArray[numDsp - 1] = (Dsp) Xmalloc(sizeof(DspRec));
        !           142:     dsp->display = display;
        !           143:     dsp->table = NULL;
        !           144:     dsp->size = INITHASHSIZE / 2;
        !           145:     dsp->numentries = 0;
        !           146:     dsp->maxentries = -1;
        !           147:     (void) ResizeTable(dsp, dsp->size * 2);
        !           148:     return dsp;
        !           149: }
        !           150: 
        !           151: 
        !           152: 
        !           153: /* Public routines. */
        !           154: 
        !           155: /* Save the given value of data to correspond with the keys Window and context.
        !           156:    If an entry with the given Window and context already exists, this one will 
        !           157:    override it; however, such an override has costs in time and space.  It
        !           158:    is better to call XDeleteContext first if you know the entry already exists.
        !           159:    Returns nonzero error code if an error has occured, 0 otherwise.
        !           160:    Possible errors are Out-of-memory.
        !           161: */   
        !           162: 
        !           163: int XSaveContext(display, window, context, data)
        !           164: register Display *display;
        !           165: register Window window;
        !           166: register XContext context;
        !           167: caddr_t data;
        !           168: {
        !           169:     register int CurHash;
        !           170:     register TableEntry CurEntry;
        !           171:     register Dsp dsp;
        !           172:     FindCorrectDsp;
        !           173:     if (++(dsp->numentries) > dsp->maxentries) 
        !           174:        if (ResizeTable(dsp, dsp->size * 2) == XCNOMEM)
        !           175:            return XCNOMEM;
        !           176:     CurEntry = (TableEntry) Xmalloc(sizeof(TableEntryRec));
        !           177:     if (CurEntry == NULL) return XCNOMEM;
        !           178:     CurEntry->window = window;
        !           179:     CurEntry->context = context;
        !           180:     CurEntry->data = data;
        !           181:     CurHash = HashValue(window, context, dsp->size);
        !           182:     CurEntry->next = dsp->table[CurHash];
        !           183:     dsp->table[CurHash] = CurEntry;
        !           184:     return 0;
        !           185: }
        !           186: 
        !           187: 
        !           188: 
        !           189: /* Given a window and context, returns the associated data.  Note that data 
        !           190:    here is a pointer since it is a return value.  Returns nonzero error code
        !           191:    if an error has occured, 0 otherwise.  Possible errors are Entry-not-found.
        !           192: */
        !           193: 
        !           194: int XFindContext(display, window, context, data)
        !           195: register Display *display;
        !           196: register Window window;
        !           197: register XContext context;
        !           198: caddr_t *data;                 /* RETURN */
        !           199: {
        !           200:     register TableEntry CurEntry;
        !           201:     register Dsp dsp;
        !           202:     FindCorrectDsp;
        !           203:     for (CurEntry = dsp->table[HashValue(window, context, dsp->size)];
        !           204:         CurEntry != NULL;
        !           205:         CurEntry = CurEntry->next)
        !           206:     {
        !           207:        if (CurEntry->window == window && CurEntry->context == context) {
        !           208:            *data = CurEntry->data;
        !           209:            return 0;
        !           210:        }
        !           211:     }
        !           212:     return XCNOENT;
        !           213: }
        !           214: 
        !           215: 
        !           216: 
        !           217: /* Deletes all entries for the given window and context from the datastructure.
        !           218:    This returns the same thing that FindContext would have returned if called
        !           219:    with the same arguments.
        !           220: */
        !           221: 
        !           222: int XDeleteContext(display, window, context)
        !           223: register Display *display;
        !           224: register Window window;
        !           225: register XContext context;
        !           226: {
        !           227:     register int CurHash;
        !           228:     int Result;
        !           229:     register TableEntry CurEntry, PrevEntry, NextEntry;
        !           230:     register Dsp dsp;
        !           231: 
        !           232:     FindCorrectDsp;
        !           233:     Result = XCNOENT;
        !           234:     CurHash = HashValue(window, context, dsp->size);
        !           235:     PrevEntry = NULL;
        !           236:     CurEntry = dsp->table[CurHash];
        !           237:     while (CurEntry != NULL) {
        !           238:        if (CurEntry->window == window && CurEntry->context == context) {
        !           239:            dsp->numentries--;
        !           240:            Result = 0;
        !           241:            NextEntry = CurEntry->next;
        !           242:            if (PrevEntry == NULL) {
        !           243:                dsp->table[CurHash] = NextEntry;
        !           244:            } else {
        !           245:                PrevEntry->next = NextEntry;
        !           246:            }
        !           247:            Xfree((char *) CurEntry);
        !           248:            CurEntry = NextEntry;
        !           249:        } else {
        !           250:            PrevEntry = CurEntry;
        !           251:            CurEntry = CurEntry->next;
        !           252:        }
        !           253:     }
        !           254:     return Result;
        !           255: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.