123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465 |
- #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);
- }
|