LilyPad: "WM Keyboard" now actually uses GetAsyncKeyState(). Just simplifies some dependencies on the window thread. Note that WM Mouse and raw input still have those dependencies, and they can't really be worked around, unfortunately.

Also, just for kicks, made pausing while pressing "escape" check the pause button in the menu.

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1891 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
mattmenke 2009-09-20 10:48:22 +00:00
parent 712e5e9229
commit 705ca3d92a
15 changed files with 171 additions and 211 deletions

View File

@ -63,6 +63,7 @@ void Pcsx2App::OnEmuKeyDown( wxKeyEvent& evt )
switch( evt.GetKeyCode() )
{
case WXK_ESCAPE:
GetMainFrame().GetMenuBar()->Check( MenuId_Emu_Pause, true );
m_CoreThread->Suspend();
break;

View File

@ -154,8 +154,9 @@ void RefreshEnabledDevices(int updateDeviceList) {
dm->EnableDevice(i);
}
}
else
dm->DisableDevice(i);
else {
dm->DisableDevice(i);
}
}
}
@ -1278,7 +1279,7 @@ INT_PTR CALLBACK DialogProc(HWND hWnd, unsigned int msg, WPARAM wParam, LPARAM l
else {
unsigned int uid;
int value;
InitInfo info = {selected==0x7F, hWndProp, hWnd, GetDlgItem(hWnd, selected)};
InitInfo info = {selected==0x7F, 1, hWndProp, hWnd, GetDlgItem(hWnd, selected)};
Device *dev = dm->GetActiveDevice(&info, &uid, &index, &value);
if (dev) {
int command = selected;
@ -1482,7 +1483,7 @@ INT_PTR CALLBACK DialogProc(HWND hWnd, unsigned int msg, WPARAM wParam, LPARAM l
if (selIndex >= 0) {
if (GetBinding(port, slot, selIndex, dev, b, ffb)) {
selected = 0xFF;
InitInfo info = {0, hWndProp, hWnd, GetDlgItem(hWnd, cmd)};
InitInfo info = {0, 1, hWndProp, hWnd, GetDlgItem(hWnd, cmd)};
EatWndProc(info.hWndButton, DoNothingWndProc, 0);
for (int i=0; i<dm->numDevices; i++) {
if (dm->devices[i] != dev) {
@ -1519,7 +1520,7 @@ INT_PTR CALLBACK DialogProc(HWND hWnd, unsigned int msg, WPARAM wParam, LPARAM l
}
}
InitInfo info = {selected==0x7F, hWndProp, hWnd, GetDlgItem(hWnd, cmd)};
InitInfo info = {selected==0x7F, 1, hWndProp, hWnd, GetDlgItem(hWnd, cmd)};
EatWndProc(info.hWndButton, DoNothingWndProc, 0);
int w = timeGetTime();
dm->Update(&info);

View File

@ -1,13 +1,2 @@
// Shouldn't really be here, but not sure where else to put it.
struct InitInfo {
// 1 when binding key to ignore.
int bindingIgnore;
HWND hWndTop;
HWND hWnd;
// For config screen, need to eat button's message handling.
HWND hWndButton;
};
void EnumDevices(int hideDXXinput);

View File

@ -36,7 +36,7 @@ INT_PTR CALLBACK DiagDialog(HWND hWnd, unsigned int uMsg, WPARAM wParam, LPARAM
//break;
case WM_TIMER:
{
InitInfo info = {0, hWnd, hWnd, hWndList};
InitInfo info = {0, 1, hWnd, hWnd, hWndList};
dm->Update(&info);
LVITEMW item;
item.mask = LVIF_TEXT;

View File

@ -155,7 +155,7 @@ public:
}
}
int Activate(void *d) {
int Activate(InitInfo *initInfo) {
int i;
IDirectInput8 *di8 = GetDirectInput();
Deactivate();
@ -208,16 +208,15 @@ public:
}
free(formats);
}
InitInfo *info = (InitInfo*)d;
// Note: Have to use hWndTop to properly hide cursor for mouse device.
if (type == OTHER) {
did->SetCooperativeLevel(info->hWndTop, DISCL_BACKGROUND | DISCL_EXCLUSIVE);
did->SetCooperativeLevel(initInfo->hWndTop, DISCL_BACKGROUND | DISCL_EXCLUSIVE);
}
else if (type == KEYBOARD) {
did->SetCooperativeLevel(info->hWndTop, DISCL_FOREGROUND);
did->SetCooperativeLevel(initInfo->hWndTop, DISCL_FOREGROUND);
}
else {
did->SetCooperativeLevel(info->hWndTop, DISCL_FOREGROUND | DISCL_EXCLUSIVE);
did->SetCooperativeLevel(initInfo->hWndTop, DISCL_FOREGROUND | DISCL_EXCLUSIVE);
}
if (did->Acquire() != DI_OK) {
did->Release();

View File

@ -286,7 +286,7 @@ public:
return Device::GetPhysicalControlName(c);
}
int Activate(void *d) {
int Activate(InitInfo *initInfo) {
if (active) Deactivate();
// Give grace period before get mad.
lastWrite = dataLastReceived = GetTickCount();

View File

@ -29,7 +29,16 @@
#include <windows.h>
#ifdef PCSX2_DEBUG
#define _CRTDBG_MAPALLOC
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#else
#include <stdlib.h>
#endif
#include <stdio.h>
#include <string.h>
#include <math.h>

View File

@ -347,7 +347,7 @@ void InputDeviceManager::AddDevice(Device *d) {
devices[numDevices++] = d;
}
void InputDeviceManager::Update(void *info) {
void InputDeviceManager::Update(InitInfo *info) {
for (int i=0; i<numDevices; i++) {
if (devices[i]->enabled) {
if (!devices[i]->active) {
@ -368,7 +368,7 @@ void InputDeviceManager::PostRead() {
}
}
Device *InputDeviceManager::GetActiveDevice(void *info, unsigned int *uid, int *index, int *value) {
Device *InputDeviceManager::GetActiveDevice(InitInfo *info, unsigned int *uid, int *index, int *value) {
int i, j;
Update(info);
int bestDiff = FULLY_DOWN/2;

View File

@ -149,19 +149,12 @@ struct ForceFeedbackAxis {
int id;
};
// Note: Unbound controls don't need to be listed, though they can be.
// Nonexistent controls can be listed as well (Like listing 5 buttons
// even for three button mice, as some APIs make it impossible to figure
// out which buttons you really have).
// Used both for active devices and for sets of settings for devices.
// Way things work:
// LoadSettings() will delete all device info, then load settings to get
// one set of generic devices. Then I enumerate all devices. Then I merge
// them, moving settings from the generic devices to the enumerated ones.
// Can't refresh without loading settings.
struct PadBindings {
Binding *bindings;
int numBindings;
@ -169,6 +162,19 @@ struct PadBindings {
int numFFBindings;
};
struct InitInfo {
// 1 when binding key to ignore.
int bindingIgnore;
// 1 when binding.
int binding;
HWND hWndTop;
HWND hWnd;
// For config screen, need to eat button's message handling.
HWND hWndButton;
};
// Mostly self-contained, but bindings are modified by config.cpp, to make
// updating the ListView simpler.
class Device {
@ -246,8 +252,7 @@ public:
void CalcVirtualState();
// args are OS dependent.
inline virtual int Activate(void *args) {
virtual int Activate(InitInfo *args) {
return 0;
}
@ -298,8 +303,8 @@ public:
~InputDeviceManager();
void AddDevice(Device *d);
Device *GetActiveDevice(void *info, unsigned int *uid, int *index, int *value);
void Update(void *attachInfo);
Device *GetActiveDevice(InitInfo *info, unsigned int *uid, int *index, int *value);
void Update(InitInfo *initInfo);
// Called after reading state, after Update().
void PostRead();

View File

@ -36,14 +36,13 @@ public:
return 1;
}
int Activate(void *d) {
int Activate(InitInfo *initInfo) {
if (ikhd) ikhd->Deactivate();
InitInfo *info = (InitInfo*) d;
binding = info->bindingIgnore;
if (info->hWndButton)
EatWndProc(info->hWndButton, StartHooksWndProc, EATPROC_NO_UPDATE_WHILE_UPDATING_DEVICES);
binding = initInfo->bindingIgnore;
if (initInfo->hWndButton)
EatWndProc(initInfo->hWndButton, StartHooksWndProc, EATPROC_NO_UPDATE_WHILE_UPDATING_DEVICES);
else
EatWndProc(info->hWnd, StartHooksWndProc, EATPROC_NO_UPDATE_WHILE_UPDATING_DEVICES);
EatWndProc(initInfo->hWnd, StartHooksWndProc, EATPROC_NO_UPDATE_WHILE_UPDATING_DEVICES);
InitState();
ikhd = this;
active = 1;

View File

@ -12,10 +12,6 @@
#include "DualShock3.h"
#include "HidDevice.h"
#ifdef PCSX2_DEBUG
#include "crtdbg.h"
#endif
// LilyPad version.
#define VERSION ((0<<8) | 10 | (0<<24))
@ -404,7 +400,7 @@ void Update(unsigned int port, unsigned int slot) {
s[i&1][i>>1] = pads[i&1][i>>1].lockedSum;
}
InitInfo info = {
0, hWnd, hWnd, 0
0, 0, hWnd, hWnd, 0
};
dm->Update(&info);
@ -694,7 +690,7 @@ s32 CALLBACK PADinit(u32 flags) {
#ifdef PCSX2_DEBUG
int tmpFlag = _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG );
tmpFlag |= _CRTDBG_LEAK_CHECK_DF;
tmpFlag |= _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF;
_CrtSetDbgFlag( tmpFlag );
#endif
@ -838,6 +834,29 @@ void CALLBACK PADconfigure() {
Configure();
}
DWORD WINAPI RenameWindowThreadProc(void *lpParameter) {
wchar_t newTitle[200];
if (hWnd) {
int len = GetWindowTextW(hWnd, newTitle, 200);
if (len > 0 && len < 199) {
wchar_t *end;
if (end = wcsstr(newTitle, L" | State ")) *end = 0;
SetWindowTextW(hWnd, newTitle);
}
}
return 0;
}
void SaveStateChanged() {
if (config.saveStateTitle) {
// GSDX only checks its window's message queue at certain points or something, so
// have to do this in another thread to prevent deadlock.
HANDLE hThread = CreateThread(0, 0, RenameWindowThreadProc, 0, 0, 0);
if (hThread) CloseHandle(hThread);
}
}
s32 CALLBACK PADopen(void *pDsp) {
if (openCount++) return 0;
DEBUG_TEXT_OUT("LilyPad opened\n\n");
@ -865,6 +884,7 @@ s32 CALLBACK PADopen(void *pDsp) {
if (config.forceHide) {
EatWndProc(hWnd, HideCursorProc, 0);
}
SaveStateChanged();
}
if (restoreFullScreen) {
@ -948,19 +968,7 @@ u8 CALLBACK PADpoll(u8 value) {
DEBUG_OUT(query.response[1+query.lastByte]);
return query.response[++query.lastByte];
}
/*
{
query.numBytes = 35;
u8 test[35] = {0xFF, 0x80, 0x5A,
0x73, 0x5A, 0xFF, 0xFF, 0x80, 0x80, 0x80, 0x80,
0x73, 0x5A, 0xFF, 0xFF, 0x80, 0x80, 0x80, 0x80,
0x73, 0x5A, 0xFF, 0xFF, 0x80, 0x80, 0x80, 0x80,
0x73, 0x5A, 0xFF, 0xFF, 0x80, 0x80, 0x80, 0x80
};
memcpy(query.response, test, sizeof(test));
DEBUG_OUT(query.response[1+query.lastByte]);
return query.response[++query.lastByte];
}//*/
int i;
Pad *pad = &pads[query.port][query.slot];
if (query.lastByte == 0) {
@ -1213,9 +1221,6 @@ u32 CALLBACK PADquery() {
return 3;
}
//void CALLBACK PADgsDriverInfo(GSdriverInfo *info) {
//}
INT_PTR CALLBACK AboutDialogProc(HWND hWndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) {
if (uMsg == WM_INITDIALOG) {
wchar_t idString[100];
@ -1238,19 +1243,6 @@ s32 CALLBACK PADtest() {
return 0;
}
DWORD WINAPI RenameWindowThreadProc(void *lpParameter) {
wchar_t newTitle[200];
if (hWnd) {
int len = GetWindowTextW(hWnd, newTitle, 200);
if (len > 0 && len < 199) {
wchar_t *end;
if (end = wcsstr(newTitle, L" | State ")) *end = 0;
SetWindowTextW(hWnd, newTitle);
}
}
return 0;
}
keyEvent* CALLBACK PADkeyEvent() {
// If running both pads, ignore every other call. So if two keys pressed in same interval...
static char eventCount = 0;
@ -1289,12 +1281,7 @@ keyEvent* CALLBACK PADkeyEvent() {
if (ev.key == VK_F2 && ev.evt == KEYPRESS) {
saveStateIndex += 1 - 2*shiftDown;
saveStateIndex = (saveStateIndex+10)%10;
if (config.saveStateTitle) {
// GSDX only checks its window's message queue at certain points or something, so
// have to do this in another thread to prevent deadlock.
HANDLE hThread = CreateThread(0, 0, RenameWindowThreadProc, 0, 0, 0);
if (hThread) CloseHandle(hThread);
}
SaveStateChanged();
}
// So don't change skip mode on alt-F4.

View File

@ -73,12 +73,11 @@ public:
this->hDevice = hDevice;
}
int Activate(void *d) {
InitInfo *info = (InitInfo*)d;
int Activate(InitInfo *initInfo) {
Deactivate();
HWND hWnd = info->hWnd;
if (info->hWndButton) {
hWnd = info->hWndButton;
HWND hWnd = initInfo->hWnd;
if (initInfo->hWndButton) {
hWnd = initInfo->hWndButton;
}
active = 1;
if (!rawKeyboardActivatedCount++) {
@ -118,12 +117,11 @@ public:
this->hDevice = hDevice;
}
int Activate(void *d) {
InitInfo *info = (InitInfo*)d;
int Activate(InitInfo *initInfo) {
Deactivate();
HWND hWnd = info->hWnd;
if (info->hWndButton) {
hWnd = info->hWndButton;
HWND hWnd = initInfo->hWnd;
if (initInfo->hWndButton) {
hWnd = initInfo->hWndButton;
}
active = 1;

View File

@ -20,8 +20,8 @@ wchar_t *WindowsKeyboard::GetPhysicalControlName(PhysicalControl *control) {
}
void WindowsKeyboard::UpdateKey(int vkey, int state) {
if (vkey > 4 && vkey < 256) {
physicalControlState[vkey] = (state << 16);
if (vkey > 7 && vkey < 256) {
physicalControlState[vkey] = state * FULLY_DOWN;
}
}

View File

@ -6,35 +6,18 @@
#include "WindowsKeyboard.h"
#include "WindowsMouse.h"
ExtraWndProcResult WindowsMessagingWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *output);
class WindowsMessagingKeyboard;
class WindowsMessagingMouse;
static WindowsMessagingKeyboard *wmk = 0;
static WindowsMessagingMouse *wmm = 0;
class WindowsMessagingKeyboard : public WindowsKeyboard {
public:
int binding;
WindowsMessagingKeyboard() : WindowsKeyboard(WM, L"WM Keyboard") {
}
int Activate(void *d) {
InitInfo *info = (InitInfo*)d;
// Redundant. Should match the next line.
// Deactivate();
if (wmk) wmk->Deactivate();
HWND hWnd = info->hWnd;
if (info->hWndButton) {
hWnd = info->hWndButton;
}
if (!wmm && !EatWndProc(hWnd, WindowsMessagingWndProc, EATPROC_NO_UPDATE_WHILE_UPDATING_DEVICES)) {
Deactivate();
return 0;
}
int Activate(InitInfo *initInfo) {
binding = initInfo->binding;
EatWndProc(initInfo->hWndButton, WMKeyboardBindingWndProc, EATPROC_NO_UPDATE_WHILE_UPDATING_DEVICES);
wmk = this;
InitState();
active = 1;
@ -42,38 +25,54 @@ public:
}
void Deactivate() {
if (active) {
if (!wmm)
ReleaseExtraProc(WindowsMessagingWndProc);
wmk = 0;
active = 0;
FreeState();
}
ReleaseExtraProc(WMKeyboardBindingWndProc);
active = 0;
FreeState();
}
int Update() {
for (int i=10; i<256; i++) {
CheckKey(i);
}
physicalControlState[VK_MENU] = 0;
physicalControlState[VK_SHIFT] = 0;
physicalControlState[VK_CONTROL] = 0;
return 1;
}
void CheckKey(int vkey) {
UpdateKey(vkey, 1&(((unsigned short)GetAsyncKeyState(vkey))>>15));
}
static ExtraWndProcResult WMKeyboardBindingWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *output) {
if (uMsg == WM_KEYDOWN || uMsg == WM_SYSKEYDOWN || uMsg == WM_KEYUP || uMsg == WM_SYSKEYUP || uMsg == WM_CHAR || uMsg == WM_UNICHAR) {
return NO_WND_PROC;
}
return CONTINUE_BLISSFULLY;
}
};
ExtraWndProcResult WMMouseWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *output);
class WindowsMessagingMouse;
static WindowsMessagingMouse *wmm = 0;
class WindowsMessagingMouse : public WindowsMouse {
public:
WindowsMessagingMouse() : WindowsMouse(WM, 1, L"WM Mouse") {
}
int Activate(void *d) {
InitInfo *info = (InitInfo*)d;
int Activate(InitInfo *initInfo) {
// Redundant. Should match the next line.
// Deactivate();
if (wmm) wmm->Deactivate();
HWND hWnd = info->hWnd;
if (info->hWndButton) {
hWnd = info->hWndButton;
HWND hWnd = initInfo->hWnd;
if (initInfo->hWndButton) {
hWnd = initInfo->hWndButton;
}
if (!wmk && !EatWndProc(hWnd, WindowsMessagingWndProc, EATPROC_NO_UPDATE_WHILE_UPDATING_DEVICES)) {
if (!EatWndProc(hWnd, WMMouseWndProc, EATPROC_NO_UPDATE_WHILE_UPDATING_DEVICES)) {
Deactivate();
return 0;
}
@ -89,92 +88,65 @@ public:
void Deactivate() {
if (active) {
if (!wmk)
ReleaseExtraProc(WindowsMessagingWndProc);
ReleaseExtraProc(WMMouseWndProc);
ReleaseMouseCapture();
wmm = 0;
active = 0;
FreeState();
}
}
static ExtraWndProcResult WMMouseWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *output) {
if (wmm) {
if (uMsg == WM_MOUSEMOVE) {
POINT p;
GetCursorPos(&p);
// Need check to prevent cursor movement cascade.
if (p.x != wmm->center.x || p.y != wmm->center.y) {
wmm->UpdateAxis(0, p.x - wmm->center.x);
wmm->UpdateAxis(1, p.y - wmm->center.y);
SetCursorPos(wmm->center.x, wmm->center.y);
}
return NO_WND_PROC;
}
else if (uMsg == WM_LBUTTONDOWN || uMsg == WM_LBUTTONUP) {
wmm->UpdateButton(0, uMsg == WM_LBUTTONDOWN);
return NO_WND_PROC;
}
else if (uMsg == WM_RBUTTONDOWN || uMsg == WM_RBUTTONUP) {
wmm->UpdateButton(1, uMsg == WM_RBUTTONDOWN);
return NO_WND_PROC;
}
else if (uMsg == WM_MBUTTONDOWN || uMsg == WM_MBUTTONUP) {
wmm->UpdateButton(2, uMsg == WM_MBUTTONDOWN);
return NO_WND_PROC;
}
else if (uMsg == WM_XBUTTONDOWN || uMsg == WM_XBUTTONUP) {
wmm->UpdateButton(3+((wParam>>16) == XBUTTON2), uMsg == WM_XBUTTONDOWN);
return NO_WND_PROC;
}
else if (uMsg == WM_MOUSEWHEEL) {
wmm->UpdateAxis(2, ((int)wParam>>16)/WHEEL_DELTA);
return NO_WND_PROC;
}
else if (uMsg == WM_MOUSEHWHEEL) {
wmm->UpdateAxis(3, ((int)wParam>>16)/WHEEL_DELTA);
return NO_WND_PROC;
}
else if (uMsg == WM_SIZE && wmm->active) {
WindowsMouse::WindowResized(hWnd);
}
// Taken care of elsewhere. When binding, killing focus means stop reading input.
// When running PCSX2, I release all mouse and keyboard input elsewhere.
/*else if (uMsg == WM_KILLFOCUS) {
wmm->Deactivate();
}//*/
}
return CONTINUE_BLISSFULLY;
}
};
ExtraWndProcResult WindowsMessagingWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *output) {
if (wmk) {
if (uMsg == WM_KEYDOWN || uMsg == WM_SYSKEYDOWN || uMsg == WM_KEYUP || uMsg == WM_SYSKEYUP) {
if (wParam == VK_SHIFT) {
wmk->CheckKey(VK_RSHIFT);
wmk->CheckKey(VK_LSHIFT);
}
else if (wParam == VK_CONTROL) {
wmk->CheckKey(VK_RCONTROL);
wmk->CheckKey(VK_LCONTROL);
}
else if (wParam == VK_MENU) {
wmk->CheckKey(VK_RMENU);
wmk->CheckKey(VK_LMENU);
}
else
wmk->UpdateKey(wParam, (uMsg == WM_KEYDOWN || uMsg == WM_SYSKEYDOWN));
return NO_WND_PROC;
}
// Needed to prevent default handling of keys in some situations.
else if (uMsg == WM_CHAR || uMsg == WM_UNICHAR) {
return NO_WND_PROC;
}
else if (uMsg == WM_ACTIVATE) {
// Not really needed, but doesn't hurt.
memset(wmk->physicalControlState, 0, sizeof(int) * wmk->numPhysicalControls);
}
}
if (wmm) {
if (uMsg == WM_MOUSEMOVE) {
POINT p;
GetCursorPos(&p);
// Need check to prevent cursor movement cascade.
if (p.x != wmm->center.x || p.y != wmm->center.y) {
wmm->UpdateAxis(0, p.x - wmm->center.x);
wmm->UpdateAxis(1, p.y - wmm->center.y);
SetCursorPos(wmm->center.x, wmm->center.y);
}
return NO_WND_PROC;
}
else if (uMsg == WM_LBUTTONDOWN || uMsg == WM_LBUTTONUP) {
wmm->UpdateButton(0, uMsg == WM_LBUTTONDOWN);
return NO_WND_PROC;
}
else if (uMsg == WM_RBUTTONDOWN || uMsg == WM_RBUTTONUP) {
wmm->UpdateButton(1, uMsg == WM_RBUTTONDOWN);
return NO_WND_PROC;
}
else if (uMsg == WM_MBUTTONDOWN || uMsg == WM_MBUTTONUP) {
wmm->UpdateButton(2, uMsg == WM_MBUTTONDOWN);
return NO_WND_PROC;
}
else if (uMsg == WM_XBUTTONDOWN || uMsg == WM_XBUTTONUP) {
wmm->UpdateButton(3+((wParam>>16) == XBUTTON2), uMsg == WM_XBUTTONDOWN);
return NO_WND_PROC;
}
else if (uMsg == WM_MOUSEWHEEL) {
wmm->UpdateAxis(2, ((int)wParam>>16)/WHEEL_DELTA);
return NO_WND_PROC;
}
else if (uMsg == WM_MOUSEHWHEEL) {
wmm->UpdateAxis(3, ((int)wParam>>16)/WHEEL_DELTA);
return NO_WND_PROC;
}
else if (uMsg == WM_SIZE && wmm->active) {
WindowsMouse::WindowResized(hWnd);
}
// Taken care of elsewhere. When binding, killing focus means stop reading input.
// When running PCSX2, I release all mouse and keyboard input elsewhere.
/*else if (uMsg == WM_KILLFOCUS) {
wmm->Deactivate();
}//*/
}
return CONTINUE_BLISSFULLY;
}
void EnumWindowsMessagingDevices() {
dm->AddDevice(new WindowsMessagingKeyboard());

View File

@ -78,7 +78,7 @@ public:
return Device::GetPhysicalControlName(c);
}
int Activate(void *d) {
int Activate(InitInfo *initInfo) {
if (active) Deactivate();
if (!xInputActiveCount) {
pXInputEnable(1);