diff options
Diffstat (limited to 'win/tkWinX.c')
-rw-r--r-- | win/tkWinX.c | 358 |
1 files changed, 161 insertions, 197 deletions
diff --git a/win/tkWinX.c b/win/tkWinX.c index ad0c4d2..f86b360 100644 --- a/win/tkWinX.c +++ b/win/tkWinX.c @@ -3,9 +3,9 @@ * * This file contains Windows emulation procedures for X routines. * - * Copyright (c) 1995-1996 Sun Microsystems, Inc. - * Copyright (c) 1994 Software Research Associates, Inc. - * Copyright (c) 1998-2000 Scriptics Corporation. + * Copyright © 1995-1996 Sun Microsystems, Inc. + * Copyright © 1994 Software Research Associates, Inc. + * Copyright © 1998-2000 Scriptics Corporation. * * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. @@ -14,22 +14,13 @@ #define XLIB_ILLEGAL_ACCESS #include "tkWinInt.h" -/* - * The w32api 1.1 package (included in Mingw 1.1) does not define _WIN32_IE by - * default. Define it here to gain access to the InitCommonControlsEx API in - * commctrl.h. - */ - -#ifndef _WIN32_IE -#define _WIN32_IE 0x0550 /* IE 5.5 */ -#endif - #include <commctrl.h> #ifdef _MSC_VER # pragma comment (lib, "comctl32.lib") # pragma comment (lib, "advapi32.lib") #endif + /* * The zmouse.h file includes the definition for WM_MOUSEWHEEL. */ @@ -45,6 +36,31 @@ #define WM_MOUSEHWHEEL 0x020E #endif +/* A WM_MOUSEWHEEL message sent by a trackpad contains the number of pixels as + * the delta value, while low precision scrollwheels always send an integer + * multiple of WHEELDELTA (= 120) as the delta value. + */ + +#define WHEELDELTA 120 + +/* + * Our heuristic for deciding whether a WM_MOUSEWHEEL message + * comes from a high resolution scrolling device is that we + * assume it is high resolution unless there are two consecutive + * delta values that are both multiples of 120. This is static, + * rather than thread-specific, since input devices are shared + * by all threads. + */ + +static int lastMod = 0; + +/* + * The serial field of TouchpadScroll events is a counter for + * events of this type only. + */ + +static unsigned long scrollCounter = 0; + /* * imm.h is needed by HandleIMEComposition */ @@ -91,10 +107,6 @@ typedef struct { * screen. */ int updatingClipboard; /* If 1, we are updating the clipboard. */ int surrogateBuffer; /* Buffer for first of surrogate pair. */ - 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; @@ -138,13 +150,7 @@ TkGetServerInfo( OSVERSIONINFOW os; if (!buffer[0]) { - HANDLE handle = GetModuleHandleW(L"NTDLL"); - int(__stdcall *getversion)(void *) = (int(__stdcall *)(void *)) - (void *)GetProcAddress(handle, "RtlGetVersion"); - os.dwOSVersionInfoSize = sizeof(OSVERSIONINFOW); - if (!getversion || getversion(&os)) { - GetVersionExW(&os); - } + GetVersionExW(&os); /* Write the first character last, preventing multi-thread issues. */ snprintf(buffer+1, sizeof(buffer)-1, "indows %d.%d %d %s", (int)os.dwMajorVersion, (int)os.dwMinorVersion, (int)os.dwBuildNumber, @@ -299,7 +305,7 @@ TkWinXInit( void TkWinXCleanup( - ClientData clientData) + void *clientData) { HINSTANCE hInstance = (HINSTANCE)clientData; @@ -391,30 +397,6 @@ TkWinGetPlatformTheme(void) /* *---------------------------------------------------------------------- * - * TkWinGetPlatformId -- - * - * Determines whether running under NT, 95, or Win32s, to allow runtime - * conditional code. Win32s is no longer supported. - * - * Results: - * The return value is always: - * VER_PLATFORM_WIN32_NT Win32 on Windows XP, Vista, Windows 7, Windows 8 - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -int -TkWinGetPlatformId(void) -{ - return VER_PLATFORM_WIN32_NT; -} - -/* - *---------------------------------------------------------------------- - * * TkGetDefaultScreenName -- * * Returns the name of the screen that Tk should use during @@ -464,10 +446,10 @@ TkWinDisplayChanged( HDC dc; Screen *screen; - if (display == NULL || ScreenOfDisplay(display, 0) == NULL) { + if (display == NULL || (((_XPrivDisplay)(display))->screens) == NULL) { return; } - screen = ScreenOfDisplay(display, 0); + screen = (((_XPrivDisplay)(display))->screens); dc = GetDC(NULL); WidthOfScreen(screen) = GetDeviceCaps(dc, HORZRES); @@ -487,13 +469,13 @@ TkWinDisplayChanged( */ screen->ext_data = (XExtData *)INT2PTR(GetDeviceCaps(dc, PLANES)); - DefaultDepthOfScreen(screen) = GetDeviceCaps(dc, BITSPIXEL) * PTR2INT(screen->ext_data); + screen->root_depth = GetDeviceCaps(dc, BITSPIXEL) * PTR2INT(screen->ext_data); - if (DefaultVisualOfScreen(screen) != NULL) { - ckfree(DefaultVisualOfScreen(screen)); + if (screen->root_visual != NULL) { + ckfree(screen->root_visual); } - DefaultVisualOfScreen(screen) = (Visual *)ckalloc(sizeof(Visual)); - DefaultVisualOfScreen(screen)->visualid = 0; + screen->root_visual = (Visual *)ckalloc(sizeof(Visual)); + screen->root_visual->visualid = 0; if (GetDeviceCaps(dc, RASTERCAPS) & RC_PALETTE) { DefaultVisualOfScreen(screen)->map_entries = GetDeviceCaps(dc, SIZEPALETTE); DefaultVisualOfScreen(screen)->c_class = PseudoColor; @@ -538,7 +520,7 @@ TkWinDisplayChanged( /* *---------------------------------------------------------------------- * - * TkpOpenDisplay -- + * TkpOpenDisplay/XkbOpenDisplay -- * * Create the Display structure and fill it with device specific * information. @@ -557,46 +539,53 @@ TkpOpenDisplay( const char *display_name) { Display *display; - Screen *screen; - TkWinDrawable *twdPtr; ThreadSpecificData *tsdPtr = (ThreadSpecificData *) Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - DWORD initialWheelTick; if (tsdPtr->winDisplay != NULL) { - if (!strcmp(tsdPtr->winDisplay->display->display_name, display_name)) { + if (!strcmp(DisplayString(tsdPtr->winDisplay->display), display_name)) { return tsdPtr->winDisplay; } else { return NULL; } } - display = ckalloc(sizeof(Display)); - memset(display, 0, sizeof(Display)); - - display->display_name = ckalloc(strlen(display_name) + 1); - strcpy(display->display_name, display_name); + display = XkbOpenDisplay(display_name, NULL, NULL, NULL, NULL, NULL); + TkWinDisplayChanged(display); - display->nscreens = 1; - LastKnownRequestProcessed(display) = 1; - display->qlen = 0; + tsdPtr->winDisplay =(TkDisplay *) ckalloc(sizeof(TkDisplay)); + memset(tsdPtr->winDisplay, 0, sizeof(TkDisplay)); + tsdPtr->winDisplay->display = display; + tsdPtr->updatingClipboard = FALSE; - screen = ckalloc(sizeof(Screen)); - memset(screen, 0, sizeof(Screen)); - DisplayOfScreen(screen) = display; + /* + * Key map info must be available immediately, because of "send event". + */ + TkpInitKeymapInfo(tsdPtr->winDisplay); /* - * Set up the root window. + * Key map info must be available immediately, because of "send event". */ + TkpInitKeymapInfo(tsdPtr->winDisplay); - twdPtr = ckalloc(sizeof(TkWinDrawable)); - if (twdPtr == NULL) { - return NULL; - } - twdPtr->type = TWD_WINDOW; - twdPtr->window.winPtr = NULL; - twdPtr->window.handle = NULL; - RootWindowOfScreen(screen) = (Window)twdPtr; + return tsdPtr->winDisplay; +} + +Display * +XkbOpenDisplay( + const char *name, + int *ev_rtrn, + int *err_rtrn, + int *major_rtrn, + int *minor_rtrn, + int *reason) +{ + _XPrivDisplay display = (_XPrivDisplay)ckalloc(sizeof(Display)); + Screen *screen = (Screen *)ckalloc(sizeof(Screen)); + TkWinDrawable *twdPtr = (TkWinDrawable *)ckalloc(sizeof(TkWinDrawable)); + + memset(screen, 0, sizeof(Screen)); + memset(display, 0, sizeof(Display)); /* * Note that these pixel values are not palette relative. @@ -610,24 +599,26 @@ TkpOpenDisplay( display->nscreens = 1; display->default_screen = 0; - TkWinDisplayChanged(display); + twdPtr->type = TWD_WINDOW; + twdPtr->window.winPtr = NULL; + twdPtr->window.handle = NULL; + screen->root = (Window)twdPtr; + screen->display = (Display *)display; - tsdPtr->winDisplay = ckalloc(sizeof(TkDisplay)); - memset(tsdPtr->winDisplay, 0, sizeof(TkDisplay)); - tsdPtr->winDisplay->display = display; - tsdPtr->updatingClipboard = FALSE; - initialWheelTick = GetTickCount(); - tsdPtr->vWheelTickPrev = initialWheelTick; - tsdPtr->hWheelTickPrev = initialWheelTick; - tsdPtr->vWheelAcc = 0; - tsdPtr->hWheelAcc = 0; + display->display_name = (char *)ckalloc(strlen(name) + 1); + strcpy(display->display_name, name); - /* - * Key map info must be available immediately, because of "send event". - */ - TkpInitKeymapInfo(tsdPtr->winDisplay); + display->nscreens = 1; + display->request = 1; + display->qlen = 0; - return tsdPtr->winDisplay; + if (ev_rtrn) *ev_rtrn = 0; + if (err_rtrn) *err_rtrn = 0; + if (major_rtrn) *major_rtrn = 0; + if (minor_rtrn) *minor_rtrn = 0; + if (reason) *reason = 0; + + return (Display *)display; } /* @@ -651,7 +642,7 @@ void TkpCloseDisplay( TkDisplay *dispPtr) { - Display *display = dispPtr->display; + _XPrivDisplay display = (_XPrivDisplay)dispPtr->display; ThreadSpecificData *tsdPtr = (ThreadSpecificData *) Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); @@ -670,7 +661,7 @@ TkpCloseDisplay( ckfree(DefaultVisualOfScreen(ScreenOfDisplay(display, 0))); } if (RootWindowOfScreen(ScreenOfDisplay(display, 0)) != None) { - ckfree(RootWindowOfScreen(ScreenOfDisplay(display, 0))); + ckfree((char *)RootWindowOfScreen(ScreenOfDisplay(display, 0))); } if (DefaultColormapOfScreen(ScreenOfDisplay(display, 0)) != None) { XFreeColormap(display, DefaultColormapOfScreen(ScreenOfDisplay(display, 0))); @@ -815,22 +806,22 @@ TkWinChildProc( break; case WM_UNICHAR: - if (wParam == UNICODE_NOCHAR) { + if (wParam == UNICODE_NOCHAR) { /* If wParam is UNICODE_NOCHAR and the application processes * this message, then return TRUE. */ result = 1; } else { /* If the event was translated, we must return 0 */ - if (Tk_TranslateWinEvent(hwnd, message, wParam, lParam, &result)) { - result = 0; + if (TkTranslateWinEvent(hwnd, message, wParam, lParam, &result)) { + result = 0; } else { - result = 1; + result = 1; } } break; default: - if (!Tk_TranslateWinEvent(hwnd, message, wParam, lParam, &result)) { + if (!TkTranslateWinEvent(hwnd, message, wParam, lParam, &result)) { result = DefWindowProcW(hwnd, message, wParam, lParam); } break; @@ -847,7 +838,7 @@ TkWinChildProc( /* *---------------------------------------------------------------------- * - * Tk_TranslateWinEvent -- + * TkTranslateWinEvent -- * * This function is called by widget window functions to handle the * translation from Win32 events to Tk events. @@ -862,7 +853,7 @@ TkWinChildProc( */ int -Tk_TranslateWinEvent( +TkTranslateWinEvent( HWND hwnd, UINT message, WPARAM wParam, @@ -881,20 +872,20 @@ Tk_TranslateWinEvent( } case WM_RENDERALLFORMATS: { - TkWindow *winPtr = (TkWindow *) Tk_HWNDToWindow(hwnd); - - if (winPtr && OpenClipboard(hwnd)) { - /* - * Make sure that nobody had taken ownership of the clipboard - * before we opened it. - */ - - if (GetClipboardOwner() == hwnd) { - TkWinClipboardRender(winPtr->dispPtr, CF_TEXT); - } - CloseClipboard(); - } - return 1; + TkWindow *winPtr = (TkWindow *) Tk_HWNDToWindow(hwnd); + + if (winPtr && OpenClipboard(hwnd)) { + /* + * Make sure that nobody had taken ownership of the clipboard + * before we opened it. + */ + + if (GetClipboardOwner() == hwnd) { + TkWinClipboardRender(winPtr->dispPtr, CF_TEXT); + } + CloseClipboard(); + } + return 1; } case WM_COMMAND: @@ -931,7 +922,7 @@ Tk_TranslateWinEvent( case WM_RBUTTONUP: case WM_XBUTTONUP: case WM_MOUSEMOVE: - Tk_PointerEvent(hwnd, (short) LOWORD(lParam), (short) HIWORD(lParam)); + TkWinPointerEvent(hwnd, (short) LOWORD(lParam), (short) HIWORD(lParam)); return 1; case WM_SYSKEYDOWN: @@ -1155,68 +1146,65 @@ GenerateXEvent( switch (message) { case WM_MOUSEWHEEL: { - /* - * Support for high resolution wheels (vertical). - */ - - DWORD wheelTick = GetTickCount(); - - if (wheelTick - tsdPtr->vWheelTickPrev < 1500) { - tsdPtr->vWheelAcc += (short) HIWORD(wParam); - } else { - tsdPtr->vWheelAcc = (short) HIWORD(wParam); - } - tsdPtr->vWheelTickPrev = wheelTick; - if (abs(tsdPtr->vWheelAcc) < 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 + * Send an Xevent using a KeyPress struct, but with the type field + * set to MouseWheelEvent for low resolution scrolls and to + * TouchpadScroll for high resolution scroll events. The Y delta + * is stored in the low order 16 bits of the keycode field. Set + * nbytes to 0 to prevent conversion of the keycode to a keysym in * TkpGetString. [Bug 1118340]. */ - event.x.type = MouseWheelEvent; - event.x.xany.send_event = -1; - event.key.nbytes = 0; - event.x.xkey.keycode = tsdPtr->vWheelAcc / WHEEL_DELTA * WHEEL_DELTA; - tsdPtr->vWheelAcc = tsdPtr->vWheelAcc % WHEEL_DELTA; + int delta = (short) HIWORD(wParam); + int mod = delta % WHEELDELTA; + if ( mod != 0 || lastMod != 0) { + /* High resolution. */ + event.x.type = TouchpadScroll; + event.x.xany.send_event = -1; + event.key.nbytes = 0; + event.x.xkey.state = state; + event.x.xany.serial = scrollCounter++; + event.x.xkey.keycode = (unsigned int) (delta & 0xffff); + } else { + event.x.type = MouseWheelEvent; + event.x.xany.send_event = -1; + event.key.nbytes = 0; + event.x.xkey.keycode = (unsigned int) delta; + } + lastMod = mod; break; } case WM_MOUSEHWHEEL: { + /* - * Support for high resolution wheels (horizontal). + * Send an Xevent using a KeyPress struct, but with the type field + * set to MouseWheelEvent for low resolution scrolls and to + * TouchpadScroll for high resolution scroll events. For low + * resolution scrolls the X delta is stored in the keycode field + * and For high resolution scrolls the X delta is in the high word + * of the keycode. Set nbytes to 0 to prevent conversion of the + * keycode to a keysym in TkpGetString. [Bug 1118340]. */ - DWORD wheelTick = GetTickCount(); - - if (wheelTick - tsdPtr->hWheelTickPrev < 1500) { - tsdPtr->hWheelAcc -= (short) HIWORD(wParam); + int delta = (short) HIWORD(wParam); + int mod = delta % WHEELDELTA; + if ( mod != 0 || lastMod != 0) { + /* High resolution. */ + event.x.type = TouchpadScroll; + event.x.xany.send_event = -1; + event.key.nbytes = 0; + event.x.xkey.state = state; + event.x.xany.serial = scrollCounter++; + event.x.xkey.keycode = (unsigned int)(-(delta << 16)); } else { - tsdPtr->hWheelAcc = -((short) HIWORD(wParam)); - } - tsdPtr->hWheelTickPrev = wheelTick; - if (abs(tsdPtr->hWheelAcc) < WHEEL_DELTA) { - return; + event.x.type = MouseWheelEvent; + event.x.xany.send_event = -1; + event.key.nbytes = 0; + event.x.xkey.state |= ShiftMask; + event.x.xkey.keycode = delta; } - - /* - * 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.x.type = MouseWheelEvent; - event.x.xany.send_event = -1; - event.key.nbytes = 0; - event.x.xkey.state |= ShiftMask; - event.x.xkey.keycode = tsdPtr->hWheelAcc / WHEEL_DELTA * WHEEL_DELTA; - tsdPtr->hWheelAcc = tsdPtr->hWheelAcc % WHEEL_DELTA; + lastMod = mod; break; } case WM_SYSKEYDOWN: @@ -1233,7 +1221,7 @@ GenerateXEvent( event.x.xany.send_event = -1; event.x.xkey.keycode = wParam; GetTranslatedKey(&event.key, (message == WM_KEYDOWN) ? WM_CHAR : - WM_SYSCHAR); + WM_SYSCHAR); break; case WM_SYSKEYUP: @@ -1306,7 +1294,7 @@ GenerateXEvent( MSG msg; if ((PeekMessageW(&msg, NULL, WM_CHAR, WM_CHAR, - PM_NOREMOVE) != 0) + PM_NOREMOVE) != 0) && (msg.message == WM_CHAR)) { GetMessageW(&msg, NULL, WM_CHAR, WM_CHAR); event.key.nbytes = 2; @@ -1718,30 +1706,6 @@ HandleIMEComposition( /* *---------------------------------------------------------------------- * - * Tk_FreeXId -- - * - * This interface is not needed under Windows. - * - * Results: - * None. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -void -Tk_FreeXId( - Display *display, - XID xid) -{ - /* Do nothing */ -} - -/* - *---------------------------------------------------------------------- - * * TkWinResendEvent -- * * This function converts an X event into a Windows event and invokes the @@ -1783,11 +1747,11 @@ TkWinResendEvent( msg = WM_RBUTTONDOWN; wparam = MK_RBUTTON; break; - case Button4: + case Button8: msg = WM_XBUTTONDOWN; wparam = MAKEWPARAM(MK_XBUTTON1, XBUTTON1); break; - case Button5: + case Button9: msg = WM_XBUTTONDOWN; wparam = MAKEWPARAM(MK_XBUTTON2, XBUTTON2); break; |