Tk

 view release on metacpan or  search on metacpan

pTk/mTk/win/tkWinWm.c  view on Meta::CPAN

     * to detect size and position changes caused by window managers.
     */

    Tk_CreateEventHandler((Tk_Window) winPtr, StructureNotifyMask,
	    TopLevelEventProc, (ClientData) winPtr);

    /*
     * Arrange for geometry requests to be reflected from the window
     * to the window manager.
     */

    Tk_ManageGeometry((Tk_Window) winPtr, &wmMgrType, (ClientData) 0);
}

/*
 *----------------------------------------------------------------------
 *
 * UpdateWrapper --
 *
 *	This function creates the wrapper window that contains the
 *	window decorations and menus for a toplevel.  This function
 *	may be called after a window is mapped to change the window
 *	style.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Destroys any old wrapper window and replaces it with a newly
 *	created wrapper.
 *
 *----------------------------------------------------------------------
 */

static void
UpdateWrapper(winPtr)
    TkWindow *winPtr;		/* Top-level window to redecorate. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    HWND parentHWND, oldWrapper;
    HWND child;
    int x, y, width, height, state;
    WINDOWPLACEMENT place;
    HICON hSmallIcon = NULL;
    HICON hBigIcon = NULL;
    Tcl_DString titleString, classString;
    int *childStateInfo = NULL;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
            Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (winPtr->window == None) {
	/*
	 * Ensure existence of the window to update the wrapper for.
	 */
	Tk_MakeWindowExist((Tk_Window) winPtr);
    }

    child = TkWinGetHWND(winPtr->window);
    parentHWND = NULL;

    if (winPtr->flags & TK_EMBEDDED) {
	wmPtr->wrapper = (HWND) winPtr->privatePtr;
	if (wmPtr->wrapper == NULL) {
	    panic("UpdateWrapper: Cannot find container window");
	}
	if (!IsWindow(wmPtr->wrapper)) {
	    panic("UpdateWrapper: Container was destroyed");
	}

    } else {
	/*
	 * Pick the decorative frame style.  Override redirect windows get
	 * created as undecorated popups.  Transient windows get a modal
	 * dialog frame.  Neither override, nor transient windows appear in
	 * the Windows taskbar.  Note that a transient window does not resize
	 * by default, so we need to explicitly add the WS_THICKFRAME style
	 * if we want it to be resizeable.
	 */

	if (winPtr->atts.override_redirect) {
	    wmPtr->style = WM_OVERRIDE_STYLE;
	    wmPtr->exStyle = EX_OVERRIDE_STYLE;
	} else if (wmPtr->masterPtr) {
	    wmPtr->style = WM_TRANSIENT_STYLE;
	    wmPtr->exStyle = EX_TRANSIENT_STYLE;
	    parentHWND = Tk_GetHWND(Tk_WindowId(wmPtr->masterPtr));
	    if (! ((wmPtr->flags & WM_WIDTH_NOT_RESIZABLE) &&
		    (wmPtr->flags & WM_HEIGHT_NOT_RESIZABLE))) {
		wmPtr->style |= WS_THICKFRAME;
	    }
	} else {
	    wmPtr->style = WM_TOPLEVEL_STYLE;
	    wmPtr->exStyle = EX_TOPLEVEL_STYLE;
	}

	wmPtr->style   |= wmPtr->styleConfig;
	wmPtr->exStyle |= wmPtr->exStyleConfig;

	if ((wmPtr->flags & WM_WIDTH_NOT_RESIZABLE)
		&& (wmPtr->flags & WM_HEIGHT_NOT_RESIZABLE)) {
	    wmPtr->style &= ~ (WS_MAXIMIZEBOX | WS_SIZEBOX);
	}

	/*
	 * Compute the geometry of the parent and child windows.
	 */

	wmPtr->flags |= WM_CREATE_PENDING|WM_MOVE_PENDING;
	UpdateGeometryInfo((ClientData)winPtr);
	wmPtr->flags &= ~(WM_CREATE_PENDING|WM_MOVE_PENDING);

	width = wmPtr->borderWidth + winPtr->changes.width;
	height = wmPtr->borderHeight + winPtr->changes.height;

	/*
	 * Set the initial position from the user or program specified
	 * location.  If nothing has been specified, then let the system
	 * pick a location.
	 */

	if (!(wmPtr->sizeHintsFlags & (USPosition | PPosition))
		&& (wmPtr->flags & WM_NEVER_MAPPED)) {
	    x = CW_USEDEFAULT;
	    y = CW_USEDEFAULT;
	} else {
	    x = winPtr->changes.x;
	    y = winPtr->changes.y;
	}

	/*
	 * Create the containing window, and set the user data to point
	 * to the TkWindow.
	 */

	tsdPtr->createWindow = winPtr;
	Tcl_WinUtfToTChar(((wmPtr->title != NULL) ?
                           wmPtr->title : winPtr->nameUid), -1, &titleString);
	Tcl_WinUtfToTChar(TK_WIN_TOPLEVEL_CLASS_NAME, -1, &classString);
	wmPtr->wrapper = (*tkWinProcs->createWindowEx)(wmPtr->exStyle,
		(LPCTSTR) Tcl_DStringValue(&classString),
		(LPCTSTR) Tcl_DStringValue(&titleString),
		wmPtr->style, x, y, width, height,
		parentHWND, NULL, Tk_GetHINSTANCE(), NULL);
	Tcl_DStringFree(&classString);
	Tcl_DStringFree(&titleString);
	if (!wmPtr->wrapper) {
	    panic("UpdateWrapper: Failed to create container");
	}
#ifdef _WIN64
	SetWindowLongPtr(wmPtr->wrapper, GWLP_USERDATA, (LONG_PTR) winPtr);
#else
	SetWindowLong(wmPtr->wrapper, GWL_USERDATA, (LONG) winPtr);
#endif
	tsdPtr->createWindow = NULL;

	place.length = sizeof(WINDOWPLACEMENT);
	GetWindowPlacement(wmPtr->wrapper, &place);
	wmPtr->x = place.rcNormalPosition.left;
	wmPtr->y = place.rcNormalPosition.top;
	TkInstallFrameMenu((Tk_Window) winPtr);
    }

    /*
     * Now we need to reparent the contained window and set its
     * style appropriately.  Be sure to update the style first so that
     * Windows doesn't try to set the focus to the child window.
     */

#ifdef _WIN64
    SetWindowLongPtr(child, GWL_STYLE,
	    WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
#else
    SetWindowLong(child, GWL_STYLE,
	    WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
#endif
    if (winPtr->flags & TK_EMBEDDED) {
#ifdef _WIN64
	SetWindowLongPtr(child, GWLP_WNDPROC, (LONG_PTR) TopLevelProc);
#else
	SetWindowLong(child, GWL_WNDPROC, (LONG) TopLevelProc);
#endif
    }
    oldWrapper = SetParent(child, wmPtr->wrapper);
    if (oldWrapper) {
	hSmallIcon = (HICON) SendMessage(oldWrapper, WM_GETICON, ICON_SMALL,
		(LPARAM) NULL);
	hBigIcon = (HICON) SendMessage(oldWrapper, WM_GETICON, ICON_BIG,
		(LPARAM) NULL);
    }

    if (oldWrapper && (oldWrapper != wmPtr->wrapper)
	    && (oldWrapper != GetDesktopWindow())) {
#ifdef _WIN64
	SetWindowLongPtr(oldWrapper, GWLP_USERDATA, (LONG) NULL);
#else
	SetWindowLong(oldWrapper, GWL_USERDATA, (LONG) NULL);
#endif

	if (wmPtr->numTransients > 0) {
	    /*
	     * Unset the current wrapper as the parent for all transient
	     * children for whom this is the master
	     */
	    WmInfo *wmPtr2;

	    childStateInfo = (int *)ckalloc((unsigned) wmPtr->numTransients
		* sizeof(int));
	    state = 0;
	    for (wmPtr2 = winPtr->dispPtr->firstWmPtr; wmPtr2 != NULL;
		 wmPtr2 = wmPtr2->nextPtr) {
		if (wmPtr2->masterPtr == winPtr) {
		    if (!(wmPtr2->flags & WM_NEVER_MAPPED)) {
			childStateInfo[state++] = wmPtr2->hints.initial_state;
			SetParent(TkWinGetHWND(wmPtr2->winPtr->window), NULL);
		    }
		}
	    }
	}
	/*
	 * Remove the menubar before destroying the window so the menubar
	 * isn't destroyed.
	 */

	SetMenu(oldWrapper, NULL);
	DestroyWindow(oldWrapper);
    }

    wmPtr->flags &= ~WM_NEVER_MAPPED;
    SendMessage(wmPtr->wrapper, TK_ATTACHWINDOW, (WPARAM) child, 0);

    /*
     * Force an initial transition from withdrawn to the real
     * initial state.
     */

    state = wmPtr->hints.initial_state;
    wmPtr->hints.initial_state = WithdrawnState;
    TkpWmSetState(winPtr, state);

    if (hSmallIcon != NULL) {
	SendMessage(wmPtr->wrapper,WM_SETICON,ICON_SMALL,(LPARAM)hSmallIcon);
    }
    if (hBigIcon != NULL) {
	SendMessage(wmPtr->wrapper,WM_SETICON,ICON_BIG,(LPARAM)hBigIcon);
    }

    /*
     * If we are embedded then force a mapping of the window now,
     * because we do not necessarily own the wrapper and may not
     * get another opportunity to map ourselves. We should not be
     * in either iconified or zoomed states when we get here, so
     * it is safe to just check for TK_EMBEDDED without checking
     * what state we are supposed to be in (default to NormalState).
     */

    if (winPtr->flags & TK_EMBEDDED) {
	XMapWindow(winPtr->display, winPtr->window);
    }

    /*
     * Set up menus on the wrapper if required.
     */

    if (wmPtr->hMenu != NULL) {
	wmPtr->flags = WM_SYNC_PENDING;
	SetMenu(wmPtr->wrapper, wmPtr->hMenu);
	wmPtr->flags &= ~WM_SYNC_PENDING;
    }

    if (childStateInfo) {
	if (wmPtr->numTransients > 0) {
	    /*
	     * Reset all transient children for whom this is the master
	     */
	    WmInfo *wmPtr2;

	    state = 0;
	    for (wmPtr2 = winPtr->dispPtr->firstWmPtr; wmPtr2 != NULL;
		 wmPtr2 = wmPtr2->nextPtr) {
		if (wmPtr2->masterPtr == winPtr) {
		    if (!(wmPtr2->flags & WM_NEVER_MAPPED)) {
			UpdateWrapper(wmPtr2->winPtr);
			TkpWmSetState(wmPtr2->winPtr, childStateInfo[state++]);
		    }
		}
	    }
	}

	ckfree((char *) childStateInfo);
    }

    /*
     * If this is the first window created by the application, then
     * we should activate the initial window.
     */

    if (tsdPtr->firstWindow) {
	tsdPtr->firstWindow = 0;
	SetActiveWindow(wmPtr->wrapper);
    }
}

/*
 *--------------------------------------------------------------
 *
 * TkWmMapWindow --
 *
 *	This procedure is invoked to map a top-level window.  This
 *	module gets a chance to update all window-manager-related
 *	information in properties before the window manager sees
 *	the map event and checks the properties.  It also gets to
 *	decide whether or not to even map the window after all.
 *
 * Results:
 *	None.
 *

pTk/mTk/win/tkWinWm.c  view on Meta::CPAN

    }
    /* Now pixmap and possibly its associated image */
    if (wmPtr->hints.flags & IconPixmapHint) {
	if (wmPtr->iconImage) {
	    Tk_FreePixmap(winPtr->display, wmPtr->hints.icon_pixmap);
	    Tk_FreeImage(wmPtr->iconImage);
	} else {
	    Tk_FreeBitmap(winPtr->display, wmPtr->hints.icon_pixmap);
	}
    }
    if (wmPtr->hints.flags & IconMaskHint) {
	Tk_FreeBitmap(winPtr->display, wmPtr->hints.icon_mask);
    }
    if (wmPtr->leaderName != NULL) {
	ckfree(wmPtr->leaderName);
    }
    if (wmPtr->icon != NULL) {
	wmPtr2 = ((TkWindow *) wmPtr->icon)->wmInfoPtr;
	wmPtr2->iconFor = NULL;
    }
    if (wmPtr->iconFor != NULL) {
	wmPtr2 = ((TkWindow *) wmPtr->iconFor)->wmInfoPtr;
	wmPtr2->icon = NULL;
	wmPtr2->hints.flags &= ~IconWindowHint;
    }
    while (wmPtr->protPtr != NULL) {
	ProtocolHandler *protPtr;

	protPtr = wmPtr->protPtr;
	wmPtr->protPtr = protPtr->nextPtr;
	Tcl_EventuallyFree((ClientData) protPtr, ProtocolFree);
    }
    if (wmPtr->cmdArgv != NULL) {
	ckfree((char *) wmPtr->cmdArgv);
    }
    if (wmPtr->clientMachine != NULL) {
	ckfree((char *) wmPtr->clientMachine);
    }
    if (wmPtr->flags & WM_UPDATE_PENDING) {
	Tcl_CancelIdleCall(UpdateGeometryInfo, (ClientData) winPtr);
    }
    if (wmPtr->masterPtr != NULL) {
	wmPtr2 = wmPtr->masterPtr->wmInfoPtr;
	/*
	 * If we had a master, tell them that we aren't tied
	 * to them anymore
	 */
	if (wmPtr2 != NULL) {
	    wmPtr2->numTransients--;
	}
	Tk_DeleteEventHandler((Tk_Window) wmPtr->masterPtr,
		VisibilityChangeMask|StructureNotifyMask,
		WmWaitVisibilityOrMapProc, (ClientData) winPtr);
	wmPtr->masterPtr = NULL;
    }

    /*
     * Destroy the decorative frame window.
     */

    if (!(winPtr->flags & TK_EMBEDDED)) {
	if (wmPtr->wrapper != NULL) {
	    DestroyWindow(wmPtr->wrapper);
	} else {
	    DestroyWindow(Tk_GetHWND(winPtr->window));
	}
    }
    if (wmPtr->iconPtr != NULL) {
	/*
	 * This may delete the icon resource data.  I believe we
	 * should do this after destroying the decorative frame,
	 * because the decorative frame is using this icon.
	 */
        DecrIconRefCount(wmPtr->iconPtr);
    }

    ckfree((char *) wmPtr);
    winPtr->wmInfoPtr = NULL;
}

/*
 *--------------------------------------------------------------
 *
 * TkWmSetClass --
 *
 *	This procedure is invoked whenever a top-level window's
 *	class is changed.  If the window has been mapped then this
 *	procedure updates the window manager property for the
 *	class.  If the window hasn't been mapped, the update is
 *	deferred until just before the first mapping.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	A window property may get updated.
 *
 *--------------------------------------------------------------
 */

void
TkWmSetClass(winPtr)
    TkWindow *winPtr;		/* Newly-created top-level window. */
{
    return;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_WmObjCmd --
 *
 *	This procedure is invoked to process the "wm" Tcl command.
 *	See the user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *

pTk/mTk/win/tkWinWm.c  view on Meta::CPAN

 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmAttributesCmd(tkwin, winPtr, interp, objc, objv)
    Tk_Window tkwin;		/* Main window of the application. */
    TkWindow *winPtr;           /* Toplevel to work with */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    LONG style, exStyle, styleBit, *stylePtr;
    char buf[TCL_INTEGER_SPACE], *string;
    int i, boolean, length;

    if (objc < 3) {
        configArgs:
	Tcl_WrongNumArgs(interp, 2, objv,
		"window"
		" ?-disabled ?bool??"
		" ?-toolwindow ?bool??"
		" ?-topmost ?bool??");
	return TCL_ERROR;
    }
    exStyle = wmPtr->exStyleConfig;
    style   = wmPtr->styleConfig;
    if (objc == 3) {
	/* FIXME XXX should not return Tcl-ish list */
	sprintf(buf, "%d", ((style & WS_DISABLED) != 0));
	Tcl_AppendResult(interp, "-disabled ", buf, (char *) NULL);
	sprintf(buf, "%d", ((exStyle & WS_EX_TOOLWINDOW) != 0));
	Tcl_AppendResult(interp, " -toolwindow ", buf, (char *) NULL);
	sprintf(buf, "%d", ((exStyle & WS_EX_TOPMOST) != 0));
	Tcl_AppendResult(interp, " -topmost ", buf, (char *) NULL);
	return TCL_OK;
    }
    for (i = 3; i < objc; i += 2) {
	string = Tcl_GetStringFromObj(objv[i], &length);
	if ((length < 2) || (string[0] != '-')) {
	    goto configArgs;
	}
	if ((i < objc-1) &&
		(Tcl_GetBooleanFromObj(interp, objv[i+1], &boolean) != TCL_OK)) {
	    return TCL_ERROR;
	}
	if (strncmp(string, "-disabled", length) == 0) {
	    stylePtr = &style;
	    styleBit = WS_DISABLED;
	} else if ((strncmp(string, "-toolwindow", length) == 0)
		   && (length >= 3)) {
	    stylePtr = &exStyle;
	    styleBit = WS_EX_TOOLWINDOW;
	} else if ((strncmp(string, "-topmost", length) == 0)
		   && (length >= 3)) {
	    stylePtr = &exStyle;
	    styleBit = WS_EX_TOPMOST;
	    if ((i < objc-1) && (winPtr->flags & TK_EMBEDDED)) {
		Tcl_AppendResult(interp, "can't set topmost flag on ",
			winPtr->pathName, ": it is an embedded window",
			(char *) NULL);
		return TCL_ERROR;
	    }
	} else {
	    goto configArgs;
	}
	if (i == objc-1) {
	    Tcl_SetIntObj(Tcl_GetObjResult(interp),
		    ((*stylePtr & styleBit) != 0));
	} else if (boolean) {
	    *stylePtr |= styleBit;
	} else {
	    *stylePtr &= ~styleBit;
	}
    }
    if ((wmPtr->styleConfig != style) ||
	    (wmPtr->exStyleConfig != exStyle)) {
	wmPtr->styleConfig = style;
	wmPtr->exStyleConfig = exStyle;
	UpdateWrapper(winPtr);
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * WmClientCmd --
 *
 *	This procedure is invoked to process the "wm client" Tcl command.
 *	See the user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmClientCmd(tkwin, winPtr, interp, objc, objv)
    Tk_Window tkwin;		/* Main window of the application. */
    TkWindow *winPtr;           /* Toplevel to work with */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    char *argv3;
    int length;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?name?");
	return TCL_ERROR;
    }
    if (objc == 3) {

pTk/mTk/win/tkWinWm.c  view on Meta::CPAN

			Tk_InternAtom((Tk_Window) winPtr, "WM_COMMAND"));
	    }
	}
	return TCL_OK;
    }
    if (Tcl_ListObjGetElements(interp, objv[3], &cmdArgc, &cmdArgv) != TCL_OK) {
	return TCL_ERROR;
    }
    if (wmPtr->cmdArgv != NULL) {
	ckfree((char *) wmPtr->cmdArgv);
    }
    wmPtr->cmdArgc = cmdArgc;
    wmPtr->cmdArgv = (CONST char **) ckalloc(cmdArgc*sizeof(char *));
    for (i=0; i < cmdArgc; i++)
     {
      wmPtr->cmdArgv[i] = Tcl_GetString(cmdArgv[i]);
     }
    if (!(wmPtr->flags & WM_NEVER_MAPPED)) {
	XSetCommand(winPtr->display, winPtr->window, wmPtr->cmdArgv, cmdArgc);
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * WmDeiconifyCmd --
 *
 *	This procedure is invoked to process the "wm deiconify" Tcl command.
 *	See the user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmDeiconifyCmd(tkwin, winPtr, interp, objc, objv)
    Tk_Window tkwin;		/* Main window of the application. */
    TkWindow *winPtr;           /* Toplevel to work with */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "window");
	return TCL_ERROR;
    }
    if (wmPtr->iconFor != NULL) {
	Tcl_AppendResult(interp, "can't deiconify ", Tcl_GetString(objv[2]),
		": it is an icon for ", Tk_PathName(wmPtr->iconFor),
		(char *) NULL);
	return TCL_ERROR;
    }
    if (winPtr->flags & TK_EMBEDDED) {
	Tcl_AppendResult(interp, "can't deiconify ", winPtr->pathName,
		": it is an embedded window", (char *) NULL);
	return TCL_ERROR;
    }

    wmPtr->flags &= ~WM_WITHDRAWN;

    /*
     * If WM_UPDATE_PENDING is true, a pending UpdateGeometryInfo may
     * need to be called first to update a withdrawn toplevel's geometry
     * before it is deiconified by TkpWmSetState.
     * Don't bother if we've never been mapped.
     */
    if ((wmPtr->flags & WM_UPDATE_PENDING) &&
	    !(wmPtr->flags & WM_NEVER_MAPPED)) {
	Tcl_CancelIdleCall(UpdateGeometryInfo, (ClientData) winPtr);
	UpdateGeometryInfo((ClientData) winPtr);
    }

    /*
     * If we were in the ZoomState (maximized), 'wm deiconify'
     * should not cause the window to shrink
     */
    if (wmPtr->hints.initial_state == ZoomState) {
	TkpWmSetState(winPtr, ZoomState);
    } else {
	TkpWmSetState(winPtr, NormalState);
    }

    /*
     * An unmapped window will be mapped at idle time
     * by a call to MapFrame. That calls CreateWrapper
     * which sets the focus and raises the window.
     */
    if (wmPtr->flags & WM_NEVER_MAPPED) {
	return TCL_OK;
    }

    /*
     * Follow Windows-like style here, raising the window to the top.
     */
    TkWmRestackToplevel(winPtr, Above, NULL);
    if (!(Tk_Attributes((Tk_Window) winPtr)->override_redirect)) {
	TkSetFocusWin(winPtr, 1);
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * WmFocusmodelCmd --
 *
 *	This procedure is invoked to process the "wm focusmodel" Tcl command.
 *	See the user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:

pTk/mTk/win/tkWinWm.c  view on Meta::CPAN

	    titlebaricon = GetIconFromPixmap(Tk_Display(winPtr), pixmap);
	    if (titlebaricon != NULL) {
		if (WinSetIcon(interp, titlebaricon,
			(isDefault ? NULL : (Tk_Window) winPtr)) != TCL_OK) {
		    /* We didn't use the titlebaricon after all */
		    DecrIconRefCount(titlebaricon);
		    titlebaricon = NULL;
		}
	    }
	}
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * WmIconifyCmd --
 *
 *	This procedure is invoked to process the "wm iconify" Tcl command.
 *	See the user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmIconifyCmd(tkwin, winPtr, interp, objc, objv)
    Tk_Window tkwin;		/* Main window of the application. */
    TkWindow *winPtr;           /* Toplevel to work with */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "window");
	return TCL_ERROR;
    }
    if (Tk_Attributes((Tk_Window) winPtr)->override_redirect) {
	Tcl_AppendResult(interp, "can't iconify \"", winPtr->pathName,
		"\": override-redirect flag is set", (char *) NULL);
	return TCL_ERROR;
    }
    if (wmPtr->masterPtr != NULL) {
	Tcl_AppendResult(interp, "can't iconify \"", winPtr->pathName,
		"\": it is a transient", (char *) NULL);
	return TCL_ERROR;
    }
    if (wmPtr->iconFor != NULL) {
	Tcl_AppendResult(interp, "can't iconify ", winPtr->pathName,
		": it is an icon for ", Tk_PathName(wmPtr->iconFor),
		(char *) NULL);
	return TCL_ERROR;
    }
    if (winPtr->flags & TK_EMBEDDED) {
	Tcl_AppendResult(interp, "can't iconify ", winPtr->pathName,
		": it is an embedded window", (char *) NULL);
	return TCL_ERROR;
    }
    TkpWmSetState(winPtr, IconicState);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * WmIconmaskCmd --
 *
 *	This procedure is invoked to process the "wm iconmask" Tcl command.
 *	See the user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmIconmaskCmd(tkwin, winPtr, interp, objc, objv)
    Tk_Window tkwin;		/* Main window of the application. */
    TkWindow *winPtr;           /* Toplevel to work with */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    Pixmap pixmap;
    char *argv3;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?bitmap?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->hints.flags & IconMaskHint) {
	    Tcl_SetResult(interp, (char *)
		    Tk_NameOfBitmap(winPtr->display, wmPtr->hints.icon_mask),
		    TCL_STATIC);
	}
	return TCL_OK;
    }
    argv3 = Tcl_GetString(objv[3]);
    if (*argv3 == '\0') {
	if (wmPtr->hints.icon_mask != None) {
	    Tk_FreeBitmap(winPtr->display, wmPtr->hints.icon_mask);
	}
	wmPtr->hints.flags &= ~IconMaskHint;
    } else {
	pixmap = Tk_GetBitmap(interp, tkwin, argv3);
	if (pixmap == None) {
	    return TCL_ERROR;
	}

pTk/mTk/win/tkWinWm.c  view on Meta::CPAN

	    || (Tcl_GetIntFromObj(interp, objv[4], &height) != TCL_OK)) {
	return TCL_ERROR;
    }
    wmPtr->minWidth = width;
    wmPtr->minHeight = height;
    WmUpdateGeom(wmPtr, winPtr);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * WmOverrideredirectCmd --
 *
 *	This procedure is invoked to process the "wm overrideredirect"
 *	Tcl command.
 *	See the user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmOverrideredirectCmd(tkwin, winPtr, interp, objc, objv)
    Tk_Window tkwin;		/* Main window of the application. */
    TkWindow *winPtr;           /* Toplevel to work with */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    int boolean, curValue;
    XSetWindowAttributes atts;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?boolean?");
	return TCL_ERROR;
    }
    curValue = Tk_Attributes((Tk_Window) winPtr)->override_redirect;
    if (objc == 3) {
	Tcl_SetBooleanObj(Tcl_GetObjResult(interp), curValue);
	return TCL_OK;
    }
    if (Tcl_GetBooleanFromObj(interp, objv[3], &boolean) != TCL_OK) {
	return TCL_ERROR;
    }
    if (curValue != boolean) {
	/*
	 * Only do this if we are really changing value, because it
	 * causes some funky stuff to occur
	 */
	atts.override_redirect = (boolean) ? True : False;
	Tk_ChangeWindowAttributes((Tk_Window) winPtr, CWOverrideRedirect,
		&atts);
	if (!(wmPtr->flags & (WM_NEVER_MAPPED)
		&& !(winPtr->flags & TK_EMBEDDED))) {
	    UpdateWrapper(winPtr);
	}
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * WmPositionfromCmd --
 *
 *	This procedure is invoked to process the "wm positionfrom"
 *	Tcl command.
 *	See the user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmPositionfromCmd(tkwin, winPtr, interp, objc, objv)
    Tk_Window tkwin;		/* Main window of the application. */
    TkWindow *winPtr;           /* Toplevel to work with */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    static CONST char *optionStrings[] = {
	"program", "user", (char *) NULL };
    enum options {
	OPT_PROGRAM, OPT_USER };
    int index;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?user/program?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->sizeHintsFlags & USPosition) {
	    Tcl_SetResult(interp, "user", TCL_STATIC);
	} else if (wmPtr->sizeHintsFlags & PPosition) {
	    Tcl_SetResult(interp, "program", TCL_STATIC);
	}
	return TCL_OK;
    }
    if (*Tcl_GetString(objv[3]) == '\0') {
	wmPtr->sizeHintsFlags &= ~(USPosition|PPosition);
    } else {
	if (Tcl_GetIndexFromObj(interp, objv[3], optionStrings, "argument", 0,
		&index) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (index == OPT_USER) {
	    wmPtr->sizeHintsFlags &= ~PPosition;

pTk/mTk/win/tkWinWm.c  view on Meta::CPAN

#else
	protPtr->command = LangMakeCallback(objv[4]);
#endif
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * WmResizableCmd --
 *
 *	This procedure is invoked to process the "wm resizable" Tcl command.
 *	See the user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmResizableCmd(tkwin, winPtr, interp, objc, objv)
    Tk_Window tkwin;		/* Main window of the application. */
    TkWindow *winPtr;           /* Toplevel to work with */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    int width, height;

    if ((objc != 3) && (objc != 5)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?width height?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	Tcl_IntResults(interp, 2, 0,
		       (wmPtr->flags & WM_WIDTH_NOT_RESIZABLE) ? 0 : 1,
		       (wmPtr->flags & WM_HEIGHT_NOT_RESIZABLE) ? 0 : 1);
	return TCL_OK;
    }
    if ((Tcl_GetBooleanFromObj(interp, objv[3], &width) != TCL_OK)
	    || (Tcl_GetBooleanFromObj(interp, objv[4], &height) != TCL_OK)) {
	return TCL_ERROR;
    }
    if (width) {
	wmPtr->flags &= ~WM_WIDTH_NOT_RESIZABLE;
    } else {
	wmPtr->flags |= WM_WIDTH_NOT_RESIZABLE;
    }
    if (height) {
	wmPtr->flags &= ~WM_HEIGHT_NOT_RESIZABLE;
    } else {
	wmPtr->flags |= WM_HEIGHT_NOT_RESIZABLE;
    }
    if (!((wmPtr->flags & WM_NEVER_MAPPED)
	    && !(winPtr->flags & TK_EMBEDDED))) {
	UpdateWrapper(winPtr);
    }
    WmUpdateGeom(wmPtr, winPtr);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * WmSizefromCmd --
 *
 *	This procedure is invoked to process the "wm sizefrom" Tcl command.
 *	See the user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmSizefromCmd(tkwin, winPtr, interp, objc, objv)
    Tk_Window tkwin;		/* Main window of the application. */
    TkWindow *winPtr;           /* Toplevel to work with */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    static CONST char *optionStrings[] = {
	"program", "user", (char *) NULL };
    enum options {
	OPT_PROGRAM, OPT_USER };
    int index;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?user|program?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->sizeHintsFlags & USSize) {
	    Tcl_SetResult(interp, "user", TCL_STATIC);
	} else if (wmPtr->sizeHintsFlags & PSize) {
	    Tcl_SetResult(interp, "program", TCL_STATIC);
	}
	return TCL_OK;
    }

    if (*Tcl_GetString(objv[3]) == '\0') {
	wmPtr->sizeHintsFlags &= ~(USSize|PSize);
    } else {
	if (Tcl_GetIndexFromObj(interp, objv[3], optionStrings, "argument", 0,
		&index) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (index == OPT_USER) {
	    wmPtr->sizeHintsFlags &= ~PSize;

pTk/mTk/win/tkWinWm.c  view on Meta::CPAN


	if (Tcl_GetIndexFromObj(interp, objv[3], optionStrings, "argument", 0,
		&index) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (index == OPT_ISABOVE) {
	    result = index1 > index2;
	} else { /* OPT_ISBELOW */
	    result = index1 < index2;
	}
	Tcl_SetIntObj(Tcl_GetObjResult(interp), result);
	return TCL_OK;
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * WmStateCmd --
 *
 *	This procedure is invoked to process the "wm state" Tcl command.
 *	See the user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmStateCmd(tkwin, winPtr, interp, objc, objv)
    Tk_Window tkwin;		/* Main window of the application. */
    TkWindow *winPtr;           /* Toplevel to work with */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    static CONST char *optionStrings[] = {
	"normal", "iconic", "withdrawn", "zoomed", (char *) NULL };
    enum options {
	OPT_NORMAL, OPT_ICONIC, OPT_WITHDRAWN, OPT_ZOOMED };
    int index;

    if ((objc < 3) || (objc > 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?state?");
	return TCL_ERROR;
    }
    if (objc == 4) {
	if (wmPtr->iconFor != NULL) {
	    Tcl_AppendResult(interp, "can't change state of ",
		    Tcl_GetString(objv[2]),
		    ": it is an icon for ", Tk_PathName(wmPtr->iconFor),
		    (char *) NULL);
	    return TCL_ERROR;
	}
	if (winPtr->flags & TK_EMBEDDED) {
	    Tcl_AppendResult(interp, "can't change state of ",
		    winPtr->pathName, ": it is an embedded window",
		    (char *) NULL);
	    return TCL_ERROR;
	}

	if (Tcl_GetIndexFromObj(interp, objv[3], optionStrings, "argument", 0,
		&index) != TCL_OK) {
	    return TCL_ERROR;
	}

	if (index == OPT_NORMAL) {
	    wmPtr->flags &= ~WM_WITHDRAWN;
	    TkpWmSetState(winPtr, NormalState);
	    /*
	     * This varies from 'wm deiconify' because it does not
	     * force the window to be raised and receive focus
	     */
	} else if (index == OPT_ICONIC) {
	    if (Tk_Attributes((Tk_Window) winPtr)->override_redirect) {
		Tcl_AppendResult(interp, "can't iconify \"",
			winPtr->pathName,
			"\": override-redirect flag is set",
			(char *) NULL);
		return TCL_ERROR;
	    }
	    if (wmPtr->masterPtr != NULL) {
		Tcl_AppendResult(interp, "can't iconify \"",
			winPtr->pathName,
			"\": it is a transient", (char *) NULL);
		return TCL_ERROR;
	    }
	    TkpWmSetState(winPtr, IconicState);
	} else if (index == OPT_WITHDRAWN) {
	    wmPtr->flags |= WM_WITHDRAWN;
	    TkpWmSetState(winPtr, WithdrawnState);
	} else { /* OPT_ZOOMED */
	    TkpWmSetState(winPtr, ZoomState);
	}
    } else {
	if (wmPtr->iconFor != NULL) {
	    Tcl_SetResult(interp, "icon", TCL_STATIC);
	} else {
	    switch (wmPtr->hints.initial_state) {
	      case NormalState:
		Tcl_SetResult(interp, "normal", TCL_STATIC);
		break;
	      case IconicState:
		Tcl_SetResult(interp, "iconic", TCL_STATIC);
		break;
	      case WithdrawnState:
		Tcl_SetResult(interp, "withdrawn", TCL_STATIC);
		break;
	      case ZoomState:
		Tcl_SetResult(interp, "zoomed", TCL_STATIC);
		break;
	    }
	}
    }
    return TCL_OK;

pTk/mTk/win/tkWinWm.c  view on Meta::CPAN

		(Tk_Window *) &masterPtr) != TCL_OK) {
	    return TCL_ERROR;
	}
	while (!Tk_TopWinHierarchy(masterPtr)) {
	    /*
	     * Ensure that the master window is actually a Tk toplevel.
	     */

	    masterPtr = masterPtr->parentPtr;
	}
	Tk_MakeWindowExist((Tk_Window) masterPtr);

	if (wmPtr->iconFor != NULL) {
	    Tcl_AppendResult(interp, "can't make \"",
		    Tcl_GetString(objv[2]),
		    "\" a transient: it is an icon for ",
		    Tk_PathName(wmPtr->iconFor),
		    (char *) NULL);
	    return TCL_ERROR;
	}

	wmPtr2 = masterPtr->wmInfoPtr;

	if (wmPtr2->iconFor != NULL) {
	    Tcl_AppendResult(interp, "can't make \"",
		    Tcl_GetString(objv[3]),
		    "\" a master: it is an icon for ",
		    Tk_PathName(wmPtr2->iconFor),
		    (char *) NULL);
	    return TCL_ERROR;
	}

	if (masterPtr == winPtr) {
	    Tcl_AppendResult(interp, "can't make \"", Tk_PathName(winPtr),
		    "\" its own master",
		    (char *) NULL);
	    return TCL_ERROR;
	} else if (masterPtr != wmPtr->masterPtr) {
	    /*
	     * Remove old master map/unmap binding before setting
	     * the new master. The event handler will ensure that
	     * transient states reflect the state of the master.
	     */

	    if (wmPtr->masterPtr != NULL) {
		wmPtr->masterPtr->wmInfoPtr->numTransients--;
		Tk_DeleteEventHandler((Tk_Window) wmPtr->masterPtr,
			VisibilityChangeMask|StructureNotifyMask,
			WmWaitVisibilityOrMapProc, (ClientData) winPtr);
	    }

	    masterPtr->wmInfoPtr->numTransients++;
	    Tk_CreateEventHandler((Tk_Window) masterPtr,
		    VisibilityChangeMask|StructureNotifyMask,
		    WmWaitVisibilityOrMapProc, (ClientData) winPtr);

	    wmPtr->masterPtr = masterPtr;
	}
    }
    if (!((wmPtr->flags & WM_NEVER_MAPPED)
	    && !(winPtr->flags & TK_EMBEDDED))) {
	if (wmPtr->masterPtr != NULL &&
		!Tk_IsMapped(wmPtr->masterPtr)) {
	    TkpWmSetState(winPtr, WithdrawnState);
	} else {
	    UpdateWrapper(winPtr);
	}
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * WmWithdrawCmd --
 *
 *	This procedure is invoked to process the "wm withdraw" Tcl command.
 *	See the user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmWithdrawCmd(tkwin, winPtr, interp, objc, objv)
    Tk_Window tkwin;		/* Main window of the application. */
    TkWindow *winPtr;           /* Toplevel to work with */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "window");
	return TCL_ERROR;
    }
    if (wmPtr->iconFor != NULL) {
	Tcl_AppendResult(interp, "can't withdraw ", Tcl_GetString(objv[2]),
		": it is an icon for ", Tk_PathName(wmPtr->iconFor),
		(char *) NULL);
	return TCL_ERROR;
    }
    wmPtr->flags |= WM_WITHDRAWN;
    TkpWmSetState(winPtr, WithdrawnState);
    return TCL_OK;
}

/*
 * Invoked by those wm subcommands that affect geometry.
 * Schedules a geometry update.
 */
static void
WmUpdateGeom(wmPtr, winPtr)
    WmInfo *wmPtr;
    TkWindow *winPtr;

pTk/mTk/win/tkWinWm.c  view on Meta::CPAN

		- wmPtr->reqGridWidth)*wmPtr->widthInc;
	wmPtr->height = winPtr->reqHeight + (wmPtr->height
		- wmPtr->reqGridHeight)*wmPtr->heightInc;
    }
    wmPtr->widthInc = 1;
    wmPtr->heightInc = 1;

    if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) {
	Tcl_DoWhenIdle(UpdateGeometryInfo, (ClientData) winPtr);
	wmPtr->flags |= WM_UPDATE_PENDING;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TopLevelEventProc --
 *
 *	This procedure is invoked when a top-level (or other externally-
 *	managed window) is restructured in any way.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Tk's internal data structures for the window get modified to
 *	reflect the structural change.
 *
 *----------------------------------------------------------------------
 */

static void
TopLevelEventProc(clientData, eventPtr)
    ClientData clientData;		/* Window for which event occurred. */
    XEvent *eventPtr;			/* Event that just happened. */
{
    register TkWindow *winPtr = (TkWindow *) clientData;

    if (eventPtr->type == DestroyNotify) {
	Tk_ErrorHandler handler;

	if (!(winPtr->flags & TK_ALREADY_DEAD)) {
	    /*
	     * A top-level window was deleted externally (e.g., by the window
	     * manager).  This is probably not a good thing, but cleanup as
	     * best we can.  The error handler is needed because
	     * Tk_DestroyWindow will try to destroy the window, but of course
	     * it's already gone.
	     */

	    handler = Tk_CreateErrorHandler(winPtr->display, -1, -1, -1,
		    (Tk_ErrorProc *) NULL, (ClientData) NULL);
	    Tk_DestroyWindow((Tk_Window) winPtr);
	    Tk_DeleteErrorHandler(handler);
	}
    }
    else if (eventPtr->type == ConfigureNotify) {
	WmInfo *wmPtr;
	wmPtr = winPtr->wmInfoPtr;

	if (winPtr->flags & TK_EMBEDDED) {
	    Tk_Window tkwin = (Tk_Window)winPtr;
	    SendMessage(wmPtr->wrapper, TK_GEOMETRYREQ, Tk_ReqWidth(tkwin),
	        Tk_ReqHeight(tkwin));
	}
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TopLevelReqProc --
 *
 *	This procedure is invoked by the geometry manager whenever
 *	the requested size for a top-level window is changed.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Arrange for the window to be resized to satisfy the request
 *	(this happens as a when-idle action).
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
static void
TopLevelReqProc(dummy, tkwin)
    ClientData dummy;			/* Not used. */
    Tk_Window tkwin;			/* Information about window. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    WmInfo *wmPtr;

    wmPtr = winPtr->wmInfoPtr;
    if ((winPtr->flags & TK_EMBEDDED) && (wmPtr->wrapper != NULL)) {
	SendMessage(wmPtr->wrapper, TK_GEOMETRYREQ, Tk_ReqWidth(tkwin),
	    Tk_ReqHeight(tkwin));
    }
    if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) {
	Tcl_DoWhenIdle(UpdateGeometryInfo, (ClientData) winPtr);
	wmPtr->flags |= WM_UPDATE_PENDING;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * UpdateGeometryInfo --
 *
 *	This procedure is invoked when a top-level window is first
 *	mapped, and also as a when-idle procedure, to bring the
 *	geometry and/or position of a top-level window back into
 *	line with what has been requested by the user and/or widgets.
 *	This procedure doesn't return until the system has
 *	responded to the geometry change.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The window's size and location may change, unless the WM prevents
 *	that from happening.
 *
 *----------------------------------------------------------------------
 */

static void
UpdateGeometryInfo(clientData)
    ClientData clientData;		/* Pointer to the window's record. */
{
    int x, y;			/* Position of border on desktop. */
    int width, height;		/* Size of client area. */
    RECT rect;
    register TkWindow *winPtr = (TkWindow *) clientData;
    register WmInfo *wmPtr = winPtr->wmInfoPtr;

    wmPtr->flags &= ~WM_UPDATE_PENDING;

    /*
     * If the window is minimized or maximized, we should not update
     * our geometry since it will end up with the wrong values.
     * ConfigureToplevel will reschedule UpdateGeometryInfo when the
     * state of the window changes.
     */

    if (IsIconic(wmPtr->wrapper) || IsZoomed(wmPtr->wrapper)) {
	return;
    }

    /*
     * Compute the border size for the current window style.  This
     * size will include the resize handles, the title bar and the
     * menubar.  Note that this size will not be correct if the
     * menubar spans multiple lines.  The height will be off by a
     * multiple of the menubar height.  It really only measures the

pTk/mTk/win/tkWinWm.c  view on Meta::CPAN

		- (width + wmPtr->borderWidth);
    } else {
	x =  wmPtr->x;
    }
    if (wmPtr->flags & WM_NEGATIVE_Y) {
	y = DisplayHeight(winPtr->display, winPtr->screenNum) - wmPtr->y
		- (height + wmPtr->borderHeight);
    } else {
	y =  wmPtr->y;
    }

    /*
     * If this window is embedded and the container is also in this
     * process, we don't need to do anything special about the
     * geometry, except to make sure that the desired size is known
     * by the container.  Also, zero out any position information,
     * since embedded windows are not allowed to move.
     */

    if (winPtr->flags & TK_BOTH_HALVES) {
	wmPtr->x = wmPtr->y = 0;
	wmPtr->flags &= ~(WM_NEGATIVE_X|WM_NEGATIVE_Y);
	Tk_GeometryRequest((Tk_Window) TkpGetOtherWindow(winPtr),
		width, height);
	return;
    }

    /*
     * Reconfigure the window if it isn't already configured correctly.  Base
     * the size check on what we *asked for* last time, not what we got.
     * Return immediately if there have been no changes in the requested
     * geometry of the toplevel.
     */
    /* TODO: need to add flag for possible menu size change */

    if (!((wmPtr->flags & WM_MOVE_PENDING)
	    || (width != wmPtr->configWidth)
	    || (height != wmPtr->configHeight))) {
	return;
    }
    wmPtr->flags &= ~WM_MOVE_PENDING;

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

    /*
     * Don't bother moving the window if we are in the process of
     * creating it.  Just update the geometry info based on what
     * we asked for.
     */

    if (wmPtr->flags & WM_CREATE_PENDING) {
	winPtr->changes.x = x;
	winPtr->changes.y = y;
	winPtr->changes.width = width;
	winPtr->changes.height = height;
	return;
    }

    wmPtr->flags |= WM_SYNC_PENDING;
    if (winPtr->flags & TK_EMBEDDED) {
	/*
	 * The wrapper window is in a different process, so we need
	 * to send it a geometry request.  This protocol assumes that
	 * the other process understands this Tk message, otherwise
	 * our requested geometry will be ignored.
	 */

	SendMessage(wmPtr->wrapper, TK_GEOMETRYREQ, width, height);
    } else {
	int reqHeight, reqWidth;
	RECT windowRect;
	int menuInc = GetSystemMetrics(SM_CYMENU);
	int newHeight;

	/*
	 * We have to keep resizing the window until we get the
	 * requested height in the client area. If the client
	 * area has zero height, then the window rect is too
	 * small by definition. Try increasing the border height
	 * and try again. Once we have a positive size, then
	 * we can adjust the height exactly. If the window
	 * rect comes back smaller than we requested, we have
	 * hit the maximum constraints that Windows imposes.
	 * Once we find a positive client size, the next size
	 * is the one we try no matter what.
	 */

	reqHeight = height + wmPtr->borderHeight;
	reqWidth = width + wmPtr->borderWidth;

	while (1) {
	    MoveWindow(wmPtr->wrapper, x, y, reqWidth, reqHeight, TRUE);
	    GetWindowRect(wmPtr->wrapper, &windowRect);
	    newHeight = windowRect.bottom - windowRect.top;

	    /*
	     * If the request wasn't satisfied, we have hit an external
	     * constraint and must stop.
	     */

	    if (newHeight < reqHeight) {
		break;
	    }

	    /*
	     * Now check the size of the client area against our ideal.
	     */

	    GetClientRect(wmPtr->wrapper, &windowRect);
	    newHeight = windowRect.bottom - windowRect.top;

	    if (newHeight == height) {
		/*
		 * We're done.
		 */
		break;
	    } else if (newHeight > height) {
		/*
		 * One last resize to get rid of the extra space.
		 */

pTk/mTk/win/tkWinWm.c  view on Meta::CPAN

	}
    }
    if (topPtr->flags & TK_ALREADY_DEAD) {
	/*
	 * Top-level is being deleted, so there's no need to cleanup
	 * the WM_COLORMAP_WINDOWS property.
	 */

	return;
    }

    if (topPtr->wmInfoPtr == NULL) {
	return;
    }

    /*
     * Find the window and slide the following ones down to cover
     * it up.
     */

    count = topPtr->wmInfoPtr->cmapCount;
    oldPtr = topPtr->wmInfoPtr->cmapList;
    for (i = 0; i < count; i++) {
	if (oldPtr[i] == winPtr) {
	    for (j = i ; j < count-1; j++) {
		oldPtr[j] = oldPtr[j+1];
	    }
	    topPtr->wmInfoPtr->cmapCount = count-1;
	    break;
	}
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkWinSetMenu--
 *
 *	Associcates a given HMENU to a window.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The menu will end up being drawn in the window, and the geometry
 *	of the window will have to be changed.
 *
 *----------------------------------------------------------------------
 */

void
TkWinSetMenu(tkwin, hMenu)
    Tk_Window tkwin;		/* the window to put the menu in */
    HMENU hMenu;		/* the menu to set */
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    WmInfo *wmPtr = winPtr->wmInfoPtr;

    wmPtr->hMenu = hMenu;

    if (!(wmPtr->flags & TK_EMBEDDED)) {
	if (!(wmPtr->flags & WM_NEVER_MAPPED)) {
	    int syncPending = wmPtr->flags & WM_SYNC_PENDING;

	    wmPtr->flags |= WM_SYNC_PENDING;
	    SetMenu(wmPtr->wrapper, hMenu);
	    if (!syncPending) {
		wmPtr->flags &= ~WM_SYNC_PENDING;
	    }
	}
	if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) {
	    Tcl_DoWhenIdle(UpdateGeometryInfo, (ClientData) winPtr);
	    wmPtr->flags |= WM_UPDATE_PENDING|WM_MOVE_PENDING;
	}
    }
}

/*
 *----------------------------------------------------------------------
 *
 * ConfigureTopLevel --
 *
 *	Generate a ConfigureNotify event based on the current position
 *	information.  This procedure is called by TopLevelProc.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Queues a new event.
 *
 *----------------------------------------------------------------------
 */

static void
ConfigureTopLevel(pos)
    WINDOWPOS *pos;
{
    TkWindow *winPtr = GetTopLevel(pos->hwnd);
    WmInfo *wmPtr;
    int state;			/* Current window state. */
    RECT rect;
    WINDOWPLACEMENT windowPos;

    if (winPtr == NULL) {
	return;
    }

    wmPtr = winPtr->wmInfoPtr;

    /*
     * Determine the current window state.
     */

    if (!IsWindowVisible(wmPtr->wrapper)) {
	state = WithdrawnState;
    } else {
	windowPos.length = sizeof(WINDOWPLACEMENT);
	GetWindowPlacement(wmPtr->wrapper, &windowPos);
	switch (windowPos.showCmd) {
	    case SW_SHOWMAXIMIZED:



( run in 0.941 second using v1.01-cache-2.11-cpan-71847e10f99 )