Hi-fi mouse input on Windows!
The remains of a RawInput mouse attempt are included, but disabled. RawInput will still be used for multi-axis devices. Eliminated the need for several #defines by requiring WinXP or newer.
This commit is contained in:
parent
5b1925afba
commit
7aa8ae3781
|
@ -37,6 +37,8 @@
|
|||
#include "GHOST_SystemWin32.h"
|
||||
#include "GHOST_EventDragnDrop.h"
|
||||
|
||||
#include <stdio.h> // for debug [mce]
|
||||
|
||||
// win64 doesn't define GWL_USERDATA
|
||||
#ifdef WIN32
|
||||
#ifndef GWL_USERDATA
|
||||
|
@ -49,31 +51,16 @@
|
|||
* According to the docs the mouse wheel message is supported from windows 98
|
||||
* upwards. Leaving WINVER at default value, the WM_MOUSEWHEEL message and the
|
||||
* wheel detent value are undefined.
|
||||
*/
|
||||
|
||||
[mce] able to remove this too?
|
||||
|
||||
#ifndef WM_MOUSEWHEEL
|
||||
#define WM_MOUSEWHEEL 0x020A
|
||||
#endif // WM_MOUSEWHEEL
|
||||
#ifndef WHEEL_DELTA
|
||||
#define WHEEL_DELTA 120 /* Value for rolling one detent, (old convention! MS changed it) */
|
||||
#define WHEEL_DELTA 120 // Value for rolling one detent, (old convention! MS changed it)
|
||||
#endif // WHEEL_DELTA
|
||||
|
||||
/*
|
||||
* Defines for mouse buttons 4 and 5 aka xbutton1 and xbutton2.
|
||||
* MSDN: Declared in Winuser.h, include Windows.h
|
||||
* This does not seem to work with MinGW so we define our own here.
|
||||
*/
|
||||
#ifndef XBUTTON1
|
||||
#define XBUTTON1 0x0001
|
||||
#endif // XBUTTON1
|
||||
#ifndef XBUTTON2
|
||||
#define XBUTTON2 0x0002
|
||||
#endif // XBUTTON2
|
||||
#ifndef WM_XBUTTONUP
|
||||
#define WM_XBUTTONUP 524
|
||||
#endif // WM_XBUTTONUP
|
||||
#ifndef WM_XBUTTONDOWN
|
||||
#define WM_XBUTTONDOWN 523
|
||||
#endif // WM_XBUTTONDOWN
|
||||
|
||||
#include "GHOST_Debug.h"
|
||||
#include "GHOST_DisplayManagerWin32.h"
|
||||
|
@ -135,9 +122,31 @@ GHOST_SystemWin32::GHOST_SystemWin32()
|
|||
m_displayManager = new GHOST_DisplayManagerWin32 ();
|
||||
GHOST_ASSERT(m_displayManager, "GHOST_SystemWin32::GHOST_SystemWin32(): m_displayManager==0\n");
|
||||
m_displayManager->initialize();
|
||||
|
||||
|
||||
// Require COM for GHOST_DropTargetWin32 created in GHOST_WindowWin32.
|
||||
OleInitialize(0);
|
||||
|
||||
m_input_fidelity_hint = HI_FI; // just for testing...
|
||||
|
||||
/*
|
||||
// register for RawInput devices
|
||||
RAWINPUTDEVICE devices[2];
|
||||
|
||||
// standard HID mouse
|
||||
devices[0].usUsagePage = 0x01;
|
||||
devices[0].usUsage = 0x02;
|
||||
devices[0].dwFlags = 0; // RIDEV_NOLEGACY; // ignore legacy mouse messages
|
||||
devices[0].hwndTarget = NULL;
|
||||
|
||||
// multi-axis mouse (SpaceNavigator)
|
||||
devices[1].usUsagePage = 0x01;
|
||||
devices[1].usUsage = 0x08;
|
||||
devices[1].dwFlags = 0;
|
||||
devices[1].hwndTarget = NULL;
|
||||
|
||||
if (RegisterRawInputDevices(devices, 2, sizeof(RAWINPUTDEVICE)))
|
||||
puts("registered for raw mouse and multi-axis input");
|
||||
*/
|
||||
}
|
||||
|
||||
GHOST_SystemWin32::~GHOST_SystemWin32()
|
||||
|
@ -513,13 +522,15 @@ GHOST_EventButton* GHOST_SystemWin32::processButtonEvent(GHOST_TEventType type,
|
|||
}
|
||||
|
||||
|
||||
GHOST_EventCursor* GHOST_SystemWin32::processCursorEvent(GHOST_TEventType type, GHOST_IWindow *Iwindow)
|
||||
GHOST_EventCursor* GHOST_SystemWin32::processCursorEvent(GHOST_TEventType type, GHOST_IWindow *Iwindow, int x, int y)
|
||||
{
|
||||
GHOST_TInt32 x_screen, y_screen;
|
||||
GHOST_SystemWin32 * system = ((GHOST_SystemWin32 * ) getSystem());
|
||||
GHOST_WindowWin32 * window = ( GHOST_WindowWin32 * ) Iwindow;
|
||||
|
||||
system->getCursorPosition(x_screen, y_screen);
|
||||
// system->getCursorPosition(x_screen, y_screen);
|
||||
x_screen = x;
|
||||
y_screen = y;
|
||||
|
||||
if(window->getCursorGrabMode() != GHOST_kGrabDisable && window->getCursorGrabMode() != GHOST_kGrabNormal)
|
||||
{
|
||||
|
@ -546,7 +557,7 @@ GHOST_EventCursor* GHOST_SystemWin32::processCursorEvent(GHOST_TEventType type,
|
|||
window->setCursorGrabAccum(x_accum + (x_screen - x_new), y_accum + (y_screen - y_new));
|
||||
}else{
|
||||
return new GHOST_EventCursor(system->getMilliSeconds(),
|
||||
GHOST_kEventCursorMove,
|
||||
type,
|
||||
window,
|
||||
x_screen + x_accum,
|
||||
y_screen + y_accum
|
||||
|
@ -556,7 +567,7 @@ GHOST_EventCursor* GHOST_SystemWin32::processCursorEvent(GHOST_TEventType type,
|
|||
}
|
||||
else {
|
||||
return new GHOST_EventCursor(system->getMilliSeconds(),
|
||||
GHOST_kEventCursorMove,
|
||||
type,
|
||||
window,
|
||||
x_screen,
|
||||
y_screen
|
||||
|
@ -628,23 +639,199 @@ void GHOST_SystemWin32::processMinMaxInfo(MINMAXINFO * minmax)
|
|||
minmax->ptMinTrackSize.y=240;
|
||||
}
|
||||
|
||||
bool GHOST_SystemWin32::processRawInput(RAWINPUT const& raw, GHOST_WindowWin32* window, int& x, int& y)
|
||||
{
|
||||
GHOST_IEvent* event = NULL;
|
||||
bool eventSent = false;
|
||||
|
||||
puts("BEGIN");
|
||||
|
||||
if (raw.header.dwType == RIM_TYPEMOUSE)
|
||||
{
|
||||
USHORT const& buttonFlags = raw.data.mouse.usButtonFlags;
|
||||
if (buttonFlags)
|
||||
{
|
||||
printf("button flags: %04X\n", buttonFlags);
|
||||
|
||||
if (buttonFlags & RI_MOUSE_LEFT_BUTTON_DOWN)
|
||||
{
|
||||
puts("left button down");
|
||||
window->registerMouseClickEvent(true);
|
||||
event = processButtonEvent(GHOST_kEventButtonDown, window, GHOST_kButtonMaskLeft);
|
||||
}
|
||||
else if (buttonFlags & RI_MOUSE_LEFT_BUTTON_UP)
|
||||
{
|
||||
puts("left button up");
|
||||
window->registerMouseClickEvent(false);
|
||||
event = processButtonEvent(GHOST_kEventButtonUp, window, GHOST_kButtonMaskLeft);
|
||||
}
|
||||
|
||||
if (buttonFlags & RI_MOUSE_RIGHT_BUTTON_DOWN)
|
||||
{
|
||||
puts("right button down");
|
||||
window->registerMouseClickEvent(true);
|
||||
event = processButtonEvent(GHOST_kEventButtonDown, window, GHOST_kButtonMaskRight);
|
||||
}
|
||||
else if (buttonFlags & RI_MOUSE_RIGHT_BUTTON_UP)
|
||||
{
|
||||
puts("right button up");
|
||||
window->registerMouseClickEvent(false);
|
||||
event = processButtonEvent(GHOST_kEventButtonUp, window, GHOST_kButtonMaskRight);
|
||||
}
|
||||
|
||||
if (buttonFlags & RI_MOUSE_MIDDLE_BUTTON_DOWN)
|
||||
{
|
||||
puts("middle button down");
|
||||
window->registerMouseClickEvent(true);
|
||||
event = processButtonEvent(GHOST_kEventButtonDown, window, GHOST_kButtonMaskMiddle);
|
||||
}
|
||||
else if (buttonFlags & RI_MOUSE_MIDDLE_BUTTON_UP)
|
||||
{
|
||||
puts("middle button up");
|
||||
window->registerMouseClickEvent(false);
|
||||
event = processButtonEvent(GHOST_kEventButtonUp, window, GHOST_kButtonMaskMiddle);
|
||||
}
|
||||
|
||||
// similar for BUTTON_4 and BUTTON_5
|
||||
|
||||
if (buttonFlags & RI_MOUSE_WHEEL)
|
||||
{
|
||||
signed short wheelDelta = raw.data.mouse.usButtonData;
|
||||
printf("wheel moved %+d\n", wheelDelta);
|
||||
}
|
||||
}
|
||||
|
||||
int dx = raw.data.mouse.lLastX; // These might be in Mickeys, not pixels.
|
||||
int dy = raw.data.mouse.lLastY;
|
||||
if (dx || dy)
|
||||
{
|
||||
printf("mouse moved (%+d,%+d)\n", dx, dy);
|
||||
x += dx;
|
||||
x += dy;
|
||||
event = processCursorEvent(GHOST_kEventCursorMove, window, x, y);
|
||||
}
|
||||
}
|
||||
else
|
||||
puts("exotic device!");
|
||||
|
||||
// assume only one event will come from this RawInput report
|
||||
// test and adjust assumptions as needed!
|
||||
|
||||
if (event)
|
||||
{
|
||||
pushEvent(event);
|
||||
event = NULL;
|
||||
eventSent = true;
|
||||
}
|
||||
|
||||
puts("END");
|
||||
|
||||
return eventSent;
|
||||
}
|
||||
|
||||
int GHOST_SystemWin32::getMoreMousePoints(int xLatest, int yLatest, int xPrev, int yPrev, GHOST_WindowWin32* window)
|
||||
{
|
||||
MOUSEMOVEPOINT point = {
|
||||
xLatest & 0x0000FFFF, // confine to low word to make GetMouseMovePointsEx happy
|
||||
yLatest & 0x0000FFFF,
|
||||
0, // time stamp unknown
|
||||
NULL // no extra info
|
||||
};
|
||||
|
||||
MOUSEMOVEPOINT morePoints[64];
|
||||
|
||||
int n = GetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT), &point, morePoints, 64, GMMP_USE_DISPLAY_POINTS);
|
||||
if (n == -1)
|
||||
{
|
||||
printf("<!> can't get more mouse points (error %d)\n", (int) GetLastError());
|
||||
return 0;
|
||||
}
|
||||
|
||||
// search for 'prev' point (we want only newer points)
|
||||
for (int i = 1; i < n; ++i)
|
||||
if (morePoints[i].x == xPrev && morePoints[i].y == yPrev)
|
||||
{
|
||||
n = i; // don't include found point (or more ancient points)
|
||||
break;
|
||||
}
|
||||
|
||||
for (int i = n - 1; i > 0; --i)
|
||||
{
|
||||
signed short x = morePoints[i].x;
|
||||
signed short y = morePoints[i].y;
|
||||
|
||||
printf("> (%d,%d)\n", x, y);
|
||||
|
||||
pushEvent(processCursorEvent(GHOST_kEventCursorMove, window, x, y));
|
||||
}
|
||||
|
||||
return n;
|
||||
} // END getMoreMousePoints
|
||||
|
||||
LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
GHOST_Event* event = 0;
|
||||
LRESULT lResult = 0;
|
||||
GHOST_SystemWin32* system = ((GHOST_SystemWin32*)getSystem());
|
||||
GHOST_ASSERT(system, "GHOST_SystemWin32::s_wndProc(): system not initialized")
|
||||
// [mce] then why not register this function at the end of SystemWin32 constructor?
|
||||
|
||||
bool handled = false;
|
||||
|
||||
if (hwnd) {
|
||||
GHOST_WindowWin32* window = (GHOST_WindowWin32*)::GetWindowLong(hwnd, GWL_USERDATA);
|
||||
if (window) {
|
||||
handled = system->handleEvent(window, msg, wParam, lParam);
|
||||
|
||||
// take care of misc. cases that need hwnd
|
||||
if (msg == WM_ACTIVATE)
|
||||
/* WARNING: Let DefWindowProc handle WM_ACTIVATE, otherwise WM_MOUSEWHEEL
|
||||
will not be dispatched to OUR active window if we minimize one of OUR windows. */
|
||||
lResult = ::DefWindowProc(hwnd, msg, wParam, lParam);
|
||||
else if (msg == WM_PAINT)
|
||||
/* An application sends the WM_PAINT message when the system or another application
|
||||
* makes a request to paint a portion of an application's window. The message is sent
|
||||
* when the UpdateWindow or RedrawWindow function is called, or by the DispatchMessage
|
||||
* function when the application obtains a WM_PAINT message by using the GetMessage or
|
||||
* PeekMessage function. */
|
||||
::ValidateRect(hwnd, NULL);
|
||||
}
|
||||
else {
|
||||
// Event found for a window before the pointer to the class has been set.
|
||||
GHOST_PRINT("GHOST_SystemWin32::wndProc: GHOST window event before creation\n")
|
||||
|
||||
/* These are events we typically miss at this point:
|
||||
WM_GETMINMAXINFO 0x24
|
||||
WM_NCCREATE 0x81
|
||||
WM_NCCALCSIZE 0x83
|
||||
WM_CREATE 0x01
|
||||
We let DefWindowProc do the work.
|
||||
*/
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Events without valid hwnd
|
||||
GHOST_PRINT("GHOST_SystemWin32::wndProc: event without window\n")
|
||||
}
|
||||
|
||||
if (!handled)
|
||||
lResult = ::DefWindowProc(hwnd, msg, wParam, lParam);
|
||||
|
||||
return lResult;
|
||||
}
|
||||
|
||||
bool GHOST_SystemWin32::handleEvent(GHOST_WindowWin32* window, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
GHOST_Event* event = NULL;
|
||||
bool eventSent = false;
|
||||
|
||||
static int mousePosX = 0, mousePosY = 0; // track mouse position between calls
|
||||
|
||||
switch (msg) {
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Keyboard events, processed
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
case WM_KEYDOWN:
|
||||
/* The WM_KEYDOWN message is posted to the window with the keyboard focus when a
|
||||
/* The WM_KEYDOWN message is posted to the window with the keyboard focus when a
|
||||
* nonsystem key is pressed. A nonsystem key is a key that is pressed when the alt
|
||||
* key is not pressed.
|
||||
*/
|
||||
|
@ -660,33 +847,33 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
|
|||
case VK_SHIFT:
|
||||
case VK_CONTROL:
|
||||
case VK_MENU:
|
||||
if (!system->m_separateLeftRightInitialized) {
|
||||
if (!m_separateLeftRightInitialized) {
|
||||
// Check whether this system supports separate left and right keys
|
||||
switch (wParam) {
|
||||
case VK_SHIFT:
|
||||
system->m_separateLeftRight =
|
||||
m_separateLeftRight =
|
||||
(HIBYTE(::GetKeyState(VK_LSHIFT)) != 0) ||
|
||||
(HIBYTE(::GetKeyState(VK_RSHIFT)) != 0) ?
|
||||
true : false;
|
||||
break;
|
||||
case VK_CONTROL:
|
||||
system->m_separateLeftRight =
|
||||
m_separateLeftRight =
|
||||
(HIBYTE(::GetKeyState(VK_LCONTROL)) != 0) ||
|
||||
(HIBYTE(::GetKeyState(VK_RCONTROL)) != 0) ?
|
||||
true : false;
|
||||
break;
|
||||
case VK_MENU:
|
||||
system->m_separateLeftRight =
|
||||
m_separateLeftRight =
|
||||
(HIBYTE(::GetKeyState(VK_LMENU)) != 0) ||
|
||||
(HIBYTE(::GetKeyState(VK_RMENU)) != 0) ?
|
||||
true : false;
|
||||
break;
|
||||
}
|
||||
system->m_separateLeftRightInitialized = true;
|
||||
m_separateLeftRightInitialized = true;
|
||||
}
|
||||
system->processModifierKeys(window);
|
||||
processModifierKeys(window);
|
||||
// Bypass call to DefWindowProc
|
||||
return 0;
|
||||
return true;
|
||||
default:
|
||||
event = processKeyEvent(window, true, wParam, lParam);
|
||||
if (!event) {
|
||||
|
@ -704,9 +891,9 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
|
|||
case VK_SHIFT:
|
||||
case VK_CONTROL:
|
||||
case VK_MENU:
|
||||
system->processModifierKeys(window);
|
||||
processModifierKeys(window);
|
||||
// Bypass call to DefWindowProc
|
||||
return 0;
|
||||
return true;
|
||||
default:
|
||||
event = processKeyEvent(window, false, wParam, lParam);
|
||||
if (!event) {
|
||||
|
@ -718,6 +905,7 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
|
|||
}
|
||||
break;
|
||||
|
||||
#if 0 // this code is illustrative; no need to compile
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Keyboard events, ignored
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
@ -742,16 +930,21 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
|
|||
* a dead key that is pressed while holding down the alt key.
|
||||
*/
|
||||
break;
|
||||
#endif // illustrative code
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Tablet events, processed
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
case WT_PACKET:
|
||||
((GHOST_WindowWin32*)window)->processWin32TabletEvent(wParam, lParam);
|
||||
puts("WT_PACKET");
|
||||
window->processWin32TabletEvent(wParam, lParam);
|
||||
break;
|
||||
case WT_CSRCHANGE:
|
||||
case WT_PROXIMITY:
|
||||
((GHOST_WindowWin32*)window)->processWin32TabletInitEvent();
|
||||
window->processWin32TabletInitEvent();
|
||||
break;
|
||||
|
||||
//#if 0 // this code has been replaced by RawInput (the WM_INPUT case)
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Mouse events, processed
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
@ -795,14 +988,100 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
|
|||
event = processButtonEvent(GHOST_kEventButtonUp, window, GHOST_kButtonMaskButton5);
|
||||
}
|
||||
break;
|
||||
//#endif // replaced mouse code
|
||||
|
||||
case WM_MOUSEMOVE:
|
||||
event = processCursorEvent(GHOST_kEventCursorMove, window);
|
||||
{
|
||||
// puts("WM_MOUSEMOVE");
|
||||
|
||||
// bool IsFromPen = ((GetMessageExtraInfo() & 0xFF515700) == 0xFF515700); // this only works on TabletPCs
|
||||
int tabletTool = GetMessageExtraInfo() & 0x7f; // true for tablet mouse, not just pen
|
||||
if (tabletTool)
|
||||
puts("(from tablet)");
|
||||
else
|
||||
{
|
||||
// these give window coords, we need view coords
|
||||
// mousePosX = LOWORD(lParam);
|
||||
// mousePosY = HIWORD(lParam);
|
||||
// window->clientToScreen(mousePosX, mousePosY, mousePosX, mousePosY);
|
||||
|
||||
int xPrev = mousePosX;
|
||||
int yPrev = mousePosY;
|
||||
window->clientToScreen(LOWORD(lParam), HIWORD(lParam), mousePosX, mousePosY);
|
||||
// if (m_input_fidelity_hint == HI_FI) // can't access hint from static function
|
||||
|
||||
putchar('\n');
|
||||
/* int n = */ getMoreMousePoints(mousePosX, mousePosY, xPrev, yPrev, window);
|
||||
// printf("%d more mouse points found\n", n);
|
||||
printf(" (%d,%d)\n", mousePosX, mousePosY);
|
||||
|
||||
event = processCursorEvent(GHOST_kEventCursorMove, window, mousePosX, mousePosY);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_INPUT:
|
||||
puts("WM_INPUT");
|
||||
{
|
||||
/*
|
||||
UINT dwSize;
|
||||
GetRawInputData((HRAWINPUT)lParam, RID_INPUT, NULL, &dwSize, sizeof(RAWINPUTHEADER));
|
||||
LPBYTE lpb = new BYTE[dwSize];
|
||||
GetRawInputData((HRAWINPUT)lParam, RID_INPUT, lpb, &dwSize, sizeof(RAWINPUTHEADER));
|
||||
RAWINPUT* raw = (RAWINPUT*)lpb;
|
||||
*/
|
||||
|
||||
RAWINPUT raw;
|
||||
RAWINPUT* raw_ptr = &raw;
|
||||
UINT rawSize = sizeof(RAWINPUT);
|
||||
// UINT bufferSize = rawSize;
|
||||
|
||||
puts("processing first event:");
|
||||
GetRawInputData((HRAWINPUT)lParam, RID_INPUT, raw_ptr, &rawSize, sizeof(RAWINPUTHEADER));
|
||||
eventSent |= processRawInput(raw, window, mousePosX, mousePosY);
|
||||
DefRawInputProc(&raw_ptr, 1, sizeof(RAWINPUTHEADER));
|
||||
|
||||
// GetRawInputBuffer(NULL, &bufferSize, sizeof(RAWINPUTHEADER));
|
||||
// UINT n = bufferSize / rawSize;
|
||||
// printf("allocating %d bytes (room for %d events)\n", bufferSize, n);
|
||||
|
||||
RAWINPUT rawBuffer[10];// = new RAWINPUT[n];
|
||||
rawSize *= 10;
|
||||
while (true)
|
||||
{
|
||||
int n = GetRawInputBuffer(rawBuffer, &rawSize, sizeof(RAWINPUTHEADER));
|
||||
if (n == -1)
|
||||
{
|
||||
printf("<!> error %d\n", (int) GetLastError());
|
||||
break;
|
||||
}
|
||||
else if (n == 0)
|
||||
{
|
||||
//puts("no more events");
|
||||
putchar('\n');
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("processing %d more events:\n", n);
|
||||
for (int i = 0; i < n; ++i)
|
||||
{
|
||||
RAWINPUT const& raw = rawBuffer[i];
|
||||
eventSent |= processRawInput(raw, window, mousePosX, mousePosY);
|
||||
}
|
||||
|
||||
// clear processed events from the queue
|
||||
DefRawInputProc((RAWINPUT**)&rawBuffer, n, sizeof(RAWINPUTHEADER));
|
||||
}
|
||||
} // inf. loop
|
||||
}
|
||||
break;
|
||||
case WM_MOUSEWHEEL:
|
||||
/* The WM_MOUSEWHEEL message is sent to the focus window
|
||||
* when the mouse wheel is rotated. The DefWindowProc
|
||||
puts("WM_MOUSEWHEEL");
|
||||
/* The WM_MOUSEWHEEL message is sent to the focus window
|
||||
* when the mouse wheel is rotated. The DefWindowProc
|
||||
* function propagates the message to the window's parent.
|
||||
* There should be no internal forwarding of the message,
|
||||
* There should be no internal forwarding of the message,
|
||||
* since DefWindowProc propagates it up the parent chain
|
||||
* until it finds a window that processes it.
|
||||
*/
|
||||
|
@ -827,6 +1106,7 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
|
|||
}
|
||||
break;
|
||||
|
||||
#if 0 // this code is illustrative; no need to compile
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Mouse events, ignored
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
@ -842,6 +1122,7 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
|
|||
* is sent to the window that has captured the mouse.
|
||||
*/
|
||||
break;
|
||||
#endif // illustrative code
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Window events, processed
|
||||
|
@ -858,19 +1139,15 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
|
|||
* the message is sent asynchronously, so the window is activated immediately.
|
||||
*/
|
||||
event = processWindowEvent(LOWORD(wParam) ? GHOST_kEventWindowActivate : GHOST_kEventWindowDeactivate, window);
|
||||
/* WARNING: Let DefWindowProc handle WM_ACTIVATE, otherwise WM_MOUSEWHEEL
|
||||
will not be dispatched to OUR active window if we minimize one of OUR windows. */
|
||||
lResult = ::DefWindowProc(hwnd, msg, wParam, lParam);
|
||||
break;
|
||||
case WM_PAINT:
|
||||
/* An application sends the WM_PAINT message when the system or another application
|
||||
/* An application sends the WM_PAINT message when the system or another application
|
||||
* makes a request to paint a portion of an application's window. The message is sent
|
||||
* when the UpdateWindow or RedrawWindow function is called, or by the DispatchMessage
|
||||
* function when the application obtains a WM_PAINT message by using the GetMessage or
|
||||
* PeekMessage function.
|
||||
*/
|
||||
event = processWindowEvent(GHOST_kEventWindowUpdate, window);
|
||||
::ValidateRect(hwnd, NULL);
|
||||
break;
|
||||
case WM_GETMINMAXINFO:
|
||||
/* The WM_GETMINMAXINFO message is sent to a window when the size or
|
||||
|
@ -906,6 +1183,8 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
|
|||
*/
|
||||
event = processWindowEvent(GHOST_kEventWindowMove, window);
|
||||
break;
|
||||
|
||||
#if 0 // this code is illustrative; no need to compile
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Window events, ignored
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
@ -986,57 +1265,44 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
|
|||
* In GHOST, we let DefWindowProc call the timer callback.
|
||||
*/
|
||||
break;
|
||||
#endif // illustrative code
|
||||
|
||||
#if 0 // this is part of the 'old' NDOF system; new one coming soon!
|
||||
case WM_BLND_NDOF_AXIS:
|
||||
{
|
||||
GHOST_TEventNDOFData ndofdata;
|
||||
system->m_ndofManager->GHOST_NDOFGetDatas(ndofdata);
|
||||
system->m_eventManager->
|
||||
m_ndofManager->GHOST_NDOFGetDatas(ndofdata);
|
||||
m_eventManager->
|
||||
pushEvent(new GHOST_EventNDOF(
|
||||
system->getMilliSeconds(),
|
||||
GHOST_kEventNDOFMotion,
|
||||
getMilliSeconds(),
|
||||
GHOST_kEventNDOFMotion,
|
||||
window, ndofdata));
|
||||
}
|
||||
break;
|
||||
case WM_BLND_NDOF_BTN:
|
||||
{
|
||||
GHOST_TEventNDOFData ndofdata;
|
||||
system->m_ndofManager->GHOST_NDOFGetDatas(ndofdata);
|
||||
system->m_eventManager->
|
||||
m_ndofManager->GHOST_NDOFGetDatas(ndofdata);
|
||||
m_eventManager->
|
||||
pushEvent(new GHOST_EventNDOF(
|
||||
system->getMilliSeconds(),
|
||||
GHOST_kEventNDOFButton,
|
||||
getMilliSeconds(),
|
||||
GHOST_kEventNDOFButton,
|
||||
window, ndofdata));
|
||||
}
|
||||
break;
|
||||
#endif // old NDOF
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Event found for a window before the pointer to the class has been set.
|
||||
GHOST_PRINT("GHOST_SystemWin32::wndProc: GHOST window event before creation\n")
|
||||
/* These are events we typically miss at this point:
|
||||
WM_GETMINMAXINFO 0x24
|
||||
WM_NCCREATE 0x81
|
||||
WM_NCCALCSIZE 0x83
|
||||
WM_CREATE 0x01
|
||||
We let DefWindowProc do the work.
|
||||
*/
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Events without valid hwnd
|
||||
GHOST_PRINT("GHOST_SystemWin32::wndProc: event without window\n")
|
||||
}
|
||||
|
||||
if (event) {
|
||||
system->pushEvent(event);
|
||||
}
|
||||
else {
|
||||
lResult = ::DefWindowProc(hwnd, msg, wParam, lParam);
|
||||
}
|
||||
return lResult;
|
||||
if (!eventSent)
|
||||
if (event) {
|
||||
pushEvent(event);
|
||||
eventSent = true;
|
||||
}
|
||||
|
||||
return eventSent;
|
||||
}
|
||||
|
||||
GHOST_TUns8* GHOST_SystemWin32::getClipboard(bool selection) const
|
||||
GHOST_TUns8* GHOST_SystemWin32::getClipboard(bool selection) const
|
||||
{
|
||||
char *buffer;
|
||||
char *temp_buff;
|
||||
|
|
|
@ -37,7 +37,10 @@
|
|||
#error WIN32 only!
|
||||
#endif // WIN32
|
||||
|
||||
#define _WIN32_WINNT 0x501 // require Windows XP or newer
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <ole2.h>
|
||||
|
||||
#include "GHOST_System.h"
|
||||
|
||||
|
@ -53,6 +56,8 @@ class GHOST_EventWheel;
|
|||
class GHOST_EventWindow;
|
||||
class GHOST_EventDragnDrop;
|
||||
|
||||
class GHOST_WindowWin32;
|
||||
|
||||
/**
|
||||
* WIN32 Implementation of GHOST_System class.
|
||||
* @see GHOST_System.
|
||||
|
@ -258,9 +263,10 @@ protected:
|
|||
* Creates cursor event.
|
||||
* @param type The type of event to create.
|
||||
* @param window The window receiving the event (the active window).
|
||||
* @param x,y Cursor position.
|
||||
* @return The event created.
|
||||
*/
|
||||
static GHOST_EventCursor* processCursorEvent(GHOST_TEventType type, GHOST_IWindow *Iwindow);
|
||||
static GHOST_EventCursor* processCursorEvent(GHOST_TEventType type, GHOST_IWindow *Iwindow, int x, int y);
|
||||
|
||||
/**
|
||||
* Creates a mouse wheel event.
|
||||
|
@ -287,12 +293,31 @@ protected:
|
|||
* @return The event created.
|
||||
*/
|
||||
static GHOST_Event* processWindowEvent(GHOST_TEventType type, GHOST_IWindow* window);
|
||||
/**
|
||||
|
||||
/**
|
||||
* Handles minimum window size.
|
||||
* @param minmax The MINMAXINFO structure.
|
||||
*/
|
||||
static void processMinMaxInfo(MINMAXINFO * minmax);
|
||||
|
||||
|
||||
/**
|
||||
* Creates and sends mouse or multi-axis events.
|
||||
* @param raw a single RawInput structure
|
||||
* @param window The window receiving the event (the active window).
|
||||
* @param x,y current mouse coordinates, which may be updated by this function
|
||||
* @return Whether any events (possibly more than one) were created and sent.
|
||||
*/
|
||||
bool processRawInput(RAWINPUT const& raw, GHOST_WindowWin32* window, int& x, int& y);
|
||||
|
||||
/**
|
||||
* Creates and sends mouse events for mouse movements "in between" WM_MOUSEMOVEs.
|
||||
* @param Latest screen coords from latest WM_MOUSEMOVE
|
||||
* @param Prev screen coords from previous WM_MOUSEMOVE
|
||||
* @param window The window receiving the event (the active window).
|
||||
* @return How many events (possibly many) were created and sent.
|
||||
*/
|
||||
int getMoreMousePoints(int xLatest, int yLatest, int xPrev, int yPrev, GHOST_WindowWin32* window);
|
||||
|
||||
/**
|
||||
* Returns the local state of the modifier keys (from the message queue).
|
||||
* @param keys The state of the keys.
|
||||
|
@ -311,6 +336,9 @@ protected:
|
|||
*/
|
||||
static LRESULT WINAPI s_wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
// non-static version of WndProc
|
||||
bool handleEvent(GHOST_WindowWin32* window, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
/** The current state of the modifier keys. */
|
||||
GHOST_ModifierKeys m_modifierKeys;
|
||||
/** State variable set at initialization. */
|
||||
|
|
Loading…
Reference in New Issue