コード例 #1
0
ファイル: grTkCommon.c プロジェクト: radc/qflow
bool
grTkLoadFont()
{
    Tk_Window tkwind;
    int i;
    char *s;
    char *unable = "Unable to load font";

    static char *fontnames[4] = {
      TK_FONT_SMALL,
      TK_FONT_MEDIUM,
      TK_FONT_LARGE,
      TK_FONT_XLARGE };
    static char *optionnames[4] = {
      "small",
      "medium",
      "large",
      "xlarge"};

    tkwind = Tk_MainWindow(magicinterp);
    for (i = 0; i < 4; i++)
    {
    	s = XGetDefault(grXdpy, "magic", optionnames[i]);
	if (s) fontnames[i] = s;
        if ((grTkFonts[i] = Tk_GetFont(magicinterp,
			tkwind, fontnames[i])) == NULL) 
        {
	    TxError("%s %s\n", unable, fontnames[i]);
            if ((grTkFonts[i] = Tk_GetFont(magicinterp,
			tkwind, TK_DEFAULT_FONT)) == NULL) 
	    {
	        TxError("%s %s\n", unable, TK_DEFAULT_FONT);
		return FALSE;
	    }
        }
    }
    return TRUE;
}
コード例 #2
0
ファイル: tclwinfont.c プロジェクト: AndresGG/sn-8.4
static int
win_choose_font (ClientData cd, Tcl_Interp *interp, int argc, char **argv)
{
  char *deffont;
  Tk_Window parent;
  int i, oldMode;
  CHOOSEFONT cf;
  LOGFONT lf;
  HDC hdc;
  HFONT hfont;
  char facebuf[LF_FACESIZE];
  TEXTMETRIC tm;
  int pointsize;
  char *s;
  Tcl_DString resultStr;             /* used to translate result in UTF8 in Tcl/Tk8.1 */
  deffont = NULL;
  parent = Tk_MainWindow (interp);

  for (i = 1; i < argc; i += 2)
    {
      if (i + 1 >= argc)
	{
	  Tcl_ResetResult (interp);
	  Tcl_AppendStringsToObj (Tcl_GetObjResult (interp),
				  "value for \"", argv[i], "\" missing",
				  (char *) NULL);
	  return TCL_ERROR;
	}

      if (strcmp (argv[i], "-default") == 0)
	deffont = argv[i + 1];
      else if (strcmp (argv[i], "-parent") == 0)
	{
	  parent = Tk_NameToWindow (interp, argv[i + 1],
				    Tk_MainWindow (interp));
	  if (parent == NULL)
	    return TCL_ERROR;
	}
      else
	{
	  Tcl_ResetResult (interp);
	  Tcl_AppendStringsToObj (Tcl_GetObjResult (interp),
				  "unknown option \"", argv[i], "\"",
				  (char *) NULL);
	  return TCL_ERROR;
	}
    }

  memset (&cf, 0, sizeof (CHOOSEFONT));
  cf.lStructSize = sizeof (CHOOSEFONT);

  if (Tk_WindowId (parent) == None)
    Tk_MakeWindowExist (parent);
  cf.hwndOwner = Tk_GetHWND (Tk_WindowId (parent));

  cf.lpLogFont = &lf;
  cf.Flags = CF_SCREENFONTS | CF_FORCEFONTEXIST;

  memset (&lf, 0, sizeof (LOGFONT));

  if (deffont != NULL)
    {
      Tk_Font tkfont;
      const TkFontAttributes *fa;

      tkfont = Tk_GetFont (interp, parent, deffont);
      if (tkfont == NULL)
	return TCL_ERROR;

      cf.Flags |= CF_INITTOLOGFONTSTRUCT;

      /* In order to initialize LOGFONT, we need to extract the real
	 font attributes from the Tk internal font information.  */
      fa = &((TkFont *) tkfont)->fa;

      /* This code is taken from TkpGetFontFromAttributes.  It
         converts a TkFontAttributes structure into a LOGFONT
         structure.  */
#if (TCL_MAJOR_VERSION >= 8) && (TCL_MINOR_VERSION >= 1)
      lf.lfHeight = - fa->size;
#else
      lf.lfHeight = - fa->pointsize;
#endif
      if (lf.lfHeight < 0)
	lf.lfHeight = MulDiv (lf.lfHeight,
			      254 * WidthOfScreen (Tk_Screen (parent)),
			      720 * WidthMMOfScreen (Tk_Screen (parent)));
      lf.lfWeight = fa->weight == TK_FW_NORMAL ? FW_NORMAL : FW_BOLD;
      lf.lfItalic = fa->slant;
      lf.lfUnderline = fa->underline;
      lf.lfStrikeOut = fa->overstrike;
      lf.lfCharSet = DEFAULT_CHARSET;
      lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
      lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
      lf.lfQuality = DEFAULT_QUALITY;
      lf.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
      if (fa->family == NULL)
	lf.lfFaceName[0] = '\0';
      else
	strncpy (lf.lfFaceName, fa->family, sizeof (lf.lfFaceName));

      Tk_FreeFont (tkfont);
    }

  oldMode = Tcl_SetServiceMode(TCL_SERVICE_ALL);
  if (! ChooseFont (&cf))
    {
      DWORD code;

      code = CommDlgExtendedError ();
      if (code == 0)
	{
	  /* The user pressed cancel.  */
	  Tcl_ResetResult (interp);
	  return TCL_OK;
	}
      else
	{
	  char buf[200];

	  sprintf (buf, "Windows common dialog error 0x%lx", (unsigned long) code);
	  Tcl_ResetResult (interp);
          #if (TCL_MAJOR_VERSION >= 8) && (TCL_MINOR_VERSION >= 1)
            Tcl_ExternalToUtfDString(NULL, buf, -1, &resultStr);
          #else
            Tcl_InitDString(&resultStr);
            Tcl_DStingAppend(&resultStr, buf, -1);
          #endif
	  Tcl_AppendStringsToObj (Tcl_GetObjResult (interp),
				  Tcl_DStringValue(&resultStr),
				  (char *) NULL);
          Tcl_DStringFree(&resultStr);
	  return TCL_ERROR;
	}
    }
  Tcl_SetServiceMode(oldMode);
  /* We now have a LOGFONT structure.  We store it into a device
     context, and then extract enough information to build a Tk font
     specification.  With luck, when Tk interprets the font
     specification it will wind up with the font that the user expects
     to see.  Some of this code is taken from AllocFont.  */

  hfont = CreateFontIndirect (&lf);
  if (hfont == NULL)
    {
      /* This should be impossible.  */
      #if (TCL_MAJOR_VERSION >= 8) && (TCL_MINOR_VERSION >= 1)
        Tcl_ExternalToUtfDString(NULL, "CreateFontIndirect failed on chosen font", -1, &resultStr);
      #else
        Tcl_InitDString(&resultStr);
        Tcl_DStingAppend(&resultStr, "CreateFontIndirect failed on chosen font", -1);
      #endif
      Tcl_SetResult (interp, Tcl_DStringValue(&resultStr), TCL_STATIC);
      Tcl_DStringFree(&resultStr);
      return TCL_ERROR;
    }

  hdc = GetDC (cf.hwndOwner);
  hfont = SelectObject (hdc, hfont);
  GetTextFace (hdc, sizeof (facebuf), facebuf);
  GetTextMetrics (hdc, &tm);

  Tcl_ResetResult (interp);

#if (TCL_MAJOR_VERSION >= 8) && (TCL_MINOR_VERSION >= 1)
  Tcl_ExternalToUtfDString(NULL, facebuf, -1, &resultStr);
#else
  Tcl_InitDString(&resultStr);
  Tcl_DStingAppend(&resultStr,facebuf,-1);
#endif

  if (Tcl_ListObjAppendElement (interp, Tcl_GetObjResult (interp),
				Tcl_NewStringObj (Tcl_DStringValue(&resultStr), -1)) != TCL_OK) {
    Tcl_DStringFree(&resultStr);
    return TCL_ERROR;
  }

  Tcl_DStringFree(&resultStr);

  pointsize = MulDiv (tm.tmHeight - tm.tmInternalLeading,
		      720 * WidthMMOfScreen (Tk_Screen (parent)),
		      254 * WidthOfScreen (Tk_Screen (parent)));

  if (Tcl_ListObjAppendElement (interp, Tcl_GetObjResult (interp),
				Tcl_NewIntObj (pointsize)) != TCL_OK) {
     return TCL_ERROR;
  }

   if (tm.tmWeight > FW_MEDIUM)
    s = "bold";
  else
    s = "normal";

#if (TCL_MAJOR_VERSION >= 8) && (TCL_MINOR_VERSION >= 1)
  Tcl_ExternalToUtfDString(NULL, s, -1, &resultStr);
#else
  Tcl_InitDString(&resultStr);
  Tcl_DStingAppend(&resultStr, s, -1);
#endif

  if (Tcl_ListObjAppendElement (interp, Tcl_GetObjResult (interp),
				Tcl_NewStringObj (Tcl_DStringValue(&resultStr), -1)) != TCL_OK) {
    Tcl_DStringFree(&resultStr);
    return TCL_ERROR;
  }

  Tcl_DStringFree(&resultStr);

  if (tm.tmItalic)
    s = "italic";
  else
    s = "roman";

#if (TCL_MAJOR_VERSION >= 8) && (TCL_MINOR_VERSION >= 1)
  Tcl_ExternalToUtfDString(NULL, s, -1, &resultStr);
#else
  Tcl_InitDString(&resultStr);
  Tcl_DStingAppend(&resultStr, s, -1);
#endif

  if (Tcl_ListObjAppendElement (interp, Tcl_GetObjResult (interp),
				Tcl_NewStringObj (Tcl_DStringValue(&resultStr), -1)) != TCL_OK) {
    Tcl_DStringFree(&resultStr);
    return TCL_ERROR;
  }
  Tcl_DStringFree(&resultStr);

  if (tm.tmUnderlined)
    {
      #if (TCL_MAJOR_VERSION >= 8) && (TCL_MINOR_VERSION >= 1)
        Tcl_ExternalToUtfDString(NULL, "underline", -1, &resultStr);
      #else
        Tcl_InitDString(&resultStr);
        Tcl_DStingAppend(&resultStr,"underline",-1);
      #endif
      if (Tcl_ListObjAppendElement (interp, Tcl_GetObjResult (interp),
				    Tcl_NewStringObj (Tcl_DStringValue(&resultStr), -1))
	  != TCL_OK) {
        Tcl_DStringFree(&resultStr);
	return TCL_ERROR;
      }
      Tcl_DStringFree(&resultStr);
    }

  if (tm.tmStruckOut)
    {
      #if (TCL_MAJOR_VERSION >= 8) && (TCL_MINOR_VERSION >= 1)
        Tcl_ExternalToUtfDString(NULL, "overstrike", -1, &resultStr);
      #else
        Tcl_InitDString(&resultStr);
        Tcl_DStingAppend(&resultStr, "overstrike", -1);
      #endif
      if (Tcl_ListObjAppendElement (interp, Tcl_GetObjResult (interp),
				    Tcl_NewStringObj (Tcl_DStringValue(&resultStr), -1))
	  != TCL_OK) {
        Tcl_DStringFree(&resultStr);
	return TCL_ERROR;
      }
      Tcl_DStringFree(&resultStr);
    }

  hfont = SelectObject (hdc, hfont);
  ReleaseDC (cf.hwndOwner, hdc);
  DeleteObject (hfont);

  return TCL_OK;
}
コード例 #3
0
ファイル: callGraphConsts.C プロジェクト: dyninst/paradyn
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;
}
コード例 #4
0
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;
}
コード例 #5
0
ファイル: tkisamp.c プロジェクト: Feneric/xconq
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);
}