int XILWindowAssistor::command(int argc, const char*const* argv)
{
	u_int		nbands;
	XilDataType	datatype;

//	fprintf(stderr,"XILWindowAssistor::"__FUNCTION__"\n");
	if (argc == 3 && strcmp(argv[1], "window") == 0) {
		sentfirstheader=0;
		imageYCC = NULL;
		ximage_ = NULL;
		window_ = VideoWindow::lookup(argv[2]);
		Tk_MakeWindowExist(window_->tkwin());
		// gc_ = Tk_GetGC(window_->tkwin(), 0, 0);
		gc_ = XCreateGC(Tk_Display(window_->tkwin()),
				Tk_WindowId(window_->tkwin()), 0, NULL);
		Tk_CreateEventHandler(window_->tkwin(), ExposureMask,
				      handle_exposure_callback,
				      (ClientData)this);
		//fprintf(stderr,"xil_create_from_window(%p,%p,%08lx)\n", xil_,Tk_Display(window_->tkwin()),Tk_WindowId(window_->tkwin()));
		displayimage_=xil_create_from_window(xil_,Tk_Display(window_->tkwin()),Tk_WindowId(window_->tkwin()));
		//fprintf(stderr,"HW_DECOMPRESS_CIS\n");
		// disable (osprey) hardware decompression for Windowed Display.
		// the software decoder is fast enough
		xil_set_attribute(displayimage_,"HW_DECOMPRESS_CIS",(void *)-1);
/*
		int arg;
		xil_get_device_attribute(displayimage_,"VIDEO_OUT",(void**)&arg);
		//fprintf(stderr,"VIDEO_OUT-> %d\n",arg);

		xil_set_device_attribute(displayimage_,"VIDEO_OUT",(void*)FALSE);

 */
//		xil_set_device_attribute(displayimage_,"H261_PIP",(void*)TRUE);

		xil_get_info(displayimage_, &targetw_, &targeth_, &nbands, &datatype);
		//fprintf(stderr,"w=%d,h=%d,bands=%d,dt=%d\n", targetw_,targeth_,nbands,datatype);
		switch (Tk_Depth(window_->tkwin())) {
		case 8:
			visual = PSEUDOCOLOR;
			break;
		case 24:
			visual = TRUECOLOR;
			break;
		default:
			fprintf(stderr,"XILWindowAssistor:command(window), unknown depth %d!\n",Tk_Depth(window_->tkwin()));
			visual = PSEUDOCOLOR;
			break;
		}
		x_cmap = 0;
		return (TCL_OK);
	}
	return (Renderer::command(argc, argv));
}
Beispiel #2
0
void trace_flash (DNATrace *t) {
    int x0, i;
    Display *d = t->display;
    Window w = Tk_WindowId(t->tkwin);
    Pixmap tmp;

    if (!Tk_IsMapped(t->tkwin) || Tk_WindowId(t->tkwin) == 0)
	return;

    x0 = point_to_pixel(t, trace_get_pos(t, t->cursor_pos));

    tmp = Tk_GetPixmap(d, w, 24, t->pos[TRACEP_T].h, Tk_Depth(t->tkwin));
    XCopyArea(d, w, tmp, t->CursorGC,
	      x0-12, t->pos[TRACEP_T].y, 24, t->pos[TRACEP_T].h, 0, 0);

    for (i=12; i > 0; i-=3) {
	XCopyArea(d, tmp, w, t->CursorGC,
		  0, 0, 24, t->pos[TRACEP_T].h, x0-12, t->pos[TRACEP_T].y);

	XFillRectangle(d, w,
		       t->CursorGC,
		       x0 - i, t->pos[TRACEP_T].y,
		       i, t->pos[TRACEP_T].h);

	XSync(d, False);

	myusleep(20000);
    }
    XCopyArea(d, tmp, w, t->CursorGC,
	      0, 0, 24, t->pos[TRACEP_T].h, x0-12, t->pos[TRACEP_T].y);


    Tk_FreePixmap(d, tmp);
}
Beispiel #3
0
int ColorModel::command(int argc, const char*const* argv)
{
	Tcl& tcl = Tcl::instance();
	if (argc == 2) {
		if (strcmp(argv[1], "alloc-colors") == 0) {
			tcl.result(allocate() < 0 ? "0" : "1");
			return (TCL_OK);
		}
		if (strcmp(argv[1], "free-colors") == 0) {
			free_colors();
			return (TCL_OK);
		}
	} else if (argc == 3) {
		if (strcmp(argv[1], "visual") == 0) {
			Tk_Window tk = Tk_NameToWindow(tcl.interp(),
						       (char*)argv[2],
						       tcl.tkmain());
			setvisual(Tk_Visual(tk), Tk_Colormap(tk),
				  Tk_Depth(tk));
			return (TCL_OK);
		}
		if (strcmp(argv[1], "gamma") == 0) {
			double v = atof(argv[2]);
			if (v < 0)
				tcl.result("0");
			gamma_ = v;
			tcl.result("1");
			return (TCL_OK);
		}
	}
	return (TclObject::command(argc, argv));
}
Beispiel #4
0
static void
DragImage_UpdateStylePixmap(
    TreeDragImage dragImage)	/* Drag image record. */
{
    TreeCtrl *tree = dragImage->tree;
    int w, h, state = 0;
    XColor *colorPtr;
    GC gc;
    StyleDrawArgs drawArgs;

    w = dragImage->styleW = TreeStyle_NeededWidth(tree, dragImage->instanceStyle, state);
    h = dragImage->styleH = TreeStyle_NeededHeight(tree, dragImage->instanceStyle, state);
    if (w > dragImage->pixmapW || h > dragImage->pixmapH)
    {

	if (dragImage->pixmap != None)
	    Tk_FreePixmap(tree->display, dragImage->pixmap);
	dragImage->pixmap = Tk_GetPixmap(tree->display,
	    Tk_WindowId(tree->tkwin),
	    w, h, Tk_Depth(tree->tkwin));

	dragImage->pixmapW = w;
	dragImage->pixmapH = h;
    }

    colorPtr = Tk_GetColor(tree->interp, tree->tkwin, "pink");
    gc = Tk_GCForColor(colorPtr, Tk_WindowId(tree->tkwin));
    XFillRectangle(tree->display, dragImage->pixmap, gc,
	0, 0, w, h);

    drawArgs.tree = tree;

    drawArgs.td.drawable = dragImage->pixmap;
    drawArgs.td.width = w; drawArgs.td.height = h;

    drawArgs.bounds[0] = drawArgs.bounds[1] = 0;
    drawArgs.bounds[2] = w; drawArgs.bounds[3] = h;

    drawArgs.state = state;
    drawArgs.style = dragImage->instanceStyle;

    drawArgs.indent = 0;

    drawArgs.x = drawArgs.y = 0;
    drawArgs.width = w; drawArgs.height = h;

    drawArgs.justify = TK_JUSTIFY_LEFT;

    TreeStyle_Draw(&drawArgs);

    if (dragImage->tkimage != NULL) {
	Tk_FreeImage(dragImage->tkimage);
	dragImage->tkimage = NULL;
    }
}
Beispiel #5
0
Pixmap
HtmlImageTilePixmap(
    HtmlImage2* pImage,
    int *pW,
    int *pH
    )
{
    if (HtmlImagePixmap(pImage)) {
        Tk_Window win;
        XGCValues gc_values;
        GC gc;
        int i, j;

        if( pImage->tilepixmap ){
            goto return_tile; 
        }

        if (!tilesize(pImage, &pImage->iTileWidth, &pImage->iTileHeight)) {
            goto return_original;
        }

        win = pImage->pImageServer->pTree->tkwin;
        pImage->tilepixmap = Tk_GetPixmap(Tk_Display(win), Tk_WindowId(win),
            pImage->iTileWidth, pImage->iTileHeight, Tk_Depth(win)
        );

        memset(&gc_values, 0, sizeof(XGCValues));
        gc = Tk_GetGC(win, 0, &gc_values);
        for (i = 0; i < pImage->iTileWidth; i += pImage->width){
            for (j = 0; j < pImage->iTileHeight; j += pImage->height){
                XCopyArea(Tk_Display(win), 
                     pImage->pixmap, pImage->tilepixmap, gc, 0, 0, 
                     pImage->width, pImage->height, 
                     i, j
                );
            }
        }
        Tk_FreeGC(Tk_Display(win), gc);
    }

return_tile:
    *pW = pImage->iTileWidth;
    *pH = pImage->iTileHeight;
    return pImage->tilepixmap;

return_original:
    *pW = pImage->width;
    *pH = pImage->height;
    return pImage->pixmap;
}
Beispiel #6
0
static void
UpdatePixmap(
    TreeDragImage dragImage	/* Drag image record. */
    )
{
    TreeCtrl *tree = dragImage->tree;
    int w, h;
    XColor *colorPtr;
    GC gc;
    DragElem *elem;
    unsigned long trans;

    w = dragImage->bounds[2] - dragImage->bounds[0];
    h = dragImage->bounds[3] - dragImage->bounds[1];
    if (w > dragImage->pixmapW || h > dragImage->pixmapH)
    {

	if (dragImage->pixmap != None)
	    Tk_FreePixmap(tree->display, dragImage->pixmap);
	dragImage->pixmap = Tk_GetPixmap(tree->display,
	    Tk_WindowId(tree->tkwin),
	    w, h, Tk_Depth(tree->tkwin));

	dragImage->pixmapW = w;
	dragImage->pixmapH = h;
    }

    colorPtr = Tk_GetColor(tree->interp, tree->tkwin, "pink");
    gc = Tk_GCForColor(colorPtr, Tk_WindowId(tree->tkwin));
    XFillRectangle(tree->display, dragImage->pixmap, gc,
	0, 0, w, h);

    trans = colorPtr->pixel;

    colorPtr = Tk_GetColor(tree->interp, tree->tkwin, "gray50");
    gc = Tk_GCForColor(colorPtr, Tk_WindowId(tree->tkwin));

    for (elem = dragImage->elem; elem != NULL; elem = elem->next) {
	XFillRectangle(tree->display, dragImage->pixmap, gc,
	    elem->x - dragImage->bounds[0],
	    elem->y - dragImage->bounds[1],
	    elem->width, elem->height);
    }

    if (dragImage->image != NULL) {
	Tk_FreeImage(dragImage->image);
	dragImage->image = NULL;
    }
}
Beispiel #7
0
/*
 *---------------------------------------------------------------------------
 *
 * HtmlImagePixmap --
 *
 * Results:
 *     Pixmap. Or zero.
 *
 * Side effects:
 *     May change the image storage to pixmap.
 *
 *---------------------------------------------------------------------------
 */
Pixmap
HtmlImagePixmap(HtmlImage2 *pImage)
{
    if (!pImage->pImageServer->pTree->options.imagepixmapify ||
        !pImage->pImageName ||
        !getImageCompressed(pImage) ||
        pImage->width<=0 ||
        pImage->height<=0
    ) {
        return 0;
    }
    if (!pImage->isValid) {
        HtmlImageImage(pImage);
    }
    if (!pImage->pixmap && !HtmlImageAlphaChannel(pImage)) {
        Tk_Window win = pImage->pImageServer->pTree->tkwin;
        Tcl_Interp *interp = pImage->pImageServer->pTree->interp;

        Pixmap pix;
        int rc;
        Tcl_Obj *pGetData;

#if 0
printf("Pixmapifying - nData = %d\n", nData);
#endif

        pix = Tk_GetPixmap(Tk_Display(win), Tk_WindowId(win),
            pImage->width, pImage->height, Tk_Depth(win)
        );
        Tk_RedrawImage(
            pImage->image, 0, 0, pImage->width, pImage->height, pix, 0, 0
        );

        pImage->pixmap = pix;

        pGetData = Tcl_NewObj();
        Tcl_IncrRefCount(pGetData);
        Tcl_ListObjAppendElement(0, pGetData, Tcl_NewStringObj("image",-1));
        Tcl_ListObjAppendElement(0, pGetData, Tcl_NewStringObj("create",-1));
        Tcl_ListObjAppendElement(0, pGetData, Tcl_NewStringObj("photo",-1));
        Tcl_ListObjAppendElement(0, pGetData, pImage->pImageName);
        pImage->nIgnoreChange++;
        rc = Tcl_EvalObjEx(interp, pGetData, TCL_EVAL_GLOBAL|TCL_EVAL_DIRECT);
        pImage->nIgnoreChange--;
        Tcl_DecrRefCount(pGetData);
        assert(rc==TCL_OK);
    }
    return pImage->pixmap;
}
Beispiel #8
0
int C_StretchBoxProc(ClientData cl, Tcl_Interp *interp, int argc, char **argv)
{
  double x2,y2,xtemp2,ytemp2;
  Pixmap pm;
  XRectangle theClientArea;
  Tk_Window tkwin;
  WindowType theWindow = theWindowArray[atoi(argv[1])];

  tkwin = theWindow->tkwin;

  theClientArea.x = 0;
  theClientArea.y = 0;
  theClientArea.width = Tk_Width(tkwin);
  theClientArea.height = Tk_Height(tkwin);
  XSetClipRectangles(theDisplay, theWindow->xwingc, 0, 0, &theClientArea, 
		     1, Unsorted);

  pm = XCreatePixmap(theDisplay, Tk_WindowId(tkwin), Tk_Width(tkwin),
		     Tk_Height(tkwin), Tk_Depth(tkwin));
  XCopyArea(theDisplay, theWindow->pixmap_buffer, pm, theWindow->xwingc, 0,
	    0, Tk_Width(tkwin), Tk_Height(tkwin), 0, 0);

  x2 = atof(argv[2]);
  y2 = atof(argv[3]);

  if (Is_X_Log(theWindow)) {
    xtemp2 = theWindow->c1 * log10(max(x2, DBL_MIN)) + theWindow->d1;
  } else {
    xtemp2 = theWindow->c1 * x2 + theWindow->d1;
  }
    
  if (Is_Y_Log(theWindow)) {
    ytemp2 = theWindow->c2 * log10(max(y2, DBL_MIN)) + theWindow->d2;
  } else {
    ytemp2 = theWindow->c2 * y2 + theWindow->d2;
  }

  XSetForeground(theDisplay, theWindow->xwingc, theWhitePixel);
  XDrawRectangle(theDisplay, pm, theWindow->xwingc, min(xtemp1,xtemp2), 
		 min(ytemp1,ytemp2), fabs(xtemp2 - xtemp1), 
		 fabs(ytemp2 - ytemp1));
  XCopyArea(theDisplay, pm, Tk_WindowId(tkwin), theWindow->xwingc, 0, 0,
	    Tk_Width(tkwin), Tk_Height(tkwin), 0, 0);
  XFlush(theDisplay);
  XFreePixmap(theDisplay, pm);
  
  return TCL_OK;
}
Beispiel #9
0
int
Tk_ConfigureValue(
    Tcl_Interp *interp,		/* Interpreter for error reporting. */
    Tk_Window tkwin,		/* Window corresponding to widgRec. */
    Tk_ConfigSpec *specs,	/* Describes legal options. */
    char *widgRec,		/* Record whose fields contain current values
				 * for options. */
    CONST char *argvName,	/* Gives the command-line name for the option
				 * whose value is to be returned. */
    int flags)			/* Used to specify additional flags that must
				 * be present in config specs for them to be
				 * considered. */
{
    Tk_ConfigSpec *specPtr;
    int needFlags, hateFlags;
    Tcl_FreeProc *freeProc;
    CONST char *result;
    char buffer[200];

    needFlags = flags & ~(TK_CONFIG_USER_BIT - 1);
    if (Tk_Depth(tkwin) <= 1) {
        hateFlags = TK_CONFIG_COLOR_ONLY;
    } else {
        hateFlags = TK_CONFIG_MONO_ONLY;
    }

    /*
     * Get the build of the config for this interpreter.
     */

    specs = GetCachedSpecs(interp, specs);

    specPtr = FindConfigSpec(interp, specs, argvName, needFlags, hateFlags);
    if (specPtr == NULL) {
        return TCL_ERROR;
    }
    result = FormatConfigValue(interp, tkwin, specPtr, widgRec, buffer,
                               &freeProc);
    Tcl_SetResult(interp, (char *) result, TCL_VOLATILE);
    if (freeProc != NULL) {
        if ((freeProc == TCL_DYNAMIC) || (freeProc == (Tcl_FreeProc *) free)) {
            ckfree((char *)result);
        } else {
            (*freeProc)((char *)result);
        }
    }
    return TCL_OK;
}
Beispiel #10
0
static PyObject * getintattr(TkWinObject * self, char * name)
{
    int value;

    if (*name == 'w' && strcmp(name, "width") == 0)
	value = Tk_Width(self->tkwin);
    else if (*name == 'h' && strcmp(name, "height") == 0)
	value = Tk_Height(self->tkwin);
    else if (*name == 'x' && name[1] == '\0')
	value = Tk_X(self->tkwin);
    else if (*name == 'y' && name[1] == '\0')
	value = Tk_Y(self->tkwin);
    else if (*name == 'd' && strcmp(name, "depth") == 0)
	value = Tk_Depth(self->tkwin);
    else
	return NULL;

    return PyInt_FromLong(value);
}
Beispiel #11
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);
}
Beispiel #12
0
/* 
 * constructor: create the zoom GC and XImage. 
 *
 * Args:
 *
 *  tkwin         - the Tk window for displaying the zoomed image
 *
 *  copyGC        - X GC used to copy image to zoom window
 *
 *  width, height - dimensions of tkwin (should be square and a multiple
 *                  of the zoom factor)
 *
 *  zoomFactor    - the zoom magnification factor
 *
 *  usingXShm     - flag: true if using X shared memory
 *
 *  verbose       - flag: if true, print diagnostic messages
 *  
 */
ImageZoom::ImageZoom(Tk_Window tkwin, GC gc, int width, int height, 
		     int zoomFactor, int usingXShm, int verbose)
    : tkwin_(tkwin),
      gc_(gc),
      width_(width),
      height_(height),
      zoomFactor_(zoomFactor),
      zoomStep_(width/zoomFactor),
      status_(TCL_OK)
{
    // make a graphics context using XOR to draw a box marking the pointer hotspot
    XGCValues gcValues;
    gcValues.function = GXcopy;
    gcValues.graphics_exposures = False;
    Tk_MakeWindowExist(tkwin_);
    rect_gc_ = XCreateGC(Tk_Display(tkwin_), Tk_WindowId(tkwin_),
			 GCFunction|GCGraphicsExposures, 
			 &gcValues);
    // create a class object to manage the XImage
    xImage_ = new ImageDisplay(Tk_Display(tkwin_), Tk_Visual(tkwin_), gc, 
			       Tk_Depth(tkwin_), usingXShm, verbose);
    status_ = xImage_->update(width, height);
}
Beispiel #13
0
void
TkpDisplayButton(
    ClientData clientData)	/* Information about widget. */
{
    register TkButton *butPtr = (TkButton *) clientData;
    GC gc;
    Tk_3DBorder border;
    Pixmap pixmap;
    int x = 0;			/* Initialization only needed to stop compiler
				 * warning. */
    int y, relief;
    Tk_Window tkwin = butPtr->tkwin;
    int width, height, fullWidth, fullHeight;
    int textXOffset, textYOffset;
    int haveImage = 0, haveText = 0;
    int offset;			/* 1 means this is a button widget, so we
				 * offset the text to make the button appear
				 * to move up and down as the relief
				 * changes. */
    int imageWidth, imageHeight;
    int imageXOffset = 0, imageYOffset = 0;
				/* image information that will be used to
				 * restrict disabled pixmap as well */

    butPtr->flags &= ~REDRAW_PENDING;
    if ((butPtr->tkwin == NULL) || !Tk_IsMapped(tkwin)) {
	return;
    }

    border = butPtr->normalBorder;
    if ((butPtr->state == STATE_DISABLED) && (butPtr->disabledFg != NULL)) {
	gc = butPtr->disabledGC;
    } else if ((butPtr->state == STATE_ACTIVE)
	    && !Tk_StrictMotif(butPtr->tkwin)) {
	gc = butPtr->activeTextGC;
	border = butPtr->activeBorder;
    } else {
	gc = butPtr->normalTextGC;
    }
    if ((butPtr->flags & SELECTED) && (butPtr->state != STATE_ACTIVE)
	    && (butPtr->selectBorder != NULL) && !butPtr->indicatorOn) {
	border = butPtr->selectBorder;
    }

    /*
     * Override the relief specified for the button if this is a checkbutton
     * or radiobutton and there's no indicator. The new relief is as follows:
     *      If the button is select  --> "sunken"
     *      If relief==overrelief    --> relief
     *      Otherwise                --> overrelief
     *
     * The effect we are trying to achieve is as follows:
     *
     *      value    mouse-over?   -->   relief
     *     -------  ------------        --------
     *       off        no               flat
     *       off        yes              raised
     *       on         no               sunken
     *       on         yes              sunken
     *
     * This is accomplished by configuring the checkbutton or radiobutton like
     * this:
     *
     *     -indicatoron 0 -overrelief raised -offrelief flat
     *
     * Bindings (see library/button.tcl) will copy the -overrelief into
     * -relief on mouseover. Hence, we can tell if we are in mouse-over by
     * comparing relief against overRelief. This is an aweful kludge, but it
     * gives use the desired behavior while keeping the code backwards
     * compatible.
     */

    relief = butPtr->relief;
    if ((butPtr->type >= TYPE_CHECK_BUTTON) && !butPtr->indicatorOn) {
	if (butPtr->flags & SELECTED) {
	    relief = TK_RELIEF_SUNKEN;
	} else if (butPtr->overRelief != relief) {
	    relief = butPtr->offRelief;
	}
    }

    offset = (butPtr->type == TYPE_BUTTON) && !Tk_StrictMotif(butPtr->tkwin);

    /*
     * In order to avoid screen flashes, this function redraws the button in a
     * pixmap, then copies the pixmap to the screen in a single operation.
     * This means that there's no point in time where the on-screen image has
     * been cleared.
     */

    pixmap = Tk_GetPixmap(butPtr->display, Tk_WindowId(tkwin),
	    Tk_Width(tkwin), Tk_Height(tkwin), Tk_Depth(tkwin));
    Tk_Fill3DRectangle(tkwin, pixmap, border, 0, 0, Tk_Width(tkwin),
	    Tk_Height(tkwin), 0, TK_RELIEF_FLAT);

    /*
     * Display image or bitmap or text for button.
     */

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

    haveText = (butPtr->textWidth != 0 && butPtr->textHeight != 0);

    if (butPtr->compound != COMPOUND_NONE && haveImage && haveText) {
	textXOffset = 0;
	textYOffset = 0;
	fullWidth = 0;
	fullHeight = 0;

	switch ((enum compound) butPtr->compound) {
	case COMPOUND_TOP:
	case COMPOUND_BOTTOM:
	    /*
	     * Image is above or below text.
	     */

	    if (butPtr->compound == COMPOUND_TOP) {
		textYOffset = height + butPtr->padY;
	    } else {
		imageYOffset = butPtr->textHeight + butPtr->padY;
	    }
	    fullHeight = height + butPtr->textHeight + butPtr->padY;
	    fullWidth = (width > butPtr->textWidth ? width :
		    butPtr->textWidth);
	    textXOffset = (fullWidth - butPtr->textWidth)/2;
	    imageXOffset = (fullWidth - width)/2;
	    break;
	case COMPOUND_LEFT:
	case COMPOUND_RIGHT:
	    /*
	     * Image is left or right of text.
	     */

	    if (butPtr->compound == COMPOUND_LEFT) {
		textXOffset = width + butPtr->padX;
	    } else {
		imageXOffset = butPtr->textWidth + butPtr->padX;
	    }
	    fullWidth = butPtr->textWidth + butPtr->padX + width;
	    fullHeight = (height > butPtr->textHeight ? height :
		    butPtr->textHeight);
	    textYOffset = (fullHeight - butPtr->textHeight)/2;
	    imageYOffset = (fullHeight - height)/2;
	    break;
	case COMPOUND_CENTER:
	    /*
	     * Image and text are superimposed.
	     */

	    fullWidth = (width > butPtr->textWidth ? width :
		    butPtr->textWidth);
	    fullHeight = (height > butPtr->textHeight ? height :
		    butPtr->textHeight);
	    textXOffset = (fullWidth - butPtr->textWidth)/2;
	    imageXOffset = (fullWidth - width)/2;
	    textYOffset = (fullHeight - butPtr->textHeight)/2;
	    imageYOffset = (fullHeight - height)/2;
	    break;
	case COMPOUND_NONE:
	    break;
	}

	TkComputeAnchor(butPtr->anchor, tkwin, butPtr->padX, butPtr->padY,
		butPtr->indicatorSpace + fullWidth, fullHeight, &x, &y);

	x += butPtr->indicatorSpace;

	x += offset;
	y += offset;
	if (relief == TK_RELIEF_RAISED) {
	    x -= offset;
	    y -= offset;
	} else if (relief == TK_RELIEF_SUNKEN) {
	    x += offset;
	    y += offset;
	}

	imageXOffset += x;
	imageYOffset += y;

	if (butPtr->image != NULL) {
	    /*
	     * Do boundary clipping, so that Tk_RedrawImage is passed valid
	     * coordinates. [Bug 979239]
	     */

	    if (imageXOffset < 0) {
		imageXOffset = 0;
	    }
	    if (imageYOffset < 0) {
		imageYOffset = 0;
	    }
	    if (width > Tk_Width(tkwin)) {
		width = Tk_Width(tkwin);
	    }
	    if (height > Tk_Height(tkwin)) {
		height = Tk_Height(tkwin);
	    }
	    if ((width + imageXOffset) > Tk_Width(tkwin)) {
		imageXOffset = Tk_Width(tkwin) - width;
	    }
	    if ((height + imageYOffset) > Tk_Height(tkwin)) {
		imageYOffset = Tk_Height(tkwin) - height;
	    }

	    if ((butPtr->selectImage != NULL) && (butPtr->flags & SELECTED)) {
		Tk_RedrawImage(butPtr->selectImage, 0, 0,
			width, height, pixmap, imageXOffset, imageYOffset);
	    } else if ((butPtr->tristateImage != NULL) && (butPtr->flags & TRISTATED)) {
		Tk_RedrawImage(butPtr->tristateImage, 0, 0,
			width, height, pixmap, imageXOffset, imageYOffset);
	    } else {
		Tk_RedrawImage(butPtr->image, 0, 0, width,
			height, pixmap, imageXOffset, imageYOffset);
	    }
	} else {
	    XSetClipOrigin(butPtr->display, gc, imageXOffset, imageYOffset);
	    XCopyPlane(butPtr->display, butPtr->bitmap, pixmap, gc,
		    0, 0, (unsigned int) width, (unsigned int) height,
		    imageXOffset, imageYOffset, 1);
	    XSetClipOrigin(butPtr->display, gc, 0, 0);
	}

	Tk_DrawTextLayout(butPtr->display, pixmap, gc,
		butPtr->textLayout, x + textXOffset, y + textYOffset, 0, -1);
	Tk_UnderlineTextLayout(butPtr->display, pixmap, gc,
		butPtr->textLayout, x + textXOffset, y + textYOffset,
		butPtr->underline);
	y += fullHeight/2;
    } else {
	if (haveImage) {
	    TkComputeAnchor(butPtr->anchor, tkwin, 0, 0,
		    butPtr->indicatorSpace + width, height, &x, &y);
	    x += butPtr->indicatorSpace;

	    x += offset;
	    y += offset;
	    if (relief == TK_RELIEF_RAISED) {
		x -= offset;
		y -= offset;
	    } else if (relief == TK_RELIEF_SUNKEN) {
		x += offset;
		y += offset;
	    }
	    imageXOffset += x;
	    imageYOffset += y;
	    if (butPtr->image != NULL) {
		/*
		 * Do boundary clipping, so that Tk_RedrawImage is passed
		 * valid coordinates. [Bug 979239]
		 */

		if (imageXOffset < 0) {
		    imageXOffset = 0;
		}
		if (imageYOffset < 0) {
		    imageYOffset = 0;
		}
		if (width > Tk_Width(tkwin)) {
		    width = Tk_Width(tkwin);
		}
		if (height > Tk_Height(tkwin)) {
		    height = Tk_Height(tkwin);
		}
		if ((width + imageXOffset) > Tk_Width(tkwin)) {
		    imageXOffset = Tk_Width(tkwin) - width;
		}
		if ((height + imageYOffset) > Tk_Height(tkwin)) {
		    imageYOffset = Tk_Height(tkwin) - height;
		}

		if ((butPtr->selectImage != NULL) &&
			(butPtr->flags & SELECTED)) {
		    Tk_RedrawImage(butPtr->selectImage, 0, 0, width,
			    height, pixmap, imageXOffset, imageYOffset);
		} else if ((butPtr->tristateImage != NULL) &&
			(butPtr->flags & TRISTATED)) {
		    Tk_RedrawImage(butPtr->tristateImage, 0, 0, width,
			    height, pixmap, imageXOffset, imageYOffset);
		} else {
		    Tk_RedrawImage(butPtr->image, 0, 0, width, height, pixmap,
			    imageXOffset, imageYOffset);
		}
	    } else {
		XSetClipOrigin(butPtr->display, gc, x, y);
		XCopyPlane(butPtr->display, butPtr->bitmap, pixmap, gc, 0, 0,
			(unsigned int) width, (unsigned int) height, x, y, 1);
		XSetClipOrigin(butPtr->display, gc, 0, 0);
	    }
	    y += height/2;
	} else {
 	    TkComputeAnchor(butPtr->anchor, tkwin, butPtr->padX, butPtr->padY,
		    butPtr->indicatorSpace + butPtr->textWidth,
		    butPtr->textHeight, &x, &y);

	    x += butPtr->indicatorSpace;

	    x += offset;
	    y += offset;
	    if (relief == TK_RELIEF_RAISED) {
		x -= offset;
		y -= offset;
	    } else if (relief == TK_RELIEF_SUNKEN) {
		x += offset;
		y += offset;
	    }
	    Tk_DrawTextLayout(butPtr->display, pixmap, gc, butPtr->textLayout,
		    x, y, 0, -1);
	    Tk_UnderlineTextLayout(butPtr->display, pixmap, gc,
		    butPtr->textLayout, x, y, butPtr->underline);
	    y += butPtr->textHeight/2;
	}
    }

    /*
     * Draw the indicator for check buttons and radio buttons. At this point,
     * x and y refer to the top-left corner of the text or image or bitmap.
     */

    if ((butPtr->type == TYPE_CHECK_BUTTON) && butPtr->indicatorOn) {
	if (butPtr->indicatorDiameter > 2*butPtr->borderWidth) {
	    TkBorder *selBorder = (TkBorder *) butPtr->selectBorder;
	    XColor *selColor = NULL;

	    if (selBorder != NULL) {
		selColor = selBorder->bgColorPtr;
	    }
	    x -= butPtr->indicatorSpace/2;
	    y = Tk_Height(tkwin)/2;
	    TkpDrawCheckIndicator(tkwin, butPtr->display, pixmap, x, y,
		    border, butPtr->normalFg, selColor, butPtr->disabledFg,
		    ((butPtr->flags & SELECTED) ? 1 :
			    (butPtr->flags & TRISTATED) ? 2 : 0),
		    (butPtr->state == STATE_DISABLED), CHECK_BUTTON);
	}
    } else if ((butPtr->type == TYPE_RADIO_BUTTON) && butPtr->indicatorOn) {
	if (butPtr->indicatorDiameter > 2*butPtr->borderWidth) {
	    TkBorder *selBorder = (TkBorder *) butPtr->selectBorder;
	    XColor *selColor = NULL;

	    if (selBorder != NULL) {
		selColor = selBorder->bgColorPtr;
	    }
	    x -= butPtr->indicatorSpace/2;
	    y = Tk_Height(tkwin)/2;
	    TkpDrawCheckIndicator(tkwin, butPtr->display, pixmap, x, y,
		    border, butPtr->normalFg, selColor, butPtr->disabledFg,
		    ((butPtr->flags & SELECTED) ? 1 :
			    (butPtr->flags & TRISTATED) ? 2 : 0),
		    (butPtr->state == STATE_DISABLED), RADIO_BUTTON);
	}
    }

    /*
     * If the button is disabled with a stipple rather than a special
     * foreground color, generate the stippled effect. If the widget is
     * selected and we use a different background color when selected, must
     * temporarily modify the GC so the stippling is the right color.
     */

    if ((butPtr->state == STATE_DISABLED)
	    && ((butPtr->disabledFg == NULL) || (butPtr->image != NULL))) {
	if ((butPtr->flags & SELECTED) && !butPtr->indicatorOn
		&& (butPtr->selectBorder != NULL)) {
	    XSetForeground(butPtr->display, butPtr->stippleGC,
		    Tk_3DBorderColor(butPtr->selectBorder)->pixel);
	}

	/*
	 * Stipple the whole button if no disabledFg was specified, otherwise
	 * restrict stippling only to displayed image
	 */

	if (butPtr->disabledFg == NULL) {
	    XFillRectangle(butPtr->display, pixmap, butPtr->stippleGC, 0, 0,
		    (unsigned) Tk_Width(tkwin), (unsigned) Tk_Height(tkwin));
	} else {
	    XFillRectangle(butPtr->display, pixmap, butPtr->stippleGC,
		    imageXOffset, imageYOffset,
		    (unsigned) imageWidth, (unsigned) imageHeight);
	}
	if ((butPtr->flags & SELECTED) && !butPtr->indicatorOn
		&& (butPtr->selectBorder != NULL)) {
	    XSetForeground(butPtr->display, butPtr->stippleGC,
		    Tk_3DBorderColor(butPtr->normalBorder)->pixel);
	}
    }

    /*
     * Draw the border and traversal highlight last. This way, if the button's
     * contents overflow they'll be covered up by the border. This code is
     * complicated by the possible combinations of focus highlight and default
     * rings. We draw the focus and highlight rings using the highlight border
     * and highlight foreground color.
     */

    if (relief != TK_RELIEF_FLAT) {
	int inset = butPtr->highlightWidth;

	if (butPtr->defaultState == DEFAULT_ACTIVE) {
	    /*
	     * Draw the default ring with 2 pixels of space between the
	     * default ring and the button and the default ring and the focus
	     * ring. Note that we need to explicitly draw the space in the
	     * highlightBorder color to ensure that we overwrite any overflow
	     * text and/or a different button background color.
	     */

	    Tk_Draw3DRectangle(tkwin, pixmap, butPtr->highlightBorder, inset,
		    inset, Tk_Width(tkwin) - 2*inset,
		    Tk_Height(tkwin) - 2*inset, 2, TK_RELIEF_FLAT);
	    inset += 2;
	    Tk_Draw3DRectangle(tkwin, pixmap, butPtr->highlightBorder, inset,
		    inset, Tk_Width(tkwin) - 2*inset,
		    Tk_Height(tkwin) - 2*inset, 1, TK_RELIEF_SUNKEN);
	    inset++;
	    Tk_Draw3DRectangle(tkwin, pixmap, butPtr->highlightBorder, inset,
		    inset, Tk_Width(tkwin) - 2*inset,
		    Tk_Height(tkwin) - 2*inset, 2, TK_RELIEF_FLAT);

	    inset += 2;
	} else if (butPtr->defaultState == DEFAULT_NORMAL) {
	    /*
	     * Leave room for the default ring and write over any text or
	     * background color.
	     */

	    Tk_Draw3DRectangle(tkwin, pixmap, butPtr->highlightBorder, 0,
		    0, Tk_Width(tkwin), Tk_Height(tkwin), 5, TK_RELIEF_FLAT);
	    inset += 5;
	}

	/*
	 * Draw the button border.
	 */

	Tk_Draw3DRectangle(tkwin, pixmap, border, inset, inset,
		Tk_Width(tkwin) - 2*inset, Tk_Height(tkwin) - 2*inset,
		butPtr->borderWidth, relief);
    }
    if (butPtr->highlightWidth > 0) {
	GC gc;

	if (butPtr->flags & GOT_FOCUS) {
	    gc = Tk_GCForColor(butPtr->highlightColorPtr, pixmap);
	} else {
	    gc = Tk_GCForColor(Tk_3DBorderColor(butPtr->highlightBorder),
		    pixmap);
	}

	/*
	 * Make sure the focus ring shrink-wraps the actual button, not the
	 * padding space left for a default ring.
	 */

	if (butPtr->defaultState == DEFAULT_NORMAL) {
	    TkDrawInsetFocusHighlight(tkwin, gc, butPtr->highlightWidth,
		    pixmap, 5);
	} else {
	    Tk_DrawFocusHighlight(tkwin, gc, butPtr->highlightWidth, pixmap);
	}
    }

    /*
     * Copy the information from the off-screen pixmap onto the screen, then
     * delete the pixmap.
     */

    XCopyArea(butPtr->display, pixmap, Tk_WindowId(tkwin),
	    butPtr->copyGC, 0, 0, (unsigned) Tk_Width(tkwin),
	    (unsigned) Tk_Height(tkwin), 0, 0);
    Tk_FreePixmap(butPtr->display, pixmap);
}
Beispiel #14
0
void
TkpDisplayScale(
    ClientData clientData)	/* Widget record for scale. */
{
    TkScale *scalePtr = (TkScale *) clientData;
    Tk_Window tkwin = scalePtr->tkwin;
    Tcl_Interp *interp = scalePtr->interp;
    Pixmap pixmap;
    int result;
    char string[PRINT_CHARS];
    XRectangle drawnArea;
    Tcl_DString buf;

    scalePtr->flags &= ~REDRAW_PENDING;
    if ((scalePtr->tkwin == NULL) || !Tk_IsMapped(scalePtr->tkwin)) {
	goto done;
    }

    /*
     * Invoke the scale's command if needed.
     */

    Tcl_Preserve(scalePtr);
    if ((scalePtr->flags & INVOKE_COMMAND) && (scalePtr->command != NULL)) {
	Tcl_Preserve(interp);
	sprintf(string, scalePtr->format, scalePtr->value);
	Tcl_DStringInit(&buf);
	Tcl_DStringAppend(&buf, scalePtr->command, -1);
	Tcl_DStringAppend(&buf, " ", -1);
	Tcl_DStringAppend(&buf, string, -1);
	result = Tcl_EvalEx(interp, Tcl_DStringValue(&buf), -1, 0);
	Tcl_DStringFree(&buf);
	if (result != TCL_OK) {
	    Tcl_AddErrorInfo(interp, "\n    (command executed by scale)");
	    Tcl_BackgroundException(interp, result);
	}
	Tcl_Release(interp);
    }
    scalePtr->flags &= ~INVOKE_COMMAND;
    if (scalePtr->flags & SCALE_DELETED) {
	Tcl_Release(scalePtr);
	return;
    }
    Tcl_Release(scalePtr);

#ifndef TK_NO_DOUBLE_BUFFERING
    /*
     * In order to avoid screen flashes, this function redraws the scale in a
     * pixmap, then copies the pixmap to the screen in a single operation.
     * This means that there's no point in time where the on-sreen image has
     * been cleared.
     */

    pixmap = Tk_GetPixmap(scalePtr->display, Tk_WindowId(tkwin),
	    Tk_Width(tkwin), Tk_Height(tkwin), Tk_Depth(tkwin));
#else
    pixmap = Tk_WindowId(tkwin);
#endif /* TK_NO_DOUBLE_BUFFERING */
    drawnArea.x = 0;
    drawnArea.y = 0;
    drawnArea.width = Tk_Width(tkwin);
    drawnArea.height = Tk_Height(tkwin);

    /*
     * Much of the redisplay is done totally differently for horizontal and
     * vertical scales. Handle the part that's different.
     */

    if (scalePtr->orient == ORIENT_VERTICAL) {
	DisplayVerticalScale(scalePtr, pixmap, &drawnArea);
    } else {
	DisplayHorizontalScale(scalePtr, pixmap, &drawnArea);
    }

    /*
     * Now handle the part of redisplay that is the same for horizontal and
     * vertical scales: border and traversal highlight.
     */

    if (scalePtr->flags & REDRAW_OTHER) {
	if (scalePtr->relief != TK_RELIEF_FLAT) {
	    Tk_Draw3DRectangle(tkwin, pixmap, scalePtr->bgBorder,
		    scalePtr->highlightWidth, scalePtr->highlightWidth,
		    Tk_Width(tkwin) - 2*scalePtr->highlightWidth,
		    Tk_Height(tkwin) - 2*scalePtr->highlightWidth,
		    scalePtr->borderWidth, scalePtr->relief);
	}
	if (scalePtr->highlightWidth != 0) {
	    GC gc;

	    if (scalePtr->flags & GOT_FOCUS) {
		gc = Tk_GCForColor(scalePtr->highlightColorPtr, pixmap);
	    } else {
		gc = Tk_GCForColor(
                        Tk_3DBorderColor(scalePtr->highlightBorder), pixmap);
	    }
	    Tk_DrawFocusHighlight(tkwin, gc, scalePtr->highlightWidth, pixmap);
	}
    }

#ifndef TK_NO_DOUBLE_BUFFERING
    /*
     * Copy the information from the off-screen pixmap onto the screen, then
     * delete the pixmap.
     */

    XCopyArea(scalePtr->display, pixmap, Tk_WindowId(tkwin),
	    scalePtr->copyGC, drawnArea.x, drawnArea.y, drawnArea.width,
	    drawnArea.height, drawnArea.x, drawnArea.y);
    Tk_FreePixmap(scalePtr->display, pixmap);
#endif /* TK_NO_DOUBLE_BUFFERING */

  done:
    scalePtr->flags &= ~REDRAW_ALL;
}
Beispiel #15
0
void
TkpDrawCheckIndicator(
    Tk_Window tkwin,		/* handle for resource alloc */
    Display *display,
    Drawable d,			/* what to draw on */
    int x, int y,		/* where to draw */
    Tk_3DBorder bgBorder,	/* colors of the border */
    XColor *indicatorColor,	/* color of the indicator */
    XColor *selectColor,	/* color when selected */
    XColor *disableColor,	/* color when disabled */
    int on,			/* are we on? */
    int disabled,		/* are we disabled? */
    int mode)			/* kind of indicator to draw */
{
    int ix, iy;
    int dim;
    int imgsel, imgstart;
    TkBorder *bg_brdr = (TkBorder*)bgBorder;
    XGCValues gcValues;
    GC copyGC;
    unsigned long imgColors[8];
    XImage *img;
    Pixmap pixmap;
    int depth;

    /*
     * Sanity check.
     */

    if (tkwin == NULL || display == None || d == None || bgBorder == NULL
	    || indicatorColor == NULL) {
	return;
    }

    if (disableColor == NULL) {
	disableColor = bg_brdr->bgColorPtr;
    }

    if (selectColor == NULL) {
	selectColor = bg_brdr->bgColorPtr;
    }

    depth = Tk_Depth(tkwin);

    /*
     * Compute starting point and dimensions of image inside button_images to
     * be used.
     */

    switch (mode) {
    default:
    case CHECK_BUTTON:
	imgsel = on == 2 ? CHECK_DISON_OFFSET :
		on == 1 ? CHECK_ON_OFFSET : CHECK_OFF_OFFSET;
	imgsel += disabled && on != 2 ? CHECK_DISOFF_OFFSET : 0;
	imgstart = CHECK_START;
	dim = CHECK_BUTTON_DIM;
	break;

    case CHECK_MENU:
	imgsel = on == 2 ? CHECK_DISOFF_OFFSET :
		on == 1 ? CHECK_ON_OFFSET : CHECK_OFF_OFFSET;
	imgsel += disabled && on != 2 ? CHECK_DISOFF_OFFSET : 0;
	imgstart = CHECK_START + 2;
	imgsel += 2;
	dim = CHECK_MENU_DIM;
	break;

    case RADIO_BUTTON:
	imgsel = on == 2 ? RADIO_DISON_OFFSET :
		on==1 ? RADIO_ON_OFFSET : RADIO_OFF_OFFSET;
	imgsel += disabled && on != 2 ? RADIO_DISOFF_OFFSET : 0;
	imgstart = RADIO_START;
	dim = RADIO_BUTTON_DIM;
	break;

    case RADIO_MENU:
	imgsel = on == 2 ? RADIO_DISOFF_OFFSET :
		on==1 ? RADIO_ON_OFFSET : RADIO_OFF_OFFSET;
	imgsel += disabled && on != 2 ? RADIO_DISOFF_OFFSET : 0;
	imgstart = RADIO_START + 3;
	imgsel += 3;
	dim = RADIO_MENU_DIM;
	break;
    }

    /*
     * Allocate the drawing areas to use. Note that we use double-buffering
     * here because not all code paths leading to this function do so.
     */

    pixmap = Tk_GetPixmap(display, d, dim, dim, depth);
    if (pixmap == None) {
	return;
    }

    x -= dim/2;
    y -= dim/2;

    img = XGetImage(display, pixmap, 0, 0,
	    (unsigned int)dim, (unsigned int)dim, AllPlanes, ZPixmap);
    if (img == NULL) {
	return;
    }

    /*
     * Set up the color mapping table.
     */

    TkpGetShadows(bg_brdr, tkwin);

    imgColors[0 /*A*/] =
	    Tk_GetColorByValue(tkwin, bg_brdr->bgColorPtr)->pixel;
    imgColors[1 /*B*/] =
	    Tk_GetColorByValue(tkwin, bg_brdr->bgColorPtr)->pixel;
    imgColors[2 /*C*/] = (bg_brdr->lightColorPtr != NULL) ?
	    Tk_GetColorByValue(tkwin, bg_brdr->lightColorPtr)->pixel :
	    WhitePixelOfScreen(bg_brdr->screen);
    imgColors[3 /*D*/] =
	    Tk_GetColorByValue(tkwin, selectColor)->pixel;
    imgColors[4 /*E*/] = (bg_brdr->darkColorPtr != NULL) ?
	    Tk_GetColorByValue(tkwin, bg_brdr->darkColorPtr)->pixel :
	    BlackPixelOfScreen(bg_brdr->screen);
    imgColors[5 /*F*/] =
	    Tk_GetColorByValue(tkwin, bg_brdr->bgColorPtr)->pixel;
    imgColors[6 /*G*/] =
	    Tk_GetColorByValue(tkwin, indicatorColor)->pixel;
    imgColors[7 /*H*/] =
	    Tk_GetColorByValue(tkwin, disableColor)->pixel;

    /*
     * Create the image, painting it into an XImage one pixel at a time.
     */

    for (iy=0 ; iy<dim ; iy++) {
	for (ix=0 ; ix<dim ; ix++) {
	    XPutPixel(img, ix, iy,
		    imgColors[button_images[imgstart+iy][imgsel+ix] - 'A'] );
	}
    }

    /*
     * Copy onto our target drawable surface.
     */

    memset(&gcValues, 0, sizeof(gcValues));
    gcValues.background = bg_brdr->bgColorPtr->pixel;
    gcValues.graphics_exposures = False;
    copyGC = Tk_GetGC(tkwin, 0, &gcValues);

    XPutImage(display, pixmap, copyGC, img, 0, 0, 0, 0,
	    (unsigned int)dim, (unsigned int)dim);
    XCopyArea(display, pixmap, d, copyGC, 0, 0,
	    (unsigned int)dim, (unsigned int)dim, x, y);

    /*
     * Tidy up.
     */

    Tk_FreeGC(display, copyGC);
    XDestroyImage(img);
    Tk_FreePixmap(display, pixmap);
}
Beispiel #16
0
int
Tk_ConfigureInfo(
    Tcl_Interp *interp,		/* Interpreter for error reporting. */
    Tk_Window tkwin,		/* Window corresponding to widgRec. */
    Tk_ConfigSpec *specs,	/* Describes legal options. */
    char *widgRec,		/* Record whose fields contain current values
				 * for options. */
    CONST char *argvName,	/* If non-NULL, indicates a single option
				 * whose info is to be returned. Otherwise
				 * info is returned for all options. */
    int flags)			/* Used to specify additional flags that must
				 * be present in config specs for them to be
				 * considered. */
{
    register Tk_ConfigSpec *specPtr;
    int needFlags, hateFlags;
    char *list;
    char *leader = "{";

    needFlags = flags & ~(TK_CONFIG_USER_BIT - 1);
    if (Tk_Depth(tkwin) <= 1) {
        hateFlags = TK_CONFIG_COLOR_ONLY;
    } else {
        hateFlags = TK_CONFIG_MONO_ONLY;
    }

    /*
     * Get the build of the config for this interpreter.
     */

    specs = GetCachedSpecs(interp, specs);

    /*
     * If information is only wanted for a single configuration spec, then
     * handle that one spec specially.
     */

    Tcl_SetResult(interp, NULL, TCL_STATIC);
    if (argvName != NULL) {
        specPtr = FindConfigSpec(interp, specs, argvName, needFlags,hateFlags);
        if (specPtr == NULL) {
            return TCL_ERROR;
        }
        Tcl_SetResult(interp,
                      FormatConfigInfo(interp, tkwin, specPtr, widgRec),
                      TCL_DYNAMIC);
        return TCL_OK;
    }

    /*
     * Loop through all the specs, creating a big list with all their
     * information.
     */

    for (specPtr = specs; specPtr->type != TK_CONFIG_END; specPtr++) {
        if ((argvName != NULL) && (specPtr->argvName != argvName)) {
            continue;
        }
        if (((specPtr->specFlags & needFlags) != needFlags)
                || (specPtr->specFlags & hateFlags)) {
            continue;
        }
        if (specPtr->argvName == NULL) {
            continue;
        }
        list = FormatConfigInfo(interp, tkwin, specPtr, widgRec);
        Tcl_AppendResult(interp, leader, list, "}", NULL);
        ckfree(list);
        leader = " {";
    }
    return TCL_OK;
}
Beispiel #17
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;
}
Beispiel #18
0
Datei: tk3d.c Projekt: 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;
}
Beispiel #19
0
int
Tk_ConfigureWidget(
    Tcl_Interp *interp,		/* Interpreter for error reporting. */
    Tk_Window tkwin,		/* Window containing widget (needed to set up
				 * X resources). */
    Tk_ConfigSpec *specs,	/* Describes legal options. */
    int argc,			/* Number of elements in argv. */
    CONST char **argv,		/* Command-line options. */
    char *widgRec,		/* Record whose fields are to be modified.
				 * Values must be properly initialized. */
    int flags)			/* Used to specify additional flags that must
				 * be present in config specs for them to be
				 * considered. Also, may have
				 * TK_CONFIG_ARGV_ONLY set. */
{
    register Tk_ConfigSpec *specPtr;
    Tk_Uid value;		/* Value of option from database. */
    int needFlags;		/* Specs must contain this set of flags or
				 * else they are not considered. */
    int hateFlags;		/* If a spec contains any bits here, it's not
				 * considered. */

    if (tkwin == NULL) {
        /*
         * Either we're not really in Tk, or the main window was destroyed and
         * we're on our way out of the application
         */

        Tcl_AppendResult(interp, "NULL main window", NULL);
        return TCL_ERROR;
    }

    needFlags = flags & ~(TK_CONFIG_USER_BIT - 1);
    if (Tk_Depth(tkwin) <= 1) {
        hateFlags = TK_CONFIG_COLOR_ONLY;
    } else {
        hateFlags = TK_CONFIG_MONO_ONLY;
    }

    /*
     * Get the build of the config for this interpreter.
     */

    specs = GetCachedSpecs(interp, specs);

    /*
     * Pass one: scan through all of the arguments, processing those that
     * match entries in the specs.
     */

    for ( ; argc > 0; argc -= 2, argv += 2) {
        CONST char *arg;

        if (flags & TK_CONFIG_OBJS) {
            arg = Tcl_GetStringFromObj((Tcl_Obj *) *argv, NULL);
        } else {
            arg = *argv;
        }
        specPtr = FindConfigSpec(interp, specs, arg, needFlags, hateFlags);
        if (specPtr == NULL) {
            return TCL_ERROR;
        }

        /*
         * Process the entry.
         */

        if (argc < 2) {
            Tcl_AppendResult(interp, "value for \"", arg, "\" missing", NULL);
            return TCL_ERROR;
        }
        if (flags & TK_CONFIG_OBJS) {
            arg = Tcl_GetString((Tcl_Obj *) argv[1]);
        } else {
            arg = argv[1];
        }
        if (DoConfig(interp, tkwin, specPtr, arg, 0, widgRec) != TCL_OK) {
            char msg[100];

            sprintf(msg, "\n    (processing \"%.40s\" option)",
                    specPtr->argvName);
            Tcl_AddErrorInfo(interp, msg);
            return TCL_ERROR;
        }
        if (!(flags & TK_CONFIG_ARGV_ONLY)) {
            specPtr->specFlags |= TK_CONFIG_OPTION_SPECIFIED;
        }
    }

    /*
     * Pass two: scan through all of the specs again; if no command-line
     * argument matched a spec, then check for info in the option database.
     * If there was nothing in the database, then use the default.
     */

    if (!(flags & TK_CONFIG_ARGV_ONLY)) {
        for (specPtr=specs; specPtr->type!=TK_CONFIG_END; specPtr++) {
            if ((specPtr->specFlags & TK_CONFIG_OPTION_SPECIFIED)
                    || (specPtr->argvName == NULL)
                    || (specPtr->type == TK_CONFIG_SYNONYM)) {
                specPtr->specFlags &= ~TK_CONFIG_OPTION_SPECIFIED;
                continue;
            }
            if (((specPtr->specFlags & needFlags) != needFlags)
                    || (specPtr->specFlags & hateFlags)) {
                continue;
            }
            value = NULL;
            if (specPtr->dbName != NULL) {
                value = Tk_GetOption(tkwin, specPtr->dbName, specPtr->dbClass);
            }
            if (value != NULL) {
                if (DoConfig(interp, tkwin, specPtr, value, 1, widgRec) !=
                        TCL_OK) {
                    char msg[200];

                    sprintf(msg, "\n    (%s \"%.50s\" in widget \"%.50s\")",
                            "database entry for",
                            specPtr->dbName, Tk_PathName(tkwin));
                    Tcl_AddErrorInfo(interp, msg);
                    return TCL_ERROR;
                }
            } else {
                if (specPtr->defValue != NULL) {
                    value = Tk_GetUid(specPtr->defValue);
                } else {
                    value = NULL;
                }
                if ((value != NULL) && !(specPtr->specFlags
                                         & TK_CONFIG_DONT_SET_DEFAULT)) {
                    if (DoConfig(interp, tkwin, specPtr, value, 1, widgRec) !=
                            TCL_OK) {
                        char msg[200];

                        sprintf(msg,
                                "\n    (%s \"%.50s\" in widget \"%.50s\")",
                                "default value for",
                                specPtr->dbName, Tk_PathName(tkwin));
                        Tcl_AddErrorInfo(interp, msg);
                        return TCL_ERROR;
                    }
                }
            }
        }
    }

    return TCL_OK;
}
Beispiel #20
0
static PyObject * try_shm_image(TkWinObject * self)
{
    XImage *ximage = NULL;
    XShmSegmentInfo * shminfo = NULL;

    /* create shminfo */
    shminfo = PyMem_Malloc(sizeof(XShmSegmentInfo));
    if (shminfo == NULL)
	return PyErr_NoMemory();
    shminfo->shmid = -1;
    shminfo->shmaddr = (char*) -1;

    ximage = XShmCreateImage(Tk_Display(self->tkwin),
			     Tk_Visual(self->tkwin),
			     Tk_Depth(self->tkwin), ZPixmap, NULL,
			     shminfo, 1, 1);
    if (ximage == NULL)
    {
	PyErr_SetString(PyExc_RuntimeError, "XShmCreateImage failed");
	goto error;
    }

    /* allocate the shm segment */
    shminfo->shmid = shmget(IPC_PRIVATE,
			    ximage->bytes_per_line * ximage->height,
			    IPC_CREAT | 0777);
    if (shminfo->shmid == -1)
    {
	PyErr_SetFromErrno(PyExc_RuntimeError);
	goto error;
    }

    shminfo->shmaddr = ximage->data = shmat(shminfo->shmid, 0, 0);
    if (shminfo->shmaddr == (char*) -1)
    {
	PyErr_SetFromErrno(PyExc_RuntimeError);
	goto error;
    }

    shminfo->readOnly = True;

    XShmAttach(Tk_Display(self->tkwin), shminfo);
    XSync(Tk_Display(self->tkwin), False);

    if (shmerror)
    {
	XDestroyImage(ximage);
	shmdt(shminfo->shmaddr);
	shmctl(shminfo->shmid, IPC_RMID, 0);
	PyMem_Free(shminfo);
	Py_INCREF(Py_None);
	return Py_None;
    }

    return PaxImage_FromShmImage(ximage, shminfo, Tk_Display(self->tkwin));

 error:
    if (ximage)
	XDestroyImage(ximage);
    if (shminfo)
    {
	if (shminfo->shmaddr != (char*) -1)
	    shmdt(shminfo->shmaddr);
	if (shminfo->shmid != -1)
	    shmctl(shminfo->shmid, IPC_RMID, 0);
	PyMem_Free(shminfo);
    }
    return NULL;
}
Beispiel #21
0
GC
Tk_GetGC(
    Tk_Window tkwin,		/* Window in which GC will be used. */
    register unsigned long valueMask,
				/* 1 bits correspond to values specified in
				 * *valuesPtr; other values are set from
				 * defaults. */
    register XGCValues *valuePtr)
				/* Values are specified here for bits set in
				 * valueMask. */
{
    ValueKey valueKey;
    Tcl_HashEntry *valueHashPtr, *idHashPtr;
    register TkGC *gcPtr;
    int isNew;
    Drawable d, freeDrawable;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;

    if (dispPtr->gcInit <= 0) {
	GCInit(dispPtr);
    }

    /*
     * Must zero valueKey at start to clear out pad bytes that may be part of
     * structure on some systems.
     */

    memset(&valueKey, 0, sizeof(valueKey));

    /*
     * First, check to see if there's already a GC that will work for this
     * request (exact matches only, sorry).
     */

    if (valueMask & GCFunction) {
	valueKey.values.function = valuePtr->function;
    } else {
	valueKey.values.function = GXcopy;
    }
    if (valueMask & GCPlaneMask) {
	valueKey.values.plane_mask = valuePtr->plane_mask;
    } else {
	valueKey.values.plane_mask = (unsigned) ~0;
    }
    if (valueMask & GCForeground) {
	valueKey.values.foreground = valuePtr->foreground;
    } else {
	valueKey.values.foreground = 0;
    }
    if (valueMask & GCBackground) {
	valueKey.values.background = valuePtr->background;
    } else {
	valueKey.values.background = 1;
    }
    if (valueMask & GCLineWidth) {
	valueKey.values.line_width = valuePtr->line_width;
    } else {
	valueKey.values.line_width = 0;
    }
    if (valueMask & GCLineStyle) {
	valueKey.values.line_style = valuePtr->line_style;
    } else {
	valueKey.values.line_style = LineSolid;
    }
    if (valueMask & GCCapStyle) {
	valueKey.values.cap_style = valuePtr->cap_style;
    } else {
	valueKey.values.cap_style = CapButt;
    }
    if (valueMask & GCJoinStyle) {
	valueKey.values.join_style = valuePtr->join_style;
    } else {
	valueKey.values.join_style = JoinMiter;
    }
    if (valueMask & GCFillStyle) {
	valueKey.values.fill_style = valuePtr->fill_style;
    } else {
	valueKey.values.fill_style = FillSolid;
    }
    if (valueMask & GCFillRule) {
	valueKey.values.fill_rule = valuePtr->fill_rule;
    } else {
	valueKey.values.fill_rule = EvenOddRule;
    }
    if (valueMask & GCArcMode) {
	valueKey.values.arc_mode = valuePtr->arc_mode;
    } else {
	valueKey.values.arc_mode = ArcPieSlice;
    }
    if (valueMask & GCTile) {
	valueKey.values.tile = valuePtr->tile;
    } else {
	valueKey.values.tile = None;
    }
    if (valueMask & GCStipple) {
	valueKey.values.stipple = valuePtr->stipple;
    } else {
	valueKey.values.stipple = None;
    }
    if (valueMask & GCTileStipXOrigin) {
	valueKey.values.ts_x_origin = valuePtr->ts_x_origin;
    } else {
	valueKey.values.ts_x_origin = 0;
    }
    if (valueMask & GCTileStipYOrigin) {
	valueKey.values.ts_y_origin = valuePtr->ts_y_origin;
    } else {
	valueKey.values.ts_y_origin = 0;
    }
    if (valueMask & GCFont) {
	valueKey.values.font = valuePtr->font;
    } else {
	valueKey.values.font = None;
    }
    if (valueMask & GCSubwindowMode) {
	valueKey.values.subwindow_mode = valuePtr->subwindow_mode;
    } else {
	valueKey.values.subwindow_mode = ClipByChildren;
    }
    if (valueMask & GCGraphicsExposures) {
	valueKey.values.graphics_exposures = valuePtr->graphics_exposures;
    } else {
	valueKey.values.graphics_exposures = True;
    }
    if (valueMask & GCClipXOrigin) {
	valueKey.values.clip_x_origin = valuePtr->clip_x_origin;
    } else {
	valueKey.values.clip_x_origin = 0;
    }
    if (valueMask & GCClipYOrigin) {
	valueKey.values.clip_y_origin = valuePtr->clip_y_origin;
    } else {
	valueKey.values.clip_y_origin = 0;
    }
    if (valueMask & GCClipMask) {
	valueKey.values.clip_mask = valuePtr->clip_mask;
    } else {
	valueKey.values.clip_mask = None;
    }
    if (valueMask & GCDashOffset) {
	valueKey.values.dash_offset = valuePtr->dash_offset;
    } else {
	valueKey.values.dash_offset = 0;
    }
    if (valueMask & GCDashList) {
	valueKey.values.dashes = valuePtr->dashes;
    } else {
	valueKey.values.dashes = 4;
    }
    valueKey.display = Tk_Display(tkwin);
    valueKey.screenNum = Tk_ScreenNumber(tkwin);
    valueKey.depth = Tk_Depth(tkwin);
    valueHashPtr = Tcl_CreateHashEntry(&dispPtr->gcValueTable,
	    (char *) &valueKey, &isNew);
    if (!isNew) {
	gcPtr = Tcl_GetHashValue(valueHashPtr);
	gcPtr->refCount++;
	return gcPtr->gc;
    }

    /*
     * No GC is currently available for this set of values. Allocate a new GC
     * and add a new structure to the database.
     */

    gcPtr = ckalloc(sizeof(TkGC));

    /*
     * Find or make a drawable to use to specify the screen and depth of the
     * GC. We may have to make a small pixmap, to avoid doing
     * Tk_MakeWindowExist on the window.
     */

    freeDrawable = None;
    if (Tk_WindowId(tkwin) != None) {
	d = Tk_WindowId(tkwin);
    } else if (valueKey.depth ==
	    DefaultDepth(valueKey.display, valueKey.screenNum)) {
	d = RootWindow(valueKey.display, valueKey.screenNum);
    } else {
	d = Tk_GetPixmap(valueKey.display,
		RootWindow(valueKey.display, valueKey.screenNum),
		1, 1, valueKey.depth);
	freeDrawable = d;
    }

    gcPtr->gc = XCreateGC(valueKey.display, d, valueMask, &valueKey.values);
    gcPtr->display = valueKey.display;
    gcPtr->refCount = 1;
    gcPtr->valueHashPtr = valueHashPtr;
    idHashPtr = Tcl_CreateHashEntry(&dispPtr->gcIdTable,
	    (char *) gcPtr->gc, &isNew);
    if (!isNew) {
	Tcl_Panic("GC already registered in Tk_GetGC");
    }
    Tcl_SetHashValue(valueHashPtr, gcPtr);
    Tcl_SetHashValue(idHashPtr, gcPtr);
    if (freeDrawable != None) {
	Tk_FreePixmap(valueKey.display, freeDrawable);
    }

    return gcPtr->gc;
}
Beispiel #22
0
void
TkpDisplayMenuButton(
    ClientData clientData)	/* Information about widget. */
{
    register TkMenuButton *mbPtr = (TkMenuButton *) clientData;
    GC gc;
    Tk_3DBorder border;
    Pixmap pixmap;
    int x = 0;			/* Initialization needed only to stop compiler
				 * warning. */
    int y = 0;
    register Tk_Window tkwin = mbPtr->tkwin;
    int fullWidth, fullHeight;
    int textXOffset, textYOffset;
    int imageWidth, imageHeight;
    int imageXOffset, imageYOffset;
    int width = 0, height = 0;
				/* Image information that will be used to
				 * restrict disabled pixmap as well */
    int haveImage = 0, haveText = 0;

    mbPtr->flags &= ~REDRAW_PENDING;
    if ((mbPtr->tkwin == NULL) || !Tk_IsMapped(tkwin)) {
	return;
    }

    if ((mbPtr->state == STATE_DISABLED) && (mbPtr->disabledFg != NULL)) {
	gc = mbPtr->disabledGC;
	border = mbPtr->normalBorder;
    } else if ((mbPtr->state == STATE_ACTIVE)
	       && !Tk_StrictMotif(mbPtr->tkwin)) {
	gc = mbPtr->activeTextGC;
	border = mbPtr->activeBorder;
    } else {
	gc = mbPtr->normalTextGC;
	border = mbPtr->normalBorder;
    }

    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;
    }
    imageWidth	= width;
    imageHeight = height;

    haveText = (mbPtr->textWidth != 0 && mbPtr->textHeight != 0);

    /*
     * In order to avoid screen flashes, this function redraws the menu button
     * in a pixmap, then copies the pixmap to the screen in a single
     * operation. This means that there's no point in time where the on-sreen
     * image has been cleared.
     */

    pixmap = Tk_GetPixmap(mbPtr->display, Tk_WindowId(tkwin),
	    Tk_Width(tkwin), Tk_Height(tkwin), Tk_Depth(tkwin));
    Tk_Fill3DRectangle(tkwin, pixmap, border, 0, 0, Tk_Width(tkwin),
	    Tk_Height(tkwin), 0, TK_RELIEF_FLAT);

    imageXOffset = 0;
    imageYOffset = 0;
    textXOffset = 0;
    textYOffset = 0;
    fullWidth = 0;
    fullHeight = 0;

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

	    if (mbPtr->compound == COMPOUND_TOP) {
		textYOffset = height + mbPtr->padY;
	    } else {
		imageYOffset = mbPtr->textHeight + mbPtr->padY;
	    }
	    fullHeight = height + mbPtr->textHeight + mbPtr->padY;
	    fullWidth = (width > mbPtr->textWidth ? width : mbPtr->textWidth);
	    textXOffset = (fullWidth - mbPtr->textWidth)/2;
	    imageXOffset = (fullWidth - width)/2;
	    break;
	case COMPOUND_LEFT:
	case COMPOUND_RIGHT:
	    /*
	     * Image is left or right of text.
	     */

	    if (mbPtr->compound == COMPOUND_LEFT) {
		textXOffset = width + mbPtr->padX;
	    } else {
		imageXOffset = mbPtr->textWidth + mbPtr->padX;
	    }
	    fullWidth = mbPtr->textWidth + mbPtr->padX + width;
	    fullHeight = (height > mbPtr->textHeight ? height :
		    mbPtr->textHeight);
	    textYOffset = (fullHeight - mbPtr->textHeight)/2;
	    imageYOffset = (fullHeight - height)/2;
	    break;
	case COMPOUND_CENTER:
	    /*
	     * Image and text are superimposed.
	     */

	    fullWidth = (width > mbPtr->textWidth ? width : mbPtr->textWidth);
	    fullHeight = (height > mbPtr->textHeight ? height :
		    mbPtr->textHeight);
	    textXOffset = (fullWidth - mbPtr->textWidth)/2;
	    imageXOffset = (fullWidth - width)/2;
	    textYOffset = (fullHeight - mbPtr->textHeight)/2;
	    imageYOffset = (fullHeight - height)/2;
	    break;
	case COMPOUND_NONE:
	    break;
	}

	TkComputeAnchor(mbPtr->anchor, tkwin, 0, 0,
		mbPtr->indicatorWidth + fullWidth, fullHeight, &x, &y);

	imageXOffset += x;
	imageYOffset += y;
	if (mbPtr->image != NULL) {
	    Tk_RedrawImage(mbPtr->image, 0, 0, width, height, pixmap,
		    imageXOffset, imageYOffset);
	} else if (mbPtr->bitmap != None) {
	    XSetClipOrigin(mbPtr->display, gc, imageXOffset, imageYOffset);
	    XCopyPlane(mbPtr->display, mbPtr->bitmap, pixmap,
		    gc, 0, 0, (unsigned) width, (unsigned) height,
		    imageXOffset, imageYOffset, 1);
	    XSetClipOrigin(mbPtr->display, gc, 0, 0);
	}

	Tk_DrawTextLayout(mbPtr->display, pixmap, gc, mbPtr->textLayout,
		x + textXOffset, y + textYOffset, 0, -1);
	Tk_UnderlineTextLayout(mbPtr->display, pixmap, gc, mbPtr->textLayout,
		x + textXOffset, y + textYOffset, mbPtr->underline);
    } else if (haveImage) {
	TkComputeAnchor(mbPtr->anchor, tkwin, 0, 0,
		width + mbPtr->indicatorWidth, height, &x, &y);
	imageXOffset += x;
	imageYOffset += y;
	if (mbPtr->image != NULL) {
	    Tk_RedrawImage(mbPtr->image, 0, 0, width, height, pixmap,
		    imageXOffset, imageYOffset);
	} else if (mbPtr->bitmap != None) {
	    XSetClipOrigin(mbPtr->display, gc, x, y);
	    XCopyPlane(mbPtr->display, mbPtr->bitmap, pixmap,
		    gc, 0, 0, (unsigned) width, (unsigned) height,
		    x, y, 1);
	    XSetClipOrigin(mbPtr->display, gc, 0, 0);
	}
    } else {
	TkComputeAnchor(mbPtr->anchor, tkwin, mbPtr->padX, mbPtr->padY,
		mbPtr->textWidth + mbPtr->indicatorWidth,
		mbPtr->textHeight, &x, &y);
	Tk_DrawTextLayout(mbPtr->display, pixmap, gc, mbPtr->textLayout,
		x + textXOffset, y + textYOffset, 0, -1);
	Tk_UnderlineTextLayout(mbPtr->display, pixmap, gc,
		mbPtr->textLayout, x + textXOffset, y + textYOffset,
		mbPtr->underline);
    }

    /*
     * If the menu button is disabled with a stipple rather than a special
     * foreground color, generate the stippled effect.
     */

    if ((mbPtr->state == STATE_DISABLED)
	    && ((mbPtr->disabledFg == NULL) || (mbPtr->image != NULL))) {
	/*
	 * Stipple the whole button if no disabledFg was specified, otherwise
	 * restrict stippling only to displayed image
	 */

	if (mbPtr->disabledFg == NULL) {
	    XFillRectangle(mbPtr->display, pixmap, mbPtr->stippleGC,
		    mbPtr->inset, mbPtr->inset,
		    (unsigned) (Tk_Width(tkwin) - 2*mbPtr->inset),
		    (unsigned) (Tk_Height(tkwin) - 2*mbPtr->inset));
	} else {
	    XFillRectangle(mbPtr->display, pixmap, mbPtr->stippleGC,
		    imageXOffset, imageYOffset,
		    (unsigned) imageWidth, (unsigned) imageHeight);
	}
    }

    /*
     * Draw the cascade indicator for the menu button on the right side of the
     * window, if desired.
     */

    if (mbPtr->indicatorOn) {
	int borderWidth;

	borderWidth = (mbPtr->indicatorHeight+1)/3;
	if (borderWidth < 1) {
	    borderWidth = 1;
	}
	/*y += mbPtr->textHeight / 2;*/
	Tk_Fill3DRectangle(tkwin, pixmap, border,
		Tk_Width(tkwin) - mbPtr->inset - mbPtr->indicatorWidth
		+ mbPtr->indicatorHeight,
		((int) (Tk_Height(tkwin) - mbPtr->indicatorHeight))/2,
		mbPtr->indicatorWidth - 2*mbPtr->indicatorHeight,
		mbPtr->indicatorHeight, borderWidth, TK_RELIEF_RAISED);
    }

    /*
     * Draw the border and traversal highlight last. This way, if the menu
     * button's contents overflow onto the border they'll be covered up by the
     * border.
     */

    if (mbPtr->relief != TK_RELIEF_FLAT) {
	Tk_Draw3DRectangle(tkwin, pixmap, border,
		mbPtr->highlightWidth, mbPtr->highlightWidth,
		Tk_Width(tkwin) - 2*mbPtr->highlightWidth,
		Tk_Height(tkwin) - 2*mbPtr->highlightWidth,
		mbPtr->borderWidth, mbPtr->relief);
    }
    if (mbPtr->highlightWidth != 0) {
	GC gc;

	if (mbPtr->flags & GOT_FOCUS) {
	    gc = Tk_GCForColor(mbPtr->highlightColorPtr, pixmap);
	} else {
	    gc = Tk_GCForColor(mbPtr->highlightBgColorPtr, pixmap);
	}
	Tk_DrawFocusHighlight(tkwin, gc, mbPtr->highlightWidth, pixmap);
    }

    /*
     * Copy the information from the off-screen pixmap onto the screen, then
     * delete the pixmap.
     */

    XCopyArea(mbPtr->display, pixmap, Tk_WindowId(tkwin),
	    mbPtr->normalTextGC, 0, 0, (unsigned) Tk_Width(tkwin),
	    (unsigned) Tk_Height(tkwin), 0, 0);
    Tk_FreePixmap(mbPtr->display, pixmap);
}