Exemple #1
0
TkCursor *
TkCreateCursorFromData(
    Tk_Window tkwin,		/* Window in which cursor will be used. */
    const char *source,		/* Bitmap data for cursor shape. */
    const char *mask,		/* Bitmap data for cursor mask. */
    int width, int height,	/* Dimensions of cursor. */
    int xHot, int yHot,		/* Location of hot-spot in cursor. */
    XColor fgColor,		/* Foreground color for cursor. */
    XColor bgColor)		/* Background color for cursor. */
{
    Cursor cursor;
    Pixmap sourcePixmap, maskPixmap;
    TkUnixCursor *cursorPtr = NULL;
    Display *display = Tk_Display(tkwin);

    sourcePixmap = XCreateBitmapFromData(display,
	    RootWindowOfScreen(Tk_Screen(tkwin)), source, (unsigned) width,
	    (unsigned) height);
    maskPixmap = XCreateBitmapFromData(display,
	    RootWindowOfScreen(Tk_Screen(tkwin)), mask, (unsigned) width,
	    (unsigned) height);
    cursor = XCreatePixmapCursor(display, sourcePixmap,
	    maskPixmap, &fgColor, &bgColor, (unsigned) xHot, (unsigned) yHot);
    Tk_FreePixmap(display, sourcePixmap);
    Tk_FreePixmap(display, maskPixmap);

    if (cursor != None) {
	cursorPtr = ckalloc(sizeof(TkUnixCursor));
	cursorPtr->info.cursor = (Tk_Cursor) cursor;
	cursorPtr->display = display;
    }
    return (TkCursor *) cursorPtr;
}
Exemple #2
0
int
Tk_GetScreenMM(
    Tcl_Interp *interp,		/* Use this for error reporting. */
    Tk_Window tkwin,		/* Window whose screen determines conversion
				 * from centimeters and other absolute
				 * units. */
    const char *string,		/* String describing a screen distance. */
    double *doublePtr)		/* Place to store converted result. */
{
    char *end;
    double d;

    d = strtod(string, &end);
    if (end == string) {
	goto error;
    }
    while ((*end != '\0') && isspace(UCHAR(*end))) {
	end++;
    }
    switch (*end) {
    case 0:
	d /= WidthOfScreen(Tk_Screen(tkwin));
	d *= WidthMMOfScreen(Tk_Screen(tkwin));
	break;
    case 'c':
	d *= 10;
	end++;
	break;
    case 'i':
	d *= 25.4;
	end++;
	break;
    case 'm':
	end++;
	break;
    case 'p':
	d *= 25.4/72.0;
	end++;
	break;
    default:
	goto error;
    }
    while ((*end != '\0') && isspace(UCHAR(*end))) {
	end++;
    }
    if (*end != 0) {
	goto error;
    }
    *doublePtr = d;
    return TCL_OK;

  error:
    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	    "bad screen distance \"%s\"", string));
    Tcl_SetErrorCode(interp, "TK", "VALUE", "SCREEN_DISTANCE", NULL);
    return TCL_ERROR;
}
Exemple #3
0
Fichier : tkGet.c Projet : das/tk
int
TkGetDoublePixels(
    Tcl_Interp *interp,		/* Use this for error reporting. */
    Tk_Window tkwin,		/* Window whose screen determines conversion
				 * from centimeters and other absolute
				 * units. */
    const char *string,		/* String describing a number of pixels. */
    double *doublePtr)		/* Place to store converted result. */
{
    char *end;
    double d;

    d = strtod((char *) string, &end);
    if (end == string) {
error:
        Tcl_AppendResult(interp, "bad screen distance \"", string, "\"", NULL);
        return TCL_ERROR;
    }
    while ((*end != '\0') && isspace(UCHAR(*end))) {
        end++;
    }
    switch (*end) {
    case 0:
        break;
    case 'c':
        d *= 10*WidthOfScreen(Tk_Screen(tkwin));
        d /= WidthMMOfScreen(Tk_Screen(tkwin));
        end++;
        break;
    case 'i':
        d *= 25.4*WidthOfScreen(Tk_Screen(tkwin));
        d /= WidthMMOfScreen(Tk_Screen(tkwin));
        end++;
        break;
    case 'm':
        d *= WidthOfScreen(Tk_Screen(tkwin));
        d /= WidthMMOfScreen(Tk_Screen(tkwin));
        end++;
        break;
    case 'p':
        d *= (25.4/72.0)*WidthOfScreen(Tk_Screen(tkwin));
        d /= WidthMMOfScreen(Tk_Screen(tkwin));
        end++;
        break;
    default:
        goto error;
    }
    while ((*end != '\0') && isspace(UCHAR(*end))) {
        end++;
    }
    if (*end != 0) {
        goto error;
    }
    *doublePtr = d;
    return TCL_OK;
}
Exemple #4
0
PyObject *
tkwin_ReadBitmapFile(TkWinObject * self, PyObject * args)
{
    Display	*display;
    Drawable	d;
    char *	arg1;
    unsigned int width, height;
    int hotspot_x, hotspot_y, error;
    Pixmap	bitmap;
    PyObject *pixmap, *tuple;

    if (!PyArg_ParseTuple(args, "s", &arg1))
	return NULL;

    display = Tk_Display(self->tkwin);
    d = RootWindowOfScreen(Tk_Screen(self->tkwin));
    error = XReadBitmapFile(display, d, arg1,
			    &width, &height, &bitmap,
			    &hotspot_x, &hotspot_y);
    /* Check error code, create a message to be returned as well as the error
     * code when the exception is raised.
     */
    tuple = NULL;
    switch (error)
    {
    case BitmapOpenFailed:
	PyErr_SetString(PyExc_IOError,
			"XReadBitMapFile - cannot open file");
	break;
    case BitmapFileInvalid:
	PyErr_SetString(PyExc_RuntimeError,
			"XReadBitMapFile - invalid bitmap data in file");
	break;
    case BitmapNoMemory:
	PyErr_SetString(PyExc_MemoryError,
			"XReadBitMapFile - no memory !!");
	break;
    case BitmapSuccess:
	/*
	 * Setup a tuple to be returned containing the info.
	 * returned from the call.
	 */
	pixmap = PaxPixmap_FromPixmap(display, bitmap, 1);
	if (pixmap != NULL)
	{
	    tuple = Py_BuildValue("(iiOii)", width, height, pixmap,
				  hotspot_x, hotspot_y);
	    Py_DECREF(pixmap);
	}
	break;
    default:
	PyErr_SetString(PyExc_SystemError,
			"XReadBitMapFile returned strange error");
	break;
    }

    return tuple;		/* will be NULL on error */
}
Exemple #5
0
XColor *
Tk_GetColorByValue(
    Tk_Window tkwin,		/* Window where color will be used. */
    XColor *colorPtr)		/* Red, green, and blue fields indicate
				 * desired color. */
{
    ValueKey valueKey;
    Tcl_HashEntry *valueHashPtr;
    int isNew;
    TkColor *tkColPtr;
    Display *display = Tk_Display(tkwin);
    TkDisplay *dispPtr = TkGetDisplay(display);

    if (!dispPtr->colorInit) {
        ColorInit(dispPtr);
    }

    /*
     * First, check to see if there's already a mapping for this color name.
     * Must clear the structure first; it's not tightly packed on 64-bit
     * systems. [Bug 2911570]
     */

    memset(&valueKey, 0, sizeof(ValueKey));
    valueKey.red = colorPtr->red;
    valueKey.green = colorPtr->green;
    valueKey.blue = colorPtr->blue;
    valueKey.colormap = Tk_Colormap(tkwin);
    valueKey.display = display;
    valueHashPtr = Tcl_CreateHashEntry(&dispPtr->colorValueTable,
                                       (char *) &valueKey, &isNew);
    if (!isNew) {
        tkColPtr = Tcl_GetHashValue(valueHashPtr);
        tkColPtr->resourceRefCount++;
        return &tkColPtr->color;
    }

    /*
     * The name isn't currently known. Find a pixel value for this color and
     * add a new structure to colorValueTable (in TkDisplay).
     */

    tkColPtr = TkpGetColorByValue(tkwin, colorPtr);
    tkColPtr->magic = COLOR_MAGIC;
    tkColPtr->gc = None;
    tkColPtr->screen = Tk_Screen(tkwin);
    tkColPtr->colormap = valueKey.colormap;
    tkColPtr->visual = Tk_Visual(tkwin);
    tkColPtr->resourceRefCount = 1;
    tkColPtr->objRefCount = 0;
    tkColPtr->type = TK_COLOR_BY_VALUE;
    tkColPtr->hashPtr = valueHashPtr;
    tkColPtr->nextPtr = NULL;
    Tcl_SetHashValue(valueHashPtr, tkColPtr);
    return &tkColPtr->color;
}
Exemple #6
0
int
Tk_GetMMFromObj(
    Tcl_Interp *interp, 	/* Used for error reporting if not NULL. */
    Tk_Window tkwin,
    Tcl_Obj *objPtr,		/* The object from which to get mms. */
    double *doublePtr)		/* Place to store resulting millimeters. */
{
    int result;
    double d;
    MMRep *mmPtr;
    static double bias[] = {
	10.0,	25.4,	1.0,	0.35278 /*25.4 / 72.0*/
    };

    if (objPtr->typePtr != &mmObjType) {
	result = SetMMFromAny(interp, objPtr);
	if (result != TCL_OK) {
	    return result;
	}
    }

    mmPtr = (MMRep *) objPtr->internalRep.twoPtrValue.ptr1;
    if (mmPtr->tkwin != tkwin) {
	d = mmPtr->value;
	if (mmPtr->units == -1) {
	    d /= WidthOfScreen(Tk_Screen(tkwin));
	    d *= WidthMMOfScreen(Tk_Screen(tkwin));
	} else {
	    d *= bias[mmPtr->units];
	}
	mmPtr->tkwin = tkwin;
	mmPtr->returnValue = d;
    }
    *doublePtr = mmPtr->returnValue;

    return TCL_OK;
}
Exemple #7
0
static Window
_GetSystemTray ()
{

  char buffer[256];
  Atom a;

  snprintf (buffer, sizeof (buffer), "_NET_SYSTEM_TRAY_S%d",
      XScreenNumberOfScreen(Tk_Screen(Tk_MainWindow(globalinterp))));

  /* Get the X11 Atom */
  a=XInternAtom (display, buffer, False);

  /* And get the window ID associated to that atom */
  return XGetSelectionOwner(display, a);
}
Exemple #8
0
static PyObject *
tkwin_CopyArea(TkWinObject * self, PyObject * args)
{
    PyObject *destobj, *gcobj;
    Drawable dest;
    GC gc;
    int src_x, src_y, dest_x, dest_y;
    unsigned int width, height;

    if (!PyArg_ParseTuple(args, "OOiiiiii", &destobj, &gcobj, &src_x,
			  &src_y, &width, &height, &dest_x, &dest_y))
	return NULL;
    if (TkWin_Check(destobj))
    {
	if (Tk_IsMapped(self->tkwin))
	    dest = Tk_WindowId(((TkWinObject*) destobj)->tkwin);
	else
	{
	    Py_INCREF(Py_None);
	    return Py_None;
	}
    }
    else if (PaxPixmap_Check(destobj))
    {
	dest = PaxPixmap_AsPixmap(destobj);
    }
    else
    {
	PyErr_SetString(PyExc_RuntimeError, "bad arguments");
	return NULL;
    }
    if (gcobj == Py_None)
	gc = DefaultGCOfScreen(Tk_Screen(self->tkwin));
    else
    {
	gc = PaxGC_AsGC(gcobj);
	if (PyErr_Occurred())
	    return NULL;
    }

    XCopyArea(Tk_Display(self->tkwin), Tk_WindowId(self->tkwin),
	      dest, gc, src_x, src_y, width, height, dest_x, dest_y);

    Py_INCREF(Py_None);
    return Py_None;
}
Exemple #9
0
void
TkpMakeContainer(
    Tk_Window tkwin)		/* Token for a window that is about to become
				 * a container. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    Container *containerPtr;
    ThreadSpecificData *tsdPtr =
            Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    /*
     * Register the window as a container so that, for example, we can find
     * out later if the embedded app. is in the same process.
     */

    Tk_MakeWindowExist(tkwin);
    containerPtr = ckalloc(sizeof(Container));
    containerPtr->parent = Tk_WindowId(tkwin);
    containerPtr->parentRoot = RootWindowOfScreen(Tk_Screen(tkwin));
    containerPtr->parentPtr = winPtr;
    containerPtr->wrapper = None;
    containerPtr->embeddedPtr = NULL;
    containerPtr->nextPtr = tsdPtr->firstContainerPtr;
    tsdPtr->firstContainerPtr = containerPtr;
    winPtr->flags |= TK_CONTAINER;

    /*
     * Request SubstructureNotify events so that we can find out when the
     * embedded application creates its window or attempts to resize it. Also
     * watch Configure events on the container so that we can resize the child
     * to match.
     */

    winPtr->atts.event_mask |= SubstructureRedirectMask|SubstructureNotifyMask;
    XSelectInput(winPtr->display, winPtr->window, winPtr->atts.event_mask);
    Tk_CreateEventHandler(tkwin,
	    SubstructureNotifyMask|SubstructureRedirectMask,
	    ContainerEventProc, winPtr);
    Tk_CreateEventHandler(tkwin, StructureNotifyMask, EmbedStructureProc,
	    containerPtr);
    Tk_CreateEventHandler(tkwin, FocusChangeMask, EmbedFocusProc,
	    containerPtr);
}
Exemple #10
0
/*--------------------------------------------------------------------------*/
int sci_opentk(char *fname, unsigned long l)
{
    Tcl_Interp *TCLinterpLocal = NULL;

    CheckRhs(0, 0);
    CheckLhs(1, 1);

    TCLinterpLocal = Tcl_CreateInterp();
    Tcl_Init(TCLinterpLocal);
    Tk_Init(TCLinterpLocal);
    TKmainWindow = Tk_MainWindow(TCLinterpLocal);
    Tk_GeometryRequest(TKmainWindow, 200, 200);
    Tk_SetWindowBackground(TKmainWindow, WhitePixelOfScreen(Tk_Screen(TKmainWindow)));

    LhsVar(1) = 0;
    PutLhsVar();

    return 0;
}
Exemple #11
0
static PyObject *
pixmap_CopyPlane(PaxPixmapObject *self, PyObject *args)
{
    PyObject *destobj, *gcobj;
    Tk_Window w = NULL;
    Drawable dest;
    GC gc;
    int src_x, src_y, dest_x, dest_y;
    unsigned int width, height;
    unsigned long plane;

    if (!PyArg_ParseTuple(args, "OOiiiiiii", &destobj, &gcobj, &src_x,
			  &src_y, &width, &height, &dest_x, &dest_y, &plane))
	return NULL;
    if (TkWin_Check(destobj))
    {
	w = TkWin_AsTkWindow(destobj);
	dest = Tk_WindowId(w);
    }
    else if (PaxPixmap_Check(destobj))
    {
	dest = PaxPixmap_AsPixmap(destobj);
    }
    else
    {
	PyErr_SetString(PyExc_RuntimeError, "bad arguments");
	return NULL;
    }
    if (gcobj == Py_None && w)
	gc = DefaultGCOfScreen(Tk_Screen(w));
    else
    {
	gc = PaxGC_AsGC(gcobj);
	if (PyErr_Occurred())
	    return NULL;
    }

    XCopyPlane(self->display, self->pixmap, dest, gc, src_x, src_y,
	       width, height, dest_x, dest_y, plane);

    Py_INCREF(Py_None);
    return Py_None;
}
Exemple #12
0
static PyObject *
tkwin_CreatePixmap(TkWinObject * self, PyObject * args)
{
    Tk_Window tkwin = self->tkwin;
    Display *display = Tk_Display(self->tkwin);
    int width, height;
    int depth;
    Pixmap pixmap;
    Drawable d;

    display = Tk_Display(tkwin);
    width = Tk_Width(tkwin);
    height = Tk_Height(tkwin);
    depth = Tk_Depth(tkwin);
    if (!PyArg_ParseTuple(args, "|iii", &width, &height, &depth))
	return NULL;

    d = RootWindowOfScreen(Tk_Screen(tkwin));

    pixmap = XCreatePixmap(display, d, width, height, depth);
    return PaxPixmap_FromPixmap(display, pixmap, 1);
}
Exemple #13
0
/*
 * TextDraw --
 * 	Draw a text element.
 * 	Called by TextElementDraw() and LabelElementDraw().
 */
static void TextDraw(TextElement *text, Tk_Window tkwin, Drawable d, Ttk_Box b)
{
    XColor *color = Tk_GetColorFromObj(tkwin, text->foregroundObj);
    int underline = -1;
    XGCValues gcValues;
    GC gc1, gc2;
    Tk_Anchor anchor = TK_ANCHOR_CENTER;
    TkRegion clipRegion = NULL;

    gcValues.font = Tk_FontId(text->tkfont);
    gcValues.foreground = color->pixel;
    gc1 = Tk_GetGC(tkwin, GCFont | GCForeground, &gcValues);
    gcValues.foreground = WhitePixelOfScreen(Tk_Screen(tkwin));
    gc2 = Tk_GetGC(tkwin, GCFont | GCForeground, &gcValues);

    /* 
     * Place text according to -anchor:
     */
    Tk_GetAnchorFromObj(NULL, text->anchorObj, &anchor);
    b = Ttk_AnchorBox(b, text->width, text->height, anchor);

    /*
     * Clip text if it's too wide:
     */
    if (b.width < text->width) {
	XRectangle rect;

	clipRegion = TkCreateRegion();
	rect.x = b.x;
	rect.y = b.y;
	rect.width = b.width + (text->embossed ? 1 : 0);
	rect.height = b.height + (text->embossed ? 1 : 0);
	TkUnionRectWithRegion(&rect, clipRegion, clipRegion);
	TkSetRegion(Tk_Display(tkwin), gc1, clipRegion);
	TkSetRegion(Tk_Display(tkwin), gc2, clipRegion);
#ifdef HAVE_XFT
	TkUnixSetXftClipRegion(clipRegion);
#endif
    }

    if (text->embossed) {
	Tk_DrawTextLayout(Tk_Display(tkwin), d, gc2,
	    text->textLayout, b.x+1, b.y+1, 0/*firstChar*/, -1/*lastChar*/);
    }
    Tk_DrawTextLayout(Tk_Display(tkwin), d, gc1,
	    text->textLayout, b.x, b.y, 0/*firstChar*/, -1/*lastChar*/);

    Tcl_GetIntFromObj(NULL, text->underlineObj, &underline);
    if (underline >= 0) {
	if (text->embossed) {
	    Tk_UnderlineTextLayout(Tk_Display(tkwin), d, gc2,
		text->textLayout, b.x+1, b.y+1, underline);
	}
	Tk_UnderlineTextLayout(Tk_Display(tkwin), d, gc1,
	    text->textLayout, b.x, b.y, underline);
    }

    if (clipRegion != NULL) {
#ifdef HAVE_XFT
	TkUnixSetXftClipRegion(None);
#endif
	XSetClipMask(Tk_Display(tkwin), gc1, None);
	XSetClipMask(Tk_Display(tkwin), gc2, None);
	TkDestroyRegion(clipRegion);
    }
    Tk_FreeGC(Tk_Display(tkwin), gc1);
    Tk_FreeGC(Tk_Display(tkwin), gc2);
}
Exemple #14
0
Fichier : tk3d.c Projet : aosm/tcl
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;
}
Exemple #15
0
Fichier : tk3d.c Projet : aosm/tcl
Tk_3DBorder
Tk_Get3DBorder(
    Tcl_Interp *interp,		/* Place to store an error message. */
    Tk_Window tkwin,		/* Token for window in which border will be
				 * drawn. */
    Tk_Uid colorName)		/* String giving name of color for window
				 * background. */
{
    Tcl_HashEntry *hashPtr;
    TkBorder *borderPtr, *existingBorderPtr;
    int isNew;
    XGCValues gcValues;
    XColor *bgColorPtr;
    TkDisplay *dispPtr;

    dispPtr = ((TkWindow *) tkwin)->dispPtr;

    if (!dispPtr->borderInit) {
	BorderInit(dispPtr);
    }

    hashPtr = Tcl_CreateHashEntry(&dispPtr->borderTable, colorName, &isNew);
    if (!isNew) {
	existingBorderPtr = (TkBorder *) Tcl_GetHashValue(hashPtr);
	for (borderPtr = existingBorderPtr; borderPtr != NULL;
		borderPtr = borderPtr->nextPtr) {
	    if ((Tk_Screen(tkwin) == borderPtr->screen)
		    && (Tk_Colormap(tkwin) == borderPtr->colormap)) {
		borderPtr->resourceRefCount++;
		return (Tk_3DBorder) borderPtr;
	    }
	}
    } else {
	existingBorderPtr = NULL;
    }

    /*
     * No satisfactory border exists yet. Initialize a new one.
     */

    bgColorPtr = Tk_GetColor(interp, tkwin, colorName);
    if (bgColorPtr == NULL) {
	if (isNew) {
	    Tcl_DeleteHashEntry(hashPtr);
	}
	return NULL;
    }

    borderPtr = TkpGetBorder();
    borderPtr->screen = Tk_Screen(tkwin);
    borderPtr->visual = Tk_Visual(tkwin);
    borderPtr->depth = Tk_Depth(tkwin);
    borderPtr->colormap = Tk_Colormap(tkwin);
    borderPtr->resourceRefCount = 1;
    borderPtr->objRefCount = 0;
    borderPtr->bgColorPtr = bgColorPtr;
    borderPtr->darkColorPtr = NULL;
    borderPtr->lightColorPtr = NULL;
    borderPtr->shadow = None;
    borderPtr->bgGC = None;
    borderPtr->darkGC = None;
    borderPtr->lightGC = None;
    borderPtr->hashPtr = hashPtr;
    borderPtr->nextPtr = existingBorderPtr;
    Tcl_SetHashValue(hashPtr, borderPtr);

    /*
     * Create the information for displaying the background color, but delay
     * the allocation of shadows until they are actually needed for drawing.
     */

    gcValues.foreground = borderPtr->bgColorPtr->pixel;
    borderPtr->bgGC = Tk_GetGC(tkwin, GCForeground, &gcValues);
    return (Tk_3DBorder) borderPtr;
}
Exemple #16
0
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);
}
Exemple #17
0
static void
draw_one_image(Imfsample *imfsample, Drawable d, GC gc, Image *img,
	       int sx, int sy, int sw, int sh)
{
    int sx2, sy2;
    TkImage *tkimg;
    Tk_Window tkwin = imfsample->tkwin;
    Display *dpy = Tk_Display(tkwin);
    XColor *imagecolor = black_color;
    XColor *maskcolor = white_color;

    if (!img->istile) {
	/* Offset the image to draw in the middle of its area,
	   whether larger or smaller than the given area. */
	sx2 = sx + (sw - img->w) / 2;  
	sy2 = sy + (sh - img->h) / 2;
	/* Only change the size of the rectangle being drawn if it's
	   smaller than what was passed in. */
	if (img->w < sw) {
	    sx = sx2;
	    sw = img->w;
	}
	if (img->h < sh) {
	    sy = sy2;
	    sh = img->h;
	}
    }
    /* Pick out a specific subimage if necessary. */
    if (img->numsubimages > 0 && img->subimages)
      img = img->subimages[img->numsubimages - 1];
    tkimg = (TkImage *) img->hook;
    if (tkimg == NULL)
      return;
    XSetClipMask(dpy, gc, None);
    if (tkimg->colr != None && imfsample->show_color) {
	if (img->istile) {
	    XSetFillStyle(dpy, gc, FillTiled);
	    XSetTile(dpy, gc, tkimg->colr);
	    XFillRectangle(dpy, d, gc, sx, sy, sw, sh);
	} else {
	    if (use_clip_mask) {
		if (tkimg->mask != None && imfsample->show_masks) {
		    XSetClipOrigin(dpy, gc, sx2, sy2);
		    /* Use the image's mask to do clipped drawing. */
		    XSetClipMask(dpy, gc, tkimg->mask);
		}
	    } else {
		if (tkimg->mask != None && imfsample->show_masks) {
		    XSetFunction(dpy, gc, GXand);
		    XCopyArea(dpy, tkimg->mask, d, gc, 0, 0, sw, sh, sx, sy);
		}
		XSetFunction(dpy, gc, GXor);
	    }
	    /* Draw the color image. */
	    XCopyArea(dpy, tkimg->colr, d, gc, 0, 0, sw, sh, sx, sy);
	    if (!use_clip_mask)
	      XSetFunction(dpy, gc, GXcopy);
	}
    } else if (tkimg->solid != NULL && imfsample->show_color) {
	XSetFillStyle(dpy, gc, FillSolid);
	XSetForeground(dpy, gc, tkimg->solid->pixel);
	XFillRectangle(dpy, d, gc, sx, sy, sw, sh);
    } else if (tkimg->mono != None || tkimg->mask != None) {
	if (use_clip_mask) {
	    /* The XFillRectangle code below does not work when we draw 
		directly to the screen on the Mac, so we use XCopyArea with a 
		small colored offscreen pixmap instead (this method does not 
		work on Unix or during double buffered drawing on the Mac). */ 
#ifdef MAC
	    if (!imfsample->double_buffer) {
		Pixmap pm = 
		    Tk_GetPixmap(dpy, Tk_WindowId(tkwin), sw, sh, 
				 DefaultDepthOfScreen(Tk_Screen(tkwin)));

		/* Draw the mask. */
		if (tkimg->mask && imfsample->show_masks) {
		    XSetClipMask(dpy, gc, tkimg->mask);
		} else {
		    XSetClipMask(dpy, gc, tkimg->mono);
		}
		if (tkimg->mono != None) {
		    Tk_Fill3DRectangle(tkwin, pm, white_border, 0, 0, 
				       sw, sh, 0, 0);
		} else {
		    Tk_Fill3DRectangle(tkwin, pm, black_border, 0, 0, 
				       sw, sh, 0, 0);
		}
		XCopyArea(dpy, pm, Tk_WindowId(tkwin), gc, 0, 0, 
			  sw, sh, sx, sy);
		/* Draw the image proper. */
		if (tkimg->mono != None) {
		    XSetClipMask(dpy, gc, tkimg->mono);
		    Tk_Fill3DRectangle(tkwin, pm, black_border, 0, 0, 
				       sw, sh, 0, 0);
		    XCopyArea(dpy, pm, Tk_WindowId(tkwin), gc, 0, 0, 
			      sw, sh, sx, sy);
		}
		Tk_FreePixmap(dpy, pm);
		return;
	    }
#endif

		XSetFillStyle(dpy, gc, FillSolid);
		/* Set the color we're going to use for the mask; use the
		imagecolor if we'll be using the mask as the only image. */
		XSetForeground(dpy, gc,
			(tkimg->mono == None ? imagecolor : maskcolor)->pixel);
		XSetClipOrigin(dpy, gc, sx2, sy2);
		/* Set the clip mask to be explicit mask or unit's image. */
		if (tkimg->mask && imfsample->show_masks) {
			XSetClipMask(dpy, gc, tkimg->mask);
		} else {
			XSetClipMask(dpy, gc, tkimg->mono);
		}
		/* Draw the mask. */
		XFillRectangle(dpy, d, gc, sx, sy, sw, sh);
		/* Draw the image proper. */
		if (tkimg->mono != None) {
		    XSetForeground(dpy, gc, imagecolor->pixel);
		    XSetClipMask(dpy, gc, tkimg->mono);
		    XFillRectangle(dpy, d, gc, sx, sy, sw, sh);
		}
	/* The Win32 case. */
	} else {
	    if (tkimg->mask != None && imfsample->show_masks) {
		XSetFunction(dpy, gc, GXand);
		XCopyArea(dpy, tkimg->mask, d, gc, 0, 0, sw, sh, sx, sy);
	    }
	    if (tkimg->mono != None) {
		XSetFunction(dpy, gc, GXor);
		XCopyArea(dpy, tkimg->mono, d, gc, 0, 0, sw, sh, sx, sy);
	    }
	    XSetFunction(dpy, gc, GXcopy);
	}
    }
}
Exemple #18
0
/*
 * Called for motion events in image window when zooming is on.
 * 
 * Args: 
 * 
 *   data - pointer to data being displayed
 *   x, y - coords in displayed image (XImage coords)
 *   w, h - width (bytesPerLine) and height of displayed image
 *   xs, ys - x and y magnification factors
 *   color0 - color to use for blank areas with no image data
 */
void ImageZoom::zoom(unsigned char* data, int x, int y, int w, int h, 
		     int xs, int ys, unsigned long color0)
{
    if (status_ != TCL_OK)
	return;

    char pixval = color0;
    register unsigned char* zoomData = xImage_->data();
    int zs = zoomStep_ >> 1;
    int incr = width_ * (zoomFactor_ - 1);
    int xz = x - zs;
    int yz = y - zs;
    int i, j, k, l;

    for (i=0; i<zoomStep_; i++) {
	for (j=0; j<zoomStep_; j++) {
	    if ((xz + j) < 0 || (xz+j) >= w || (yz + i) < 0  || (yz + i) >= h) {
		pixval = color0;
	    }
	    else {
		pixval = data[(yz+i)*w + xz + j];
	    }
	    for (k=0; k<zoomFactor_; k++) {
		for (l=0; l<zoomFactor_; l++) {
		    zoomData[l*width_] = pixval; 
		}
		zoomData++;
	    }
	}
	zoomData += incr;
    }
    
    // send to X server
    xImage_->put(Tk_WindowId(tkwin_), 0, 0, Tk_X(tkwin_), Tk_Y(tkwin_), width_, height_);

    /* draw 2 rectangles around the center pixel(s) */
    int size = zoomFactor_;
    int x0 = width_/2 - size/2;
    int y0 = height_/2 - size/2;

    Screen* screen = Tk_Screen(tkwin_);
    
    XSetForeground(Tk_Display(tkwin_), rect_gc_, WhitePixelOfScreen(screen));
    XSetBackground(Tk_Display(tkwin_), rect_gc_, BlackPixelOfScreen(screen));
    XDrawRectangle(Tk_Display(tkwin_),
		   Tk_WindowId(tkwin_),
		   rect_gc_,
		   x0,
		   y0,
		   size,
		   size);

    XSetForeground(Tk_Display(tkwin_), rect_gc_, BlackPixelOfScreen(screen));
    XSetBackground(Tk_Display(tkwin_), rect_gc_, WhitePixelOfScreen(screen));
    XDrawRectangle(Tk_Display(tkwin_),
		   Tk_WindowId(tkwin_),
		   rect_gc_,
		   x0-1,
		   y0-1,
		   size+2,
		   size+2);
}
Exemple #19
0
static void
ImgBmapConfigureInstance(
    BitmapInstance *instancePtr)/* Instance to reconfigure. */
{
    BitmapMaster *masterPtr = instancePtr->masterPtr;
    XColor *colorPtr;
    XGCValues gcValues;
    GC gc;
    unsigned int mask;
    Pixmap oldBitmap, oldMask;

    /*
     * For each of the options in masterPtr, translate the string form into an
     * internal form appropriate for instancePtr.
     */

    if (*masterPtr->bgUid != 0) {
	colorPtr = Tk_GetColor(masterPtr->interp, instancePtr->tkwin,
		masterPtr->bgUid);
	if (colorPtr == NULL) {
	    goto error;
	}
    } else {
	colorPtr = NULL;
    }
    if (instancePtr->bg != NULL) {
	Tk_FreeColor(instancePtr->bg);
    }
    instancePtr->bg = colorPtr;

    colorPtr = Tk_GetColor(masterPtr->interp, instancePtr->tkwin,
	    masterPtr->fgUid);
    if (colorPtr == NULL) {
	goto error;
    }
    if (instancePtr->fg != NULL) {
	Tk_FreeColor(instancePtr->fg);
    }
    instancePtr->fg = colorPtr;

    /*
     * Careful: We have to allocate new Pixmaps before deleting the old ones.
     * Otherwise, The XID allocator will always return the same XID for the
     * new Pixmaps as was used for the old Pixmaps. And that will prevent the
     * data and/or mask from changing in the GC below.
     */

    oldBitmap = instancePtr->bitmap;
    instancePtr->bitmap = None;
    oldMask = instancePtr->mask;
    instancePtr->mask = None;

    if (masterPtr->data != NULL) {
	instancePtr->bitmap = XCreateBitmapFromData(
		Tk_Display(instancePtr->tkwin),
		RootWindowOfScreen(Tk_Screen(instancePtr->tkwin)),
		masterPtr->data, (unsigned) masterPtr->width,
		(unsigned) masterPtr->height);
    }
    if (masterPtr->maskData != NULL) {
	instancePtr->mask = XCreateBitmapFromData(
		Tk_Display(instancePtr->tkwin),
		RootWindowOfScreen(Tk_Screen(instancePtr->tkwin)),
		masterPtr->maskData, (unsigned) masterPtr->width,
		(unsigned) masterPtr->height);
    }

    if (oldMask != None) {
	Tk_FreePixmap(Tk_Display(instancePtr->tkwin), oldMask);
    }
    if (oldBitmap != None) {
	Tk_FreePixmap(Tk_Display(instancePtr->tkwin), oldBitmap);
    }

    if (masterPtr->data != NULL) {
	gcValues.foreground = instancePtr->fg->pixel;
	gcValues.graphics_exposures = False;
	mask = GCForeground|GCGraphicsExposures;
	if (instancePtr->bg != NULL) {
	    gcValues.background = instancePtr->bg->pixel;
	    mask |= GCBackground;
	    if (instancePtr->mask != None) {
		gcValues.clip_mask = instancePtr->mask;
		mask |= GCClipMask;
	    }
	} else {
	    gcValues.clip_mask = instancePtr->bitmap;
	    mask |= GCClipMask;
	}
	gc = Tk_GetGC(instancePtr->tkwin, mask, &gcValues);
    } else {
	gc = None;
    }
    if (instancePtr->gc != None) {
	Tk_FreeGC(Tk_Display(instancePtr->tkwin), instancePtr->gc);
    }
    instancePtr->gc = gc;
    return;

  error:
    /*
     * An error occurred: clear the graphics context in the instance to make
     * it clear that this instance cannot be displayed. Then report the error.
     */

    if (instancePtr->gc != None) {
	Tk_FreeGC(Tk_Display(instancePtr->tkwin), instancePtr->gc);
    }
    instancePtr->gc = None;
    Tcl_AppendObjToErrorInfo(masterPtr->interp, Tcl_ObjPrintf(
	    "\n    (while configuring image \"%s\")", Tk_NameOfImage(
	    masterPtr->tkMaster)));
    Tcl_BackgroundError(masterPtr->interp);
}
Exemple #20
0
static TkBitmap *
GetBitmap(
    Tcl_Interp *interp,		/* Interpreter to use for error reporting,
				 * this may be NULL. */
    Tk_Window tkwin,		/* Window in which bitmap will be used. */
    const char *string)		/* Description of bitmap. See manual entry for
				 * details on legal syntax. */
{
    Tcl_HashEntry *nameHashPtr, *predefHashPtr;
    TkBitmap *bitmapPtr, *existingBitmapPtr;
    TkPredefBitmap *predefPtr;
    Pixmap bitmap;
    int isNew, width, height, dummy2;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;
    ThreadSpecificData *tsdPtr =
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (!dispPtr->bitmapInit) {
	BitmapInit(dispPtr);
    }

    nameHashPtr = Tcl_CreateHashEntry(&dispPtr->bitmapNameTable, string,
	    &isNew);
    if (!isNew) {
	existingBitmapPtr = Tcl_GetHashValue(nameHashPtr);
	for (bitmapPtr = existingBitmapPtr; bitmapPtr != NULL;
		bitmapPtr = bitmapPtr->nextPtr) {
	    if ((Tk_Display(tkwin) == bitmapPtr->display) &&
		    (Tk_ScreenNumber(tkwin) == bitmapPtr->screenNum)) {
		bitmapPtr->resourceRefCount++;
		return bitmapPtr;
	    }
	}
    } else {
	existingBitmapPtr = NULL;
    }

    /*
     * No suitable bitmap exists. Create a new bitmap from the information
     * contained in the string. If the string starts with "@" then the rest of
     * the string is a file name containing the bitmap. Otherwise the string
     * must refer to a bitmap defined by a call to Tk_DefineBitmap.
     */

    if (*string == '@') {	/* INTL: ISO char */
	Tcl_DString buffer;
	int result;

	if (Tcl_IsSafe(interp)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "can't specify bitmap with '@' in a safe interpreter",
		    -1));
	    Tcl_SetErrorCode(interp, "TK", "SAFE", "BITMAP_FILE", NULL);
	    goto error;
	}

	/*
	 * Note that we need to cast away the const from the string because
	 * Tcl_TranslateFileName is non-const, even though it doesn't modify
	 * the string.
	 */

	string = Tcl_TranslateFileName(interp, (char *) string + 1, &buffer);
	if (string == NULL) {
	    goto error;
	}
	result = TkReadBitmapFile(Tk_Display(tkwin),
		RootWindowOfScreen(Tk_Screen(tkwin)), string,
		(unsigned int *) &width, (unsigned int *) &height,
		&bitmap, &dummy2, &dummy2);
	if (result != BitmapSuccess) {
	    if (interp != NULL) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"error reading bitmap file \"%s\"", string));
		Tcl_SetErrorCode(interp, "TK", "BITMAP", "FILE_ERROR", NULL);
	    }
	    Tcl_DStringFree(&buffer);
	    goto error;
	}
	Tcl_DStringFree(&buffer);
    } else {
	predefHashPtr = Tcl_FindHashEntry(&tsdPtr->predefBitmapTable, string);
	if (predefHashPtr == NULL) {
	    /*
	     * The following platform specific call allows the user to define
	     * bitmaps that may only exist during run time. If it returns None
	     * nothing was found and we return the error.
	     */

	    bitmap = TkpGetNativeAppBitmap(Tk_Display(tkwin), string,
		    &width, &height);

	    if (bitmap == None) {
		if (interp != NULL) {
		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			    "bitmap \"%s\" not defined", string));
		    Tcl_SetErrorCode(interp, "TK", "LOOKUP", "BITMAP", string,
			    NULL);
		}
		goto error;
	    }
	} else {
	    predefPtr = Tcl_GetHashValue(predefHashPtr);
	    width = predefPtr->width;
	    height = predefPtr->height;
	    if (predefPtr->native) {
		bitmap = TkpCreateNativeBitmap(Tk_Display(tkwin),
		    predefPtr->source);
		if (bitmap == None) {
		    Tcl_Panic("native bitmap creation failed");
		}
	    } else {
		bitmap = XCreateBitmapFromData(Tk_Display(tkwin),
			RootWindowOfScreen(Tk_Screen(tkwin)),
			predefPtr->source, (unsigned)width, (unsigned)height);
	    }
	}
    }

    /*
     * Add information about this bitmap to our database.
     */

    bitmapPtr = ckalloc(sizeof(TkBitmap));
    bitmapPtr->bitmap = bitmap;
    bitmapPtr->width = width;
    bitmapPtr->height = height;
    bitmapPtr->display = Tk_Display(tkwin);
    bitmapPtr->screenNum = Tk_ScreenNumber(tkwin);
    bitmapPtr->resourceRefCount = 1;
    bitmapPtr->objRefCount = 0;
    bitmapPtr->nameHashPtr = nameHashPtr;
    bitmapPtr->idHashPtr = Tcl_CreateHashEntry(&dispPtr->bitmapIdTable,
	    (char *) bitmap, &isNew);
    if (!isNew) {
	Tcl_Panic("bitmap already registered in Tk_GetBitmap");
    }
    bitmapPtr->nextPtr = existingBitmapPtr;
    Tcl_SetHashValue(nameHashPtr, bitmapPtr);
    Tcl_SetHashValue(bitmapPtr->idHashPtr, bitmapPtr);
    return bitmapPtr;

  error:
    if (isNew) {
	Tcl_DeleteHashEntry(nameHashPtr);
    }
    return NULL;
}
Exemple #21
0
XColor *
Tk_GetColorFromObj(
    Tk_Window tkwin,		/* The window in which the color will be
				 * used. */
    Tcl_Obj *objPtr)		/* String value contains the name of the
				 * desired color. */
{
    TkColor *tkColPtr;
    Tcl_HashEntry *hashPtr;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;

    if (objPtr->typePtr != &tkColorObjType) {
        InitColorObj(objPtr);
    }

    /*
     * First check to see if the internal representation of the object is
     * defined and is a color that is valid for the current screen and color
     * map. If it is, we are done.
     */

    tkColPtr = (TkColor *) objPtr->internalRep.twoPtrValue.ptr1;
    if ((tkColPtr != NULL)
            && (tkColPtr->resourceRefCount > 0)
            && (Tk_Screen(tkwin) == tkColPtr->screen)
            && (Tk_Colormap(tkwin) == tkColPtr->colormap)) {
        /*
         * The object already points to the right TkColor structure. Just
         * return it.
         */

        return (XColor *) tkColPtr;
    }

    /*
     * If we reach this point, it means that the TkColor structure that we
     * have cached in the internal representation is not valid for the current
     * screen and colormap. But there is a list of other TkColor structures
     * attached to the TkDisplay. Walk this list looking for the right TkColor
     * structure.
     */

    hashPtr = Tcl_FindHashEntry(&dispPtr->colorNameTable,
                                Tcl_GetString(objPtr));
    if (hashPtr == NULL) {
        goto error;
    }
    for (tkColPtr = Tcl_GetHashValue(hashPtr);
            (tkColPtr != NULL); tkColPtr = tkColPtr->nextPtr) {
        if ((Tk_Screen(tkwin) == tkColPtr->screen)
                && (Tk_Colormap(tkwin) == tkColPtr->colormap)) {
            FreeColorObjProc(objPtr);
            objPtr->internalRep.twoPtrValue.ptr1 = (void *) tkColPtr;
            tkColPtr->objRefCount++;
            return (XColor *) tkColPtr;
        }
    }

error:
    Tcl_Panic("Tk_GetColorFromObj called with non-existent color!");
    /*
     * The following code isn't reached; it's just there to please compilers.
     */
    return NULL;
}
Exemple #22
0
int
Tk_PostscriptImage(
    Tk_Image image,		/* Token for image to redisplay. */
    Tcl_Interp *interp,
    Tk_Window tkwin,
    Tk_PostscriptInfo psinfo,	/* postscript info */
    int x, int y,		/* Upper-left pixel of region in image that
				 * needs to be redisplayed. */
    int width, int height,	/* Dimensions of region to redraw. */
    int prepass)
{
    Image *imagePtr = (Image *) image;
    int result;
    XImage *ximage;
    Pixmap pmap;
    GC newGC;
    XGCValues gcValues;

    if (imagePtr->masterPtr->typePtr == NULL) {
	/*
	 * No master for image, so nothing to display on postscript.
	 */

	return TCL_OK;
    }

    /*
     * Check if an image specific postscript-generation function exists;
     * otherwise go on with generic code.
     */

    if (imagePtr->masterPtr->typePtr->postscriptProc != NULL) {
	return imagePtr->masterPtr->typePtr->postscriptProc(
		imagePtr->masterPtr->masterData, interp, tkwin, psinfo,
		x, y, width, height, prepass);
    }

    if (prepass) {
	return TCL_OK;
    }

    /*
     * Create a Pixmap, tell the image to redraw itself there, and then
     * generate an XImage from the Pixmap. We can then read pixel values out
     * of the XImage.
     */

    pmap = Tk_GetPixmap(Tk_Display(tkwin), Tk_WindowId(tkwin), width, height,
	    Tk_Depth(tkwin));

    gcValues.foreground = WhitePixelOfScreen(Tk_Screen(tkwin));
    newGC = Tk_GetGC(tkwin, GCForeground, &gcValues);
    if (newGC != NULL) {
	XFillRectangle(Tk_Display(tkwin), pmap, newGC, 0, 0,
		(unsigned) width, (unsigned) height);
	Tk_FreeGC(Tk_Display(tkwin), newGC);
    }

    Tk_RedrawImage(image, x, y, width, height, pmap, 0, 0);

    ximage = XGetImage(Tk_Display(tkwin), pmap, 0, 0,
	    (unsigned) width, (unsigned) height, AllPlanes, ZPixmap);

    Tk_FreePixmap(Tk_Display(tkwin), pmap);

    if (ximage == NULL) {
	/*
	 * The XGetImage() function is apparently not implemented on this
	 * system. Just ignore it.
	 */

	return TCL_OK;
    }
    result = TkPostscriptImage(interp, tkwin, psinfo, ximage, x, y,
	    width, height);

    XDestroyImage(ximage);
    return result;
}
Exemple #23
0
static int
ConfigureText(
    Tcl_Interp *interp,		/* Interpreter for error reporting. */
    Tk_Canvas canvas,		/* Canvas containing itemPtr. */
    Tk_Item *itemPtr,		/* Rectangle item to reconfigure. */
    int objc,			/* Number of elements in objv. */
    Tcl_Obj *const objv[],	/* Arguments describing things to configure. */
    int flags)			/* Flags to pass to Tk_ConfigureWidget. */
{
    TextItem *textPtr = (TextItem *) itemPtr;
    XGCValues gcValues;
    GC newGC, newSelGC;
    unsigned long mask;
    Tk_Window tkwin;
    Tk_CanvasTextInfo *textInfoPtr = textPtr->textInfoPtr;
    XColor *selBgColorPtr;
    XColor *color;
    Pixmap stipple;
    Tk_State state;

    tkwin = Tk_CanvasTkwin(canvas);
    if (TCL_OK != Tk_ConfigureWidget(interp, tkwin, configSpecs, objc,
	    (const char **) objv, (char *) textPtr, flags|TK_CONFIG_OBJS)) {
	return TCL_ERROR;
    }

    /*
     * A few of the options require additional processing, such as graphics
     * contexts.
     */

    state = itemPtr->state;

    if (textPtr->activeColor != NULL || textPtr->activeStipple != None) {
	itemPtr->redraw_flags |= TK_ITEM_STATE_DEPENDANT;
    } else {
	itemPtr->redraw_flags &= ~TK_ITEM_STATE_DEPENDANT;
    }

    if (state == TK_STATE_NULL) {
	state = Canvas(canvas)->canvas_state;
    }

    color = textPtr->color;
    stipple = textPtr->stipple;
    if (Canvas(canvas)->currentItemPtr == itemPtr) {
	if (textPtr->activeColor != NULL) {
	    color = textPtr->activeColor;
	}
	if (textPtr->activeStipple != None) {
	    stipple = textPtr->activeStipple;
	}
    } else if (state == TK_STATE_DISABLED) {
	if (textPtr->disabledColor != NULL) {
	    color = textPtr->disabledColor;
	}
	if (textPtr->disabledStipple != None) {
	    stipple = textPtr->disabledStipple;
	}
    }

    newGC = newSelGC = NULL;
    if (textPtr->tkfont != NULL) {
	gcValues.font = Tk_FontId(textPtr->tkfont);
	mask = GCFont;
	if (color != NULL) {
	    gcValues.foreground = color->pixel;
	    mask |= GCForeground;
	    if (stipple != None) {
		gcValues.stipple = stipple;
		gcValues.fill_style = FillStippled;
		mask |= GCStipple|GCFillStyle;
	    }
	    newGC = Tk_GetGC(tkwin, mask, &gcValues);
	}
	mask &= ~(GCTile|GCFillStyle|GCStipple);
	if (stipple != None) {
	    gcValues.stipple = stipple;
	    gcValues.fill_style = FillStippled;
	    mask |= GCStipple|GCFillStyle;
	}
	if (textInfoPtr->selFgColorPtr != NULL) {
	    gcValues.foreground = textInfoPtr->selFgColorPtr->pixel;
	}
	newSelGC = Tk_GetGC(tkwin, mask|GCForeground, &gcValues);
    }
    if (textPtr->gc != NULL) {
	Tk_FreeGC(Tk_Display(tkwin), textPtr->gc);
    }
    textPtr->gc = newGC;
    if (textPtr->selTextGC != NULL) {
	Tk_FreeGC(Tk_Display(tkwin), textPtr->selTextGC);
    }
    textPtr->selTextGC = newSelGC;

    selBgColorPtr = Tk_3DBorderColor(textInfoPtr->selBorder);
    if (Tk_3DBorderColor(textInfoPtr->insertBorder)->pixel
	    == selBgColorPtr->pixel) {
	if (selBgColorPtr->pixel == BlackPixelOfScreen(Tk_Screen(tkwin))) {
	    gcValues.foreground = WhitePixelOfScreen(Tk_Screen(tkwin));
	} else {
	    gcValues.foreground = BlackPixelOfScreen(Tk_Screen(tkwin));
	}
	newGC = Tk_GetGC(tkwin, GCForeground, &gcValues);
    } else {
	newGC = NULL;
    }
    if (textPtr->cursorOffGC != NULL) {
	Tk_FreeGC(Tk_Display(tkwin), textPtr->cursorOffGC);
    }
    textPtr->cursorOffGC = newGC;

    /*
     * If the text was changed, move the selection and insertion indices to
     * keep them inside the item.
     */

    textPtr->numBytes = strlen(textPtr->text);
    textPtr->numChars = Tcl_NumUtfChars(textPtr->text, textPtr->numBytes);
    if (textInfoPtr->selItemPtr == itemPtr) {

	if (textInfoPtr->selectFirst >= textPtr->numChars) {
	    textInfoPtr->selItemPtr = NULL;
	} else {
	    if (textInfoPtr->selectLast >= textPtr->numChars) {
		textInfoPtr->selectLast = textPtr->numChars - 1;
	    }
	    if ((textInfoPtr->anchorItemPtr == itemPtr)
		    && (textInfoPtr->selectAnchor >= textPtr->numChars)) {
		textInfoPtr->selectAnchor = textPtr->numChars - 1;
	    }
	}
    }
    if (textPtr->insertPos >= textPtr->numChars) {
	textPtr->insertPos = textPtr->numChars;
    }

    /*
     * Restrict so that 0.0 <= angle < 360.0, and then recompute the cached
     * sine and cosine of the angle. Note that fmod() can produce negative
     * results, and we try to avoid negative zero as well.
     */

    textPtr->angle = fmod(textPtr->angle, 360.0);
    if (textPtr->angle < 0.0) {
	textPtr->angle += 360.0;
    }
    if (textPtr->angle == 0.0) {
	textPtr->angle = 0.0;
    }
    textPtr->sine = sin(textPtr->angle * PI/180.0);
    textPtr->cosine = cos(textPtr->angle * PI/180.0);

    ComputeTextBbox(canvas, textPtr);
    return TCL_OK;
}
Exemple #24
0
XColor *
Tk_GetColor(
    Tcl_Interp *interp,		/* Place to leave error message if color can't
				 * be found. */
    Tk_Window tkwin,		/* Window in which color will be used. */
    Tk_Uid name)		/* Name of color to be allocated (in form
				 * suitable for passing to XParseColor). */
{
    Tcl_HashEntry *nameHashPtr;
    int isNew;
    TkColor *tkColPtr;
    TkColor *existingColPtr;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;

    if (!dispPtr->colorInit) {
        ColorInit(dispPtr);
    }

    /*
     * First, check to see if there's already a mapping for this color name.
     */

    nameHashPtr = Tcl_CreateHashEntry(&dispPtr->colorNameTable, name, &isNew);
    if (!isNew) {
        existingColPtr = Tcl_GetHashValue(nameHashPtr);
        for (tkColPtr = existingColPtr; tkColPtr != NULL;
                tkColPtr = tkColPtr->nextPtr) {
            if ((tkColPtr->screen == Tk_Screen(tkwin))
                    && (Tk_Colormap(tkwin) == tkColPtr->colormap)) {
                tkColPtr->resourceRefCount++;
                return &tkColPtr->color;
            }
        }
    } else {
        existingColPtr = NULL;
    }

    /*
     * The name isn't currently known. Map from the name to a pixel value.
     */

    tkColPtr = TkpGetColor(tkwin, name);
    if (tkColPtr == NULL) {
        if (interp != NULL) {
            if (*name == '#') {
                Tcl_AppendResult(interp, "invalid color name \"", name,
                                 "\"", NULL);
            } else {
                Tcl_AppendResult(interp, "unknown color name \"", name,
                                 "\"", NULL);
            }
        }
        if (isNew) {
            Tcl_DeleteHashEntry(nameHashPtr);
        }
        return NULL;
    }

    /*
     * Now create a new TkColor structure and add it to colorNameTable (in
     * TkDisplay).
     */

    tkColPtr->magic = COLOR_MAGIC;
    tkColPtr->gc = None;
    tkColPtr->screen = Tk_Screen(tkwin);
    tkColPtr->colormap = Tk_Colormap(tkwin);
    tkColPtr->visual = Tk_Visual(tkwin);
    tkColPtr->resourceRefCount = 1;
    tkColPtr->objRefCount = 0;
    tkColPtr->type = TK_COLOR_BY_NAME;
    tkColPtr->hashPtr = nameHashPtr;
    tkColPtr->nextPtr = existingColPtr;
    Tcl_SetHashValue(nameHashPtr, tkColPtr);

    return &tkColPtr->color;
}
Exemple #25
0
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;
}
void
TkpComputeMenuButtonGeometry(
    TkMenuButton *mbPtr)	/* Widget record for menu button. */
{
    int width, height, mm, pixels;
    int	 avgWidth, txtWidth, txtHeight;
    int haveImage = 0, haveText = 0;
    Tk_FontMetrics fm;

    mbPtr->inset = mbPtr->highlightWidth + mbPtr->borderWidth;

    width = 0;
    height = 0;
    txtWidth = 0;
    txtHeight = 0;
    avgWidth = 0;

    if (mbPtr->image != None) {
	Tk_SizeOfImage(mbPtr->image, &width, &height);
	haveImage = 1;
    } else if (mbPtr->bitmap != None) {
	Tk_SizeOfBitmap(mbPtr->display, mbPtr->bitmap, &width, &height);
	haveImage = 1;
    }

    if (haveImage == 0 || mbPtr->compound != COMPOUND_NONE) {
	Tk_FreeTextLayout(mbPtr->textLayout);

	mbPtr->textLayout = Tk_ComputeTextLayout(mbPtr->tkfont, mbPtr->text,
		-1, mbPtr->wrapLength, mbPtr->justify, 0, &mbPtr->textWidth,
		&mbPtr->textHeight);
	txtWidth = mbPtr->textWidth;
	txtHeight = mbPtr->textHeight;
	avgWidth = Tk_TextWidth(mbPtr->tkfont, "0", 1);
	Tk_GetFontMetrics(mbPtr->tkfont, &fm);
	haveText = (txtWidth != 0 && txtHeight != 0);
    }

    /*
     * If the menubutton is compound (ie, it shows both an image and text),
     * the new geometry is a combination of the image and text geometry. We
     * only honor the compound bit if the menubutton has both text and an
     * image, because otherwise it is not really a compound menubutton.
     */

    if (mbPtr->compound != COMPOUND_NONE && haveImage && haveText) {
	switch ((enum compound) mbPtr->compound) {
	case COMPOUND_TOP:
	case COMPOUND_BOTTOM:
	    /*
	     * Image is above or below text.
	     */

	    height += txtHeight + mbPtr->padY;
	    width = (width > txtWidth ? width : txtWidth);
	    break;
	case COMPOUND_LEFT:
	case COMPOUND_RIGHT:
	    /*
	     * Image is left or right of text.
	     */

	    width += txtWidth + mbPtr->padX;
	    height = (height > txtHeight ? height : txtHeight);
	    break;
	case COMPOUND_CENTER:
	    /*
	     * Image and text are superimposed.
	     */

	    width = (width > txtWidth ? width : txtWidth);
	    height = (height > txtHeight ? height : txtHeight);
	    break;
	case COMPOUND_NONE:
	    break;
	}
	if (mbPtr->width > 0) {
	    width = mbPtr->width;
	}
	if (mbPtr->height > 0) {
	    height = mbPtr->height;
	}
	width += 2*mbPtr->padX;
	height += 2*mbPtr->padY;
    } else {
	if (haveImage) {
	    if (mbPtr->width > 0) {
		width = mbPtr->width;
	    }
	    if (mbPtr->height > 0) {
		height = mbPtr->height;
	    }
	} else {
	    width = txtWidth;
	    height = txtHeight;
	    if (mbPtr->width > 0) {
		width = mbPtr->width * avgWidth;
	    }
	    if (mbPtr->height > 0) {
		height = mbPtr->height * fm.linespace;
	    }
	}
    }

    if (! haveImage) {
	width += 2*mbPtr->padX;
	height += 2*mbPtr->padY;
    }

    if (mbPtr->indicatorOn) {
	mm = WidthMMOfScreen(Tk_Screen(mbPtr->tkwin));
	pixels = WidthOfScreen(Tk_Screen(mbPtr->tkwin));
	mbPtr->indicatorHeight= (INDICATOR_HEIGHT * pixels)/(10*mm);
	mbPtr->indicatorWidth = (INDICATOR_WIDTH * pixels)/(10*mm)
		+ 2*mbPtr->indicatorHeight;
	width += mbPtr->indicatorWidth;
    } else {
	mbPtr->indicatorHeight = 0;
	mbPtr->indicatorWidth = 0;
    }

    Tk_GeometryRequest(mbPtr->tkwin, (int) (width + 2*mbPtr->inset),
	    (int) (height + 2*mbPtr->inset));
    Tk_SetInternalBorder(mbPtr->tkwin, mbPtr->inset);
}
Exemple #27
0
static
int
GetPixelsFromObjEx(
    Tcl_Interp *interp, 	/* Used for error reporting if not NULL. */
    Tk_Window tkwin,
    Tcl_Obj *objPtr,		/* The object from which to get pixels. */
    int *intPtr,
    double *dblPtr)		/* Places to store resulting pixels. */
{
    int result, fresh;
    double d;
    PixelRep *pixelPtr;
    static double bias[] = {
	1.0,	10.0,	25.4,	0.35278 /*25.4 / 72.0*/
    };

    /*
     * Special hacks where the type of the object is known to be something
     * that is just numeric and cannot require distance conversion. This pokes
     * holes in Tcl's abstractions, but they are just for optimization, not
     * semantics.
     */

    if (objPtr->typePtr != &pixelObjType) {
	ThreadSpecificData *typeCache = GetTypeCache();

	if (objPtr->typePtr == typeCache->doubleTypePtr) {
	    (void) Tcl_GetDoubleFromObj(interp, objPtr, &d);
	    if (dblPtr != NULL) {
		*dblPtr = d;
	    }
	    *intPtr = (int) (d<0 ? d-0.5 : d+0.5);
	    return TCL_OK;
	} else if (objPtr->typePtr == typeCache->intTypePtr) {
	    (void) Tcl_GetIntFromObj(interp, objPtr, intPtr);
	    if (dblPtr) {
		*dblPtr = (double) (*intPtr);
	    }
	    return TCL_OK;
	}
    }

 retry:
    fresh = (objPtr->typePtr != &pixelObjType);
    if (fresh) {
	result = SetPixelFromAny(interp, objPtr);
	if (result != TCL_OK) {
	    return result;
	}
    }

    if (SIMPLE_PIXELREP(objPtr)) {
	*intPtr = GET_SIMPLEPIXEL(objPtr);
	if (dblPtr) {
	    *dblPtr = (double) (*intPtr);
	}
    } else {
	pixelPtr = GET_COMPLEXPIXEL(objPtr);
	if ((!fresh) && (pixelPtr->tkwin != tkwin)) {
	    /*
	     * In the case of exo-screen conversions of non-pixels, we force a
	     * recomputation from the string.
	     */

	    FreePixelInternalRep(objPtr);
	    goto retry;
	}
	if ((pixelPtr->tkwin != tkwin) || dblPtr) {
	    d = pixelPtr->value;
	    if (pixelPtr->units >= 0) {
		d *= bias[pixelPtr->units] * WidthOfScreen(Tk_Screen(tkwin));
		d /= WidthMMOfScreen(Tk_Screen(tkwin));
	    }
	    pixelPtr->returnValue = (int) (d<0 ? d-0.5 : d+0.5);
	    pixelPtr->tkwin = tkwin;
	    if (dblPtr) {
		*dblPtr = d;
	    }
	}
	*intPtr = pixelPtr->returnValue;
    }
    return TCL_OK;
}
Exemple #28
0
XColor *
Tk_AllocColorFromObj(
    Tcl_Interp *interp,		/* Used only for error reporting. If NULL,
				 * then no messages are provided. */
    Tk_Window tkwin,		/* Window in which the color will be used.*/
    Tcl_Obj *objPtr)		/* Object that describes the color; string
				 * value is a color name such as "red" or
				 * "#ff0000".*/
{
    TkColor *tkColPtr;

    if (objPtr->typePtr != &tkColorObjType) {
        InitColorObj(objPtr);
    }
    tkColPtr = (TkColor *) objPtr->internalRep.twoPtrValue.ptr1;

    /*
     * If the object currently points to a TkColor, see if it's the one we
     * want. If so, increment its reference count and return.
     */

    if (tkColPtr != NULL) {
        if (tkColPtr->resourceRefCount == 0) {
            /*
             * This is a stale reference: it refers to a TkColor that's no
             * longer in use. Clear the reference.
             */

            FreeColorObjProc(objPtr);
            tkColPtr = NULL;
        } else if ((Tk_Screen(tkwin) == tkColPtr->screen)
                   && (Tk_Colormap(tkwin) == tkColPtr->colormap)) {
            tkColPtr->resourceRefCount++;
            return (XColor *) tkColPtr;
        }
    }

    /*
     * The object didn't point to the TkColor that we wanted. Search the list
     * of TkColors with the same name to see if one of the other TkColors is
     * the right one.
     */

    if (tkColPtr != NULL) {
        TkColor *firstColorPtr = Tcl_GetHashValue(tkColPtr->hashPtr);

        FreeColorObjProc(objPtr);
        for (tkColPtr = firstColorPtr; tkColPtr != NULL;
                tkColPtr = tkColPtr->nextPtr) {
            if ((Tk_Screen(tkwin) == tkColPtr->screen)
                    && (Tk_Colormap(tkwin) == tkColPtr->colormap)) {
                tkColPtr->resourceRefCount++;
                tkColPtr->objRefCount++;
                objPtr->internalRep.twoPtrValue.ptr1 = (void *) tkColPtr;
                return (XColor *) tkColPtr;
            }
        }
    }

    /*
     * Still no luck. Call Tk_GetColor to allocate a new TkColor object.
     */

    tkColPtr = (TkColor *) Tk_GetColor(interp, tkwin, Tcl_GetString(objPtr));
    objPtr->internalRep.twoPtrValue.ptr1 = (void *) tkColPtr;
    if (tkColPtr != NULL) {
        tkColPtr->objRefCount++;
    }
    return (XColor *) tkColPtr;
}
Exemple #29
0
static Cursor
CreateCursorFromTableOrFile(
    Tcl_Interp *interp,		/* Interpreter to use for error reporting. */
    Tk_Window tkwin,		/* Window in which cursor will be used. */
    int argc,
    const char **argv,		/* Cursor spec parsed into elements. */
    const struct TkCursorName *tkCursorPtr)
				/* Non-NULL when cursor is defined in Tk
				 * table. */
{
    Cursor cursor = None;

    int width, height, maskWidth, maskHeight;
    int xHot = -1, yHot = -1;
    int dummy1, dummy2;
    XColor fg, bg;
    const char *fgColor;
    const char *bgColor;
    int inTkTable = (tkCursorPtr != NULL);

    Display *display = Tk_Display(tkwin);
    Drawable drawable = RootWindowOfScreen(Tk_Screen(tkwin));

    Pixmap source = None;
    Pixmap mask = None;

    /*
     * A cursor defined in a file accepts either 2 or 4 arguments.
     *
     * {srcfile fg}
     * {srcfile maskfile fg bg}
     *
     * A cursor defined in the Tk table accepts 1, 2, or 3 arguments.
     *
     * {tkcursorname}
     * {tkcursorname fg}
     * {tkcursorname fg bg}
     */

    if (inTkTable) {
	/*
	 * This logic is like TkReadBitmapFile().
	 */

	char *data;

	data = TkGetBitmapData(NULL, tkCursorPtr->data, NULL,
		&width, &height, &xHot, &yHot);
	if (data == NULL) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "error reading bitmap data for \"%s\"", argv[0]));
	    Tcl_SetErrorCode(interp, "TK", "CURSOR", "BITMAP_DATA", NULL);
	    goto cleanup;
	}

	source = XCreateBitmapFromData(display, drawable, data, width,height);
	ckfree(data);
    } else {
	if (TkReadBitmapFile(display, drawable, &argv[0][1],
		(unsigned *) &width, (unsigned *) &height,
		&source, &xHot, &yHot) != BitmapSuccess) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "cleanup reading bitmap file \"%s\"", &argv[0][1]));
	    Tcl_SetErrorCode(interp, "TK", "CURSOR", "BITMAP_FILE", NULL);
	    goto cleanup;
	}
    }

    if ((xHot < 0) || (yHot < 0) || (xHot >= width) || (yHot >= height)) {
	if (inTkTable) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "bad hot spot in bitmap data for \"%s\"", argv[0]));
	} else {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "bad hot spot in bitmap file \"%s\"", &argv[0][1]));
	}
	Tcl_SetErrorCode(interp, "TK", "CURSOR", "HOTSPOT", NULL);
	goto cleanup;
    }

    /*
     * Parse color names from optional fg and bg arguments
     */

    if (argc == 1) {
	fg.red = fg.green = fg.blue = 0;
	bg.red = bg.green = bg.blue = 65535;
    } else if (argc == 2) {
	fgColor = argv[1];
	if (TkParseColor(display, Tk_Colormap(tkwin), fgColor, &fg) == 0) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "invalid color name \"%s\"", fgColor));
	    Tcl_SetErrorCode(interp, "TK", "CURSOR", "COLOR", NULL);
	    goto cleanup;
	}
	if (inTkTable) {
	    bg.red = bg.green = bg.blue = 0;
	} else {
	    bg = fg;
	}
    } else {
	/* 3 or 4 arguments */
	if (inTkTable) {
	    fgColor = argv[1];
	    bgColor = argv[2];
	} else {
	    fgColor = argv[2];
	    bgColor = argv[3];
	}
	if (TkParseColor(display, Tk_Colormap(tkwin), fgColor, &fg) == 0) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "invalid color name \"%s\"", fgColor));
	    Tcl_SetErrorCode(interp, "TK", "CURSOR", "COLOR", NULL);
	    goto cleanup;
	}
	if (TkParseColor(display, Tk_Colormap(tkwin), bgColor, &bg) == 0) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "invalid color name \"%s\"", bgColor));
	    Tcl_SetErrorCode(interp, "TK", "CURSOR", "COLOR", NULL);
	    goto cleanup;
	}
    }

    /*
     * If there is no mask data, then create the cursor now.
     */

    if ((!inTkTable && (argc == 2)) || (inTkTable && tkCursorPtr->mask == NULL)) {
	cursor = XCreatePixmapCursor(display, source, source,
		&fg, &fg, (unsigned) xHot, (unsigned) yHot);
	goto cleanup;
    }

    /*
     * Parse bitmap mask data and create cursor with fg and bg colors.
     */

    if (inTkTable) {
	/*
	 * This logic is like TkReadBitmapFile().
	 */

	char *data;

	data = TkGetBitmapData(NULL, tkCursorPtr->mask, NULL,
		&maskWidth, &maskHeight, &dummy1, &dummy2);
	if (data == NULL) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "error reading bitmap mask data for \"%s\"", argv[0]));
	    Tcl_SetErrorCode(interp, "TK", "CURSOR", "MASK_DATA", NULL);
	    goto cleanup;
	}

	mask = XCreateBitmapFromData(display, drawable, data, maskWidth,
		maskHeight);

	ckfree(data);
    } else {
	if (TkReadBitmapFile(display, drawable, argv[1],
		(unsigned int *) &maskWidth, (unsigned int *) &maskHeight,
		&mask, &dummy1, &dummy2) != BitmapSuccess) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "cleanup reading bitmap file \"%s\"", argv[1]));
	    Tcl_SetErrorCode(interp, "TK", "CURSOR", "MASK_FILE", NULL);
	    goto cleanup;
	}
    }

    if ((maskWidth != width) || (maskHeight != height)) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"source and mask bitmaps have different sizes", -1));
	Tcl_SetErrorCode(interp, "TK", "CURSOR", "SIZE_MATCH", NULL);
	goto cleanup;
    }

    cursor = XCreatePixmapCursor(display, source, mask,
	    &fg, &bg, (unsigned) xHot, (unsigned) yHot);

  cleanup:
    if (source != None) {
	Tk_FreePixmap(display, source);
    }
    if (mask != None) {
	Tk_FreePixmap(display, mask);
    }
    return cursor;
}