Annotation of researchv9/X11/src/X.V11R1/lib/X/Context.c, revision 1.1.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.