Check-in [377a6871aa]
Not logged in

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

Overview
Comment:merge with trunk
Timelines: family | ancestors | descendants | both | wtf-8-experiment
Files: files | file ages | folders
SHA1: 377a6871aa286714d7ad2f79ad92e1daf48c6740
User & Date: chw 2019-09-24 05:01:11
Context
2019-09-25
06:31
merge with trunk check-in: 8db9fa7370 user: chw tags: wtf-8-experiment
2019-09-24
05:01
merge with trunk check-in: 377a6871aa user: chw tags: wtf-8-experiment
04:59
add selected tk upstream changes check-in: 5a80b8cc36 user: chw tags: trunk
2019-09-23
04:45
merge with trunk check-in: ef359f628c user: chw tags: wtf-8-experiment
Changes

Changes to jni/sdl2tk/doc/ttk_labelframe.n.

26
27
28
29
30
31
32




33
34
35
36
37
38
39
40
41
42






43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
.\" XXX: .OP -borderwidth borderWidth BorderWidth
.\" XXX: The desired width of the widget border.  Default is theme-dependent.
.\" XXX: .OP -relief relief Relief
.\" XXX: One of the standard Tk border styles:
.\" XXX: \fBflat\fR, \fBgroove\fR, \fBraised\fR, \fBridge\fR,
.\" XXX: \fBsolid\fR, or \fBsunken\fR.
.\" XXX: Default is theme-dependent.




.OP \-labelanchor labelAnchor LabelAnchor
Specifies where to place the label.
Allowed values are (clockwise from the top upper left corner):
\fBnw\fR, \fBn\fR, \fBne\fR, \fBen\fR, \fBe\fR, \fBes\fR,
\fBse\fR, \fBs\fR,\fBsw\fR, \fBws\fR, \fBw\fR and \fBwn\fR.
The default value is theme-dependent.
.\" Alternate explanation: The first character must be one of n, s, e, or w
.\" and specifies which side the label should be placed on;
.\" the remaining characters specify how the label is aligned on that side.
.\" NOTE: Now allows other values as well; leave this undocumented for now






.OP \-text text Text
Specifies the text of the label.
.OP \-underline underline Underline
If set, specifies the integer index (0-based) of a character to
underline in the text string.
The underlined character is used for mnemonic activation.
Mnemonic activation for a \fBttk::labelframe\fR
sets the keyboard focus to the first child of the \fBttk::labelframe\fR widget.
.OP \-labelwidget labelWidget LabelWidget
The name of a widget to use for the label.
If set, overrides the \fB\-text\fR option.
The \fB\-labelwidget\fR must be a child of the \fBlabelframe\fR widget
or one of the \fBlabelframe\fR's ancestors, and must belong to the
same top-level widget as the \fBlabelframe\fR.
.OP \-width width Width
If specified, the widget's requested width in pixels.
.OP \-height height Height
If specified, the widget's requested height in pixels.
(See \fIttk::frame(n)\fR for further notes on \fB\-width\fR and
\fB\-height\fR).
.SH "WIDGET COMMAND"
.PP
Supports the standard widget commands
\fBconfigure\fR, \fBcget\fR, \fBidentify\fR, \fBinstate\fR, and \fBstate\fR;
see \fIttk::widget(n)\fR.
.SH "STYLING OPTIONS"
.PP







>
>
>
>










>
>
>
>
>
>








<
<
<
<
<
<


<
<
<
<







26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60






61
62




63
64
65
66
67
68
69
.\" XXX: .OP -borderwidth borderWidth BorderWidth
.\" XXX: The desired width of the widget border.  Default is theme-dependent.
.\" XXX: .OP -relief relief Relief
.\" XXX: One of the standard Tk border styles:
.\" XXX: \fBflat\fR, \fBgroove\fR, \fBraised\fR, \fBridge\fR,
.\" XXX: \fBsolid\fR, or \fBsunken\fR.
.\" XXX: Default is theme-dependent.
.OP \-height height Height
If specified, the widget's requested height in pixels.
(See \fIttk::frame(n)\fR for further notes on \fB\-width\fR and
\fB\-height\fR).
.OP \-labelanchor labelAnchor LabelAnchor
Specifies where to place the label.
Allowed values are (clockwise from the top upper left corner):
\fBnw\fR, \fBn\fR, \fBne\fR, \fBen\fR, \fBe\fR, \fBes\fR,
\fBse\fR, \fBs\fR,\fBsw\fR, \fBws\fR, \fBw\fR and \fBwn\fR.
The default value is theme-dependent.
.\" Alternate explanation: The first character must be one of n, s, e, or w
.\" and specifies which side the label should be placed on;
.\" the remaining characters specify how the label is aligned on that side.
.\" NOTE: Now allows other values as well; leave this undocumented for now
.OP \-labelwidget labelWidget LabelWidget
The name of a widget to use for the label.
If set, overrides the \fB\-text\fR option.
The \fB\-labelwidget\fR must be a child of the \fBlabelframe\fR widget
or one of the \fBlabelframe\fR's ancestors, and must belong to the
same top-level widget as the \fBlabelframe\fR.
.OP \-text text Text
Specifies the text of the label.
.OP \-underline underline Underline
If set, specifies the integer index (0-based) of a character to
underline in the text string.
The underlined character is used for mnemonic activation.
Mnemonic activation for a \fBttk::labelframe\fR
sets the keyboard focus to the first child of the \fBttk::labelframe\fR widget.






.OP \-width width Width
If specified, the widget's requested width in pixels.




.SH "WIDGET COMMAND"
.PP
Supports the standard widget commands
\fBconfigure\fR, \fBcget\fR, \fBidentify\fR, \fBinstate\fR, and \fBstate\fR;
see \fIttk::widget(n)\fR.
.SH "STYLING OPTIONS"
.PP

Changes to jni/sdl2tk/win/tkWinButton.c.

238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
...
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
...
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
....
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
CreateProc(
    Tk_Window tkwin,		/* Token for window. */
    Window parentWin,		/* Parent of new window. */
    ClientData instanceData)	/* Button instance data. */
{
    Window window;
    HWND parent;
    const WCHAR *class;
    WinButton *butPtr = (WinButton *)instanceData;

    parent = Tk_GetHWND(parentWin);
    if (butPtr->info.type == TYPE_LABEL) {
	class = L"STATIC";
	butPtr->style = SS_OWNERDRAW | WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS;
    } else {
................................................................................
	butPtr->style = BS_OWNERDRAW | WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS;
    }
    butPtr->hwnd = CreateWindowW(class, NULL, butPtr->style,
	    Tk_X(tkwin), Tk_Y(tkwin), Tk_Width(tkwin), Tk_Height(tkwin),
	    parent, NULL, Tk_GetHINSTANCE(), NULL);
    SetWindowPos(butPtr->hwnd, HWND_TOP, 0, 0, 0, 0,
		    SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
    butPtr->oldProc = (WNDPROC)SetWindowLongPtr(butPtr->hwnd, GWLP_WNDPROC,
	    (LONG_PTR) ButtonProc);

    window = Tk_AttachHWND(tkwin, butPtr->hwnd);
    return window;
}
 
/*
................................................................................
TkpDestroyButton(
    TkButton *butPtr)
{
    WinButton *winButPtr = (WinButton *)butPtr;
    HWND hwnd = winButPtr->hwnd;

    if (hwnd) {
	SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR) winButPtr->oldProc);
    }
}
 
/*
 *----------------------------------------------------------------------
 *
 * TkpDisplayButton --
................................................................................
    }
    /* FALLTHRU */
    default:
	if (Tk_TranslateWinEvent(hwnd, message, wParam, lParam, &result)) {
	    return result;
	}
    }
    return DefWindowProc(hwnd, message, wParam, lParam);
}
 
/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







|







 







|







 







|







 







|









238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
...
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
...
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
....
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
CreateProc(
    Tk_Window tkwin,		/* Token for window. */
    Window parentWin,		/* Parent of new window. */
    ClientData instanceData)	/* Button instance data. */
{
    Window window;
    HWND parent;
    LPCWSTR class;
    WinButton *butPtr = (WinButton *)instanceData;

    parent = Tk_GetHWND(parentWin);
    if (butPtr->info.type == TYPE_LABEL) {
	class = L"STATIC";
	butPtr->style = SS_OWNERDRAW | WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS;
    } else {
................................................................................
	butPtr->style = BS_OWNERDRAW | WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS;
    }
    butPtr->hwnd = CreateWindowW(class, NULL, butPtr->style,
	    Tk_X(tkwin), Tk_Y(tkwin), Tk_Width(tkwin), Tk_Height(tkwin),
	    parent, NULL, Tk_GetHINSTANCE(), NULL);
    SetWindowPos(butPtr->hwnd, HWND_TOP, 0, 0, 0, 0,
		    SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
    butPtr->oldProc = (WNDPROC)SetWindowLongPtrW(butPtr->hwnd, GWLP_WNDPROC,
	    (LONG_PTR) ButtonProc);

    window = Tk_AttachHWND(tkwin, butPtr->hwnd);
    return window;
}
 
/*
................................................................................
TkpDestroyButton(
    TkButton *butPtr)
{
    WinButton *winButPtr = (WinButton *)butPtr;
    HWND hwnd = winButPtr->hwnd;

    if (hwnd) {
	SetWindowLongPtrW(hwnd, GWLP_WNDPROC, (LONG_PTR) winButPtr->oldProc);
    }
}
 
/*
 *----------------------------------------------------------------------
 *
 * TkpDisplayButton --
................................................................................
    }
    /* FALLTHRU */
    default:
	if (Tk_TranslateWinEvent(hwnd, message, wParam, lParam, &result)) {
	    return result;
	}
    }
    return DefWindowProcW(hwnd, message, wParam, lParam);
}
 
/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to jni/sdl2tk/win/tkWinColor.c.

343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
	if ((index >= cmap->size) || (newPixel != closePixel)) {
	    if (cmap->size == sizePalette) {
		color->red   = closeEntry.peRed * 257;
		color->green = closeEntry.peGreen * 257;
		color->blue  = closeEntry.peBlue * 257;
		entry = closeEntry;
		if (index >= cmap->size) {
		    OutputDebugStringA("XAllocColor: Colormap is bigger than we thought");
		}
	    } else {
		cmap->size++;
		ResizePalette(cmap->palette, cmap->size);
		SetPaletteEntries(cmap->palette, cmap->size - 1, 1, &entry);
	    }
	}







|







343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
	if ((index >= cmap->size) || (newPixel != closePixel)) {
	    if (cmap->size == sizePalette) {
		color->red   = closeEntry.peRed * 257;
		color->green = closeEntry.peGreen * 257;
		color->blue  = closeEntry.peBlue * 257;
		entry = closeEntry;
		if (index >= cmap->size) {
		    OutputDebugStringW(L"XAllocColor: Colormap is bigger than we thought");
		}
	    } else {
		cmap->size++;
		ResizePalette(cmap->palette, cmap->size);
		SetPaletteEntries(cmap->palette, cmap->size - 1, 1, &entry);
	    }
	}

Changes to jni/sdl2tk/win/tkWinDialog.c.

36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
...
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
...
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
....
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
....
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
....
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
....
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
....
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
....
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
....
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
....
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
....
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
....
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
....
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
....
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
....
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
....
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
#endif

/* This "new" dialog style is now actually the "old" dialog style post-Vista */
#ifndef BIF_NEWDIALOGSTYLE
#define BIF_NEWDIALOGSTYLE 0x0040
#endif

#ifndef BFFM_VALIDATEFAILED
#ifdef UNICODE
#define BFFM_VALIDATEFAILED 4
#else
#define BFFM_VALIDATEFAILED 3
#endif
#endif /* BFFM_VALIDATEFAILED */

typedef struct {
    int debugFlag;		/* Flags whether we should output debugging
				 * information while displaying a builtin
				 * dialog. */
    Tcl_Interp *debugInterp;	/* Interpreter to used for debugging. */
    UINT WM_LBSELCHANGED;	/* Holds a registered windows event used for
................................................................................
#define NUM_TYPES (sizeof(allowedTypes) / sizeof(allowedTypes[0]))

/*
 * Abstract trivial differences between Win32 and Win64.
 */

#define TkWinGetHInstance(from) \
	((HINSTANCE) GetWindowLongPtr((from), GWLP_HINSTANCE))
#define TkWinGetUserData(from) \
	GetWindowLongPtr((from), GWLP_USERDATA)
#define TkWinSetUserData(to,what) \
	SetWindowLongPtr((to), GWLP_USERDATA, (LPARAM)(what))

/*
 * The value of TK_MULTI_MAX_PATH dictates how many files can be retrieved
 * with tk_get*File -multiple 1. It must be allocated on the stack, so make it
 * large enough but not too large. - hobbs
 *
 * The data is stored as <dir>\0<file1>\0<file2>\0...<fileN>\0\0. Since
................................................................................
static void
EatSpuriousMessageBugFix(void)
{
    MSG msg;
    DWORD nTime = GetTickCount() + 250;

    while (GetTickCount() < nTime) {
	PeekMessage(&msg, 0, WM_MOUSEFIRST, WM_MOUSELAST, PM_REMOVE);
    }
}
 
/*
 *-------------------------------------------------------------------------
 *
 * TkWinDialogDebug --
................................................................................
    if (Tcl_DStringValue(&optsPtr->utfDirString)[0] != '\0') {
        Tcl_Obj *normPath, *iniDirPath;
        iniDirPath = Tcl_NewStringObj(Tcl_DStringValue(&optsPtr->utfDirString), -1);
        Tcl_IncrRefCount(iniDirPath);
        normPath = Tcl_FSGetNormalizedPath(interp, iniDirPath);
        /* XXX - Note on failures do not raise error, simply ignore ini dir */
        if (normPath) {
            const WCHAR *nativePath;
            Tcl_IncrRefCount(normPath);
            nativePath = Tcl_FSGetNativePath(normPath); /* Points INTO normPath*/
            if (nativePath) {
                hr = ShellProcs.SHCreateItemFromParsingName(
                    nativePath, NULL,
                    &IIDIShellItem, (void **) &dirIf);
                if (SUCCEEDED(hr)) {
................................................................................
	     */

	    ofnPtr = notifyPtr->lpOFN;
	    ofnData = (OFNData *) ofnPtr->lCustData;
	    buffer = ofnData->dynFileBuffer;
	    hdlg = GetParent(hdlg);

	    selsize = (int) SendMessage(hdlg, CDM_GETSPEC, 0, 0);
	    dirsize = (int) SendMessage(hdlg, CDM_GETFOLDERPATH, 0, 0);
	    buffersize = (selsize + dirsize + 1);

	    /*
	     * Just empty the buffer if dirsize indicates an error. [Bug
	     * 3071836]
	     */

................................................................................
	    if ((selsize > 1) && (dirsize > 0)) {
		if (ofnData->dynFileBufferSize < buffersize) {
		    buffer = ckrealloc(buffer, buffersize * sizeof(WCHAR));
		    ofnData->dynFileBufferSize = buffersize;
		    ofnData->dynFileBuffer = buffer;
		}

		SendMessage(hdlg, CDM_GETFOLDERPATH, dirsize, (LPARAM) buffer);
		buffer += dirsize;

		SendMessage(hdlg, CDM_GETSPEC, selsize, (LPARAM) buffer);

		/*
		 * If there are multiple files, delete the quotes and change
		 * every second quote to NULL terminator
		 */

		if (buffer[0] == '"') {
................................................................................

		    Tcl_DString tmpfile;
		    ConvertExternalFilename(buffer, &tmpfile);
		    if (TCL_PATH_ABSOLUTE ==
			    Tcl_GetPathType(Tcl_DStringValue(&tmpfile))) {
			/* re-get the full path to the start of the buffer */
			buffer = (WCHAR *) ofnData->dynFileBuffer;
			SendMessage(hdlg, CDM_GETSPEC, selsize, (LPARAM) buffer);
		    } else {
			*(buffer-1) = '\\';
		    }
		    buffer[selsize] = '\0'; /* Second NULL terminator. */
		    Tcl_DStringFree(&tmpfile);
		}
	    } else {
................................................................................
    path[0] = '\0';
    ZeroMemory(&cdCBData, sizeof(ChooseDir));
    cdCBData.interp = interp;
    cdCBData.mustExist = ofnOpts.mustExist;

    utfDir = Tcl_DStringValue(&ofnOpts.utfDirString);
    if (utfDir[0] != '\0') {
	const WCHAR *uniStr;

        Tcl_WinUtfToTChar(Tcl_DStringValue(&ofnOpts.utfDirString), -1,
                          &tempString);
        uniStr = (WCHAR *) Tcl_DStringValue(&tempString);

        /* Convert possible relative path to full path to keep dialog happy. */

................................................................................

    if (tsdPtr->debugFlag) {
	tsdPtr->debugInterp = (Tcl_Interp *) chooseDirSharedData->interp;
	Tcl_DoWhenIdle(SetTkDialog, hwnd);
    }
    chooseDirSharedData->retDir[0] = '\0';
    switch (message) {
    case BFFM_VALIDATEFAILED:
	/*
	 * First save and check to see if it is a valid path name, if so then
	 * make that path the one shown in the window. Otherwise, it failed
	 * the check and should be treated as such. Use
	 * Set/GetCurrentDirectory which allows relative path names and names
	 * with forward slashes. Use Tcl_TranslateFileName to make sure names
	 * like ~ are converted correctly.
................................................................................
	 * for things like server names. Perhaps a new switch
	 * -enablenonfolders can be used to allow non folders to be selected.
	 *
	 * Not called when user changes edit box directly.
	 */

	if (SHGetPathFromIDListW((LPITEMIDLIST) lParam, selDir)) {
	    SendMessage(hwnd, BFFM_SETSTATUSTEXT, 0, (LPARAM) selDir);
	    // enable the OK button
	    SendMessage(hwnd, BFFM_ENABLEOK, 0, (LPARAM) 1);
	} else {
	    // disable the OK button
	    SendMessage(hwnd, BFFM_ENABLEOK, 0, (LPARAM) 0);
	}
	UpdateWindow(hwnd);
	return 1;

    case BFFM_INITIALIZED: {
	/*
	 * Directory browser initializing - tell it where to start from, user
................................................................................

	WCHAR *initDir = chooseDirSharedData->initDir;

	SetCurrentDirectoryW(initDir);

	if (*initDir == '\\') {
	    /*
	     * BFFM_SETSELECTION only understands UNC paths as pidls, so
	     * convert path to pidl using IShellFolder interface.
	     */

	    LPMALLOC pMalloc;
	    LPSHELLFOLDER psfFolder;

	    if (SUCCEEDED(SHGetMalloc(&pMalloc))) {
................................................................................
		    LPITEMIDLIST pidlMain;
		    ULONG ulCount, ulAttr;

		    if (SUCCEEDED(psfFolder->lpVtbl->ParseDisplayName(
			    psfFolder, hwnd, NULL, (WCHAR *)
			    initDir, &ulCount,&pidlMain,&ulAttr))
			    && (pidlMain != NULL)) {
			SendMessage(hwnd, BFFM_SETSELECTION, FALSE,
				(LPARAM) pidlMain);
			pMalloc->lpVtbl->Free(pMalloc, pidlMain);
		    }
		    psfFolder->lpVtbl->Release(psfFolder);
		}
		pMalloc->lpVtbl->Release(pMalloc);
	    }
	} else {
	    SendMessage(hwnd, BFFM_SETSELECTION, TRUE, (LPARAM) initDir);
	}
	SendMessage(hwnd, BFFM_ENABLEOK, 0, (LPARAM) 1);
	break;
    }

    }
    return 0;
}
 
................................................................................
    enum options {
	MSG_DEFAULT,	MSG_DETAIL,	MSG_ICON,	MSG_MESSAGE,
	MSG_PARENT,	MSG_TITLE,	MSG_TYPE
    };
    ThreadSpecificData *tsdPtr =
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    Tcl_DString titleBuf, tmpBuf;
    const WCHAR *titlePtr, *tmpPtr;
    const char *src;

    defaultBtn = -1;
    detailObj = NULL;
    icon = MB_ICONINFORMATION;
    messageObj = NULL;
    parent = tkwin;
................................................................................
     * In order to have the parent window icon reflected in a MessageBox, we
     * have to create a hook that will trigger when the MessageBox is being
     * created.
     */

    tsdPtr->hSmallIcon = TkWinGetIcon(parent, ICON_SMALL);
    tsdPtr->hBigIcon   = TkWinGetIcon(parent, ICON_BIG);
    tsdPtr->hMsgBoxHook = SetWindowsHookEx(WH_CBT, MsgBoxCBTProc, NULL,
	    GetCurrentThreadId());
    src = Tcl_GetString(tmpObj);
    tmpPtr = Tcl_WinUtfToTChar(src, tmpObj->length, &tmpBuf);
    if (titleObj != NULL) {
	src = Tcl_GetString(titleObj);
	titlePtr = Tcl_WinUtfToTChar(src, titleObj->length, &titleBuf);
    } else {
................................................................................
	 */

	LPCBT_CREATEWND lpcbtcreate = (LPCBT_CREATEWND) lParam;

	if (WC_DIALOG == lpcbtcreate->lpcs->lpszClass) {
	    HWND hwnd = (HWND) wParam;

	    SendMessage(hwnd, WM_SETICON, ICON_SMALL,
		    (LPARAM) tsdPtr->hSmallIcon);
	    SendMessage(hwnd, WM_SETICON, ICON_BIG, (LPARAM) tsdPtr->hBigIcon);
	}
    }

    /*
     * Call the next hook proc, if there is one
     */

................................................................................
     * background evaluation (ie: errors dont come back here).
     */

    if (WM_COMMAND == msg && LOWORD(wParam) == 1026) {
	LOGFONTW lf = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0}};
	HDC hdc = GetDC(hwndDlg);

	SendMessage(hwndDlg, WM_CHOOSEFONT_GETLOGFONT, 0, (LPARAM) &lf);
	if (phd && phd->cmdObj) {
	    ApplyLogfont(phd->interp, phd->cmdObj, hdc, &lf);
	}
	if (phd && phd->parent) {
	    TkSendVirtualEvent(phd->parent, "TkFontchooserFontChanged", NULL);
	}
	return 1;
................................................................................
	if (parent == NULL) {
	    return TCL_ERROR;
	}
    }

    Tk_MakeWindowExist(parent);

    ZeroMemory(&cf, sizeof(CHOOSEFONTW));
    ZeroMemory(&lf, sizeof(LOGFONTW));
    lf.lfCharSet = DEFAULT_CHARSET;
    cf.lStructSize = sizeof(CHOOSEFONTW);
    cf.hwndOwner = Tk_GetHWND(Tk_WindowId(parent));
    cf.lpLogFont = &lf;
    cf.nFontType = SCREEN_FONTTYPE;
    cf.Flags = CF_SCREENFONTS | CF_EFFECTS | CF_ENABLEHOOK;
    cf.rgbColors = RGB(0,0,0);
    cf.lpfnHook = HookProc;
    cf.lCustData = (INT_PTR) hdPtr;







|
<
|
<
<
<
|







 







|

|

|







 







|







 







|







 







|
|







 







|


|







 







|







 







|







 







|







 







|

|


|







 







|







 







|








|

|







 







|







 







|







 







|

|







 







|







 







|
|

|







36
37
38
39
40
41
42
43

44



45
46
47
48
49
50
51
52
...
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
...
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
....
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
....
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
....
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
....
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
....
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
....
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
....
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
....
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
....
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
....
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
....
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
....
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
....
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
....
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
#endif

/* This "new" dialog style is now actually the "old" dialog style post-Vista */
#ifndef BIF_NEWDIALOGSTYLE
#define BIF_NEWDIALOGSTYLE 0x0040
#endif

#ifndef BFFM_VALIDATEFAILEDW

#define BFFM_VALIDATEFAILEDW 4



#endif /* BFFM_VALIDATEFAILEDW */

typedef struct {
    int debugFlag;		/* Flags whether we should output debugging
				 * information while displaying a builtin
				 * dialog. */
    Tcl_Interp *debugInterp;	/* Interpreter to used for debugging. */
    UINT WM_LBSELCHANGED;	/* Holds a registered windows event used for
................................................................................
#define NUM_TYPES (sizeof(allowedTypes) / sizeof(allowedTypes[0]))

/*
 * Abstract trivial differences between Win32 and Win64.
 */

#define TkWinGetHInstance(from) \
	((HINSTANCE) GetWindowLongPtrW((from), GWLP_HINSTANCE))
#define TkWinGetUserData(from) \
	GetWindowLongPtrW((from), GWLP_USERDATA)
#define TkWinSetUserData(to,what) \
	SetWindowLongPtrW((to), GWLP_USERDATA, (LPARAM)(what))

/*
 * The value of TK_MULTI_MAX_PATH dictates how many files can be retrieved
 * with tk_get*File -multiple 1. It must be allocated on the stack, so make it
 * large enough but not too large. - hobbs
 *
 * The data is stored as <dir>\0<file1>\0<file2>\0...<fileN>\0\0. Since
................................................................................
static void
EatSpuriousMessageBugFix(void)
{
    MSG msg;
    DWORD nTime = GetTickCount() + 250;

    while (GetTickCount() < nTime) {
	PeekMessageW(&msg, 0, WM_MOUSEFIRST, WM_MOUSELAST, PM_REMOVE);
    }
}
 
/*
 *-------------------------------------------------------------------------
 *
 * TkWinDialogDebug --
................................................................................
    if (Tcl_DStringValue(&optsPtr->utfDirString)[0] != '\0') {
        Tcl_Obj *normPath, *iniDirPath;
        iniDirPath = Tcl_NewStringObj(Tcl_DStringValue(&optsPtr->utfDirString), -1);
        Tcl_IncrRefCount(iniDirPath);
        normPath = Tcl_FSGetNormalizedPath(interp, iniDirPath);
        /* XXX - Note on failures do not raise error, simply ignore ini dir */
        if (normPath) {
            LPCWSTR nativePath;
            Tcl_IncrRefCount(normPath);
            nativePath = Tcl_FSGetNativePath(normPath); /* Points INTO normPath*/
            if (nativePath) {
                hr = ShellProcs.SHCreateItemFromParsingName(
                    nativePath, NULL,
                    &IIDIShellItem, (void **) &dirIf);
                if (SUCCEEDED(hr)) {
................................................................................
	     */

	    ofnPtr = notifyPtr->lpOFN;
	    ofnData = (OFNData *) ofnPtr->lCustData;
	    buffer = ofnData->dynFileBuffer;
	    hdlg = GetParent(hdlg);

	    selsize = (int) SendMessageW(hdlg, CDM_GETSPEC, 0, 0);
	    dirsize = (int) SendMessageW(hdlg, CDM_GETFOLDERPATH, 0, 0);
	    buffersize = (selsize + dirsize + 1);

	    /*
	     * Just empty the buffer if dirsize indicates an error. [Bug
	     * 3071836]
	     */

................................................................................
	    if ((selsize > 1) && (dirsize > 0)) {
		if (ofnData->dynFileBufferSize < buffersize) {
		    buffer = ckrealloc(buffer, buffersize * sizeof(WCHAR));
		    ofnData->dynFileBufferSize = buffersize;
		    ofnData->dynFileBuffer = buffer;
		}

		SendMessageW(hdlg, CDM_GETFOLDERPATH, dirsize, (LPARAM) buffer);
		buffer += dirsize;

		SendMessageW(hdlg, CDM_GETSPEC, selsize, (LPARAM) buffer);

		/*
		 * If there are multiple files, delete the quotes and change
		 * every second quote to NULL terminator
		 */

		if (buffer[0] == '"') {
................................................................................

		    Tcl_DString tmpfile;
		    ConvertExternalFilename(buffer, &tmpfile);
		    if (TCL_PATH_ABSOLUTE ==
			    Tcl_GetPathType(Tcl_DStringValue(&tmpfile))) {
			/* re-get the full path to the start of the buffer */
			buffer = (WCHAR *) ofnData->dynFileBuffer;
			SendMessageW(hdlg, CDM_GETSPEC, selsize, (LPARAM) buffer);
		    } else {
			*(buffer-1) = '\\';
		    }
		    buffer[selsize] = '\0'; /* Second NULL terminator. */
		    Tcl_DStringFree(&tmpfile);
		}
	    } else {
................................................................................
    path[0] = '\0';
    ZeroMemory(&cdCBData, sizeof(ChooseDir));
    cdCBData.interp = interp;
    cdCBData.mustExist = ofnOpts.mustExist;

    utfDir = Tcl_DStringValue(&ofnOpts.utfDirString);
    if (utfDir[0] != '\0') {
	LPCWSTR uniStr;

        Tcl_WinUtfToTChar(Tcl_DStringValue(&ofnOpts.utfDirString), -1,
                          &tempString);
        uniStr = (WCHAR *) Tcl_DStringValue(&tempString);

        /* Convert possible relative path to full path to keep dialog happy. */

................................................................................

    if (tsdPtr->debugFlag) {
	tsdPtr->debugInterp = (Tcl_Interp *) chooseDirSharedData->interp;
	Tcl_DoWhenIdle(SetTkDialog, hwnd);
    }
    chooseDirSharedData->retDir[0] = '\0';
    switch (message) {
    case BFFM_VALIDATEFAILEDW:
	/*
	 * First save and check to see if it is a valid path name, if so then
	 * make that path the one shown in the window. Otherwise, it failed
	 * the check and should be treated as such. Use
	 * Set/GetCurrentDirectory which allows relative path names and names
	 * with forward slashes. Use Tcl_TranslateFileName to make sure names
	 * like ~ are converted correctly.
................................................................................
	 * for things like server names. Perhaps a new switch
	 * -enablenonfolders can be used to allow non folders to be selected.
	 *
	 * Not called when user changes edit box directly.
	 */

	if (SHGetPathFromIDListW((LPITEMIDLIST) lParam, selDir)) {
	    SendMessageW(hwnd, BFFM_SETSTATUSTEXTW, 0, (LPARAM) selDir);
	    // enable the OK button
	    SendMessageW(hwnd, BFFM_ENABLEOK, 0, (LPARAM) 1);
	} else {
	    // disable the OK button
	    SendMessageW(hwnd, BFFM_ENABLEOK, 0, (LPARAM) 0);
	}
	UpdateWindow(hwnd);
	return 1;

    case BFFM_INITIALIZED: {
	/*
	 * Directory browser initializing - tell it where to start from, user
................................................................................

	WCHAR *initDir = chooseDirSharedData->initDir;

	SetCurrentDirectoryW(initDir);

	if (*initDir == '\\') {
	    /*
	     * BFFM_SETSELECTIONW only understands UNC paths as pidls, so
	     * convert path to pidl using IShellFolder interface.
	     */

	    LPMALLOC pMalloc;
	    LPSHELLFOLDER psfFolder;

	    if (SUCCEEDED(SHGetMalloc(&pMalloc))) {
................................................................................
		    LPITEMIDLIST pidlMain;
		    ULONG ulCount, ulAttr;

		    if (SUCCEEDED(psfFolder->lpVtbl->ParseDisplayName(
			    psfFolder, hwnd, NULL, (WCHAR *)
			    initDir, &ulCount,&pidlMain,&ulAttr))
			    && (pidlMain != NULL)) {
			SendMessageW(hwnd, BFFM_SETSELECTIONW, FALSE,
				(LPARAM) pidlMain);
			pMalloc->lpVtbl->Free(pMalloc, pidlMain);
		    }
		    psfFolder->lpVtbl->Release(psfFolder);
		}
		pMalloc->lpVtbl->Release(pMalloc);
	    }
	} else {
	    SendMessageW(hwnd, BFFM_SETSELECTIONW, TRUE, (LPARAM) initDir);
	}
	SendMessageW(hwnd, BFFM_ENABLEOK, 0, (LPARAM) 1);
	break;
    }

    }
    return 0;
}
 
................................................................................
    enum options {
	MSG_DEFAULT,	MSG_DETAIL,	MSG_ICON,	MSG_MESSAGE,
	MSG_PARENT,	MSG_TITLE,	MSG_TYPE
    };
    ThreadSpecificData *tsdPtr =
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    Tcl_DString titleBuf, tmpBuf;
    LPCWSTR titlePtr, tmpPtr;
    const char *src;

    defaultBtn = -1;
    detailObj = NULL;
    icon = MB_ICONINFORMATION;
    messageObj = NULL;
    parent = tkwin;
................................................................................
     * In order to have the parent window icon reflected in a MessageBox, we
     * have to create a hook that will trigger when the MessageBox is being
     * created.
     */

    tsdPtr->hSmallIcon = TkWinGetIcon(parent, ICON_SMALL);
    tsdPtr->hBigIcon   = TkWinGetIcon(parent, ICON_BIG);
    tsdPtr->hMsgBoxHook = SetWindowsHookExW(WH_CBT, MsgBoxCBTProc, NULL,
	    GetCurrentThreadId());
    src = Tcl_GetString(tmpObj);
    tmpPtr = Tcl_WinUtfToTChar(src, tmpObj->length, &tmpBuf);
    if (titleObj != NULL) {
	src = Tcl_GetString(titleObj);
	titlePtr = Tcl_WinUtfToTChar(src, titleObj->length, &titleBuf);
    } else {
................................................................................
	 */

	LPCBT_CREATEWND lpcbtcreate = (LPCBT_CREATEWND) lParam;

	if (WC_DIALOG == lpcbtcreate->lpcs->lpszClass) {
	    HWND hwnd = (HWND) wParam;

	    SendMessageW(hwnd, WM_SETICON, ICON_SMALL,
		    (LPARAM) tsdPtr->hSmallIcon);
	    SendMessageW(hwnd, WM_SETICON, ICON_BIG, (LPARAM) tsdPtr->hBigIcon);
	}
    }

    /*
     * Call the next hook proc, if there is one
     */

................................................................................
     * background evaluation (ie: errors dont come back here).
     */

    if (WM_COMMAND == msg && LOWORD(wParam) == 1026) {
	LOGFONTW lf = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0}};
	HDC hdc = GetDC(hwndDlg);

	SendMessageW(hwndDlg, WM_CHOOSEFONT_GETLOGFONT, 0, (LPARAM) &lf);
	if (phd && phd->cmdObj) {
	    ApplyLogfont(phd->interp, phd->cmdObj, hdc, &lf);
	}
	if (phd && phd->parent) {
	    TkSendVirtualEvent(phd->parent, "TkFontchooserFontChanged", NULL);
	}
	return 1;
................................................................................
	if (parent == NULL) {
	    return TCL_ERROR;
	}
    }

    Tk_MakeWindowExist(parent);

    ZeroMemory(&cf, sizeof(CHOOSEFONT));
    ZeroMemory(&lf, sizeof(LOGFONT));
    lf.lfCharSet = DEFAULT_CHARSET;
    cf.lStructSize = sizeof(CHOOSEFONT);
    cf.hwndOwner = Tk_GetHWND(Tk_WindowId(parent));
    cf.lpLogFont = &lf;
    cf.nFontType = SCREEN_FONTTYPE;
    cf.Flags = CF_SCREENFONTS | CF_EFFECTS | CF_ENABLEHOOK;
    cf.rgbColors = RGB(0,0,0);
    cf.lpfnHook = HookProc;
    cf.lCustData = (INT_PTR) hdPtr;

Changes to jni/sdl2tk/win/tkWinDraw.c.

1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467

    rect.left = x;
    rect.top = y;
    rect.right = x + width;
    rect.bottom = y + height;
    oldColor = SetBkColor(dc, (COLORREF)pixel);
    SetBkMode(dc, OPAQUE);
    ExtTextOut(dc, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL);
    SetBkColor(dc, oldColor);
}
 
/*
 *----------------------------------------------------------------------
 *
 * TkpDrawHighlightBorder --







|







1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467

    rect.left = x;
    rect.top = y;
    rect.right = x + width;
    rect.bottom = y + height;
    oldColor = SetBkColor(dc, (COLORREF)pixel);
    SetBkMode(dc, OPAQUE);
    ExtTextOutW(dc, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL);
    SetBkColor(dc, oldColor);
}
 
/*
 *----------------------------------------------------------------------
 *
 * TkpDrawHighlightBorder --

Changes to jni/sdl2tk/win/tkWinEmbed.c.

156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
...
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
....
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
....
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
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 */
................................................................................
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "window \"%s\" doesn't exist", string));
	    Tcl_SetErrorCode(interp, "TK", "EMBED", "EXIST", NULL);
	}
	return TCL_ERROR;
    }

    id = SendMessage(hwnd, TK_INFO, TK_CONTAINER_VERIFY, 0);
    if (id == PTR2INT(hwnd)) {
	if (!SendMessage(hwnd, TK_INFO, TK_CONTAINER_ISAVAILABLE, 0)) {
    	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "The container is already in use", -1));
	    Tcl_SetErrorCode(interp, "TK", "EMBED", "IN_USE", NULL);
	    return TCL_ERROR;
	}
    } else if (id == -PTR2INT(hwnd)) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
................................................................................
    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 --
 *
................................................................................
    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) {







|







 







|

|







 







|







 







|







156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
...
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
....
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
....
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
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 = SendMessageW(hwnd, TK_STATE, -1, -1) - 1;

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

	while (Tcl_DoOneEvent(TCL_IDLE_EVENTS)) {
	    /* empty body */
................................................................................
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "window \"%s\" doesn't exist", string));
	    Tcl_SetErrorCode(interp, "TK", "EMBED", "EXIST", NULL);
	}
	return TCL_ERROR;
    }

    id = SendMessageW(hwnd, TK_INFO, TK_CONTAINER_VERIFY, 0);
    if (id == PTR2INT(hwnd)) {
	if (!SendMessageW(hwnd, TK_INFO, TK_CONTAINER_ISAVAILABLE, 0)) {
    	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "The container is already in use", -1));
	    Tcl_SetErrorCode(interp, "TK", "EMBED", "IN_USE", NULL);
	    return TCL_ERROR;
	}
    } else if (id == -PTR2INT(hwnd)) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
................................................................................
    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));
    SendMessageW(hwnd, TK_CLAIMFOCUS, (WPARAM) force, 0);
}
 
/*
 *----------------------------------------------------------------------
 *
 * TkpRedirectKeyEvent --
 *
................................................................................
    while (1) {
	if (containerPtr->embeddedPtr == winPtr) {
	    containerPtr->embeddedHWnd = NULL;
	    containerPtr->embeddedPtr = NULL;
	    break;
	}
	if (containerPtr->parentPtr == winPtr) {
	    SendMessageW(containerPtr->embeddedHWnd, WM_CLOSE, 0, 0);
	    containerPtr->parentPtr = NULL;
	    containerPtr->embeddedPtr = NULL;
	    break;
	}
	prevPtr = containerPtr;
	containerPtr = containerPtr->nextPtr;
	if (containerPtr == NULL) {

Changes to jni/sdl2tk/win/tkWinFont.c.

746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
....
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
....
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
....
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
....
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
....
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
....
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
....
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
....
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
....
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
....
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
....
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
....
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
				 * memory allocation */
    SubFont *thisSubFontPtr =
	    FindSubFontForChar(fontPtr, c, &lastSubFontPtr);
				/* Pointer to the subfont to use for the given
				 * character */
    FontFamily *familyPtr = thisSubFontPtr->familyPtr;
    HFONT oldfont;		/* Saved font from the device context */
    TEXTMETRIC tm;		/* Font metrics of the selected subfont */

    /*
     * Get the font attributes.
     */

    oldfont = SelectObject(hdc, thisSubFontPtr->hFont0);
    GetTextMetrics(hdc, &tm);
    SelectObject(hdc, oldfont);
    ReleaseDC(fontPtr->hwnd, hdc);
    faPtr->family = familyPtr->faceName;
    faPtr->size = TkFontGetPoints(tkwin,
	    (double)(tm.tmInternalLeading - tm.tmHeight));
    faPtr->weight = (tm.tmWeight > FW_MEDIUM) ? TK_FW_BOLD : TK_FW_NORMAL;
    faPtr->slant = tm.tmItalic ? TK_FS_ITALIC : TK_FS_ROMAN;
................................................................................
    if ((gc->fill_style == FillStippled
	    || gc->fill_style == FillOpaqueStippled)
	    && gc->stipple != None) {
	TkWinDrawable *twdPtr = (TkWinDrawable *) gc->stipple;
	HBRUSH oldBrush, stipple;
	HBITMAP oldBitmap, bitmap;
	HDC dcMem;
	TEXTMETRIC tm;
	SIZE size;

	if (twdPtr->type != TWD_BITMAP) {
	    Tcl_Panic("unexpected drawable type in stipple");
	}

	/*
................................................................................
	SetBkColor(dcMem, RGB(0, 0, 0));

	/*
	 * Compute the bounding box and create a compatible bitmap.
	 */

	GetTextExtentPointA(dcMem, source, numBytes, &size);
	GetTextMetrics(dcMem, &tm);
	size.cx -= tm.tmOverhang;
	bitmap = CreateCompatibleBitmap(dc, size.cx, size.cy);
	oldBitmap = SelectObject(dcMem, bitmap);

	/*
	 * The following code is tricky because fonts are rendered in multiple
	 * colors. First we draw onto a black background and copy the white
................................................................................
	SetTextAlign(dc, TA_LEFT | TA_BASELINE);
	SetTextColor(dc, gc->foreground);
	SetBkMode(dc, TRANSPARENT);
	MultiFontTextOut(dc, fontPtr, source, numBytes, x, y, 0.0);
    } else {
	HBITMAP oldBitmap, bitmap;
	HDC dcMem;
	TEXTMETRIC tm;
	SIZE size;

	dcMem = CreateCompatibleDC(dc);

	SetTextAlign(dcMem, TA_LEFT | TA_BASELINE);
	SetTextColor(dcMem, gc->foreground);
	SetBkMode(dcMem, TRANSPARENT);
................................................................................
	SetBkColor(dcMem, RGB(0, 0, 0));

	/*
	 * Compute the bounding box and create a compatible bitmap.
	 */

	GetTextExtentPointA(dcMem, source, numBytes, &size);
	GetTextMetrics(dcMem, &tm);
	size.cx -= tm.tmOverhang;
	bitmap = CreateCompatibleBitmap(dc, size.cx, size.cy);
	oldBitmap = SelectObject(dcMem, bitmap);

	MultiFontTextOut(dcMem, fontPtr, source, numBytes, 0, tm.tmAscent,
		0.0);
	BitBlt(dc, x, y - tm.tmAscent, size.cx, size.cy, dcMem,
................................................................................
    if ((gc->fill_style == FillStippled
	    || gc->fill_style == FillOpaqueStippled)
	    && gc->stipple != None) {
	TkWinDrawable *twdPtr = (TkWinDrawable *)gc->stipple;
	HBRUSH oldBrush, stipple;
	HBITMAP oldBitmap, bitmap;
	HDC dcMem;
	TEXTMETRIC tm;
	SIZE size;

	if (twdPtr->type != TWD_BITMAP) {
	    Tcl_Panic("unexpected drawable type in stipple");
	}

	/*
................................................................................
	SetBkColor(dcMem, RGB(0, 0, 0));

	/*
	 * Compute the bounding box and create a compatible bitmap.
	 */

	GetTextExtentPointA(dcMem, source, numBytes, &size);
	GetTextMetrics(dcMem, &tm);
	size.cx -= tm.tmOverhang;
	bitmap = CreateCompatibleBitmap(dc, size.cx, size.cy);
	oldBitmap = SelectObject(dcMem, bitmap);

	/*
	 * The following code is tricky because fonts are rendered in multiple
	 * colors. First we draw onto a black background and copy the white
................................................................................
	SetTextAlign(dc, TA_LEFT | TA_BASELINE);
	SetTextColor(dc, gc->foreground);
	SetBkMode(dc, TRANSPARENT);
	MultiFontTextOut(dc, fontPtr, source, numBytes, (int)x, (int)y, angle);
    } else {
	HBITMAP oldBitmap, bitmap;
	HDC dcMem;
	TEXTMETRIC tm;
	SIZE size;

	dcMem = CreateCompatibleDC(dc);

	SetTextAlign(dcMem, TA_LEFT | TA_BASELINE);
	SetTextColor(dcMem, gc->foreground);
	SetBkMode(dcMem, TRANSPARENT);
................................................................................
	SetBkColor(dcMem, RGB(0, 0, 0));

	/*
	 * Compute the bounding box and create a compatible bitmap.
	 */

	GetTextExtentPointA(dcMem, source, numBytes, &size);
	GetTextMetrics(dcMem, &tm);
	size.cx -= tm.tmOverhang;
	bitmap = CreateCompatibleBitmap(dc, size.cx, size.cy);
	oldBitmap = SelectObject(dcMem, bitmap);

	MultiFontTextOut(dcMem, fontPtr, source, numBytes, 0, tm.tmAscent,
		angle);
	BitBlt(dc, (int)x, (int)y - tm.tmAscent, size.cx, size.cy, dcMem,
................................................................................
    int ch;
    SIZE size;
    HFONT oldFont;
    FontFamily *familyPtr;
    Tcl_DString runString;
    const char *p, *end, *next;
    SubFont *lastSubFontPtr, *thisSubFontPtr;
    TEXTMETRIC tm;

    lastSubFontPtr = &fontPtr->subFontArray[0];
    oldFont = SelectFont(hdc, fontPtr, lastSubFontPtr, angle);
    GetTextMetrics(hdc, &tm);

    end = source + numBytes;
    for (p = source; p < end; ) {
	next = p + TkUtfToUniChar(p, &ch);
	thisSubFontPtr = FindSubFontForChar(fontPtr, ch, &lastSubFontPtr);

	/*
................................................................................
			&size);
		x += size.cx;
		Tcl_DStringFree(&runString);
	    }
	    lastSubFontPtr = thisSubFontPtr;
	    source = p;
	    SelectFont(hdc, fontPtr, lastSubFontPtr, angle);
	    GetTextMetrics(hdc, &tm);
	}
	p = next;
    }
    if (p > source) {
	familyPtr = lastSubFontPtr->familyPtr;
 	Tcl_UtfToExternalDString(familyPtr->encoding, source,
		(int) (p - source), &runString);
................................................................................
static void
InitFont(
    Tk_Window tkwin,		/* Main window of interp in which font will be
				 * used, for getting HDC. */
    HFONT hFont,		/* Windows token for font. */
    int overstrike,		/* The overstrike attribute of logfont used to
				 * allocate this font. For some reason, the
				 * TEXTMETRICs may contain incorrect info in
				 * the tmStruckOut field. */
    WinFont *fontPtr)		/* Filled with information constructed from
				 * the above arguments. */
{
    HDC hdc;
    HWND hwnd;
    HFONT oldFont;
    TEXTMETRIC tm;
    Window window;
    TkFontMetrics *fmPtr;
    Tcl_Encoding encoding;
    Tcl_DString faceString;
    TkFontAttributes *faPtr;
    WCHAR buf[LF_FACESIZE];

    window = Tk_WindowId(tkwin);
    hwnd = (window == None) ? NULL : TkWinGetHWND(window);
    hdc = GetDC(hwnd);
    oldFont = SelectObject(hdc, hFont);

    GetTextMetrics(hdc, &tm);

    /*
     * On any version NT, there may fonts with international names. Use the
     * NT-only Unicode version of GetTextFace to get the font's name. If we
     * used the ANSI version on a non-internationalized version of NT, we
     * would get a font name with '?' replacing all the international
     * characters.
................................................................................

    fontPtr->numSubFonts 	= 1;
    fontPtr->subFontArray	= fontPtr->staticSubFonts;
    InitSubFont(hdc, hFont, 1, &fontPtr->subFontArray[0]);

    encoding = fontPtr->subFontArray[0].familyPtr->encoding;
    if (encoding == TkWinGetUnicodeEncoding()) {
	GetCharWidth(hdc, 0, BASE_CHARS - 1, fontPtr->widths);
    } else {
	GetCharWidthA(hdc, 0, BASE_CHARS - 1, fontPtr->widths);
    }
    Tcl_DStringFree(&faceString);

    SelectObject(hdc, oldFont);
    ReleaseDC(hwnd, hdc);







|






|







 







|







 







|







 







|







 







|







 







|







 







|







 







|







 







|







 







|



|







 







|







 







|







|












|







 







|







746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
....
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
....
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
....
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
....
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
....
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
....
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
....
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
....
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
....
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
....
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
....
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
....
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
				 * memory allocation */
    SubFont *thisSubFontPtr =
	    FindSubFontForChar(fontPtr, c, &lastSubFontPtr);
				/* Pointer to the subfont to use for the given
				 * character */
    FontFamily *familyPtr = thisSubFontPtr->familyPtr;
    HFONT oldfont;		/* Saved font from the device context */
    TEXTMETRICW tm;		/* Font metrics of the selected subfont */

    /*
     * Get the font attributes.
     */

    oldfont = SelectObject(hdc, thisSubFontPtr->hFont0);
    GetTextMetricsW(hdc, &tm);
    SelectObject(hdc, oldfont);
    ReleaseDC(fontPtr->hwnd, hdc);
    faPtr->family = familyPtr->faceName;
    faPtr->size = TkFontGetPoints(tkwin,
	    (double)(tm.tmInternalLeading - tm.tmHeight));
    faPtr->weight = (tm.tmWeight > FW_MEDIUM) ? TK_FW_BOLD : TK_FW_NORMAL;
    faPtr->slant = tm.tmItalic ? TK_FS_ITALIC : TK_FS_ROMAN;
................................................................................
    if ((gc->fill_style == FillStippled
	    || gc->fill_style == FillOpaqueStippled)
	    && gc->stipple != None) {
	TkWinDrawable *twdPtr = (TkWinDrawable *) gc->stipple;
	HBRUSH oldBrush, stipple;
	HBITMAP oldBitmap, bitmap;
	HDC dcMem;
	TEXTMETRICW tm;
	SIZE size;

	if (twdPtr->type != TWD_BITMAP) {
	    Tcl_Panic("unexpected drawable type in stipple");
	}

	/*
................................................................................
	SetBkColor(dcMem, RGB(0, 0, 0));

	/*
	 * Compute the bounding box and create a compatible bitmap.
	 */

	GetTextExtentPointA(dcMem, source, numBytes, &size);
	GetTextMetricsW(dcMem, &tm);
	size.cx -= tm.tmOverhang;
	bitmap = CreateCompatibleBitmap(dc, size.cx, size.cy);
	oldBitmap = SelectObject(dcMem, bitmap);

	/*
	 * The following code is tricky because fonts are rendered in multiple
	 * colors. First we draw onto a black background and copy the white
................................................................................
	SetTextAlign(dc, TA_LEFT | TA_BASELINE);
	SetTextColor(dc, gc->foreground);
	SetBkMode(dc, TRANSPARENT);
	MultiFontTextOut(dc, fontPtr, source, numBytes, x, y, 0.0);
    } else {
	HBITMAP oldBitmap, bitmap;
	HDC dcMem;
	TEXTMETRICW tm;
	SIZE size;

	dcMem = CreateCompatibleDC(dc);

	SetTextAlign(dcMem, TA_LEFT | TA_BASELINE);
	SetTextColor(dcMem, gc->foreground);
	SetBkMode(dcMem, TRANSPARENT);
................................................................................
	SetBkColor(dcMem, RGB(0, 0, 0));

	/*
	 * Compute the bounding box and create a compatible bitmap.
	 */

	GetTextExtentPointA(dcMem, source, numBytes, &size);
	GetTextMetricsW(dcMem, &tm);
	size.cx -= tm.tmOverhang;
	bitmap = CreateCompatibleBitmap(dc, size.cx, size.cy);
	oldBitmap = SelectObject(dcMem, bitmap);

	MultiFontTextOut(dcMem, fontPtr, source, numBytes, 0, tm.tmAscent,
		0.0);
	BitBlt(dc, x, y - tm.tmAscent, size.cx, size.cy, dcMem,
................................................................................
    if ((gc->fill_style == FillStippled
	    || gc->fill_style == FillOpaqueStippled)
	    && gc->stipple != None) {
	TkWinDrawable *twdPtr = (TkWinDrawable *)gc->stipple;
	HBRUSH oldBrush, stipple;
	HBITMAP oldBitmap, bitmap;
	HDC dcMem;
	TEXTMETRICW tm;
	SIZE size;

	if (twdPtr->type != TWD_BITMAP) {
	    Tcl_Panic("unexpected drawable type in stipple");
	}

	/*
................................................................................
	SetBkColor(dcMem, RGB(0, 0, 0));

	/*
	 * Compute the bounding box and create a compatible bitmap.
	 */

	GetTextExtentPointA(dcMem, source, numBytes, &size);
	GetTextMetricsW(dcMem, &tm);
	size.cx -= tm.tmOverhang;
	bitmap = CreateCompatibleBitmap(dc, size.cx, size.cy);
	oldBitmap = SelectObject(dcMem, bitmap);

	/*
	 * The following code is tricky because fonts are rendered in multiple
	 * colors. First we draw onto a black background and copy the white
................................................................................
	SetTextAlign(dc, TA_LEFT | TA_BASELINE);
	SetTextColor(dc, gc->foreground);
	SetBkMode(dc, TRANSPARENT);
	MultiFontTextOut(dc, fontPtr, source, numBytes, (int)x, (int)y, angle);
    } else {
	HBITMAP oldBitmap, bitmap;
	HDC dcMem;
	TEXTMETRICW tm;
	SIZE size;

	dcMem = CreateCompatibleDC(dc);

	SetTextAlign(dcMem, TA_LEFT | TA_BASELINE);
	SetTextColor(dcMem, gc->foreground);
	SetBkMode(dcMem, TRANSPARENT);
................................................................................
	SetBkColor(dcMem, RGB(0, 0, 0));

	/*
	 * Compute the bounding box and create a compatible bitmap.
	 */

	GetTextExtentPointA(dcMem, source, numBytes, &size);
	GetTextMetricsW(dcMem, &tm);
	size.cx -= tm.tmOverhang;
	bitmap = CreateCompatibleBitmap(dc, size.cx, size.cy);
	oldBitmap = SelectObject(dcMem, bitmap);

	MultiFontTextOut(dcMem, fontPtr, source, numBytes, 0, tm.tmAscent,
		angle);
	BitBlt(dc, (int)x, (int)y - tm.tmAscent, size.cx, size.cy, dcMem,
................................................................................
    int ch;
    SIZE size;
    HFONT oldFont;
    FontFamily *familyPtr;
    Tcl_DString runString;
    const char *p, *end, *next;
    SubFont *lastSubFontPtr, *thisSubFontPtr;
    TEXTMETRICW tm;

    lastSubFontPtr = &fontPtr->subFontArray[0];
    oldFont = SelectFont(hdc, fontPtr, lastSubFontPtr, angle);
    GetTextMetricsW(hdc, &tm);

    end = source + numBytes;
    for (p = source; p < end; ) {
	next = p + TkUtfToUniChar(p, &ch);
	thisSubFontPtr = FindSubFontForChar(fontPtr, ch, &lastSubFontPtr);

	/*
................................................................................
			&size);
		x += size.cx;
		Tcl_DStringFree(&runString);
	    }
	    lastSubFontPtr = thisSubFontPtr;
	    source = p;
	    SelectFont(hdc, fontPtr, lastSubFontPtr, angle);
	    GetTextMetricsW(hdc, &tm);
	}
	p = next;
    }
    if (p > source) {
	familyPtr = lastSubFontPtr->familyPtr;
 	Tcl_UtfToExternalDString(familyPtr->encoding, source,
		(int) (p - source), &runString);
................................................................................
static void
InitFont(
    Tk_Window tkwin,		/* Main window of interp in which font will be
				 * used, for getting HDC. */
    HFONT hFont,		/* Windows token for font. */
    int overstrike,		/* The overstrike attribute of logfont used to
				 * allocate this font. For some reason, the
				 * TEXTMETRICWs may contain incorrect info in
				 * the tmStruckOut field. */
    WinFont *fontPtr)		/* Filled with information constructed from
				 * the above arguments. */
{
    HDC hdc;
    HWND hwnd;
    HFONT oldFont;
    TEXTMETRICW tm;
    Window window;
    TkFontMetrics *fmPtr;
    Tcl_Encoding encoding;
    Tcl_DString faceString;
    TkFontAttributes *faPtr;
    WCHAR buf[LF_FACESIZE];

    window = Tk_WindowId(tkwin);
    hwnd = (window == None) ? NULL : TkWinGetHWND(window);
    hdc = GetDC(hwnd);
    oldFont = SelectObject(hdc, hFont);

    GetTextMetricsW(hdc, &tm);

    /*
     * On any version NT, there may fonts with international names. Use the
     * NT-only Unicode version of GetTextFace to get the font's name. If we
     * used the ANSI version on a non-internationalized version of NT, we
     * would get a font name with '?' replacing all the international
     * characters.
................................................................................

    fontPtr->numSubFonts 	= 1;
    fontPtr->subFontArray	= fontPtr->staticSubFonts;
    InitSubFont(hdc, hFont, 1, &fontPtr->subFontArray[0]);

    encoding = fontPtr->subFontArray[0].familyPtr->encoding;
    if (encoding == TkWinGetUnicodeEncoding()) {
	GetCharWidthW(hdc, 0, BASE_CHARS - 1, fontPtr->widths);
    } else {
	GetCharWidthA(hdc, 0, BASE_CHARS - 1, fontPtr->widths);
    }
    Tcl_DStringFree(&faceString);

    SelectObject(hdc, oldFont);
    ReleaseDC(hwnd, hdc);

Changes to jni/sdl2tk/win/tkWinInt.h.

220
221
222
223
224
225
226
227
228
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
/*
 * The following functions are not present in old versions of Windows
 * API headers but are used in the Tk source to ensure 64bit
 * compatibility.
 */

#ifndef GetClassLongPtr
#   define GetClassLongPtrA	GetClassLongA
#   define GetClassLongPtrW	GetClassLongW
#   define SetClassLongPtrA	SetClassLongA
#   define SetClassLongPtrW	SetClassLongW
#   ifdef UNICODE
#	define GetClassLongPtr	GetClassLongPtrW
#	define SetClassLongPtr	SetClassLongPtrW
#   else
#	define GetClassLongPtr	GetClassLongPtrA
#	define SetClassLongPtr	SetClassLongPtrA
#   endif /* !UNICODE */
#endif /* !GetClassLongPtr */
#ifndef GCLP_HICON
#   define GCLP_HICON		GCL_HICON
#endif /* !GCLP_HICON */
#ifndef GCLP_HICONSM
#   define GCLP_HICONSM		(-34)
#endif /* !GCLP_HICONSM */

#ifndef GetWindowLongPtr
#   define GetWindowLongPtrA	GetWindowLongA
#   define GetWindowLongPtrW	GetWindowLongW
#   define SetWindowLongPtrA	SetWindowLongA
#   define SetWindowLongPtrW	SetWindowLongW
#   ifdef UNICODE
#	define GetWindowLongPtr	GetWindowLongPtrW
#	define SetWindowLongPtr	SetWindowLongPtrW
#   else
#	define GetWindowLongPtr	GetWindowLongPtrW
#	define SetWindowLongPtr	SetWindowLongPtrW
#   endif /* !UNICODE */
#endif /* !GetWindowLongPtr */
#ifndef GWLP_WNDPROC
#define GWLP_WNDPROC		GWL_WNDPROC
#define GWLP_HINSTANCE		GWL_HINSTANCE
#define GWLP_HWNDPARENT		GWL_HWNDPARENT
#define GWLP_USERDATA		GWL_USERDATA
#define GWLP_ID			GWL_ID
#endif /* !GWLP_WNDPROC */

#endif /* _TKWININT */







<

<

<
<
<
<
<
<
<









<

<

<
<
<
<
<
<
<










220
221
222
223
224
225
226

227

228







229
230
231
232
233
234
235
236
237

238

239







240
241
242
243
244
245
246
247
248
249
/*
 * The following functions are not present in old versions of Windows
 * API headers but are used in the Tk source to ensure 64bit
 * compatibility.
 */

#ifndef GetClassLongPtr

#   define GetClassLongPtrW	GetClassLongW

#   define SetClassLongPtrW	SetClassLongW







#endif /* !GetClassLongPtr */
#ifndef GCLP_HICON
#   define GCLP_HICON		GCL_HICON
#endif /* !GCLP_HICON */
#ifndef GCLP_HICONSM
#   define GCLP_HICONSM		(-34)
#endif /* !GCLP_HICONSM */

#ifndef GetWindowLongPtr

#   define GetWindowLongPtrW	GetWindowLongW

#   define SetWindowLongPtrW	SetWindowLongW







#endif /* !GetWindowLongPtr */
#ifndef GWLP_WNDPROC
#define GWLP_WNDPROC		GWL_WNDPROC
#define GWLP_HINSTANCE		GWL_HINSTANCE
#define GWLP_HWNDPARENT		GWL_HWNDPARENT
#define GWLP_USERDATA		GWL_USERDATA
#define GWLP_ID			GWL_ID
#endif /* !GWLP_WNDPROC */

#endif /* _TKWININT */

Changes to jni/sdl2tk/win/tkWinKey.c.

189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
...
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
...
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
...
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
    unsigned int keycode,
    int state,
    int noascii)
{
    BYTE keys[256];
    int result, deadkey, shift;
    WCHAR buf[4];
    unsigned int scancode = MapVirtualKey(keycode, 0);

    /*
     * Do not run keycodes of lock keys through ToUnicode(). One of ToUnicode()'s
     * side effects is to handle the lights on the keyboard, and we don't want
     * to mess that up.
     */

    if (noascii || keycode == VK_CAPITAL || keycode == VK_SCROLL ||
	    keycode == VK_NUMLOCK) {
	goto skipToUnicode;
    }

    /*
     * Use MapVirtualKey() to detect some dead keys.
     */

    if (MapVirtualKey(keycode, 2) > 0x7fffUL) {
	return XK_Multi_key;
    }

    /*
     * Set up a keyboard with correct modifiers
     */

................................................................................
	 * This was a dead char, and there were one previously remembered by
	 * the keyboard. Call ToUnicode() again with proper parameters to
	 * restore it.
	 *
	 * Get information about the old char
	 */

	deadkey = VkKeyScan(buf[0]);
	shift = deadkey >> 8;
	deadkey &= 255;
	scancode = MapVirtualKey(deadkey, 0);

	/*
	 * Set up a keyboard with proper modifier keys
	 */

	memset(keys, 0, 256);
	if (shift & 1) {
................................................................................
    for (i = 0; i <= MAX_KEYCODE; i++) {
	if (keymap[i] == keySym) {
	    eventPtr->xkey.keycode = i;
	    return;
	}
    }
    if (keySym >= 0x20) {
	result = VkKeyScan((WCHAR) keySym);
	if (result != -1) {
	    shift = result >> 8;
	    if (shift & 1)
		eventPtr->xkey.state |= ShiftMask;
	    if (shift & 2)
		eventPtr->xkey.state |= ControlMask;
	    if (shift & 4)
................................................................................
    }
    for (i = 0; i <= MAX_KEYCODE; i++) {
	if (keymap[i] == keysym) {
	    return ((KeyCode) i);
	}
    }
    if (keysym >= 0x20) {
	result = VkKeyScan((WCHAR) keysym);
	if (result != -1) {
	    return (KeyCode) (result & 0xff);
	}
    }

    return 0;
}







|













|


|







 







|


|







 







|







 







|







189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
...
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
...
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
...
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
    unsigned int keycode,
    int state,
    int noascii)
{
    BYTE keys[256];
    int result, deadkey, shift;
    WCHAR buf[4];
    unsigned int scancode = MapVirtualKeyW(keycode, 0);

    /*
     * Do not run keycodes of lock keys through ToUnicode(). One of ToUnicode()'s
     * side effects is to handle the lights on the keyboard, and we don't want
     * to mess that up.
     */

    if (noascii || keycode == VK_CAPITAL || keycode == VK_SCROLL ||
	    keycode == VK_NUMLOCK) {
	goto skipToUnicode;
    }

    /*
     * Use MapVirtualKeyW() to detect some dead keys.
     */

    if (MapVirtualKeyW(keycode, 2) > 0x7fffUL) {
	return XK_Multi_key;
    }

    /*
     * Set up a keyboard with correct modifiers
     */

................................................................................
	 * This was a dead char, and there were one previously remembered by
	 * the keyboard. Call ToUnicode() again with proper parameters to
	 * restore it.
	 *
	 * Get information about the old char
	 */

	deadkey = VkKeyScanW(buf[0]);
	shift = deadkey >> 8;
	deadkey &= 255;
	scancode = MapVirtualKeyW(deadkey, 0);

	/*
	 * Set up a keyboard with proper modifier keys
	 */

	memset(keys, 0, 256);
	if (shift & 1) {
................................................................................
    for (i = 0; i <= MAX_KEYCODE; i++) {
	if (keymap[i] == keySym) {
	    eventPtr->xkey.keycode = i;
	    return;
	}
    }
    if (keySym >= 0x20) {
	result = VkKeyScanW((WCHAR) keySym);
	if (result != -1) {
	    shift = result >> 8;
	    if (shift & 1)
		eventPtr->xkey.state |= ShiftMask;
	    if (shift & 2)
		eventPtr->xkey.state |= ControlMask;
	    if (shift & 4)
................................................................................
    }
    for (i = 0; i <= MAX_KEYCODE; i++) {
	if (keymap[i] == keysym) {
	    return ((KeyCode) i);
	}
    }
    if (keysym >= 0x20) {
	result = VkKeyScanW((WCHAR) keysym);
	if (result != -1) {
	    return (KeyCode) (result & 0xff);
	}
    }

    return 0;
}

Changes to jni/sdl2tk/win/tkWinMenu.c.

569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
...
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
...
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
....
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
....
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
....
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
....
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
....
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
....
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
....
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
ReconfigureWindowsMenu(
    ClientData clientData)	/* The menu we are rebuilding */
{
    TkMenu *menuPtr = clientData;
    TkMenuEntry *mePtr;
    HMENU winMenuHdl = (HMENU) menuPtr->platformData;
    char *itemText = NULL;
    const WCHAR *lpNewItem;
    UINT flags;
    UINT itemID;
    int i, count, systemMenu = 0, base;
    Tcl_DString translatedText;

    if (NULL == winMenuHdl) {
    	return;
................................................................................
	    continue;
	}

	itemText = GetEntryText(menuPtr, mePtr);
	if ((menuPtr->menuType == MENUBAR)
		|| (menuPtr->menuFlags & MENU_SYSTEM_MENU)) {
	    Tcl_WinUtfToTChar(itemText, -1, &translatedText);
	    lpNewItem = (const WCHAR *) Tcl_DStringValue(&translatedText);
	    flags |= MF_STRING;
	} else {
	    lpNewItem = (LPCWSTR) mePtr;
	    flags |= MF_OWNERDRAW;
	}

	/*
................................................................................
    UINT message,
    WPARAM wParam,
    LPARAM lParam)
{
    LRESULT lResult;

    if (!TkWinHandleMenuEvent(&hwnd, &message, &wParam, &lParam, &lResult)) {
	lResult = DefWindowProc(hwnd, message, wParam, lParam);
    }
    return lResult;
}
 
/*
 *----------------------------------------------------------------------
 *
................................................................................
	lResult = TkWinHandleMenuEvent(&hwnd, &message, &wParam, &lParam,
		&lResult);
	if (lResult || (GetCapture() != hwnd)) {
	    break;
	}
	/* FALLTHRU */
    default:
	lResult = DefWindowProc(hwnd, message, wParam, lParam);
	break;
    }
    return lResult;
}
 
/*
 *----------------------------------------------------------------------
................................................................................
    POINT ptOrg;
    int topOffset, leftOffset;

    SetBkColor(hdc, gc->background);
    SetTextColor(hdc, gc->foreground);

    scratchDC = CreateCompatibleDC(hdc);
    bitmap = LoadBitmap(NULL, MAKEINTRESOURCE(bitmapID));

    SelectObject(scratchDC, bitmap);
    SetMapMode(scratchDC, GetMapMode(hdc));
    GetObjectA(bitmap, sizeof(BITMAP), &bm);
    ptSize.x = bm.bmWidth;
    ptSize.y = bm.bmHeight;
    DPtoLP(scratchDC, &ptSize, 1);
................................................................................
/*
 *--------------------------------------------------------------
 *
 * TkWinMenuKeyObjCmd --
 *
 *	This function is invoked when keys related to pulling down menus is
 *	pressed. The corresponding Windows events are generated and passed to
 *	DefWindowProc if appropriate. This cmd is registered as tk::WinMenuKey
 *	in the interp.
 *
 * Results:
 *	Always returns TCL_OK.
 *
 * Side effects:
 *	The menu system may take over and process user events for menu input.
................................................................................
	return TCL_ERROR;
    }
    keySym = i;

    if (eventPtr->type == KeyPress) {
	switch (keySym) {
	case XK_Alt_L:
	    scanCode = MapVirtualKey(VK_LMENU, 0);
	    CallWindowProc(DefWindowProc, Tk_GetHWND(Tk_WindowId(tkwin)),
		    WM_SYSKEYDOWN, VK_MENU,
		    (int) (scanCode << 16) | (1 << 29));
	    break;
	case XK_Alt_R:
	    scanCode = MapVirtualKey(VK_RMENU, 0);
	    CallWindowProc(DefWindowProc, Tk_GetHWND(Tk_WindowId(tkwin)),
		    WM_SYSKEYDOWN, VK_MENU,
		    (int) (scanCode << 16) | (1 << 29) | (1 << 24));
	    break;
	case XK_F10:
	    scanCode = MapVirtualKey(VK_F10, 0);
	    CallWindowProc(DefWindowProc, Tk_GetHWND(Tk_WindowId(tkwin)),
		    WM_SYSKEYDOWN, VK_F10, (int) (scanCode << 16));
	    break;
	default:
	    virtualKey = XKeysymToKeycode(winPtr->display, keySym);
	    scanCode = MapVirtualKey(virtualKey, 0);
	    if (0 != scanCode) {
		XKeyEvent xkey = eventPtr->xkey;
		CallWindowProc(DefWindowProc, Tk_GetHWND(Tk_WindowId(tkwin)),
			WM_SYSKEYDOWN, virtualKey,
			(int) ((scanCode << 16) | (1 << 29)));
		if (xkey.nbytes > 0) {
		    for (i = 0; i < xkey.nbytes; i++) {
			CallWindowProc(DefWindowProc,
				Tk_GetHWND(Tk_WindowId(tkwin)), WM_SYSCHAR,
				xkey.trans_chars[i],
				(int) ((scanCode << 16) | (1 << 29)));
		    }
		}
	    }
	}
    } else if (eventPtr->type == KeyRelease) {
	switch (keySym) {
	case XK_Alt_L:
	    scanCode = MapVirtualKey(VK_LMENU, 0);
	    CallWindowProc(DefWindowProc, Tk_GetHWND(Tk_WindowId(tkwin)),
		    WM_SYSKEYUP, VK_MENU, (int) (scanCode << 16)
		    | (1 << 29) | (1 << 30) | (1 << 31));
	    break;
	case XK_Alt_R:
	    scanCode = MapVirtualKey(VK_RMENU, 0);
	    CallWindowProc(DefWindowProc, Tk_GetHWND(Tk_WindowId(tkwin)),
		    WM_SYSKEYUP, VK_MENU, (int) (scanCode << 16) | (1 << 24)
		    | (1 << 29) | (1 << 30) | (1 << 31));
	    break;
	case XK_F10:
	    scanCode = MapVirtualKey(VK_F10, 0);
	    CallWindowProc(DefWindowProc, Tk_GetHWND(Tk_WindowId(tkwin)),
		    WM_SYSKEYUP, VK_F10,
		    (int) (scanCode << 16) | (1 << 30) | (1 << 31));
	    break;
	default:
	    virtualKey = XKeysymToKeycode(winPtr->display, keySym);
	    scanCode = MapVirtualKey(virtualKey, 0);
	    if (0 != scanCode) {
		CallWindowProc(DefWindowProc, Tk_GetHWND(Tk_WindowId(tkwin)),
			WM_SYSKEYUP, virtualKey, (int) ((scanCode << 16)
			| (1 << 29) | (1 << 30) | (1 << 31)));
	    }
	}
    }
    return TCL_OK;
}
................................................................................
				 * called? */
{
    char sizeString[TCL_INTEGER_SPACE];
    char faceName[LF_FACESIZE];
    HDC scratchDC;
    int bold = 0;
    int italic = 0;
    TEXTMETRIC tm;
    int pointSize;
    HFONT menuFont;
    /* See: [Bug #3239768] tk8.4.19 (and later) WIN32 menu font support */
    struct {
        NONCLIENTMETRICSW metrics;
#if (WINVER < 0x0600)
        int padding;
................................................................................
     */

    defaultBorderWidth = GetSystemMetrics(SM_CXBORDER);
    if (GetSystemMetrics(SM_CYBORDER) > defaultBorderWidth) {
	defaultBorderWidth = GetSystemMetrics(SM_CYBORDER);
    }

    scratchDC = CreateDCA("DISPLAY", NULL, NULL, NULL);
    if (!firstTime) {
	Tcl_DStringFree(&menuFontDString);
    }
    Tcl_DStringInit(&menuFontDString);

    nc.metrics.cbSize = sizeof(nc);

    os.dwOSVersionInfoSize = sizeof(OSVERSIONINFOW);
    GetVersionExW(&os);
    if (os.dwMajorVersion < 6) {
	nc.metrics.cbSize -= sizeof(int);
    }

    SystemParametersInfo(SPI_GETNONCLIENTMETRICS, nc.metrics.cbSize,
	    &nc.metrics, 0);
    menuFont = CreateFontIndirectW(&nc.metrics.lfMenuFont);
    SelectObject(scratchDC, menuFont);
    GetTextMetrics(scratchDC, &tm);
    GetTextFaceA(scratchDC, LF_FACESIZE, faceName);
    pointSize = MulDiv(tm.tmHeight - tm.tmInternalLeading,
	    72, GetDeviceCaps(scratchDC, LOGPIXELSY));
    if (tm.tmWeight >= 700) {
	bold = 1;
    }
    if (tm.tmItalic) {
................................................................................

    /*
     * Accelerators used to be always underlines until Win2K when a system
     * parameter was introduced to hide them unless Alt is pressed.
     */

    showMenuAccelerators = TRUE;
    SystemParametersInfo(SPI_GETKEYBOARDCUES, 0, &showMenuAccelerators, 0);
}
 
/*
 *----------------------------------------------------------------------
 *
 * TkpMenuInit --
 *







|







 







|







 







|







 







|







 







|







 







|







 







|
|




|
|




|
|




|


|




|










|
|




|
|




|
|





|

|







 







|







 







|













|



|







 







|







569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
...
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
...
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
....
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
....
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
....
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
....
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
....
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
....
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
....
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
ReconfigureWindowsMenu(
    ClientData clientData)	/* The menu we are rebuilding */
{
    TkMenu *menuPtr = clientData;
    TkMenuEntry *mePtr;
    HMENU winMenuHdl = (HMENU) menuPtr->platformData;
    char *itemText = NULL;
    LPCWSTR lpNewItem;
    UINT flags;
    UINT itemID;
    int i, count, systemMenu = 0, base;
    Tcl_DString translatedText;

    if (NULL == winMenuHdl) {
    	return;
................................................................................
	    continue;
	}

	itemText = GetEntryText(menuPtr, mePtr);
	if ((menuPtr->menuType == MENUBAR)
		|| (menuPtr->menuFlags & MENU_SYSTEM_MENU)) {
	    Tcl_WinUtfToTChar(itemText, -1, &translatedText);
	    lpNewItem = (LPCWSTR) Tcl_DStringValue(&translatedText);
	    flags |= MF_STRING;
	} else {
	    lpNewItem = (LPCWSTR) mePtr;
	    flags |= MF_OWNERDRAW;
	}

	/*
................................................................................
    UINT message,
    WPARAM wParam,
    LPARAM lParam)
{
    LRESULT lResult;

    if (!TkWinHandleMenuEvent(&hwnd, &message, &wParam, &lParam, &lResult)) {
	lResult = DefWindowProcW(hwnd, message, wParam, lParam);
    }
    return lResult;
}
 
/*
 *----------------------------------------------------------------------
 *
................................................................................
	lResult = TkWinHandleMenuEvent(&hwnd, &message, &wParam, &lParam,
		&lResult);
	if (lResult || (GetCapture() != hwnd)) {
	    break;
	}
	/* FALLTHRU */
    default:
	lResult = DefWindowProcW(hwnd, message, wParam, lParam);
	break;
    }
    return lResult;
}
 
/*
 *----------------------------------------------------------------------
................................................................................
    POINT ptOrg;
    int topOffset, leftOffset;

    SetBkColor(hdc, gc->background);
    SetTextColor(hdc, gc->foreground);

    scratchDC = CreateCompatibleDC(hdc);
    bitmap = LoadBitmapW(NULL, (LPCWSTR)MAKEINTRESOURCE(bitmapID));

    SelectObject(scratchDC, bitmap);
    SetMapMode(scratchDC, GetMapMode(hdc));
    GetObjectA(bitmap, sizeof(BITMAP), &bm);
    ptSize.x = bm.bmWidth;
    ptSize.y = bm.bmHeight;
    DPtoLP(scratchDC, &ptSize, 1);
................................................................................
/*
 *--------------------------------------------------------------
 *
 * TkWinMenuKeyObjCmd --
 *
 *	This function is invoked when keys related to pulling down menus is
 *	pressed. The corresponding Windows events are generated and passed to
 *	DefWindowProcW if appropriate. This cmd is registered as tk::WinMenuKey
 *	in the interp.
 *
 * Results:
 *	Always returns TCL_OK.
 *
 * Side effects:
 *	The menu system may take over and process user events for menu input.
................................................................................
	return TCL_ERROR;
    }
    keySym = i;

    if (eventPtr->type == KeyPress) {
	switch (keySym) {
	case XK_Alt_L:
	    scanCode = MapVirtualKeyW(VK_LMENU, 0);
	    CallWindowProcW(DefWindowProcW, Tk_GetHWND(Tk_WindowId(tkwin)),
		    WM_SYSKEYDOWN, VK_MENU,
		    (int) (scanCode << 16) | (1 << 29));
	    break;
	case XK_Alt_R:
	    scanCode = MapVirtualKeyW(VK_RMENU, 0);
	    CallWindowProcW(DefWindowProcW, Tk_GetHWND(Tk_WindowId(tkwin)),
		    WM_SYSKEYDOWN, VK_MENU,
		    (int) (scanCode << 16) | (1 << 29) | (1 << 24));
	    break;
	case XK_F10:
	    scanCode = MapVirtualKeyW(VK_F10, 0);
	    CallWindowProcW(DefWindowProcW, Tk_GetHWND(Tk_WindowId(tkwin)),
		    WM_SYSKEYDOWN, VK_F10, (int) (scanCode << 16));
	    break;
	default:
	    virtualKey = XKeysymToKeycode(winPtr->display, keySym);
	    scanCode = MapVirtualKeyW(virtualKey, 0);
	    if (0 != scanCode) {
		XKeyEvent xkey = eventPtr->xkey;
		CallWindowProcW(DefWindowProcW, Tk_GetHWND(Tk_WindowId(tkwin)),
			WM_SYSKEYDOWN, virtualKey,
			(int) ((scanCode << 16) | (1 << 29)));
		if (xkey.nbytes > 0) {
		    for (i = 0; i < xkey.nbytes; i++) {
			CallWindowProcW(DefWindowProcW,
				Tk_GetHWND(Tk_WindowId(tkwin)), WM_SYSCHAR,
				xkey.trans_chars[i],
				(int) ((scanCode << 16) | (1 << 29)));
		    }
		}
	    }
	}
    } else if (eventPtr->type == KeyRelease) {
	switch (keySym) {
	case XK_Alt_L:
	    scanCode = MapVirtualKeyW(VK_LMENU, 0);
	    CallWindowProcW(DefWindowProcW, Tk_GetHWND(Tk_WindowId(tkwin)),
		    WM_SYSKEYUP, VK_MENU, (int) (scanCode << 16)
		    | (1 << 29) | (1 << 30) | (1 << 31));
	    break;
	case XK_Alt_R:
	    scanCode = MapVirtualKeyW(VK_RMENU, 0);
	    CallWindowProcW(DefWindowProcW, Tk_GetHWND(Tk_WindowId(tkwin)),
		    WM_SYSKEYUP, VK_MENU, (int) (scanCode << 16) | (1 << 24)
		    | (1 << 29) | (1 << 30) | (1 << 31));
	    break;
	case XK_F10:
	    scanCode = MapVirtualKeyW(VK_F10, 0);
	    CallWindowProcW(DefWindowProcW, Tk_GetHWND(Tk_WindowId(tkwin)),
		    WM_SYSKEYUP, VK_F10,
		    (int) (scanCode << 16) | (1 << 30) | (1 << 31));
	    break;
	default:
	    virtualKey = XKeysymToKeycode(winPtr->display, keySym);
	    scanCode = MapVirtualKeyW(virtualKey, 0);
	    if (0 != scanCode) {
		CallWindowProcW(DefWindowProcW, Tk_GetHWND(Tk_WindowId(tkwin)),
			WM_SYSKEYUP, virtualKey, (int) ((scanCode << 16)
			| (1 << 29) | (1 << 30) | (1 << 31)));
	    }
	}
    }
    return TCL_OK;
}
................................................................................
				 * called? */
{
    char sizeString[TCL_INTEGER_SPACE];
    char faceName[LF_FACESIZE];
    HDC scratchDC;
    int bold = 0;
    int italic = 0;
    TEXTMETRICW tm;
    int pointSize;
    HFONT menuFont;
    /* See: [Bug #3239768] tk8.4.19 (and later) WIN32 menu font support */
    struct {
        NONCLIENTMETRICSW metrics;
#if (WINVER < 0x0600)
        int padding;
................................................................................
     */

    defaultBorderWidth = GetSystemMetrics(SM_CXBORDER);
    if (GetSystemMetrics(SM_CYBORDER) > defaultBorderWidth) {
	defaultBorderWidth = GetSystemMetrics(SM_CYBORDER);
    }

    scratchDC = CreateDCW(L"DISPLAY", NULL, NULL, NULL);
    if (!firstTime) {
	Tcl_DStringFree(&menuFontDString);
    }
    Tcl_DStringInit(&menuFontDString);

    nc.metrics.cbSize = sizeof(nc);

    os.dwOSVersionInfoSize = sizeof(OSVERSIONINFOW);
    GetVersionExW(&os);
    if (os.dwMajorVersion < 6) {
	nc.metrics.cbSize -= sizeof(int);
    }

    SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, nc.metrics.cbSize,
	    &nc.metrics, 0);
    menuFont = CreateFontIndirectW(&nc.metrics.lfMenuFont);
    SelectObject(scratchDC, menuFont);
    GetTextMetricsW(scratchDC, &tm);
    GetTextFaceA(scratchDC, LF_FACESIZE, faceName);
    pointSize = MulDiv(tm.tmHeight - tm.tmInternalLeading,
	    72, GetDeviceCaps(scratchDC, LOGPIXELSY));
    if (tm.tmWeight >= 700) {
	bold = 1;
    }
    if (tm.tmItalic) {
................................................................................

    /*
     * Accelerators used to be always underlines until Win2K when a system
     * parameter was introduced to hide them unless Alt is pressed.
     */

    showMenuAccelerators = TRUE;
    SystemParametersInfoW(SPI_GETKEYBOARDCUES, 0, &showMenuAccelerators, 0);
}
 
/*
 *----------------------------------------------------------------------
 *
 * TkpMenuInit --
 *

Changes to jni/sdl2tk/win/tkWinScrlbr.c.

241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
...
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
...
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
	    TkWinSetWindowPos(scrollPtr->hwnd, Tk_GetHWND(winPtr->window),
		    Below);
	    break;
	}
    }

    scrollPtr->lastVertical = scrollPtr->info.vertical;
    scrollPtr->oldProc = (WNDPROC)SetWindowLongPtr(scrollPtr->hwnd,
	    GWLP_WNDPROC, (LONG_PTR) ScrollbarProc);
    window = Tk_AttachHWND(tkwin, scrollPtr->hwnd);

    UpdateScrollbar(scrollPtr);
    return window;
}
 
................................................................................
     * Destroy and recreate the scrollbar control if the orientation has
     * changed.
     */

    if (scrollPtr->lastVertical != scrollPtr->info.vertical) {
	HWND hwnd = Tk_GetHWND(Tk_WindowId(tkwin));

	SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR) scrollPtr->oldProc);
	DestroyWindow(hwnd);

	CreateProc(tkwin, Tk_WindowId(Tk_Parent(tkwin)),
		(ClientData) scrollPtr);
    } else {
	UpdateScrollbar(scrollPtr);
    }
................................................................................
TkpDestroyScrollbar(
    TkScrollbar *scrollPtr)
{
    WinScrollbar *winScrollPtr = (WinScrollbar *)scrollPtr;
    HWND hwnd = winScrollPtr->hwnd;

    if (hwnd) {
	SetWindowLongPtr(hwnd, GWLP_WNDPROC, (INT_PTR) winScrollPtr->oldProc);
	if (winScrollPtr->winFlags & IN_MODAL_LOOP) {
	    ((TkWindow *)scrollPtr->tkwin)->flags |= TK_DONT_DESTROY_WINDOW;
	    SetParent(hwnd, NULL);
	}
    }
    winScrollPtr->winFlags |= ALREADY_DEAD;
}







|







 







|







 







|







241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
...
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
...
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
	    TkWinSetWindowPos(scrollPtr->hwnd, Tk_GetHWND(winPtr->window),
		    Below);
	    break;
	}
    }

    scrollPtr->lastVertical = scrollPtr->info.vertical;
    scrollPtr->oldProc = (WNDPROC)SetWindowLongPtrW(scrollPtr->hwnd,
	    GWLP_WNDPROC, (LONG_PTR) ScrollbarProc);
    window = Tk_AttachHWND(tkwin, scrollPtr->hwnd);

    UpdateScrollbar(scrollPtr);
    return window;
}
 
................................................................................
     * Destroy and recreate the scrollbar control if the orientation has
     * changed.
     */

    if (scrollPtr->lastVertical != scrollPtr->info.vertical) {
	HWND hwnd = Tk_GetHWND(Tk_WindowId(tkwin));

	SetWindowLongPtrW(hwnd, GWLP_WNDPROC, (LONG_PTR) scrollPtr->oldProc);
	DestroyWindow(hwnd);

	CreateProc(tkwin, Tk_WindowId(Tk_Parent(tkwin)),
		(ClientData) scrollPtr);
    } else {
	UpdateScrollbar(scrollPtr);
    }
................................................................................
TkpDestroyScrollbar(
    TkScrollbar *scrollPtr)
{
    WinScrollbar *winScrollPtr = (WinScrollbar *)scrollPtr;
    HWND hwnd = winScrollPtr->hwnd;

    if (hwnd) {
	SetWindowLongPtrW(hwnd, GWLP_WNDPROC, (INT_PTR) winScrollPtr->oldProc);
	if (winScrollPtr->winFlags & IN_MODAL_LOOP) {
	    ((TkWindow *)scrollPtr->tkwin)->flags |= TK_DONT_DESTROY_WINDOW;
	    SetParent(hwnd, NULL);
	}
    }
    winScrollPtr->winFlags |= ALREADY_DEAD;
}

Changes to jni/sdl2tk/win/tkWinTest.c.

433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
...
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
static int
TestfindwindowObjCmd(
    ClientData clientData,	/* Main window for application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument values. */
{
    const WCHAR  *title = NULL, *class = NULL;
    Tcl_DString titleString, classString;
    HWND hwnd = NULL;
    int r = TCL_OK;
    DWORD myPid;

    Tcl_DStringInit(&classString);
    Tcl_DStringInit(&titleString);
................................................................................
    }

    dictObj = Tcl_NewDictObj();
    Tcl_DictObjPut(interp, dictObj, Tcl_NewStringObj("class", 5), classObj);
    Tcl_DictObjPut(interp, dictObj, Tcl_NewStringObj("id", 2),
	Tcl_NewLongObj(GetWindowLongA(INT2PTR(hwnd), GWL_ID)));

    cch = GetWindowTextW(INT2PTR(hwnd), (LPWSTR)buf, cchBuf);
    Tcl_WinTCharToUtf(buf, cch * sizeof (WCHAR), &ds);
    textObj = Tcl_NewStringObj(Tcl_DStringValue(&ds), Tcl_DStringLength(&ds));
    Tcl_DStringFree(&ds);

    Tcl_DictObjPut(interp, dictObj, Tcl_NewStringObj("text", 4), textObj);
    Tcl_DictObjPut(interp, dictObj, Tcl_NewStringObj("parent", 6),
	Tcl_NewLongObj(PTR2INT(GetParent((INT2PTR(hwnd))))));







|







 







|







433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
...
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
static int
TestfindwindowObjCmd(
    ClientData clientData,	/* Main window for application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument values. */
{
    LPCWSTR title = NULL, class = NULL;
    Tcl_DString titleString, classString;
    HWND hwnd = NULL;
    int r = TCL_OK;
    DWORD myPid;

    Tcl_DStringInit(&classString);
    Tcl_DStringInit(&titleString);
................................................................................
    }

    dictObj = Tcl_NewDictObj();
    Tcl_DictObjPut(interp, dictObj, Tcl_NewStringObj("class", 5), classObj);
    Tcl_DictObjPut(interp, dictObj, Tcl_NewStringObj("id", 2),
	Tcl_NewLongObj(GetWindowLongA(INT2PTR(hwnd), GWL_ID)));

    cch = GetWindowTextW(INT2PTR(hwnd), buf, cchBuf);
    Tcl_WinTCharToUtf(buf, cch * sizeof (WCHAR), &ds);
    textObj = Tcl_NewStringObj(Tcl_DStringValue(&ds), Tcl_DStringLength(&ds));
    Tcl_DStringFree(&ds);

    Tcl_DictObjPut(interp, dictObj, Tcl_NewStringObj("text", 4), textObj);
    Tcl_DictObjPut(interp, dictObj, Tcl_NewStringObj("parent", 6),
	Tcl_NewLongObj(PTR2INT(GetParent((INT2PTR(hwnd))))));

Changes to jni/sdl2tk/win/tkWinWm.c.

1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
....
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
....
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
....
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
....
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
....
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
....
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
....
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
....
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
....
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
....
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
....
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
....
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
....
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
....
4934
4935
4936
4937
4938
4939
4940
4941
4942
4943
4944
4945
4946
4947
4948
....
5448
5449
5450
5451
5452
5453
5454
5455
5456
5457
5458
5459
5460
5461
5462
....
5501
5502
5503
5504
5505
5506
5507
5508
5509
5510
5511
5512
5513
5514
5515
....
5553
5554
5555
5556
5557
5558
5559
5560
5561
5562
5563
5564
5565
5566
5567
....
5970
5971
5972
5973
5974
5975
5976
5977
5978
5979
5980
5981
5982
5983
5984
....
6275
6276
6277
6278
6279
6280
6281
6282
6283
6284
6285
6286
6287
6288
6289
....
6487
6488
6489
6490
6491
6492
6493
6494
6495
6496
6497
6498
6499
6500
6501
6502
....
7191
7192
7193
7194
7195
7196
7197
7198
7199
7200
7201
7202
7203
7204
7205
....
7417
7418
7419
7420
7421
7422
7423
7424
7425
7426
7427
7428
7429
7430
7431
....
7731
7732
7733
7734
7735
7736
7737
7738
7739
7740
7741
7742
7743
7744
7745
....
8127
8128
8129
8130
8131
8132
8133
8134
8135
8136
8137
8138
8139
8140
8141
....
8318
8319
8320
8321
8322
8323
8324
8325
8326
8327
8328
8329
8330
8331
8332
....
8395
8396
8397
8398
8399
8400
8401
8402
8403
8404
8405
8406
8407
8408
8409
....
8414
8415
8416
8417
8418
8419
8420
8421
8422
8423
8424
8425
8426
8427
8428
8429
8430
8431
....
8931
8932
8933
8934
8935
8936
8937
8938
8939
8940
8941
8942
8943
8944
8945
8946
8947
8948
		return TCL_ERROR;
	    }
	} else {
	    ThreadSpecificData *tsdPtr;

	    /*
	     * Don't check return result of SetClassLong() or
	     * SetClassLongPtr() since they return the previously set value
	     * which is zero on the initial call or in an error case. The MSDN
	     * documentation does not indicate that the result needs to be
	     * checked.
	     */

	    SetClassLongPtr(hwnd, GCLP_HICONSM,
		    (LPARAM) GetIcon(titlebaricon, ICON_SMALL));
	    SetClassLongPtr(hwnd, GCLP_HICON,
		    (LPARAM) GetIcon(titlebaricon, ICON_BIG));
	    tsdPtr = (ThreadSpecificData *)
		    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
	    if (tsdPtr->iconPtr != NULL) {
		DecrIconRefCount(tsdPtr->iconPtr);
	    }
	    tsdPtr->iconPtr = titlebaricon;
................................................................................
	    if (hwnd == NULL) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"Can't set icon; window has no wrapper.", -1));
		Tcl_SetErrorCode(interp, "TK", "WM", "ICON", "WRAPPER", NULL);
		return TCL_ERROR;
	    }
	}
	SendMessage(hwnd, WM_SETICON, ICON_SMALL,
		(LPARAM) GetIcon(titlebaricon, ICON_SMALL));
	SendMessage(hwnd, WM_SETICON, ICON_BIG,
		(LPARAM) GetIcon(titlebaricon, ICON_BIG));

	/*
	 * Update the iconPtr we keep for each WmInfo structure.
	 */

	if (wmPtr->iconPtr != NULL) {
................................................................................
    }

    /*
     * Find the icon otherwise associated with the toplevel, or finally with
     * the window class.
     */

    icon = (HICON) SendMessage(wmPtr->wrapper, WM_GETICON, iconsize,
	    (LPARAM) NULL);
    if (icon == (HICON) NULL) {
	icon = (HICON) GetClassLongPtr(wmPtr->wrapper,
		(iconsize == ICON_BIG) ? GCLP_HICON : GCLP_HICONSM);
    }
    return icon;
}
 
/*
 *----------------------------------------------------------------------
................................................................................
     * completed, then the user data slot will not have been set yet, so we
     * use the global createWindow variable.
     */

    if (tsdPtr->createWindow) {
	return tsdPtr->createWindow;
    }
    return (TkWindow *) GetWindowLongPtr(hwnd, GWLP_USERDATA);
}
 
/*
 *----------------------------------------------------------------------
 *
 * SetLimits --
 *
................................................................................

	wmPtr->wrapper = CreateWindowExW(wmPtr->exStyle,
		TK_WIN_TOPLEVEL_CLASS_NAME,
		(LPCWSTR) 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;

	if ((wmPtr->exStyleConfig & WS_EX_LAYERED) &&
	    (pSetLayeredWindowAttributes != NULL)) {
	    /*
	     * The user supplies a double from [0..1], but Windows wants an
	     * int (transparent) 0..255 (opaque), so do the translation. Add
................................................................................

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

    SetWindowLongPtr(child, GWL_STYLE,
	    WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS);

    if (winPtr->flags & TK_EMBEDDED) {
	SetWindowLongPtr(child, GWLP_WNDPROC, (LONG_PTR) TopLevelProc);
    }

    SetParent(child, wmPtr->wrapper);
    if (oldWrapper) {
	hSmallIcon = (HICON)
		SendMessage(oldWrapper, WM_GETICON, ICON_SMALL, (LPARAM)NULL);
	hBigIcon = (HICON)
		SendMessage(oldWrapper, WM_GETICON, ICON_BIG, (LPARAM) NULL);
    }

    if (oldWrapper && (oldWrapper != wmPtr->wrapper)
	    && (oldWrapper != GetDesktopWindow())) {
	SetWindowLongPtr(oldWrapper, GWLP_USERDATA, (LONG_PTR) 0);

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

................................................................................

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

    wmPtr->flags &= ~WM_NEVER_MAPPED;
    if (winPtr->flags & TK_EMBEDDED &&
	    SendMessage(wmPtr->wrapper, TK_ATTACHWINDOW, (WPARAM) child, 0)) {
	SendMessage(wmPtr->wrapper, TK_GEOMETRYREQ,
		Tk_ReqWidth((Tk_Window) winPtr),
		Tk_ReqHeight((Tk_Window) winPtr));
	SendMessage(wmPtr->wrapper, TK_SETMENU, (WPARAM) wmPtr->hMenu,
		(LPARAM) Tk_GetMenuHWND((Tk_Window) winPtr));
    }

    /*
     * Force an initial transition from withdrawn to the real initial state.
     * Set the Z order based on previous wrapper before we set the state.
     */
................................................................................
		SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE|SWP_NOSENDCHANGING
		|SWP_NOOWNERZORDER);
    }
    TkpWmSetState(winPtr, state);
    wmPtr->hints.initial_state = state;

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

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

    if (winPtr->flags & TK_EMBEDDED) {
	if (state+1 != SendMessage(wmPtr->wrapper, TK_STATE, state, 0)) {
	    TkpWmSetState(winPtr, NormalState);
	    wmPtr->hints.initial_state = NormalState;
	}
	XMapWindow(winPtr->display, winPtr->window);
    }

    /*
................................................................................
	if (wmPtr->wrapper != NULL) {
	    DestroyWindow(wmPtr->wrapper);
	} else if (winPtr->window) {
	    DestroyWindow(Tk_GetHWND(winPtr->window));
	}
    } else {
	if (wmPtr->wrapper != NULL) {
	    SendMessage(wmPtr->wrapper, TK_DETACHWINDOW, 0, 0);
	}
    }
    if (wmPtr->iconPtr != NULL) {
	/*
	 * This may delete the icon resource data. I believe we should do this
	 * after destroying the decorative frame, because the decorative frame
	 * is using this icon.
................................................................................
		     * Set the window directly regardless of UpdateWrapper.
		     * The user supplies a double from [0..1], but Windows
		     * wants an int (transparent) 0..255 (opaque), so do the
		     * translation. Add the 0.5 to round the value.
		     */

		    if (!(wmPtr->exStyleConfig & WS_EX_LAYERED)) {
			SetWindowLongPtr(wmPtr->wrapper, GWL_EXSTYLE,
				*stylePtr);
		    }
		    pSetLayeredWindowAttributes((HWND) wmPtr->wrapper,
			    wmPtr->colorref, (BYTE) (wmPtr->alpha * 255 + 0.5),
			    (unsigned) (LWA_ALPHA |
				    (wmPtr->crefObj ? LWA_COLORKEY : 0)));
		}
................................................................................
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"can't deiconify %s: it is an icon for %s",
		Tcl_GetString(objv[2]), Tk_PathName(wmPtr->iconFor)));
	Tcl_SetErrorCode(interp, "TK", "WM", "DEICONIFY", "ICON", NULL);
	return TCL_ERROR;
    }
    if (winPtr->flags & TK_EMBEDDED) {
	if (!SendMessage(wmPtr->wrapper, TK_DEICONIFY, 0, 0)) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't deiconify %s: the container does not support the request",
		    winPtr->pathName));
	    Tcl_SetErrorCode(interp, "TK", "WM", "COMMUNICATION", NULL);
	    return TCL_ERROR;
	}
	return TCL_OK;
................................................................................
	    height = wmPtr->reqGridHeight + (winPtr->changes.height
		    - winPtr->reqHeight)/wmPtr->heightInc;
	} else {
	    width = winPtr->changes.width;
	    height = winPtr->changes.height;
	}
	if (winPtr->flags & TK_EMBEDDED) {
	    int result = SendMessage(wmPtr->wrapper, TK_MOVEWINDOW, -1, -1);

	    wmPtr->x = result >> 16;
	    wmPtr->y = result & 0x0000ffff;
	}
	Tcl_SetObjResult(interp, Tcl_ObjPrintf("%dx%d%c%d%c%d",
		width, height, xSign, wmPtr->x, ySign, wmPtr->y));
	return TCL_OK;
................................................................................
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "window");
	return TCL_ERROR;
    }
    if (winPtr->flags & TK_EMBEDDED) {
	if (!SendMessage(wmPtr->wrapper, TK_ICONIFY, 0, 0)) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't iconify %s: the container does not support the request",
		    winPtr->pathName));
	    Tcl_SetErrorCode(interp, "TK", "WM", "ICONIFY", "EMBEDDED", NULL);
	    return TCL_ERROR;
	}
    }
................................................................................
    XSetWindowAttributes atts;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?boolean?");
	return TCL_ERROR;
    }
    if (winPtr->flags & TK_EMBEDDED) {
	curValue = SendMessage(wmPtr->wrapper, TK_OVERRIDEREDIRECT, -1, -1)-1;
	if (curValue < 0) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "Container does not support overrideredirect", -1));
	    Tcl_SetErrorCode(interp, "TK", "WM", "COMMUNICATION", NULL);
	    return TCL_ERROR;
	}
    } else {
................................................................................
	return TCL_OK;
    }
    if (Tcl_GetBooleanFromObj(interp, objv[3], &boolean) != TCL_OK) {
	return TCL_ERROR;
    }
    if (curValue != boolean) {
	if (winPtr->flags & TK_EMBEDDED) {
	    SendMessage(wmPtr->wrapper, TK_OVERRIDEREDIRECT, boolean, 0);
	} else {
	    /*
	     * Only do this if we are really changing value, because it causes
	     * some funky stuff to occur.
	     */

	    atts.override_redirect = (boolean) ? True : False;
................................................................................
	    case OPT_ZOOMED:
		state = ZoomState;
		break;
	    default:
		Tcl_Panic("unexpected index");
	    }

	    if (state+1 != SendMessage(wmPtr->wrapper, TK_STATE, state, 0)) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"can't change state of %s: the container does not support the request",
			winPtr->pathName));
		Tcl_SetErrorCode(interp, "TK", "WM", "COMMUNICATION", NULL);
		return TCL_ERROR;
	    }
	    return TCL_OK;
................................................................................

	if (wmPtr->iconFor != NULL) {
	    stateStr = "icon";
	} else {
	    int state;

	    if (winPtr->flags & TK_EMBEDDED) {
		state = SendMessage(wmPtr->wrapper, TK_STATE, -1, -1) - 1;
	    } else {
		state = wmPtr->hints.initial_state;
	    }
	    switch (state) {
	    case NormalState:	stateStr = "normal";	break;
	    case IconicState:	stateStr = "iconic";	break;
	    case WithdrawnState: stateStr = "withdrawn"; break;
................................................................................

    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) {
	if (wrapper) {
	    WCHAR buf[256];
	    Tcl_DString titleString;
................................................................................
		"can't withdraw %s: it is an icon for %s",
		Tcl_GetString(objv[2]), Tk_PathName(wmPtr->iconFor)));
	Tcl_SetErrorCode(interp, "TK", "WM", "WITHDRAW", "ICON", NULL);
	return TCL_ERROR;
    }

    if (winPtr->flags & TK_EMBEDDED) {
	if (SendMessage(wmPtr->wrapper, TK_WITHDRAW, 0, 0) < 0) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't withdraw %s: the container does not support the request",
		    Tcl_GetString(objv[2])));
	    Tcl_SetErrorCode(interp, "TK", "WM", "COMMUNICATION", NULL);
	    return TCL_ERROR;
	}
    } else {
................................................................................
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    WmInfo *wmPtr;

    wmPtr = winPtr->wmInfoPtr;
    if (wmPtr) {
	if ((winPtr->flags & TK_EMBEDDED) && (wmPtr->wrapper != NULL)) {
	    SendMessage(wmPtr->wrapper, TK_GEOMETRYREQ, Tk_ReqWidth(tkwin),
		Tk_ReqHeight(tkwin));
	}
	if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) {
	    Tcl_DoWhenIdle(UpdateGeometryInfo, winPtr);
	    wmPtr->flags |= WM_UPDATE_PENDING;
	}
    }
................................................................................
	/*
	 * The wrapper window is in a different process, so we need to send it
	 * a geometry request. This protocol assumes that the other process
	 * understands this Tk message, otherwise our requested geometry will
	 * be ignored.
	 */

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

	/*
................................................................................
	insertAfter = (otherPtr->wmInfoPtr->wrapper != NULL)
		? otherPtr->wmInfoPtr->wrapper : Tk_GetHWND(otherPtr->window);
    } else {
	insertAfter = NULL;
    }

    if (winPtr->flags & TK_EMBEDDED) {
	SendMessage(winPtr->wmInfoPtr->wrapper, TK_RAISEWINDOW,
		(WPARAM) insertAfter, aboveBelow);
    } else {
	TkWinSetWindowPos(hwnd, insertAfter, aboveBelow);
    }
}
 
/*
................................................................................
    }
    if (!(winPtr->flags & TK_EMBEDDED)) {
	if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) {
	    Tcl_DoWhenIdle(UpdateGeometryInfo, winPtr);
	    wmPtr->flags |= WM_UPDATE_PENDING|WM_MOVE_PENDING;
	}
    } else {
	SendMessage(wmPtr->wrapper, TK_SETMENU, (WPARAM) hMenu,
		(LPARAM) Tk_GetMenuHWND(tkwin));
    }
}
 
/*
 *----------------------------------------------------------------------
 *
................................................................................
	oldPalette = SelectPalette(dc, tsdPtr->systemPalette, FALSE);
	if (RealizePalette(dc)) {
	    RefreshColormap(winPtr->atts.colormap, winPtr->dispPtr);
	} else if (wmPtr->cmapCount > 1) {
	    SelectPalette(dc, oldPalette, TRUE);
	    RealizePalette(dc);
	    ReleaseDC(hwnd, dc);
	    SendMessage(hwnd, WM_PALETTECHANGED, (WPARAM) hwnd, (LPARAM) NULL);
	    return TRUE;
	}
    } else {
	/*
	 * Window is being notified of a change in the system palette. If this
	 * window is the foreground window, then we should only install the
	 * secondary palettes, since the primary was installed in response to
................................................................................
	 */

	if (!(pos->flags & SWP_NOSIZE)) {
	    winPtr->changes.width = pos->cx;
	    winPtr->changes.height = pos->cy;
	}
	if (!(pos->flags & SWP_NOMOVE)) {
	    long result = SendMessage(winPtr->wmInfoPtr->wrapper,
		    TK_MOVEWINDOW, -1, -1);
	    winPtr->wmInfoPtr->x = winPtr->changes.x = result >> 16;
	    winPtr->wmInfoPtr->y = winPtr->changes.y = result & 0xffff;
	}

	GenerateConfigureNotify(winPtr);

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

	    result = DefWindowProc(hwnd, message, wParam, lParam);
	    goto done;
	}

	/*
	 * Don't activate the window yet since there is a grab that takes
	 * precedence. Instead we need to queue an event so we can check the
	 * grab state right before we handle the mouse event.
................................................................................
    case WM_MENUSELECT:
    case WM_ENTERIDLE:
    case WM_INITMENUPOPUP:
	if (winPtr) {
	    HWND hMenuHWnd = Tk_GetEmbeddedMenuHWND((Tk_Window) winPtr);

	    if (hMenuHWnd) {
		if (SendMessage(hMenuHWnd, message, wParam, lParam)) {
		    goto done;
		}
	    } else if (TkWinHandleMenuEvent(&hwnd, &message, &wParam, &lParam,
		    &result)) {
		goto done;
	    }
	}
................................................................................
	HWND child = Tk_GetHWND(winPtr->window);

	if (message == WM_SETFOCUS) {
	    SetFocus(child);
	    result = 0;
	} else if (!Tk_TranslateWinEvent(child, message, wParam, lParam,
		&result)) {
	    result = DefWindowProc(hwnd, message, wParam, lParam);
	}
    } else {
	result = DefWindowProc(hwnd, message, wParam, lParam);
    }

  done:
    Tcl_ServiceAll();
    return result;
}
 
................................................................................
void
TkpWinToplevelDetachWindow(
    TkWindow *winPtr)
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;

    if (winPtr->flags & TK_EMBEDDED) {
	int state = SendMessage(wmPtr->wrapper, TK_STATE, -1, -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 = NULL;
	if (state >= 0 && state <= 3) {
	    wmPtr->hints.initial_state = state;
	}
    }







|





|

|







 







|

|







 







|


|







 







|







 







|







 







|



|





|

|




|







 







|
|


|







 







|



|











|







 







|







 







|







 







|







 







|







 







|







 







|







 







|







 







|







 







|







 







|







 







|







 







|







 







|
|







 







|







 







|







 







|







 







|







 







|







 







|







 







|


|







 







|

|
|







1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
....
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
....
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
....
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
....
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
....
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
....
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
....
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
....
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
....
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
....
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
....
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
....
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
....
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
....
4934
4935
4936
4937
4938
4939
4940
4941
4942
4943
4944
4945
4946
4947
4948
....
5448
5449
5450
5451
5452
5453
5454
5455
5456
5457
5458
5459
5460
5461
5462
....
5501
5502
5503
5504
5505
5506
5507
5508
5509
5510
5511
5512
5513
5514
5515
....
5553
5554
5555
5556
5557
5558
5559
5560
5561
5562
5563
5564
5565
5566
5567
....
5970
5971
5972
5973
5974
5975
5976
5977
5978
5979
5980
5981
5982
5983
5984
....
6275
6276
6277
6278
6279
6280
6281
6282
6283
6284
6285
6286
6287
6288
6289
....
6487
6488
6489
6490
6491
6492
6493
6494
6495
6496
6497
6498
6499
6500
6501
6502
....
7191
7192
7193
7194
7195
7196
7197
7198
7199
7200
7201
7202
7203
7204
7205
....
7417
7418
7419
7420
7421
7422
7423
7424
7425
7426
7427
7428
7429
7430
7431
....
7731
7732
7733
7734
7735
7736
7737
7738
7739
7740
7741
7742
7743
7744
7745
....
8127
8128
8129
8130
8131
8132
8133
8134
8135
8136
8137
8138
8139
8140
8141
....
8318
8319
8320
8321
8322
8323
8324
8325
8326
8327
8328
8329
8330
8331
8332
....
8395
8396
8397
8398
8399
8400
8401
8402
8403
8404
8405
8406
8407
8408
8409
....
8414
8415
8416
8417
8418
8419
8420
8421
8422
8423
8424
8425
8426
8427
8428
8429
8430
8431
....
8931
8932
8933
8934
8935
8936
8937
8938
8939
8940
8941
8942
8943
8944
8945
8946
8947
8948
		return TCL_ERROR;
	    }
	} else {
	    ThreadSpecificData *tsdPtr;

	    /*
	     * Don't check return result of SetClassLong() or
	     * SetClassLongPtrW() since they return the previously set value
	     * which is zero on the initial call or in an error case. The MSDN
	     * documentation does not indicate that the result needs to be
	     * checked.
	     */

	    SetClassLongPtrW(hwnd, GCLP_HICONSM,
		    (LPARAM) GetIcon(titlebaricon, ICON_SMALL));
	    SetClassLongPtrW(hwnd, GCLP_HICON,
		    (LPARAM) GetIcon(titlebaricon, ICON_BIG));
	    tsdPtr = (ThreadSpecificData *)
		    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
	    if (tsdPtr->iconPtr != NULL) {
		DecrIconRefCount(tsdPtr->iconPtr);
	    }
	    tsdPtr->iconPtr = titlebaricon;
................................................................................
	    if (hwnd == NULL) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"Can't set icon; window has no wrapper.", -1));
		Tcl_SetErrorCode(interp, "TK", "WM", "ICON", "WRAPPER", NULL);
		return TCL_ERROR;
	    }
	}
	SendMessageW(hwnd, WM_SETICON, ICON_SMALL,
		(LPARAM) GetIcon(titlebaricon, ICON_SMALL));
	SendMessageW(hwnd, WM_SETICON, ICON_BIG,
		(LPARAM) GetIcon(titlebaricon, ICON_BIG));

	/*
	 * Update the iconPtr we keep for each WmInfo structure.
	 */

	if (wmPtr->iconPtr != NULL) {
................................................................................
    }

    /*
     * Find the icon otherwise associated with the toplevel, or finally with
     * the window class.
     */

    icon = (HICON) SendMessageW(wmPtr->wrapper, WM_GETICON, iconsize,
	    (LPARAM) NULL);
    if (icon == (HICON) NULL) {
	icon = (HICON) GetClassLongPtrW(wmPtr->wrapper,
		(iconsize == ICON_BIG) ? GCLP_HICON : GCLP_HICONSM);
    }
    return icon;
}
 
/*
 *----------------------------------------------------------------------
................................................................................
     * completed, then the user data slot will not have been set yet, so we
     * use the global createWindow variable.
     */

    if (tsdPtr->createWindow) {
	return tsdPtr->createWindow;
    }
    return (TkWindow *) GetWindowLongPtrW(hwnd, GWLP_USERDATA);
}
 
/*
 *----------------------------------------------------------------------
 *
 * SetLimits --
 *
................................................................................

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

	if ((wmPtr->exStyleConfig & WS_EX_LAYERED) &&
	    (pSetLayeredWindowAttributes != NULL)) {
	    /*
	     * The user supplies a double from [0..1], but Windows wants an
	     * int (transparent) 0..255 (opaque), so do the translation. Add
................................................................................

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

    SetWindowLongPtrW(child, GWL_STYLE,
	    WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS);

    if (winPtr->flags & TK_EMBEDDED) {
	SetWindowLongPtrW(child, GWLP_WNDPROC, (LONG_PTR) TopLevelProc);
    }

    SetParent(child, wmPtr->wrapper);
    if (oldWrapper) {
	hSmallIcon = (HICON)
		SendMessageW(oldWrapper, WM_GETICON, ICON_SMALL, (LPARAM)NULL);
	hBigIcon = (HICON)
		SendMessageW(oldWrapper, WM_GETICON, ICON_BIG, (LPARAM) NULL);
    }

    if (oldWrapper && (oldWrapper != wmPtr->wrapper)
	    && (oldWrapper != GetDesktopWindow())) {
	SetWindowLongPtrW(oldWrapper, GWLP_USERDATA, (LONG_PTR) 0);

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

................................................................................

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

    wmPtr->flags &= ~WM_NEVER_MAPPED;
    if (winPtr->flags & TK_EMBEDDED &&
	    SendMessageW(wmPtr->wrapper, TK_ATTACHWINDOW, (WPARAM) child, 0)) {
	SendMessageW(wmPtr->wrapper, TK_GEOMETRYREQ,
		Tk_ReqWidth((Tk_Window) winPtr),
		Tk_ReqHeight((Tk_Window) winPtr));
	SendMessageW(wmPtr->wrapper, TK_SETMENU, (WPARAM) wmPtr->hMenu,
		(LPARAM) Tk_GetMenuHWND((Tk_Window) winPtr));
    }

    /*
     * Force an initial transition from withdrawn to the real initial state.
     * Set the Z order based on previous wrapper before we set the state.
     */
................................................................................
		SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE|SWP_NOSENDCHANGING
		|SWP_NOOWNERZORDER);
    }
    TkpWmSetState(winPtr, state);
    wmPtr->hints.initial_state = state;

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

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

    if (winPtr->flags & TK_EMBEDDED) {
	if (state+1 != SendMessageW(wmPtr->wrapper, TK_STATE, state, 0)) {
	    TkpWmSetState(winPtr, NormalState);
	    wmPtr->hints.initial_state = NormalState;
	}
	XMapWindow(winPtr->display, winPtr->window);
    }

    /*
................................................................................
	if (wmPtr->wrapper != NULL) {
	    DestroyWindow(wmPtr->wrapper);
	} else if (winPtr->window) {
	    DestroyWindow(Tk_GetHWND(winPtr->window));
	}
    } else {
	if (wmPtr->wrapper != NULL) {
	    SendMessageW(wmPtr->wrapper, TK_DETACHWINDOW, 0, 0);
	}
    }
    if (wmPtr->iconPtr != NULL) {
	/*
	 * This may delete the icon resource data. I believe we should do this
	 * after destroying the decorative frame, because the decorative frame
	 * is using this icon.
................................................................................
		     * Set the window directly regardless of UpdateWrapper.
		     * The user supplies a double from [0..1], but Windows
		     * wants an int (transparent) 0..255 (opaque), so do the
		     * translation. Add the 0.5 to round the value.
		     */

		    if (!(wmPtr->exStyleConfig & WS_EX_LAYERED)) {
			SetWindowLongPtrW(wmPtr->wrapper, GWL_EXSTYLE,
				*stylePtr);
		    }
		    pSetLayeredWindowAttributes((HWND) wmPtr->wrapper,
			    wmPtr->colorref, (BYTE) (wmPtr->alpha * 255 + 0.5),
			    (unsigned) (LWA_ALPHA |
				    (wmPtr->crefObj ? LWA_COLORKEY : 0)));
		}
................................................................................
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"can't deiconify %s: it is an icon for %s",
		Tcl_GetString(objv[2]), Tk_PathName(wmPtr->iconFor)));
	Tcl_SetErrorCode(interp, "TK", "WM", "DEICONIFY", "ICON", NULL);
	return TCL_ERROR;
    }
    if (winPtr->flags & TK_EMBEDDED) {
	if (!SendMessageW(wmPtr->wrapper, TK_DEICONIFY, 0, 0)) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't deiconify %s: the container does not support the request",
		    winPtr->pathName));
	    Tcl_SetErrorCode(interp, "TK", "WM", "COMMUNICATION", NULL);
	    return TCL_ERROR;
	}
	return TCL_OK;
................................................................................
	    height = wmPtr->reqGridHeight + (winPtr->changes.height
		    - winPtr->reqHeight)/wmPtr->heightInc;
	} else {
	    width = winPtr->changes.width;
	    height = winPtr->changes.height;
	}
	if (winPtr->flags & TK_EMBEDDED) {
	    int result = SendMessageW(wmPtr->wrapper, TK_MOVEWINDOW, -1, -1);

	    wmPtr->x = result >> 16;
	    wmPtr->y = result & 0x0000ffff;
	}
	Tcl_SetObjResult(interp, Tcl_ObjPrintf("%dx%d%c%d%c%d",
		width, height, xSign, wmPtr->x, ySign, wmPtr->y));
	return TCL_OK;
................................................................................
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "window");
	return TCL_ERROR;
    }
    if (winPtr->flags & TK_EMBEDDED) {
	if (!SendMessageW(wmPtr->wrapper, TK_ICONIFY, 0, 0)) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't iconify %s: the container does not support the request",
		    winPtr->pathName));
	    Tcl_SetErrorCode(interp, "TK", "WM", "ICONIFY", "EMBEDDED", NULL);
	    return TCL_ERROR;
	}
    }
................................................................................
    XSetWindowAttributes atts;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?boolean?");
	return TCL_ERROR;
    }
    if (winPtr->flags & TK_EMBEDDED) {
	curValue = SendMessageW(wmPtr->wrapper, TK_OVERRIDEREDIRECT, -1, -1)-1;
	if (curValue < 0) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "Container does not support overrideredirect", -1));
	    Tcl_SetErrorCode(interp, "TK", "WM", "COMMUNICATION", NULL);
	    return TCL_ERROR;
	}
    } else {
................................................................................
	return TCL_OK;
    }
    if (Tcl_GetBooleanFromObj(interp, objv[3], &boolean) != TCL_OK) {
	return TCL_ERROR;
    }
    if (curValue != boolean) {
	if (winPtr->flags & TK_EMBEDDED) {
	    SendMessageW(wmPtr->wrapper, TK_OVERRIDEREDIRECT, boolean, 0);
	} else {
	    /*
	     * Only do this if we are really changing value, because it causes
	     * some funky stuff to occur.
	     */

	    atts.override_redirect = (boolean) ? True : False;
................................................................................
	    case OPT_ZOOMED:
		state = ZoomState;
		break;
	    default:
		Tcl_Panic("unexpected index");
	    }

	    if (state+1 != SendMessageW(wmPtr->wrapper, TK_STATE, state, 0)) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"can't change state of %s: the container does not support the request",
			winPtr->pathName));
		Tcl_SetErrorCode(interp, "TK", "WM", "COMMUNICATION", NULL);
		return TCL_ERROR;
	    }
	    return TCL_OK;
................................................................................

	if (wmPtr->iconFor != NULL) {
	    stateStr = "icon";
	} else {
	    int state;

	    if (winPtr->flags & TK_EMBEDDED) {
		state = SendMessageW(wmPtr->wrapper, TK_STATE, -1, -1) - 1;
	    } else {
		state = wmPtr->hints.initial_state;
	    }
	    switch (state) {
	    case NormalState:	stateStr = "normal";	break;
	    case IconicState:	stateStr = "iconic";	break;
	    case WithdrawnState: stateStr = "withdrawn"; break;
................................................................................

    if (objc > 4) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?newTitle?");
	return TCL_ERROR;
    }

    if (winPtr->flags & TK_EMBEDDED) {
	wrapper = (HWND) SendMessageW(wmPtr->wrapper, TK_GETFRAMEWID, 0, 0);
    } else {
	wrapper = wmPtr->wrapper;
    }
    if (objc == 3) {
	if (wrapper) {
	    WCHAR buf[256];
	    Tcl_DString titleString;
................................................................................
		"can't withdraw %s: it is an icon for %s",
		Tcl_GetString(objv[2]), Tk_PathName(wmPtr->iconFor)));
	Tcl_SetErrorCode(interp, "TK", "WM", "WITHDRAW", "ICON", NULL);
	return TCL_ERROR;
    }

    if (winPtr->flags & TK_EMBEDDED) {
	if (SendMessageW(wmPtr->wrapper, TK_WITHDRAW, 0, 0) < 0) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't withdraw %s: the container does not support the request",
		    Tcl_GetString(objv[2])));
	    Tcl_SetErrorCode(interp, "TK", "WM", "COMMUNICATION", NULL);
	    return TCL_ERROR;
	}
    } else {
................................................................................
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    WmInfo *wmPtr;

    wmPtr = winPtr->wmInfoPtr;
    if (wmPtr) {
	if ((winPtr->flags & TK_EMBEDDED) && (wmPtr->wrapper != NULL)) {
	    SendMessageW(wmPtr->wrapper, TK_GEOMETRYREQ, Tk_ReqWidth(tkwin),
		Tk_ReqHeight(tkwin));
	}
	if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) {
	    Tcl_DoWhenIdle(UpdateGeometryInfo, winPtr);
	    wmPtr->flags |= WM_UPDATE_PENDING;
	}
    }
................................................................................
	/*
	 * The wrapper window is in a different process, so we need to send it
	 * a geometry request. This protocol assumes that the other process
	 * understands this Tk message, otherwise our requested geometry will
	 * be ignored.
	 */

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

	/*
................................................................................
	insertAfter = (otherPtr->wmInfoPtr->wrapper != NULL)
		? otherPtr->wmInfoPtr->wrapper : Tk_GetHWND(otherPtr->window);
    } else {
	insertAfter = NULL;
    }

    if (winPtr->flags & TK_EMBEDDED) {
	SendMessageW(winPtr->wmInfoPtr->wrapper, TK_RAISEWINDOW,
		(WPARAM) insertAfter, aboveBelow);
    } else {
	TkWinSetWindowPos(hwnd, insertAfter, aboveBelow);
    }
}
 
/*
................................................................................
    }
    if (!(winPtr->flags & TK_EMBEDDED)) {
	if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) {
	    Tcl_DoWhenIdle(UpdateGeometryInfo, winPtr);
	    wmPtr->flags |= WM_UPDATE_PENDING|WM_MOVE_PENDING;
	}
    } else {
	SendMessageW(wmPtr->wrapper, TK_SETMENU, (WPARAM) hMenu,
		(LPARAM) Tk_GetMenuHWND(tkwin));
    }
}
 
/*
 *----------------------------------------------------------------------
 *
................................................................................
	oldPalette = SelectPalette(dc, tsdPtr->systemPalette, FALSE);
	if (RealizePalette(dc)) {
	    RefreshColormap(winPtr->atts.colormap, winPtr->dispPtr);
	} else if (wmPtr->cmapCount > 1) {
	    SelectPalette(dc, oldPalette, TRUE);
	    RealizePalette(dc);
	    ReleaseDC(hwnd, dc);
	    SendMessageW(hwnd, WM_PALETTECHANGED, (WPARAM) hwnd, (LPARAM) NULL);
	    return TRUE;
	}
    } else {
	/*
	 * Window is being notified of a change in the system palette. If this
	 * window is the foreground window, then we should only install the
	 * secondary palettes, since the primary was installed in response to
................................................................................
	 */

	if (!(pos->flags & SWP_NOSIZE)) {
	    winPtr->changes.width = pos->cx;
	    winPtr->changes.height = pos->cy;
	}
	if (!(pos->flags & SWP_NOMOVE)) {
	    long result = SendMessageW(winPtr->wmInfoPtr->wrapper,
		    TK_MOVEWINDOW, -1, -1);
	    winPtr->wmInfoPtr->x = winPtr->changes.x = result >> 16;
	    winPtr->wmInfoPtr->y = winPtr->changes.y = result & 0xffff;
	}

	GenerateConfigureNotify(winPtr);

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

	    result = DefWindowProcW(hwnd, message, wParam, lParam);
	    goto done;
	}

	/*
	 * Don't activate the window yet since there is a grab that takes
	 * precedence. Instead we need to queue an event so we can check the
	 * grab state right before we handle the mouse event.
................................................................................
    case WM_MENUSELECT:
    case WM_ENTERIDLE:
    case WM_INITMENUPOPUP:
	if (winPtr) {
	    HWND hMenuHWnd = Tk_GetEmbeddedMenuHWND((Tk_Window) winPtr);

	    if (hMenuHWnd) {
		if (SendMessageW(hMenuHWnd, message, wParam, lParam)) {
		    goto done;
		}
	    } else if (TkWinHandleMenuEvent(&hwnd, &message, &wParam, &lParam,
		    &result)) {
		goto done;
	    }
	}
................................................................................
	HWND child = Tk_GetHWND(winPtr->window);

	if (message == WM_SETFOCUS) {
	    SetFocus(child);
	    result = 0;
	} else if (!Tk_TranslateWinEvent(child, message, wParam, lParam,
		&result)) {
	    result = DefWindowProcW(hwnd, message, wParam, lParam);
	}
    } else {
	result = DefWindowProcW(hwnd, message, wParam, lParam);
    }

  done:
    Tcl_ServiceAll();
    return result;
}
 
................................................................................
void
TkpWinToplevelDetachWindow(
    TkWindow *winPtr)
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;

    if (winPtr->flags & TK_EMBEDDED) {
	int state = SendMessageW(wmPtr->wrapper, TK_STATE, -1, -1) - 1;

	SendMessageW(wmPtr->wrapper, TK_SETMENU, 0, 0);
	SendMessageW(wmPtr->wrapper, TK_DETACHWINDOW, 0, 0);
	winPtr->flags &= ~TK_EMBEDDED;
	winPtr->privatePtr = NULL;
	wmPtr->wrapper = NULL;
	if (state >= 0 && state <= 3) {
	    wmPtr->hints.initial_state = state;
	}
    }

Changes to jni/sdl2tk/win/tkWinX.c.

782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
...
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
...
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
...
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
....
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
....
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
....
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
....
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
	UpdateInputLanguage((int) wParam);
	result = 1;
	break;

    case WM_IME_COMPOSITION:
	result = 0;
	if (HandleIMEComposition(hwnd, lParam) == 0) {
	    result = DefWindowProc(hwnd, message, wParam, lParam);
	}
	break;

    case WM_SETCURSOR:
	/*
	 * Short circuit the WM_SETCURSOR message since we set the cursor
	 * elsewhere.
................................................................................
    case WM_CREATE:
    case WM_ERASEBKGND:
	result = 0;
	break;

    case WM_PAINT:
	GenerateXEvent(hwnd, message, wParam, lParam);
	result = DefWindowProc(hwnd, message, wParam, lParam);
	break;

    case TK_CLAIMFOCUS:
    case TK_GEOMETRYREQ:
    case TK_ATTACHWINDOW:
    case TK_DETACHWINDOW:
    case TK_ICONIFY:
................................................................................
	        result = 1;
	    }
	}
	break;

    default:
	if (!Tk_TranslateWinEvent(hwnd, message, wParam, lParam, &result)) {
	    result = DefWindowProc(hwnd, message, wParam, lParam);
	}
	break;
    }

    /*
     * Handle any newly queued events before returning control to Windows.
     */
................................................................................
	 * or we will loop.
	 */

	HWND target = (message == WM_NOTIFY)
		? ((NMHDR*)lParam)->hwndFrom : (HWND) lParam;

	if (target && target != hwnd) {
	    *resultPtr = SendMessage(target, message, wParam, lParam);
	    return 1;
	}
	break;
    }

    case WM_LBUTTONDOWN:
    case WM_LBUTTONDBLCLK:
................................................................................
	    } else {
		event.xkey.nbytes = 1;
		event.xkey.trans_chars[0] = (char) wParam;

		if (IsDBCSLeadByte((BYTE) wParam)) {
		    MSG msg;

		    if ((PeekMessage(&msg, NULL, WM_CHAR, WM_CHAR,
		            PM_NOREMOVE) != 0)
			    && (msg.message == WM_CHAR)) {
			GetMessage(&msg, NULL, WM_CHAR, WM_CHAR);
			event.xkey.nbytes = 2;
			event.xkey.trans_chars[1] = (char) msg.wParam;
		   }
		}
	    }
	    Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);
	    event.type = KeyRelease;
................................................................................
 *
 *	This function works around a deficiency in some versions of Windows
 *	2000 to make it possible to entry multi-lingual characters under all
 *	versions of Windows 2000.
 *
 *	When an Input Method Editor (IME) is ready to send input characters to
 *	an application, it sends a WM_IME_COMPOSITION message with the
 *	GCS_RESULTSTR. However, The DefWindowProc() on English Windows 2000
 *	arbitrarily converts all non-Latin-1 characters in the composition to
 *	"?".
 *
 *	This function correctly processes the composition data and sends the
 *	UNICODE values of the composed characters to TK's event queue.
 *
 * Results:
................................................................................
    }

    hIMC = ImmGetContext(hwnd);
    if (!hIMC) {
	return 0;
    }

    n = ImmGetCompositionString(hIMC, GCS_RESULTSTR, NULL, 0);

    if (n > 0) {
	WCHAR *buff = (WCHAR *) ckalloc(n);
	TkWindow *winPtr;
	XEvent event;
	int i;

	n = ImmGetCompositionString(hIMC, GCS_RESULTSTR, buff, (unsigned) n) / 2;

	/*
	 * Set up the fields pertinent to key event.
	 *
	 * We set send_event to the special value of -3, so that TkpGetString
	 * in tkWinKey.c knows that keycode already contains a UNICODE
	 * char and there's no need to do encoding conversion.
................................................................................
	wparam |= MK_SHIFT;
    }
    if (eventPtr->xbutton.state & ControlMask) {
	wparam |= MK_CONTROL;
    }
    lparam = MAKELPARAM((short) eventPtr->xbutton.x,
	    (short) eventPtr->xbutton.y);
    return CallWindowProc(wndproc, hwnd, msg, wparam, lparam);
}
 
/*
 *----------------------------------------------------------------------
 *
 * TkpGetMS --
 *







|







 







|







 







|







 







|







 







|


|







 







|







 







|







|







 







|







782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
...
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
...
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
...
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
....
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
....
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
....
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
....
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
	UpdateInputLanguage((int) wParam);
	result = 1;
	break;

    case WM_IME_COMPOSITION:
	result = 0;
	if (HandleIMEComposition(hwnd, lParam) == 0) {
	    result = DefWindowProcW(hwnd, message, wParam, lParam);
	}
	break;

    case WM_SETCURSOR:
	/*
	 * Short circuit the WM_SETCURSOR message since we set the cursor
	 * elsewhere.
................................................................................
    case WM_CREATE:
    case WM_ERASEBKGND:
	result = 0;
	break;

    case WM_PAINT:
	GenerateXEvent(hwnd, message, wParam, lParam);
	result = DefWindowProcW(hwnd, message, wParam, lParam);
	break;

    case TK_CLAIMFOCUS:
    case TK_GEOMETRYREQ:
    case TK_ATTACHWINDOW:
    case TK_DETACHWINDOW:
    case TK_ICONIFY:
................................................................................
	        result = 1;
	    }
	}
	break;

    default:
	if (!Tk_TranslateWinEvent(hwnd, message, wParam, lParam, &result)) {
	    result = DefWindowProcW(hwnd, message, wParam, lParam);
	}
	break;
    }

    /*
     * Handle any newly queued events before returning control to Windows.
     */
................................................................................
	 * or we will loop.
	 */

	HWND target = (message == WM_NOTIFY)
		? ((NMHDR*)lParam)->hwndFrom : (HWND) lParam;

	if (target && target != hwnd) {
	    *resultPtr = SendMessageW(target, message, wParam, lParam);
	    return 1;
	}
	break;
    }

    case WM_LBUTTONDOWN:
    case WM_LBUTTONDBLCLK:
................................................................................
	    } else {
		event.xkey.nbytes = 1;
		event.xkey.trans_chars[0] = (char) wParam;

		if (IsDBCSLeadByte((BYTE) wParam)) {
		    MSG msg;

		    if ((PeekMessageW(&msg, NULL, WM_CHAR, WM_CHAR,
		            PM_NOREMOVE) != 0)
			    && (msg.message == WM_CHAR)) {
			GetMessageW(&msg, NULL, WM_CHAR, WM_CHAR);
			event.xkey.nbytes = 2;
			event.xkey.trans_chars[1] = (char) msg.wParam;
		   }
		}
	    }
	    Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);
	    event.type = KeyRelease;
................................................................................
 *
 *	This function works around a deficiency in some versions of Windows
 *	2000 to make it possible to entry multi-lingual characters under all
 *	versions of Windows 2000.
 *
 *	When an Input Method Editor (IME) is ready to send input characters to
 *	an application, it sends a WM_IME_COMPOSITION message with the
 *	GCS_RESULTSTR. However, The DefWindowProcW() on English Windows 2000
 *	arbitrarily converts all non-Latin-1 characters in the composition to
 *	"?".
 *
 *	This function correctly processes the composition data and sends the
 *	UNICODE values of the composed characters to TK's event queue.
 *
 * Results:
................................................................................
    }

    hIMC = ImmGetContext(hwnd);
    if (!hIMC) {
	return 0;
    }

    n = ImmGetCompositionStringW(hIMC, GCS_RESULTSTR, NULL, 0);

    if (n > 0) {
	WCHAR *buff = (WCHAR *) ckalloc(n);
	TkWindow *winPtr;
	XEvent event;
	int i;

	n = ImmGetCompositionStringW(hIMC, GCS_RESULTSTR, buff, (unsigned) n) / 2;

	/*
	 * Set up the fields pertinent to key event.
	 *
	 * We set send_event to the special value of -3, so that TkpGetString
	 * in tkWinKey.c knows that keycode already contains a UNICODE
	 * char and there's no need to do encoding conversion.
................................................................................
	wparam |= MK_SHIFT;
    }
    if (eventPtr->xbutton.state & ControlMask) {
	wparam |= MK_CONTROL;
    }
    lparam = MAKELPARAM((short) eventPtr->xbutton.x,
	    (short) eventPtr->xbutton.y);
    return CallWindowProcW(wndproc, hwnd, msg, wparam, lparam);
}
 
/*
 *----------------------------------------------------------------------
 *
 * TkpGetMS --
 *

Changes to jni/sdl2tk/win/ttkWinMonitor.c.

88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
...
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
...
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
    wc.lpszMenuName  = name;
    wc.lpszClassName = name;

    if (RegisterClassExW(&wc)) {
	hwnd = CreateWindowW( name, title, WS_OVERLAPPEDWINDOW,
	    CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
	    NULL, NULL, hinst, NULL );
	SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR) interp);
	ShowWindow(hwnd, SW_HIDE);
	UpdateWindow(hwnd);
    }
    return hwnd;
}

static void
................................................................................
    HWND hwnd = (HWND)clientData;
    DestroyWindow(hwnd);
}
 
static LRESULT WINAPI
WndProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
{
    Tcl_Interp *interp = (Tcl_Interp *)GetWindowLongPtr(hwnd, GWLP_USERDATA);
    Ttk_Theme theme;

    switch (msg) {
    case WM_DESTROY:
	break;

    case WM_SYSCOLORCHANGE:
................................................................................
	theme = Ttk_GetCurrentTheme(interp);
	if (theme) {
	    Ttk_UseTheme(interp, theme);
	    /* @@@ What to do about errors here? */
	}
	break;
    }
    return DefWindowProc(hwnd, msg, wp, lp);
}
 
/*
 * Windows-specific platform initialization:
 */

MODULE_SCOPE int TtkWinTheme_Init(Tcl_Interp *, HWND hwnd);







|







 







|







 







|







88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
...
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
...
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
    wc.lpszMenuName  = name;
    wc.lpszClassName = name;

    if (RegisterClassExW(&wc)) {
	hwnd = CreateWindowW( name, title, WS_OVERLAPPEDWINDOW,
	    CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
	    NULL, NULL, hinst, NULL );
	SetWindowLongPtrW(hwnd, GWLP_USERDATA, (LONG_PTR) interp);
	ShowWindow(hwnd, SW_HIDE);
	UpdateWindow(hwnd);
    }
    return hwnd;
}

static void
................................................................................
    HWND hwnd = (HWND)clientData;
    DestroyWindow(hwnd);
}
 
static LRESULT WINAPI
WndProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
{
    Tcl_Interp *interp = (Tcl_Interp *)GetWindowLongPtrW(hwnd, GWLP_USERDATA);
    Ttk_Theme theme;

    switch (msg) {
    case WM_DESTROY:
	break;

    case WM_SYSCOLORCHANGE:
................................................................................
	theme = Ttk_GetCurrentTheme(interp);
	if (theme) {
	    Ttk_UseTheme(interp, theme);
	    /* @@@ What to do about errors here? */
	}
	break;
    }
    return DefWindowProcW(hwnd, msg, wp, lp);
}
 
/*
 * Windows-specific platform initialization:
 */

MODULE_SCOPE int TtkWinTheme_Init(Tcl_Interp *, HWND hwnd);