void rfbProcessUDPInput(int sock)
{
  int n;
  rfbClientToServerMsg msg;

  if ((n = read(sock, (char *)&msg, sizeof(msg))) <= 0) {
    if (n < 0)
      rfbLogPerror("rfbProcessUDPInput: read");
    rfbDisconnectUDPSock();
    return;
  }

  switch (msg.type) {
    case rfbKeyEvent:
      if (n != sz_rfbKeyEventMsg) {
        rfbLog("rfbProcessUDPInput: key event incorrect length\n");
        rfbDisconnectUDPSock();
        return;
      }
      if (!rfbViewOnly)
        KeyEvent((KeySym)Swap32IfLE(msg.ke.key), msg.ke.down);
      break;

    case rfbPointerEvent:
      if (n != sz_rfbPointerEventMsg) {
        rfbLog("rfbProcessUDPInput: ptr event incorrect length\n");
        rfbDisconnectUDPSock();
        return;
      }
      if (!rfbViewOnly)
        PtrAddEvent(msg.pe.buttonMask, Swap16IfLE(msg.pe.x),
                    Swap16IfLE(msg.pe.y), 0);
      break;

    default:
      rfbLog("rfbProcessUDPInput: unknown message type %d\n", msg.type);
      rfbDisconnectUDPSock();
  }
}
void rfbProcessUDPInput(int sock)
{
  int n;
  rfbClientToServerMsg msg;

  if ((n = read(sock, (char *)&msg, sizeof(msg))) <= 0) {
    if (n < 0)
      rfbLogPerror("rfbProcessUDPInput: read");
    rfbDisconnectUDPSock();
    return;
  }

  switch (msg.type) {
    case rfbKeyEvent:
      if (n != sz_rfbKeyEventMsg) {
        rfbLog("rfbProcessUDPInput: key event incorrect length\n");
        rfbDisconnectUDPSock();
        return;
      }
      if (!rfbViewOnly)
        KeyEvent((KeySym)Swap32IfLE(msg.ke.key), msg.ke.down);
      break;

    case rfbPointerEvent:
      if (n != sz_rfbPointerEventMsg) {
        rfbLog("rfbProcessUDPInput: ptr event incorrect length\n");
        rfbDisconnectUDPSock();
        return;
      }
      if (!rfbViewOnly)
        PtrAddEvent(msg.pe.buttonMask, Swap16IfLE(msg.pe.x),
                    Swap16IfLE(msg.pe.y), 0);
      break;

    default:
      rfbLog("rfbProcessUDPInput: unknown message type %d\n", msg.type);
      rfbDisconnectUDPSock();
  }
}