/** Check if specified LED states correspond to the system modifier states. */ bool winHidLedsInSync(bool fNumLockOn, bool fCapsLockOn, bool fScrollLockOn) { if (winGetModifierState(VK_NUMLOCK) != fNumLockOn) return false; if (winGetModifierState(VK_CAPITAL) != fCapsLockOn) return false; if (winGetModifierState(VK_SCROLL) != fScrollLockOn) return false; return true; }
/** * Set current state of a keyboard modifier. * * @param idModifier Modifier to set (VK_CAPITAL, VK_SCROLL or VK_NUMLOCK) * @param fState State to set */ static void winSetModifierState(int idModifier, bool fState) { AssertReturnVoid((idModifier == VK_CAPITAL) || (idModifier == VK_SCROLL) || (idModifier == VK_NUMLOCK)); /* If the modifier is already in desired state, just do nothing. Otherwise, toggle it. */ if (winGetModifierState(idModifier) != fState) { /* Simulate KeyUp+KeyDown keystroke */ keybd_event(idModifier, 0, KEYEVENTF_EXTENDEDKEY, 0); keybd_event(idModifier, 0, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0); /* Process posted above keyboard events immediately: */ MSG msg; while (::PeekMessage(&msg, NULL, WM_KEYFIRST, WM_KEYLAST, PM_REMOVE)) ::DispatchMessage(&msg); LogRel2(("HID LEDs sync: setting %s state to %s (0x%X).\n", VBOX_CONTROL_TO_STR_NAME(idModifier), VBOX_BOOL_TO_STR_STATE(fState), MapVirtualKey(idModifier, MAPVK_VK_TO_VSC))); } else { LogRel2(("HID LEDs sync: setting %s state: skipped: state is already %s (0x%X).\n", VBOX_CONTROL_TO_STR_NAME(idModifier), VBOX_BOOL_TO_STR_STATE(fState), MapVirtualKey(idModifier, MAPVK_VK_TO_VSC))); } }
/** * Allocate memory and store modifier states there. * * @returns allocated memory witch contains modifier states or NULL. */ void * WinHidDevicesKeepLedsState(void) { VBoxModifiersState_t *pState; pState = (VBoxModifiersState_t *)malloc(sizeof(VBoxModifiersState_t)); if (pState) { pState->fNumLockOn = winGetModifierState(VK_NUMLOCK); pState->fCapsLockOn = winGetModifierState(VK_CAPITAL); pState->fScrollLockOn = winGetModifierState(VK_SCROLL); LogRel2(("HID LEDs sync: host state captured: NUM(%s) CAPS(%s) SCROLL(%s)\n", VBOX_BOOL_TO_STR_STATE(pState->fNumLockOn), VBOX_BOOL_TO_STR_STATE(pState->fCapsLockOn), VBOX_BOOL_TO_STR_STATE(pState->fScrollLockOn))); return (void *)pState; } LogRel2(("HID LEDs sync: unable to allocate memory for HID LEDs synchronization data. LEDs sync will be disabled.\n")); return NULL; }
/** * Set current state of a keyboard modifier. * * @param idModifier Modifier to set (VK_CAPITAL, VK_SCROLL or VK_NUMLOCK) * @param fState State to set */ static void winSetModifierState(int idModifier, bool fState) { AssertReturnVoid((idModifier == VK_CAPITAL) || (idModifier == VK_SCROLL) || (idModifier == VK_NUMLOCK)); /* If the modifier is already in desired state, just do nothing. Otherwise, toggle it. */ if (winGetModifierState(idModifier) != fState) { /* Simulate KeyUp+KeyDown keystroke */ keybd_event(idModifier, 0, KEYEVENTF_EXTENDEDKEY, 0); keybd_event(idModifier, 0, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0); LogRel2(("HID LEDs sync: setting %s state to %s (0x%X).\n", VBOX_CONTROL_TO_STR_NAME(idModifier), VBOX_BOOL_TO_STR_STATE(fState), MapVirtualKey(idModifier, MAPVK_VK_TO_VSC))); } else { LogRel2(("HID LEDs sync: setting %s state: skipped: state is already %s (0x%X).\n", VBOX_CONTROL_TO_STR_NAME(idModifier), VBOX_BOOL_TO_STR_STATE(fState), MapVirtualKey(idModifier, MAPVK_VK_TO_VSC))); } }