// // Copyright (C) 1996 Ben Ross // // You may distribute under the terms of the GNU General Public // License as specified in the COPYING file. // // $Id: XeGCTable.C,v 1.1 1996/11/17 09:25:47 ben Exp $ #include #include #include #include #define TABLESIZE 256 XeGCTable::XeGCTable(void) { _table = new TableElem*[TABLESIZE]; for(int i=0; i < TABLESIZE; i++) { _table[i] = NULL; } } XeGCTable::~XeGCTable(void) { TableElem **head; TableElem *temp; for(int i=0; i_next; XFreeGC(gDisplay, temp->_gContext); delete temp; } } delete[] _table; } GC XeGCTable::getGC(Window w, XGCValues* key, ulong flags) { GC theGC; // This GC has already been cached, so return it. if((theGC = exists(key, flags))) { //printf("Restoring GC 0x%08x from index: %d\n", theGC, hash(key, flags)); return theGC; } theGC = XCreateGC(gDisplay, w, flags, key); addGC(theGC, key, flags); return theGC; } uchar XeGCTable::charify(ulong val) { uchar b1, b2, b3, b4; b1 = val & 0x000000ff; b2 = (val & 0x0000ff00) >> 8; b3 = (val & 0x00ff0000) >> 16; b4 = (val & 0xff000000) >> 24; return b1 ^ b2 ^ b3 ^ b4; } uchar XeGCTable::hash(XGCValues* key, ulong flags) { uchar index = 0; if(flags & GCFunction) index ^= charify(key->function); if(flags & GCForeground) index ^= charify(key->foreground); if(flags & GCBackground) index ^= charify(key->background); if(flags & GCLineWidth) index ^= charify((ulong)key->line_width); if(flags & GCFont) index ^= charify((ulong)key->font); return index; } void XeGCTable::addGC(GC gc, XGCValues* key, ulong flags) { //printf("Adding GC 0x%08x at index: %d\n", gc, hash(key, flags)); TableElem **head = &_table[hash(key, flags)]; TableElem *elem = new TableElem; memcpy(&(elem->_key), key, sizeof(XGCValues)); elem->_gContext = gc; elem->_prev = NULL; if(*head) { (*head)->_prev = elem; } elem->_next = *head; *head = elem; } GC XeGCTable::exists(XGCValues* key, ulong flags) { TableElem *temp = _table[hash(key, flags)]; while(temp) { if(compare(key, &(temp->_key), flags)) return temp->_gContext; temp = temp->_next; } return NULL; } bool XeGCTable::compare(XGCValues* k1, XGCValues* k2, ulong flags) { if(!flags) return FALSE; if(flags & GCFunction && k1->function != k2->function) return FALSE; if(flags & GCPlaneMask && k1->plane_mask != k2->plane_mask) return FALSE; if(flags & GCForeground && k1->foreground != k2->foreground) return FALSE; if(flags & GCBackground && k1->background != k2->background) return FALSE; if(flags & GCLineWidth && k1->line_width != k2->line_width) return FALSE; if(flags & GCLineStyle && k1->line_style != k2->line_style) return FALSE; if(flags & GCCapStyle && k1->cap_style != k2->cap_style) return FALSE; if(flags & GCJoinStyle && k1->join_style != k2->join_style) return FALSE; if(flags & GCFillStyle && k1->fill_style != k2->fill_style) return FALSE; if(flags & GCFillRule && k1->fill_rule != k2->fill_rule) return FALSE; if(flags & GCArcMode && k1->arc_mode != k2->arc_mode) return FALSE; if(flags & GCTile && k1->tile != k2->tile) return FALSE; if(flags & GCStipple && k1->stipple != k2->stipple) return FALSE; if(flags & GCTileStipXOrigin && k1->ts_x_origin != k2->ts_x_origin) return FALSE; if(flags & GCTileStipYOrigin && k1->ts_y_origin != k2->ts_y_origin) return FALSE; if(flags & GCFont && k1->font != k2->font) return FALSE; if(flags & GCSubwindowMode && k1->subwindow_mode != k2->subwindow_mode) return FALSE; if(flags & GCGraphicsExposures && k1->graphics_exposures != k2->graphics_exposures) return FALSE; if(flags & GCClipXOrigin && k1->clip_x_origin != k2->clip_y_origin) return FALSE; if(flags & GCClipYOrigin && k1->clip_y_origin != k2->clip_y_origin) return FALSE; if(flags & GCClipMask && k1->clip_mask != k2->clip_mask) return FALSE; if(flags & GCDashOffset && k1->dash_offset != k2->dash_offset) return FALSE; if(flags & GCDashList && k1->dashes != k2->dashes) return FALSE; return TRUE; }