Tk Source Code

Check-in [8ddfcf75]
Login
Bounty program for improvements to Tcl and certain Tcl packages.
Tcl 2019 Conference, Houston/TX, US, Nov 4-8
Send your abstracts to [email protected]
or submit via the online form by Sep 9.

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Extract implementation of TIP 167 from Ticket [845248]. New [wm attributes]: -contexthelp and -shadow
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | tip-167
Files: files | file ages | folders
SHA3-256: 8ddfcf758514b46200382c0f62dc4efa055726a8829626a49aabdd0b41135316
User & Date: dkf 2019-06-08 16:44:40
Context
2019-06-08
16:44
Extract implementation of TIP 167 from Ticket [845248]. New [wm attributes]: -contexthelp and -shadow Leaf check-in: 8ddfcf75 user: dkf tags: tip-167
2019-06-07
19:12
Fix [c345ddf1a7]: typo in comment of tkMacOSXDraw.c check-in: ff8d6c88 user: fvogel tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to generic/tkInt.h.

957
958
959
960
961
962
963









964
965
966
967
968
969
970
 * bits.
 */

#define META_MASK	(AnyModifier<<1)
#define ALT_MASK	(AnyModifier<<2)
#define EXTENDED_MASK	(AnyModifier<<3)










/*
 * Object types not declared in tkObj.c need to be mentioned here so they can
 * be properly registered with Tcl:
 */

MODULE_SCOPE const Tcl_ObjType tkBorderObjType;
MODULE_SCOPE const Tcl_ObjType tkBitmapObjType;






>
>
>
>
>
>
>
>
>







957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
 * bits.
 */

#define META_MASK	(AnyModifier<<1)
#define ALT_MASK	(AnyModifier<<2)
#define EXTENDED_MASK	(AnyModifier<<3)

/*
 * The following special modifiers are passed to Tk_UpdatePointer to specify
 * respectively that the cursor should not be changed, and to say to update
 * the current position but not to generate button events.
 */

#define NOCURSOR_MASK	(AnyModifier<<4)
#define NOBUTTONEVENTS_MASK	(AnyModifier<<5)

/*
 * Object types not declared in tkObj.c need to be mentioned here so they can
 * be properly registered with Tcl:
 */

MODULE_SCOPE const Tcl_ObjType tkBorderObjType;
MODULE_SCOPE const Tcl_ObjType tkBitmapObjType;

Changes to generic/tkPointer.c.

229
230
231
232
233
234
235
236
237
238
239
240

241
242














243
244
245
246
247
248
249
250
251
252




253
254
255
256
257
258
259
    Tk_Window tkwin,		/* Window to which pointer event is reported.
				 * May be NULL. */
    int x, int y,		/* Pointer location in root coords. */
    int state)			/* Modifier state mask. */
{
    ThreadSpecificData *tsdPtr =
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    TkWindow *winPtr = (TkWindow *)tkwin;
    TkWindow *targetWinPtr;
    XPoint pos;
    XEvent event;
    int changes = (state ^ tsdPtr->lastState) & ALL_BUTTONS;

    int type, b, mask;















    pos.x = x;
    pos.y = y;

    /*
     * Use the current keyboard state, but the old mouse button state since we
     * haven't generated the button events yet.
     */

    tsdPtr->lastState = (state & ~ALL_BUTTONS) | (tsdPtr->lastState
	    & ALL_BUTTONS);





    /*
     * Generate Enter/Leave events. If the pointer has crossed window
     * boundaries, update the current mouse position so we don't generate
     * redundant motion events.
     */







|



|
>
|

>
>
>
>
>
>
>
>
>
>
>
>
>
>










>
>
>
>







229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
    Tk_Window tkwin,		/* Window to which pointer event is reported.
				 * May be NULL. */
    int x, int y,		/* Pointer location in root coords. */
    int state)			/* Modifier state mask. */
{
    ThreadSpecificData *tsdPtr =
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    TkWindow *winPtr = (TkWindow *) tkwin;
    TkWindow *targetWinPtr;
    XPoint pos;
    XEvent event;
    int no_cursor = (state & NOCURSOR_MASK);
    int no_button_events = (state & NOBUTTONEVENTS_MASK);
    int changes, type, b, mask;

    if (state & ALL_BUTTONS) {
	tsdPtr->lastState &= ~NOCURSOR_MASK;
    }
    state &= ~NOCURSOR_MASK & ~NOBUTTONEVENTS_MASK;
    if (no_cursor) {
	tsdPtr->lastState &= ~ALL_BUTTONS;
	tsdPtr->lastState |= (state & ALL_BUTTONS) | NOCURSOR_MASK;
	return;
    } else if (tsdPtr->lastState & NOCURSOR_MASK) {
	tsdPtr->lastState &= ~(NOCURSOR_MASK | ALL_BUTTONS);
	tsdPtr->lastState |= state & ALL_BUTTONS;
	return;
    }
    changes = (state ^ tsdPtr->lastState) & ALL_BUTTONS;
    pos.x = x;
    pos.y = y;

    /*
     * Use the current keyboard state, but the old mouse button state since we
     * haven't generated the button events yet.
     */

    tsdPtr->lastState = (state & ~ALL_BUTTONS) | (tsdPtr->lastState
	    & ALL_BUTTONS);

    if (no_button_events) {
	return;
    }

    /*
     * Generate Enter/Leave events. If the pointer has crossed window
     * boundaries, update the current mouse position so we don't generate
     * redundant motion events.
     */

Changes to win/tkWinCursor.c.

245
246
247
248
249
250
251




252
253
254
255
256
257
258
259
260






261
262
263
264
265
266
267
268
269
270
271
272
 *----------------------------------------------------------------------
 */

void
TkpSetCursor(
    TkpCursor cursor)
{




    HCURSOR hcursor;
    TkWinCursor *winCursor = (TkWinCursor *) cursor;

    if (winCursor == NULL || winCursor->winCursor == NULL) {
	hcursor = LoadCursor(NULL, TK_DEFAULT_CURSOR);
    } else {
	hcursor = winCursor->winCursor;
    }







    if (hcursor != NULL) {
	SetCursor(hcursor);
    }
}
 
/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */






>
>
>
>









>
>
>
>
>
>












245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
 *----------------------------------------------------------------------
 */

void
TkpSetCursor(
    TkpCursor cursor)
{
    static HCURSOR hcursor_idc_help = NULL;
				/* the hcursor_idc_help test is necessary for
				 * the CONTEXT HELP to work by using [wm
				 * attributes $window -contexthelp]. */
    HCURSOR hcursor;
    TkWinCursor *winCursor = (TkWinCursor *) cursor;

    if (winCursor == NULL || winCursor->winCursor == NULL) {
	hcursor = LoadCursor(NULL, TK_DEFAULT_CURSOR);
    } else {
	hcursor = winCursor->winCursor;
    }

    if (hcursor_idc_help == NULL) {
	hcursor_idc_help = LoadCursor(NULL, IDC_HELP);
    }
    if (GetCursor() == hcursor_idc_help) {
	return;
    }
    if (hcursor != NULL) {
	SetCursor(hcursor);
    }
}
 
/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to win/tkWinDialog.c.

665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703

704
705
706
707
708
709
710
 *	windows control (eg a button) then it will be activated by accident.
 *
 * 	This problem does not occur in dialog boxes, because windows must do
 * 	some special processing to solve the problem. (separate message
 * 	processing functions are used to cope with keyboard navigation of
 * 	controls.)
 *
 * 	Here is one solution. After returning, we flush all mouse events
 *      for 1/4 second. In 8.6.5 and earlier, the code used to
 *      poll the message queue consuming WM_LBUTTONUP messages.
 * 	On seeing a WM_LBUTTONDOWN message, it would exit early, since the user
 * 	must be doing something new. However this early exit does not work
 *      on Vista and later because the Windows sends both BUTTONDOWN and
 *      BUTTONUP after the DBLCLICK instead of just BUTTONUP as on XP.
 *      Rather than try and figure out version specific sequences, we
 *      ignore all mouse events in that interval.
 *
 *      This fix only works for the current application, so the problem will
 * 	still occur if the open dialog happens to be over another applications
 * 	button. However this is a fairly rare occurrance.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Consumes unwanted mouse related messages.
 *
 *-------------------------------------------------------------------------
 */

static void
EatSpuriousMessageBugFix(void)
{
    MSG msg;
    DWORD nTime = GetTickCount() + 250;

    while (GetTickCount() < nTime) {
	PeekMessage(&msg, 0, WM_MOUSEFIRST, WM_MOUSELAST, PM_REMOVE);
    }

}
 
/*
 *-------------------------------------------------------------------------
 *
 * TkWinDialogDebug --
 *






<
<
<
<
<
<
<
<
<
<
<
<
<
<












|
<

<
<
<
>







665
666
667
668
669
670
671














672
673
674
675
676
677
678
679
680
681
682
683
684

685



686
687
688
689
690
691
692
693
 *	windows control (eg a button) then it will be activated by accident.
 *
 * 	This problem does not occur in dialog boxes, because windows must do
 * 	some special processing to solve the problem. (separate message
 * 	processing functions are used to cope with keyboard navigation of
 * 	controls.)
 *














 * Results:
 *	None.
 *
 * Side effects:
 *	Consumes unwanted mouse related messages.
 *
 *-------------------------------------------------------------------------
 */

static void
EatSpuriousMessageBugFix(void)
{
    int state = TkWinGetModifierState();





    Tk_UpdatePointer(NULL, 0, 0, state | NOBUTTONEVENTS_MASK);
}
 
/*
 *-------------------------------------------------------------------------
 *
 * TkWinDialogDebug --
 *

Changes to win/tkWinInt.h.

33
34
35
36
37
38
39




40
41
42
43
44
45
46
...
114
115
116
117
118
119
120

121
122
123
124
125
126
127
#ifndef WS_EX_TOOLWINDOW
#define WS_EX_TOOLWINDOW	0x00000080L
#endif
#ifndef SPI_SETKEYBOARDCUES
#define SPI_SETKEYBOARDCUES 0x100B
#endif





/*
 * The TkWinDCState is used to save the state of a device context so that it
 * can be restored later.
 */

typedef struct TkWinDCState {
    HPALETTE palette;
................................................................................
#define TkWinGetPalette(colormap) (((TkWinColormap *) colormap)->palette)

/*
 * The following macros define the class names for Tk Window types.
 */

#define TK_WIN_TOPLEVEL_CLASS_NAME TEXT("TkTopLevel")

#define TK_WIN_CHILD_CLASS_NAME TEXT("TkChild")

/*
 * The following variable is a translation table between X gc functions and
 * Win32 raster and BitBlt op modes.
 */







>
>
>
>







 







>







33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
...
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#ifndef WS_EX_TOOLWINDOW
#define WS_EX_TOOLWINDOW	0x00000080L
#endif
#ifndef SPI_SETKEYBOARDCUES
#define SPI_SETKEYBOARDCUES 0x100B
#endif

#ifndef CS_DROPSHADOW
#define CS_DROPSHADOW		0x00020000
#endif

/*
 * The TkWinDCState is used to save the state of a device context so that it
 * can be restored later.
 */

typedef struct TkWinDCState {
    HPALETTE palette;
................................................................................
#define TkWinGetPalette(colormap) (((TkWinColormap *) colormap)->palette)

/*
 * The following macros define the class names for Tk Window types.
 */

#define TK_WIN_TOPLEVEL_CLASS_NAME TEXT("TkTopLevel")
#define TK_WIN_TOPLEVEL_SHADOW_CLASS_NAME TEXT("TkTopLevelShadow")
#define TK_WIN_CHILD_CLASS_NAME TEXT("TkChild")

/*
 * The following variable is a translation table between X gc functions and
 * Win32 raster and BitBlt op modes.
 */

Changes to win/tkWinWm.c.

331
332
333
334
335
336
337

338
339
340
341
342
343
344
...
898
899
900
901
902
903
904







905
906
907
908
909
910
911
....
1883
1884
1885
1886
1887
1888
1889

1890
1891
1892
1893
1894
1895
1896
....
2126
2127
2128
2129
2130
2131
2132


2133
2134
2135
2136
2137
2138
2139
2140
....
3027
3028
3029
3030
3031
3032
3033
3034
3035

3036
3037
3038
3039
3040
3041
3042
3043
3044

3045
3046

3047
3048
3049
3050
3051
3052
3053
....
3069
3070
3071
3072
3073
3074
3075








3076
3077
3078
3079
3080
3081
3082
....
3089
3090
3091
3092
3093
3094
3095






3096
3097
3098
3099
3100
3101
3102
....
3213
3214
3215
3216
3217
3218
3219









3220
3221
3222
3223
3224
3225
3226
....
3290
3291
3292
3293
3294
3295
3296










3297
3298
3299
3300
3301
3302
3303
....
7859
7860
7861
7862
7863
7864
7865


7866
7867
7868
7869
7870
7871
7872
....
7995
7996
7997
7998
7999
8000
8001













8002
8003
8004
8005
8006
8007
8008
#define WM_MOVE_PENDING			(1<<7)
#define WM_COLORMAPS_EXPLICIT		(1<<8)
#define WM_ADDED_TOPLEVEL_COLORMAP	(1<<9)
#define WM_WIDTH_NOT_RESIZABLE		(1<<10)
#define WM_HEIGHT_NOT_RESIZABLE		(1<<11)
#define WM_WITHDRAWN			(1<<12)
#define WM_FULLSCREEN			(1<<13)


/*
 * Window styles for various types of toplevel windows.
 */

#define WM_OVERRIDE_STYLE (WS_CLIPCHILDREN|WS_CLIPSIBLINGS|CS_DBLCLKS)
#define EX_OVERRIDE_STYLE (WS_EX_TOOLWINDOW)
................................................................................
		tsdPtr->iconPtr = titlebaricon;
	    }
	    class.hCursor = LoadCursor(NULL, IDC_ARROW);

	    if (!RegisterClass(&class)) {
		Tcl_Panic("Unable to register TkTopLevel class");
	    }







	}
	Tcl_MutexUnlock(&winWmMutex);
    }
    return TCL_OK;
}
 
/*
................................................................................

    if (!tsdPtr->initialized) {
	return;
    }
    tsdPtr->initialized = 0;

    UnregisterClass(TK_WIN_TOPLEVEL_CLASS_NAME, hInstance);

}
 
/*
 *--------------------------------------------------------------
 *
 * TkWmNewWindow --
 *
................................................................................
	 */

	tsdPtr->createWindow = winPtr;
	Tcl_WinUtfToTChar(((wmPtr->title != NULL) ?
		wmPtr->title : winPtr->nameUid), -1, &titleString);

	wmPtr->wrapper = CreateWindowEx(wmPtr->exStyle,


		TK_WIN_TOPLEVEL_CLASS_NAME,
		(LPCTSTR) Tcl_DStringValue(&titleString),
		wmPtr->style, x, y, width, height,
		parentHWND, NULL, Tk_GetHINSTANCE(), NULL);
	Tcl_DStringFree(&titleString);
	SetWindowLongPtr(wmPtr->wrapper, GWLP_USERDATA, (LONG_PTR) winPtr);
	tsdPtr->createWindow = NULL;

................................................................................
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    LONG style, exStyle, styleBit, *stylePtr = NULL;
    const char *string;
    int i, boolean;
    size_t length;
    int config_fullscreen = 0, updatewrapper = 0;
    int fullscreen_attr_changed = 0, fullscreen_attr = 0;


    if ((objc < 3) || ((objc > 5) && ((objc%2) == 0))) {
    configArgs:
	Tcl_WrongNumArgs(interp, 2, objv,
		"window"
		" ?-alpha ?double??"
		" ?-transparentcolor ?color??"
		" ?-disabled ?bool??"
		" ?-fullscreen ?bool??"

		" ?-toolwindow ?bool??"
		" ?-topmost ?bool??");

	return TCL_ERROR;
    }
    exStyle = wmPtr->exStyleConfig;
    style = wmPtr->styleConfig;
    if (objc == 3) {
	Tcl_Obj *objPtr = Tcl_NewObj();
	Tcl_ListObjAppendElement(NULL, objPtr,
................................................................................
		Tcl_NewStringObj("-toolwindow", -1));
	Tcl_ListObjAppendElement(NULL, objPtr,
		Tcl_NewWideIntObj((exStyle & WS_EX_TOOLWINDOW) != 0));
	Tcl_ListObjAppendElement(NULL, objPtr,
		Tcl_NewStringObj("-topmost", -1));
	Tcl_ListObjAppendElement(NULL, objPtr,
		Tcl_NewWideIntObj((exStyle & WS_EX_TOPMOST) != 0));








	Tcl_SetObjResult(interp, objPtr);
	return TCL_OK;
    }
    for (i = 3; i < objc; i += 2) {
	string = Tcl_GetString(objv[i]);
	length = objv[i]->length;
	if ((length < 2) || (string[0] != '-')) {
................................................................................
		|| ((length > 2) && (strncmp(string, "-transparentcolor",
			length) == 0))) {
	    stylePtr = &exStyle;
	    styleBit = WS_EX_LAYERED;
	} else if (strncmp(string, "-fullscreen", length) == 0) {
	    config_fullscreen = 1;
	    styleBit = 0;






	} else if ((length > 3)
		&& (strncmp(string, "-toolwindow", length) == 0)) {
	    stylePtr = &exStyle;
	    styleBit = WS_EX_TOOLWINDOW;
	    if (objc != 4) {
		/*
		 * Changes to toolwindow style require an update
................................................................................
		    Tcl_SetObjResult(interp, Tcl_NewWideIntObj(
			    (wmPtr->flags & WM_FULLSCREEN) != 0));
		} else {
		    fullscreen_attr_changed = 1;
		    fullscreen_attr = boolean;
		}
		config_fullscreen = 0;









	    } else if (objc == 4) {
		Tcl_SetObjResult(interp,
			Tcl_NewWideIntObj((*stylePtr & styleBit) != 0));
	    } else if (boolean) {
		*stylePtr |= styleBit;
	    } else {
		*stylePtr &= ~styleBit;
................................................................................
			" max width/height is too small", winPtr->pathName));
		Tcl_SetErrorCode(interp, "TK", "WM", "ATTR", "SMALL_MAX", NULL);
		return TCL_ERROR;
	    }
	}

	TkpWmSetFullScreen(winPtr, fullscreen_attr);










    }

    return TCL_OK;
}
 
/*
 *----------------------------------------------------------------------
................................................................................
    static int oldMode;		/* This static is set upon entering move/size
				 * mode and is used to reset the service mode
				 * after leaving move/size mode. Note that
				 * this mechanism assumes move/size is only
				 * one level deep. */
    LRESULT result = 0;
    TkWindow *winPtr = NULL;



    switch (message) {
    case WM_KILLFOCUS:
    case WM_ERASEBKGND:
	result = 0;
	goto done;

................................................................................
	     */

	    result = HTCLIENT;
	    goto done;
	}
	break;
    }














    case WM_MOUSEACTIVATE: {
	winPtr = GetTopLevel((HWND) wParam);
	if (winPtr && (TkGrabState(winPtr) != TK_GRAB_EXCLUDED)) {
	    /*
	     * This allows us to pass the message onto the native menus [Bug:
	     * 2272]






>







 







>
>
>
>
>
>
>







 







>







 







>
>
|







 







|

>






|


>

|
>







 







>
>
>
>
>
>
>
>







 







>
>
>
>
>
>







 







>
>
>
>
>
>
>
>
>







 







>
>
>
>
>
>
>
>
>
>







 







>
>







 







>
>
>
>
>
>
>
>
>
>
>
>
>







331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
...
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
....
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
....
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
....
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
....
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
....
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
....
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
....
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
....
7906
7907
7908
7909
7910
7911
7912
7913
7914
7915
7916
7917
7918
7919
7920
7921
....
8044
8045
8046
8047
8048
8049
8050
8051
8052
8053
8054
8055
8056
8057
8058
8059
8060
8061
8062
8063
8064
8065
8066
8067
8068
8069
8070
#define WM_MOVE_PENDING			(1<<7)
#define WM_COLORMAPS_EXPLICIT		(1<<8)
#define WM_ADDED_TOPLEVEL_COLORMAP	(1<<9)
#define WM_WIDTH_NOT_RESIZABLE		(1<<10)
#define WM_HEIGHT_NOT_RESIZABLE		(1<<11)
#define WM_WITHDRAWN			(1<<12)
#define WM_FULLSCREEN			(1<<13)
#define WM_DROPSHADOW			(1<<14)

/*
 * Window styles for various types of toplevel windows.
 */

#define WM_OVERRIDE_STYLE (WS_CLIPCHILDREN|WS_CLIPSIBLINGS|CS_DBLCLKS)
#define EX_OVERRIDE_STYLE (WS_EX_TOOLWINDOW)
................................................................................
		tsdPtr->iconPtr = titlebaricon;
	    }
	    class.hCursor = LoadCursor(NULL, IDC_ARROW);

	    if (!RegisterClass(&class)) {
		Tcl_Panic("Unable to register TkTopLevel class");
	    }

	    class.style = CS_HREDRAW | CS_VREDRAW | CS_DROPSHADOW;
	    class.lpszClassName = TK_WIN_TOPLEVEL_SHADOW_CLASS_NAME;

	    if (!RegisterClass(&class)) {
		Tcl_Panic("Unable to register TkTopLevelShadow class");
	    }
	}
	Tcl_MutexUnlock(&winWmMutex);
    }
    return TCL_OK;
}
 
/*
................................................................................

    if (!tsdPtr->initialized) {
	return;
    }
    tsdPtr->initialized = 0;

    UnregisterClass(TK_WIN_TOPLEVEL_CLASS_NAME, hInstance);
    Unregisterclass(TK_WIN_TOPLEVEL_SHADOW_CLASS_NAME, hInstance);
}
 
/*
 *--------------------------------------------------------------
 *
 * TkWmNewWindow --
 *
................................................................................
	 */

	tsdPtr->createWindow = winPtr;
	Tcl_WinUtfToTChar(((wmPtr->title != NULL) ?
		wmPtr->title : winPtr->nameUid), -1, &titleString);

	wmPtr->wrapper = CreateWindowEx(wmPtr->exStyle,
		(wmPtr->flags & WM_DROPSHADOW
			? TK_WIN_TOPLEVEL_SHADOW_CLASS_NAME
			: TK_WIN_TOPLEVEL_CLASS_NAME),
		(LPCTSTR) Tcl_DStringValue(&titleString),
		wmPtr->style, x, y, width, height,
		parentHWND, NULL, Tk_GetHINSTANCE(), NULL);
	Tcl_DStringFree(&titleString);
	SetWindowLongPtr(wmPtr->wrapper, GWLP_USERDATA, (LONG_PTR) winPtr);
	tsdPtr->createWindow = NULL;

................................................................................
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    LONG style, exStyle, styleBit, *stylePtr = NULL;
    const char *string;
    int i, boolean;
    size_t length;
    int config_fullscreen = 0, config_shadow = 0, updatewrapper = 0;
    int fullscreen_attr_changed = 0, fullscreen_attr = 0;
    int shadow_attr_changed = 0, shadow_attr = 0;

    if ((objc < 3) || ((objc > 5) && ((objc%2) == 0))) {
    configArgs:
	Tcl_WrongNumArgs(interp, 2, objv,
		"window"
		" ?-alpha ?double??"
		" ?-contexthelp ?bool??"
		" ?-disabled ?bool??"
		" ?-fullscreen ?bool??"
		" ?-shadow ?bool??"
		" ?-toolwindow ?bool??"
		" ?-topmost ?bool??"
		" ?-transparentcolor ?color??");
	return TCL_ERROR;
    }
    exStyle = wmPtr->exStyleConfig;
    style = wmPtr->styleConfig;
    if (objc == 3) {
	Tcl_Obj *objPtr = Tcl_NewObj();
	Tcl_ListObjAppendElement(NULL, objPtr,
................................................................................
		Tcl_NewStringObj("-toolwindow", -1));
	Tcl_ListObjAppendElement(NULL, objPtr,
		Tcl_NewWideIntObj((exStyle & WS_EX_TOOLWINDOW) != 0));
	Tcl_ListObjAppendElement(NULL, objPtr,
		Tcl_NewStringObj("-topmost", -1));
	Tcl_ListObjAppendElement(NULL, objPtr,
		Tcl_NewWideIntObj((exStyle & WS_EX_TOPMOST) != 0));
	Tcl_ListObjAppendElement(NULL, objPtr,
		Tcl_NewStringObj("-contexthelp", -1));
	Tcl_ListObjAppendElement(NULL, objPtr,
		Tcl_NewBooleanObj((style & WS_EX_CONTEXTHELP) != 0));
	Tcl_ListObjAppendElement(NULL, objPtr,
		Tcl_NewStringObj("-shadow", -1));
	Tcl_ListObjAppendElement(NULL, objPtr,
		Tcl_NewBooleanObj((wmPtr->flags & WM_DROPSHADOW) != 0));
	Tcl_SetObjResult(interp, objPtr);
	return TCL_OK;
    }
    for (i = 3; i < objc; i += 2) {
	string = Tcl_GetString(objv[i]);
	length = objv[i]->length;
	if ((length < 2) || (string[0] != '-')) {
................................................................................
		|| ((length > 2) && (strncmp(string, "-transparentcolor",
			length) == 0))) {
	    stylePtr = &exStyle;
	    styleBit = WS_EX_LAYERED;
	} else if (strncmp(string, "-fullscreen", length) == 0) {
	    config_fullscreen = 1;
	    styleBit = 0;
	} else if (strncmp(string, "-shadow", (unsigned) length) == 0) {
	    config_shadow = 1;
	    styleBit = 0;
	} else if (strncmp(string,"-contexthelp", length) == 0) {
	    stylePtr = &exStyle;
	    styleBit = WS_EX_CONTEXTHELP;
	} else if ((length > 3)
		&& (strncmp(string, "-toolwindow", length) == 0)) {
	    stylePtr = &exStyle;
	    styleBit = WS_EX_TOOLWINDOW;
	    if (objc != 4) {
		/*
		 * Changes to toolwindow style require an update
................................................................................
		    Tcl_SetObjResult(interp, Tcl_NewWideIntObj(
			    (wmPtr->flags & WM_FULLSCREEN) != 0));
		} else {
		    fullscreen_attr_changed = 1;
		    fullscreen_attr = boolean;
		}
		config_fullscreen = 0;
	    } else if (config_shadow) {
		if (objc == 4) {
		    Tcl_SetBooleanObj(Tcl_GetObjResult(interp),
			    (wmPtr->flags & WM_DROPSHADOW) != 0);
		} else {
		    shadow_attr_changed = 1;
		    shadow_attr = boolean;
		}
		config_shadow = 0;
	    } else if (objc == 4) {
		Tcl_SetObjResult(interp,
			Tcl_NewWideIntObj((*stylePtr & styleBit) != 0));
	    } else if (boolean) {
		*stylePtr |= styleBit;
	    } else {
		*stylePtr &= ~styleBit;
................................................................................
			" max width/height is too small", winPtr->pathName));
		Tcl_SetErrorCode(interp, "TK", "WM", "ATTR", "SMALL_MAX", NULL);
		return TCL_ERROR;
	    }
	}

	TkpWmSetFullScreen(winPtr, fullscreen_attr);
    }
    if (shadow_attr_changed) {
	if (shadow_attr) {
	    wmPtr->flags |= WM_DROPSHADOW;
	} else {
	    wmPtr->flags &= ~WM_DROPSHADOW;
	}
	if (!(wmPtr->flags & WM_NEVER_MAPPED)) {
	    UpdateWrapper(winPtr);
	}
    }

    return TCL_OK;
}
 
/*
 *----------------------------------------------------------------------
................................................................................
    static int oldMode;		/* This static is set upon entering move/size
				 * mode and is used to reset the service mode
				 * after leaving move/size mode. Note that
				 * this mechanism assumes move/size is only
				 * one level deep. */
    LRESULT result = 0;
    TkWindow *winPtr = NULL;
    POINT point;
    int state;

    switch (message) {
    case WM_KILLFOCUS:
    case WM_ERASEBKGND:
	result = 0;
	goto done;

................................................................................
	     */

	    result = HTCLIENT;
	    goto done;
	}
	break;
    }

    case WM_NCLBUTTONDOWN:
    case WM_NCLBUTTONDBLCLK:
    case WM_NCLBUTTONUP:
    case WM_NCMBUTTONDOWN:
    case WM_NCMBUTTONDBLCLK:
    case WM_NCMBUTTONUP:
    case WM_NCRBUTTONDOWN:
    case WM_NCRBUTTONDBLCLK:
    case WM_NCRBUTTONUP: 
	Tk_UpdatePointer(NULL, 0, 0, TkWinGetModifierState() | NOCURSOR_MASK);
	result = (*tkWinProcs->defWindowProc)(hwnd, message, wParam, lParam);
	goto done;

    case WM_MOUSEACTIVATE: {
	winPtr = GetTopLevel((HWND) wParam);
	if (winPtr && (TkGrabState(winPtr) != TK_GRAB_EXCLUDED)) {
	    /*
	     * This allows us to pass the message onto the native menus [Bug:
	     * 2272]

Changes to win/tkWinX.c.

699
700
701
702
703
704
705























































706
707
708
709
710
711
712
...
722
723
724
725
726
727
728







729
730
731
732
733
734
735
    MessageBeep(MB_OK);
    return Success;
}
 
/*
 *----------------------------------------------------------------------
 *























































 * TkWinChildProc --
 *
 *	Callback from Windows whenever an event occurs on a child window.
 *
 * Results:
 *	Standard Windows return value.
 *
................................................................................
    UINT message,
    WPARAM wParam,
    LPARAM lParam)
{
    LRESULT result;

    switch (message) {







    case WM_INPUTLANGCHANGE:
	UpdateInputLanguage((int) wParam);
	result = 1;
	break;

    case WM_IME_COMPOSITION:
	result = 0;






>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>
>
>
>
>
>
>







699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
...
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
    MessageBeep(MB_OK);
    return Success;
}
 
/*
 *----------------------------------------------------------------------
 *
 * HelpEvent --
 *
 *	Generates a "Help" virtual event. This can be used to do
 *	context-sensitive help.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Places a virtual event on the event queue.
 *
 *----------------------------------------------------------------------
 */

static void
HelpEvent(
    HWND hwnd,
    UINT message,
    WPARAM wParam,
    LPARAM lParam)
{
    TkWindow *winPtr = (TkWindow *) Tk_HWNDToWindow(hwnd);
    XVirtualEvent event;
    POINTS rootPoint;
    POINT clientPoint;
    DWORD msgPos;

    event.type = VirtualEvent;
    event.serial = winPtr->display->request;
    event.send_event = 0;
    event.display = winPtr->display;
    event.event = Tk_WindowId(winPtr);
    event.root = XRootWindow(winPtr->display, 0);
    event.subwindow = None;
    event.time = TkpGetMS();

    msgPos = GetMessagePos();
    rootPoint = MAKEPOINTS(msgPos);
    clientPoint.x = rootPoint.x;
    clientPoint.y = rootPoint.y;
    ScreenToClient(hwnd, &clientPoint);
    event.x = clientPoint.x;
    event.y = clientPoint.y;
    event.x_root = rootPoint.x;
    event.y_root = rootPoint.y;
    event.state = TkWinGetModifierState();
    event.same_screen = 1;
    event.name = Tk_GetUid("Help");
    event.user_data = NULL;
    Tk_QueueWindowEvent((XEvent *) &event, TCL_QUEUE_TAIL);
}
 
/*
 *----------------------------------------------------------------------
 *
 * TkWinChildProc --
 *
 *	Callback from Windows whenever an event occurs on a child window.
 *
 * Results:
 *	Standard Windows return value.
 *
................................................................................
    UINT message,
    WPARAM wParam,
    LPARAM lParam)
{
    LRESULT result;

    switch (message) {
    case WM_HELP:
	Tk_UpdatePointer(NULL, 0, 0,
		TkWinGetModifierState() | NOBUTTONEVENTS_MASK);
	HelpEvent(hwnd, message, wParam, lParam);
	result = DefWindowProc(hwnd, message, wParam, lParam);
	break;

    case WM_INPUTLANGCHANGE:
	UpdateInputLanguage((int) wParam);
	result = 1;
	break;

    case WM_IME_COMPOSITION:
	result = 0;