select-gui.c 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. /*
  2. * Implementation of do_select() for network.c to use, that uses
  3. * WSAAsyncSelect to convert network activity into window messages,
  4. * for integration into a GUI event loop.
  5. */
  6. #include "putty.h"
  7. static HWND winsel_hwnd = NULL;
  8. void winselgui_set_hwnd(HWND hwnd)
  9. {
  10. winsel_hwnd = hwnd;
  11. }
  12. void winselgui_clear_hwnd(void)
  13. {
  14. winsel_hwnd = NULL;
  15. }
  16. const char *do_select(SOCKET skt, bool enable)
  17. {
  18. int msg, events;
  19. if (enable) {
  20. msg = WM_NETEVENT;
  21. events = (FD_CONNECT | FD_READ | FD_WRITE |
  22. FD_OOB | FD_CLOSE | FD_ACCEPT);
  23. } else {
  24. msg = events = 0;
  25. }
  26. assert(winsel_hwnd);
  27. if (p_WSAAsyncSelect(skt, winsel_hwnd, msg, events) == SOCKET_ERROR)
  28. return winsock_error_string(p_WSAGetLastError());
  29. return NULL;
  30. }
  31. struct wm_netevent_params {
  32. /* Used to pass data to wm_netevent_callback */
  33. WPARAM wParam;
  34. LPARAM lParam;
  35. };
  36. static void wm_netevent_callback(void *vctx)
  37. {
  38. struct wm_netevent_params *params = (struct wm_netevent_params *)vctx;
  39. select_result(params->wParam, params->lParam);
  40. sfree(params);
  41. }
  42. void winselgui_response(WPARAM wParam, LPARAM lParam)
  43. {
  44. /*
  45. * To protect against re-entrancy when Windows's recv()
  46. * immediately triggers a new WSAAsyncSelect window message, we
  47. * don't call select_result directly from this handler but instead
  48. * wait until we're back out at the top level of the message loop.
  49. */
  50. struct wm_netevent_params *params = snew(struct wm_netevent_params);
  51. params->wParam = wParam;
  52. params->lParam = lParam;
  53. queue_toplevel_callback(wm_netevent_callback, params);
  54. }