From a24199bd3446b589ea816cd70e58f5165f18724f Mon Sep 17 00:00:00 2001 From: chengyemao Date: Mon, 20 Dec 2004 01:13:12 +0000 Subject: 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 --- win/tkWin.h | 4 +- win/tkWinEmbed.c | 38 +++++---- win/tkWinInt.h | 11 ++- win/tkWinWm.c | 256 ++++++++++++++++++++++++++++++++++++++++++------------- win/tkWinX.c | 4 +- 5 files changed, 235 insertions(+), 78 deletions(-) diff --git a/win/tkWin.h b/win/tkWin.h index ca7fdc8..a95779d 100644 --- a/win/tkWin.h +++ b/win/tkWin.h @@ -9,7 +9,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkWin.h,v 1.8 2004/12/19 18:14:26 chengyemao Exp $ + * RCS: @(#) $Id: tkWin.h,v 1.9 2004/12/20 01:13:12 chengyemao Exp $ */ #ifndef _TKWIN @@ -46,7 +46,7 @@ #define TK_ICONIFY (WM_USER+6) /* an embedded window requests to iconify */ #define TK_DEICONIFY (WM_USER+7) /* an embedded window requests to deiconify */ #define TK_WITHDRAW (WM_USER+8) /* an embedded window requests to withdraw */ -#define TK_TITLE (WM_USER+9) /* an embedded window requests to set title */ +#define TK_GETFRAMEWID (WM_USER+9) /* an embedded window requests a frame window id */ /* diff --git a/win/tkWinEmbed.c b/win/tkWinEmbed.c index d43f3b5..a9f987e 100644 --- a/win/tkWinEmbed.c +++ b/win/tkWinEmbed.c @@ -11,11 +11,10 @@ * 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.13 2004/12/19 18:14:26 chengyemao Exp $ + * RCS: @(#) $Id: tkWinEmbed.c,v 1.14 2004/12/20 01:13:12 chengyemao Exp $ */ #include "tkWinInt.h" -extern TkWinProcs *tkWinProcs; /* * One of the following structures exists for each container in this @@ -51,6 +50,7 @@ static void EmbeddedEventProc _ANSI_ARGS_(( static void EmbedGeometryRequest _ANSI_ARGS_(( Container*containerPtr, int width, int height)); static void EmbedWindowDeleted _ANSI_ARGS_((TkWindow *winPtr)); + /* *---------------------------------------------------------------------- @@ -194,7 +194,7 @@ TkpUseWindow(interp, tkwin, string) if(id == 0 || id != (long)hwnd) { char msg[256]; if(id == 0) { - sprintf(msg, "The window \"%s\" is already in use", string); + 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 { @@ -436,11 +436,8 @@ TkWinEmbeddedEventProc(hwnd, message, wParam, lParam) TkWinSetWindowPos(GetParent(containerPtr->parentHWnd), (HWND)wParam, (int)lParam); break; - case TK_TITLE: - /* - * lParam - a pointer to a unicode string - */ - (*tkWinProcs->setWindowText)(GetParent(containerPtr->parentHWnd), (LPCTSTR)lParam); + case TK_GETFRAMEWID: + result = (long)GetParent(containerPtr->parentHWnd); break; case TK_CLAIMFOCUS: @@ -454,15 +451,16 @@ TkWinEmbeddedEventProc(hwnd, message, wParam, lParam) } break; - /* - * Return 0 since the current Tk container implementation - * is unable to provide these services. - * - */ + case TK_WITHDRAW: + TkpWinToplevelWithDraw(containerPtr->parentPtr); + break; + case TK_ICONIFY: + TkpWinToplevelIconify(containerPtr->parentPtr); + break; + case TK_DEICONIFY: - case TK_WITHDRAW: - result = 0; + TkpWinToplevelDeiconify(containerPtr->parentPtr); break; case TK_MOVEWINDOW: @@ -470,6 +468,16 @@ TkWinEmbeddedEventProc(hwnd, message, wParam, lParam) * 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; + + /* + * Return 0 since the current Tk container implementation + * is unable to provide following services. + * + */ + + default: result = 0; break; } diff --git a/win/tkWinInt.h b/win/tkWinInt.h index dfb0f35..a8ac9bd 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.19 2004/09/23 01:08:11 hobbs Exp $ + * RCS: @(#) $Id: tkWinInt.h,v 1.20 2004/12/20 01:13:12 chengyemao Exp $ */ #ifndef _TKWININT @@ -221,5 +221,14 @@ extern Tcl_Encoding TkWinGetUnicodeEncoding _ANSI_ARGS_((void)); #define TK_THEME_WIN_CLASSIC 1 #define TK_THEME_WIN_XP 2 +/* + * The following is implemented in tkWinWm and used by tkWinEmbed.c + */ +void TkpWinToplevelWithDraw _ANSI_ARGS_((TkWindow *winPtr)); +void TkpWinToplevelIconify _ANSI_ARGS_((TkWindow *winPtr)); +void TkpWinToplevelDeiconify _ANSI_ARGS_((TkWindow *winPtr)); +long TkpWinToplevelIsControlledByWm _ANSI_ARGS_((TkWindow *winPtr)); +long TkpWinToplevelMove _ANSI_ARGS_((TkWindow *winPtr, int x, int y)); + #endif /* _TKWININT */ diff --git a/win/tkWinWm.c b/win/tkWinWm.c index 4328663..8182ce5 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.81 2004/12/19 18:14:26 chengyemao Exp $ + * RCS: @(#) $Id: tkWinWm.c,v 1.82 2004/12/20 01:13:12 chengyemao Exp $ */ #include "tkWinInt.h" @@ -3286,47 +3286,7 @@ WmDeiconifyCmd(tkwin, winPtr, interp, objc, objv) } return TCL_OK; } - - wmPtr->flags &= ~WM_WITHDRAWN; - - /* - * If WM_UPDATE_PENDING is true, a pending UpdateGeometryInfo may - * need to be called first to update a withdrawn toplevel's geometry - * before it is deiconified by TkpWmSetState. - * Don't bother if we've never been mapped. - */ - if ((wmPtr->flags & WM_UPDATE_PENDING) && - !(wmPtr->flags & WM_NEVER_MAPPED)) { - Tcl_CancelIdleCall(UpdateGeometryInfo, (ClientData) winPtr); - UpdateGeometryInfo((ClientData) winPtr); - } - - /* - * If we were in the ZoomState (maximized), 'wm deiconify' - * should not cause the window to shrink - */ - if (wmPtr->hints.initial_state == ZoomState) { - TkpWmSetState(winPtr, ZoomState); - } else { - TkpWmSetState(winPtr, NormalState); - } - - /* - * An unmapped window will be mapped at idle time - * by a call to MapFrame. That calls CreateWrapper - * which sets the focus and raises the window. - */ - if (wmPtr->flags & WM_NEVER_MAPPED) { - return TCL_OK; - } - - /* - * Follow Windows-like style here, raising the window to the top. - */ - TkWmRestackToplevel(winPtr, Above, NULL); - if (!(Tk_Attributes((Tk_Window) winPtr)->override_redirect)) { - TkSetFocusWin(winPtr, 1); - } + TkpWinToplevelDeiconify(winPtr); return TCL_OK; } @@ -3465,7 +3425,7 @@ WmGeometryCmd(tkwin, winPtr, interp, objc, objv) } if (objc == 3) { char buf[16 + TCL_INTEGER_SPACE * 4]; - + int x, y; xSign = (wmPtr->flags & WM_NEGATIVE_X) ? '-' : '+'; ySign = (wmPtr->flags & WM_NEGATIVE_Y) ? '-' : '+'; if (wmPtr->gridWin != NULL) { @@ -3477,8 +3437,14 @@ WmGeometryCmd(tkwin, winPtr, interp, objc, objv) width = winPtr->changes.width; height = winPtr->changes.height; } - sprintf(buf, "%dx%d%c%d%c%d", width, height, xSign, wmPtr->x, - ySign, wmPtr->y); + if(winPtr->flags & TK_EMBEDDED) { + int result = SendMessage(wmPtr->wrapper, TK_MOVEWINDOW, -1, -1); + wmPtr->x = result >> 16; + wmPtr->y = result & 0x0000ffff; + } + x = wmPtr->x; + y = wmPtr->y; + sprintf(buf, "%dx%d%c%d%c%d", width, height, xSign, x, ySign, y); Tcl_SetResult(interp, buf, TCL_VOLATILE); return TCL_OK; } @@ -4353,8 +4319,8 @@ WmOverrideredirectCmd(tkwin, winPtr, interp, objc, objv) atts.override_redirect = (boolean) ? True : False; Tk_ChangeWindowAttributes((Tk_Window) winPtr, CWOverrideRedirect, &atts); - if (!(wmPtr->flags & (WM_NEVER_MAPPED) - && !(winPtr->flags & TK_EMBEDDED))) { + if (!(wmPtr->flags & (WM_NEVER_MAPPED)) + && !(winPtr->flags & TK_EMBEDDED)) { UpdateWrapper(winPtr); } } @@ -4897,16 +4863,28 @@ WmTitleCmd(tkwin, winPtr, interp, objc, objv) register WmInfo *wmPtr = winPtr->wmInfoPtr; char *argv3; int length; + HWND wrapper; if (objc > 4) { Tcl_WrongNumArgs(interp, 2, objv, "window ?newTitle?"); return TCL_ERROR; } + + if(winPtr->flags & TK_EMBEDDED) { + wrapper = (HWND)SendMessage(wmPtr->wrapper, TK_GETFRAMEWID, 0, 0); + } else { + wrapper = wmPtr->wrapper; + } if (objc == 3) { - Tcl_SetResult(interp, (char *) + if(winPtr->flags & TK_EMBEDDED) { + char buf[256]; + GetWindowText(wrapper, buf, 256); + Tcl_SetResult(interp, buf, TCL_VOLATILE); + } else { + Tcl_SetResult(interp, (char *) ((wmPtr->title != NULL) ? wmPtr->title : winPtr->nameUid), TCL_STATIC); - return TCL_OK; + } } else { if (wmPtr->title != NULL) { ckfree((char *) wmPtr->title); @@ -4918,13 +4896,8 @@ WmTitleCmd(tkwin, winPtr, interp, objc, objv) if (!(wmPtr->flags & WM_NEVER_MAPPED) && wmPtr->wrapper != NULL) { Tcl_DString titleString; Tcl_WinUtfToTChar(wmPtr->title, -1, &titleString); - if(winPtr->flags & TK_EMBEDDED) { - SendMessage(wmPtr->wrapper, TK_TITLE, 0, - (long)(LPCTSTR)Tcl_DStringValue(&titleString)); - } else { - (*tkWinProcs->setWindowText)(wmPtr->wrapper, - (LPCTSTR) Tcl_DStringValue(&titleString)); - } + (*tkWinProcs->setWindowText)(wrapper, + (LPCTSTR) Tcl_DStringValue(&titleString)); Tcl_DStringFree(&titleString); } } @@ -5094,8 +5067,13 @@ WmWithdrawCmd(tkwin, winPtr, interp, objc, objv) (char *) NULL); return TCL_ERROR; } - wmPtr->flags |= WM_WITHDRAWN; - TkpWmSetState(winPtr, WithdrawnState); + + if(winPtr->flags & TK_EMBEDDED) { + SendMessage(wmPtr->wrapper, TK_WITHDRAW, 0, 0); + } else { + wmPtr->flags |= WM_WITHDRAWN; + TkpWmSetState(winPtr, WithdrawnState); + } return TCL_OK; } @@ -7673,3 +7651,165 @@ TkWinSetForegroundWindow(winPtr) SetForegroundWindow(Tk_GetHWND(winPtr->window)); } } + +/* + *---------------------------------------------------------------------- + * + * TkpWinToplevelWithdraw -- + * + * This function is to be used by a window manage to withdraw + * a toplevel window. + * + * Results: + * none + * + * Side effects: + * May withdraw the toplevel window. + * + *---------------------------------------------------------------------- + */ +void +TkpWinToplevelWithDraw(winPtr) + TkWindow *winPtr; +{ + register WmInfo *wmPtr = winPtr->wmInfoPtr; + wmPtr->flags |= WM_WITHDRAWN; + TkpWmSetState(winPtr, WithdrawnState); +} + +/* + *---------------------------------------------------------------------- + * + * TkpWinToplevelIconify -- + * + * This function is to be used by a window manage to iconify + * a toplevel window. + * + * Results: + * none + * + * Side effects: + * May iconify the toplevel window. + * + *---------------------------------------------------------------------- + */ +void TkpWinToplevelIconify(winPtr) + TkWindow *winPtr; +{ + TkpWmSetState(winPtr, IconicState); +} + +/* + *---------------------------------------------------------------------- + * + * TkpWinToplevelDeiconify -- + * + * This function is to be used by a window manage to deiconify + * a toplevel window. + * + * Results: + * none + * + * Side effects: + * May deiconify the toplevel window. + * + *---------------------------------------------------------------------- + */ +void TkpWinToplevelDeiconify(winPtr) + TkWindow *winPtr; +{ + register WmInfo *wmPtr = winPtr->wmInfoPtr; + + wmPtr->flags &= ~WM_WITHDRAWN; + + /* + * If WM_UPDATE_PENDING is true, a pending UpdateGeometryInfo may + * need to be called first to update a withdrawn toplevel's geometry + * before it is deiconified by TkpWmSetState. + * Don't bother if we've never been mapped. + */ + if ((wmPtr->flags & WM_UPDATE_PENDING) && + !(wmPtr->flags & WM_NEVER_MAPPED)) { + Tcl_CancelIdleCall(UpdateGeometryInfo, (ClientData) winPtr); + UpdateGeometryInfo((ClientData) winPtr); + } + + /* + * If we were in the ZoomState (maximized), 'wm deiconify' + * should not cause the window to shrink + */ + if (wmPtr->hints.initial_state == ZoomState) { + TkpWmSetState(winPtr, ZoomState); + } else { + TkpWmSetState(winPtr, NormalState); + } + + /* + * An unmapped window will be mapped at idle time + * by a call to MapFrame. That calls CreateWrapper + * which sets the focus and raises the window. + */ + if (wmPtr->flags & WM_NEVER_MAPPED) { + return; + } + + /* + * Follow Windows-like style here, raising the window to the top. + */ + TkWmRestackToplevel(winPtr, Above, NULL); + if (!(Tk_Attributes((Tk_Window) winPtr)->override_redirect)) { + TkSetFocusWin(winPtr, 1); + } +} + +/* + *---------------------------------------------------------------------- + * + * TkpWinGeometryIsControlledByWm -- + * + * This function is to be used by a window manage to see if + * wm has canceled geometry control. + * + * Results: + * 0 - if the window manager has canceled its control + * 1 - if the window manager controls the geometry + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ +long TkpWinToplevelIsControlledByWm(winPtr) + TkWindow *winPtr; +{ + register WmInfo *wmPtr = winPtr->wmInfoPtr; + return ((wmPtr->width != -1) && (wmPtr->height != -1))? 1:0; +} + +/* + *---------------------------------------------------------------------- + * + * TkpWinToplevelMove -- + * + * This function is to be used by a container to move + * an embedded window. + * + * Results: + * position of the upper left frame in a 32-bit long: + * 16-MSBits - x; 16-LSBits - y + * + * Side effects: + * May move the embedded window. + * + *---------------------------------------------------------------------- + */ +long TkpWinToplevelMove(winPtr, x, y) + TkWindow *winPtr; + int x, y; +{ + register WmInfo *wmPtr = winPtr->wmInfoPtr; + if(!TkpWinToplevelIsControlledByWm(winPtr) && x >= 0 && y >= 0) { + Tk_MoveToplevelWindow((Tk_Window)winPtr, x, y); + } + return ((wmPtr->x << 16) & 0xffff0000) | (wmPtr->y & 0x0000ffff); +} diff --git a/win/tkWinX.c b/win/tkWinX.c index 40abdf9..0b2f8b1 100644 --- a/win/tkWinX.c +++ b/win/tkWinX.c @@ -10,7 +10,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkWinX.c,v 1.37 2004/12/19 18:14:27 chengyemao Exp $ + * RCS: @(#) $Id: tkWinX.c,v 1.38 2004/12/20 01:13:14 chengyemao Exp $ */ #include "tkWinInt.h" @@ -819,7 +819,7 @@ TkWinChildProc(hwnd, message, wParam, lParam) case TK_MOVEWINDOW: case TK_WITHDRAW: case TK_RAISEWINDOW: - case TK_TITLE: + case TK_GETFRAMEWID: result = TkWinEmbeddedEventProc(hwnd, message, wParam, lParam); break; -- cgit v0.12