Пример #1
0
Файл: tkImage.c Проект: tcltk/tk
/*ARGSUSED*/
void
Tk_SetTSOrigin(
    Tk_Window tkwin,
    GC gc,
    int x, int y)
{
    while (!Tk_TopWinHierarchy(tkwin)) {
	x -= Tk_X(tkwin) + Tk_Changes(tkwin)->border_width;
	y -= Tk_Y(tkwin) + Tk_Changes(tkwin)->border_width;
	tkwin = Tk_Parent(tkwin);
    }
    XSetTSOrigin(Tk_Display(tkwin), gc, x, y);
}
Пример #2
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);
}
Пример #3
0
/*
 *---------------------------------------------------------------------------
 *
 * Blt_MakeTransparentWindowExist --
 *
 *	Similar to Tk_MakeWindowExist but instead creates a transparent window
 *	to block for user events from sibling windows.
 *
 *	Differences from Tk_MakeWindowExist.
 *
 *	1. This is always a "busy" window. There's never a platform-specific
 *	   class procedure to execute.
 *
 *	2. The window is transparent and never will have children, so
 *	   colormap information is irrelevant.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	When the procedure returns, the internal window associated with tkwin
 *	is guaranteed to exist.  This may require the window's ancestors to be
 *	created too.
 *
 *---------------------------------------------------------------------------
 */
void
Blt_MakeTransparentWindowExist(
    Tk_Window tkwin,		/* Token for window. */
    Window parent,		/* Parent window. */
    int isBusy)			/*  */
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    TkWindow *winPtr2;
    Tcl_HashEntry *hPtr;
    int notUsed;
    TkDisplay *dispPtr;
    HWND hParent;
    int style;
    DWORD exStyle;
    HWND hWnd;

    if (winPtr->window != None) {
	return;			/* Window already exists. */
    }
    /* Create a transparent window and put it on top.  */

    hParent = (HWND) parent;
    style = (WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
    exStyle = (WS_EX_TRANSPARENT | WS_EX_TOPMOST);
#define TK_WIN_CHILD_CLASS_NAME "TkChild"
    hWnd = CreateWindowEx(exStyle, TK_WIN_CHILD_CLASS_NAME, NULL, style,
	Tk_X(tkwin), Tk_Y(tkwin), Tk_Width(tkwin), Tk_Height(tkwin),
	hParent, NULL, (HINSTANCE)Tk_GetHINSTANCE(), NULL);
    winPtr->window = Tk_AttachHWND(tkwin, hWnd);

    dispPtr = winPtr->dispPtr;
    hPtr = Tcl_CreateHashEntry(&dispPtr->winTable, (char *)winPtr->window,
	&notUsed);
    Tcl_SetHashValue(hPtr, winPtr);
    winPtr->dirtyAtts = 0;
    winPtr->dirtyChanges = 0;
#ifdef TK_USE_INPUT_METHODS
    winPtr->inputContext = NULL;
#endif /* TK_USE_INPUT_METHODS */
    if (!(winPtr->flags & TK_TOP_LEVEL)) {
	/*
	 * If any siblings higher up in the stacking order have already been
	 * created then move this window to its rightful position in the
	 * stacking order.
	 *
	 * NOTE: this code ignores any changes anyone might have made to the
	 * sibling and stack_mode field of the window's attributes, so it
	 * really isn't safe for these to be manipulated except by calling
	 * Tk_RestackWindow.
	 */
	for (winPtr2 = winPtr->nextPtr; winPtr2 != NULL;
	    winPtr2 = winPtr2->nextPtr) {
	    if ((winPtr2->window != None) && !(winPtr2->flags & TK_TOP_LEVEL)) {
		XWindowChanges changes;
		changes.sibling = winPtr2->window;
		changes.stack_mode = Below;
		XConfigureWindow(winPtr->display, winPtr->window,
		    CWSibling | CWStackMode, &changes);
		break;
	    }
	}
    }
    /*
     * Issue a ConfigureNotify event if there were deferred configuration
     * changes (but skip it if the window is being deleted; the
     * ConfigureNotify event could cause problems if we're being called from
     * Tk_DestroyWindow under some conditions).
     */
    if ((winPtr->flags & TK_NEED_CONFIG_NOTIFY)
	&& !(winPtr->flags & TK_ALREADY_DEAD)) {
	winPtr->flags &= ~TK_NEED_CONFIG_NOTIFY;
	DoConfigureNotify((Tk_FakeWin *)tkwin);
    }
}
Пример #4
0
static void
RecomputePlacement(
    ClientData clientData)	/* Pointer to Master record. */
{
    register Master *masterPtr = clientData;
    register Slave *slavePtr;
    int x, y, width, height, tmp;
    int masterWidth, masterHeight, masterX, masterY;
    double x1, y1, x2, y2;
    int abort;			/* May get set to non-zero to abort this
				 * placement operation. */

    masterPtr->flags &= ~PARENT_RECONFIG_PENDING;

    /*
     * Abort any nested call to RecomputePlacement for this window, since
     * we'll do everything necessary here, and set up so this call can be
     * aborted if necessary.
     */

    if (masterPtr->abortPtr != NULL) {
	*masterPtr->abortPtr = 1;
    }
    masterPtr->abortPtr = &abort;
    abort = 0;
    Tcl_Preserve(masterPtr);

    /*
     * Iterate over all the slaves for the master. Each slave's geometry can
     * be computed independently of the other slaves. Changes to the window's
     * structure could cause almost anything to happen, including deleting the
     * parent or child. If this happens, we'll be told to abort.
     */

    for (slavePtr = masterPtr->slavePtr; slavePtr != NULL && !abort;
	    slavePtr = slavePtr->nextPtr) {
	/*
	 * Step 1: compute size and borderwidth of master, taking into account
	 * desired border mode.
	 */

	masterX = masterY = 0;
	masterWidth = Tk_Width(masterPtr->tkwin);
	masterHeight = Tk_Height(masterPtr->tkwin);
	if (slavePtr->borderMode == BM_INSIDE) {
	    masterX = Tk_InternalBorderLeft(masterPtr->tkwin);
	    masterY = Tk_InternalBorderTop(masterPtr->tkwin);
	    masterWidth -= masterX + Tk_InternalBorderRight(masterPtr->tkwin);
	    masterHeight -= masterY +
		    Tk_InternalBorderBottom(masterPtr->tkwin);
	} else if (slavePtr->borderMode == BM_OUTSIDE) {
	    masterX = masterY = -Tk_Changes(masterPtr->tkwin)->border_width;
	    masterWidth -= 2 * masterX;
	    masterHeight -= 2 * masterY;
	}

	/*
	 * Step 2: compute size of slave (outside dimensions including border)
	 * and location of anchor point within master.
	 */

	x1 = slavePtr->x + masterX + (slavePtr->relX*masterWidth);
	x = (int) (x1 + ((x1 > 0) ? 0.5 : -0.5));
	y1 = slavePtr->y + masterY + (slavePtr->relY*masterHeight);
	y = (int) (y1 + ((y1 > 0) ? 0.5 : -0.5));
	if (slavePtr->flags & (CHILD_WIDTH|CHILD_REL_WIDTH)) {
	    width = 0;
	    if (slavePtr->flags & CHILD_WIDTH) {
		width += slavePtr->width;
	    }
	    if (slavePtr->flags & CHILD_REL_WIDTH) {
		/*
		 * The code below is a bit tricky. In order to round correctly
		 * when both relX and relWidth are specified, compute the
		 * location of the right edge and round that, then compute
		 * width. If we compute the width and round it, rounding
		 * errors in relX and relWidth accumulate.
		 */

		x2 = x1 + (slavePtr->relWidth*masterWidth);
		tmp = (int) (x2 + ((x2 > 0) ? 0.5 : -0.5));
		width += tmp - x;
	    }
	} else {
	    width = Tk_ReqWidth(slavePtr->tkwin)
		    + 2*Tk_Changes(slavePtr->tkwin)->border_width;
	}
	if (slavePtr->flags & (CHILD_HEIGHT|CHILD_REL_HEIGHT)) {
	    height = 0;
	    if (slavePtr->flags & CHILD_HEIGHT) {
		height += slavePtr->height;
	    }
	    if (slavePtr->flags & CHILD_REL_HEIGHT) {
		/*
		 * See note above for rounding errors in width computation.
		 */

		y2 = y1 + (slavePtr->relHeight*masterHeight);
		tmp = (int) (y2 + ((y2 > 0) ? 0.5 : -0.5));
		height += tmp - y;
	    }
	} else {
	    height = Tk_ReqHeight(slavePtr->tkwin)
		    + 2*Tk_Changes(slavePtr->tkwin)->border_width;
	}

	/*
	 * Step 3: adjust the x and y positions so that the desired anchor
	 * point on the slave appears at that position. Also adjust for the
	 * border mode and master's border.
	 */

	switch (slavePtr->anchor) {
	case TK_ANCHOR_N:
	    x -= width/2;
	    break;
	case TK_ANCHOR_NE:
	    x -= width;
	    break;
	case TK_ANCHOR_E:
	    x -= width;
	    y -= height/2;
	    break;
	case TK_ANCHOR_SE:
	    x -= width;
	    y -= height;
	    break;
	case TK_ANCHOR_S:
	    x -= width/2;
	    y -= height;
	    break;
	case TK_ANCHOR_SW:
	    y -= height;
	    break;
	case TK_ANCHOR_W:
	    y -= height/2;
	    break;
	case TK_ANCHOR_NW:
	    break;
	case TK_ANCHOR_CENTER:
	    x -= width/2;
	    y -= height/2;
	    break;
	}

	/*
	 * Step 4: adjust width and height again to reflect inside dimensions
	 * of window rather than outside. Also make sure that the width and
	 * height aren't zero.
	 */

	width -= 2*Tk_Changes(slavePtr->tkwin)->border_width;
	height -= 2*Tk_Changes(slavePtr->tkwin)->border_width;
	if (width <= 0) {
	    width = 1;
	}
	if (height <= 0) {
	    height = 1;
	}

	/*
	 * Step 5: reconfigure the window and map it if needed. If the slave
	 * is a child of the master, we do this ourselves. If the slave isn't
	 * a child of the master, let Tk_MaintainGeometry do the work (it will
	 * re-adjust things as relevant windows map, unmap, and move).
	 */

	if (masterPtr->tkwin == Tk_Parent(slavePtr->tkwin)) {
	    if ((x != Tk_X(slavePtr->tkwin))
		    || (y != Tk_Y(slavePtr->tkwin))
		    || (width != Tk_Width(slavePtr->tkwin))
		    || (height != Tk_Height(slavePtr->tkwin))) {
		Tk_MoveResizeWindow(slavePtr->tkwin, x, y, width, height);
	    }
            if (abort) {
                break;
            }

	    /*
	     * Don't map the slave unless the master is mapped: the slave will
	     * get mapped later, when the master is mapped.
	     */

	    if (Tk_IsMapped(masterPtr->tkwin)) {
		Tk_MapWindow(slavePtr->tkwin);
	    }
	} else {
	    if ((width <= 0) || (height <= 0)) {
		Tk_UnmaintainGeometry(slavePtr->tkwin, masterPtr->tkwin);
		Tk_UnmapWindow(slavePtr->tkwin);
	    } else {
		Tk_MaintainGeometry(slavePtr->tkwin, masterPtr->tkwin,
			x, y, width, height);
	    }
	}
    }

    masterPtr->abortPtr = NULL;
    Tcl_Release(masterPtr);
}
Пример #5
0
void
TkTextEmbWinDisplayProc(
    TkText *textPtr,		/* Information about text widget. */
    TkTextDispChunk *chunkPtr,	/* Chunk that is to be drawn. */
    int x,			/* X-position in dst at which to draw this
				 * chunk (differs from the x-position in the
				 * chunk because of scrolling). */
    int y,			/* Top of rectangular bounding box for line:
				 * tells where to draw this chunk in dst
				 * (x-position is in the chunk itself). */
    int lineHeight,		/* Total height of line. */
    int baseline,		/* Offset of baseline from y. */
    Display *display,		/* Display to use for drawing (unused).  */
    Drawable dst,		/* Pixmap or window in which to draw
				 * (unused).  */
    int screenY)		/* Y-coordinate in text window that
				 * corresponds to y. */
{
    int lineX, windowX, windowY, width, height;
    Tk_Window tkwin;
    TkTextSegment *ewPtr = chunkPtr->clientData;
    TkTextEmbWindowClient *client = EmbWinGetClient(textPtr, ewPtr);

    if (client == NULL) {
	return;
    }

    tkwin = client->tkwin;
    if (tkwin == NULL) {
	return;
    }

    if ((x + chunkPtr->width) <= 0) {
	/*
	 * The window is off-screen; just unmap it.
	 */

	if (textPtr->tkwin != Tk_Parent(tkwin)) {
	    Tk_UnmaintainGeometry(tkwin, textPtr->tkwin);
	} else {
	    Tk_UnmapWindow(tkwin);
	}
	return;
    }

    /*
     * Compute the window's location and size in the text widget, taking into
     * account the align and stretch values for the window.
     */

    EmbWinBboxProc(textPtr, chunkPtr, 0, screenY, lineHeight, baseline,
	    &lineX, &windowY, &width, &height);
    windowX = lineX - chunkPtr->x + x;

    if (textPtr->tkwin == Tk_Parent(tkwin)) {
	if ((windowX != Tk_X(tkwin)) || (windowY != Tk_Y(tkwin))
		|| (Tk_ReqWidth(tkwin) != Tk_Width(tkwin))
		|| (height != Tk_Height(tkwin))) {
	    Tk_MoveResizeWindow(tkwin, windowX, windowY, width, height);
	}
	Tk_MapWindow(tkwin);
    } else {
	Tk_MaintainGeometry(tkwin, textPtr->tkwin, windowX, windowY,
		width, height);
    }

    /*
     * Mark the window as displayed so that it won't get unmapped.
     */

    client->displayed = 1;
}
Пример #6
0
static void
DisplayWinItem(
    Tk_Canvas canvas,		/* Canvas that contains item. */
    Tk_Item *itemPtr,		/* Item to be displayed. */
    Display *display,		/* Display on which to draw item. */
    Drawable drawable,		/* Pixmap or window in which to draw item. */
    int regionX, int regionY, int regionWidth, int regionHeight)
				/* Describes region of canvas that must be
				 * redisplayed (not used). */
{
    WindowItem *winItemPtr = (WindowItem *) itemPtr;
    int width, height;
    short x, y;
    Tk_Window canvasTkwin = Tk_CanvasTkwin(canvas);
    Tk_State state = itemPtr->state;

    if (winItemPtr->tkwin == NULL) {
	return;
    }
    if (state == TK_STATE_NULL) {
	state = Canvas(canvas)->canvas_state;
    }

    /*
     * A drawable of None is used by the canvas UnmapNotify handler
     * to indicate that we should no longer display ourselves.
     */
    if (state == TK_STATE_HIDDEN || drawable == None) {
	if (canvasTkwin == Tk_Parent(winItemPtr->tkwin)) {
	    Tk_UnmapWindow(winItemPtr->tkwin);
	} else {
	    Tk_UnmaintainGeometry(winItemPtr->tkwin, canvasTkwin);
	}
	return;
    }
    Tk_CanvasWindowCoords(canvas, (double) winItemPtr->header.x1,
	    (double) winItemPtr->header.y1, &x, &y);
    width = winItemPtr->header.x2 - winItemPtr->header.x1;
    height = winItemPtr->header.y2 - winItemPtr->header.y1;

    /*
     * If the window is completely out of the visible area of the canvas then
     * unmap it. This code used not to be present (why unmap the window if it
     * isn't visible anyway?) but this could cause the window to suddenly
     * reappear if the canvas window got resized.
     */

    if (((x + width) <= 0) || ((y + height) <= 0)
	    || (x >= Tk_Width(canvasTkwin)) || (y >= Tk_Height(canvasTkwin))) {
	if (canvasTkwin == Tk_Parent(winItemPtr->tkwin)) {
	    Tk_UnmapWindow(winItemPtr->tkwin);
	} else {
	    Tk_UnmaintainGeometry(winItemPtr->tkwin, canvasTkwin);
	}
	return;
    }

    /*
     * Reposition and map the window (but in different ways depending on
     * whether the canvas is the window's parent).
     */

    if (canvasTkwin == Tk_Parent(winItemPtr->tkwin)) {
	if ((x != Tk_X(winItemPtr->tkwin)) || (y != Tk_Y(winItemPtr->tkwin))
		|| (width != Tk_Width(winItemPtr->tkwin))
		|| (height != Tk_Height(winItemPtr->tkwin))) {
	    Tk_MoveResizeWindow(winItemPtr->tkwin, x, y, width, height);
	}
	Tk_MapWindow(winItemPtr->tkwin);
    } else {
	Tk_MaintainGeometry(winItemPtr->tkwin, canvasTkwin, x, y,
		width, height);
    }
}
Пример #7
0
void
TkGenWMConfigureEvent(
    Tk_Window tkwin,
    int x, int y,
    int width, int height,
    int flags)
{
    XEvent event;
    WmInfo *wmPtr;
    TkWindow *winPtr = (TkWindow *) tkwin;

    if (tkwin == NULL) {
	return;
    }

    event.type = ConfigureNotify;
    event.xconfigure.serial = LastKnownRequestProcessed(Tk_Display(tkwin));
    event.xconfigure.send_event = False;
    event.xconfigure.display = Tk_Display(tkwin);
    event.xconfigure.event = Tk_WindowId(tkwin);
    event.xconfigure.window = Tk_WindowId(tkwin);
    event.xconfigure.border_width = winPtr->changes.border_width;
    event.xconfigure.override_redirect = winPtr->atts.override_redirect;
    if (winPtr->changes.stack_mode == Above) {
	event.xconfigure.above = winPtr->changes.sibling;
    } else {
	event.xconfigure.above = None;
    }

    if (!(flags & TK_LOCATION_CHANGED)) {
	x = Tk_X(tkwin);
	y = Tk_Y(tkwin);
    }
    if (!(flags & TK_SIZE_CHANGED)) {
	width = Tk_Width(tkwin);
	height = Tk_Height(tkwin);
    }
    event.xconfigure.x = x;
    event.xconfigure.y = y;
    event.xconfigure.width = width;
    event.xconfigure.height = height;

    if (flags & TK_MACOSX_HANDLE_EVENT_IMMEDIATELY) {
	Tk_HandleEvent(&event);
    } else {
	Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);
    }

    /*
     * Update window manager information.
     */

    if (Tk_IsTopLevel(winPtr)) {
	wmPtr = winPtr->wmInfoPtr;
	if (flags & TK_LOCATION_CHANGED) {
	    wmPtr->x = x;
	    wmPtr->y = y;
	    wmPtr->flags &= ~(WM_NEGATIVE_X | WM_NEGATIVE_Y);
	}
	if ((flags & TK_SIZE_CHANGED) && !(wmPtr->flags & WM_SYNC_PENDING) &&
		((width != Tk_Width(tkwin)) || (height != Tk_Height(tkwin)))) {
	    if ((wmPtr->width == -1) && (width == winPtr->reqWidth)) {
		/*
		 * Don't set external width, since the user didn't change it
		 * from what the widgets asked for.
		 */
	    } else if (wmPtr->gridWin != NULL) {
		wmPtr->width = wmPtr->reqGridWidth
			+ (width - winPtr->reqWidth)/wmPtr->widthInc;
		if (wmPtr->width < 0) {
		    wmPtr->width = 0;
		}
	    } else {
		wmPtr->width = width;
	    }

	    if ((wmPtr->height == -1) && (height == winPtr->reqHeight)) {
		/*
		 * Don't set external height, since the user didn't change it
		 * from what the widgets asked for.
		 */
	    } else if (wmPtr->gridWin != NULL) {
		wmPtr->height = wmPtr->reqGridHeight
			+ (height - winPtr->reqHeight)/wmPtr->heightInc;
		if (wmPtr->height < 0) {
		    wmPtr->height = 0;
		}
	    } else {
		wmPtr->height = height;
	    }

	    wmPtr->configWidth = width;
	    wmPtr->configHeight = height;
	}
    }

    /*
     * Now set up the changes structure. Under X we wait for the
     * ConfigureNotify to set these values. On the Mac we know imediatly that
     * this is what we want - so we just set them. However, we need to make
     * sure the windows clipping region is marked invalid so the change is
     * visible to the subwindow.
     */

    winPtr->changes.x = x;
    winPtr->changes.y = y;
    winPtr->changes.width = width;
    winPtr->changes.height = height;
    TkMacOSXInvalClipRgns(tkwin);
}
Пример #8
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);
}
Пример #9
0
Файл: tkBusy.c Проект: das/tk
static Busy *
CreateBusy(
    Tcl_Interp *interp,		/* Interpreter to report error to */
    Tk_Window tkRef)		/* Window hosting the busy window */
{
    Busy *busyPtr;
    int length, x, y;
    const char *fmt;
    char *name;
    Tk_Window tkBusy, tkChild, tkParent;
    Window parent;
    Tk_FakeWin *winPtr;

    busyPtr = (Busy *) ckalloc(sizeof(Busy));
    x = y = 0;
    length = strlen(Tk_Name(tkRef));
    name = ckalloc(length + 6);
    if (Tk_IsTopLevel(tkRef)) {
        fmt = "_Busy";		/* Child */
        tkParent = tkRef;
    } else {
        Tk_Window tkwin;

        fmt = "%s_Busy";	/* Sibling */
        tkParent = Tk_Parent(tkRef);
        for (tkwin = tkRef; (tkwin != NULL) && !Tk_IsTopLevel(tkwin);
                tkwin = Tk_Parent(tkwin)) {
            if (tkwin == tkParent) {
                break;
            }
            x += Tk_X(tkwin) + Tk_Changes(tkwin)->border_width;
            y += Tk_Y(tkwin) + Tk_Changes(tkwin)->border_width;
        }
    }
    for (tkChild = FirstChild(tkParent); tkChild != NULL;
            tkChild = NextChild(tkChild)) {
        Tk_MakeWindowExist(tkChild);
    }
    sprintf(name, fmt, Tk_Name(tkRef));
    tkBusy = Tk_CreateWindow(interp, tkParent, name, NULL);
    ckfree(name);

    if (tkBusy == NULL) {
        return NULL;
    }
    Tk_MakeWindowExist(tkRef);
    busyPtr->display = Tk_Display(tkRef);
    busyPtr->interp = interp;
    busyPtr->tkRef = tkRef;
    busyPtr->tkParent = tkParent;
    busyPtr->tkBusy = tkBusy;
    busyPtr->width = Tk_Width(tkRef);
    busyPtr->height = Tk_Height(tkRef);
    busyPtr->x = Tk_X(tkRef);
    busyPtr->y = Tk_Y(tkRef);
    busyPtr->cursor = None;
    Tk_SetClass(tkBusy, "Busy");
    busyPtr->optionTable = Tk_CreateOptionTable(interp, busyOptionSpecs);
    if (Tk_InitOptions(interp, (char *) busyPtr, busyPtr->optionTable,
                       tkBusy) != TCL_OK) {
        Tk_DestroyWindow(tkBusy);
        return NULL;
    }
    SetWindowInstanceData(tkBusy, busyPtr);
    winPtr = (Tk_FakeWin *) tkRef;

    TkpCreateBusy(winPtr, tkRef, &parent, tkParent, busyPtr);

    MakeTransparentWindowExist(tkBusy, parent);

    Tk_MoveResizeWindow(tkBusy, x, y, busyPtr->width, busyPtr->height);

    /*
     * Only worry if the busy window is destroyed.
     */

    Tk_CreateEventHandler(tkBusy, StructureNotifyMask, BusyEventProc,
                          busyPtr);

    /*
     * Indicate that the busy window's geometry is being managed. This will
     * also notify us if the busy window is ever packed.
     */

    Tk_ManageGeometry(tkBusy, &busyMgrInfo, busyPtr);
    if (busyPtr->cursor != None) {
        Tk_DefineCursor(tkBusy, busyPtr->cursor);
    }

    /*
     * Track the reference window to see if it is resized or destroyed.
     */

    Tk_CreateEventHandler(tkRef, StructureNotifyMask, RefWinEventProc,
                          busyPtr);
    return busyPtr;
}
Пример #10
0
Файл: tkBusy.c Проект: das/tk
static void
RefWinEventProc(
    ClientData clientData,	/* Busy window record */
    register XEvent *eventPtr)	/* Event which triggered call to routine */
{
    register Busy *busyPtr = clientData;

    switch (eventPtr->type) {
    case ReparentNotify:
    case DestroyNotify:
        /*
         * Arrange for the busy structure to be removed at a proper time.
         */

        Tcl_EventuallyFree(busyPtr, DestroyBusy);
        break;

    case ConfigureNotify:
        if ((busyPtr->width != Tk_Width(busyPtr->tkRef)) ||
                (busyPtr->height != Tk_Height(busyPtr->tkRef)) ||
                (busyPtr->x != Tk_X(busyPtr->tkRef)) ||
                (busyPtr->y != Tk_Y(busyPtr->tkRef))) {
            int x, y;

            busyPtr->width = Tk_Width(busyPtr->tkRef);
            busyPtr->height = Tk_Height(busyPtr->tkRef);
            busyPtr->x = Tk_X(busyPtr->tkRef);
            busyPtr->y = Tk_Y(busyPtr->tkRef);

            x = y = 0;

            if (busyPtr->tkParent != busyPtr->tkRef) {
                Tk_Window tkwin;

                for (tkwin = busyPtr->tkRef; (tkwin != NULL) &&
                        (!Tk_IsTopLevel(tkwin)); tkwin = Tk_Parent(tkwin)) {
                    if (tkwin == busyPtr->tkParent) {
                        break;
                    }
                    x += Tk_X(tkwin) + Tk_Changes(tkwin)->border_width;
                    y += Tk_Y(tkwin) + Tk_Changes(tkwin)->border_width;
                }
            }
            if (busyPtr->tkBusy != NULL) {
                Tk_MoveResizeWindow(busyPtr->tkBusy, x, y, busyPtr->width,
                                    busyPtr->height);
                TkpShowBusyWindow(busyPtr);
            }
        }
        break;

    case MapNotify:
        if (busyPtr->tkParent != busyPtr->tkRef) {
            TkpShowBusyWindow(busyPtr);
        }
        break;

    case UnmapNotify:
        if (busyPtr->tkParent != busyPtr->tkRef) {
            TkpHideBusyWindow(busyPtr);
        }
        break;
    }
}