head	1.37;
access;
symbols
	core-8-5-9:1.33.2.1
	core-8-5-8:1.33
	macosx-cocoa-merge:1.35
	macosx-cocoa-premerge:1.35
	macosx-carbon-freeze:1.35
	core-8-5-7:1.33
	core-8-5-6:1.33
	core-8-6-b1:1.35
	core-8-6-a3:1.35
	core-8-5-5:1.33
	core-8-6-a2:1.35
	core-8-5-4:1.33
	core-8-5-3:1.33
	core-8-6-a1:1.35
	core-8-4-19:1.7.2.2
	core-8-5-branch:1.33.0.2
	core-8-5-2:1.33
	core-8-4-18:1.7.2.2
	core-8-5-1:1.33
	core-8-4-17:1.7.2.2
	core-8-5-0:1.33
	core-8-5-b3:1.32
	core-8-5-b2:1.32
	core-8-4-16:1.7.2.2
	core-8-5-b1:1.32
	core-stablilizer-merge:1.31
	core-stabilizer-branch:1.31.0.2
	core-stabilizer-merge:1.33
	core-8-4-15:1.7.2.2
	core-8-5-a6:1.31
	core-8-5-a5:1.31
	core-8-4-14:1.7.2.2
	core-8-5-a4:1.30
	core-8-4-13:1.7.2.2
	core-8-4-12:1.7.2.1
	core-8-4-11:1.7.2.1
	core-8-5-a3:1.28
	core-8-4-10:1.7.2.1
	core-8-4-9-branch:1.7.2.1.0.2
	core-8-5-a2:1.10
	core-8-4-9:1.7.2.1
	core-8-4-8:1.7.2.1
	core-8-4-7:1.7
	core-8-5-a1:1.10
	core-8-4-6:1.7
	core-8-4-5:1.7
	mistachkin-dev-branch:1.7.0.4
	core-8-4-4:1.7
	core-8-4-3:1.7
	core-8-4-branch:1.7.0.2
	core-8-4-2:1.7
	core-8-4-1:1.7
	core-8-3-5:1.3.12.1
	core-8-4-0:1.7
	macosx-8-4-merge-2002-08-31-trunk:1.7
	macosx-8-4-premerge-2002-08-31-branch:1.4.6.2
	macosx-8-4-premerge-2002-08-31-trunk:1.7
	macosx-8-4-merge-2002-08-30-branch:1.4.6.2
	macosx-8-4-merge-2002-08-30-trunk:1.7
	macosx-8-4-merge-2002-08-20-branch:1.4.6.2
	macosx-8-4-merge-2002-08-20-trunk:1.7
	core-8-4-b2:1.7
	core-8-4-b1:1.6
	macosx-premerge-6-9-02:1.4
	core-8-4-a4:1.4
	core-8-3-4:1.3.12.1
	macosx-8-4-branch:1.4.0.6
	macosx-8-4-branchpoint:1.4
	core-8-4-a3:1.4
	core-8-3-3:1.3.12.1
	dgp-privates-into-namespace:1.4.0.4
	tclpro-1-5-0:1.3
	core-8-4-win-speedup:1.4.0.2
	core-8-4-a2:1.4
	tclpro-1-4-1:1.3
	tclpro-1-4-0:1.3
	core-8-3-2:1.3
	ajuba-ajuba2-2-1-base:1.3
	ajuba-ajuba2-2-0:1.3
	core-8-4-a1:1.3
	core-8-3-1-branch:1.3.0.12
	core-8-3-1:1.3
	scriptics-sc-2-0-b5:1.3
	scriptics-sc-2-0-fixed:1.3
	scriptics-sc-2-0-b2:1.3
	scriptics-sc-2-0-b1:1.3
	core-8-3-0:1.3
	core-8-3-b2:1.3
	core-8-3-b1:1.3
	scriptics-sc-1-1:1.3
	scriptics-sc-1-1-b1:1.3
	core-8-2-3:1.3
	scriptics-sc-1-1-branch:1.3.0.10
	scriptics-sc-1-1-base:1.3
	scriptics-sc-1-0:1.3
	scriptics-sc-1-0-branch:1.3.0.8
	scriptics-sc-1-0-base:1.3
	core-8-2-2:1.3
	core-8-2-1:1.3
	scriptics-bc-1-0-b1:1.3
	core-8-2-1-branch:1.3.0.6
	scriptics-tclpro-1-3-0:1.3
	core-8-2-0:1.3
	core-8-2-b3-branch:1.3.0.4
	core-8-2-b3-base:1.3
	scriptics-tclpro-1-3-b4:1.3
	core-8-2-b2:1.3
	scriptics-tclpro-1-3-b3:1.3
	core-8-2-b1:1.3
	scriptics-tclpro-1-3-b2:1.3
	merge-to-mainline-5/21/99:1.3
	scriptics-tclpro-1-3-b2-branch:1.3.0.2
	core-8-1-1:1.3
	scriptics-tclpro-1-3-b1:1.3
	core-8-1-1-base:1.3
	core-8-1-0:1.3
	merge-to-mainline-4-29-99:1.3
	merge-to-mainline-4-23-99:1.3
	core-8-1-branch-old:1.1.0.4
	core-8-0-6-branch:1.2.0.6
	core-8-0-6-base:1.2
	core-8-0-5:1.2
	core-8-1-b3:1.1.4.3
	core-8-1-b2:1.1.4.3
	dev-8-1-stubs-branch:1.1.4.3.0.2
	dev-stubs-branch:1.2.0.4
	scriptics-tclpro-1-2:1.2
	scriptics-tclpro-1-2-b2:1.2
	core-8-1-merge-2/10/99:1.2
	core-8-0-5-branch:1.2.0.2
	core-8-0-5-base:1.2
	scriptics-tclpro-1-2-b1:1.2
	scriptics-tclpro-1-2-a1:1.2
	core-8-1-b1:1.1.4.2
	core-8-0-4:1.2
	core-8-1-a2:1.1.4.1
	core-8-0-2:1.1
	core-8-0-3:1.2;
locks; strict;
comment	@ * @;


1.37
date	2010.09.10.08.59.25;	author nijtmans;	state Exp;
branches;
next	1.36;

1.36
date	2010.01.13.23.08.11;	author nijtmans;	state Exp;
branches;
next	1.35;

1.35
date	2008.04.27.22.39.17;	author dkf;	state Exp;
branches;
next	1.34;

1.34
date	2008.04.08.03.28.05;	author kennykb;	state Exp;
branches;
next	1.33;

1.33
date	2007.12.13.15.28.55;	author dgp;	state Exp;
branches
	1.33.2.1;
next	1.32;

1.32
date	2007.09.08.16.13.45;	author dkf;	state Exp;
branches;
next	1.31;

1.31
date	2006.05.29.22.21.40;	author hobbs;	state Exp;
branches
	1.31.2.1;
next	1.30;

1.30
date	2005.12.02.13.42.29;	author dkf;	state Exp;
branches;
next	1.29;

1.29
date	2005.12.02.00.19.04;	author dkf;	state Exp;
branches;
next	1.28;

1.28
date	2005.01.27.15.29.22;	author chengyemao;	state Exp;
branches;
next	1.27;

1.27
date	2005.01.18.15.19.28;	author chengyemao;	state Exp;
branches;
next	1.26;

1.26
date	2005.01.17.07.08.51;	author chengyemao;	state Exp;
branches;
next	1.25;

1.25
date	2005.01.16.00.23.12;	author chengyemao;	state Exp;
branches;
next	1.24;

1.24
date	2005.01.12.04.30.19;	author chengyemao;	state Exp;
branches;
next	1.23;

1.23
date	2005.01.12.02.58.29;	author chengyemao;	state Exp;
branches;
next	1.22;

1.22
date	2005.01.10.15.35.30;	author chengyemao;	state Exp;
branches;
next	1.21;

1.21
date	2005.01.09.19.17.23;	author chengyemao;	state Exp;
branches;
next	1.20;

1.20
date	2005.01.09.18.28.06;	author chengyemao;	state Exp;
branches;
next	1.19;

1.19
date	2005.01.07.15.18.03;	author chengyemao;	state Exp;
branches;
next	1.18;

1.18
date	2005.01.07.01.39.24;	author chengyemao;	state Exp;
branches;
next	1.17;

1.17
date	2005.01.05.02.46.59;	author chengyemao;	state Exp;
branches;
next	1.16;

1.16
date	2004.12.28.08.45.31;	author chengyemao;	state Exp;
branches;
next	1.15;

1.15
date	2004.12.20.15.30.43;	author chengyemao;	state Exp;
branches;
next	1.14;

1.14
date	2004.12.20.01.13.12;	author chengyemao;	state Exp;
branches;
next	1.13;

1.13
date	2004.12.19.18.14.26;	author chengyemao;	state Exp;
branches;
next	1.12;

1.12
date	2004.12.18.20.35.16;	author chengyemao;	state Exp;
branches;
next	1.11;

1.11
date	2004.12.17.14.17.54;	author chengyemao;	state Exp;
branches;
next	1.10;

1.10
date	2004.01.13.02.06.02;	author davygrvy;	state Exp;
branches;
next	1.9;

1.9
date	2003.12.21.23.50.13;	author davygrvy;	state Exp;
branches;
next	1.8;

1.8
date	2003.12.13.01.07.35;	author davygrvy;	state Exp;
branches;
next	1.7;

1.7
date	2002.08.05.04.30.41;	author dgp;	state Exp;
branches
	1.7.2.1;
next	1.6;

1.6
date	2002.06.22.08.37.25;	author hobbs;	state Exp;
branches;
next	1.5;

1.5
date	2002.05.27.17.33.26;	author mdejong;	state Exp;
branches;
next	1.4;

1.4
date	2000.07.06.03.17.44;	author mo;	state Exp;
branches
	1.4.6.1;
next	1.3;

1.3
date	99.04.16.01.51.51;	author stanton;	state Exp;
branches
	1.3.12.1;
next	1.2;

1.2
date	98.09.14.18.24.00;	author stanton;	state Exp;
branches;
next	1.1;

1.1
date	98.04.01.10.00.30;	author rjohnson;	state Exp;
branches
	1.1.4.1;
next	;

1.1.4.1
date	98.09.29.00.26.07;	author stanton;	state Exp;
branches;
next	1.1.4.2;

1.1.4.2
date	98.09.30.02.19.32;	author stanton;	state Exp;
branches;
next	1.1.4.3;

1.1.4.3
date	98.12.13.08.16.18;	author lfb;	state Exp;
branches;
next	;

1.3.12.1
date	2001.04.04.07.57.18;	author hobbs;	state Exp;
branches;
next	;

1.4.6.1
date	2002.06.10.05.38.28;	author wolfsuit;	state Exp;
branches;
next	1.4.6.2;

1.4.6.2
date	2002.08.20.20.27.19;	author das;	state Exp;
branches;
next	;

1.7.2.1
date	2004.10.27.00.37.38;	author davygrvy;	state Exp;
branches
	1.7.2.1.2.1;
next	1.7.2.2;

1.7.2.2
date	2006.04.11.20.23.45;	author hobbs;	state Exp;
branches;
next	;

1.7.2.1.2.1
date	2005.01.04.05.07.03;	author chengyemao;	state Exp;
branches;
next	1.7.2.1.2.2;

1.7.2.1.2.2
date	2005.01.05.02.45.53;	author chengyemao;	state Exp;
branches;
next	1.7.2.1.2.3;

1.7.2.1.2.3
date	2005.01.19.02.03.48;	author chengyemao;	state Exp;
branches;
next	1.7.2.1.2.4;

1.7.2.1.2.4
date	2005.01.27.15.30.06;	author chengyemao;	state Exp;
branches;
next	;

1.31.2.1
date	2007.09.09.04.15.54;	author dgp;	state Exp;
branches;
next	;

1.33.2.1
date	2010.03.12.13.02.36;	author nijtmans;	state Exp;
branches;
next	;


desc
@@


1.37
log
@Make compilable with -DUNICODE, or mark files with a TODO which are not done yet.
tkWinPort.h:  mingw/cygwin fixes: <tchar.h> should always be included here.
@
text
@/*
 * tkWinEmbed.c --
 *
 *	This file contains platform specific procedures for Windows platforms
 *	to provide basic operations needed for application embedding (where
 *	one application can use as its main window an internal window from
 *	another application).
 *
 * Copyright (c) 1996-1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * RCS: @@(#) $Id: tkWinEmbed.c,v 1.36 2010/01/13 23:08:11 nijtmans Exp $
 */

#include "tkWinInt.h"

/*
 * One of the following structures exists for each container in this
 * application. It keeps track of the container window and its associated
 * embedded window.
 */

typedef struct Container {
    HWND parentHWnd;		/* Windows HWND to the parent window */
    TkWindow *parentPtr;	/* Tk's information about the container or
				 * NULL if the container isn't in this
				 * process. */
    HWND embeddedHWnd;		/* Windows HWND to the embedded window. */
    TkWindow *embeddedPtr;	/* Tk's information about the embedded window,
				 * or NULL if the embedded application isn't
				 * in this process. */
    HWND embeddedMenuHWnd;	/* Tk's embedded menu window handler. */
    struct Container *nextPtr;	/* Next in list of all containers in this
				 * process. */
} Container;

typedef struct ThreadSpecificData {
    Container *firstContainerPtr;
				/* First in list of all containers managed by
				 * this process. */
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

static void		ContainerEventProc(ClientData clientData,
			    XEvent *eventPtr);
static void		EmbedGeometryRequest(Container *containerPtr,
			    int width, int height);
static void		EmbedWindowDeleted(TkWindow *winPtr);
static void		Tk_MapEmbeddedWindow(TkWindow* winPtr);
HWND			Tk_GetEmbeddedHWnd(TkWindow* winPtr);

/*
 *----------------------------------------------------------------------
 *
 * TkWinCleanupContainerList --
 *
 *	Finalizes the list of containers.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Releases memory occupied by containers of embedded windows.
 *
 *----------------------------------------------------------------------
 */

void
TkWinCleanupContainerList(void)
{
    Container *nextPtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    for (; tsdPtr->firstContainerPtr != (Container *) NULL;
	    tsdPtr->firstContainerPtr = nextPtr) {
	nextPtr = tsdPtr->firstContainerPtr->nextPtr;
	ckfree((char *) tsdPtr->firstContainerPtr);
    }
    tsdPtr->firstContainerPtr = (Container *) NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpTestembedCmd --
 *
 *	Test command for the embedding facility.
 *
 * Results:
 *	Always returns TCL_OK.
 *
 * Side effects:
 *	Currently it does not do anything.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
int
TkpTestembedCmd(
    ClientData clientData,
    Tcl_Interp *interp,
    int argc,
    const char **argv)
{
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_DetachEmbeddedWindow --
 *
 *	This function detaches an embedded window
 *
 * Results:
 *	No return value. Detach the embedded window.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static
void
Tk_DetachEmbeddedWindow(
    TkWindow *winPtr,		/* an embedded window */
    BOOL detachFlag)		/* a flag of truely detaching */
{
    TkpWinToplevelDetachWindow(winPtr);
    if(detachFlag) {
	TkpWinToplevelOverrideRedirect(winPtr, 0);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_MapEmbeddedWindow --
 *
 *	This function is required for mapping an embedded window during idle.
 *	The input winPtr must be preserved using Tcl_Preserve before call this
 *	function and will be released by this function.
 *
 * Results:
 *	No return value. Map the embedded window if it is not dead.
 *
 * Side effects:
 *	The embedded window may change its state as the container's.
 *
 *----------------------------------------------------------------------
 */

static
void Tk_MapEmbeddedWindow(
    TkWindow *winPtr)		/* Top-level window that's about to be
				 * mapped. */
{
    if(!(winPtr->flags & TK_ALREADY_DEAD)) {
	HWND hwnd = (HWND)winPtr->privatePtr;
	int state = SendMessage(hwnd, TK_STATE, -1, -1) - 1;

	if (state < 0 || state > 3) {
	    state = NormalState;
	}

	while (Tcl_DoOneEvent(TCL_IDLE_EVENTS)) {
	    /* empty body */
	}

	TkpWmSetState(winPtr, state);
	TkWmMapWindow(winPtr);
    }
    Tcl_Release((ClientData)winPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * TkpUseWindow --
 *
 *	This procedure causes a Tk window to use a given Windows handle for a
 *	window as its underlying window, rather than a new Windows window
 *	being created automatically. It is invoked by an embedded application
 *	to specify the window in which the application is embedded.
 *
 *	This procedure uses a simple attachment protocol by sending TK_INFO
 *	messages to the window to use with two sub messages:
 *
 *	    TK_CONTAINER_VERIFY - if a window handles this message, it should
 *		return either a (long)hwnd for a container or a -(long)hwnd
 *		for a non-container.
 *
 *	    TK_CONTAINER_ISAVAILABLE - a container window should return either
 *		a TRUE (non-zero) if it is available for use or a FALSE (zero)
 *		othersize.
 *
 *	The TK_INFO messages are required in order to verify if the window to
 *	use is a valid container. Without an id verification, an invalid
 *	window attachment may cause unexpected crashes/panics (bug 1096074).
 *	Additional sub messages may be definded/used in future for other
 *	needs.
 *
 *	We do not enforce the above protocol for the reason of backward
 *	compatibility. If the window to use is unable to handle TK_INFO
 *	messages (e.g., legacy Tk container applications before 8.5), a dialog
 *	box with a warning message pops up and the user is asked to confirm if
 *	the attachment should proceed. However, we may have to enforce it in
 *	future.
 *
 * Results:
 *	The return value is normally TCL_OK. If an error occurred (such as if
 *	the argument does not identify a legal Windows window handle or it is
 *	already in use or a cancel button is pressed by a user in confirming
 *	the use window as a Tk container) the return value is TCL_ERROR and an
 *	error message is left in the the interp's result if interp is not
 *	NULL.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
TkpUseWindow(
    Tcl_Interp *interp,		/* If not NULL, used for error reporting if
				 * string is bogus. */
    Tk_Window tkwin,		/* Tk window that does not yet have an
				 * associated X window. */
    const char *string)		/* String identifying an X window to use for
				 * tkwin; must be an integer value. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    int id;
    HWND hwnd;
/*
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
*/

/*
    if (winPtr->window != None) {
	Tcl_AppendResult(interp,
		"can't modify container after widget is created", NULL);
	return TCL_ERROR;
    }
*/

    if (strcmp(string, "") == 0) {
	if (winPtr->flags & TK_EMBEDDED) {
	    Tk_DetachEmbeddedWindow(winPtr, TRUE);
	}
	return TCL_OK;
    }

    if (Tcl_GetInt(interp, string, &id) != TCL_OK) {
	return TCL_ERROR;
    }
    hwnd = (HWND) id;
    if ((HWND)winPtr->privatePtr == hwnd) {
	return TCL_OK;
    }

    /*
     * Check if the window is a valid handle. If it is invalid, return
     * TCL_ERROR and potentially leave an error message in the interp's
     * result.
     */

    if (!IsWindow(hwnd)) {
	if (interp != NULL) {
	    Tcl_AppendResult(interp, "window \"", string,
		    "\" doesn't exist", NULL);
	}
	return TCL_ERROR;
    }

    id = SendMessage(hwnd, TK_INFO, TK_CONTAINER_VERIFY, 0);
    if (id == (long)hwnd) {
	if (!SendMessage(hwnd, TK_INFO, TK_CONTAINER_ISAVAILABLE, 0)) {
    	    Tcl_AppendResult(interp, "The container is already in use", NULL);
	    return TCL_ERROR;
	}
    } else if (id == -(long)hwnd) {
	Tcl_AppendResult(interp, "the window to use is not a Tk container",
		NULL);
	return TCL_ERROR;
    } else {
	/*
	 * Proceed if the user decide to do so because it can be a legacy
	 * container application. However we may have to return a TCL_ERROR in
	 * order to avoid bug 1096074 in future.
	 */

	char msg[256];

	sprintf(msg, "Unable to get information of window \"%.80s\".  Attach to this\nwindow may have unpredictable results if it is not a valid container.\n\nPress Ok to proceed or Cancel to abort attaching.", string);
	if (IDCANCEL == MessageBoxA(hwnd, msg, "Tk Warning",
		MB_OKCANCEL | MB_ICONWARNING)) {
    	    Tcl_SetResult(interp, "Operation has been canceled", TCL_STATIC);
	    return TCL_ERROR;
	}
    }

    Tk_DetachEmbeddedWindow(winPtr, FALSE);

    /*
     * Store the parent window in the platform private data slot so
     * TkWmMapWindow can use it when creating the wrapper window.
     */

    winPtr->privatePtr = (struct TkWindowPrivate*) hwnd;
    winPtr->flags |= TK_EMBEDDED;
    winPtr->flags &= ~(TK_MAPPED);

    /*
     * Preserve the winPtr and create an idle handler to map the embedded
     * window.
     */

    Tcl_Preserve((ClientData) winPtr);
    Tcl_DoWhenIdle((Tcl_IdleProc*) Tk_MapEmbeddedWindow, (ClientData) winPtr);

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpMakeContainer --
 *
 *	This procedure is called to indicate that a particular window will be
 *	a container for an embedded application. This changes certain aspects
 *	of the window's behavior, such as whether it will receive events
 *	anymore.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkpMakeContainer(
    Tk_Window tkwin)
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    Container *containerPtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

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

    Tk_MakeWindowExist(tkwin);
    containerPtr = (Container *) ckalloc(sizeof(Container));
    containerPtr->parentPtr = winPtr;
    containerPtr->parentHWnd = Tk_GetHWND(Tk_WindowId(tkwin));
    containerPtr->embeddedHWnd = NULL;
    containerPtr->embeddedPtr = NULL;
    containerPtr->embeddedMenuHWnd = NULL;
    containerPtr->nextPtr = tsdPtr->firstContainerPtr;
    tsdPtr->firstContainerPtr = containerPtr;
    winPtr->flags |= TK_CONTAINER;

    /*
     * Unlike in tkUnixEmbed.c, we don't make any requests for events in the
     * embedded window here. Now we just allow the embedding of another TK
     * application into TK windows. When the embedded window makes a request,
     * that will be done by sending to the container window a WM_USER message,
     * which will be intercepted by TkWinContainerProc.
     *
     * We need to get structure events of the container itself, though.
     */

    Tk_CreateEventHandler(tkwin, StructureNotifyMask,
	    ContainerEventProc, (ClientData) containerPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * TkWinEmbeddedEventProc --
 *
 *	This procedure is invoked by the Tk event dispatcher when various
 *	useful events are received for the *children* of a container window.
 *	It forwards relevant information, such as geometry requests, from the
 *	events into the container's application.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Depends on the event. For example, when ConfigureRequest events occur,
 *	geometry information gets set for the container window.
 *
 *----------------------------------------------------------------------
 */

LRESULT
TkWinEmbeddedEventProc(
    HWND hwnd,
    UINT message,
    WPARAM wParam,
    LPARAM lParam)
{
    int result = 1;
    Container *containerPtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    /*
     * Find the Container structure associated with the parent window.
     */

    for (containerPtr = tsdPtr->firstContainerPtr;
	    containerPtr && containerPtr->parentHWnd != hwnd;
	    containerPtr = containerPtr->nextPtr) {
	/* empty loop body */
    }

    if (containerPtr) {
	TkWindow *topwinPtr = NULL;
	if(Tk_IsTopLevel(containerPtr->parentPtr)) {
	    topwinPtr = containerPtr->parentPtr;
	}
	switch (message) {
	case TK_INFO:
	    /*
	     * An embedded window may send this message for container
	     * verification and availability before attach.
	     *
	     * wParam - a sub message
	     *
	     *	    TK_CONTAINER_ISAVAILABLE - if the container is available
	     *		for use?
	     *		result = 1 for yes and 0 for no;
	     *
	     *	    TK_CONTAINER_VERIFY - request the container to verify its
	     *		identification
	     *		result =  (long)hwnd if this window is a container
	     *			 -(long)hwnd otherwise
	     *
	     * lParam - N/A
	     */

	    switch(wParam) {
	    case TK_CONTAINER_ISAVAILABLE:
		result = containerPtr->embeddedHWnd == NULL? 1:0;
		break;
	    case TK_CONTAINER_VERIFY:
		result = (long)containerPtr->parentHWnd;
		break;
	    default:
		result = 0;
	    }
	    break;

	case TK_ATTACHWINDOW:
	    /*
	     * An embedded window (either from this application or from
	     * another application) is trying to attach to this container. We
	     * attach it only if this container is not yet containing any
	     * window.
	     *
	     * wParam - a handle of an embedded window
	     * lParam - N/A
	     *
	     * An embedded window may send this message with a wParam of NULL
	     * to test if a window is able to provide embedding service. The
	     * container returns its window handle for accepting the
	     * attachment and identifying itself or a zero for being already
	     * in use.
	     *
	     * Return value:
	     * 0    - the container is unable to be used.
	     * hwnd - the container is ready to be used.
	     */
	    if (containerPtr->embeddedHWnd == NULL) {
		if (wParam) {
		    TkWindow *winPtr = (TkWindow *)
			    Tk_HWNDToWindow((HWND) wParam);
		    if (winPtr) {
			winPtr->flags |= TK_BOTH_HALVES;
			containerPtr->embeddedPtr = winPtr;
			containerPtr->parentPtr->flags |= TK_BOTH_HALVES;
		    }
		    containerPtr->embeddedHWnd = (HWND)wParam;
		}
		result = (long)containerPtr->parentHWnd;
	    } else {
		result = 0;
	    }
	    break;

	case TK_DETACHWINDOW:
	    /*
	     * An embedded window notifies the container that it is detached.
	     * The container should clearn the related variables and redraw
	     * its window.
	     *
	     * wParam - N/A
	     * lParam - N/A
	     *
	     * Return value:
	     * 0	- the message is not processed.
	     * others	- the message is processed.
	     */

	    containerPtr->embeddedMenuHWnd = NULL;
	    containerPtr->embeddedHWnd = NULL;
	    containerPtr->parentPtr->flags &= ~TK_BOTH_HALVES;
	    if (topwinPtr) {
		TkWinSetMenu((Tk_Window) topwinPtr, 0);
	    }
	    InvalidateRect(hwnd, NULL, TRUE);
	    break;

	case TK_GEOMETRYREQ:
	    /*
	     * An embedded window requests a window size change.
	     *
	     * wParam - window width
	     * lParam - window height
	     *
	     * Return value:
	     * 0	- the message is not processed.
	     * others	- the message is processed.
	     */

	    EmbedGeometryRequest(containerPtr, (int)wParam, lParam);
	    break;

	case TK_RAISEWINDOW:
	    /*
	     * An embedded window requests to change its Z-order.
	     *
	     * wParam - a window handle as a z-order stack reference
	     * lParam - a flag of above-below: 0 - above; 1 or others: - below
	     *
	     * Return value:
	     * 0	- the message is not processed.
	     * others	- the message is processed.
	     */

	    TkWinSetWindowPos(GetParent(containerPtr->parentHWnd),
		    (HWND)wParam, (int)lParam);
	    break;

	case TK_GETFRAMEWID:
	    /*
	     * An embedded window requests to get the frame window's id.
	     *
	     * wParam - N/A
	     * lParam - N/A
	     *
	     * Return vlaue:
	     *
	     * A handle of the frame window. If it is not availble, a zero is
	     * returned.
	     */
	    if (topwinPtr) {
		result = (long)GetParent(containerPtr->parentHWnd);
	    } else {
		topwinPtr = containerPtr->parentPtr;
		while (!(topwinPtr->flags & TK_TOP_HIERARCHY)) {
		    topwinPtr = topwinPtr->parentPtr;
		}
		if (topwinPtr && topwinPtr->window) {
		    result = (long)GetParent(Tk_GetHWND(topwinPtr->window));
		} else {
		    result = 0;
		}
	    }
	    break;

	case TK_CLAIMFOCUS:
	    /*
	     * An embedded window requests a focus.
	     *
	     * wParam - a flag of forcing focus
	     * lParam - N/A
	     *
	     * Return value:
	     * 0    - the message is not processed
	     * 1    - the message is processed
	     */

	    if (!SetFocus(containerPtr->embeddedHWnd) && wParam) {
		/*
		 * forcing focus TBD
		 */
	    }
	    break;

	case TK_WITHDRAW:
	    /*
	     * An embedded window requests withdraw.
	     *
	     * wParam	- N/A
	     * lParam	- N/A
	     *
	     * Return value
	     * 0    - the message is not processed
	     * 1    - the message is processed
	     */

	    if (topwinPtr) {
		TkpWinToplevelWithDraw(topwinPtr);
	    } else {
		result = 0;
	    }
	    break;

	case TK_ICONIFY:
	    /*
	     * An embedded window requests iconification.
	     *
	     * wParam	- N/A
	     * lParam	- N/A
	     *
	     * Return value
	     * 0    - the message is not processed
	     * 1    - the message is processed
	     */

	    if (topwinPtr) {
		TkpWinToplevelIconify(topwinPtr);
	    } else {
		result = 0;
	    }
	    break;

	case TK_DEICONIFY:
	    /*
	     * An embedded window requests deiconification.
	     *
	     * wParam	- N/A
	     * lParam	- N/A
	     *
	     * Return value
	     * 0    - the message is not processed
	     * 1    - the message is processed
	     */
	    if (topwinPtr) {
		TkpWinToplevelDeiconify(topwinPtr);
	    } else {
		result = 0;
	    }
	    break;

	case TK_MOVEWINDOW:
	    /*
	     * An embedded window requests to move position if both wParam and
	     * lParam are greater or equal to 0.
	     *	    wParam - x value of the frame's upper left
	     *	    lParam - y value of the frame's upper left
	     *
	     * Otherwise an embedded window requests the current position
	     *
	     * Return value: an encoded window position in a 32bit long, i.e,
	     * ((x << 16) & 0xffff0000) | (y & 0xffff)
	     *
	     * Only a toplevel container may move the embedded.
	     */

	    result = TkpWinToplevelMove(containerPtr->parentPtr,
		    wParam, lParam);
	    break;

	case TK_OVERRIDEREDIRECT:
	    /*
	     * An embedded window request overrideredirect.
	     *
	     * wParam
	     *	0	- add a frame if there is no one
	     *  1	- remove the frame if there is a one
	     *  < 0	- query the current overrideredirect value
	     *
	     * lParam	- N/A
	     *
	     * Return value:
	     * 1 + the current value of overrideredirect if the container is a
	     * toplevel. Otherwise 0.
	     */
	    if (topwinPtr) {
		result = 1 + TkpWinToplevelOverrideRedirect(topwinPtr, wParam);
	    } else {
		result = 0;
	    }
	    break;

	case TK_SETMENU:
	    /*
	     * An embedded requests to set a menu.
	     *
	     * wParam	- a menu handle
	     * lParam	- a menu window handle
	     *
	     * Return value:
	     * 1    - the message is processed
	     * 0    - the message is not processed
	     */
	    if (topwinPtr) {
		containerPtr->embeddedMenuHWnd = (HWND)lParam;
		TkWinSetMenu((Tk_Window)topwinPtr, (HMENU)wParam);
	    } else {
		result = 0;
	    }
	    break;

	case TK_STATE:
	    /*
	     * An embedded window request set/get state services.
	     *
	     * wParam	- service directive
	     *	    0 - 3 for setting state
	     *		0 - withdrawn state
	     *		1 - normal state
	     *		2 - zoom state
	     *		3 - icon state
	     * others for gettting state
	     *
	     * lParam	- N/A
	     *
	     * Return value
	     * 1 + the current state or 0 if the container is not a toplevel
	     */

	    if (topwinPtr) {
		if (wParam <= 3) {
		    TkpWmSetState(topwinPtr, wParam);
		}
		result = 1+TkpWmGetState(topwinPtr);
	    } else {
		result = 0;
	    }
	    break;

	    /*
	     * Return 0 since the current Tk container implementation is
	     * unable to provide following services.
	     */
	default:
	    result = 0;
	    break;
	}
    } else {
	if ((message == TK_INFO) && (wParam == TK_CONTAINER_VERIFY)) {
	    /*
	     * Reply the message sender: this is not a Tk container
	     */

	    return -(long)hwnd;
	} else {
	    result = 0;
	}
    }

    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * EmbedGeometryRequest --
 *
 *	This procedure is invoked when an embedded application requests a
 *	particular size. It processes the request (which may or may not
 *	actually resize the window) and reflects the results back to the
 *	embedded application.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	If we deny the child's size change request, a Configure event is
 *	synthesized to let the child know that the size is the same as it used
 *	to be. Events get processed while we're waiting for the geometry
 *	managers to do their thing.
 *
 *----------------------------------------------------------------------
 */

void
EmbedGeometryRequest(
    Container *containerPtr,	/* Information about the container window. */
    int width, int height)	/* Size that the child has requested. */
{
    TkWindow *winPtr = containerPtr->parentPtr;

    /*
     * Forward the requested size into our geometry management hierarchy via
     * the container window. We need to send a Configure event back to the
     * embedded application even if we decide not to resize the window; to
     * make this happen, process all idle event handlers synchronously here
     * (so that the geometry managers have had a chance to do whatever they
     * want to do), and if the window's size didn't change then generate a
     * configure event.
     */

    Tk_GeometryRequest((Tk_Window)winPtr, width, height);

    if (containerPtr->embeddedHWnd != NULL) {
	while (Tcl_DoOneEvent(TCL_IDLE_EVENTS)) {
	    /* Empty loop body. */
	}

	SetWindowPos(containerPtr->embeddedHWnd, NULL, 0, 0,
		winPtr->changes.width, winPtr->changes.height, SWP_NOZORDER);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * ContainerEventProc --
 *
 *	This procedure is invoked by the Tk event dispatcher when various
 *	useful events are received for the container window.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Depends on the event. For example, when ConfigureRequest events occur,
 *	geometry information gets set for the container window.
 *
 *----------------------------------------------------------------------
 */

static void
ContainerEventProc(
    ClientData clientData,	/* Token for container window. */
    XEvent *eventPtr)		/* ResizeRequest event. */
{
    Container *containerPtr = (Container *)clientData;
    Tk_Window tkwin = (Tk_Window)containerPtr->parentPtr;

    if (eventPtr->type == ConfigureNotify) {
	/*
	 * Resize the embedded window, if there is any.
	 */

	if (containerPtr->embeddedHWnd) {
	    SetWindowPos(containerPtr->embeddedHWnd, NULL, 0, 0,
		    Tk_Width(tkwin), Tk_Height(tkwin), SWP_NOZORDER);
	}
    } else if (eventPtr->type == DestroyNotify) {
	/*
	 * The container is gone, remove it from the list.
	 */

	EmbedWindowDeleted(containerPtr->parentPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkpGetOtherWindow --
 *
 *	If both the container and embedded window are in the same process,
 *	this procedure will return either one, given the other.
 *
 * Results:
 *	If winPtr is a container, the return value is the token for the
 *	embedded window, and vice versa. If the "other" window isn't in this
 *	process, NULL is returned.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

TkWindow *
TkpGetOtherWindow(
    TkWindow *winPtr)		/* Tk's structure for a container or embedded
				 * window. */
{
    Container *containerPtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    for (containerPtr = tsdPtr->firstContainerPtr; containerPtr != NULL;
	    containerPtr = containerPtr->nextPtr) {
	if (containerPtr->embeddedPtr == winPtr) {
	    return containerPtr->parentPtr;
	} else if (containerPtr->parentPtr == winPtr) {
	    return containerPtr->embeddedPtr;
	}
    }
    return NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_GetEmbeddedHWnd --
 *
 *	This function returns the embedded window id.
 *
 * Results:
 *	If winPtr is a container, the return value is the HWND for the
 *	embedded window. Otherwise it returns NULL.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

HWND
Tk_GetEmbeddedHWnd(
    TkWindow *winPtr)
{
    Container *containerPtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    for (containerPtr = tsdPtr->firstContainerPtr; containerPtr != NULL;
	    containerPtr = containerPtr->nextPtr) {
	if (containerPtr->parentPtr == winPtr) {
	    return containerPtr->embeddedHWnd;
	}
    }
    return NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_GetEmbeddedMenuHWND --
 *
 *	This function returns the embedded menu window id.
 *
 * Results:
 *	If winPtr is a container, the return value is the HWND for the
 *	embedded menu window. Otherwise it returns NULL.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

HWND
Tk_GetEmbeddedMenuHWND(
    Tk_Window tkwin)
{
    TkWindow *winPtr = (TkWindow*)tkwin;
    Container *containerPtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    for (containerPtr = tsdPtr->firstContainerPtr; containerPtr != NULL;
	    containerPtr = containerPtr->nextPtr) {
	if (containerPtr->parentPtr == winPtr) {
	    return containerPtr->embeddedMenuHWnd;
	}
    }
    return NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpClaimFocus --
 *
 *	This procedure is invoked when someone asks or the input focus to be
 *	put on a window in an embedded application, but the application
 *	doesn't currently have the focus. It requests the input focus from the
 *	container application.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The input focus may change.
 *
 *----------------------------------------------------------------------
 */

void
TkpClaimFocus(
    TkWindow *topLevelPtr,	/* Top-level window containing desired focus
				 * window; should be embedded. */
    int force)			/* One means that the container should claim
				 * the focus if it doesn't currently have
				 * it. */
{
    HWND hwnd = GetParent(Tk_GetHWND(topLevelPtr->window));
    SendMessage(hwnd, TK_CLAIMFOCUS, (WPARAM) force, 0);
}

/*
 *----------------------------------------------------------------------
 *
 * TkpRedirectKeyEvent --
 *
 *	This procedure is invoked when a key press or release event arrives
 *	for an application that does not believe it owns the input focus.
 *	This can happen because of embedding; for example, X can send an event
 *	to an embedded application when the real focus window is in the
 *	container application and is an ancestor of the container. This
 *	procedure's job is to forward the event back to the application where
 *	it really belongs.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The event may get sent to a different application.
 *
 *----------------------------------------------------------------------
 */

void
TkpRedirectKeyEvent(
    TkWindow *winPtr,		/* Window to which the event was originally
				 * reported. */
    XEvent *eventPtr)		/* X event to redirect (should be KeyPress or
				 * KeyRelease). */
{
    /* not implemented */
}

/*
 *----------------------------------------------------------------------
 *
 * EmbedWindowDeleted --
 *
 *	This procedure is invoked when a window involved in embedding (as
 *	either the container or the embedded application) is destroyed. It
 *	cleans up the Container structure for the window.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	A Container structure may be freed.
 *
 *----------------------------------------------------------------------
 */

static void
EmbedWindowDeleted(
    TkWindow *winPtr)		/* Tk's information about window that was
				 * deleted. */
{
    Container *containerPtr, *prevPtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    /*
     * Find the Container structure for this window work. Delete the
     * information about the embedded application and free the container's
     * record. The main container may be null. [Bug #476176]
     */

    prevPtr = NULL;
    containerPtr = tsdPtr->firstContainerPtr;
    if (containerPtr == NULL) return;
    while (1) {
	if (containerPtr->embeddedPtr == winPtr) {
	    containerPtr->embeddedHWnd = NULL;
	    containerPtr->embeddedPtr = NULL;
	    break;
	}
	if (containerPtr->parentPtr == winPtr) {
	    SendMessage(containerPtr->embeddedHWnd, WM_CLOSE, 0, 0);
	    containerPtr->parentPtr = NULL;
	    containerPtr->embeddedPtr = NULL;
	    break;
	}
	prevPtr = containerPtr;
	containerPtr = containerPtr->nextPtr;
	if (containerPtr == NULL) {
	    return;
	}
    }
    if ((containerPtr->embeddedPtr == NULL)
	    && (containerPtr->parentPtr == NULL)) {
	if (prevPtr == NULL) {
	    tsdPtr->firstContainerPtr = containerPtr->nextPtr;
	} else {
	    prevPtr->nextPtr = containerPtr->nextPtr;
	}
	ckfree((char *) containerPtr);
    }
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */
@


1.36
log
@Eliminate tkpMenubuttonClass
make tkpButtonProcs CONST
fix gcc warnings: missing initializer
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkWinEmbed.c,v 1.35 2008/04/27 22:39:17 dkf Exp $
d303 1
a303 1
	if (IDCANCEL == MessageBox(hwnd, msg, "Tk Warning",
@


1.35
log
@Get rid of pre-C89-isms (esp. CONST vs const).
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkWinEmbed.c,v 1.34 2008/04/08 03:28:05 kennykb Exp $
d741 1
a741 1
		if (wParam >= 0 && wParam <= 3) {
@


1.34
log
@* tkDecls.h:     Reverted das's change of Tk's stubs pointers
* tkIntDecls.h:  from 'extern' to 'EXTERN'. Since the stubs pointer
* tkPlatDecls.h: is always linked statically, its wrong to import
                 or export it from a DLL, and the change causes
                 trouble for extensions that build with -DUSE_TK_STUBS.
* tkWinEmbed.c:  Removed #if 0 code. Trust the revision control system,
                 if you need it again, you can find it.
* tkWinSend.c:   Added conditional compilation to silence several
                 compiler warnings.
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkWinEmbed.c,v 1.33 2007/12/13 15:28:55 dgp Exp $
d107 1
a107 1
    CONST char **argv)
d235 1
a235 1
    CONST char *string)		/* String identifying an X window to use for
@


1.33
log
@merge stable branch onto HEAD
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkWinEmbed.c,v 1.31.2.1 2007/09/09 04:15:54 dgp Exp $
a47 2
static void		EmbeddedEventProc(ClientData clientData,
			    XEvent *eventPtr);
a389 33
#if 0
/*
 *----------------------------------------------------------------------
 *
 * EmbeddedEventProc --
 *
 *	This procedure is invoked by the Tk event dispatcher when various
 *	useful events are received for a window that is embedded in another
 *	application.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Our internal state gets cleaned up when an embedded window is
 *	destroyed.
 *
 *----------------------------------------------------------------------
 */

static void
EmbeddedEventProc(
    ClientData clientData,	/* Token for container window. */
    XEvent *eventPtr)		/* ResizeRequest event. */
{
    TkWindow *winPtr = (TkWindow *) clientData;

    if (eventPtr->type == DestroyNotify) {
	EmbedWindowDeleted(winPtr);
    }
}
#endif

@


1.33.2.1
log
@[Bug 2956548] TkpButtonSetDefaults only initializes one button type
Fix various gcc warnings, all backported from Tk 8.6
VC6++ does not have SPI_SETKEYBOARDCUES
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkWinEmbed.c,v 1.33 2007/12/13 15:28:55 dgp Exp $
d48 2
d392 33
@


1.32
log
@Assorted minor cleanups.
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkWinEmbed.c,v 1.31 2006/05/29 22:21:40 hobbs Exp $
@


1.31
log
@	* win/tkWinEmbed.c (TkpGetOtherWindow):   [Bug 1212056] do not panic
	* unix/tkUnixEmbed.c (TkpGetOtherWindow): if no window is found -
	* unix/tkUnixWm.c (Tk_CoordsToWindow, UpdateGeometryInfo): handle it
	in the caller
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkWinEmbed.c,v 1.30 2005/12/02 13:42:29 dkf Exp $
d243 1
d246 1
d250 2
a251 1
	Tcl_AppendResult(interp, "can't modify container after widget is created", NULL);
d321 1
a321 1
    winPtr->flags &= (~(TK_MAPPED));
d328 2
a329 2
    Tcl_Preserve((ClientData)winPtr);
    Tcl_DoWhenIdle(Tk_MapEmbeddedWindow,(ClientData)winPtr);
d392 1
d423 1
@


1.31.2.1
log
@merge updates from HEAD
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkWinEmbed.c,v 1.31 2006/05/29 22:21:40 hobbs Exp $
a242 1
/*
a244 1
*/
d248 1
a248 2
	Tcl_AppendResult(interp,
		"can't modify container after widget is created", NULL);
d318 1
a318 1
    winPtr->flags &= ~(TK_MAPPED);
d325 2
a326 2
    Tcl_Preserve((ClientData) winPtr);
    Tcl_DoWhenIdle((Tcl_IdleProc*) Tk_MapEmbeddedWindow, (ClientData) winPtr);
a388 1
#if 0
a418 1
#endif
@


1.30
log
@More fixes (mostly getting rid of excess spaces)
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkWinEmbed.c,v 1.29 2005/12/02 00:19:04 dkf Exp $
a933 1
    Tcl_Panic("TkpGetOtherWindow couldn't find window");
@


1.29
log
@ANSIfication
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkWinEmbed.c,v 1.28 2005/01/27 15:29:22 chengyemao Exp $
d77 1
a77 1
            Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
d81 2
a82 2
        nextPtr = tsdPtr->firstContainerPtr->nextPtr;
        ckfree((char *) tsdPtr->firstContainerPtr);
d244 1
a244 1
            Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
d261 1
a261 1
        return TCL_ERROR;
d275 1
a275 1
        if (interp != NULL) {
d278 2
a279 2
        }
        return TCL_ERROR;
d284 1
a284 1
        if (!SendMessage(hwnd, TK_INFO, TK_CONTAINER_ISAVAILABLE, 0)) {
d289 1
a289 1
        Tcl_AppendResult(interp, "the window to use is not a Tk container",
d293 10
a302 9
        /*
         * Proceed if the user decide to do so because it can be a legacy
         * container application. However we may have to return a TCL_ERROR in
         * order to avoid bug 1096074 in future.
         */

        char msg[256];
        sprintf(msg, "Unable to get information of window \"%s\".  Attach to this\nwindow may have unpredictable results if it is not a valid container.\n\nPress Ok to proceed or Cancel to abort attaching.", string);
        if (IDCANCEL == MessageBox(hwnd, msg, "Tk Warning",
d357 1
a357 1
            Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
d450 1
a450 1
            Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
d924 1
a924 1
            Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
d961 1
a961 1
            Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
d996 1
a996 1
            Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
d1095 1
a1095 1
            Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
@


1.28
log
@Flushed idle events before mapping an embedded window
@
text
@d1 1
a1 1
/* 
d11 2
a12 2
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
d14 1
a14 1
 * RCS: @@(#) $Id: tkWinEmbed.c,v 1.27 2005/01/18 15:19:28 chengyemao Exp $
d21 2
a22 2
 * application.  It keeps track of the container window and its
 * associated embedded window.
d26 11
a36 13
    HWND parentHWnd;			/* Windows HWND to the parent window */
    TkWindow *parentPtr;		/* Tk's information about the container
					 * or NULL if the container isn't
					 * in this process. */
    HWND embeddedHWnd;			/* Windows HWND to the embedded window
					 */
    TkWindow *embeddedPtr;		/* Tk's information about the embedded
					 * window, or NULL if the
					 * embedded application isn't in
					 * this process. */
    HWND embeddedMenuHWnd;		/* Tk's embedded menu window handler */
    struct Container *nextPtr;		/* Next in list of all containers in
					 * this process. */
d40 3
a42 2
    Container *firstContainerPtr;       /* First in list of all containers
					 * managed by this process.  */
d46 9
a54 10
static void		ContainerEventProc _ANSI_ARGS_((ClientData clientData,
			    XEvent *eventPtr));
static void		EmbeddedEventProc _ANSI_ARGS_((
			    ClientData clientData, XEvent *eventPtr));
static void		EmbedGeometryRequest _ANSI_ARGS_((
    			    Container*containerPtr, int width, int height));
static void		EmbedWindowDeleted _ANSI_ARGS_((TkWindow *winPtr));
static void		Tk_MapEmbeddedWindow _ANSI_ARGS_((TkWindow* winPtr));
HWND			Tk_GetEmbeddedHWnd _ANSI_ARGS_((TkWindow* winPtr));

d72 2
a73 1
void TkWinCleanupContainerList(void)
d76 1
a76 1
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *) 
d78 3
a80 4
    
    for (;
        tsdPtr->firstContainerPtr != (Container *) NULL;
        tsdPtr->firstContainerPtr = nextPtr) {
d105 5
a109 5
TkpTestembedCmd(clientData, interp, argc, argv)
    ClientData clientData;
    Tcl_Interp *interp;
    int argc;
    CONST char **argv;
d129 6
a134 4
static 
void Tk_DetachEmbeddedWindow(winPtr, detachFlag)
    TkWindow *winPtr;	    /* an embedded window */
    BOOL detachFlag;	    /* a flag of truely detaching */
d137 1
a137 2
    if(detachFlag)
    {
d147 3
a149 3
 *	This function is required for mapping an embedded window during
 *	idle.  The input winPtr must be preserved using Tcl_Preserve before
 *	call this function and will be released by this function.
d159 5
a163 4
static 
void Tk_MapEmbeddedWindow(winPtr)
    TkWindow *winPtr;		/* Top-level window that's about to
				 * be mapped. */
d168 2
a169 1
	if(state < 0 || state > 3) {
d171 7
a177 3
	} 
	while(Tcl_DoOneEvent(TCL_IDLE_EVENTS)); 
	TkpWmSetState(winPtr, state);	
d182 1
a182 1

d188 15
a202 16
 *	This procedure causes a Tk window to use a given Windows handle
 *	for a window as its underlying window, rather than a new Windows
 *	window being created automatically. It is invoked by an embedded
 *	application to specify the window in which the application is
 *	embedded.
 *
 *	This procedure uses a simple attachment protocol by sending 
 *	TK_INFO messages to the window to use with two sub messages:
 *
 *	    TK_CONTAINER_VERIFY - if a window handles this message,
 *		it should return either a (long)hwnd for a container or
 *		a -(long)hwnd for a non-container. 
 *
 *	    TK_CONTAINER_ISAVAILABLE - a container window should return 
 *		either a TRUE (non-zero) if it is available for use or
 *		a FALSE (zero) othersize.
d204 2
a205 2
 *	The TK_INFO messages are required in order to verify if the window 
 *	to use is a valid container. Without an id verification, an invalid 
d207 1
a207 1
 *	Additional sub messages may be definded/used in future for other 
d209 8
a216 8
 *	
 *	We do not enforce the above protocol for the reason of backward 
 *	compatibility. If the window to use is unable to handle TK_INFO 
 *	messages (e.g., legacy Tk container applications before 8.5),
 *	a dialog box with a warning message pops up and the user is asked 
 *	to confirm if the attachment should proceed.  However, we may have 
 *	to enforce it in future.
 *	
d218 6
a223 6
 *	The return value is normally TCL_OK. If an error occurred (such as
 *	if the argument does not identify a legal Windows window handle or
 *	it is already in use or a cancel button is pressed by a user in 
 *	confirming the use window as a Tk container) the return value is 
 *	TCL_ERROR and an error message is left in the the interp's result 
 *	if interp is not NULL.
d231 5
a235 5
int 
TkpUseWindow(interp, tkwin, string)
    Tcl_Interp *interp;		/* If not NULL, used for error reporting
				 * if string is bogus. */
    Tk_Window tkwin;		/* Tk window that does not yet have an
d237 2
a238 2
    CONST char *string;		/* String identifying an X window to use
				 * for tkwin;  must be an integer value. */
d243 1
a243 1
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *) 
d245 1
d247 2
a248 2
    if(winPtr->window != None) {
	Tcl_AppendResult(interp, "can't modify container after widget is created", (char *) NULL);
d252 3
a254 2
    if(strcmp(string, "") == 0) {
	if(winPtr->flags & TK_EMBEDDED) {
d264 3
a266 1
    if((HWND)winPtr->privatePtr == hwnd) return TCL_OK;
d275 3
a277 3
        if (interp != (Tcl_Interp *) NULL) {
            Tcl_AppendResult(interp, "window \"", string,
                    "\" doesn't exist", (char *) NULL);
d283 2
a284 2
    if(id == (long)hwnd) {
        if(!SendMessage(hwnd, TK_INFO, TK_CONTAINER_ISAVAILABLE, 0)) {
d288 4
a291 3
    } else if(id == -(long)hwnd) {
        Tcl_AppendResult(interp, "the window to use is not a Tk container", NULL);
	    return TCL_ERROR;
d294 3
a296 3
         * Proceed if the user decide to do so because it can be a legacy 
         * container application.  However we may have to return a TCL_ERROR 
         * in order to avoid bug 1096074 in future.
d298 1
d301 3
a303 2
        if(IDCANCEL == MessageBox(hwnd, msg, "Tk Warning", MB_OKCANCEL | MB_ICONWARNING)) {
    	    Tcl_SetResult(interp, "Operation has been canceled", TCL_STATIC); 
d320 4
a323 3
     * Preserve the winPtr and create an idle handler to 
     * map the embedded window
     */ 
d335 4
a338 4
 *	This procedure is called to indicate that a particular window will
 *	be a container for an embedded application. This changes certain
 *	aspects of the window's behavior, such as whether it will receive
 *	events anymore.
d350 2
a351 2
TkpMakeContainer(tkwin)
    Tk_Window tkwin;
d355 1
a355 1
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *) 
d357 1
a357 1
    
d359 2
a360 2
     * Register the window as a container so that, for example, we can
     * find out later if the embedded app. is in the same process.
d375 5
a379 6
     * Unlike in tkUnixEmbed.c, we don't make any requests for events
     * in the embedded window here.  Now we just allow the embedding
     * of another TK application into TK windows. When the embedded
     * window makes a request, that will be done by sending to the
     * container window a WM_USER message, which will be intercepted
     * by TkWinContainerProc.
d385 1
a385 1
	ContainerEventProc, (ClientData) containerPtr);
d394 2
a395 2
 *	useful events are received for a window that is embedded in
 *	another application.
d408 3
a410 3
EmbeddedEventProc(clientData, eventPtr)
    ClientData clientData;		/* Token for container window. */
    XEvent *eventPtr;			/* ResizeRequest event. */
d424 4
a427 5
 *	This procedure is invoked by the Tk event dispatcher when
 *	various useful events are received for the *children* of a
 *	container window. It forwards relevant information, such as
 *	geometry requests, from the events into the container's
 *	application.
d433 2
a434 2
 *	Depends on the event.  For example, when ConfigureRequest events
 *	occur, geometry information gets set for the container window.
d440 5
a444 5
TkWinEmbeddedEventProc(hwnd, message, wParam, lParam)
    HWND hwnd;
    UINT message;
    WPARAM wParam;
    LPARAM lParam;
d448 1
a448 1
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *) 
d467 4
a470 3
	    case TK_INFO:
	    /* An embedded window may send this message for container
	     * verification and availability before attach. 
d474 2
a475 2
	     *	    TK_CONTAINER_ISAVAILABLE - if the container is 
	     *		available for use?
d478 2
a479 2
	     *	    TK_CONTAINER_VERIFY - request the container to
	     *		verify its identification
d485 1
d487 1
a487 1
		case TK_CONTAINER_ISAVAILABLE:
d490 1
a490 2

		case TK_CONTAINER_VERIFY:
d493 1
a493 2
		
		default:
d498 5
a502 4
	    case TK_ATTACHWINDOW:
	    /* An embedded window (either from this application or from
	     * another application) is trying to attach to this container.
	     * We attach it only if this container is not yet containing any
d509 4
a512 3
	     * to test if a window is able to provide embedding service. The 
	     * container returns its window handle for accepting the attachment 
	     * and identifying itself or a zero for being already in use.
d516 1
a516 1
	     * hwnd - the container is ready to be used. 
d519 4
a522 3
		if(wParam) {
		    TkWindow* winPtr = (TkWindow*)Tk_HWNDToWindow((HWND)wParam);
		    if(winPtr) {
d529 1
a529 1
		result =  (long)containerPtr->parentHWnd;
d535 3
a537 2
	    case TK_DETACHWINDOW:
	    /* An embedded window notifies the container that it is detached.
d540 1
a540 1
	     * 
d548 1
d552 3
a554 1
	    if(topwinPtr) TkWinSetMenu((Tk_Window)topwinPtr, 0);
d558 3
a560 2
	    case TK_GEOMETRYREQ:
	    /* An embedded window requests a window size change.
d569 1
d573 5
a577 4
	    case TK_RAISEWINDOW:
	    /* An embedded window requests to change its Z-order
	     * 
	     * wParam - a window handle as a z-order stack reference 
d579 1
a579 1
	     * 
d584 3
a586 1
	    TkWinSetWindowPos(GetParent(containerPtr->parentHWnd), (HWND)wParam, (int)lParam);
d589 3
a591 2
	    case TK_GETFRAMEWID:
	    /* An embedded window requests to get the frame window's id
d598 2
a599 2
	     * A handle of the frame window. If it is not availble, a 
	     * zeor is returned.
d601 1
a601 1
	    if(topwinPtr) {
d608 1
a608 1
		if(topwinPtr && topwinPtr->window) {
d616 5
a620 4
	    case TK_CLAIMFOCUS:
	    /* An embedded window requests a focus
	     * 
	     * wParam - a flag of forcing focus 
d627 2
a628 1
	    if(!SetFocus(containerPtr->embeddedHWnd) && wParam) {
d635 4
a638 3
	    case TK_WITHDRAW:
	    /* An embedded window requests withdraw
	     * 
d646 2
a647 1
	    if(topwinPtr) 
d649 1
a649 1
	    else
d651 1
d654 4
a657 3
	    case TK_ICONIFY:
	    /* An embedded window requests iconification
	     * 
d665 2
a666 1
	    if(topwinPtr) 
d668 1
a668 1
	    else
d670 1
d673 4
a676 3
	    case TK_DEICONIFY:
	    /* An embedded window requests deiconification
	     * 
d684 1
a684 1
	    if(topwinPtr) 
d686 1
a686 1
	    else
d688 1
d691 4
a694 3
	    case TK_MOVEWINDOW:
	    /* An embedded window requests to move position if
	     * both wParam and lParam are greater or equal to 0.
d698 4
a701 2
	     * Otherwise an embedded window requests the current 
	     * position
a702 3
	     * Return value: an encoded window position in a 32bit long, 
	     * i.e, ((x << 16) & 0xffff0000) | (y & 0xffff)
	     * 
d705 3
a707 1
	    result = TkpWinToplevelMove(containerPtr->parentPtr, wParam, lParam);
d710 3
a712 2
	    case TK_OVERRIDEREDIRECT:
	    /* An embedded window request overrideredirect.
d722 2
a723 2
	     * 1 + the current value of overrideredirect if the container is
	     * a toplevel.  Otherwise 0.
d725 2
a726 2
	    if(topwinPtr) {
		result = 1+TkpWinToplevelOverrideRedirect(topwinPtr, wParam);
d732 3
a734 2
	    case TK_SETMENU:
	    /* An embedded requests to set a menu
d743 1
a743 1
	    if(topwinPtr) {
d751 3
a753 2
	    case TK_STATE:
	    /* An embedded window request set/get state services
d768 3
a770 2
	    if(topwinPtr) {
		if(wParam >= 0 && wParam <= 3) {
d780 2
a781 3
	     * Return 0 since the current Tk container implementation 
	     * is unable to provide following services.
	     *  
d783 2
a784 2
	    default:
	    result = 0;  
d788 1
a788 1
	if(message == TK_INFO && wParam == TK_CONTAINER_VERIFY) {
d792 1
d807 4
a810 4
 *	This procedure is invoked when an embedded application requests
 *	a particular size.  It processes the request (which may or may
 *	not actually resize the window) and reflects the results back
 *	to the embedded application.
d816 4
a819 4
 *	If we deny the child's size change request, a Configure event
 *	is synthesized to let the child know that the size is the same
 *	as it used to be.  Events get processed while we're waiting for
 *	the geometry managers to do their thing.
d825 3
a827 3
EmbedGeometryRequest(containerPtr, width, height)
    Container *containerPtr;	/* Information about the container window. */
    int width, height;		/* Size that the child has requested. */
d829 2
a830 2
    TkWindow * winPtr = containerPtr->parentPtr;
    
d832 7
a838 7
     * Forward the requested size into our geometry management hierarchy
     * via the container window.  We need to send a Configure event back
     * to the embedded application even if we decide not to resize
     * the window;  to make this happen, process all idle event handlers
     * synchronously here (so that the geometry managers have had a
     * chance to do whatever they want to do), and if the window's size
     * didn't change then generate a configure event.
d840 1
d848 2
a849 2
	SetWindowPos(containerPtr->embeddedHWnd, NULL,
	    0, 0, winPtr->changes.width, winPtr->changes.height, SWP_NOZORDER);
d858 2
a859 2
 *	This procedure is invoked by the Tk event dispatcher when
 *	various useful events are received for the container window.
d865 2
a866 2
 *	Depends on the event.  For example, when ConfigureRequest events
 *	occur, geometry information gets set for the container window.
d872 3
a874 3
ContainerEventProc(clientData, eventPtr)
    ClientData clientData;		/* Token for container window. */
    XEvent *eventPtr;			/* ResizeRequest event. */
d880 4
a883 1
	/* Resize the embedded window, if there is any */
d885 2
a886 2
	    SetWindowPos(containerPtr->embeddedHWnd, NULL,
	        0, 0, Tk_Width(tkwin), Tk_Height(tkwin), SWP_NOZORDER);
d889 4
a892 1
	/* The container is gone, remove it from the list */
d902 2
a903 2
 *	If both the container and embedded window are in the same
 *	process, this procedure will return either one, given the other.
d907 2
a908 2
 *	embedded window, and vice versa.  If the "other" window isn't in
 *	this process, NULL is returned.
d917 3
a919 3
TkpGetOtherWindow(winPtr)
    TkWindow *winPtr;		/* Tk's structure for a container or
				 * embedded window. */
d922 1
a922 1
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *) 
d955 2
a956 2
Tk_GetEmbeddedHWnd(winPtr)
    TkWindow *winPtr;
d959 1
a959 1
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *) 
d989 2
a990 2
Tk_GetEmbeddedMenuHWND(tkwin)
    Tk_Window tkwin;
d994 1
a994 1
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *) 
d1011 4
a1014 4
 *	This procedure is invoked when someone asks or the input focus
 *	to be put on a window in an embedded application, but the
 *	application doesn't currently have the focus.  It requests the
 *	input focus from the container application.
d1026 6
a1031 6
TkpClaimFocus(topLevelPtr, force)
    TkWindow *topLevelPtr;		/* Top-level window containing desired
					 * focus window; should be embedded. */
    int force;				/* One means that the container should
					 * claim the focus if it doesn't
					 * currently have it. */
d1042 7
a1048 7
 *	This procedure is invoked when a key press or release event
 *	arrives for an application that does not believe it owns the
 *	input focus.  This can happen because of embedding; for example,
 *	X can send an event to an embedded application when the real
 *	focus window is in the container application and is an ancestor
 *	of the container.  This procedure's job is to forward the event
 *	back to the application where it really belongs.
d1060 2
a1061 2
TkpRedirectKeyEvent(winPtr, eventPtr)
    TkWindow *winPtr;		/* Window to which the event was originally
d1063 2
a1064 2
    XEvent *eventPtr;		/* X event to redirect (should be KeyPress
				 * or KeyRelease). */
d1074 3
a1076 3
 *	This procedure is invoked when a window involved in embedding
 *	(as either the container or the embedded application) is
 *	destroyed.  It cleans up the Container structure for the window.
d1088 3
a1090 3
EmbedWindowDeleted(winPtr)
    TkWindow *winPtr;		/* Tk's information about window that
				 * was deleted. */
d1093 1
a1093 1
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *) 
d1097 1
a1097 1
     * Find the Container structure for this window work.  Delete the
d1099 1
a1099 2
     * record.
     * The main container may be null. [Bug #476176]
d1133 8
@


1.27
log
@Minor change for correct initial embeddedMenuHwnd
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkWinEmbed.c,v 1.26 2005/01/17 07:08:51 chengyemao Exp $
d171 1
@


1.26
log
@Simplified TkpUseWindow; got rid of unnecessary code for saving an embedded window info in a container struct; stopped using a destruction event handler for an embedded window since it has nothing to do
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkWinEmbed.c,v 1.25 2005/01/16 00:23:12 chengyemao Exp $
d356 1
@


1.25
log
@Added TK_INFO message for use in an embedded window attachment protocol; modified TkpUseWindow to allow to attach to a legacy container with a warning; modified some return values of messages from an embedded window to differentiate a case of unprocessed
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkWinEmbed.c,v 1.24 2005/01/12 04:30:19 chengyemao Exp $
d119 27
d156 1
a156 1
 *	None.
d160 2
a161 1
static void Tk_MapEmbeddedWindow(winPtr)
d166 6
a235 1
    TkWindow *usePtr;
a237 1
    Container *containerPtr;
d248 1
a248 3
	    TkpWinToplevelDetachWindow(winPtr);
	    if(winPtr->flags & TK_TOP_LEVEL)
		TkpWinToplevelOverrideRedirect(winPtr, 0);
d296 1
a296 1
    TkpWinToplevelDetachWindow(winPtr);    
a303 42

    /*
     * Create an event handler to clean up the Container structure when
     * tkwin is eventually deleted.
     */

    Tk_CreateEventHandler(tkwin, StructureNotifyMask, EmbeddedEventProc,
	    (ClientData) winPtr);
    
    /*
     * Save information about the container and the embedded window
     * in a Container structure.  If there is already an existing
     * Container structure, it means that both container and embedded
     * app. are in the same process.
     */

    for (containerPtr = tsdPtr->firstContainerPtr; 
            containerPtr != NULL; containerPtr = containerPtr->nextPtr) {
	if (containerPtr->parentHWnd == hwnd) {
	    winPtr->flags |= TK_BOTH_HALVES;
	    containerPtr->parentPtr->flags |= TK_BOTH_HALVES;
	    break;
	}
    }
    if (containerPtr == NULL) {
	containerPtr = (Container *) ckalloc(sizeof(Container));
	containerPtr->parentPtr = NULL;
	containerPtr->parentHWnd = hwnd;
	containerPtr->nextPtr = tsdPtr->firstContainerPtr;
	tsdPtr->firstContainerPtr = containerPtr;
    }

    /*
     * embeddedHWnd is not created yet. It will be created by TkWmMapWindow(),
     * which will send a TK_ATTACHWINDOW to the container window.
     * TkWinEmbeddedEventProc will process this message and set the embeddedHWnd
     * variable
     */

    containerPtr->embeddedPtr = winPtr;
    containerPtr->embeddedHWnd = NULL;

d505 9
a513 1
		containerPtr->embeddedHWnd = (HWND)wParam;
d1067 1
d1073 1
a1073 1
	    Tcl_Panic("EmbedWindowDeleted couldn't find window");
@


1.24
log
@A better way to map an embbedded window
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkWinEmbed.c,v 1.23 2005/01/12 02:58:29 chengyemao Exp $
d55 1
d154 23
a176 9
 *	This procesure sends a TK_ATTACHWINDOW message to the window to 
 *	use. The returned value is either 0 (the window to use is already 
 *	in use or unable to be used as a container) or the hwnd of the 
 *	window to use (the window to use is ready to serve as a container) 
 *	or other values	(the window to use needs to be confirmed since 
 *	this protocol was not used before Tk85). This protocol is required
 *	in order to verify if the window to use is a valid container.
 *	Without an id verification, an invalid window attachment may cause
 *	unexpected crashes/panics (see bug # 1096074).
d243 4
a246 5
    usePtr = (TkWindow *) Tk_HWNDToWindow(hwnd);
    if (usePtr != NULL) {
        if (!(usePtr->flags & TK_CONTAINER)) {
	    Tcl_AppendResult(interp, "window \"", usePtr->pathName,
                    "\" doesn't have -container option set", (char *) NULL);
d249 13
a261 8
    } 

    id = SendMessage(hwnd, TK_ATTACHWINDOW, 0, 0);
    if(id == 0 || id != (long)hwnd) {
	char msg[256];
	if(id == 0) {
	    sprintf(msg, "The window \"%s\" is unable to be or has already been used as a container.", string);
	    Tcl_SetResult(interp, msg, TCL_VOLATILE);
a262 6
	} else {
	    sprintf(msg, "The window \"%s\" failed to identify itself as a Tk container.\nPress Ok to proceed or Cancel to abort attaching.", string);
	    if(IDCANCEL == MessageBox(hwnd, msg, "Tk Warning", MB_OKCANCEL | MB_ICONWARNING)) {
	        Tcl_SetResult(interp, "Operation has been canceled", TCL_STATIC); 
	        return TCL_ERROR;
	    }
d294 1
a294 4
	    containerPtr->parentPtr = usePtr;
	    if(usePtr) {
		containerPtr->parentPtr->flags |= TK_BOTH_HALVES;
	    }
d467 31
d688 2
a689 2
	     * the current value of overrideredirect if the container is
	     * a toplevel.  Otherwise -1.
d692 1
a692 1
		result = TkpWinToplevelOverrideRedirect(topwinPtr, wParam);
d694 1
a694 1
		result = -1;
d730 1
a730 1
	     * the current state or -1 if the container is not a toplevel
d736 1
a736 1
		result = TkpWmGetState(topwinPtr);
d738 1
a738 1
		result = -1;
d752 8
a759 1
	result = 0;
@


1.23
log
@Minor bug fix to support embedding/embedded
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkWinEmbed.c,v 1.22 2005/01/10 15:35:30 chengyemao Exp $
d54 1
d118 27
d309 6
a314 5
    if(winPtr->flags & TK_TOP_LEVEL) {
	// call this function in idle may crash because the window
	// may be destroyed in script
	TkWmMapWindow(winPtr);
    }
@


1.22
log
@corrected return values and added comments for embedded window messages
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkWinEmbed.c,v 1.21 2005/01/09 19:17:23 chengyemao Exp $
d174 2
a175 1
	    TkpWinToplevelOverrideRedirect(winPtr, 0);
d281 5
a285 1
    Tcl_DoWhenIdle(TkWmMapWindow, (ClientData)winPtr);
@


1.21
log
@Modified to support a container of either a toplevel or a frame
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkWinEmbed.c,v 1.20 2005/01/09 18:28:06 chengyemao Exp $
d171 1
a171 1
    if(stricmp(string, "") == 0) {
d430 1
d436 4
d450 11
d469 2
a470 1
	    /*
d473 4
d478 1
a478 1
	    EmbedGeometryRequest(containerPtr, (int) wParam, lParam);
d482 2
a483 1
	    /*
d486 4
d495 23
a517 1
	    result = (long)GetParent(containerPtr->parentHWnd);
d521 2
a522 1
	    /* 
d524 5
d538 13
a550 1
	    if(topwinPtr) TkpWinToplevelWithDraw(topwinPtr);
d554 13
a566 1
	    if(topwinPtr) TkpWinToplevelIconify(topwinPtr);
d570 13
a582 1
	    if(topwinPtr) TkpWinToplevelDeiconify(topwinPtr);
d586 12
a597 3
	    /*
	     *	wParam - x value of the frame's upper left;
	     *	lParam - y value of the frame's upper left;
d599 1
a599 3
	    if(topwinPtr) {
	        result = TkpWinToplevelMove(topwinPtr, wParam, lParam);
	    }
d603 13
d618 2
d624 9
d636 2
a637 1
		result = 1;
d642 14
a655 5
	    /*
	     *	0 - normal state
	     *	1 - withdrawn state
	     *	2 - zoom state
	     *	3 - icon state
d662 2
d666 1
a671 1

@


1.20
log
@Changed to make platform implementation ready for a toplevel -use option; completed a full toplevel -use option configuration for Windows
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkWinEmbed.c,v 1.19 2005/01/07 15:18:03 chengyemao Exp $
d418 4
d448 1
a448 1
	    TkWinSetMenu((Tk_Window)containerPtr->parentPtr, 0);
d484 1
a484 1
	    TkpWinToplevelWithDraw(containerPtr->parentPtr);
d488 1
a488 1
	    TkpWinToplevelIconify(containerPtr->parentPtr);
d492 1
a492 1
	    TkpWinToplevelDeiconify(containerPtr->parentPtr);
d500 3
a502 1
	    result = TkpWinToplevelMove(containerPtr->parentPtr, wParam, lParam);
d506 3
a508 1
	    result = TkpWinToplevelOverrideRedirect(containerPtr->parentPtr, wParam);
d512 5
a516 3
	    containerPtr->embeddedMenuHWnd = (HWND)lParam;
	    TkWinSetMenu((Tk_Window)containerPtr->parentPtr, (HMENU)wParam);
	    result = 1;
d526 5
a530 2
	    if(wParam >= 0 && wParam <= 3) {
		TkpWmSetState(containerPtr->parentPtr, wParam);
a531 1
	    result = TkpWmGetState(containerPtr->parentPtr);
@


1.19
log
@Implemented TK_STAT message to support {wm state} for embedded window
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkWinEmbed.c,v 1.18 2005/01/07 01:39:24 chengyemao Exp $
d165 13
d183 1
d224 2
d252 4
a255 1
	    containerPtr->parentPtr->flags |= TK_BOTH_HALVES;
d280 2
d444 1
@


1.18
log
@Removed unnecsssary panic from TkpUseWindow and forced redraw container after the embedded detached
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkWinEmbed.c,v 1.17 2005/01/05 02:46:59 chengyemao Exp $
d487 12
@


1.17
log
@Made the remarks of TkpUseWindow clearer regarding the embedding/embedded attachment protocol
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkWinEmbed.c,v 1.16 2004/12/28 08:45:31 chengyemao Exp $
a165 4
    if (winPtr->window != None) {
        Tcl_Panic("TkpUseWindow: Already assigned a window");
    }

d423 1
@


1.16
log
@Modified to support embedded menu widget
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkWinEmbed.c,v 1.15 2004/12/20 15:30:43 chengyemao Exp $
d127 8
a134 4
 *	in use) or the hwnd of the window to use (the window to use is 
 *	ready to serve as a container) or other values (the window to use 
 *	needs to be confirmed since this protocol was not used before Tk85).
 *
d202 1
a202 1
	    sprintf(msg, "The window \"%s\" is either unable or already to be used as a container", string);
@


1.15
log
@implemented overrideredirect for an embedded; corrected incorrect frame upper left x and y of an embedded toplevel
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkWinEmbed.c,v 1.14 2004/12/20 01:13:12 chengyemao Exp $
d36 1
d420 1
d480 7
a486 1
	     /*
d664 35
@


1.14
log
@featrue implementation of Tk container and embedded including TK_MOVEWINDOW, TK_ICONIFY, TK_DEICONIFY, TK_WITHDRAW; replaced TK_TITLE with TK_GETFRAMEWID for setting container's title across process boundary; bug fix in wm overrideredirect for TK_EMBEDDED window
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkWinEmbed.c,v 1.13 2004/12/19 18:14:26 chengyemao Exp $
d474 4
d626 34
@


1.13
log
@Bug fix and feature implementation of embedded/embedding Tk
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkWinEmbed.c,v 1.12 2004/12/18 20:35:16 chengyemao Exp $
a17 1
extern TkWinProcs *tkWinProcs;
d53 1
d197 1
a197 1
	    sprintf(msg, "The window \"%s\" is already in use", string);
d439 2
a440 5
	    case TK_TITLE:
	    /*
	     * lParam - a pointer to a unicode string
	     */
	    (*tkWinProcs->setWindowText)(GetParent(containerPtr->parentHWnd), (LPCTSTR)lParam);
d454 4
a457 5
	    /*
	     * Return 0 since the current Tk container implementation 
	     * is unable to provide these services.
	     *  
	     */
d459 3
d463 1
a463 2
	    case TK_WITHDRAW:
	    result = 0;  
d471 10
@


1.12
log
@Bug fix [222677]
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkWinEmbed.c,v 1.11 2004/12/17 14:17:54 chengyemao Exp $
d18 1
a18 1

d124 6
d132 5
a136 3
 *	if the argument does not identify a legal Windows window handle),
 *	the return value is TCL_ERROR and an error message is left in the
 *	the interp's result if interp is not NULL.
d191 16
d380 1
d402 7
d412 1
d414 1
a414 1
		return 0;
d424 4
d430 45
d476 2
d479 2
a480 1
    return 1;
@


1.11
log
@bug fix (842945,831627)
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkWinEmbed.c,v 1.10 2004/01/13 02:06:02 davygrvy Exp $
d370 19
a388 3
    if (containerPtr == NULL) {
	Tcl_Panic("TkWinContainerProc couldn't find Container record");
    }
d390 3
a392 11
    switch (message) {
	case TK_ATTACHWINDOW:
	/* An embedded window (either from this application or from
	 * another application) is trying to attach to this container.
	 * We attach it only if this container is not yet containing any
	 * window.
	 */
	if (containerPtr->embeddedHWnd == NULL) {
	    containerPtr->embeddedHWnd = (HWND)wParam;
	} else {
	    return 0;
a393 10
	break;

	case TK_DETACHWINDOW:
	containerPtr->embeddedHWnd = NULL;
	containerPtr->parentPtr->flags &= ~TK_BOTH_HALVES;
	break;

	case TK_GEOMETRYREQ:
	EmbedGeometryRequest(containerPtr, (int) wParam, lParam);
	break;
d633 1
@


1.10
log
@	* generic/tk3d.c:	All uses of 'panic' (the macro) changed
	* generic/tkBind.c:	to 'Tcl_Panic' (the function).  The #define
	* generic/tkBitmap.c:	of panic in tcl.h clearly states it is
	* generic/tkCanvArc.c:	deprecated in the comments.
	* generic/tkCanvBmap.c: [Tcl Patch 865264]
	* generic/tkCanvImg.c:
	* generic/tkCanvLine.c:
	* generic/tkCanvPoly.c:
	* generic/tkCanvText.c:
	* generic/tkCanvWind.c:
	* generic/tkColor.c:
	* generic/tkConfig.c:
	* generic/tkCursor.c:
	* generic/tkError.c:
	* generic/tkEvent.c:
	* generic/tkFocus.c:
	* generic/tkFont.c:
	* generic/tkFrame.c:
	* generic/tkGC.c:
	* generic/tkGrid.c:
	* generic/tkImgBmap.c:
	* generic/tkImgPhoto.c:
	* generic/tkImgUtil.c:
	* generic/tkMenu.c:
	* generic/tkObj.c:
	* generic/tkPack.c:
	* generic/tkPlace.c:
	* generic/tkRectOval.c:
	* generic/tkSelect.c:
	* generic/tkText.c:
	* generic/tkTextBTree.c:
	* generic/tkTextDisp.c:
	* generic/tkTextImage.c:
	* generic/tkTextIndex.c:
	* generic/tkTextMark.c:
	* generic/tkTextWind.c:
	* generic/tkVisual.c:
	* generic/tkWindow.c:
	* mac/tkMacAppInit.c:
	* mac/tkMacAppearanceStubs.c:
	* mac/tkMacButton.c:
	* mac/tkMacDraw.c:
	* mac/tkMacEmbed.c:
	* mac/tkMacFont.c:
	* mac/tkMacInit.c:
	* mac/tkMacMenus.c:
	* mac/tkMacPort.h:
	* mac/tkMacSubwindows.c:
	* mac/tkMacWm.c:
	* mac/tkMacXStubs.c:
	* macosx/tkMacOSXEmbed.c:
	* macosx/tkMacOSXFont.c:
	* macosx/tkMacOSXMenus.c:
	* macosx/tkMacOSXNotify.c:
	* macosx/tkMacOSXPort.h:
	* macosx/tkMacOSXSubwindows.c:
	* macosx/tkMacOSXWm.c:
	* macosx/tkMacOSXXStubs.c:
	* unix/tkUnix3d.c:
	* unix/tkUnixColor.c:
	* unix/tkUnixEmbed.c:
	* unix/tkUnixEvent.c:
	* unix/tkUnixFocus.c:
	* unix/tkUnixFont.c:
	* unix/tkUnixSelect.c:
	* unix/tkUnixSend.c:
	* unix/tkUnixWm.c:
	* win/tkWin3d.c:
	* win/tkWinButton.c:
	* win/tkWinColor.c:
	* win/tkWinDialog.c:
	* win/tkWinDraw.c:
	* win/tkWinEmbed.c:
	* win/tkWinFont.c:
	* win/tkWinPixmap.c:
	* win/tkWinPointer.c:
	* win/tkWinScrlbr.c:
	* win/tkWinWm.c:
	* win/tkWinX.c:
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkWinEmbed.c,v 1.9 2003/12/21 23:50:13 davygrvy Exp $
a46 2
static void		CleanupContainerList _ANSI_ARGS_((
    			    ClientData clientData));
d58 1
a58 1
 * CleanupContainerList --
d71 1
a71 4
	/* ARGSUSED */
static void
CleanupContainerList(clientData)
    ClientData clientData;
a198 9

    /*
     * If this is the first container, register an exit handler so that
     * things will get cleaned up at finalization.
     */

    if (tsdPtr->firstContainerPtr == (Container *) NULL) {
        TkCreateExitHandler(CleanupContainerList, (ClientData) NULL);
    }
a265 9

    /*
     * If this is the first container, register an exit handler so that
     * things will get cleaned up at finalization.
     */

    if (tsdPtr->firstContainerPtr == (Container *) NULL) {
        TkCreateExitHandler(CleanupContainerList, (ClientData) NULL);
    }
d375 1
a375 1
      case TK_ATTACHWINDOW:
d386 1
d388 3
d392 2
a393 1
      case TK_GEOMETRYREQ:
a476 3
	if (containerPtr->embeddedPtr == NULL) {
	    return;
	}
@


1.9
log
@	* generic/tkEvent.c:  Added three new functions: TkCreateExitHandler,
	* generic/tkInt.h:    TkDeleteExitHandler, and TkFinalize.  This adds
	* generic/tkMenu.c:   an insertion point so Tk's exit handlers can be
	* generic/tkWindow.c: called on their own from tk85.dll's DllMain
	* mac/tkMacButton.c:  for DLL_PROCESS_DETACH.  These are private to
	* unix/tkUnixEvent.c: the binary and not exported.  It is possible
	* win/tkWin32Dll.c:   the Windows OS can unload Tk _prior_ to Tcl
	* win/tkWinEmbed.c:   under some conditions such as ExitProcess().
	* win/tkWinMenu.c:    This avoids a dangling pointer problem when Tcl
	* win/tkWinX.c:	      does Tcl_Finalize after Tk has been unloaded.
	* win/winMain.c:      DllMain's DLL_PROCESS_DETACH now protected with
			      SEH as DeleteWindowsExitProc is causing an
			      exception of its own under some teardown
			      conditions.  AT&T assembly syntax has not been
			      added for MinGW yet.  [Tcl Patch 858493]
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkWinEmbed.c,v 1.8 2003/12/13 01:07:35 davygrvy Exp $
d159 1
a159 1
        panic("TkpUseWindow: Already assigned a window");
d545 1
a545 1
    panic("TkpGetOtherWindow couldn't find window");
d662 1
a662 1
	    panic("EmbedWindowDeleted couldn't find window");
@


1.8
log
@(TkWinEmbeddedEventProc) : for loop dereferences containerPtr but can't
get to the if (containerPtr == NULL) test due to the unhandled read
memory exception for when it really is NULL.
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkWinEmbed.c,v 1.7 2002/08/05 04:30:41 dgp Exp $
d211 1
a211 1
        Tcl_CreateExitHandler(CleanupContainerList, (ClientData) NULL);
d287 1
a287 1
        Tcl_CreateExitHandler(CleanupContainerList, (ClientData) NULL);
@


1.7
log
@Applied companion patch for Tcl Patch 585105,
updating Tk to use Tcl 8.4's fully CONST-ified
interface, and fully CONSTifying Tk at the
same time.

This patch includes purging Tk of its last
direct access to interp->result.  [Bug 589853]

The substantial changes include copying
event sequence strings into Tcl_DStrings
in tkBind.c, and copying [text] indices into
Tcl_DStrings because parsing them involved
overwriting them.  If this causes performance
trouble, that can be resolved by further
converting them to Tcl_Obj's.

The #defines USE_NON_CONST and USE_COMPAT_CONST
have the same effect for Tk as they do for Tcl.
(They actually change tcl.h)
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkWinEmbed.c,v 1.6 2002/06/22 08:37:25 hobbs Exp $
d388 1
a388 1
	    containerPtr->parentHWnd != hwnd;
d390 5
a394 3
	if (containerPtr == NULL) {
	    panic("TkWinContainerProc couldn't find Container record");
	}
@


1.7.2.1
log
@* generic/tkInt.h:	Backport of shutdown safety mods from the HEAD
* generic/tkMenu.c:	dating from 2003-12-21
* generic/tkUtil.c:
* generic/tkWindow.c:
* mac/tkMacButton.c:
* unix/tkUnixEvent.c:
* win/tkWin32Dll.c:
* win/tkWinEmbed.c:
* win/tkWinMenu.c:
* win/tkWinX.c:
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkWinEmbed.c,v 1.7 2002/08/05 04:30:41 dgp Exp $
d211 1
a211 1
        TkCreateExitHandler(CleanupContainerList, (ClientData) NULL);
d287 1
a287 1
        TkCreateExitHandler(CleanupContainerList, (ClientData) NULL);
d388 1
a388 1
	    containerPtr && containerPtr->parentHWnd != hwnd;
d390 3
a392 5
	/* empty loop body */
    }

    if (containerPtr == NULL) {
	Tcl_Panic("TkWinContainerProc couldn't find Container record");
@


1.7.2.2
log
@	* win/tkWinEmbed.c (TkpGetOtherWindow):   do not panic if no window
	* win/tkWinWm.c (UpdateGeometryInfo):     is found - handle it in
	* unix/tkUnixEmbed.c (TkpGetOtherWindow): the caller. [Bug 1212056]
	* unix/tkUnixWm.c (Tk_CoordsToWindow, UpdateGeometryInfo):
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkWinEmbed.c,v 1.7.2.1 2004/10/27 00:37:38 davygrvy Exp $
d545 1
@


1.7.2.1.2.1
log
@bug fixes (crahes/panic during finalization/exit); feature implementation for embedding/embedded Tk (Windows). See Tk 8.5 changes (12/17/04 - 01/03/05) for details
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkWinEmbed.c,v 1.15 2004/12/20 15:30:43 chengyemao Exp $
d19 1
a36 1
    HWND embeddedMenuHWnd;		/* Tk's embedded menu window handler */
d47 2
a55 1

d60 1
a60 1
 * TkWinCleanupContainerList --
d73 4
a76 1
void TkWinCleanupContainerList(void)
a128 6
 *	This procesure sends a TK_ATTACHWINDOW message to the window to 
 *	use. The returned value is either 0 (the window to use is already 
 *	in use) or the hwnd of the window to use (the window to use is 
 *	ready to serve as a container) or other values (the window to use 
 *	needs to be confirmed since this protocol was not used before Tk85).
 *
d131 3
a133 5
 *	if the argument does not identify a legal Windows window handle or
 *	it is already in use or a cancel button is pressed by a user in 
 *	confirming the use window as a Tk container) the return value is 
 *	TCL_ERROR and an error message is left in the the interp's result 
 *	if interp is not NULL.
d159 1
a159 1
        Tcl_Panic("TkpUseWindow: Already assigned a window");
a187 16
    } 

    id = SendMessage(hwnd, TK_ATTACHWINDOW, 0, 0);
    if(id == 0 || id != (long)hwnd) {
	char msg[256];
	if(id == 0) {
	    sprintf(msg, "The window \"%s\" is either unable or already to be used as a container", string);
	    Tcl_SetResult(interp, msg, TCL_VOLATILE);
	    return TCL_ERROR;
	} else {
	    sprintf(msg, "The window \"%s\" failed to identify itself as a Tk container.\nPress Ok to proceed or Cancel to abort attaching.", string);
	    if(IDCANCEL == MessageBox(hwnd, msg, "Tk Warning", MB_OKCANCEL | MB_ICONWARNING)) {
	        Tcl_SetResult(interp, "Operation has been canceled", TCL_STATIC); 
	        return TCL_ERROR;
	    }
	}
d204 9
d280 9
a378 1
    int result = 1;
d393 3
a395 22
    if (containerPtr) {
	switch (message) {
	    case TK_ATTACHWINDOW:
	    /* An embedded window (either from this application or from
	     * another application) is trying to attach to this container.
	     * We attach it only if this container is not yet containing any
	     * window.
	     *
	     * wParam - a handle of an embedded window
	     *
	     * An embedded window may send this message with a wParam of NULL
	     * to test if a window is able to provide embedding service. The 
	     * container returns its window handle for accepting the attachment 
	     * and identifying itself or a zero for being already in use.
	     */
	    if (containerPtr->embeddedHWnd == NULL) {
		containerPtr->embeddedHWnd = (HWND)wParam;
		result =  (long)containerPtr->parentHWnd;
	    } else {
		result = 0;
	    }
	    break;
d397 12
a408 43
	    case TK_DETACHWINDOW:
	    containerPtr->embeddedHWnd = NULL;
	    containerPtr->parentPtr->flags &= ~TK_BOTH_HALVES;
	    break;

	    case TK_GEOMETRYREQ:
	    /*
	     * wParam - window width
	     * lParam - window height
	     */
	    EmbedGeometryRequest(containerPtr, (int) wParam, lParam);
	    break;

	    case TK_RAISEWINDOW:
	    /*
	     * wParam - a window handle as a z-order stack reference 
	     * lParam - a flag of above-below: 0 - above; 1 or others: - below
	     */
	    TkWinSetWindowPos(GetParent(containerPtr->parentHWnd), (HWND)wParam, (int)lParam);
	    break;

	    case TK_GETFRAMEWID:
	    result = (long)GetParent(containerPtr->parentHWnd);
	    break;

	    case TK_CLAIMFOCUS:
	    /* 
	     * wParam - a flag of forcing focus 
	     */
	    if(!SetFocus(containerPtr->embeddedHWnd) && wParam) {
		/*
		 * forcing focus TBD
		 */
	    }
	    break;

	    case TK_WITHDRAW:
	    TkpWinToplevelWithDraw(containerPtr->parentPtr);
	    break;

	    case TK_ICONIFY:
	    TkpWinToplevelIconify(containerPtr->parentPtr);
	    break;
d410 4
a413 33
	    case TK_DEICONIFY:
	    TkpWinToplevelDeiconify(containerPtr->parentPtr);
	    break;

	    case TK_MOVEWINDOW:
	    /*
	     *	wParam - x value of the frame's upper left;
	     *	lParam - y value of the frame's upper left;
	     */
	    result = TkpWinToplevelMove(containerPtr->parentPtr, wParam, lParam);
	    break;

	    case TK_OVERRIDEREDIRECT:
	    result = TkpWinToplevelOverrideRedirect(containerPtr->parentPtr, wParam);
	    break;

	    case TK_SETMENU:
	    containerPtr->embeddedMenuHWnd = (HWND)lParam;
	    TkWinSetMenu((Tk_Window)containerPtr->parentPtr, (HMENU)wParam);
	    result = 1;
	    break;

	    /*
	     * Return 0 since the current Tk container implementation 
	     * is unable to provide following services.
	     *  
	     */
	    default:
	    result = 0;  
	    break;
	}
    } else {
	result = 0;
d415 1
a415 2

    return result;
d495 3
d545 1
a545 70
    Tcl_Panic("TkpGetOtherWindow couldn't find window");
    return NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_GetEmbeddedHWnd --
 *
 *	This function returns the embedded window id.
 *
 * Results:
 *	If winPtr is a container, the return value is the HWND for the
 *	embedded window. Otherwise it returns NULL.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

HWND
Tk_GetEmbeddedHWnd(winPtr)
    TkWindow *winPtr;
{
    Container *containerPtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *) 
            Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    for (containerPtr = tsdPtr->firstContainerPtr; containerPtr != NULL;
	    containerPtr = containerPtr->nextPtr) {
	if (containerPtr->parentPtr == winPtr) {
	    return containerPtr->embeddedHWnd;
	}
    }
    return NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_GetEmbeddedMenuHWND --
 *
 *	This function returns the embedded menu window id.
 *
 * Results:
 *	If winPtr is a container, the return value is the HWND for the
 *	embedded menu window. Otherwise it returns NULL.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

HWND
Tk_GetEmbeddedMenuHWND(tkwin)
    Tk_Window tkwin;
{
    TkWindow *winPtr = (TkWindow*)tkwin;
    Container *containerPtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *) 
            Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    for (containerPtr = tsdPtr->firstContainerPtr; containerPtr != NULL;
	    containerPtr = containerPtr->nextPtr) {
	if (containerPtr->parentPtr == winPtr) {
	    return containerPtr->embeddedMenuHWnd;
	}
    }
a655 1
	    SendMessage(containerPtr->embeddedHWnd, WM_CLOSE, 0, 0);
d662 1
a662 1
	    Tcl_Panic("EmbedWindowDeleted couldn't find window");
@


1.7.2.1.2.2
log
@Made the remarks of TkpUseWindow clearer regarding the embedding/embedded attachment protocol
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkWinEmbed.c,v 1.7.2.1.2.1 2005/01/04 05:07:03 chengyemao Exp $
d127 3
a129 7
 *	in use or unable to be used as a container) or the hwnd of the 
 *	window to use (the window to use is ready to serve as a container) 
 *	or other values	(the window to use needs to be confirmed since 
 *	this protocol was not used before Tk85). This protocol is required
 *	in order to verify if the window to use is a valid container.
 *	Without an id verification, an invalid window attachment may cause
 *	unexpected crashes/panics (see bug # 1096074).
d198 1
a198 1
	    sprintf(msg, "The window \"%s\" is unable to be or has already been used as a container.", string);
@


1.7.2.1.2.3
log
@Updated for embedded/embedding implementation for Windows
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkWinEmbed.c,v 1.7.2.1.2.2 2005/01/05 02:45:53 chengyemao Exp $
a53 2
static HWND		Tk_GetEmbeddedHWnd _ANSI_ARGS_((TkWindow *winPtr));
static void		Tk_MapEmbeddedWindow _ANSI_ARGS_((TkWindow* winPtr));
a116 60
 * Tk_DetachEmbeddedWindow --
 *
 *	This function detaches an embedded window
 *
 * Results:
 *	No return value. Detach the embedded window.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */
static 
void Tk_DetachEmbeddedWindow(winPtr, detachFlag)
    TkWindow *winPtr;	    /* an embedded window */
    BOOL detachFlag;	    /* a flag of truely detaching */
{
    TkpWinToplevelDetachWindow(winPtr);
    if(detachFlag)
    {
	TkpWinToplevelOverrideRedirect(winPtr, 0);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_MapEmbeddedWindow --
 *
 *	This function is required for mapping an embedded window during
 *	idle.  The input winPtr must be preserved using Tcl_Preserve before
 *	call this function and will be released by the function.
 *
 * Results:
 *	No return value. Map the embedded window if it is not dead.
 *
 * Side effects:
 *	The embedded window may change its state as the container's.
 *
 *----------------------------------------------------------------------
 */
static void Tk_MapEmbeddedWindow(winPtr)
    TkWindow *winPtr;		/* Top-level window that's about to
				 * be mapped. */
{
    if(!(winPtr->flags & TK_ALREADY_DEAD)) {
	HWND hwnd = (HWND)winPtr->privatePtr;
	int state = SendMessage(hwnd, TK_STATE, -1, -1) - 1;
	if(state < 0 || state > 3) {
	    state = NormalState;
	} 
	TkpWmSetState(winPtr, state);
	TkWmMapWindow(winPtr);
    }
    Tcl_Release((ClientData)winPtr);
}

/*
 *----------------------------------------------------------------------
 *
d125 9
a133 23
 *	This procedure uses a simple attachment protocol by sending 
 *	TK_INFO messages to the window to use with two sub messages:
 *
 *	    TK_CONTAINER_VERIFY - if a window handles this message,
 *		it should return either a (long)hwnd for a container or
 *		a -(long)hwnd for a non-container. 
 *
 *	    TK_CONTAINER_ISAVAILABLE - a container window should return 
 *		either a TRUE (non-zero) if it is available for use or
 *		a FALSE (zero) othersize.
 *
 *	The TK_INFO messages are required in order to verify if the window 
 *	to use is a valid container. Without an id verification, an invalid 
 *	window attachment may cause unexpected crashes/panics (bug 1096074).
 *	Additional sub messages may be definded/used in future for other 
 *	needs.
 *	
 *	We do not enforce the above protocol for the reason of backward 
 *	compatibility. If the window to use is unable to handle TK_INFO 
 *	messages (e.g., legacy Tk container applications before 8.5),
 *	a dialog box with a warning message pops up and the user is asked 
 *	to confirm if the attachment should proceed.  However, we may have 
 *	to enforce it in future.
d159 1
d162 1
d165 3
a167 11
/*
    if(winPtr->window != None) {
	Tcl_AppendResult(interp, "can't modify container after widget is created", (char *) NULL);
	return TCL_ERROR;
    }
*/
    if(strcmp(string, "") == 0) {
	if(winPtr->flags & TK_EMBEDDED) {
	    Tk_DetachEmbeddedWindow(winPtr, TRUE);
	}
	return TCL_OK;
d174 1
a174 2
    if((HWND)winPtr->privatePtr == hwnd) return TCL_OK;
 
d189 5
a193 4
    id = SendMessage(hwnd, TK_INFO, TK_CONTAINER_VERIFY, 0);
    if(id == (long)hwnd) {
	if(!SendMessage(hwnd, TK_INFO, TK_CONTAINER_ISAVAILABLE, 0)) {
	    Tcl_AppendResult(interp, "The container is already in use", NULL);
d196 16
a211 10
    } else if(id == -(long)hwnd) {
	Tcl_AppendResult(interp, "the window to use is not a container", NULL);
	return TCL_ERROR;
    } else {
        char msg[256];
        sprintf(msg, "Unable to get information of window \"%s\".  Attach to this\nwindow may have unpredictable results if it is not a Tk container.\n\nPress Ok to proceed or Cancel to abort attaching.", string);
        if(IDCANCEL == MessageBox(hwnd, msg, "Tk Warning", MB_OKCANCEL | MB_ICONWARNING)) {
            Tcl_SetResult(interp, "Operation has been canceled", TCL_STATIC); 
            return TCL_ERROR;
        }
a213 2
    Tk_DetachEmbeddedWindow(winPtr, FALSE);

d220 32
a251 3
    winPtr->flags |= TK_EMBEDDED;
    winPtr->flags &= (~(TK_MAPPED));
 
d253 4
a256 2
     * We have to map the embedded window carefully to avoid crashing in
     * TkWmMapWindow during idle due to window destroyed by script. 
d259 5
a263 2
    Tcl_Preserve((ClientData)winPtr);
    Tcl_DoWhenIdle(Tk_MapEmbeddedWindow, (ClientData)winPtr);
a266 1

a305 1
    containerPtr->embeddedMenuHWnd = NULL;
a400 4
	TkWindow *topwinPtr = NULL;
	if(Tk_IsTopLevel(containerPtr->parentPtr)) {
	    topwinPtr = containerPtr->parentPtr;
	}
a401 15
	    case TK_INFO:
	    switch(wParam) {
		case TK_CONTAINER_ISAVAILABLE:
		result = containerPtr->embeddedHWnd == NULL? 1:0;
		break;

		case TK_CONTAINER_VERIFY:
		result = (long)containerPtr->parentHWnd;
		break;
		
		default:
		result = 0;
	    }
	    break;

a408 1
	     * lParam - N/A
a413 4
	     *
	     * Return value:
	     * 0    - the container is unable to be used.
	     * hwnd - the container is ready to be used. 
d416 1
a416 9
		if(wParam) {
		    TkWindow* winPtr = (TkWindow*)Tk_HWNDToWindow((HWND)wParam);
		    if(winPtr) {
			winPtr->flags |= TK_BOTH_HALVES;
			containerPtr->embeddedPtr = winPtr;
			containerPtr->parentPtr->flags |= TK_BOTH_HALVES;
		    }
		    containerPtr->embeddedHWnd = (HWND)wParam;
		}
a423 12
	    /* An embedded window notifies the container that it is detached.
	     * The container should clearn the related variables and redraw
	     * its window.
	     * 
	     * wParam - N/A
	     * lParam - N/A
	     *
	     * Return value:
	     * 0	- the message is not processed.
	     * others	- the message is processed.
	     */
	    containerPtr->embeddedMenuHWnd = NULL;
a425 2
	    if(topwinPtr) TkWinSetMenu((Tk_Window)topwinPtr, 0);
	    InvalidateRect(hwnd, NULL, TRUE);
d429 1
a429 2
	    /* An embedded window requests a window size change.
	     *
a431 4
	     *
	     * Return value:
	     * 0	- the message is not processed.
	     * others	- the message is processed.
d433 1
a433 1
	    EmbedGeometryRequest(containerPtr, (int)wParam, lParam);
d437 1
a437 2
	    /* An embedded window requests to change its Z-order
	     * 
a439 4
	     * 
	     * Return value:
	     * 0	- the message is not processed.
	     * others	- the message is processed.
d445 1
a445 23
	    /* An embedded window requests to get the frame window's id
	     *
	     * wParam - N/A
	     * lParam - N/A
	     *
	     * Return vlaue:
	     *
	     * A handle of the frame window. If it is not availble, a 
	     * zeor is returned.
	     */
	    if(topwinPtr) {
		result = (long)GetParent(containerPtr->parentHWnd);
	    } else {
		topwinPtr = containerPtr->parentPtr;
		while (!(topwinPtr->flags & TK_TOP_HIERARCHY)) {
		    topwinPtr = topwinPtr->parentPtr;
		}
		if(topwinPtr && topwinPtr->window) {
		    result = (long)GetParent(Tk_GetHWND(topwinPtr->window));
		} else {
		    result = 0;
		}
	    }
d449 1
a449 2
	    /* An embedded window requests a focus
	     * 
a450 5
	     * lParam - N/A
	     *
	     * Return value:
	     * 0    - the message is not processed
	     * 1    - the message is processed
d460 1
a460 13
	    /* An embedded window requests withdraw
	     * 
	     * wParam	- N/A
	     * lParam	- N/A
	     *
	     * Return value
	     * 0    - the message is not processed
	     * 1    - the message is processed
	     */
	    if(topwinPtr) 
		TkpWinToplevelWithDraw(topwinPtr);
	    else
		result = 0;
d464 1
a464 13
	    /* An embedded window requests iconification
	     * 
	     * wParam	- N/A
	     * lParam	- N/A
	     *
	     * Return value
	     * 0    - the message is not processed
	     * 1    - the message is processed
	     */
	    if(topwinPtr) 
		TkpWinToplevelIconify(topwinPtr);
	    else
		result = 0;
d468 1
a468 13
	    /* An embedded window requests deiconification
	     * 
	     * wParam	- N/A
	     * lParam	- N/A
	     *
	     * Return value
	     * 0    - the message is not processed
	     * 1    - the message is processed
	     */
	    if(topwinPtr) 
		TkpWinToplevelDeiconify(topwinPtr);
	    else
		result = 0;
d472 3
a474 12
	    /* An embedded window requests to move position if
	     * both wParam and lParam are greater or equal to 0.
	     *	    wParam - x value of the frame's upper left
	     *	    lParam - y value of the frame's upper left
	     *
	     * Otherwise an embedded window requests the current 
	     * position
	     *
	     * Return value: an encoded window position in a 32bit long, 
	     * i.e, ((x << 16) & 0xffff0000) | (y & 0xffff)
	     * 
	     * Only a toplevel container may move the embedded.
d480 1
a480 18
	    /* An embedded window request overrideredirect.
	     *
	     * wParam
	     *	0	- add a frame if there is no one
	     *  1	- remove the frame if there is a one
	     *  < 0	- query the current overrideredirect value
	     *
	     * lParam	- N/A
	     *
	     * Return value:
	     * 1 + the current value of overrideredirect if the container is
	     * a toplevel.  Otherwise 0.
	     */
	    if(topwinPtr) {
		result = TkpWinToplevelOverrideRedirect(topwinPtr, wParam)+1;
	    } else {
		result = 0;
	    }
d484 3
a486 41
	    /* An embedded requests to set a menu
	     *
	     * wParam	- a menu handle
	     * lParam	- a menu window handle
	     *
	     * Return value:
	     * 1    - the message is processed
	     * 0    - the message is not processed
	     */
	    if(topwinPtr) {
		containerPtr->embeddedMenuHWnd = (HWND)lParam;
		TkWinSetMenu((Tk_Window)topwinPtr, (HMENU)wParam);
	    } else {
		result = 0;
	    }
	    break;

	    case TK_STATE:
	    /* An embedded window request set/get state services
	     *
	     * wParam	- service directive
	     *	    0 - 3 for setting state
	     *		0 - withdrawn state
	     *		1 - normal state
	     *		2 - zoom state
	     *		3 - icon state
	     * others for gettting state
	     *
	     * lParam	- N/A
	     *
	     * Return value
	     * 1 + the current state or 0 if the container is not a toplevel
	     */
	    if(topwinPtr) {
		if(wParam >= 0 && wParam <= 3) {
		    TkpWmSetState(topwinPtr, wParam);
		}
		result = 1 + TkpWmGetState(topwinPtr);
	    } else {
		result = 0;
	    }
a498 3
	if(message == TK_INFO && wParam == TK_CONTAINER_VERIFY) {
	    result = -(long)hwnd;
	}
d598 2
a599 3
 *	If both the container and embedded window are created by Tk of
 *	the same process, this procedure will return either one, 
 *	given the other.
d650 1
a650 1
static HWND
a810 1
	    containerPtr->embeddedPtr = NULL;
d816 1
a816 1
	    return;
@


1.7.2.1.2.4
log
@Flushed idle events before mapping an embedded window
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkWinEmbed.c,v 1.7.2.1.2.3 2005/01/19 02:03:48 chengyemao Exp $
a169 1
	while(Tcl_DoOneEvent(TCL_IDLE_EVENTS)); 
@


1.6
log
@	* win/tkWinEmbed.c (EmbedWindowDeleted): added a check for a null
	containerPtr.  The core of this bug is likely elsewhere. [Bug #476176]
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkWinEmbed.c,v 1.5 2002/05/27 17:33:26 mdejong Exp $
d113 1
a113 1
    char **argv;
d147 1
a147 1
    char *string;		/* String identifying an X window to use
@


1.5
log
@	* tests/embed.test: Added cross platform embed tests.
	Check that window passed to -use has the -container
	option set.
	* tests/wm.test: Remove useless catch call. Deiconify
	. just in case, stackorder tests will not pass unless
	it is in the normal state. Add -container flag to
	embedded stackorder test.
	* unix/tkUnixEmbed.c (TkpUseWindow):
	* win/tkWinEmbed.c (TkpUseWindow): Lookup Tk window
	based on the id passed in as the value for -use.
	Generate an error if the Tk window did not have
	the -container option set.
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkWinEmbed.c,v 1.4 2000/07/06 03:17:44 mo Exp $
d641 1
d646 1
@


1.4
log
@	* generic/tkFileFilter.c (AddClause): Cast to match function prototype.
	* win/stubs.c (_XInitImageFuncPtrs): Add return value for function.
	* win/tkWinButton.c (buttonStyles, ButtonBindProc, ComputeStyle):
	Remove unused declarations.
	* win/tkWinColor.c (GetColorByName, GetColorByValue): Remove unused
	function declarations.
	* win/tkWinDialog.c (TrySetDirectory): Remove unused function declaration.
	* win/tkWinEmbed.c (TkWinEmbeddedEventProc): Cast to match function prototype.
	* win/tkWinMenu.c (winMenuMutex, MenuExitProc): Remove unused declaration.
	* win/tkWinWindow.c (StackWindow): Remove unused declaration.
	* win/tkWinWm.c (ConfigureEvent): Remove unused declaration.
	* win/tkWinX.c (winXMutex): Remove unused declaration.
	* xlib/ximage.c (XCreateBitmapFromData): Cast to match function prototype.
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkWinEmbed.c,v 1.3 1999/04/16 01:51:51 stanton Exp $
d151 1
d179 9
@


1.4.6.1
log
@Merging with TOT as of 06/09/2002.
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id$
a150 1
    TkWindow *usePtr;
a177 9
    }

    usePtr = (TkWindow *) Tk_HWNDToWindow(hwnd);
    if (usePtr != NULL) {
        if (!(usePtr->flags & TK_CONTAINER)) {
	    Tcl_AppendResult(interp, "window \"", usePtr->pathName,
                    "\" doesn't have -container option set", (char *) NULL);
	    return TCL_ERROR;
	}
@


1.4.6.2
log
@merged with trunk at tag macosx-8-4-merge-2002-08-20-trunk
@
text
@d113 1
a113 1
    CONST char **argv;
d147 1
a147 1
    CONST char *string;		/* String identifying an X window to use
a640 1
     * The main container may be null. [Bug #476176]
a644 1
    if (containerPtr == NULL) return;
@


1.3
log
@* Merged 8.1 branch into the main trunk
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id$
d400 1
a400 1
	EmbedGeometryRequest(containerPtr, wParam, lParam);
@


1.3.12.1
log
@see ChangeLog for specific file details
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkWinEmbed.c,v 1.4 2000/07/06 03:17:44 mo Exp $
d400 1
a400 1
	EmbedGeometryRequest(containerPtr, (int) wParam, lParam);
@


1.2
log
@Replaced SCCS strings, fixed binary files
@
text
@d9 1
a9 1
 * Copyright (c) 1996 Sun Microsystems, Inc.
d41 2
a42 2
static Container *firstContainerPtr = NULL;
					/* First in list of all containers
d44 2
d79 2
d83 4
a86 4
        firstContainerPtr != (Container *) NULL;
        firstContainerPtr = nextPtr) {
        nextPtr = firstContainerPtr->nextPtr;
        ckfree((char *) firstContainerPtr);
d88 1
a88 1
    firstContainerPtr = (Container *) NULL;
d133 1
a133 1
 *	interp->result if interp is not NULL.
d154 2
d168 2
a169 1
     * TCL_ERROR and potentially leave an error message in interp->result.
d200 1
a200 1
    if (firstContainerPtr == (Container *) NULL) {
d211 2
a212 2
    for (containerPtr = firstContainerPtr; containerPtr != NULL;
	    containerPtr = containerPtr->nextPtr) {
d223 2
a224 2
	containerPtr->nextPtr = firstContainerPtr;
	firstContainerPtr = containerPtr;
d268 2
d276 1
a276 1
    if (firstContainerPtr == (Container *) NULL) {
d291 2
a292 2
    containerPtr->nextPtr = firstContainerPtr;
    firstContainerPtr = containerPtr;
d370 2
d377 1
a377 1
    for (containerPtr = firstContainerPtr;
d522 2
d525 1
a525 1
    for (containerPtr = firstContainerPtr; containerPtr != NULL;
d624 2
d634 1
a634 1
    containerPtr = firstContainerPtr;
d654 1
a654 1
	    firstContainerPtr = containerPtr->nextPtr;
@


1.1
log
@Initial revision
@
text
@d14 1
a14 1
 * SCCS: @@(#) tkWinEmbed.c 1.20 97/11/05 17:47:09;
@


1.1.4.1
log
@initial tk8.1a2 version
@
text
@d9 1
a9 1
 * Copyright (c) 1996-1997 Sun Microsystems, Inc.
d14 1
a14 1
 * SCCS: @@(#) tkWinEmbed.c 1.21 97/11/07 21:59:08;
d129 1
a129 1
 *	the interp's result if interp is not NULL.
d162 1
a162 2
     * TCL_ERROR and potentially leave an error message in the interp's
     * result.
@


1.1.4.2
log
@Merged 8.0.3 changes into 8.1
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkWinEmbed.c,v 1.2 1998/09/14 18:24:00 stanton Exp $
@


1.1.4.3
log
@
Tk 8.1 Muti-threading changes.

Moved static and global data elements into thread-local storage,
or introduced locks where not possible, as first stage of adding
thread safety to Tk.
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkWinEmbed.c,v 1.1.4.2 1998/09/30 02:19:32 stanton Exp $
d41 2
a42 2
typedef struct ThreadSpecificData {
    Container *firstContainerPtr;       /* First in list of all containers
a43 2
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;
a76 2
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *) 
            Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
d79 4
a82 4
        tsdPtr->firstContainerPtr != (Container *) NULL;
        tsdPtr->firstContainerPtr = nextPtr) {
        nextPtr = tsdPtr->firstContainerPtr->nextPtr;
        ckfree((char *) tsdPtr->firstContainerPtr);
d84 1
a84 1
    tsdPtr->firstContainerPtr = (Container *) NULL;
a149 2
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *) 
            Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
d194 1
a194 1
    if (tsdPtr->firstContainerPtr == (Container *) NULL) {
d205 2
a206 2
    for (containerPtr = tsdPtr->firstContainerPtr; 
            containerPtr != NULL; containerPtr = containerPtr->nextPtr) {
d217 2
a218 2
	containerPtr->nextPtr = tsdPtr->firstContainerPtr;
	tsdPtr->firstContainerPtr = containerPtr;
a261 2
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *) 
            Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
d268 1
a268 1
    if (tsdPtr->firstContainerPtr == (Container *) NULL) {
d283 2
a284 2
    containerPtr->nextPtr = tsdPtr->firstContainerPtr;
    tsdPtr->firstContainerPtr = containerPtr;
a361 2
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *) 
            Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
d367 1
a367 1
    for (containerPtr = tsdPtr->firstContainerPtr;
a511 2
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *) 
            Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
d513 1
a513 1
    for (containerPtr = tsdPtr->firstContainerPtr; containerPtr != NULL;
a611 2
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *) 
            Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
d620 1
a620 1
    containerPtr = tsdPtr->firstContainerPtr;
d640 1
a640 1
	    tsdPtr->firstContainerPtr = containerPtr->nextPtr;
@


