Import Tk 8.6.10
This commit is contained in:
165
win/tkWinX.c
165
win/tkWinX.c
@@ -35,6 +35,15 @@
|
||||
|
||||
#include <zmouse.h>
|
||||
|
||||
/*
|
||||
* WM_MOUSEHWHEEL is normally defined by Winuser.h for Vista/2008 or later,
|
||||
* but is also usable on 2000/XP if IntelliPoint drivers are installed.
|
||||
*/
|
||||
|
||||
#ifndef WM_MOUSEHWHEEL
|
||||
#define WM_MOUSEHWHEEL 0x020E
|
||||
#endif
|
||||
|
||||
/*
|
||||
* imm.h is needed by HandleIMEComposition
|
||||
*/
|
||||
@@ -60,7 +69,7 @@
|
||||
static const char winScreenName[] = ":0"; /* Default name of windows display. */
|
||||
static HINSTANCE tkInstance = NULL; /* Application instance handle. */
|
||||
static int childClassInitialized; /* Registered child class? */
|
||||
static WNDCLASS childClass; /* Window class for child windows. */
|
||||
static WNDCLASSW childClass; /* Window class for child windows. */
|
||||
static int tkPlatformId = 0; /* version of Windows platform */
|
||||
static int tkWinTheme = 0; /* See TkWinGetPlatformTheme */
|
||||
static Tcl_Encoding keyInputEncoding = NULL;
|
||||
@@ -77,13 +86,15 @@ static Tcl_Encoding unicodeEncoding = NULL;
|
||||
* specific date for threads.
|
||||
*/
|
||||
|
||||
typedef struct ThreadSpecificData {
|
||||
typedef struct {
|
||||
TkDisplay *winDisplay; /* TkDisplay structure that represents Windows
|
||||
* screen. */
|
||||
int updatingClipboard; /* If 1, we are updating the clipboard. */
|
||||
int surrogateBuffer; /* Buffer for first of surrogate pair. */
|
||||
DWORD wheelTickPrev; /* For high resolution wheels. */
|
||||
short wheelAcc; /* For high resolution wheels. */
|
||||
DWORD vWheelTickPrev; /* For high resolution wheels (vertical). */
|
||||
DWORD hWheelTickPrev; /* For high resolution wheels (horizontal). */
|
||||
short vWheelAcc; /* For high resolution wheels (vertical). */
|
||||
short hWheelAcc; /* For high resolution wheels (horizontal). */
|
||||
} ThreadSpecificData;
|
||||
static Tcl_ThreadDataKey dataKey;
|
||||
|
||||
@@ -127,7 +138,7 @@ TkGetServerInfo(
|
||||
OSVERSIONINFOW os;
|
||||
|
||||
if (!buffer[0]) {
|
||||
HANDLE handle = GetModuleHandle(TEXT("NTDLL"));
|
||||
HANDLE handle = GetModuleHandleW(L"NTDLL");
|
||||
int(__stdcall *getversion)(void *) =
|
||||
(int(__stdcall *)(void *))GetProcAddress(handle, "RtlGetVersion");
|
||||
os.dwOSVersionInfoSize = sizeof(OSVERSIONINFOW);
|
||||
@@ -168,7 +179,7 @@ HINSTANCE
|
||||
Tk_GetHINSTANCE(void)
|
||||
{
|
||||
if (tkInstance == NULL) {
|
||||
tkInstance = GetModuleHandle(NULL);
|
||||
tkInstance = GetModuleHandleW(NULL);
|
||||
}
|
||||
return tkInstance;
|
||||
}
|
||||
@@ -248,7 +259,7 @@ TkWinXInit(
|
||||
childClass.hIcon = NULL;
|
||||
childClass.hCursor = NULL;
|
||||
|
||||
if (!RegisterClass(&childClass)) {
|
||||
if (!RegisterClassW(&childClass)) {
|
||||
Tcl_Panic("Unable to register TkChild class");
|
||||
}
|
||||
|
||||
@@ -256,9 +267,9 @@ TkWinXInit(
|
||||
* Initialize input language info
|
||||
*/
|
||||
|
||||
if (GetLocaleInfo(LANGIDFROMLCID(PTR2INT(GetKeyboardLayout(0))),
|
||||
if (GetLocaleInfoW(LANGIDFROMLCID(PTR2INT(GetKeyboardLayout(0))),
|
||||
LOCALE_IDEFAULTANSICODEPAGE | LOCALE_RETURN_NUMBER,
|
||||
(LPTSTR) &lpCP, sizeof(lpCP)/sizeof(TCHAR))
|
||||
(LPWSTR) &lpCP, sizeof(lpCP)/sizeof(WCHAR))
|
||||
&& TranslateCharsetInfo(INT2PTR(lpCP), &lpCs, TCI_SRCCODEPAGE)) {
|
||||
UpdateInputLanguage((int) lpCs.ciCharset);
|
||||
}
|
||||
@@ -298,7 +309,7 @@ TkWinXCleanup(
|
||||
|
||||
if (childClassInitialized) {
|
||||
childClassInitialized = 0;
|
||||
UnregisterClass(TK_WIN_CHILD_CLASS_NAME, hInstance);
|
||||
UnregisterClassW(TK_WIN_CHILD_CLASS_NAME, hInstance);
|
||||
}
|
||||
|
||||
if (unicodeEncoding != NULL) {
|
||||
@@ -354,17 +365,17 @@ TkWinGetPlatformId(void)
|
||||
if ((os.dwPlatformId == VER_PLATFORM_WIN32_NT) &&
|
||||
(os.dwMajorVersion == 5 && os.dwMinorVersion == 1)) {
|
||||
HKEY hKey;
|
||||
LPCTSTR szSubKey = TEXT("Control Panel\\Appearance");
|
||||
LPCTSTR szCurrent = TEXT("Current");
|
||||
LPCWSTR szSubKey = L"Control Panel\\Appearance";
|
||||
LPCWSTR szCurrent = L"Current";
|
||||
DWORD dwSize = 200;
|
||||
char pBuffer[200];
|
||||
|
||||
memset(pBuffer, 0, dwSize);
|
||||
if (RegOpenKeyEx(HKEY_CURRENT_USER, szSubKey, 0L,
|
||||
if (RegOpenKeyExW(HKEY_CURRENT_USER, szSubKey, 0L,
|
||||
KEY_READ, &hKey) != ERROR_SUCCESS) {
|
||||
tkWinTheme = TK_THEME_WIN_XP;
|
||||
} else {
|
||||
RegQueryValueEx(hKey, szCurrent, NULL, NULL, (LPBYTE) pBuffer, &dwSize);
|
||||
RegQueryValueExW(hKey, szCurrent, NULL, NULL, (LPBYTE) pBuffer, &dwSize);
|
||||
RegCloseKey(hKey);
|
||||
if (strcmp(pBuffer, "Windows Standard") == 0) {
|
||||
tkWinTheme = TK_THEME_WIN_CLASSIC;
|
||||
@@ -490,30 +501,30 @@ TkWinDisplayChanged(
|
||||
screen->root_visual->visualid = 0;
|
||||
if (GetDeviceCaps(dc, RASTERCAPS) & RC_PALETTE) {
|
||||
screen->root_visual->map_entries = GetDeviceCaps(dc, SIZEPALETTE);
|
||||
screen->root_visual->class = PseudoColor;
|
||||
screen->root_visual->c_class = PseudoColor;
|
||||
screen->root_visual->red_mask = 0x0;
|
||||
screen->root_visual->green_mask = 0x0;
|
||||
screen->root_visual->blue_mask = 0x0;
|
||||
} else if (screen->root_depth == 4) {
|
||||
screen->root_visual->class = StaticColor;
|
||||
screen->root_visual->c_class = StaticColor;
|
||||
screen->root_visual->map_entries = 16;
|
||||
} else if (screen->root_depth == 8) {
|
||||
screen->root_visual->class = StaticColor;
|
||||
screen->root_visual->c_class = StaticColor;
|
||||
screen->root_visual->map_entries = 256;
|
||||
} else if (screen->root_depth == 12) {
|
||||
screen->root_visual->class = TrueColor;
|
||||
screen->root_visual->c_class = TrueColor;
|
||||
screen->root_visual->map_entries = 32;
|
||||
screen->root_visual->red_mask = 0xf0;
|
||||
screen->root_visual->green_mask = 0xf000;
|
||||
screen->root_visual->blue_mask = 0xf00000;
|
||||
} else if (screen->root_depth == 16) {
|
||||
screen->root_visual->class = TrueColor;
|
||||
screen->root_visual->c_class = TrueColor;
|
||||
screen->root_visual->map_entries = 64;
|
||||
screen->root_visual->red_mask = 0xf8;
|
||||
screen->root_visual->green_mask = 0xfc00;
|
||||
screen->root_visual->blue_mask = 0xf80000;
|
||||
} else if (screen->root_depth >= 24) {
|
||||
screen->root_visual->class = TrueColor;
|
||||
screen->root_visual->c_class = TrueColor;
|
||||
screen->root_visual->map_entries = 256;
|
||||
screen->root_visual->red_mask = 0xff;
|
||||
screen->root_visual->green_mask = 0xff00;
|
||||
@@ -555,6 +566,7 @@ TkpOpenDisplay(
|
||||
Display *display;
|
||||
ThreadSpecificData *tsdPtr =
|
||||
Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
|
||||
DWORD initialWheelTick;
|
||||
|
||||
if (tsdPtr->winDisplay != NULL) {
|
||||
if (!strcmp(tsdPtr->winDisplay->display->display_name, display_name)) {
|
||||
@@ -585,7 +597,7 @@ TkpOpenDisplay(
|
||||
|
||||
twdPtr = ckalloc(sizeof(TkWinDrawable));
|
||||
if (twdPtr == NULL) {
|
||||
return None;
|
||||
return NULL;
|
||||
}
|
||||
twdPtr->type = TWD_WINDOW;
|
||||
twdPtr->window.winPtr = NULL;
|
||||
@@ -610,8 +622,16 @@ TkpOpenDisplay(
|
||||
ZeroMemory(tsdPtr->winDisplay, sizeof(TkDisplay));
|
||||
tsdPtr->winDisplay->display = display;
|
||||
tsdPtr->updatingClipboard = FALSE;
|
||||
tsdPtr->wheelTickPrev = GetTickCount();
|
||||
tsdPtr->wheelAcc = 0;
|
||||
initialWheelTick = GetTickCount();
|
||||
tsdPtr->vWheelTickPrev = initialWheelTick;
|
||||
tsdPtr->hWheelTickPrev = initialWheelTick;
|
||||
tsdPtr->vWheelAcc = 0;
|
||||
tsdPtr->hWheelAcc = 0;
|
||||
|
||||
/*
|
||||
* Key map info must be available immediately, because of "send event".
|
||||
*/
|
||||
TkpInitKeymapInfo(tsdPtr->winDisplay);
|
||||
|
||||
return tsdPtr->winDisplay;
|
||||
}
|
||||
@@ -760,7 +780,7 @@ TkWinChildProc(
|
||||
case WM_IME_COMPOSITION:
|
||||
result = 0;
|
||||
if (HandleIMEComposition(hwnd, lParam) == 0) {
|
||||
result = DefWindowProc(hwnd, message, wParam, lParam);
|
||||
result = DefWindowProcW(hwnd, message, wParam, lParam);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -780,7 +800,7 @@ TkWinChildProc(
|
||||
|
||||
case WM_PAINT:
|
||||
GenerateXEvent(hwnd, message, wParam, lParam);
|
||||
result = DefWindowProc(hwnd, message, wParam, lParam);
|
||||
result = DefWindowProcW(hwnd, message, wParam, lParam);
|
||||
break;
|
||||
|
||||
case TK_CLAIMFOCUS:
|
||||
@@ -817,7 +837,7 @@ TkWinChildProc(
|
||||
|
||||
default:
|
||||
if (!Tk_TranslateWinEvent(hwnd, message, wParam, lParam, &result)) {
|
||||
result = DefWindowProc(hwnd, message, wParam, lParam);
|
||||
result = DefWindowProcW(hwnd, message, wParam, lParam);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -898,7 +918,7 @@ Tk_TranslateWinEvent(
|
||||
? ((NMHDR*)lParam)->hwndFrom : (HWND) lParam;
|
||||
|
||||
if (target && target != hwnd) {
|
||||
*resultPtr = SendMessage(target, message, wParam, lParam);
|
||||
*resultPtr = SendMessageW(target, message, wParam, lParam);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
@@ -910,9 +930,12 @@ Tk_TranslateWinEvent(
|
||||
case WM_MBUTTONDBLCLK:
|
||||
case WM_RBUTTONDOWN:
|
||||
case WM_RBUTTONDBLCLK:
|
||||
case WM_XBUTTONDOWN:
|
||||
case WM_XBUTTONDBLCLK:
|
||||
case WM_LBUTTONUP:
|
||||
case WM_MBUTTONUP:
|
||||
case WM_RBUTTONUP:
|
||||
case WM_XBUTTONUP:
|
||||
case WM_MOUSEMOVE:
|
||||
Tk_PointerEvent(hwnd, (short) LOWORD(lParam), (short) HIWORD(lParam));
|
||||
return 1;
|
||||
@@ -937,6 +960,7 @@ Tk_TranslateWinEvent(
|
||||
case WM_SYSKEYUP:
|
||||
case WM_KEYUP:
|
||||
case WM_MOUSEWHEEL:
|
||||
case WM_MOUSEHWHEEL:
|
||||
GenerateXEvent(hwnd, message, wParam, lParam);
|
||||
return 1;
|
||||
case WM_MENUCHAR:
|
||||
@@ -981,7 +1005,7 @@ GenerateXEvent(
|
||||
ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
|
||||
Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
|
||||
|
||||
if (message == WM_MOUSEWHEEL) {
|
||||
if ((message == WM_MOUSEWHEEL) || (message == WM_MOUSEHWHEEL)) {
|
||||
union {LPARAM lParam; POINTS point;} root;
|
||||
POINT pos;
|
||||
root.lParam = lParam;
|
||||
@@ -1096,6 +1120,7 @@ GenerateXEvent(
|
||||
break;
|
||||
|
||||
case WM_MOUSEWHEEL:
|
||||
case WM_MOUSEHWHEEL:
|
||||
case WM_CHAR:
|
||||
case WM_UNICHAR:
|
||||
case WM_SYSKEYDOWN:
|
||||
@@ -1137,18 +1162,18 @@ GenerateXEvent(
|
||||
switch (message) {
|
||||
case WM_MOUSEWHEEL: {
|
||||
/*
|
||||
* Support for high resolution wheels.
|
||||
* Support for high resolution wheels (vertical).
|
||||
*/
|
||||
|
||||
DWORD wheelTick = GetTickCount();
|
||||
|
||||
if (wheelTick - tsdPtr->wheelTickPrev < 1500) {
|
||||
tsdPtr->wheelAcc += (short) HIWORD(wParam);
|
||||
if (wheelTick - tsdPtr->vWheelTickPrev < 1500) {
|
||||
tsdPtr->vWheelAcc += (short) HIWORD(wParam);
|
||||
} else {
|
||||
tsdPtr->wheelAcc = (short) HIWORD(wParam);
|
||||
tsdPtr->vWheelAcc = (short) HIWORD(wParam);
|
||||
}
|
||||
tsdPtr->wheelTickPrev = wheelTick;
|
||||
if (abs(tsdPtr->wheelAcc) < WHEEL_DELTA) {
|
||||
tsdPtr->vWheelTickPrev = wheelTick;
|
||||
if (abs(tsdPtr->vWheelAcc) < WHEEL_DELTA) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1163,8 +1188,41 @@ GenerateXEvent(
|
||||
event.type = MouseWheelEvent;
|
||||
event.xany.send_event = -1;
|
||||
event.xkey.nbytes = 0;
|
||||
event.xkey.keycode = tsdPtr->wheelAcc / WHEEL_DELTA * WHEEL_DELTA;
|
||||
tsdPtr->wheelAcc = tsdPtr->wheelAcc % WHEEL_DELTA;
|
||||
event.xkey.keycode = tsdPtr->vWheelAcc / WHEEL_DELTA * WHEEL_DELTA;
|
||||
tsdPtr->vWheelAcc = tsdPtr->vWheelAcc % WHEEL_DELTA;
|
||||
break;
|
||||
}
|
||||
case WM_MOUSEHWHEEL: {
|
||||
/*
|
||||
* Support for high resolution wheels (horizontal).
|
||||
*/
|
||||
|
||||
DWORD wheelTick = GetTickCount();
|
||||
|
||||
if (wheelTick - tsdPtr->hWheelTickPrev < 1500) {
|
||||
tsdPtr->hWheelAcc -= (short) HIWORD(wParam);
|
||||
} else {
|
||||
tsdPtr->hWheelAcc = -((short) HIWORD(wParam));
|
||||
}
|
||||
tsdPtr->hWheelTickPrev = wheelTick;
|
||||
if (abs(tsdPtr->hWheelAcc) < WHEEL_DELTA) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* We have invented a new X event type to handle this event. It
|
||||
* still uses the KeyPress struct. However, the keycode field has
|
||||
* been overloaded to hold the zDelta of the wheel. Set nbytes to
|
||||
* 0 to prevent conversion of the keycode to a keysym in
|
||||
* TkpGetString. [Bug 1118340].
|
||||
*/
|
||||
|
||||
event.type = MouseWheelEvent;
|
||||
event.xany.send_event = -1;
|
||||
event.xkey.nbytes = 0;
|
||||
event.xkey.state |= ShiftMask;
|
||||
event.xkey.keycode = tsdPtr->hWheelAcc / WHEEL_DELTA * WHEEL_DELTA;
|
||||
tsdPtr->hWheelAcc = tsdPtr->hWheelAcc % WHEEL_DELTA;
|
||||
break;
|
||||
}
|
||||
case WM_SYSKEYDOWN:
|
||||
@@ -1253,10 +1311,10 @@ GenerateXEvent(
|
||||
if (IsDBCSLeadByte((BYTE) wParam)) {
|
||||
MSG msg;
|
||||
|
||||
if ((PeekMessage(&msg, NULL, WM_CHAR, WM_CHAR,
|
||||
if ((PeekMessageW(&msg, NULL, WM_CHAR, WM_CHAR,
|
||||
PM_NOREMOVE) != 0)
|
||||
&& (msg.message == WM_CHAR)) {
|
||||
GetMessage(&msg, NULL, WM_CHAR, WM_CHAR);
|
||||
GetMessageW(&msg, NULL, WM_CHAR, WM_CHAR);
|
||||
event.xkey.nbytes = 2;
|
||||
event.xkey.trans_chars[1] = (char) msg.wParam;
|
||||
}
|
||||
@@ -1478,7 +1536,7 @@ UpdateInputLanguage(
|
||||
return;
|
||||
}
|
||||
|
||||
wsprintfA(codepage, "cp%d", charsetInfo.ciACP);
|
||||
sprintf(codepage, "cp%d", charsetInfo.ciACP);
|
||||
|
||||
if ((encoding = Tcl_GetEncoding(NULL, codepage)) == NULL) {
|
||||
/*
|
||||
@@ -1539,7 +1597,10 @@ Tcl_Encoding
|
||||
TkWinGetUnicodeEncoding(void)
|
||||
{
|
||||
if (unicodeEncoding == NULL) {
|
||||
unicodeEncoding = Tcl_GetEncoding(NULL, "unicode");
|
||||
unicodeEncoding = Tcl_GetEncoding(NULL, "utf-16");
|
||||
if (unicodeEncoding == NULL) {
|
||||
unicodeEncoding = Tcl_GetEncoding(NULL, "unicode");
|
||||
}
|
||||
}
|
||||
return unicodeEncoding;
|
||||
}
|
||||
@@ -1555,7 +1616,7 @@ TkWinGetUnicodeEncoding(void)
|
||||
*
|
||||
* 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
|
||||
* GCS_RESULTSTR. However, The DefWindowProcW() on English Windows 2000
|
||||
* arbitrarily converts all non-Latin-1 characters in the composition to
|
||||
* "?".
|
||||
*
|
||||
@@ -1594,7 +1655,7 @@ HandleIMEComposition(
|
||||
return 0;
|
||||
}
|
||||
|
||||
n = ImmGetCompositionString(hIMC, GCS_RESULTSTR, NULL, 0);
|
||||
n = ImmGetCompositionStringW(hIMC, GCS_RESULTSTR, NULL, 0);
|
||||
|
||||
if (n > 0) {
|
||||
WCHAR *buff = (WCHAR *) ckalloc(n);
|
||||
@@ -1602,7 +1663,7 @@ HandleIMEComposition(
|
||||
XEvent event;
|
||||
int i;
|
||||
|
||||
n = ImmGetCompositionString(hIMC, GCS_RESULTSTR, buff, (unsigned) n) / 2;
|
||||
n = ImmGetCompositionStringW(hIMC, GCS_RESULTSTR, buff, (unsigned) n) / 2;
|
||||
|
||||
/*
|
||||
* Set up the fields pertinent to key event.
|
||||
@@ -1687,7 +1748,7 @@ Tk_FreeXId(
|
||||
* TkWinResendEvent --
|
||||
*
|
||||
* This function converts an X event into a Windows event and invokes the
|
||||
* specified windo function.
|
||||
* specified window function.
|
||||
*
|
||||
* Results:
|
||||
* A standard Windows result.
|
||||
@@ -1725,6 +1786,14 @@ TkWinResendEvent(
|
||||
msg = WM_RBUTTONDOWN;
|
||||
wparam = MK_RBUTTON;
|
||||
break;
|
||||
case Button4:
|
||||
msg = WM_XBUTTONDOWN;
|
||||
wparam = MAKEWPARAM(MK_XBUTTON1, XBUTTON1);
|
||||
break;
|
||||
case Button5:
|
||||
msg = WM_XBUTTONDOWN;
|
||||
wparam = MAKEWPARAM(MK_XBUTTON2, XBUTTON2);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@@ -1738,6 +1807,12 @@ TkWinResendEvent(
|
||||
if (eventPtr->xbutton.state & Button3Mask) {
|
||||
wparam |= MK_RBUTTON;
|
||||
}
|
||||
if (eventPtr->xbutton.state & Button4Mask) {
|
||||
wparam |= MK_XBUTTON1;
|
||||
}
|
||||
if (eventPtr->xbutton.state & Button5Mask) {
|
||||
wparam |= MK_XBUTTON2;
|
||||
}
|
||||
if (eventPtr->xbutton.state & ShiftMask) {
|
||||
wparam |= MK_SHIFT;
|
||||
}
|
||||
@@ -1746,7 +1821,7 @@ TkWinResendEvent(
|
||||
}
|
||||
lparam = MAKELPARAM((short) eventPtr->xbutton.x,
|
||||
(short) eventPtr->xbutton.y);
|
||||
return CallWindowProc(wndproc, hwnd, msg, wparam, lparam);
|
||||
return CallWindowProcW(wndproc, hwnd, msg, wparam, lparam);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user