Tk_3DBorder Tk_Alloc3DBorderFromObj( Tcl_Interp *interp, /* Interp for error results. */ Tk_Window tkwin, /* Need the screen the border is used on.*/ Tcl_Obj *objPtr) /* Object giving name of color for window * background. */ { TkBorder *borderPtr; if (objPtr->typePtr != &tkBorderObjType) { InitBorderObj(objPtr); } borderPtr = (TkBorder *) objPtr->internalRep.twoPtrValue.ptr1; /* * If the object currently points to a TkBorder, see if it's the one we * want. If so, increment its reference count and return. */ if (borderPtr != NULL) { if (borderPtr->resourceRefCount == 0) { /* * This is a stale reference: it refers to a border that's no * longer in use. Clear the reference. */ FreeBorderObjProc(objPtr); borderPtr = NULL; } else if ((Tk_Screen(tkwin) == borderPtr->screen) && (Tk_Colormap(tkwin) == borderPtr->colormap)) { borderPtr->resourceRefCount++; return (Tk_3DBorder) borderPtr; } } /* * The object didn't point to the border that we wanted. Search the list * of borders with the same name to see if one of the others is the right * one. */ /* * If the cached value is NULL, either the object type was not a color * going in, or the object is a color type but had previously been freed. * * If the value is not NULL, the internal rep is the value of the color * the last time this object was accessed. Check the screen and colormap * of the last access, and if they match, we are done. */ if (borderPtr != NULL) { TkBorder *firstBorderPtr = (TkBorder *) Tcl_GetHashValue(borderPtr->hashPtr); FreeBorderObjProc(objPtr); for (borderPtr = firstBorderPtr ; borderPtr != NULL; borderPtr = borderPtr->nextPtr) { if ((Tk_Screen(tkwin) == borderPtr->screen) && (Tk_Colormap(tkwin) == borderPtr->colormap)) { borderPtr->resourceRefCount++; borderPtr->objRefCount++; objPtr->internalRep.twoPtrValue.ptr1 = (void *) borderPtr; return (Tk_3DBorder) borderPtr; } } } /* * Still no luck. Call Tk_Get3DBorder to allocate a new border. */ borderPtr = (TkBorder *) Tk_Get3DBorder(interp, tkwin, Tcl_GetString(objPtr)); objPtr->internalRep.twoPtrValue.ptr1 = (void *) borderPtr; if (borderPtr != NULL) { borderPtr->objRefCount++; } return (Tk_3DBorder) borderPtr; }
callGraphConsts::callGraphConsts(Tcl_Interp *interp, Tk_Window theTkWindow) { display = Tk_Display(theTkWindow); // needed in destructor textColor = Tk_GetColor(interp, theTkWindow, Tk_GetUid("black")); assert(textColor); // Root Item FontStruct's: Tk_Uid rootItemFontName = Tk_GetOption( theTkWindow, "listRootItemFont", "Font" ); assert( rootItemFontName != NULL ); rootItemFontStruct = Tk_GetFont( interp, theTkWindow, rootItemFontName ); Tk_Uid rootItemItalicFontName = Tk_GetOption( theTkWindow, "listRootItemEmphFont", "Font" ); assert( rootItemItalicFontName != NULL ); rootItemItalicFontStruct = Tk_GetFont( interp, theTkWindow, rootItemItalicFontName ); // Root Item Text GCs: XGCValues values; values.foreground = textColor->pixel; values.font = Tk_FontId(rootItemFontStruct); rootItemTextGC = Tk_GetGC(theTkWindow, GCForeground | GCFont, &values); assert(rootItemTextGC); values.font = Tk_FontId(rootItemItalicFontStruct); values.foreground = textColor->pixel; rootItemShadowTextGC = Tk_GetGC(theTkWindow, GCForeground | GCFont, &values); assert(rootItemShadowTextGC); // Listbox FontStruct's: Tk_Uid listboxItemFontName = Tk_GetOption( theTkWindow, "listItemFont", "Font" ); assert( listboxItemFontName ); listboxItemFontStruct = Tk_GetFont(interp, theTkWindow, listboxItemFontName ); Tk_Uid listboxItemItalicFontName = Tk_GetOption( theTkWindow, "listItemEmphFont", "Font" ); assert( listboxItemItalicFontName ); listboxItemItalicFontStruct = Tk_GetFont(interp, theTkWindow, listboxItemItalicFontName ); // Listbox Item Text GCs: values.foreground = textColor->pixel; values.font = Tk_FontId(listboxItemFontStruct); listboxItemGC = Tk_GetGC(theTkWindow, GCForeground | GCFont, &values); assert(listboxItemGC); values.font = Tk_FontId(listboxItemItalicFontStruct); values.foreground = textColor->pixel; listboxItemShadowTextGC = Tk_GetGC(theTkWindow, GCForeground | GCFont, &values); assert(listboxItemShadowTextGC); rootItemTk3DBordersByStyle.resize(2); //Color for non-recursive nodes rootItemTk3DBordersByStyle[0] = Tk_Get3DBorder(interp, theTkWindow, Tk_GetUid("gray")); assert(rootItemTk3DBordersByStyle[0]); //Color for recursive nodes rootItemTk3DBordersByStyle[1] = Tk_Get3DBorder(interp, theTkWindow, Tk_GetUid("#60c0a0")); //green assert(rootItemTk3DBordersByStyle[1]); listboxItemTk3DBordersByStyle = rootItemTk3DBordersByStyle; // 3D borders for listbox: // It seems reasonable to use the exact same colors for shg listbox items: //listboxScrollbarBorder = rootItemBorder; }
static int DoConfig( Tcl_Interp *interp, /* Interpreter for error reporting. */ Tk_Window tkwin, /* Window containing widget (needed to set up * X resources). */ Tk_ConfigSpec *specPtr, /* Specifier to apply. */ Tk_Uid value, /* Value to use to fill in widgRec. */ int valueIsUid, /* Non-zero means value is a Tk_Uid; zero * means it's an ordinary string. */ char *widgRec) /* Record whose fields are to be modified. * Values must be properly initialized. */ { char *ptr; Tk_Uid uid; int nullValue; nullValue = 0; if ((*value == 0) && (specPtr->specFlags & TK_CONFIG_NULL_OK)) { nullValue = 1; } do { ptr = widgRec + specPtr->offset; switch (specPtr->type) { case TK_CONFIG_BOOLEAN: if (Tcl_GetBoolean(interp, value, (int *) ptr) != TCL_OK) { return TCL_ERROR; } break; case TK_CONFIG_INT: if (Tcl_GetInt(interp, value, (int *) ptr) != TCL_OK) { return TCL_ERROR; } break; case TK_CONFIG_DOUBLE: if (Tcl_GetDouble(interp, value, (double *) ptr) != TCL_OK) { return TCL_ERROR; } break; case TK_CONFIG_STRING: { char *oldStr, *newStr; if (nullValue) { newStr = NULL; } else { newStr = (char *) ckalloc((unsigned) (strlen(value) + 1)); strcpy(newStr, value); } oldStr = *((char **) ptr); if (oldStr != NULL) { ckfree(oldStr); } *((char **) ptr) = newStr; break; } case TK_CONFIG_UID: if (nullValue) { *((Tk_Uid *) ptr) = NULL; } else { uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value); *((Tk_Uid *) ptr) = uid; } break; case TK_CONFIG_COLOR: { XColor *newPtr, *oldPtr; if (nullValue) { newPtr = NULL; } else { uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value); newPtr = Tk_GetColor(interp, tkwin, uid); if (newPtr == NULL) { return TCL_ERROR; } } oldPtr = *((XColor **) ptr); if (oldPtr != NULL) { Tk_FreeColor(oldPtr); } *((XColor **) ptr) = newPtr; break; } case TK_CONFIG_FONT: { Tk_Font newFont; if (nullValue) { newFont = NULL; } else { newFont = Tk_GetFont(interp, tkwin, value); if (newFont == NULL) { return TCL_ERROR; } } Tk_FreeFont(*((Tk_Font *) ptr)); *((Tk_Font *) ptr) = newFont; break; } case TK_CONFIG_BITMAP: { Pixmap newBmp, oldBmp; if (nullValue) { newBmp = None; } else { uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value); newBmp = Tk_GetBitmap(interp, tkwin, uid); if (newBmp == None) { return TCL_ERROR; } } oldBmp = *((Pixmap *) ptr); if (oldBmp != None) { Tk_FreeBitmap(Tk_Display(tkwin), oldBmp); } *((Pixmap *) ptr) = newBmp; break; } case TK_CONFIG_BORDER: { Tk_3DBorder newBorder, oldBorder; if (nullValue) { newBorder = NULL; } else { uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value); newBorder = Tk_Get3DBorder(interp, tkwin, uid); if (newBorder == NULL) { return TCL_ERROR; } } oldBorder = *((Tk_3DBorder *) ptr); if (oldBorder != NULL) { Tk_Free3DBorder(oldBorder); } *((Tk_3DBorder *) ptr) = newBorder; break; } case TK_CONFIG_RELIEF: uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value); if (Tk_GetRelief(interp, uid, (int *) ptr) != TCL_OK) { return TCL_ERROR; } break; case TK_CONFIG_CURSOR: case TK_CONFIG_ACTIVE_CURSOR: { Tk_Cursor newCursor, oldCursor; if (nullValue) { newCursor = None; } else { uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value); newCursor = Tk_GetCursor(interp, tkwin, uid); if (newCursor == None) { return TCL_ERROR; } } oldCursor = *((Tk_Cursor *) ptr); if (oldCursor != None) { Tk_FreeCursor(Tk_Display(tkwin), oldCursor); } *((Tk_Cursor *) ptr) = newCursor; if (specPtr->type == TK_CONFIG_ACTIVE_CURSOR) { Tk_DefineCursor(tkwin, newCursor); } break; } case TK_CONFIG_JUSTIFY: uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value); if (Tk_GetJustify(interp, uid, (Tk_Justify *) ptr) != TCL_OK) { return TCL_ERROR; } break; case TK_CONFIG_ANCHOR: uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value); if (Tk_GetAnchor(interp, uid, (Tk_Anchor *) ptr) != TCL_OK) { return TCL_ERROR; } break; case TK_CONFIG_CAP_STYLE: uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value); if (Tk_GetCapStyle(interp, uid, (int *) ptr) != TCL_OK) { return TCL_ERROR; } break; case TK_CONFIG_JOIN_STYLE: uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value); if (Tk_GetJoinStyle(interp, uid, (int *) ptr) != TCL_OK) { return TCL_ERROR; } break; case TK_CONFIG_PIXELS: if (Tk_GetPixels(interp, tkwin, value, (int *) ptr) != TCL_OK) { return TCL_ERROR; } break; case TK_CONFIG_MM: if (Tk_GetScreenMM(interp, tkwin, value, (double*)ptr) != TCL_OK) { return TCL_ERROR; } break; case TK_CONFIG_WINDOW: { Tk_Window tkwin2; if (nullValue) { tkwin2 = NULL; } else { tkwin2 = Tk_NameToWindow(interp, value, tkwin); if (tkwin2 == NULL) { return TCL_ERROR; } } *((Tk_Window *) ptr) = tkwin2; break; } case TK_CONFIG_CUSTOM: if ((*specPtr->customPtr->parseProc)( specPtr->customPtr->clientData, interp, tkwin, value, widgRec, specPtr->offset) != TCL_OK) { return TCL_ERROR; } break; default: { char buf[64 + TCL_INTEGER_SPACE]; sprintf(buf, "bad config table: unknown type %d", specPtr->type); Tcl_SetResult(interp, buf, TCL_VOLATILE); return TCL_ERROR; } } specPtr++; } while ((specPtr->argvName == NULL) && (specPtr->type != TK_CONFIG_END)); return TCL_OK; }
static void imfsample_display(ClientData cldata) { char *str; int row, col, namex, namey, n, sx, sy, update = FALSE, done; Imfsample *imfsample = (Imfsample *) cldata; Display *dpy = imfsample->display; Tk_Window tkwin = imfsample->tkwin; GC gc; Pixmap pm = None; Drawable d; Tk_Font tkfont; int winwidth = Tk_Width(Tk_Parent(tkwin)); int winheight = Tk_Height(Tk_Parent(tkwin)); char tclbuf[100]; int rslt; imfsample->update_pending = 0; if (!Tk_IsMapped(tkwin)) { return; } /* Check if we need to redraw the entire imfsample. */ if (imfsample->imfapp) { if (imfsample->oldfirst != imfsample->firstvisrow || imfsample->redraw) { imfsample->oldfirst = imfsample->firstvisrow; update = TRUE; } } /* Create a pixmap for double-buffering if necessary. */ if (imfsample->double_buffer) { update = TRUE; pm = Tk_GetPixmap(imfsample->display, Tk_WindowId(tkwin), Tk_Width(tkwin), Tk_Height(tkwin), DefaultDepthOfScreen(Tk_Screen(tkwin))); d = pm; } else { d = Tk_WindowId(tkwin); } if (black_color == NULL) { black_color = Tk_GetColor(interp, tkwin, Tk_GetUid("black")); } if (white_color == NULL) { white_color = Tk_GetColor(interp, tkwin, Tk_GetUid("white")); } if (black_border == NULL) { black_border = Tk_Get3DBorder(interp, tkwin, "black"); } if (white_border == NULL) { white_border = Tk_Get3DBorder(interp, tkwin, "white"); } /* Collect GC and font for subsequent work. */ gc = imfsample->gc; XSetClipMask(dpy, gc, None); if (imfsample->show_names) { #ifdef WIN32 tkfont = Tk_GetFont(interp, tkwin, "-family arial -size 8"); #elif defined (MAC) tkfont = Tk_GetFont(interp, tkwin, "-family helvetica -size 11"); #else tkfont = Tk_GetFont(interp, tkwin, "-family helvetica -size 12"); #endif XSetFont(imfsample->display, gc, Tk_FontId(tkfont)); } /* Redraw the entire widget background/border, but not if we are just updating the selected image. */ if (imfsample->selected == imfsample->previous /* Always redraw if we have only one image (e.g. closeups). */ || (imfsample->numimages == 1 && imfsample->selected == -1) || update) { done = FALSE; if (imfsample->with_terrain >= 0 /* Terrain tiles are not supported on Windows yet. */ && use_clip_mask) { ImageFamily *timf = imfsample->imf_list[imfsample->with_terrain]; Image *timg; TkImage *tkimg; timg = best_image(timf, 64, 64); if (timg) { tkimg = (TkImage *) timg->hook; if (tkimg && tkimg->colr) { XSetFillStyle(dpy, gc, FillTiled); XSetTile(dpy, gc, tkimg->colr); XFillRectangle(dpy, d, gc, 0, 0, Tk_Width(tkwin), Tk_Height(tkwin)); done = TRUE; } } } if (!done) { Tk_Fill3DRectangle(tkwin, d, imfsample->bg_border, 0, 0, Tk_Width(tkwin), Tk_Height(tkwin), imfsample->border_width, imfsample->relief); } } #if 0 for (i = 0; i < imfsample->numimages; i++) { if (imf_interp_hook) imfsample->imf_list[i] = (*imf_interp_hook)(imfsample->imf_list[i], NULL, TRUE); } #endif /* Tweak the default item width/height to something better. */ if (imfsample->iheight == 0) { imfsample->iheight = 32; if (imfsample->numimages == 1) imfsample->iheight = imfsample->height; } if (imfsample->iwidth == 0) { imfsample->iwidth = 32; if (imfsample->numimages == 1) imfsample->iwidth = imfsample->width; } imfsample->eltw = imfsample->iwidth; if (imfsample->show_grid) imfsample->eltw += 2; else imfsample->eltw += 2 * imfsample->pad; if (imfsample->show_names && !imfsample->show_grid) imfsample->eltw += 80; imfsample->elth = imfsample->iheight; if (imfsample->show_grid) imfsample->elth += 2; else imfsample->elth += 2 * imfsample->pad; /* Fix a lower bound on the vertical spacing. */ /* (should be determined by choice of app font) */ if (imfsample->elth < 10 && !imfsample->show_grid) imfsample->elth = 10; /* Compute and save the number of columns to use. */ imfsample->cols = winwidth / imfsample->eltw; if (imfsample->cols <= 0) imfsample->cols = 1; /* We can get a little wider spacing by recalculating the element width. */ if (imfsample->show_names && !imfsample->show_grid) imfsample->eltw = (winwidth - 10) / imfsample->cols; imfsample->rows = imfsample->numimages / imfsample->cols; /* Account for a last partial row. */ if (imfsample->rows * imfsample->cols < imfsample->numimages) ++(imfsample->rows); /* Compute the number of visible rows. It would be time-consuming to render all the images, so try to do only the visible ones. */ imfsample->numvisrows = winheight / imfsample->elth; if (imfsample->numvisrows > imfsample->rows) imfsample->numvisrows = imfsample->rows; if (imfsample->numvisrows < 1) imfsample->numvisrows = min(1, imfsample->rows); if (imfsample->firstvisrow + imfsample->numvisrows > imfsample->rows) imfsample->firstvisrow = imfsample->rows - imfsample->numvisrows; /* Imfapp-specific code that adjusts the canvas content to fit a resized window and also sets the canvas scrollregion correctly. */ if (imfsample->imfapp && imfsample->redraw) { imfsample->width = Tk_Width(Tk_Parent(tkwin)); imfsample->height = imfsample->rows * imfsample->elth + 7; Tk_GeometryRequest(tkwin, imfsample->width, imfsample->height); /* There must be a better way to do this ... */ sprintf(tclbuf, ".images.canvas configure -scrollregion [ list 0 0 0 %d ]", imfsample->height); rslt = Tcl_Eval(interp, tclbuf); if (rslt == TCL_ERROR) { fprintf(stderr, "Error: %s\n", Tcl_GetStringResult(interp)); } /* Force a redraw of the scrollbar if the window was resized. */ if (imfsample->numimages) { sprintf(tclbuf, ".images.canvas.content yview scroll 0 units"); } else { sprintf(tclbuf, ".images.scroll set 0 1"); } rslt = Tcl_Eval(interp, tclbuf); if (rslt == TCL_ERROR) { fprintf(stderr, "Error: %s\n", Tcl_GetStringResult(interp)); } } /* Now iterate through all the images we want to draw. */ for (row = imfsample->firstvisrow; row <= (imfsample->firstvisrow + imfsample->numvisrows); ++row) { if (row < 0) continue; for (col = 0; col < imfsample->cols; ++col) { n = row * imfsample->cols + col; if (n >= imfsample->numimages) break; sx = col * imfsample->eltw; sy = (row - imfsample->firstvisrow) * imfsample->elth; /* Erase the old selected imf if we picked a new one. */ if (n == imfsample->previous && n != imfsample->selected) { done = FALSE; if (imfsample->with_terrain >= 0 /* Terrain tiles are not supported on Windows yet. */ && use_clip_mask) { ImageFamily *timf = imfsample->imf_list[imfsample->with_terrain]; Image *timg; TkImage *tkimg; timg = best_image(timf, 64, 64); if (timg) { tkimg = (TkImage *) timg->hook; if (tkimg && tkimg->colr) { XSetFillStyle(dpy, gc, FillTiled); XSetTile(dpy, gc, tkimg->colr); if (imfsample->show_grid) { XFillRectangle(dpy, d, gc, sx, sy + 2, imfsample->eltw, imfsample->elth); } else { XFillRectangle(dpy, d, gc, sx, sy + 7, imfsample->eltw, imfsample->elth); } done = TRUE; } } } if (!done) { if (imfsample->show_grid) { Tk_Fill3DRectangle(tkwin, d, imfsample->bg_border, sx, sy + 2, imfsample->eltw, imfsample->elth, imfsample->border_width, imfsample->relief); } else { Tk_Fill3DRectangle(tkwin, d, imfsample->bg_border, sx, sy + 7, imfsample->eltw, imfsample->elth, imfsample->border_width, imfsample->relief); } } } /* Just draw the old erased image if we selected a new one, else draw every image. */ if (imfsample->selected == imfsample->previous || n == imfsample->previous || update) { if (imfsample->show_grid) { Tk_Fill3DRectangle(tkwin, d, imfsample->cu_border, sx + 2, sy + 2, imfsample->iwidth, imfsample->iheight, imfsample->border_width, imfsample->relief); draw_one_main_image(imfsample, d, gc, imfsample->imf_list[n], sx + 2, sy + 2, imfsample->iwidth, imfsample->iheight); } else { draw_one_main_image(imfsample, d, gc, imfsample->imf_list[n], sx + imfsample->pad, sy + imfsample->pad, imfsample->iwidth, imfsample->iheight); } if (imfsample->show_names && !imfsample->show_grid) { namex = sx + 5; namey = sy + imfsample->elth + 3; XSetClipMask(dpy, gc, None); XSetFillStyle(dpy, gc, FillSolid); XSetForeground(dpy, gc, Tk_3DBorderColor( imfsample->fg_border)->pixel); str = imfsample->imf_list[n]->name; Tk_DrawChars(dpy, d, gc, tkfont, str, strlen(str), namex, namey); } } /* Box the selected imf. */ if (n == imfsample->selected) { XSetClipMask(dpy, gc, None); XSetFillStyle(dpy, gc, FillSolid); XSetForeground(dpy, gc, Tk_3DBorderColor(imfsample->fg_border)->pixel); if (imfsample->show_grid) { /* A rectangle on the Mac is 1 pixel smaller in both directions. */ #ifdef MAC XDrawRectangle(dpy, d, gc, sx + 2, sy + 2, imfsample->eltw - 2, imfsample->elth - 2); #else XDrawRectangle(dpy, d, gc, sx + 2, sy + 2, imfsample->eltw - 3, imfsample->elth - 3); #endif } else { #ifdef MAC XDrawRectangle(dpy, d, gc, sx, sy + 7, imfsample->eltw, imfsample->elth); #else XDrawRectangle(dpy, d, gc, sx, sy + 7, imfsample->eltw - 1, imfsample->elth - 1); #endif } } } } /* Reset the old selected image to the new one if it exists. */ if (imfsample->selected != -1) { imfsample->previous = imfsample->selected; } /* Reset the redraw flag. */ imfsample->redraw = FALSE; /* If double-buffered, copy to the screen and release the pixmap. */ if (imfsample->double_buffer) { XCopyArea(imfsample->display, pm, Tk_WindowId(tkwin), imfsample->copygc, 0, 0, (unsigned) winwidth, (unsigned) winheight, 0, 0); Tk_FreePixmap(imfsample->display, pm); } if (imfsample->show_names) { Tk_FreeFont(tkfont); } /* In theory this shouldn't be necessary, but in practice the interface widgets (esp. the progress bar fill color) are affected by the last value of the foreground left over from drawing, so set to a consistent value. */ /* (Note that as of 2000-09-16, some color errors persist, so this might not really be necessary -sts) */ XSetForeground(imfsample->display, imfsample->gc, black_color->pixel); XSetBackground(imfsample->display, imfsample->gc, white_color->pixel); XSetForeground(imfsample->display, imfsample->copygc, black_color->pixel); XSetBackground(imfsample->display, imfsample->copygc, white_color->pixel); }