From a2455a5686d0db82e6d05203f8048152c7e7193f Mon Sep 17 00:00:00 2001
From: chengyemao <chengyemao>
Date: Sun, 9 Jan 2005 18:28:05 +0000
Subject: Changed to make platform implementation ready for a toplevel -use
 option; completed a full toplevel -use option configuration for Windows

---
 generic/tkFrame.c      | 16 ++++++++++++----
 macosx/tkMacOSXEmbed.c |  5 +++--
 unix/tkUnixEmbed.c     |  5 +++--
 win/tkWinEmbed.c       | 26 ++++++++++++++++++++++++--
 win/tkWinInt.h         |  4 ++--
 win/tkWinWm.c          | 37 +++++++++++++++++++++++++++++++++++--
 6 files changed, 79 insertions(+), 14 deletions(-)

diff --git a/generic/tkFrame.c b/generic/tkFrame.c
index f6ae5cb..b27b454 100644
--- a/generic/tkFrame.c
+++ b/generic/tkFrame.c
@@ -12,7 +12,7 @@
  * See the file "license.terms" for information on usage and redistribution
  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
  *
- * RCS: @(#) $Id: tkFrame.c,v 1.18 2004/12/17 13:56:15 chengyemao Exp $
+ * RCS: @(#) $Id: tkFrame.c,v 1.19 2005/01/09 18:28:05 chengyemao Exp $
  */
 
 #include "default.h"
@@ -803,10 +803,18 @@ FrameWidgetObjCmd(clientData, interp, objc, objv)
 			&& (strncmp(arg, "-use", length) == 0))
 			|| ((c == 'v')
 			&& (strncmp(arg, "-visual", length) == 0))) {
-		    Tcl_AppendResult(interp, "can't modify ", arg,
+		    if(c == 'u') {
+			CONST char*string = Tcl_GetString(objv[i+1]);
+			if(TCL_OK == TkpUseWindow(interp, framePtr->tkwin, string)) {
+			    result = TCL_ERROR;
+			    goto done;
+			}
+		    } else {
+			Tcl_AppendResult(interp, "can't modify ", arg,
 			    " option after widget is created", (char *) NULL);
-		    result = TCL_ERROR;
-		    goto done;
+			result = TCL_ERROR;
+			goto done;
+		    }
 		}
 	    }
 	    result = ConfigureFrame(interp, framePtr, objc-2, objv+2);
diff --git a/macosx/tkMacOSXEmbed.c b/macosx/tkMacOSXEmbed.c
index 15be5b4..7ed29e8 100644
--- a/macosx/tkMacOSXEmbed.c
+++ b/macosx/tkMacOSXEmbed.c
@@ -14,7 +14,7 @@
  * See the file "license.terms" for information on usage and redistribution
  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
  *
- *  RCS: @(#) $Id: tkMacOSXEmbed.c,v 1.3 2004/01/13 02:06:01 davygrvy Exp $
+ *  RCS: @(#) $Id: tkMacOSXEmbed.c,v 1.4 2005/01/09 18:28:06 chengyemao Exp $
  */
 
 #include "tkInt.h"
@@ -242,7 +242,8 @@ TkpUseWindow(
     int result;
 
     if (winPtr->window != None) {
-        Tcl_Panic("TkpUseWindow: X window already assigned");
+	Tcl_AppendResult(interp, "can't modify container after widget is created", (char *) NULL);
+	return TCL_ERROR;
     }
     
     /*
diff --git a/unix/tkUnixEmbed.c b/unix/tkUnixEmbed.c
index 5d46e84..40d54ad 100644
--- a/unix/tkUnixEmbed.c
+++ b/unix/tkUnixEmbed.c
@@ -11,7 +11,7 @@
  * See the file "license.terms" for information on usage and redistribution
  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
  *
- * RCS: @(#) $Id: tkUnixEmbed.c,v 1.7 2004/01/13 02:06:01 davygrvy Exp $
+ * RCS: @(#) $Id: tkUnixEmbed.c,v 1.8 2005/01/09 18:28:06 chengyemao Exp $
  */
 
 #include "tkInt.h"
@@ -115,7 +115,8 @@ TkpUseWindow(interp, tkwin, string)
             Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
 
     if (winPtr->window != None) {
-	Tcl_Panic("TkUseWindow: X window already assigned");
+	Tcl_AppendResult(interp, "can't modify container after widget is created", (char *) NULL);
+	return TCL_ERROR;
     }
     if (Tcl_GetInt(interp, string, &id) != TCL_OK) {
 	return TCL_ERROR;
diff --git a/win/tkWinEmbed.c b/win/tkWinEmbed.c
index 470140b..2908f27 100644
--- a/win/tkWinEmbed.c
+++ b/win/tkWinEmbed.c
@@ -11,7 +11,7 @@
  * 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.19 2005/01/07 15:18:03 chengyemao Exp $
+ * RCS: @(#) $Id: tkWinEmbed.c,v 1.20 2005/01/09 18:28:06 chengyemao Exp $
  */
 
 #include "tkWinInt.h"
@@ -162,11 +162,25 @@ TkpUseWindow(interp, tkwin, string)
     Container *containerPtr;
     ThreadSpecificData *tsdPtr = (ThreadSpecificData *) 
             Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+/*
+    if(winPtr->window != None) {
+	Tcl_AppendResult(interp, "can't modify container after widget is created", (char *) NULL);
+	return TCL_ERROR;
+    }
+*/
+    if(stricmp(string, "") == 0) {
+	if(winPtr->flags & TK_EMBEDDED) {
+	    TkpWinToplevelDetachWindow(winPtr);
+	    TkpWinToplevelOverrideRedirect(winPtr, 0);
+	}
+	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
@@ -207,6 +221,8 @@ TkpUseWindow(interp, tkwin, string)
 	}
     }
 
+    TkpWinToplevelDetachWindow(winPtr);    
+
     /*
      * Store the parent window in the platform private data slot so
      * TkWmMapWindow can use it when creating the wrapper window.
@@ -233,7 +249,10 @@ TkpUseWindow(interp, tkwin, string)
             containerPtr != NULL; containerPtr = containerPtr->nextPtr) {
 	if (containerPtr->parentHWnd == hwnd) {
 	    winPtr->flags |= TK_BOTH_HALVES;
-	    containerPtr->parentPtr->flags |= TK_BOTH_HALVES;
+	    containerPtr->parentPtr = usePtr;
+	    if(usePtr) {
+		containerPtr->parentPtr->flags |= TK_BOTH_HALVES;
+	    }
 	    break;
 	}
     }
@@ -258,6 +277,8 @@ TkpUseWindow(interp, tkwin, string)
     winPtr->flags |= TK_EMBEDDED;
     winPtr->flags &= (~(TK_MAPPED));
 
+    Tcl_DoWhenIdle(TkWmMapWindow, (ClientData)winPtr);
+
     return TCL_OK;
 }
 
@@ -420,6 +441,7 @@ TkWinEmbeddedEventProc(hwnd, message, wParam, lParam)
 	    containerPtr->embeddedMenuHWnd = NULL;
 	    containerPtr->embeddedHWnd = NULL;
 	    containerPtr->parentPtr->flags &= ~TK_BOTH_HALVES;
+	    TkWinSetMenu((Tk_Window)containerPtr->parentPtr, 0);
 	    InvalidateRect(hwnd, NULL, TRUE);
 	    break;
 
diff --git a/win/tkWinInt.h b/win/tkWinInt.h
index ed3b324..02009ef 100644
--- a/win/tkWinInt.h
+++ b/win/tkWinInt.h
@@ -11,7 +11,7 @@
  * See the file "license.terms" for information on usage and redistribution
  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
  *
- * RCS: @(#) $Id: tkWinInt.h,v 1.21 2004/12/20 15:30:43 chengyemao Exp $
+ * RCS: @(#) $Id: tkWinInt.h,v 1.22 2005/01/09 18:28:06 chengyemao Exp $
  */
 
 #ifndef _TKWININT
@@ -230,6 +230,6 @@ void	TkpWinToplevelDeiconify		_ANSI_ARGS_((TkWindow *winPtr));
 long	TkpWinToplevelIsControlledByWm	_ANSI_ARGS_((TkWindow *winPtr));
 long	TkpWinToplevelMove		_ANSI_ARGS_((TkWindow *winPtr, int x, int y));
 long	TkpWinToplevelOverrideRedirect	_ANSI_ARGS_((TkWindow *winPtr, int reqValue));
-
+void	TkpWinToplevelDetachWindow	_ANSI_ARGS_((TkWindow *winPtr));
 #endif /* _TKWININT */
 
diff --git a/win/tkWinWm.c b/win/tkWinWm.c
index 1e875d2..1dec80e 100644
--- a/win/tkWinWm.c
+++ b/win/tkWinWm.c
@@ -12,7 +12,7 @@
  * See the file "license.terms" for information on usage and redistribution
  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
  *
- * RCS: @(#) $Id: tkWinWm.c,v 1.89 2005/01/09 00:22:48 chengyemao Exp $
+ * RCS: @(#) $Id: tkWinWm.c,v 1.90 2005/01/09 18:28:06 chengyemao Exp $
  */
 
 #include "tkWinInt.h"
@@ -2204,7 +2204,7 @@ UpdateWrapper(winPtr)
 	{
 	    SendMessage(wmPtr->wrapper, TK_GEOMETRYREQ, 
 		Tk_ReqWidth((Tk_Window)winPtr), Tk_ReqHeight((Tk_Window)winPtr));
-	    SendMessage(wmPtr->wrapper, TK_SETMENU, (WPARAM)wmPtr->hMenu, 0);
+	    SendMessage(wmPtr->wrapper, TK_SETMENU, (WPARAM)wmPtr->hMenu, (LPARAM)Tk_GetMenuHWND((Tk_Window)winPtr));
 	}
     }
 
@@ -7950,3 +7950,36 @@ long TkpWinToplevelOverrideRedirect(winPtr, reqValue)
     }
     return reqValue;
 }
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkpWinToplevelDetachWindow --
+ *
+ *	This function is to be usd for changing a toplevel's wrapper or
+ *	container.
+ *
+ * Results:
+ *	The window's wrapper/container is removed.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void TkpWinToplevelDetachWindow(winPtr)
+    TkWindow *winPtr;
+{
+    register WmInfo *wmPtr = winPtr->wmInfoPtr;
+    if(winPtr->flags & TK_EMBEDDED) {
+	int state = SendMessage(wmPtr->wrapper, TK_STATE, -1, -1);
+        SendMessage(wmPtr->wrapper, TK_SETMENU, 0, 0);
+        SendMessage(wmPtr->wrapper, TK_DETACHWINDOW, 0, 0);
+        winPtr->flags &= ~TK_EMBEDDED;
+	winPtr->privatePtr = NULL;
+        wmPtr->wrapper = None;
+	wmPtr->hints.initial_state = state;
+    }
+    TkpWinToplevelOverrideRedirect(winPtr, 1);
+}
-- 
cgit v0.12