1
0

eventRelay.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465
  1. #include "main.h"
  2. #include "./eventRelay.h"
  3. #include <vector>
  4. #define EVENT_RELAY_WINDOW_CLASS L"NullsoftEventRelay"
  5. typedef struct EventHandler
  6. {
  7. size_t cookie;
  8. DeviceEventCallbacks callbacks;
  9. void *user;
  10. } EventHandler;
  11. typedef std::vector<EventHandler*> EventHandlerList;
  12. typedef struct EventRelay
  13. {
  14. EventHandlerList handlerList;
  15. DeviceManagerHandler *managerHandler;
  16. DeviceHandler *deviceHandler;
  17. } EventRelay;
  18. #define EVENTRELAY(_hwnd) ((EventRelay*)(LONGX86)GetWindowLongPtrW((_hwnd), 0))
  19. #define EVENTRELAY_RET_VOID(_self, _hwnd) {(_self) = EVENTRELAY((_hwnd)); if (NULL == (_self)) return;}
  20. #define EVENTRELAY_RET_VAL(_self, _hwnd, _error) {(_self) = EVENTRELAY((_hwnd)); if (NULL == (_self)) return (_error);}
  21. static LRESULT CALLBACK
  22. EventRelay_WindowProc(HWND hwnd, unsigned int uMsg, WPARAM wParam, LPARAM lParam);
  23. static ATOM
  24. EventRelay_GetClassAtom(HINSTANCE instance)
  25. {
  26. WNDCLASSEXW klass;
  27. ATOM klassAtom;
  28. klassAtom = (ATOM)GetClassInfoExW(instance, EVENT_RELAY_WINDOW_CLASS, &klass);
  29. if (0 != klassAtom)
  30. return klassAtom;
  31. memset(&klass, 0, sizeof(klass));
  32. klass.cbSize = sizeof(klass);
  33. klass.style = 0;
  34. klass.lpfnWndProc = EventRelay_WindowProc;
  35. klass.cbClsExtra = 0;
  36. klass.cbWndExtra = sizeof(EventRelay*);
  37. klass.hInstance = instance;
  38. klass.hIcon = NULL;
  39. klass.hCursor = NULL;
  40. klass.hbrBackground = NULL;
  41. klass.lpszMenuName = NULL;
  42. klass.lpszClassName = EVENT_RELAY_WINDOW_CLASS;
  43. klass.hIconSm = NULL;
  44. klassAtom = RegisterClassExW(&klass);
  45. return klassAtom;
  46. }
  47. HWND
  48. EventRelay_CreateWindow()
  49. {
  50. HINSTANCE instance;
  51. ATOM klassAtom;
  52. HWND hwnd;
  53. instance = GetModuleHandleW(NULL);
  54. klassAtom = EventRelay_GetClassAtom(instance);
  55. if (0 == klassAtom)
  56. return NULL;
  57. hwnd = CreateWindowEx(WS_EX_NOACTIVATE | WS_EX_NOPARENTNOTIFY,
  58. MAKEINTATOM(klassAtom),
  59. NULL,
  60. WS_OVERLAPPED,
  61. 0, 0, 0, 0,
  62. HWND_MESSAGE,
  63. NULL,
  64. instance,
  65. NULL);
  66. return hwnd;
  67. }
  68. static size_t
  69. EventRelay_GenerateCookie(EventRelay *self)
  70. {
  71. size_t cookie;
  72. EventHandler *handler;
  73. if (NULL == self)
  74. return 0;
  75. cookie = self->handlerList.size() + 1;
  76. for(;;)
  77. {
  78. size_t index = self->handlerList.size();
  79. while(index--)
  80. {
  81. handler = self->handlerList[index];
  82. if (cookie == handler->cookie)
  83. {
  84. cookie++;
  85. break;
  86. }
  87. }
  88. if (((size_t)-1) == index)
  89. return cookie;
  90. }
  91. return cookie;
  92. }
  93. static EventHandler *
  94. EventRelay_CreateEventHandler(EventRelay *self, DeviceEventCallbacks *callbacks, void *user)
  95. {
  96. EventHandler *handler;
  97. size_t cookie;
  98. if (NULL == self || NULL == callbacks)
  99. return NULL;
  100. cookie = EventRelay_GenerateCookie(self);
  101. if (0 == cookie)
  102. return NULL;
  103. handler = (EventHandler*)malloc(sizeof(EventHandler));
  104. if (NULL == handler)
  105. return NULL;
  106. handler->user = user;
  107. handler->cookie = cookie;
  108. handler->callbacks.deviceCb = callbacks->deviceCb;
  109. handler->callbacks.typeCb = callbacks->typeCb;
  110. handler->callbacks.connectionCb = callbacks->connectionCb;
  111. handler->callbacks.commandCb = callbacks->commandCb;
  112. handler->callbacks.discoveryCb = callbacks->discoveryCb;
  113. return handler;
  114. }
  115. static void
  116. EventRelay_DestroyEventHandler(EventHandler *handler)
  117. {
  118. if (NULL == handler)
  119. return;
  120. free(handler);
  121. }
  122. static LRESULT
  123. EventRelay_OnCreate(HWND hwnd, CREATESTRUCT *createStruct)
  124. {
  125. EventRelay *self;
  126. ifc_deviceobjectenum *enumerator;
  127. ifc_deviceobject *object;
  128. ifc_device *device;
  129. if (NULL == WASABI_API_DEVICES)
  130. return -1;
  131. self = new EventRelay();
  132. if (NULL == self)
  133. return -1;
  134. self->deviceHandler = NULL;
  135. self->managerHandler = NULL;
  136. SetLastError(ERROR_SUCCESS);
  137. if (!SetWindowLongPtr(hwnd, 0, (LONGX86)self) && ERROR_SUCCESS != GetLastError())
  138. return -1;
  139. if (FAILED(DeviceHandler::CreateInstance(&self->deviceHandler)))
  140. return -1;
  141. self->deviceHandler->SetRelayWindow(hwnd);
  142. if (SUCCEEDED(WASABI_API_DEVICES->DeviceEnumerate(&enumerator)))
  143. {
  144. while(S_OK == enumerator->Next(&object, 1, NULL))
  145. {
  146. if (SUCCEEDED(object->QueryInterface(IFC_Device, (void**)&device)))
  147. {
  148. self->deviceHandler->Advise(device);
  149. device->Release();
  150. }
  151. object->Release();
  152. }
  153. enumerator->Release();
  154. }
  155. if (FAILED(DeviceManagerHandler::CreateInstance(&self->managerHandler)))
  156. return -1;
  157. self->managerHandler->SetRelayWindow(hwnd);
  158. if (FAILED(self->managerHandler->Advise(WASABI_API_DEVICES)))
  159. return -1;
  160. return 0;
  161. }
  162. static void
  163. EventRelay_OnDestroy(HWND hwnd)
  164. {
  165. EventRelay *self;
  166. MSG msg;
  167. self = EVENTRELAY(hwnd);
  168. SetWindowLongPtr(hwnd, 0, 0);
  169. if (NULL == self)
  170. return;
  171. size_t index = self->handlerList.size();
  172. while(index--)
  173. {
  174. EventHandler *handler = self->handlerList[index];
  175. EventRelay_DestroyEventHandler(handler);
  176. }
  177. if (NULL != self->managerHandler)
  178. {
  179. self->managerHandler->SetRelayWindow(NULL);
  180. if (NULL != WASABI_API_DEVICES)
  181. self->managerHandler->Unadvise(WASABI_API_DEVICES);
  182. self->managerHandler->Release();
  183. }
  184. if (NULL != self->deviceHandler)
  185. {
  186. self->deviceHandler->SetRelayWindow(NULL);
  187. if (NULL != WASABI_API_DEVICES)
  188. {
  189. ifc_deviceobjectenum *enumerator;
  190. ifc_deviceobject *object;
  191. ifc_device *device;
  192. if (SUCCEEDED(WASABI_API_DEVICES->DeviceEnumerate(&enumerator)))
  193. {
  194. while(S_OK == enumerator->Next(&object, 1, NULL))
  195. {
  196. if (SUCCEEDED(object->QueryInterface(IFC_Device, (void**)&device)))
  197. {
  198. self->deviceHandler->Unadvise(device);
  199. device->Release();
  200. }
  201. object->Release();
  202. }
  203. enumerator->Release();
  204. }
  205. }
  206. self->deviceHandler->Release();
  207. }
  208. delete self;
  209. // finish pumping messages
  210. while(FALSE != PeekMessage(&msg, hwnd, EVENTRELAY_WM_FIRST, EVENTRELAY_WM_LAST, PM_REMOVE))
  211. {
  212. EventRelay_WindowProc(msg.hwnd, msg.message, msg.wParam, msg.lParam);
  213. }
  214. }
  215. static LRESULT
  216. EventRelay_OnRegisterHandler(HWND hwnd, DeviceEventCallbacks *callbacks, void *user)
  217. {
  218. EventRelay *self;
  219. EventHandler *handler;
  220. EVENTRELAY_RET_VAL(self, hwnd, 0);
  221. handler = EventRelay_CreateEventHandler(self, callbacks, user);
  222. if(NULL == handler)
  223. return 0;
  224. self->handlerList.push_back(handler);
  225. return (LRESULT)handler->cookie;
  226. }
  227. static LRESULT
  228. EventRelay_OnUnregisterHandler(HWND hwnd, size_t cookie)
  229. {
  230. EventRelay *self;
  231. EVENTRELAY_RET_VAL(self, hwnd, FALSE);
  232. size_t index = self->handlerList.size();
  233. while(index--)
  234. {
  235. EventHandler *handler = self->handlerList[index];
  236. if (handler->cookie == cookie)
  237. {
  238. self->handlerList.erase(self->handlerList.begin() + index);
  239. EventRelay_DestroyEventHandler(handler);
  240. return TRUE;
  241. }
  242. }
  243. return FALSE;
  244. }
  245. static void
  246. EventRelay_OnNotifyDevice(HWND hwnd, ifc_device *device, DeviceEvent eventId)
  247. {
  248. ReplyMessage(0);
  249. if (NULL != device)
  250. {
  251. EventRelay *self;
  252. self = EVENTRELAY(hwnd);
  253. if (NULL != self)
  254. {
  255. switch(eventId)
  256. {
  257. case Event_DeviceAdded:
  258. if (NULL != self->deviceHandler)
  259. self->deviceHandler->Advise(device);
  260. break;
  261. case Event_DeviceRemoved:
  262. if (NULL != self->deviceHandler)
  263. self->deviceHandler->Unadvise(device);
  264. break;
  265. }
  266. size_t index = self->handlerList.size();
  267. while(index--)
  268. {
  269. EventHandler *handler = self->handlerList[index];
  270. if (NULL != handler->callbacks.deviceCb)
  271. handler->callbacks.deviceCb(device, eventId, handler->user);
  272. }
  273. }
  274. device->Release();
  275. }
  276. }
  277. static void
  278. EventRelay_OnNotifyDiscovery(HWND hwnd, api_devicemanager *manager, DeviceDiscoveryEvent eventId)
  279. {
  280. ReplyMessage(0);
  281. if (NULL != manager)
  282. {
  283. EventRelay *self;
  284. self = EVENTRELAY(hwnd);
  285. if (NULL != self)
  286. {
  287. size_t index = self->handlerList.size();
  288. while(index--)
  289. {
  290. EventHandler *handler = self->handlerList[index];
  291. if (NULL != handler->callbacks.discoveryCb)
  292. handler->callbacks.discoveryCb(manager, eventId, handler->user);
  293. }
  294. }
  295. manager->Release();
  296. }
  297. }
  298. static void
  299. EventRelay_OnNotifyType(HWND hwnd, ifc_devicetype *type, DeviceTypeEvent eventId)
  300. {
  301. ReplyMessage(0);
  302. if (NULL != type)
  303. {
  304. EventRelay *self;
  305. self = EVENTRELAY(hwnd);
  306. if (NULL != self)
  307. {
  308. size_t index = self->handlerList.size();
  309. while(index--)
  310. {
  311. EventHandler *handler = self->handlerList[index];
  312. if (NULL != handler->callbacks.typeCb)
  313. handler->callbacks.typeCb(type, eventId, handler->user);
  314. }
  315. }
  316. type->Release();
  317. }
  318. }
  319. static void
  320. EventRelay_OnNotifyConnection(HWND hwnd, ifc_deviceconnection *connection, DeviceConnectionEvent eventId)
  321. {
  322. ReplyMessage(0);
  323. if (NULL != connection)
  324. {
  325. EventRelay *self;
  326. self = EVENTRELAY(hwnd);
  327. if (NULL != self)
  328. {
  329. size_t index = self->handlerList.size();
  330. while(index--)
  331. {
  332. EventHandler *handler = self->handlerList[index];
  333. if (NULL != handler->callbacks.connectionCb)
  334. handler->callbacks.connectionCb(connection, eventId, handler->user);
  335. }
  336. }
  337. connection->Release();
  338. }
  339. }
  340. static void
  341. EventRelay_OnNotifyCommand(HWND hwnd, ifc_devicecommand *command, DeviceCommandEvent eventId)
  342. {
  343. ReplyMessage(0);
  344. if (NULL != command)
  345. {
  346. EventRelay *self;
  347. self = EVENTRELAY(hwnd);
  348. if (NULL != self)
  349. {
  350. size_t index = self->handlerList.size();
  351. while(index--)
  352. {
  353. EventHandler *handler = self->handlerList[index];
  354. if (NULL != handler->callbacks.commandCb)
  355. handler->callbacks.commandCb(command, eventId, handler->user);
  356. }
  357. }
  358. command->Release();
  359. }
  360. }
  361. static LRESULT CALLBACK
  362. EventRelay_WindowProc(HWND hwnd, unsigned int uMsg, WPARAM wParam, LPARAM lParam)
  363. {
  364. switch(uMsg)
  365. {
  366. case WM_CREATE: return EventRelay_OnCreate(hwnd, (CREATESTRUCT*)lParam);
  367. case WM_DESTROY: EventRelay_OnDestroy(hwnd); return 0;
  368. case EVENTRELAY_WM_REGISTER_HANDLER: return EventRelay_OnRegisterHandler(hwnd, (DeviceEventCallbacks*)lParam, (void*)wParam);
  369. case EVENTRELAY_WM_UNREGISTER_HANDLER: return EventRelay_OnUnregisterHandler(hwnd, (size_t)lParam);
  370. case EVENTRELAY_WM_NOTIFY_DEVICE: EventRelay_OnNotifyDevice(hwnd, (ifc_device*)lParam, (DeviceEvent)wParam); return 0;
  371. case EVENTRELAY_WM_NOTIFY_DISCOVERY: EventRelay_OnNotifyDiscovery(hwnd, (api_devicemanager*)lParam, (DeviceDiscoveryEvent)wParam); return 0;
  372. case EVENTRELAY_WM_NOTIFY_TYPE: EventRelay_OnNotifyType(hwnd, (ifc_devicetype*)lParam, (DeviceTypeEvent)wParam); return 0;
  373. case EVENTRELAY_WM_NOTIFY_CONNECTION: EventRelay_OnNotifyConnection(hwnd, (ifc_deviceconnection*)lParam, (DeviceConnectionEvent)wParam); return 0;
  374. case EVENTRELAY_WM_NOTIFY_COMMAND: EventRelay_OnNotifyCommand(hwnd, (ifc_devicecommand*)lParam, (DeviceCommandEvent)wParam); return 0;
  375. }
  376. return DefWindowProc(hwnd, uMsg, wParam, lParam);
  377. }