diff options
Diffstat (limited to 'intern/ghost/intern/GHOST_SystemWin32.cpp')
-rw-r--r-- | intern/ghost/intern/GHOST_SystemWin32.cpp | 829 |
1 files changed, 400 insertions, 429 deletions
diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp index 7c07ea6cd64..5c58f9a856c 100644 --- a/intern/ghost/intern/GHOST_SystemWin32.cpp +++ b/intern/ghost/intern/GHOST_SystemWin32.cpp @@ -42,47 +42,48 @@ # include "GHOST_NDOFManagerWin32.h" #endif -// Key code values not found in winuser.h +/* Key code values not found in `winuser.h`. */ #ifndef VK_MINUS # define VK_MINUS 0xBD -#endif // VK_MINUS +#endif /* VK_MINUS */ #ifndef VK_SEMICOLON # define VK_SEMICOLON 0xBA -#endif // VK_SEMICOLON +#endif /* VK_SEMICOLON */ #ifndef VK_PERIOD # define VK_PERIOD 0xBE -#endif // VK_PERIOD +#endif /* VK_PERIOD */ #ifndef VK_COMMA # define VK_COMMA 0xBC -#endif // VK_COMMA +#endif /* VK_COMMA */ #ifndef VK_BACK_QUOTE # define VK_BACK_QUOTE 0xC0 -#endif // VK_BACK_QUOTE +#endif /* VK_BACK_QUOTE */ #ifndef VK_SLASH # define VK_SLASH 0xBF -#endif // VK_SLASH +#endif /* VK_SLASH */ #ifndef VK_BACK_SLASH # define VK_BACK_SLASH 0xDC -#endif // VK_BACK_SLASH +#endif /* VK_BACK_SLASH */ #ifndef VK_EQUALS # define VK_EQUALS 0xBB -#endif // VK_EQUALS +#endif /* VK_EQUALS */ #ifndef VK_OPEN_BRACKET # define VK_OPEN_BRACKET 0xDB -#endif // VK_OPEN_BRACKET +#endif /* VK_OPEN_BRACKET */ #ifndef VK_CLOSE_BRACKET # define VK_CLOSE_BRACKET 0xDD -#endif // VK_CLOSE_BRACKET +#endif /* VK_CLOSE_BRACKET */ #ifndef VK_GR_LESS # define VK_GR_LESS 0xE2 -#endif // VK_GR_LESS +#endif /* VK_GR_LESS */ -/* Workaround for some laptop touchpads, some of which seems to +/** + * Workaround for some laptop touch-pads, some of which seems to * have driver issues which makes it so window function receives - * the message, but PeekMessage doesn't pick those messages for + * the message, but #PeekMessage doesn't pick those messages for * some reason. * - * We send a dummy WM_USER message to force PeekMessage to receive + * We send a dummy WM_USER message to force #PeekMessage to receive * something, making it so blender's window manager sees the new * messages coming in. */ @@ -101,22 +102,23 @@ static void initRawInput() RAWINPUTDEVICE devices[DEVICE_COUNT]; memset(devices, 0, DEVICE_COUNT * sizeof(RAWINPUTDEVICE)); - // Initiates WM_INPUT messages from keyboard - // That way GHOST can retrieve true keys + /* Initiates WM_INPUT messages from keyboard + * That way GHOST can retrieve true keys. */ devices[0].usUsagePage = 0x01; devices[0].usUsage = 0x06; /* http://msdn.microsoft.com/en-us/windows/hardware/gg487473.aspx */ #ifdef WITH_INPUT_NDOF - // multi-axis mouse (SpaceNavigator, etc.) + /* multi-axis mouse (SpaceNavigator, etc.). */ devices[1].usUsagePage = 0x01; devices[1].usUsage = 0x08; #endif - if (RegisterRawInputDevices(devices, DEVICE_COUNT, sizeof(RAWINPUTDEVICE))) - ; // yay! - else + if (RegisterRawInputDevices(devices, DEVICE_COUNT, sizeof(RAWINPUTDEVICE))) { + /* Success. */ + } + else { GHOST_PRINTF("could not register for RawInput: %d\n", (int)GetLastError()); - + } #undef DEVICE_COUNT } @@ -129,17 +131,17 @@ GHOST_SystemWin32::GHOST_SystemWin32() GHOST_ASSERT(m_displayManager, "GHOST_SystemWin32::GHOST_SystemWin32(): m_displayManager==0\n"); m_displayManager->initialize(); - m_consoleStatus = 1; + m_consoleStatus = true; - // Tell Windows we are per monitor DPI aware. This disables the default - // blurry scaling and enables WM_DPICHANGED to allow us to draw at proper DPI. + /* Tell Windows we are per monitor DPI aware. This disables the default + * blurry scaling and enables WM_DPICHANGED to allow us to draw at proper DPI. */ SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE); - // Check if current keyboard layout uses AltGr and save keylayout ID for - // specialized handling if keys like VK_OEM_*. I.e. french keylayout - // generates VK_OEM_8 for their exclamation key (key left of right shift) + /* Check if current keyboard layout uses AltGr and save keylayout ID for + * specialized handling if keys like VK_OEM_*. I.e. french keylayout + * generates #VK_OEM_8 for their exclamation key (key left of right shift). */ this->handleKeyboardChange(); - // Require COM for GHOST_DropTargetWin32 created in GHOST_WindowWin32. + /* Require COM for GHOST_DropTargetWin32 created in GHOST_WindowWin32. */ OleInitialize(0); #ifdef WITH_INPUT_NDOF @@ -149,7 +151,7 @@ GHOST_SystemWin32::GHOST_SystemWin32() GHOST_SystemWin32::~GHOST_SystemWin32() { - // Shutdown COM + /* Shutdown COM. */ OleUninitialize(); if (isStartedFromCommandPrompt()) { @@ -159,7 +161,7 @@ GHOST_SystemWin32::~GHOST_SystemWin32() uint64_t GHOST_SystemWin32::performanceCounterToMillis(__int64 perf_ticks) const { - // Calculate the time passed since system initialization. + /* Calculate the time passed since system initialization. */ __int64 delta = (perf_ticks - m_start) * 1000; uint64_t t = (uint64_t)(delta / m_freq); @@ -173,12 +175,12 @@ uint64_t GHOST_SystemWin32::tickCountToMillis(__int64 ticks) const uint64_t GHOST_SystemWin32::getMilliSeconds() const { - // Hardware does not support high resolution timers. We will use GetTickCount instead then. + /* Hardware does not support high resolution timers. We will use GetTickCount instead then. */ if (!m_hasPerformanceCounter) { return tickCountToMillis(::GetTickCount()); } - // Retrieve current count + /* Retrieve current count */ __int64 count = 0; ::QueryPerformanceCounter((LARGE_INTEGER *)&count); @@ -227,13 +229,13 @@ GHOST_IWindow *GHOST_SystemWin32::createWindow(const char *title, state, type, ((glSettings.flags & GHOST_glStereoVisual) != 0), - ((glSettings.flags & GHOST_glAlphaBackground) != 0), + false, (GHOST_WindowWin32 *)parentWindow, ((glSettings.flags & GHOST_glDebugContext) != 0), is_dialog); if (window->getValid()) { - // Store the pointer to the window + /* Store the pointer to the window */ m_windowManager->addWindow(window); m_windowManager->setActiveWindow(window); } @@ -272,7 +274,7 @@ GHOST_IContext *GHOST_SystemWin32::createOffscreenContext(GHOST_GLSettings glSet HDC mHDC = GetDC(wnd); HDC prev_hdc = wglGetCurrentDC(); HGLRC prev_context = wglGetCurrentContext(); -#if defined(WITH_GL_PROFILE_CORE) + for (int minor = 5; minor >= 0; --minor) { context = new GHOST_ContextWGL(false, true, @@ -310,29 +312,6 @@ GHOST_IContext *GHOST_SystemWin32::createOffscreenContext(GHOST_GLSettings glSet return NULL; } -#elif defined(WITH_GL_PROFILE_COMPAT) - // ask for 2.1 context, driver gives any GL version >= 2.1 - // (hopefully the latest compatibility profile) - // 2.1 ignores the profile bit & is incompatible with core profile - context = new GHOST_ContextWGL(false, - true, - NULL, - NULL, - 0, // no profile bit - 2, - 1, - (debug_context ? WGL_CONTEXT_DEBUG_BIT_ARB : 0), - GHOST_OPENGL_WGL_RESET_NOTIFICATION_STRATEGY); - - if (context->initializeDrawingContext()) { - return context; - } - else { - delete context; - } -#else -# error // must specify either core or compat at build time -#endif finished: wglMakeCurrent(prev_hdc, prev_context); return context; @@ -374,6 +353,7 @@ GHOST_ContextD3D *GHOST_SystemWin32::createOffscreenContextD3D() context = new GHOST_ContextD3D(false, wnd); if (context->initializeDrawingContext() == GHOST_kFailure) { delete context; + context = nullptr; } return context; @@ -418,10 +398,10 @@ bool GHOST_SystemWin32::processEvents(bool waitForEvent) driveTrackpad(); - // Process all the events waiting for us + /* Process all the events waiting for us. */ while (::PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE) != 0) { - // TranslateMessage doesn't alter the message, and doesn't change our raw keyboard data. - // Needed for MapVirtualKey or if we ever need to get chars from wm_ime_char or similar. + /* #TranslateMessage doesn't alter the message, and doesn't change our raw keyboard data. + * Needed for #MapVirtualKey or if we ever need to get chars from wm_ime_char or similar. */ ::TranslateMessage(&msg); ::DispatchMessageW(&msg); hasEventHandled = true; @@ -453,8 +433,9 @@ GHOST_TSuccess GHOST_SystemWin32::getCursorPosition(int32_t &x, int32_t &y) cons GHOST_TSuccess GHOST_SystemWin32::setCursorPosition(int32_t x, int32_t y) { - if (!::GetActiveWindow()) + if (!::GetActiveWindow()) { return GHOST_kFailure; + } return ::SetCursorPos(x, y) == TRUE ? GHOST_kSuccess : GHOST_kFailure; } @@ -475,12 +456,11 @@ GHOST_TSuccess GHOST_SystemWin32::getModifierKeys(GHOST_ModifierKeys &keys) cons down = HIBYTE(::GetKeyState(VK_RCONTROL)) != 0; keys.set(GHOST_kModifierKeyRightControl, down); - bool lwindown = HIBYTE(::GetKeyState(VK_LWIN)) != 0; - bool rwindown = HIBYTE(::GetKeyState(VK_RWIN)) != 0; - if (lwindown || rwindown) - keys.set(GHOST_kModifierKeyOS, true); - else - keys.set(GHOST_kModifierKeyOS, false); + down = HIBYTE(::GetKeyState(VK_LWIN)) != 0; + keys.set(GHOST_kModifierKeyLeftOS, down); + down = HIBYTE(::GetKeyState(VK_RWIN)) != 0; + keys.set(GHOST_kModifierKeyRightOS, down); + return GHOST_kSuccess; } @@ -512,7 +492,7 @@ GHOST_TSuccess GHOST_SystemWin32::init() initRawInput(); m_lfstart = ::GetTickCount(); - // Determine whether this system has a high frequency performance counter. */ + /* Determine whether this system has a high frequency performance counter. */ m_hasPerformanceCounter = ::QueryPerformanceFrequency((LARGE_INTEGER *)&m_freq) == TRUE; if (m_hasPerformanceCounter) { GHOST_PRINT("GHOST_SystemWin32::init: High Frequency Performance Timer available\n"); @@ -543,7 +523,7 @@ GHOST_TSuccess GHOST_SystemWin32::init() wc.lpszMenuName = 0; wc.lpszClassName = L"GHOST_WindowClass"; - // Use RegisterClassEx for setting small icon + /* Use #RegisterClassEx for setting small icon. */ if (::RegisterClassW(&wc) == 0) { success = GHOST_kFailure; } @@ -557,76 +537,15 @@ GHOST_TSuccess GHOST_SystemWin32::exit() return GHOST_System::exit(); } -GHOST_TKey GHOST_SystemWin32::hardKey(RAWINPUT const &raw, - bool *r_keyDown, - bool *r_is_repeated_modifier) +GHOST_TKey GHOST_SystemWin32::hardKey(RAWINPUT const &raw, bool *r_key_down) { - bool is_repeated_modifier = false; - - GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem(); - GHOST_TKey key = GHOST_kKeyUnknown; - GHOST_ModifierKeys modifiers; - system->retrieveModifierKeys(modifiers); - - // RI_KEY_BREAK doesn't work for sticky keys release, so we also - // check for the up message + /* #RI_KEY_BREAK doesn't work for sticky keys release, so we also check for the up message. */ unsigned int msg = raw.data.keyboard.Message; - *r_keyDown = !(raw.data.keyboard.Flags & RI_KEY_BREAK) && msg != WM_KEYUP && msg != WM_SYSKEYUP; - - key = this->convertKey(raw.data.keyboard.VKey, - raw.data.keyboard.MakeCode, - (raw.data.keyboard.Flags & (RI_KEY_E1 | RI_KEY_E0))); - - // extra handling of modifier keys: don't send repeats out from GHOST - if (key >= GHOST_kKeyLeftShift && key <= GHOST_kKeyRightAlt) { - bool changed = false; - GHOST_TModifierKey modifier; - switch (key) { - case GHOST_kKeyLeftShift: { - changed = (modifiers.get(GHOST_kModifierKeyLeftShift) != *r_keyDown); - modifier = GHOST_kModifierKeyLeftShift; - break; - } - case GHOST_kKeyRightShift: { - changed = (modifiers.get(GHOST_kModifierKeyRightShift) != *r_keyDown); - modifier = GHOST_kModifierKeyRightShift; - break; - } - case GHOST_kKeyLeftControl: { - changed = (modifiers.get(GHOST_kModifierKeyLeftControl) != *r_keyDown); - modifier = GHOST_kModifierKeyLeftControl; - break; - } - case GHOST_kKeyRightControl: { - changed = (modifiers.get(GHOST_kModifierKeyRightControl) != *r_keyDown); - modifier = GHOST_kModifierKeyRightControl; - break; - } - case GHOST_kKeyLeftAlt: { - changed = (modifiers.get(GHOST_kModifierKeyLeftAlt) != *r_keyDown); - modifier = GHOST_kModifierKeyLeftAlt; - break; - } - case GHOST_kKeyRightAlt: { - changed = (modifiers.get(GHOST_kModifierKeyRightAlt) != *r_keyDown); - modifier = GHOST_kModifierKeyRightAlt; - break; - } - default: - break; - } + *r_key_down = !(raw.data.keyboard.Flags & RI_KEY_BREAK) && msg != WM_KEYUP && msg != WM_SYSKEYUP; - if (changed) { - modifiers.set(modifier, *r_keyDown); - system->storeModifierKeys(modifiers); - } - else { - is_repeated_modifier = true; - } - } - - *r_is_repeated_modifier = is_repeated_modifier; - return key; + return this->convertKey(raw.data.keyboard.VKey, + raw.data.keyboard.MakeCode, + (raw.data.keyboard.Flags & (RI_KEY_E1 | RI_KEY_E0))); } /** @@ -680,11 +599,11 @@ GHOST_TKey GHOST_SystemWin32::convertKey(short vKey, short scanCode, short exten GHOST_TKey key; if ((vKey >= '0') && (vKey <= '9')) { - // VK_0 thru VK_9 are the same as ASCII '0' thru '9' (0x30 - 0x39) + /* VK_0 thru VK_9 are the same as ASCII '0' thru '9' (0x30 - 0x39). */ key = (GHOST_TKey)(vKey - '0' + GHOST_kKey0); } else if ((vKey >= 'A') && (vKey <= 'Z')) { - // VK_A thru VK_Z are the same as ASCII 'A' thru 'Z' (0x41 - 0x5A) + /* VK_A thru VK_Z are the same as ASCII 'A' thru 'Z' (0x41 - 0x5A). */ key = (GHOST_TKey)(vKey - 'A' + GHOST_kKeyA); } else if ((vKey >= VK_F1) && (vKey <= VK_F24)) { @@ -829,8 +748,10 @@ GHOST_TKey GHOST_SystemWin32::convertKey(short vKey, short scanCode, short exten key = (extend) ? GHOST_kKeyRightAlt : GHOST_kKeyLeftAlt; break; case VK_LWIN: + key = GHOST_kKeyLeftOS; + break; case VK_RWIN: - key = GHOST_kKeyOS; + key = GHOST_kKeyRightOS; break; case VK_APPS: key = GHOST_kKeyApp; @@ -979,11 +900,11 @@ void GHOST_SystemWin32::processWintabEvent(GHOST_WindowWin32 *window) new GHOST_EventButton(info.time, info.type, window, info.button, info.tabletData)); mouseMoveHandled = true; - break; } else { WINTAB_PRINTF(" ... but no system button\n"); } + break; } case GHOST_kEventButtonUp: { WINTAB_PRINTF("HWND %p Wintab button up", window->getHWND()); @@ -1058,7 +979,7 @@ void GHOST_SystemWin32::processPointerEvent( } switch (type) { - case WM_POINTERUPDATE: + case WM_POINTERUPDATE: { /* Coalesced pointer events are reverse chronological order, reorder chronologically. * Only contiguous move events are coalesced. */ for (uint32_t i = pointerInfo.size(); i-- > 0;) { @@ -1073,7 +994,8 @@ void GHOST_SystemWin32::processPointerEvent( /* Leave event unhandled so that system cursor is moved. */ break; - case WM_POINTERDOWN: + } + case WM_POINTERDOWN: { /* Move cursor to point of contact because GHOST_EventButton does not include position. */ system->pushEvent(new GHOST_EventCursor(pointerInfo[0].time, GHOST_kEventCursorMove, @@ -1092,7 +1014,8 @@ void GHOST_SystemWin32::processPointerEvent( eventHandled = true; break; - case WM_POINTERUP: + } + case WM_POINTERUP: { system->pushEvent(new GHOST_EventButton(pointerInfo[0].time, GHOST_kEventButtonUp, window, @@ -1104,8 +1027,10 @@ void GHOST_SystemWin32::processPointerEvent( eventHandled = true; break; - default: + } + default: { break; + } } } @@ -1122,6 +1047,12 @@ GHOST_EventCursor *GHOST_SystemWin32::processCursorEvent(GHOST_WindowWin32 *wind system->getCursorPosition(x_screen, y_screen); if (window->getCursorGrabModeIsWarp()) { + /* WORKAROUND: + * Sometimes Windows ignores `SetCursorPos()` or `SendInput()` calls or the mouse event is + * outdated. Identify these cases by checking if the cursor is not yet within bounds. */ + static bool is_warping_x = false; + static bool is_warping_y = false; + int32_t x_new = x_screen; int32_t y_new = y_screen; int32_t x_accum, y_accum; @@ -1138,29 +1069,41 @@ GHOST_EventCursor *GHOST_SystemWin32::processCursorEvent(GHOST_WindowWin32 *wind window->getCursorGrabAccum(x_accum, y_accum); if (x_new != x_screen || y_new != y_screen) { + system->setCursorPosition(x_new, y_new); /* wrap */ + + /* Do not update the accum values if we are an outdated or failed pos-warp event. */ + if (!is_warping_x) { + is_warping_x = x_new != x_screen; + if (is_warping_x) { + x_accum += (x_screen - x_new); + } + } + + if (!is_warping_y) { + is_warping_y = y_new != y_screen; + if (is_warping_y) { + y_accum += (y_screen - y_new); + } + } + window->setCursorGrabAccum(x_accum, y_accum); + /* When wrapping we don't need to add an event because the setCursorPosition call will cause * a new event after. */ - system->setCursorPosition(x_new, y_new); /* wrap */ - window->setCursorGrabAccum(x_accum + (x_screen - x_new), y_accum + (y_screen - y_new)); - } - else { - return new GHOST_EventCursor(system->getMilliSeconds(), - GHOST_kEventCursorMove, - window, - x_screen + x_accum, - y_screen + y_accum, - GHOST_TABLET_DATA_NONE); + return NULL; } + + is_warping_x = false; + is_warping_y = false; + x_screen += x_accum; + y_screen += y_accum; } - else { - return new GHOST_EventCursor(system->getMilliSeconds(), - GHOST_kEventCursorMove, - window, - x_screen, - y_screen, - GHOST_TABLET_DATA_NONE); - } - return NULL; + + return new GHOST_EventCursor(system->getMilliSeconds(), + GHOST_kEventCursorMove, + window, + x_screen, + y_screen, + GHOST_TABLET_DATA_NONE); } void GHOST_SystemWin32::processWheelEvent(GHOST_WindowWin32 *window, WPARAM wParam, LPARAM lParam) @@ -1171,7 +1114,7 @@ void GHOST_SystemWin32::processWheelEvent(GHOST_WindowWin32 *window, WPARAM wPar int delta = GET_WHEEL_DELTA_WPARAM(wParam); if (acc * delta < 0) { - // scroll direction reversed. + /* Scroll direction reversed. */ acc = 0; } acc += delta; @@ -1187,48 +1130,55 @@ void GHOST_SystemWin32::processWheelEvent(GHOST_WindowWin32 *window, WPARAM wPar GHOST_EventKey *GHOST_SystemWin32::processKeyEvent(GHOST_WindowWin32 *window, RAWINPUT const &raw) { - bool keyDown = false; - bool is_repeated_modifier = false; + const char vk = raw.data.keyboard.VKey; + bool key_down = false; GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem(); - GHOST_TKey key = system->hardKey(raw, &keyDown, &is_repeated_modifier); + GHOST_TKey key = system->hardKey(raw, &key_down); GHOST_EventKey *event; + /* NOTE(@campbellbarton): key repeat in WIN32 also applies to modifier-keys. + * Check for this case and filter out modifier-repeat. + * Typically keyboard events are *not* filtered as part of GHOST's event handling. + * As other GHOST back-ends don't have the behavior, it's simplest not to send them through. + * Ideally it would be possible to check the key-map for keys that repeat but this doesn't look + * to be supported. */ + bool is_repeat = false; + bool is_repeated_modifier = false; + if (key_down) { + if (system->m_keycode_last_repeat_key == vk) { + is_repeat = true; + is_repeated_modifier = GHOST_KEY_MODIFIER_CHECK(key); + } + system->m_keycode_last_repeat_key = vk; + } + else { + if (system->m_keycode_last_repeat_key == vk) { + system->m_keycode_last_repeat_key = 0; + } + } + /* We used to check `if (key != GHOST_kKeyUnknown)`, but since the message * values `WM_SYSKEYUP`, `WM_KEYUP` and `WM_CHAR` are ignored, we capture * those events here as well. */ if (!is_repeated_modifier) { - char vk = raw.data.keyboard.VKey; char utf8_char[6] = {0}; - char ascii = 0; - bool is_repeat = false; + BYTE state[256]; + const BOOL has_state = GetKeyboardState((PBYTE)state); + const bool ctrl_pressed = has_state && state[VK_CONTROL] & 0x80; + const bool alt_pressed = has_state && state[VK_MENU] & 0x80; - /* Unlike on Linux, not all keys can send repeat events. E.g. modifier keys don't. */ - if (keyDown) { - if (system->m_keycode_last_repeat_key == vk) { - is_repeat = true; - } - system->m_keycode_last_repeat_key = vk; - } - else { - if (system->m_keycode_last_repeat_key == vk) { - system->m_keycode_last_repeat_key = 0; - } + if (!key_down) { + /* Pass. */ } - - wchar_t utf16[3] = {0}; - BYTE state[256] = {0}; - int r; - GetKeyboardState((PBYTE)state); - bool ctrl_pressed = state[VK_CONTROL] & 0x80; - bool alt_pressed = state[VK_MENU] & 0x80; - /* No text with control key pressed (Alt can be used to insert special characters though!). */ - if (ctrl_pressed && !alt_pressed) { - utf8_char[0] = '\0'; + else if (ctrl_pressed && !alt_pressed) { + /* Pass. */ } - // Don't call ToUnicodeEx on dead keys as it clears the buffer and so won't allow diacritical - // composition. + /* Don't call #ToUnicodeEx on dead keys as it clears the buffer and so won't allow diacritical + * composition. */ else if (MapVirtualKeyW(vk, 2) != 0) { + wchar_t utf16[3] = {0}; + int r; /* TODO: #ToUnicodeEx can respond with up to 4 utf16 chars (only 2 here). * Could be up to 24 utf8 bytes. */ if ((r = ToUnicodeEx( @@ -1243,28 +1193,25 @@ GHOST_EventKey *GHOST_SystemWin32::processKeyEvent(GHOST_WindowWin32 *window, RA } } - if (!keyDown) { - utf8_char[0] = '\0'; - ascii = '\0'; - } - else { - ascii = utf8_char[0] & 0x80 ? '?' : utf8_char[0]; - } - #ifdef WITH_INPUT_IME - if (window->getImeInput()->IsImeKeyEvent(ascii, key)) { - return NULL; + if (key_down && ((utf8_char[0] & 0x80) == 0)) { + const char ascii = utf8_char[0]; + if (window->getImeInput()->IsImeKeyEvent(ascii, key)) { + return NULL; + } } #endif /* WITH_INPUT_IME */ event = new GHOST_EventKey(system->getMilliSeconds(), - keyDown ? GHOST_kEventKeyDown : GHOST_kEventKeyUp, + key_down ? GHOST_kEventKeyDown : GHOST_kEventKeyUp, window, key, is_repeat, utf8_char); - // GHOST_PRINTF("%c\n", ascii); // we already get this info via EventPrinter +#if 0 /* we already get this info via EventPrinter. */ + GHOST_PRINTF("%c\n", ascii); +#endif } else { event = NULL; @@ -1285,9 +1232,7 @@ GHOST_Event *GHOST_SystemWin32::processWindowSizeEvent(GHOST_WindowWin32 *window system->dispatchEvents(); return NULL; } - else { - return sizeEvent; - } + return sizeEvent; } GHOST_Event *GHOST_SystemWin32::processWindowEvent(GHOST_TEventType type, @@ -1368,54 +1313,53 @@ bool GHOST_SystemWin32::processNDOF(RAWINPUT const &raw) uint64_t now = getMilliSeconds(); static bool firstEvent = true; - if (firstEvent) { // determine exactly which device is plugged in + if (firstEvent) { /* Determine exactly which device is plugged in. */ RID_DEVICE_INFO info; unsigned infoSize = sizeof(RID_DEVICE_INFO); info.cbSize = infoSize; GetRawInputDeviceInfo(raw.header.hDevice, RIDI_DEVICEINFO, &info, &infoSize); - if (info.dwType == RIM_TYPEHID) + if (info.dwType == RIM_TYPEHID) { m_ndofManager->setDevice(info.hid.dwVendorId, info.hid.dwProductId); - else + } + else { GHOST_PRINT("<!> not a HID device... mouse/kb perhaps?\n"); - + } firstEvent = false; } - // The NDOF manager sends button changes immediately, and *pretends* to - // send motion. Mark as 'sent' so motion will always get dispatched. + /* The NDOF manager sends button changes immediately, and *pretends* to + * send motion. Mark as 'sent' so motion will always get dispatched. */ eventSent = true; BYTE const *data = raw.data.hid.bRawData; BYTE packetType = data[0]; switch (packetType) { - case 1: // translation - { + case 1: { /* Translation. */ const short *axis = (short *)(data + 1); - // massage into blender view coords (same goes for rotation) + /* Massage into blender view coords (same goes for rotation). */ const int t[3] = {axis[0], -axis[2], axis[1]}; m_ndofManager->updateTranslation(t, now); if (raw.data.hid.dwSizeHid == 13) { - // this report also includes rotation + /* This report also includes rotation. */ const int r[3] = {-axis[3], axis[5], -axis[4]}; m_ndofManager->updateRotation(r, now); - // I've never gotten one of these, has anyone else? + /* I've never gotten one of these, has anyone else? */ GHOST_PRINT("ndof: combined T + R\n"); } break; } - case 2: // rotation - { + case 2: { /* Rotation. */ + const short *axis = (short *)(data + 1); const int r[3] = {-axis[0], axis[2], -axis[1]}; m_ndofManager->updateRotation(r, now); break; } - case 3: // buttons - { + case 3: { /* Buttons. */ int button_bits; memcpy(&button_bits, data + 1, sizeof(button_bits)); m_ndofManager->updateButtons(button_bits, now); @@ -1424,7 +1368,7 @@ bool GHOST_SystemWin32::processNDOF(RAWINPUT const &raw) } return eventSent; } -#endif // WITH_INPUT_NDOF +#endif /* WITH_INPUT_NDOF */ void GHOST_SystemWin32::driveTrackpad() { @@ -1487,8 +1431,8 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam, if (hwnd) { if (msg == WM_NCCREATE) { - // Tell Windows to automatically handle scaling of non-client areas - // such as the caption bar. EnableNonClientDpiScaling was introduced in Windows 10 + /* Tell Windows to automatically handle scaling of non-client areas + * such as the caption bar. #EnableNonClientDpiScaling was introduced in Windows 10. */ HMODULE m_user32 = ::LoadLibrary("User32.dll"); if (m_user32) { GHOST_WIN32_EnableNonClientDpiScaling fpEnableNonClientDpiScaling = @@ -1503,7 +1447,7 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam, GHOST_WindowWin32 *window = (GHOST_WindowWin32 *)::GetWindowLongPtr(hwnd, GWLP_USERDATA); if (window) { switch (msg) { - // we need to check if new key layout has AltGr + /* We need to check if new key layout has AltGr. */ case WM_INPUTLANGCHANGE: { system->handleKeyboardChange(); #ifdef WITH_INPUT_IME @@ -1512,9 +1456,9 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam, #endif break; } - //////////////////////////////////////////////////////////////////////// - // Keyboard events, processed - //////////////////////////////////////////////////////////////////////// + /* ========================== + * Keyboard events, processed + * ========================== */ case WM_INPUT: { RAWINPUT raw; RAWINPUT *raw_ptr = &raw; @@ -1523,7 +1467,7 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam, GetRawInputData((HRAWINPUT)lParam, RID_INPUT, raw_ptr, &rawSize, sizeof(RAWINPUTHEADER)); switch (raw.header.dwType) { - case RIM_TYPEKEYBOARD: + case RIM_TYPEKEYBOARD: { event = processKeyEvent(window, raw); if (!event) { GHOST_PRINT("GHOST_SystemWin32::wndProc: key event "); @@ -1531,20 +1475,22 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam, GHOST_PRINT(" key ignored\n"); } break; + } #ifdef WITH_INPUT_NDOF - case RIM_TYPEHID: + case RIM_TYPEHID: { if (system->processNDOF(raw)) { eventHandled = true; } break; + } #endif } break; } #ifdef WITH_INPUT_IME - //////////////////////////////////////////////////////////////////////// - // IME events, processed, read more in GHOST_IME.h - //////////////////////////////////////////////////////////////////////// + /* ================================================= + * IME events, processed, read more in `GHOST_IME.h` + * ================================================= */ case WM_IME_NOTIFY: { /* Update conversion status when IME is changed or input mode is changed. */ if (wParam == IMN_SETOPENSTATUS || wParam == IMN_SETCONVERSIONMODE) { @@ -1592,56 +1538,53 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam, break; } #endif /* WITH_INPUT_IME */ - //////////////////////////////////////////////////////////////////////// - // Keyboard events, ignored - //////////////////////////////////////////////////////////////////////// + /* ======================== + * Keyboard events, ignored + * ======================== */ case WM_KEYDOWN: case WM_SYSKEYDOWN: case WM_KEYUP: case WM_SYSKEYUP: - /* These functions were replaced by #WM_INPUT. */ + /* These functions were replaced by #WM_INPUT. */ case WM_CHAR: - /* The WM_CHAR message is posted to the window with the keyboard focus when - * a WM_KEYDOWN message is translated by the TranslateMessage function. WM_CHAR - * contains the character code of the key that was pressed. - */ + /* The #WM_CHAR message is posted to the window with the keyboard focus when + * a WM_KEYDOWN message is translated by the #TranslateMessage function. + * WM_CHAR contains the character code of the key that was pressed. */ case WM_DEADCHAR: - /* The WM_DEADCHAR message is posted to the window with the keyboard focus when a - * WM_KEYUP message is translated by the TranslateMessage function. WM_DEADCHAR + /* The #WM_DEADCHAR message is posted to the window with the keyboard focus when a + * WM_KEYUP message is translated by the #TranslateMessage function. WM_DEADCHAR * specifies a character code generated by a dead key. A dead key is a key that * generates a character, such as the umlaut (double-dot), that is combined with * another character to form a composite character. For example, the umlaut-O * character (Ö) is generated by typing the dead key for the umlaut character, and - * then typing the O key. - */ + * then typing the O key. */ break; case WM_SYSDEADCHAR: - /* The WM_SYSDEADCHAR message is sent to the window with the keyboard focus when - * a WM_SYSKEYDOWN message is translated by the TranslateMessage function. - * WM_SYSDEADCHAR specifies the character code of a system dead key - that is, - * a dead key that is pressed while holding down the alt key. - */ - case WM_SYSCHAR: - /* The WM_SYSCHAR message is sent to the window with the keyboard focus when - * a WM_SYSCHAR message is translated by the TranslateMessage function. + /* The #WM_SYSDEADCHAR message is sent to the window with the keyboard focus when + * a WM_SYSKEYDOWN message is translated by the #TranslateMessage function. + * WM_SYSDEADCHAR specifies the character code of a system dead key - that is, + * a dead key that is pressed while holding down the alt key. */ + case WM_SYSCHAR: { + /* #The WM_SYSCHAR message is sent to the window with the keyboard focus when + * a WM_SYSCHAR message is translated by the #TranslateMessage function. * WM_SYSCHAR specifies the character code of a dead key - that is, * a dead key that is pressed while holding down the alt key. - * To prevent the sound, DefWindowProc must be avoided by return - */ + * To prevent the sound, #DefWindowProc must be avoided by return. */ break; - case WM_SYSCOMMAND: - /* The WM_SYSCOMMAND message is sent to the window when system commands such as + } + case WM_SYSCOMMAND: { + /* The #WM_SYSCOMMAND message is sent to the window when system commands such as * maximize, minimize or close the window are triggered. Also it is sent when ALT - * button is press for menu. To prevent this we must return preventing DefWindowProc. + * button is press for menu. To prevent this we must return preventing #DefWindowProc. * * Note that the four low-order bits of the wParam parameter are used internally by the * OS. To obtain the correct result when testing the value of wParam, an application must - * combine the value 0xFFF0 with the wParam value by using the bit-wise AND operator. - */ + * combine the value 0xFFF0 with the wParam value by using the bit-wise AND operator. */ switch (wParam & 0xFFF0) { - case SC_KEYMENU: + case SC_KEYMENU: { eventHandled = true; break; + } case SC_RESTORE: { ::ShowWindow(hwnd, SW_RESTORE); window->setState(window->getState()); @@ -1672,9 +1615,10 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam, } } break; - //////////////////////////////////////////////////////////////////////// - // Wintab events, processed - //////////////////////////////////////////////////////////////////////// + } + /* ======================== + * Wintab events, processed + * ======================== */ case WT_CSRCHANGE: { WINTAB_PRINTF("HWND %p HCTX %p WT_CSRCHANGE\n", window->getHWND(), (void *)lParam); GHOST_Wintab *wt = window->getWintab(); @@ -1726,44 +1670,53 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam, eventHandled = true; break; } - case WT_PACKET: + case WT_PACKET: { processWintabEvent(window); eventHandled = true; break; - //////////////////////////////////////////////////////////////////////// - // Wintab events, debug - //////////////////////////////////////////////////////////////////////// - case WT_CTXOPEN: + } + /* ==================== + * Wintab events, debug + * ==================== */ + case WT_CTXOPEN: { WINTAB_PRINTF("HWND %p HCTX %p WT_CTXOPEN\n", window->getHWND(), (void *)wParam); break; - case WT_CTXCLOSE: + } + case WT_CTXCLOSE: { WINTAB_PRINTF("HWND %p HCTX %p WT_CTXCLOSE\n", window->getHWND(), (void *)wParam); break; - case WT_CTXUPDATE: + } + case WT_CTXUPDATE: { WINTAB_PRINTF("HWND %p HCTX %p WT_CTXUPDATE\n", window->getHWND(), (void *)wParam); break; - case WT_CTXOVERLAP: + } + case WT_CTXOVERLAP: { WINTAB_PRINTF("HWND %p HCTX %p WT_CTXOVERLAP", window->getHWND(), (void *)wParam); switch (lParam) { - case CXS_DISABLED: + case CXS_DISABLED: { WINTAB_PRINTF(" CXS_DISABLED\n"); break; - case CXS_OBSCURED: + } + case CXS_OBSCURED: { WINTAB_PRINTF(" CXS_OBSCURED\n"); break; - case CXS_ONTOP: + } + case CXS_ONTOP: { WINTAB_PRINTF(" CXS_ONTOP\n"); break; + } } break; - //////////////////////////////////////////////////////////////////////// - // Pointer events, processed - //////////////////////////////////////////////////////////////////////// + } + /* ========================= + * Pointer events, processed + * ========================= */ case WM_POINTERUPDATE: case WM_POINTERDOWN: - case WM_POINTERUP: + case WM_POINTERUP: { processPointerEvent(msg, window, wParam, lParam, eventHandled); break; + } case WM_POINTERLEAVE: { uint32_t pointerId = GET_POINTERID_WPARAM(wParam); POINTER_INFO pointerInfo; @@ -1778,19 +1731,22 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam, } break; } - //////////////////////////////////////////////////////////////////////// - // Mouse events, processed - //////////////////////////////////////////////////////////////////////// - case WM_LBUTTONDOWN: + /* ======================= + * Mouse events, processed + * ======================= */ + case WM_LBUTTONDOWN: { event = processButtonEvent(GHOST_kEventButtonDown, window, GHOST_kButtonMaskLeft); break; - case WM_MBUTTONDOWN: + } + case WM_MBUTTONDOWN: { event = processButtonEvent(GHOST_kEventButtonDown, window, GHOST_kButtonMaskMiddle); break; - case WM_RBUTTONDOWN: + } + case WM_RBUTTONDOWN: { event = processButtonEvent(GHOST_kEventButtonDown, window, GHOST_kButtonMaskRight); break; - case WM_XBUTTONDOWN: + } + case WM_XBUTTONDOWN: { if ((short)HIWORD(wParam) == XBUTTON1) { event = processButtonEvent(GHOST_kEventButtonDown, window, GHOST_kButtonMaskButton4); } @@ -1798,16 +1754,20 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam, event = processButtonEvent(GHOST_kEventButtonDown, window, GHOST_kButtonMaskButton5); } break; - case WM_LBUTTONUP: + } + case WM_LBUTTONUP: { event = processButtonEvent(GHOST_kEventButtonUp, window, GHOST_kButtonMaskLeft); break; - case WM_MBUTTONUP: + } + case WM_MBUTTONUP: { event = processButtonEvent(GHOST_kEventButtonUp, window, GHOST_kButtonMaskMiddle); break; - case WM_RBUTTONUP: + } + case WM_RBUTTONUP: { event = processButtonEvent(GHOST_kEventButtonUp, window, GHOST_kButtonMaskRight); break; - case WM_XBUTTONUP: + } + case WM_XBUTTONUP: { if ((short)HIWORD(wParam) == XBUTTON1) { event = processButtonEvent(GHOST_kEventButtonUp, window, GHOST_kButtonMaskButton4); } @@ -1815,7 +1775,8 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam, event = processButtonEvent(GHOST_kEventButtonUp, window, GHOST_kButtonMaskButton5); } break; - case WM_MOUSEMOVE: + } + case WM_MOUSEMOVE: { if (!window->m_mousePresent) { WINTAB_PRINTF("HWND %p mouse enter\n", window->getHWND()); TRACKMOUSEEVENT tme = {sizeof(tme)}; @@ -1832,6 +1793,7 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam, event = processCursorEvent(window); break; + } case WM_MOUSEWHEEL: { /* The WM_MOUSEWHEEL message is sent to the focus window * when the mouse wheel is rotated. The DefWindowProc @@ -1847,7 +1809,7 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam, #endif break; } - case WM_SETCURSOR: + case WM_SETCURSOR: { /* The WM_SETCURSOR message is sent to a window if the mouse causes the cursor * to move within a window and mouse input is not captured. * This means we have to set the cursor shape every time the mouse moves! @@ -1855,16 +1817,17 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam, * arrow if it is not in the client area. */ if (LOWORD(lParam) == HTCLIENT) { - // Load the current cursor + /* Load the current cursor. */ window->loadCursor(window->getCursorVisibility(), window->getCursorShape()); - // Bypass call to DefWindowProc + /* Bypass call to #DefWindowProc. */ return 0; } else { - // Outside of client area show standard cursor + /* Outside of client area show standard cursor. */ window->loadCursor(true, GHOST_kStandardCursorDefault); } break; + } case WM_MOUSELEAVE: { WINTAB_PRINTF("HWND %p mouse leave\n", window->getHWND()); window->m_mousePresent = false; @@ -1877,26 +1840,27 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam, } break; } - //////////////////////////////////////////////////////////////////////// - // Mouse events, ignored - //////////////////////////////////////////////////////////////////////// - case WM_NCMOUSEMOVE: - /* The WM_NCMOUSEMOVE message is posted to a window when the cursor is moved - * within the non-client area of the window. This message is posted to the window that - * contains the cursor. If a window has captured the mouse, this message is not posted. - */ - case WM_NCHITTEST: + /* ===================== + * Mouse events, ignored + * ===================== */ + case WM_NCMOUSEMOVE: { + /* The WM_NCMOUSEMOVE message is posted to a window when the cursor is moved + * within the non-client area of the window. This message is posted to the window that + * contains the cursor. If a window has captured the mouse, this message is not posted. + */ + } + case WM_NCHITTEST: { /* The WM_NCHITTEST message is sent to a window when the cursor moves, or * when a mouse button is pressed or released. If the mouse is not captured, * the message is sent to the window beneath the cursor. Otherwise, the message * is sent to the window that has captured the mouse. */ break; - - //////////////////////////////////////////////////////////////////////// - // Window events, processed - //////////////////////////////////////////////////////////////////////// - case WM_CLOSE: + } + /* ======================== + * Window events, processed + * ======================== */ + case WM_CLOSE: { /* The WM_CLOSE message is sent as a signal that a window * or an application should terminate. Restore if minimized. */ if (IsIconic(hwnd)) { @@ -1904,31 +1868,29 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam, } event = processWindowEvent(GHOST_kEventWindowClose, window); break; - case WM_ACTIVATE: + } + case WM_ACTIVATE: { /* The WM_ACTIVATE message is sent to both the window being activated and the window * being deactivated. If the windows use the same input queue, the message is sent * synchronously, first to the window procedure of the top-level window being * deactivated, then to the window procedure of the top-level window being activated. * If the windows use different input queues, the message is sent asynchronously, * so the window is activated immediately. */ - { - GHOST_ModifierKeys modifiers; - modifiers.clear(); - system->storeModifierKeys(modifiers); - system->m_wheelDeltaAccum = 0; - system->m_keycode_last_repeat_key = 0; - 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. */ - if (LOWORD(wParam) == WA_INACTIVE) - window->lostMouseCapture(); - - lResult = ::DefWindowProc(hwnd, msg, wParam, lParam); - break; + + system->m_wheelDeltaAccum = 0; + system->m_keycode_last_repeat_key = 0; + 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. */ + if (LOWORD(wParam) == WA_INACTIVE) { + window->lostMouseCapture(); } - case WM_ENTERSIZEMOVE: + + lResult = ::DefWindowProc(hwnd, msg, wParam, lParam); + break; + } + case WM_ENTERSIZEMOVE: { /* The WM_ENTERSIZEMOVE message is sent one time to a window after it enters the moving * or sizing modal loop. The window enters the moving or sizing modal loop when the user * clicks the window's title bar or sizing border, or when the window passes the @@ -1938,10 +1900,12 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam, */ window->m_inLiveResize = 1; break; - case WM_EXITSIZEMOVE: + } + case WM_EXITSIZEMOVE: { window->m_inLiveResize = 0; break; - case WM_PAINT: + } + case 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 @@ -1956,7 +1920,8 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam, eventHandled = true; } break; - case WM_GETMINMAXINFO: + } + case WM_GETMINMAXINFO: { /* The WM_GETMINMAXINFO message is sent to a window when the size or * position of the window is about to change. An application can use * this message to override the window's default maximized size and @@ -1965,10 +1930,12 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam, processMinMaxInfo((MINMAXINFO *)lParam); /* Let DefWindowProc handle it. */ break; - case WM_SIZING: + } + case WM_SIZING: { event = processWindowSizeEvent(window); break; - case WM_SIZE: + } + case WM_SIZE: { /* The WM_SIZE message is sent to a window after its size has changed. * The WM_SIZE and WM_MOVE messages are not sent if an application handles the * WM_WINDOWPOSCHANGED message without calling DefWindowProc. It is more efficient @@ -1977,15 +1944,17 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam, */ event = processWindowSizeEvent(window); break; - case WM_CAPTURECHANGED: + } + case WM_CAPTURECHANGED: { window->lostMouseCapture(); break; + } case WM_MOVING: /* The WM_MOVING message is sent to a window that the user is moving. By processing * this message, an application can monitor the size and position of the drag rectangle * and, if needed, change its size or position. */ - case WM_MOVE: + case WM_MOVE: { /* The WM_SIZE and WM_MOVE messages are not sent if an application handles the * WM_WINDOWPOSCHANGED message without calling DefWindowProc. It is more efficient * to perform any move or size change processing during the WM_WINDOWPOSCHANGED @@ -2001,33 +1970,33 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam, } break; - case WM_DPICHANGED: + } + case WM_DPICHANGED: { /* The WM_DPICHANGED message is sent when the effective dots per inch (dpi) for a * window has changed. The DPI is the scale factor for a window. There are multiple * events that can cause the DPI to change such as when the window is moved to a monitor - * with a different DPI. - */ - { - // The suggested new size and position of the window. - RECT *const suggestedWindowRect = (RECT *)lParam; + * with a different DPI. */ - // Push DPI change event first - system->pushEvent(processWindowEvent(GHOST_kEventWindowDPIHintChanged, window)); - system->dispatchEvents(); - eventHandled = true; + /* The suggested new size and position of the window. */ + RECT *const suggestedWindowRect = (RECT *)lParam; - // Then move and resize window - SetWindowPos(hwnd, - NULL, - suggestedWindowRect->left, - suggestedWindowRect->top, - suggestedWindowRect->right - suggestedWindowRect->left, - suggestedWindowRect->bottom - suggestedWindowRect->top, - SWP_NOZORDER | SWP_NOACTIVATE); + /* Push DPI change event first. */ + system->pushEvent(processWindowEvent(GHOST_kEventWindowDPIHintChanged, window)); + system->dispatchEvents(); + eventHandled = true; - window->updateDPI(); - } + /* Then move and resize window. */ + SetWindowPos(hwnd, + NULL, + suggestedWindowRect->left, + suggestedWindowRect->top, + suggestedWindowRect->right - suggestedWindowRect->left, + suggestedWindowRect->bottom - suggestedWindowRect->top, + SWP_NOZORDER | SWP_NOACTIVATE); + + window->updateDPI(); break; + } case WM_DISPLAYCHANGE: { GHOST_Wintab *wt = window->getWintab(); if (wt) { @@ -2035,7 +2004,7 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam, } break; } - case WM_KILLFOCUS: + case WM_KILLFOCUS: { /* The WM_KILLFOCUS message is sent to a window immediately before it loses the keyboard * focus. We want to prevent this if a window is still active and it loses focus to * nowhere. */ @@ -2043,73 +2012,73 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam, ::SetFocus(hwnd); } break; - case WM_SETTINGCHANGE: + } + case WM_SETTINGCHANGE: { /* Microsoft: "Note that some applications send this message with lParam set to NULL" */ if ((lParam != NULL) && (wcscmp(LPCWSTR(lParam), L"ImmersiveColorSet") == 0)) { window->ThemeRefresh(); } break; - //////////////////////////////////////////////////////////////////////// - // Window events, ignored - //////////////////////////////////////////////////////////////////////// + } + /* ====================== + * Window events, ignored + * ====================== */ case WM_WINDOWPOSCHANGED: - /* The WM_WINDOWPOSCHANGED message is sent to a window whose size, position, or place - * in the Z order has changed as a result of a call to the SetWindowPos function or - * another window-management function. - * The WM_SIZE and WM_MOVE messages are not sent if an application handles the - * WM_WINDOWPOSCHANGED message without calling DefWindowProc. It is more efficient - * to perform any move or size change processing during the WM_WINDOWPOSCHANGED - * message without calling DefWindowProc. - */ + /* The WM_WINDOWPOSCHANGED message is sent to a window whose size, position, or place + * in the Z order has changed as a result of a call to the SetWindowPos function or + * another window-management function. + * The WM_SIZE and WM_MOVE messages are not sent if an application handles the + * WM_WINDOWPOSCHANGED message without calling DefWindowProc. It is more efficient + * to perform any move or size change processing during the WM_WINDOWPOSCHANGED + * message without calling DefWindowProc. + */ case WM_ERASEBKGND: - /* An application sends the WM_ERASEBKGND message when the window background must be - * erased (for example, when a window is resized). The message is sent to prepare an - * invalidated portion of a window for painting. - */ + /* An application sends the WM_ERASEBKGND message when the window background must be + * erased (for example, when a window is resized). The message is sent to prepare an + * invalidated portion of a window for painting. */ case WM_NCPAINT: - /* An application sends the WM_NCPAINT message to a window - * when its frame must be painted. */ + /* An application sends the WM_NCPAINT message to a window + * when its frame must be painted. */ case WM_NCACTIVATE: - /* The WM_NCACTIVATE message is sent to a window when its non-client area needs to be - * changed to indicate an active or inactive state. */ + /* The WM_NCACTIVATE message is sent to a window when its non-client area needs to be + * changed to indicate an active or inactive state. */ case WM_DESTROY: - /* The WM_DESTROY message is sent when a window is being destroyed. It is sent to the - * window procedure of the window being destroyed after the window is removed from the - * screen. This message is sent first to the window being destroyed and then to the child - * windows (if any) as they are destroyed. During the processing of the message, it can - * be assumed that all child windows still exist. */ - case WM_NCDESTROY: + /* The WM_DESTROY message is sent when a window is being destroyed. It is sent to the + * window procedure of the window being destroyed after the window is removed from the + * screen. This message is sent first to the window being destroyed and then to the child + * windows (if any) as they are destroyed. During the processing of the message, it can + * be assumed that all child windows still exist. */ + case WM_NCDESTROY: { /* The WM_NCDESTROY message informs a window that its non-client area is being * destroyed. The DestroyWindow function sends the WM_NCDESTROY message to the window * following the WM_DESTROY message. WM_DESTROY is used to free the allocated memory * object associated with the window. */ break; + } case WM_SHOWWINDOW: - /* The WM_SHOWWINDOW message is sent to a window when the window is - * about to be hidden or shown. */ + /* The WM_SHOWWINDOW message is sent to a window when the window is + * about to be hidden or shown. */ case WM_WINDOWPOSCHANGING: - /* The WM_WINDOWPOSCHANGING message is sent to a window whose size, position, or place in - * the Z order is about to change as a result of a call to the SetWindowPos function or - * another window-management function. - */ - case WM_SETFOCUS: + /* The WM_WINDOWPOSCHANGING message is sent to a window whose size, position, or place in + * the Z order is about to change as a result of a call to the SetWindowPos function or + * another window-management function. */ + case WM_SETFOCUS: { /* The WM_SETFOCUS message is sent to a window after it has gained the keyboard focus. */ break; - //////////////////////////////////////////////////////////////////////// - // Other events - //////////////////////////////////////////////////////////////////////// + } + /* ============ + * Other events + * ============ */ case WM_GETTEXT: - /* An application sends a WM_GETTEXT message to copy the text that - * corresponds to a window into a buffer provided by the caller. - */ + /* An application sends a WM_GETTEXT message to copy the text that + * corresponds to a window into a buffer provided by the caller. */ case WM_ACTIVATEAPP: - /* The WM_ACTIVATEAPP message is sent when a window belonging to a - * different application than the active window is about to be activated. - * The message is sent to the application whose window is being activated - * and to the application whose window is being deactivated. - */ - case WM_TIMER: + /* The WM_ACTIVATEAPP message is sent when a window belonging to a + * different application than the active window is about to be activated. + * The message is sent to the application whose window is being activated + * and to the application whose window is being deactivated. */ + case WM_TIMER: { /* The WIN32 docs say: * The WM_TIMER message is posted to the installing thread's message queue * when a timer expires. You can process the message by providing a WM_TIMER @@ -2117,19 +2086,20 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam, * call the TimerProc callback function specified in the call to the SetTimer * function used to install the timer. * - * In GHOST, we let DefWindowProc call the timer callback. - */ + * In GHOST, we let DefWindowProc call the timer callback. */ break; - case DM_POINTERHITTEST: + } + case DM_POINTERHITTEST: { /* The DM_POINTERHITTEST message is sent to a window, when pointer input is first * detected, in order to determine the most probable input target for Direct * Manipulation. */ window->onPointerHitTest(wParam); break; + } } } else { - // Event found for a window before the pointer to the class has been set. + /* 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 @@ -2141,7 +2111,7 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam, } } else { - // Events without valid hwnd + /* Events without valid `hwnd`. */ GHOST_PRINT("GHOST_SystemWin32::wndProc: event without window\n"); } @@ -2150,16 +2120,15 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam, eventHandled = true; } - if (!eventHandled) + if (!eventHandled) { lResult = ::DefWindowProcW(hwnd, msg, wParam, lParam); + } return lResult; } char *GHOST_SystemWin32::getClipboard(bool selection) const { - char *temp_buff; - if (IsClipboardFormatAvailable(CF_UNICODETEXT) && OpenClipboard(NULL)) { wchar_t *buffer; HANDLE hData = GetClipboardData(CF_UNICODETEXT); @@ -2173,7 +2142,7 @@ char *GHOST_SystemWin32::getClipboard(bool selection) const return NULL; } - temp_buff = alloc_utf_8_from_16(buffer, 0); + char *temp_buff = alloc_utf_8_from_16(buffer, 0); /* Buffer mustn't be accessed after CloseClipboard * it would like accessing free-d memory */ @@ -2182,7 +2151,7 @@ char *GHOST_SystemWin32::getClipboard(bool selection) const return temp_buff; } - else if (IsClipboardFormatAvailable(CF_TEXT) && OpenClipboard(NULL)) { + if (IsClipboardFormatAvailable(CF_TEXT) && OpenClipboard(NULL)) { char *buffer; size_t len = 0; HANDLE hData = GetClipboardData(CF_TEXT); @@ -2197,7 +2166,7 @@ char *GHOST_SystemWin32::getClipboard(bool selection) const } len = strlen(buffer); - temp_buff = (char *)malloc(len + 1); + char *temp_buff = (char *)malloc(len + 1); strncpy(temp_buff, buffer, len); temp_buff[len] = '\0'; @@ -2208,21 +2177,19 @@ char *GHOST_SystemWin32::getClipboard(bool selection) const return temp_buff; } - else { - return NULL; - } + return nullptr; } void GHOST_SystemWin32::putClipboard(const char *buffer, bool selection) const { if (selection || !buffer) { return; - } // for copying the selection, used on X11 + } /* For copying the selection, used on X11. */ if (OpenClipboard(NULL)) { EmptyClipboard(); - // Get length of buffer including the terminating null + /* Get length of buffer including the terminating null. */ size_t len = count_utf_16_from_8(buffer); HGLOBAL clipbuffer = GlobalAlloc(GMEM_MOVEABLE, sizeof(wchar_t) * len); @@ -2279,7 +2246,7 @@ GHOST_TSuccess GHOST_SystemWin32::showMessageBox(const char *title, case IDCONTINUE: break; default: - break; // should never happen + break; /* Should never happen. */ } free((void *)title_16); @@ -2347,14 +2314,15 @@ static bool isStartedFromCommandPrompt() } /* When we're starting from a wrapper we need to compare with parent process ID. */ - if (pid != (start_from_launcher ? ppid : GetCurrentProcessId())) + if (pid != (start_from_launcher ? ppid : GetCurrentProcessId())) { return true; + } } return false; } -int GHOST_SystemWin32::setConsoleWindowState(GHOST_TConsoleWindowState action) +bool GHOST_SystemWin32::setConsoleWindowState(GHOST_TConsoleWindowState action) { HWND wnd = GetConsoleWindow(); @@ -2362,28 +2330,31 @@ int GHOST_SystemWin32::setConsoleWindowState(GHOST_TConsoleWindowState action) case GHOST_kConsoleWindowStateHideForNonConsoleLaunch: { if (!isStartedFromCommandPrompt()) { ShowWindow(wnd, SW_HIDE); - m_consoleStatus = 0; + m_consoleStatus = false; } break; } - case GHOST_kConsoleWindowStateHide: + case GHOST_kConsoleWindowStateHide: { ShowWindow(wnd, SW_HIDE); - m_consoleStatus = 0; + m_consoleStatus = false; break; - case GHOST_kConsoleWindowStateShow: + } + case GHOST_kConsoleWindowStateShow: { ShowWindow(wnd, SW_SHOW); if (!isStartedFromCommandPrompt()) { DeleteMenu(GetSystemMenu(wnd, FALSE), SC_CLOSE, MF_BYCOMMAND); } - m_consoleStatus = 1; + m_consoleStatus = true; break; - case GHOST_kConsoleWindowStateToggle: + } + case GHOST_kConsoleWindowStateToggle: { ShowWindow(wnd, m_consoleStatus ? SW_HIDE : SW_SHOW); m_consoleStatus = !m_consoleStatus; if (m_consoleStatus && !isStartedFromCommandPrompt()) { DeleteMenu(GetSystemMenu(wnd, FALSE), SC_CLOSE, MF_BYCOMMAND); } break; + } } return m_consoleStatus; |