Initial community commit
This commit is contained in:
parent
537bcbc862
commit
fc06254474
16440 changed files with 4239995 additions and 2 deletions
465
Src/Plugins/Library/ml_devices/eventRelay.cpp
Normal file
465
Src/Plugins/Library/ml_devices/eventRelay.cpp
Normal file
|
@ -0,0 +1,465 @@
|
|||
#include "main.h"
|
||||
#include "./eventRelay.h"
|
||||
#include <vector>
|
||||
|
||||
#define EVENT_RELAY_WINDOW_CLASS L"NullsoftEventRelay"
|
||||
|
||||
typedef struct EventHandler
|
||||
{
|
||||
size_t cookie;
|
||||
DeviceEventCallbacks callbacks;
|
||||
void *user;
|
||||
} EventHandler;
|
||||
|
||||
typedef std::vector<EventHandler*> EventHandlerList;
|
||||
|
||||
typedef struct EventRelay
|
||||
{
|
||||
EventHandlerList handlerList;
|
||||
DeviceManagerHandler *managerHandler;
|
||||
DeviceHandler *deviceHandler;
|
||||
} EventRelay;
|
||||
|
||||
#define EVENTRELAY(_hwnd) ((EventRelay*)(LONGX86)GetWindowLongPtrW((_hwnd), 0))
|
||||
#define EVENTRELAY_RET_VOID(_self, _hwnd) {(_self) = EVENTRELAY((_hwnd)); if (NULL == (_self)) return;}
|
||||
#define EVENTRELAY_RET_VAL(_self, _hwnd, _error) {(_self) = EVENTRELAY((_hwnd)); if (NULL == (_self)) return (_error);}
|
||||
|
||||
|
||||
static LRESULT CALLBACK
|
||||
EventRelay_WindowProc(HWND hwnd, unsigned int uMsg, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
|
||||
static ATOM
|
||||
EventRelay_GetClassAtom(HINSTANCE instance)
|
||||
{
|
||||
WNDCLASSEXW klass;
|
||||
ATOM klassAtom;
|
||||
|
||||
klassAtom = (ATOM)GetClassInfoExW(instance, EVENT_RELAY_WINDOW_CLASS, &klass);
|
||||
if (0 != klassAtom)
|
||||
return klassAtom;
|
||||
|
||||
memset(&klass, 0, sizeof(klass));
|
||||
klass.cbSize = sizeof(klass);
|
||||
klass.style = 0;
|
||||
klass.lpfnWndProc = EventRelay_WindowProc;
|
||||
klass.cbClsExtra = 0;
|
||||
klass.cbWndExtra = sizeof(EventRelay*);
|
||||
klass.hInstance = instance;
|
||||
klass.hIcon = NULL;
|
||||
klass.hCursor = NULL;
|
||||
klass.hbrBackground = NULL;
|
||||
klass.lpszMenuName = NULL;
|
||||
klass.lpszClassName = EVENT_RELAY_WINDOW_CLASS;
|
||||
klass.hIconSm = NULL;
|
||||
klassAtom = RegisterClassExW(&klass);
|
||||
|
||||
return klassAtom;
|
||||
}
|
||||
|
||||
HWND
|
||||
EventRelay_CreateWindow()
|
||||
{
|
||||
HINSTANCE instance;
|
||||
ATOM klassAtom;
|
||||
HWND hwnd;
|
||||
|
||||
instance = GetModuleHandleW(NULL);
|
||||
klassAtom = EventRelay_GetClassAtom(instance);
|
||||
if (0 == klassAtom)
|
||||
return NULL;
|
||||
|
||||
hwnd = CreateWindowEx(WS_EX_NOACTIVATE | WS_EX_NOPARENTNOTIFY,
|
||||
MAKEINTATOM(klassAtom),
|
||||
NULL,
|
||||
WS_OVERLAPPED,
|
||||
0, 0, 0, 0,
|
||||
HWND_MESSAGE,
|
||||
NULL,
|
||||
instance,
|
||||
NULL);
|
||||
|
||||
return hwnd;
|
||||
}
|
||||
|
||||
|
||||
static size_t
|
||||
EventRelay_GenerateCookie(EventRelay *self)
|
||||
{
|
||||
size_t cookie;
|
||||
EventHandler *handler;
|
||||
|
||||
|
||||
if (NULL == self)
|
||||
return 0;
|
||||
|
||||
cookie = self->handlerList.size() + 1;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
size_t index = self->handlerList.size();
|
||||
while(index--)
|
||||
{
|
||||
handler = self->handlerList[index];
|
||||
if (cookie == handler->cookie)
|
||||
{
|
||||
cookie++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (((size_t)-1) == index)
|
||||
return cookie;
|
||||
}
|
||||
|
||||
return cookie;
|
||||
}
|
||||
|
||||
static EventHandler *
|
||||
EventRelay_CreateEventHandler(EventRelay *self, DeviceEventCallbacks *callbacks, void *user)
|
||||
{
|
||||
EventHandler *handler;
|
||||
size_t cookie;
|
||||
|
||||
if (NULL == self || NULL == callbacks)
|
||||
return NULL;
|
||||
|
||||
cookie = EventRelay_GenerateCookie(self);
|
||||
if (0 == cookie)
|
||||
return NULL;
|
||||
|
||||
handler = (EventHandler*)malloc(sizeof(EventHandler));
|
||||
if (NULL == handler)
|
||||
return NULL;
|
||||
|
||||
handler->user = user;
|
||||
handler->cookie = cookie;
|
||||
handler->callbacks.deviceCb = callbacks->deviceCb;
|
||||
handler->callbacks.typeCb = callbacks->typeCb;
|
||||
handler->callbacks.connectionCb = callbacks->connectionCb;
|
||||
handler->callbacks.commandCb = callbacks->commandCb;
|
||||
handler->callbacks.discoveryCb = callbacks->discoveryCb;
|
||||
|
||||
return handler;
|
||||
}
|
||||
|
||||
static void
|
||||
EventRelay_DestroyEventHandler(EventHandler *handler)
|
||||
{
|
||||
if (NULL == handler)
|
||||
return;
|
||||
|
||||
free(handler);
|
||||
}
|
||||
|
||||
static LRESULT
|
||||
EventRelay_OnCreate(HWND hwnd, CREATESTRUCT *createStruct)
|
||||
{
|
||||
EventRelay *self;
|
||||
ifc_deviceobjectenum *enumerator;
|
||||
ifc_deviceobject *object;
|
||||
ifc_device *device;
|
||||
|
||||
if (NULL == WASABI_API_DEVICES)
|
||||
return -1;
|
||||
|
||||
self = new EventRelay();
|
||||
if (NULL == self)
|
||||
return -1;
|
||||
|
||||
self->deviceHandler = NULL;
|
||||
self->managerHandler = NULL;
|
||||
|
||||
SetLastError(ERROR_SUCCESS);
|
||||
if (!SetWindowLongPtr(hwnd, 0, (LONGX86)self) && ERROR_SUCCESS != GetLastError())
|
||||
return -1;
|
||||
|
||||
if (FAILED(DeviceHandler::CreateInstance(&self->deviceHandler)))
|
||||
return -1;
|
||||
|
||||
self->deviceHandler->SetRelayWindow(hwnd);
|
||||
|
||||
if (SUCCEEDED(WASABI_API_DEVICES->DeviceEnumerate(&enumerator)))
|
||||
{
|
||||
while(S_OK == enumerator->Next(&object, 1, NULL))
|
||||
{
|
||||
if (SUCCEEDED(object->QueryInterface(IFC_Device, (void**)&device)))
|
||||
{
|
||||
self->deviceHandler->Advise(device);
|
||||
device->Release();
|
||||
}
|
||||
object->Release();
|
||||
}
|
||||
enumerator->Release();
|
||||
}
|
||||
|
||||
if (FAILED(DeviceManagerHandler::CreateInstance(&self->managerHandler)))
|
||||
return -1;
|
||||
|
||||
self->managerHandler->SetRelayWindow(hwnd);
|
||||
if (FAILED(self->managerHandler->Advise(WASABI_API_DEVICES)))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
EventRelay_OnDestroy(HWND hwnd)
|
||||
{
|
||||
EventRelay *self;
|
||||
MSG msg;
|
||||
|
||||
self = EVENTRELAY(hwnd);
|
||||
SetWindowLongPtr(hwnd, 0, 0);
|
||||
|
||||
if (NULL == self)
|
||||
return;
|
||||
|
||||
size_t index = self->handlerList.size();
|
||||
while(index--)
|
||||
{
|
||||
EventHandler *handler = self->handlerList[index];
|
||||
EventRelay_DestroyEventHandler(handler);
|
||||
}
|
||||
|
||||
if (NULL != self->managerHandler)
|
||||
{
|
||||
self->managerHandler->SetRelayWindow(NULL);
|
||||
|
||||
if (NULL != WASABI_API_DEVICES)
|
||||
self->managerHandler->Unadvise(WASABI_API_DEVICES);
|
||||
|
||||
self->managerHandler->Release();
|
||||
}
|
||||
|
||||
if (NULL != self->deviceHandler)
|
||||
{
|
||||
self->deviceHandler->SetRelayWindow(NULL);
|
||||
|
||||
if (NULL != WASABI_API_DEVICES)
|
||||
{
|
||||
ifc_deviceobjectenum *enumerator;
|
||||
ifc_deviceobject *object;
|
||||
ifc_device *device;
|
||||
|
||||
if (SUCCEEDED(WASABI_API_DEVICES->DeviceEnumerate(&enumerator)))
|
||||
{
|
||||
while(S_OK == enumerator->Next(&object, 1, NULL))
|
||||
{
|
||||
if (SUCCEEDED(object->QueryInterface(IFC_Device, (void**)&device)))
|
||||
{
|
||||
self->deviceHandler->Unadvise(device);
|
||||
device->Release();
|
||||
}
|
||||
object->Release();
|
||||
}
|
||||
enumerator->Release();
|
||||
}
|
||||
}
|
||||
|
||||
self->deviceHandler->Release();
|
||||
}
|
||||
|
||||
delete self;
|
||||
|
||||
// finish pumping messages
|
||||
while(FALSE != PeekMessage(&msg, hwnd, EVENTRELAY_WM_FIRST, EVENTRELAY_WM_LAST, PM_REMOVE))
|
||||
{
|
||||
EventRelay_WindowProc(msg.hwnd, msg.message, msg.wParam, msg.lParam);
|
||||
}
|
||||
}
|
||||
|
||||
static LRESULT
|
||||
EventRelay_OnRegisterHandler(HWND hwnd, DeviceEventCallbacks *callbacks, void *user)
|
||||
{
|
||||
EventRelay *self;
|
||||
EventHandler *handler;
|
||||
|
||||
EVENTRELAY_RET_VAL(self, hwnd, 0);
|
||||
|
||||
handler = EventRelay_CreateEventHandler(self, callbacks, user);
|
||||
if(NULL == handler)
|
||||
return 0;
|
||||
|
||||
self->handlerList.push_back(handler);
|
||||
return (LRESULT)handler->cookie;
|
||||
}
|
||||
|
||||
static LRESULT
|
||||
EventRelay_OnUnregisterHandler(HWND hwnd, size_t cookie)
|
||||
{
|
||||
EventRelay *self;
|
||||
|
||||
EVENTRELAY_RET_VAL(self, hwnd, FALSE);
|
||||
|
||||
size_t index = self->handlerList.size();
|
||||
while(index--)
|
||||
{
|
||||
EventHandler *handler = self->handlerList[index];
|
||||
if (handler->cookie == cookie)
|
||||
{
|
||||
self->handlerList.erase(self->handlerList.begin() + index);
|
||||
EventRelay_DestroyEventHandler(handler);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
EventRelay_OnNotifyDevice(HWND hwnd, ifc_device *device, DeviceEvent eventId)
|
||||
{
|
||||
ReplyMessage(0);
|
||||
|
||||
if (NULL != device)
|
||||
{
|
||||
EventRelay *self;
|
||||
self = EVENTRELAY(hwnd);
|
||||
|
||||
if (NULL != self)
|
||||
{
|
||||
switch(eventId)
|
||||
{
|
||||
case Event_DeviceAdded:
|
||||
if (NULL != self->deviceHandler)
|
||||
self->deviceHandler->Advise(device);
|
||||
break;
|
||||
|
||||
case Event_DeviceRemoved:
|
||||
if (NULL != self->deviceHandler)
|
||||
self->deviceHandler->Unadvise(device);
|
||||
break;
|
||||
}
|
||||
|
||||
size_t index = self->handlerList.size();
|
||||
while(index--)
|
||||
{
|
||||
EventHandler *handler = self->handlerList[index];
|
||||
if (NULL != handler->callbacks.deviceCb)
|
||||
handler->callbacks.deviceCb(device, eventId, handler->user);
|
||||
}
|
||||
}
|
||||
|
||||
device->Release();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
EventRelay_OnNotifyDiscovery(HWND hwnd, api_devicemanager *manager, DeviceDiscoveryEvent eventId)
|
||||
{
|
||||
ReplyMessage(0);
|
||||
|
||||
if (NULL != manager)
|
||||
{
|
||||
EventRelay *self;
|
||||
self = EVENTRELAY(hwnd);
|
||||
|
||||
if (NULL != self)
|
||||
{
|
||||
size_t index = self->handlerList.size();
|
||||
while(index--)
|
||||
{
|
||||
EventHandler *handler = self->handlerList[index];
|
||||
if (NULL != handler->callbacks.discoveryCb)
|
||||
handler->callbacks.discoveryCb(manager, eventId, handler->user);
|
||||
}
|
||||
}
|
||||
|
||||
manager->Release();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
EventRelay_OnNotifyType(HWND hwnd, ifc_devicetype *type, DeviceTypeEvent eventId)
|
||||
{
|
||||
ReplyMessage(0);
|
||||
|
||||
if (NULL != type)
|
||||
{
|
||||
EventRelay *self;
|
||||
self = EVENTRELAY(hwnd);
|
||||
|
||||
if (NULL != self)
|
||||
{
|
||||
size_t index = self->handlerList.size();
|
||||
while(index--)
|
||||
{
|
||||
EventHandler *handler = self->handlerList[index];
|
||||
if (NULL != handler->callbacks.typeCb)
|
||||
handler->callbacks.typeCb(type, eventId, handler->user);
|
||||
}
|
||||
}
|
||||
|
||||
type->Release();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
EventRelay_OnNotifyConnection(HWND hwnd, ifc_deviceconnection *connection, DeviceConnectionEvent eventId)
|
||||
{
|
||||
ReplyMessage(0);
|
||||
|
||||
if (NULL != connection)
|
||||
{
|
||||
EventRelay *self;
|
||||
self = EVENTRELAY(hwnd);
|
||||
|
||||
if (NULL != self)
|
||||
{
|
||||
size_t index = self->handlerList.size();
|
||||
while(index--)
|
||||
{
|
||||
EventHandler *handler = self->handlerList[index];
|
||||
if (NULL != handler->callbacks.connectionCb)
|
||||
handler->callbacks.connectionCb(connection, eventId, handler->user);
|
||||
}
|
||||
}
|
||||
|
||||
connection->Release();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
EventRelay_OnNotifyCommand(HWND hwnd, ifc_devicecommand *command, DeviceCommandEvent eventId)
|
||||
{
|
||||
ReplyMessage(0);
|
||||
|
||||
if (NULL != command)
|
||||
{
|
||||
EventRelay *self;
|
||||
self = EVENTRELAY(hwnd);
|
||||
|
||||
if (NULL != self)
|
||||
{
|
||||
size_t index = self->handlerList.size();
|
||||
while(index--)
|
||||
{
|
||||
EventHandler *handler = self->handlerList[index];
|
||||
if (NULL != handler->callbacks.commandCb)
|
||||
handler->callbacks.commandCb(command, eventId, handler->user);
|
||||
}
|
||||
}
|
||||
|
||||
command->Release();
|
||||
}
|
||||
}
|
||||
|
||||
static LRESULT CALLBACK
|
||||
EventRelay_WindowProc(HWND hwnd, unsigned int uMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch(uMsg)
|
||||
{
|
||||
case WM_CREATE: return EventRelay_OnCreate(hwnd, (CREATESTRUCT*)lParam);
|
||||
case WM_DESTROY: EventRelay_OnDestroy(hwnd); return 0;
|
||||
|
||||
case EVENTRELAY_WM_REGISTER_HANDLER: return EventRelay_OnRegisterHandler(hwnd, (DeviceEventCallbacks*)lParam, (void*)wParam);
|
||||
case EVENTRELAY_WM_UNREGISTER_HANDLER: return EventRelay_OnUnregisterHandler(hwnd, (size_t)lParam);
|
||||
case EVENTRELAY_WM_NOTIFY_DEVICE: EventRelay_OnNotifyDevice(hwnd, (ifc_device*)lParam, (DeviceEvent)wParam); return 0;
|
||||
case EVENTRELAY_WM_NOTIFY_DISCOVERY: EventRelay_OnNotifyDiscovery(hwnd, (api_devicemanager*)lParam, (DeviceDiscoveryEvent)wParam); return 0;
|
||||
case EVENTRELAY_WM_NOTIFY_TYPE: EventRelay_OnNotifyType(hwnd, (ifc_devicetype*)lParam, (DeviceTypeEvent)wParam); return 0;
|
||||
case EVENTRELAY_WM_NOTIFY_CONNECTION: EventRelay_OnNotifyConnection(hwnd, (ifc_deviceconnection*)lParam, (DeviceConnectionEvent)wParam); return 0;
|
||||
case EVENTRELAY_WM_NOTIFY_COMMAND: EventRelay_OnNotifyCommand(hwnd, (ifc_devicecommand*)lParam, (DeviceCommandEvent)wParam); return 0;
|
||||
}
|
||||
return DefWindowProc(hwnd, uMsg, wParam, lParam);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue