19#include <winpr/assert.h> 
   20#include <freerdp/config.h> 
   22#include <freerdp/log.h> 
   25#define TAG SERVER_TAG("shadow.input") 
   27static BOOL shadow_input_synchronize_event(rdpInput* input, UINT32 flags)
 
   30  rdpShadowClient* client = (rdpShadowClient*)input->context;
 
   32  WINPR_ASSERT(client->server);
 
   33  rdpShadowSubsystem* subsystem = client->server->subsystem;
 
   34  WINPR_ASSERT(subsystem);
 
   36  WLog_DBG(TAG, 
"[%s] flags=0x%04" PRIx16, client->mayInteract ? 
"use" : 
"discard", flags);
 
   37  if (!client->mayInteract)
 
   40  return IFCALLRESULT(TRUE, subsystem->SynchronizeEvent, subsystem, client, flags);
 
   43static BOOL shadow_input_keyboard_event(rdpInput* input, UINT16 flags, UINT8 code)
 
   46  rdpShadowClient* client = (rdpShadowClient*)input->context;
 
   48  WINPR_ASSERT(client->server);
 
   49  rdpShadowSubsystem* subsystem = client->server->subsystem;
 
   50  WINPR_ASSERT(subsystem);
 
   52  WLog_DBG(TAG, 
"[%s] flags=0x%04" PRIx16, client->mayInteract ? 
"use" : 
"discard", flags);
 
   53  if (!client->mayInteract)
 
   56  return IFCALLRESULT(TRUE, subsystem->KeyboardEvent, subsystem, client, flags, code);
 
   59static BOOL shadow_input_unicode_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code)
 
   62  rdpShadowClient* client = (rdpShadowClient*)input->context;
 
   64  WINPR_ASSERT(client->server);
 
   65  rdpShadowSubsystem* subsystem = client->server->subsystem;
 
   66  WINPR_ASSERT(subsystem);
 
   68  WLog_DBG(TAG, 
"[%s] flags=0x%04" PRIx16, client->mayInteract ? 
"use" : 
"discard", flags);
 
   69  if (!client->mayInteract)
 
   72  return IFCALLRESULT(TRUE, subsystem->UnicodeKeyboardEvent, subsystem, client, flags, code);
 
   75static BOOL shadow_input_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y)
 
   78  rdpShadowClient* client = (rdpShadowClient*)input->context;
 
   80  WINPR_ASSERT(client->server);
 
   81  rdpShadowSubsystem* subsystem = client->server->subsystem;
 
   82  WINPR_ASSERT(subsystem);
 
   84  if (client->server->shareSubRect)
 
   86    x += client->server->subRect.left;
 
   87    y += client->server->subRect.top;
 
   90  if ((flags & (PTR_FLAGS_WHEEL | PTR_FLAGS_HWHEEL | PTR_FLAGS_WHEEL_NEGATIVE)) == 0)
 
   95    if ((client->pointerX == subsystem->pointerX) && (client->pointerY == subsystem->pointerY))
 
   97      flags &= ~PTR_FLAGS_MOVE;
 
   99      if (!(flags & (PTR_FLAGS_BUTTON1 | PTR_FLAGS_BUTTON2 | PTR_FLAGS_BUTTON3)))
 
  104  WLog_DBG(TAG, 
"[%s] flags=0x%04" PRIx16 
", x=%" PRIu16 
", y=%" PRIu16,
 
  105           client->mayInteract ? 
"use" : 
"discard", flags, x, y);
 
  106  if (!client->mayInteract)
 
  109  return IFCALLRESULT(TRUE, subsystem->MouseEvent, subsystem, client, flags, x, y);
 
  112static BOOL shadow_input_rel_mouse_event(rdpInput* input, UINT16 flags, INT16 xDelta, INT16 yDelta)
 
  116  rdpShadowClient* client = (rdpShadowClient*)input->context;
 
  117  WINPR_ASSERT(client);
 
  118  WINPR_ASSERT(client->server);
 
  120  rdpShadowSubsystem* subsystem = client->server->subsystem;
 
  121  WINPR_ASSERT(subsystem);
 
  123  WLog_DBG(TAG, 
"[%s] flags=0x%04" PRIx16 
", x=%" PRId16 
", y=%" PRId16,
 
  124           client->mayInteract ? 
"use" : 
"discard", flags, xDelta, yDelta);
 
  125  const uint16_t mask = PTR_FLAGS_MOVE | PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON1 | PTR_FLAGS_BUTTON2 |
 
  126                        PTR_FLAGS_BUTTON3 | PTR_XFLAGS_BUTTON1 | PTR_XFLAGS_BUTTON2;
 
  127  if ((flags & mask) != 0)
 
  129    WLog_WARN(TAG, 
"Unknown flags 0x%04" PRIx16, flags & ~mask);
 
  131  if (!client->mayInteract)
 
  134  return IFCALLRESULT(TRUE, subsystem->RelMouseEvent, subsystem, client, flags, xDelta, yDelta);
 
  137static BOOL shadow_input_extended_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y)
 
  140  rdpShadowClient* client = (rdpShadowClient*)input->context;
 
  141  WINPR_ASSERT(client);
 
  142  WINPR_ASSERT(client->server);
 
  143  rdpShadowSubsystem* subsystem = client->server->subsystem;
 
  144  WINPR_ASSERT(subsystem);
 
  146  if (client->server->shareSubRect)
 
  148    x += client->server->subRect.left;
 
  149    y += client->server->subRect.top;
 
  152  client->pointerX = x;
 
  153  client->pointerY = y;
 
  155  WLog_DBG(TAG, 
"[%s] flags=0x%04" PRIx16 
", x=%" PRIu16 
", y=%" PRIu16,
 
  156           client->mayInteract ? 
"use" : 
"discard", flags, x, y);
 
  157  if (!client->mayInteract)
 
  160  return IFCALLRESULT(TRUE, subsystem->ExtendedMouseEvent, subsystem, client, flags, x, y);
 
  163void shadow_input_register_callbacks(rdpInput* input)
 
  166  input->SynchronizeEvent = shadow_input_synchronize_event;
 
  167  input->KeyboardEvent = shadow_input_keyboard_event;
 
  168  input->UnicodeKeyboardEvent = shadow_input_unicode_keyboard_event;
 
  169  input->MouseEvent = shadow_input_mouse_event;
 
  170  input->ExtendedMouseEvent = shadow_input_extended_mouse_event;
 
  171  input->RelMouseEvent = shadow_input_rel_mouse_event;