mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
bug 921565 - look for WM_DEVICECHANGE in Windows gamepad backend and rescan for devices. r=jimm
This commit is contained in:
parent
48a2fe2e87
commit
313430c578
@ -232,7 +232,6 @@ public:
|
||||
mTimer = do_CreateInstance("@mozilla.org/timer;1", &rv);
|
||||
nsCOMPtr<nsIObserverService> observerService =
|
||||
mozilla::services::GetObserverService();
|
||||
observerService->AddObserver(this, "devices-changed", false);
|
||||
observerService->AddObserver(this,
|
||||
NS_XPCOM_WILL_SHUTDOWN_OBSERVER_ID,
|
||||
false);
|
||||
@ -245,7 +244,6 @@ public:
|
||||
if (mObserving) {
|
||||
nsCOMPtr<nsIObserverService> observerService =
|
||||
mozilla::services::GetObserverService();
|
||||
observerService->RemoveObserver(this, "devices-changed");
|
||||
observerService->RemoveObserver(this, NS_XPCOM_WILL_SHUTDOWN_OBSERVER_ID);
|
||||
mObserving = false;
|
||||
}
|
||||
@ -255,6 +253,15 @@ public:
|
||||
Stop();
|
||||
}
|
||||
|
||||
void SetDeviceChangeTimer() {
|
||||
// set stable timer, since we will get multiple devices-changed
|
||||
// notifications at once
|
||||
if (mTimer) {
|
||||
mTimer->Cancel();
|
||||
mTimer->Init(this, kDevicesChangedStableDelay, nsITimer::TYPE_ONE_SHOT);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
// Gamepad service owns us, we just hold a reference back to it.
|
||||
WindowsGamepadService& mSvc;
|
||||
@ -277,7 +284,11 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void DevicesChanged();
|
||||
enum DeviceChangeType {
|
||||
DeviceChangeNotification,
|
||||
DeviceChangeStable
|
||||
};
|
||||
void DevicesChanged(DeviceChangeType type);
|
||||
void Startup();
|
||||
void Shutdown();
|
||||
|
||||
@ -589,8 +600,12 @@ WindowsGamepadService::CleanupGamepad(Gamepad& gamepad) {
|
||||
}
|
||||
|
||||
void
|
||||
WindowsGamepadService::DevicesChanged() {
|
||||
SetEvent(mThreadRescanEvent);
|
||||
WindowsGamepadService::DevicesChanged(DeviceChangeType type) {
|
||||
if (type == DeviceChangeNotification) {
|
||||
mObserver->SetDeviceChangeTimer();
|
||||
} else if (type == DeviceChangeStable) {
|
||||
SetEvent(mThreadRescanEvent);
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -598,27 +613,39 @@ Observer::Observe(nsISupports* aSubject,
|
||||
const char* aTopic,
|
||||
const PRUnichar* aData) {
|
||||
if (strcmp(aTopic, "timer-callback") == 0) {
|
||||
mSvc.DevicesChanged();
|
||||
mSvc.DevicesChanged(WindowsGamepadService::DeviceChangeStable);
|
||||
} else if (strcmp(aTopic, NS_XPCOM_WILL_SHUTDOWN_OBSERVER_ID) == 0) {
|
||||
Stop();
|
||||
} else if (strcmp(aTopic, "devices-changed")) {
|
||||
// set stable timer, since we will get multiple devices-changed
|
||||
// notifications at once
|
||||
if (mTimer) {
|
||||
mTimer->Cancel();
|
||||
mTimer->Init(this, kDevicesChangedStableDelay, nsITimer::TYPE_ONE_SHOT);
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
WindowsGamepadService* gService = nullptr;
|
||||
HWND sHWnd = nullptr;
|
||||
|
||||
static
|
||||
LRESULT CALLBACK
|
||||
GamepadWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
|
||||
const unsigned int DBT_DEVICEARRIVAL = 0x8000;
|
||||
const unsigned int DBT_DEVICEREMOVECOMPLETE = 0x8004;
|
||||
const unsigned int DBT_DEVNODES_CHANGED = 0x7;
|
||||
|
||||
if (msg == WM_DEVICECHANGE &&
|
||||
(wParam == DBT_DEVICEARRIVAL ||
|
||||
wParam == DBT_DEVICEREMOVECOMPLETE ||
|
||||
wParam == DBT_DEVNODES_CHANGED)) {
|
||||
if (gService) {
|
||||
gService->DevicesChanged(WindowsGamepadService::DeviceChangeNotification);
|
||||
}
|
||||
}
|
||||
return DefWindowProc(hwnd, msg, wParam, lParam);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace mozilla {
|
||||
namespace hal_impl {
|
||||
|
||||
WindowsGamepadService* gService = nullptr;
|
||||
|
||||
void StartMonitoringGamepadStatus()
|
||||
{
|
||||
if (gService)
|
||||
@ -626,6 +653,23 @@ void StartMonitoringGamepadStatus()
|
||||
|
||||
gService = new WindowsGamepadService();
|
||||
gService->Startup();
|
||||
|
||||
if (sHWnd == nullptr) {
|
||||
WNDCLASSW wc;
|
||||
HMODULE hSelf = GetModuleHandle(nullptr);
|
||||
|
||||
if (!GetClassInfoW(hSelf, L"MozillaGamepadClass", &wc)) {
|
||||
ZeroMemory(&wc, sizeof(WNDCLASSW));
|
||||
wc.hInstance = hSelf;
|
||||
wc.lpfnWndProc = GamepadWindowProc;
|
||||
wc.lpszClassName = L"MozillaGamepadClass";
|
||||
RegisterClassW(&wc);
|
||||
}
|
||||
|
||||
sHWnd = CreateWindowW(L"MozillaGamepadClass", L"Gamepad Watcher",
|
||||
0, 0, 0, 0, 0,
|
||||
nullptr, nullptr, hSelf, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void StopMonitoringGamepadStatus()
|
||||
@ -633,6 +677,11 @@ void StopMonitoringGamepadStatus()
|
||||
if (!gService)
|
||||
return;
|
||||
|
||||
if (sHWnd) {
|
||||
DestroyWindow(sHWnd);
|
||||
sHWnd = nullptr;
|
||||
}
|
||||
|
||||
gService->Shutdown();
|
||||
delete gService;
|
||||
gService = nullptr;
|
||||
|
Loading…
Reference in New Issue
Block a user