[haiku-commits] BRANCH jessicah-github.synergy [81423a3] src/add-ons/input_server/devices/synergy

  • From: jessicah-github.synergy <community@xxxxxxxxxxxx>
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Wed, 1 Oct 2014 13:01:33 +0200 (CEST)

added 4 changesets to branch 'refs/remotes/jessicah-github/synergy'
old head: e0b88faae29e4f09ce24b8c16182d4a0a739b518
new head: 81423a30f7034de7790bb5ae451a6cb2434be37f
overview: https://github.com/jessicah/haiku/compare/e0b88fa...81423a3

----------------------------------------------------------------------------

bd3ce77: synergy: handle CBYE command
  
  * this enables the client to reconnect to the server after it
    has been shutdown and later restarted; this fixes an issue
    where Haiku would lose the connection to a Windows server
    when the screen is locked

accad32: synergy: correct line endings to LF

fded361: synergy: don't leak the BNotification and BBitmap objects

81423a3: synergy: major cleanup/refactor

                         [ Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx> ]

----------------------------------------------------------------------------

4 files changed, 902 insertions(+), 911 deletions(-)
.../devices/synergy/haiku-usynergy.cpp           |  420 +++---
.../devices/synergy/haiku-usynergy.h             |  107 +-
.../input_server/devices/synergy/uSynergy.c      | 1279 +++++++++---------
.../input_server/devices/synergy/uSynergy.h      |    7 +-

############################################################################

Commit:      bd3ce7761d1230db334c0860b9cb093293315d73
Author:      Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx>
Date:        Wed Oct  1 05:57:12 2014 UTC

synergy: handle CBYE command

* this enables the client to reconnect to the server after it
  has been shutdown and later restarted; this fixes an issue
  where Haiku would lose the connection to a Windows server
  when the screen is locked

----------------------------------------------------------------------------

diff --git a/src/add-ons/input_server/devices/synergy/uSynergy.c 
b/src/add-ons/input_server/devices/synergy/uSynergy.c
index 8ebbd46..7b0eb56 100644
--- a/src/add-ons/input_server/devices/synergy/uSynergy.c
+++ b/src/add-ons/input_server/devices/synergy/uSynergy.c
@@ -167,6 +167,19 @@ static void sSendMouseCallback(uSynergyContext *context)
 
 
 /**
+@brief Mark context as being disconnected
+**/
+static void sSetDisconnected(uSynergyContext *context)
+{
+       context->m_connected            = USYNERGY_FALSE;
+       context->m_hasReceivedHello = USYNERGY_FALSE;
+       context->m_isCaptured           = USYNERGY_FALSE;
+       context->m_replyCur                     = context->m_replyBuffer + 4;
+       context->m_sequenceNumber       = 0;
+}
+
+
+/**
 @brief Send keyboard callback when a key has been pressed or released
 **/
 static void sSendKeyboardCallback(uSynergyContext *context, uint16_t key, 
uint16_t modifiers, uSynergyBool down, uSynergyBool repeat)
@@ -428,6 +441,13 @@ static void sProcessMessage(uSynergyContext *context, 
const uint8_t *message)
                        parse_msg += size;
                }
        }
+       else if (USYNERGY_IS_PACKET("CBYE"))
+       {
+               // Server is closing connection
+               sSetDisconnected(context);
+               sTrace(context, "Server has quit");
+               return;
+       }
        else
        {
                // Unknown packet, could be any of these
@@ -456,19 +476,6 @@ static void sProcessMessage(uSynergyContext *context, 
const uint8_t *message)
 
 
 
-/**
-@brief Mark context as being disconnected
-**/
-static void sSetDisconnected(uSynergyContext *context)
-{
-       context->m_connected            = USYNERGY_FALSE;
-       context->m_hasReceivedHello = USYNERGY_FALSE;
-       context->m_isCaptured           = USYNERGY_FALSE;
-       context->m_replyCur                     = context->m_replyBuffer + 4;
-       context->m_sequenceNumber       = 0;
-}
-
-
 
 /**
 @brief Update a connected context

############################################################################

Commit:      accad320891683c860b596775e454c5417d95319
Author:      Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx>
Date:        Wed Oct  1 05:59:31 2014 UTC

synergy: correct line endings to LF

----------------------------------------------------------------------------

diff --git a/src/add-ons/input_server/devices/synergy/uSynergy.c 
b/src/add-ons/input_server/devices/synergy/uSynergy.c
index 7b0eb56..d745258 100644
--- a/src/add-ons/input_server/devices/synergy/uSynergy.c
+++ b/src/add-ons/input_server/devices/synergy/uSynergy.c
@@ -1,643 +1,643 @@
-/*
-uSynergy client -- Implementation for the embedded Synergy client library
-  version 1.0.0, July 7th, 2012
-
-Copyright (c) 2012 Alex Evans
-
-This software is provided 'as-is', without any express or implied
-warranty. In no event will the authors be held liable for any damages
-arising from the use of this software.
-
-Permission is granted to anyone to use this software for any purpose,
-including commercial applications, and to alter it and redistribute it
-freely, subject to the following restrictions:
-
-   1. The origin of this software must not be misrepresented; you must not
-   claim that you wrote the original software. If you use this software
-   in a product, an acknowledgment in the product documentation would be
-   appreciated but is not required.
-
-   2. Altered source versions must be plainly marked as such, and must not be
-   misrepresented as being the original software.
-
-   3. This notice may not be removed or altered from any source
-   distribution.
-*/
-#include "uSynergy.h"
-#include <stdio.h>
-#include <string.h>
-
-
-
-//---------------------------------------------------------------------------------------------------------------------
-//     Internal helpers
-//---------------------------------------------------------------------------------------------------------------------
-
-
-
-/**
-@brief Read 16 bit integer in network byte order and convert to native byte 
order
-**/
-static int16_t sNetToNative16(const unsigned char *value)
-{
-#ifdef USYNERGY_LITTLE_ENDIAN
-       return value[1] | (value[0] << 8);
-#else
-       return value[0] | (value[1] << 8);
-#endif
-}
-
-
-
-/**
-@brief Read 32 bit integer in network byte order and convert to native byte 
order
-**/
-static int32_t sNetToNative32(const unsigned char *value)
-{
-#ifdef USYNERGY_LITTLE_ENDIAN
-       return value[3] | (value[2] << 8) | (value[1] << 16) | (value[0] << 24);
-#else
-       return value[0] | (value[1] << 8) | (value[2] << 16) | (value[3] << 24);
-#endif
-}
-
-
-
-/**
-@brief Trace text to client
-**/
-static void sTrace(uSynergyContext *context, const char* text)
-{
-       // Don't trace if we don't have a trace function
-       if (context->m_traceFunc != 0L)
-               context->m_traceFunc(context->m_cookie, text);
-}
-
-
-
-/**
-@brief Add string to reply packet
-**/
-static void sAddString(uSynergyContext *context, const char *string)
-{
-       size_t len = strlen(string);
-       memcpy(context->m_replyCur, string, len);
-       context->m_replyCur += len;
-}
-
-
-
-/**
-@brief Add uint8 to reply packet
-**/
-static void sAddUInt8(uSynergyContext *context, uint8_t value)
-{
-       *context->m_replyCur++ = value;
-}
-
-
-
-/**
-@brief Add uint16 to reply packet
-**/
-static void sAddUInt16(uSynergyContext *context, uint16_t value)
-{
-       uint8_t *reply = context->m_replyCur;
-       *reply++ = (uint8_t)(value >> 8);
-       *reply++ = (uint8_t)value;
-       context->m_replyCur = reply;
-}
-
-
-
-/**
-@brief Add uint32 to reply packet
-**/
-static void sAddUInt32(uSynergyContext *context, uint32_t value)
-{
-       uint8_t *reply = context->m_replyCur;
-       *reply++ = (uint8_t)(value >> 24);
-       *reply++ = (uint8_t)(value >> 16);
-       *reply++ = (uint8_t)(value >> 8);
-       *reply++ = (uint8_t)value;
-       context->m_replyCur = reply;
-}
-
-
-
-/**
-@brief Send reply packet
-**/
-static uSynergyBool sSendReply(uSynergyContext *context)
-{
-       // Set header size
-       uint8_t         *reply_buf      = context->m_replyBuffer;
-       uint32_t        reply_len       = (uint32_t)(context->m_replyCur - 
reply_buf);                          /* Total size of reply */
-       uint32_t        body_len        = reply_len - 4;                        
                                                                /* Size of body 
*/
-       uSynergyBool ret;
-       reply_buf[0] = (uint8_t)(body_len >> 24);
-       reply_buf[1] = (uint8_t)(body_len >> 16);
-       reply_buf[2] = (uint8_t)(body_len >> 8);
-       reply_buf[3] = (uint8_t)body_len;
-
-       // Send reply
-       ret = context->m_sendFunc(context->m_cookie, context->m_replyBuffer, 
reply_len);
-
-       // Reset reply buffer write pointer
-       context->m_replyCur = context->m_replyBuffer+4;
-       return ret;
-}
-
-
-
-/**
-@brief Call mouse callback after a mouse event
-**/
-static void sSendMouseCallback(uSynergyContext *context)
-{
-       // Skip if no callback is installed
-       if (context->m_mouseCallback == 0L)
-               return;
-
-       // Send callback
-       context->m_mouseCallback(context->m_cookie, context->m_mouseX, 
context->m_mouseY, context->m_mouseWheelX,
-               context->m_mouseWheelY, context->m_mouseButtonLeft, 
context->m_mouseButtonRight, context->m_mouseButtonMiddle);
-}
-
-
-
-/**
-@brief Mark context as being disconnected
-**/
-static void sSetDisconnected(uSynergyContext *context)
-{
-       context->m_connected            = USYNERGY_FALSE;
-       context->m_hasReceivedHello = USYNERGY_FALSE;
-       context->m_isCaptured           = USYNERGY_FALSE;
-       context->m_replyCur                     = context->m_replyBuffer + 4;
-       context->m_sequenceNumber       = 0;
-}
-
-
-/**
-@brief Send keyboard callback when a key has been pressed or released
-**/
-static void sSendKeyboardCallback(uSynergyContext *context, uint16_t key, 
uint16_t modifiers, uSynergyBool down, uSynergyBool repeat)
-{
-       // Skip if no callback is installed
-       if (context->m_keyboardCallback == 0L)
-               return;
-
-       // Send callback
-       context->m_keyboardCallback(context->m_cookie, key, modifiers, down, 
repeat);
-}
-
-
-
-/**
-@brief Send joystick callback
-**/
-static void sSendJoystickCallback(uSynergyContext *context, uint8_t joyNum)
-{
-       int8_t *sticks;
-
-       // Skip if no callback is installed
-       if (context->m_joystickCallback == 0L)
-               return;
-
-       // Send callback
-       sticks = context->m_joystickSticks[joyNum];
-       context->m_joystickCallback(context->m_cookie, joyNum, 
context->m_joystickButtons[joyNum], sticks[0], sticks[1], sticks[2], sticks[3]);
-}
-
-
-
-/**
-@brief Parse a single client message, update state, send callbacks and send 
replies
-**/
-#define USYNERGY_IS_PACKET(pkt_id)     memcmp(message+4, pkt_id, 4)==0
-static void sProcessMessage(uSynergyContext *context, const uint8_t *message)
-{
-       // We have a packet!
-       if (memcmp(message+4, "Synergy", 7)==0)
-       {
-               // Welcome message
-               //              kMsgHello                       = 
"Synergy%2i%2i"
-               //              kMsgHelloBack           = "Synergy%2i%2i%s"
-               sAddString(context, "Synergy");
-               sAddUInt16(context, USYNERGY_PROTOCOL_MAJOR);
-               sAddUInt16(context, USYNERGY_PROTOCOL_MINOR);
-               sAddUInt32(context, (uint32_t)strlen(context->m_clientName));
-               sAddString(context, context->m_clientName);
-               if (!sSendReply(context))
-               {
-                       // Send reply failed, let's try to reconnect
-                       sTrace(context, "SendReply failed, trying to reconnect 
in a second");
-                       context->m_connected = USYNERGY_FALSE;
-                       context->m_sleepFunc(context->m_cookie, 1000);
-               }
-               else
-               {
-                       // Let's assume we're connected
-                       char buffer[256+1];
-                       sprintf(buffer, "Connected as client \"%s\"", 
context->m_clientName);
-                       sTrace(context, buffer);
-                       context->m_hasReceivedHello = USYNERGY_TRUE;
-               }
-               return;
-       }
-       else if (USYNERGY_IS_PACKET("QINF"))
-       {
-               // Screen info. Reply with DINF
-               //              kMsgQInfo                       = "QINF"
-               //              kMsgDInfo                       = 
"DINF%2i%2i%2i%2i%2i%2i%2i"
-               uint16_t x = 0, y = 0, warp = 0;
-               sAddString(context, "DINF");
-               sAddUInt16(context, x);
-               sAddUInt16(context, y);
-               sAddUInt16(context, context->m_clientWidth);
-               sAddUInt16(context, context->m_clientHeight);
-               sAddUInt16(context, warp);
-               sAddUInt16(context, 0);         // mx?
-               sAddUInt16(context, 0);         // my?
-               sSendReply(context);
-               return;
-       }
-       else if (USYNERGY_IS_PACKET("CIAK"))
-       {
-               // Do nothing?
-               //              kMsgCInfoAck            = "CIAK"
-               return;
-       }
-       else if (USYNERGY_IS_PACKET("CROP"))
-       {
-               // Do nothing?
-               //              kMsgCResetOptions       = "CROP"
-               return;
-       }
-       else if (USYNERGY_IS_PACKET("CINN"))
-       {
-               // Screen enter. Reply with CNOP
-               //              kMsgCEnter                      = 
"CINN%2i%2i%4i%2i"
-
-               // Obtain the Synergy sequence number
-               context->m_sequenceNumber = sNetToNative32(message + 12);
-               context->m_isCaptured = USYNERGY_TRUE;
-
-               // Call callback
-               if (context->m_screenActiveCallback != 0L)
-                       context->m_screenActiveCallback(context->m_cookie, 
USYNERGY_TRUE);
-       }
-       else if (USYNERGY_IS_PACKET("COUT"))
-       {
-               // Screen leave
-               //              kMsgCLeave                      = "COUT"
-               context->m_isCaptured = USYNERGY_FALSE;
-
-               // Call callback
-               if (context->m_screenActiveCallback != 0L)
-                       context->m_screenActiveCallback(context->m_cookie, 
USYNERGY_FALSE);
-       }
-       else if (USYNERGY_IS_PACKET("DMDN"))
-       {
-               // Mouse down
-               //              kMsgDMouseDown          = "DMDN%1i"
-               char btn = message[8]-1;
-               if (btn==2)
-                       context->m_mouseButtonRight             = USYNERGY_TRUE;
-               else if (btn==1)
-                       context->m_mouseButtonMiddle    = USYNERGY_TRUE;
-               else
-                       context->m_mouseButtonLeft              = USYNERGY_TRUE;
-               sSendMouseCallback(context);
-       }
-       else if (USYNERGY_IS_PACKET("DMUP"))
-       {
-               // Mouse up
-               //              kMsgDMouseUp            = "DMUP%1i"
-               char btn = message[8]-1;
-               if (btn==2)
-                       context->m_mouseButtonRight             = 
USYNERGY_FALSE;
-               else if (btn==1)
-                       context->m_mouseButtonMiddle    = USYNERGY_FALSE;
-               else
-                       context->m_mouseButtonLeft              = 
USYNERGY_FALSE;
-               sSendMouseCallback(context);
-       }
-       else if (USYNERGY_IS_PACKET("DMMV"))
-       {
-               // Mouse move. Reply with CNOP
-               //              kMsgDMouseMove          = "DMMV%2i%2i"
-               context->m_mouseX = sNetToNative16(message+8);
-               context->m_mouseY = sNetToNative16(message+10);
-               sSendMouseCallback(context);
-       }
-       else if (USYNERGY_IS_PACKET("DMWM"))
-       {
-               // Mouse wheel
-               //              kMsgDMouseWheel         = "DMWM%2i%2i"
-               //              kMsgDMouseWheel1_0      = "DMWM%2i"
-               context->m_mouseWheelX += sNetToNative16(message+8);
-               context->m_mouseWheelY += sNetToNative16(message+10);
-               sSendMouseCallback(context);
-       }
-       else if (USYNERGY_IS_PACKET("DKDN"))
-       {
-               // Key down
-               //              kMsgDKeyDown            = "DKDN%2i%2i%2i"
-               //              kMsgDKeyDown1_0         = "DKDN%2i%2i"
-               //uint16_t id = sNetToNative16(message+8);
-               uint16_t mod = sNetToNative16(message+10);
-               uint16_t key = sNetToNative16(message+12);
-               sSendKeyboardCallback(context, key, mod, USYNERGY_TRUE, 
USYNERGY_FALSE);
-       }
-       else if (USYNERGY_IS_PACKET("DKRP"))
-       {
-               // Key repeat
-               //              kMsgDKeyRepeat          = "DKRP%2i%2i%2i%2i"
-               //              kMsgDKeyRepeat1_0       = "DKRP%2i%2i%2i"
-               uint16_t mod = sNetToNative16(message+10);
-//             uint16_t count = sNetToNative16(message+12);
-               uint16_t key = sNetToNative16(message+14);
-               sSendKeyboardCallback(context, key, mod, USYNERGY_TRUE, 
USYNERGY_TRUE);
-       }
-       else if (USYNERGY_IS_PACKET("DKUP"))
-       {
-               // Key up
-               //              kMsgDKeyUp                      = 
"DKUP%2i%2i%2i"
-               //              kMsgDKeyUp1_0           = "DKUP%2i%2i"
-               //uint16 id=Endian::sNetToNative(sbuf[4]);
-               uint16_t mod = sNetToNative16(message+10);
-               uint16_t key = sNetToNative16(message+12);
-               sSendKeyboardCallback(context, key, mod, USYNERGY_FALSE, 
USYNERGY_FALSE);
-       }
-       else if (USYNERGY_IS_PACKET("DGBT"))
-       {
-               // Joystick buttons
-               //              kMsgDGameButtons        = "DGBT%1i%2i";
-               uint8_t joy_num = message[8];
-               if (joy_num<USYNERGY_NUM_JOYSTICKS)
-               {
-                       // Copy button state, then send callback
-                       context->m_joystickButtons[joy_num] = (message[9] << 8) 
| message[10];
-                       sSendJoystickCallback(context, joy_num);
-               }
-       }
-       else if (USYNERGY_IS_PACKET("DGST"))
-       {
-               // Joystick sticks
-               //              kMsgDGameSticks         = "DGST%1i%1i%1i%1i%1i";
-               uint8_t joy_num = message[8];
-               if (joy_num<USYNERGY_NUM_JOYSTICKS)
-               {
-                       // Copy stick state, then send callback
-                       memcpy(context->m_joystickSticks[joy_num], message+9, 
4);
-                       sSendJoystickCallback(context, joy_num);
-               }
-       }
-       else if (USYNERGY_IS_PACKET("DSOP"))
-       {
-               // Set options
-               //              kMsgDSetOptions         = "DSOP%4I"
-       }
-       else if (USYNERGY_IS_PACKET("CALV"))
-       {
-               // Keepalive, reply with CALV and then CNOP
-               //              kMsgCKeepAlive          = "CALV"
-               sAddString(context, "CALV");
-               sSendReply(context);
-               // now reply with CNOP
-       }
-       else if (USYNERGY_IS_PACKET("DCLP"))
-       {
-               // Clipboard message
-               //              kMsgDClipboard          = "DCLP%1i%4i%s"
-               //
-               // The clipboard message contains:
-               //              1 uint32:       The size of the message
-               //              4 chars:        The identifier ("DCLP")
-               //              1 uint8:        The clipboard index
-               //              1 uint32:       The sequence number. It's zero, 
because this message is always coming from the server?
-               //              1 uint32:       The total size of the remaining 
'string' (as per the Synergy %s string format (which is 1 uint32 for size 
followed by a char buffer (not necessarily null terminated)).
-               //              1 uint32:       The number of formats present 
in the message
-               // And then 'number of formats' times the following:
-               //              1 uint32:       The format of the clipboard data
-               //              1 uint32:       The size n of the clipboard data
-               //              n uint8:        The clipboard data
-               const uint8_t * parse_msg       = message+17;
-               uint32_t                num_formats = sNetToNative32(parse_msg);
-               parse_msg += 4;
-               for (; num_formats; num_formats--)
-               {
-                       // Parse clipboard format header
-                       uint32_t format = sNetToNative32(parse_msg);
-                       uint32_t size   = sNetToNative32(parse_msg+4);
-                       parse_msg += 8;
-
-                       // Call callback
-                       if (context->m_clipboardCallback)
-                               context->m_clipboardCallback(context->m_cookie, 
format, parse_msg, size);
-
-                       parse_msg += size;
-               }
-       }
-       else if (USYNERGY_IS_PACKET("CBYE"))
-       {
-               // Server is closing connection
-               sSetDisconnected(context);
-               sTrace(context, "Server has quit");
-               return;
-       }
-       else
-       {
-               // Unknown packet, could be any of these
-               //              kMsgCNoop                       = "CNOP"
-               //              kMsgCClose                      = "CBYE"
-               //              kMsgCClipboard          = "CCLP%1i%4i"
-               //              kMsgCScreenSaver        = "CSEC%1i"
-               //              kMsgDKeyRepeat          = "DKRP%2i%2i%2i%2i"
-               //              kMsgDKeyRepeat1_0       = "DKRP%2i%2i%2i"
-               //              kMsgDMouseRelMove       = "DMRM%2i%2i"
-               //              kMsgEIncompatible       = "EICV%2i%2i"
-               //              kMsgEBusy                       = "EBSY"
-               //              kMsgEUnknown            = "EUNK"
-               //              kMsgEBad                        = "EBAD"
-               char buffer[64];
-               sprintf(buffer, "Unknown packet '%c%c%c%c'", message[4], 
message[5], message[6], message[7]);
-               sTrace(context, buffer);
-               return;
-       }
-
-       // Reply with CNOP maybe?
-       sAddString(context, "CNOP");
-       sSendReply(context);
-}
-#undef USYNERGY_IS_PACKET
-
-
-
-
-/**
-@brief Update a connected context
-**/
-static void sUpdateContext(uSynergyContext *context)
-{
-       /* Receive data (blocking) */
-       int receive_size = USYNERGY_RECEIVE_BUFFER_SIZE - context->m_receiveOfs;
-       int num_received = 0;
-       int packlen = 0;
-       if (context->m_receiveFunc(context->m_cookie, context->m_receiveBuffer 
+ context->m_receiveOfs, receive_size, &num_received) == USYNERGY_FALSE)
-       {
-               /* Receive failed, let's try to reconnect */
-               char buffer[128];
-               sprintf(buffer, "Receive failed (%d bytes asked, %d bytes 
received), trying to reconnect in a second", receive_size, num_received);
-               sTrace(context, buffer);
-               sSetDisconnected(context);
-               context->m_sleepFunc(context->m_cookie, 1000);
-               return;
-       }
-       context->m_receiveOfs += num_received;
-
-       /*      If we didn't receive any data then we're probably still polling 
to get connected and
-               therefore not getting any data back. To avoid overloading the 
system with a Synergy
-               thread that would hammer on polling, we let it rest for a bit 
if there's no data. */
-       if (num_received == 0)
-               context->m_sleepFunc(context->m_cookie, 500);
-
-       /* Check for timeouts */
-       if (context->m_hasReceivedHello)
-       {
-               uint32_t cur_time = context->m_getTimeFunc();
-               if (num_received == 0)
-               {
-                       /* Timeout after 2 secs of inactivity (we received no 
CALV) */
-                       if ((cur_time - context->m_lastMessageTime) > 
USYNERGY_IDLE_TIMEOUT)
-                               sSetDisconnected(context);
-               }
-               else
-                       context->m_lastMessageTime = cur_time;
-       }
-
-       /* Eat packets */
-       for (;;)
-       {
-               /* Grab packet length and bail out if the packet goes beyond 
the end of the buffer */
-               packlen = sNetToNative32(context->m_receiveBuffer);
-               if (packlen+4 > context->m_receiveOfs)
-                       break;
-
-               /* Process message */
-               sProcessMessage(context, context->m_receiveBuffer);
-
-               /* Move packet to front of buffer */
-               memmove(context->m_receiveBuffer, 
context->m_receiveBuffer+packlen+4, context->m_receiveOfs-packlen-4);
-               context->m_receiveOfs -= packlen+4;
-       }
-
-       /* Throw away over-sized packets */
-       if (packlen > USYNERGY_RECEIVE_BUFFER_SIZE)
-       {
-               /* Oversized packet, ditch tail end */
-               char buffer[128];
-               sprintf(buffer, "Oversized packet: '%c%c%c%c' (length %d)", 
context->m_receiveBuffer[4], context->m_receiveBuffer[5], 
context->m_receiveBuffer[6], context->m_receiveBuffer[7], packlen);
-               sTrace(context, buffer);
-               num_received = context->m_receiveOfs-4; // 4 bytes for the size 
field
-               while (num_received != packlen)
-               {
-                       int buffer_left = packlen - num_received;
-                       int to_receive = buffer_left < 
USYNERGY_RECEIVE_BUFFER_SIZE ? buffer_left : USYNERGY_RECEIVE_BUFFER_SIZE;
-                       int ditch_received = 0;
-                       if (context->m_receiveFunc(context->m_cookie, 
context->m_receiveBuffer, to_receive, &ditch_received) == USYNERGY_FALSE)
-                       {
-                               /* Receive failed, let's try to reconnect */
-                               sTrace(context, "Receive failed, trying to 
reconnect in a second");
-                               sSetDisconnected(context);
-                               context->m_sleepFunc(context->m_cookie, 1000);
-                               break;
-                       }
-                       else
-                       {
-                               num_received += ditch_received;
-                       }
-               }
-               context->m_receiveOfs = 0;
-       }
-}
-
-
-//---------------------------------------------------------------------------------------------------------------------
-//     Public interface
-//---------------------------------------------------------------------------------------------------------------------
-
-
-
-/**
-@brief Initialize uSynergy context
-**/
-void uSynergyInit(uSynergyContext *context)
-{
-       /* Zero memory */
-       memset(context, 0, sizeof(uSynergyContext));
-
-       /* Initialize to default state */
-       sSetDisconnected(context);
-}
-
-
-/**
-@brief Update uSynergy
-**/
-void uSynergyUpdate(uSynergyContext *context)
-{
-       if (context->m_connected)
-       {
-               /* Update context, receive data, call callbacks */
-               sUpdateContext(context);
-       }
-       else
-       {
-               /* Try to connect */
-               if (context->m_connectFunc(context->m_cookie))
-                       context->m_connected = USYNERGY_TRUE;
-       }
-}
-
-
-
-/**
-@brief Send clipboard data
-**/
-void uSynergySendClipboard(uSynergyContext *context, const char *text)
-{
-       // Calculate maximum size that will fit in a reply packet
-       uint32_t overhead_size =        4 +                                     
/* Message size */
-                                                               4 +             
                        /* Message ID */
-                                                               1 +             
                        /* Clipboard index */
-                                                               4 +             
                        /* Sequence number */
-                                                               4 +             
                        /* Rest of message size (because it's a Synergy string 
from here on) */
-                                                               4 +             
                        /* Number of clipboard formats */
-                                                               4 +             
                        /* Clipboard format */
-                                                               4;              
                        /* Clipboard data length */
-       uint32_t max_length = USYNERGY_REPLY_BUFFER_SIZE - overhead_size;
-
-       // Clip text to max length
-       uint32_t text_length = (uint32_t)strlen(text);
-       if (text_length > max_length)
-       {
-               char buffer[128];
-               sprintf(buffer, "Clipboard buffer too small, clipboard 
truncated at %d characters", max_length);
-               sTrace(context, buffer);
-               text_length = max_length;
-       }
-
-       // Assemble packet
-       sAddString(context, "DCLP");
-       sAddUInt8(context, 0);                                                  
/* Clipboard index */
-       sAddUInt32(context, context->m_sequenceNumber);
-       sAddUInt32(context, 4+4+4+text_length);                 /* Rest of 
message size: numFormats, format, length, data */
-       sAddUInt32(context, 1);                                                 
/* Number of formats (only text for now) */
-       sAddUInt32(context, USYNERGY_CLIPBOARD_FORMAT_TEXT);
-       sAddUInt32(context, text_length);
-       sAddString(context, text);
-       sSendReply(context);
-}
+/*
+uSynergy client -- Implementation for the embedded Synergy client library
+  version 1.0.0, July 7th, 2012
+
+Copyright (c) 2012 Alex Evans
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any damages
+arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it
+freely, subject to the following restrictions:
+
+   1. The origin of this software must not be misrepresented; you must not
+   claim that you wrote the original software. If you use this software
+   in a product, an acknowledgment in the product documentation would be
+   appreciated but is not required.
+
+   2. Altered source versions must be plainly marked as such, and must not be
+   misrepresented as being the original software.
+
+   3. This notice may not be removed or altered from any source
+   distribution.
+*/
+#include "uSynergy.h"
+#include <stdio.h>
+#include <string.h>
+
+
+
+//---------------------------------------------------------------------------------------------------------------------
+//     Internal helpers
+//---------------------------------------------------------------------------------------------------------------------
+
+
+
+/**
+@brief Read 16 bit integer in network byte order and convert to native byte 
order
+**/
+static int16_t sNetToNative16(const unsigned char *value)
+{
+#ifdef USYNERGY_LITTLE_ENDIAN
+       return value[1] | (value[0] << 8);
+#else
+       return value[0] | (value[1] << 8);
+#endif
+}
+
+
+
+/**
+@brief Read 32 bit integer in network byte order and convert to native byte 
order
+**/
+static int32_t sNetToNative32(const unsigned char *value)
+{
+#ifdef USYNERGY_LITTLE_ENDIAN
+       return value[3] | (value[2] << 8) | (value[1] << 16) | (value[0] << 24);
+#else
+       return value[0] | (value[1] << 8) | (value[2] << 16) | (value[3] << 24);
+#endif
+}
+
+
+
+/**
+@brief Trace text to client
+**/
+static void sTrace(uSynergyContext *context, const char* text)
+{
+       // Don't trace if we don't have a trace function
+       if (context->m_traceFunc != 0L)
+               context->m_traceFunc(context->m_cookie, text);
+}
+
+
+
+/**
+@brief Add string to reply packet
+**/
+static void sAddString(uSynergyContext *context, const char *string)
+{
+       size_t len = strlen(string);
+       memcpy(context->m_replyCur, string, len);
+       context->m_replyCur += len;
+}
+
+
+
+/**
+@brief Add uint8 to reply packet
+**/
+static void sAddUInt8(uSynergyContext *context, uint8_t value)
+{
+       *context->m_replyCur++ = value;
+}
+
+
+
+/**
+@brief Add uint16 to reply packet
+**/
+static void sAddUInt16(uSynergyContext *context, uint16_t value)
+{
+       uint8_t *reply = context->m_replyCur;
+       *reply++ = (uint8_t)(value >> 8);
+       *reply++ = (uint8_t)value;
+       context->m_replyCur = reply;
+}
+
+
+
+/**
+@brief Add uint32 to reply packet
+**/
+static void sAddUInt32(uSynergyContext *context, uint32_t value)
+{
+       uint8_t *reply = context->m_replyCur;
+       *reply++ = (uint8_t)(value >> 24);
+       *reply++ = (uint8_t)(value >> 16);
+       *reply++ = (uint8_t)(value >> 8);
+       *reply++ = (uint8_t)value;
+       context->m_replyCur = reply;
+}
+
+
+
+/**
+@brief Send reply packet
+**/
+static uSynergyBool sSendReply(uSynergyContext *context)
+{
+       // Set header size
+       uint8_t         *reply_buf      = context->m_replyBuffer;
+       uint32_t        reply_len       = (uint32_t)(context->m_replyCur - 
reply_buf);                          /* Total size of reply */
+       uint32_t        body_len        = reply_len - 4;                        
                                                                /* Size of body 
*/
+       uSynergyBool ret;
+       reply_buf[0] = (uint8_t)(body_len >> 24);
+       reply_buf[1] = (uint8_t)(body_len >> 16);
+       reply_buf[2] = (uint8_t)(body_len >> 8);
+       reply_buf[3] = (uint8_t)body_len;
+
+       // Send reply
+       ret = context->m_sendFunc(context->m_cookie, context->m_replyBuffer, 
reply_len);
+
+       // Reset reply buffer write pointer
+       context->m_replyCur = context->m_replyBuffer+4;
+       return ret;
+}
+
+
+
+/**
+@brief Call mouse callback after a mouse event
+**/
+static void sSendMouseCallback(uSynergyContext *context)
+{
+       // Skip if no callback is installed
+       if (context->m_mouseCallback == 0L)
+               return;
+
+       // Send callback
+       context->m_mouseCallback(context->m_cookie, context->m_mouseX, 
context->m_mouseY, context->m_mouseWheelX,
+               context->m_mouseWheelY, context->m_mouseButtonLeft, 
context->m_mouseButtonRight, context->m_mouseButtonMiddle);
+}
+
+
+
+/**
+@brief Mark context as being disconnected
+**/
+static void sSetDisconnected(uSynergyContext *context)
+{
+       context->m_connected            = USYNERGY_FALSE;
+       context->m_hasReceivedHello = USYNERGY_FALSE;
+       context->m_isCaptured           = USYNERGY_FALSE;
+       context->m_replyCur                     = context->m_replyBuffer + 4;
+       context->m_sequenceNumber       = 0;
+}
+
+
+/**
+@brief Send keyboard callback when a key has been pressed or released
+**/
+static void sSendKeyboardCallback(uSynergyContext *context, uint16_t key, 
uint16_t modifiers, uSynergyBool down, uSynergyBool repeat)
+{
+       // Skip if no callback is installed
+       if (context->m_keyboardCallback == 0L)
+               return;
+
+       // Send callback
+       context->m_keyboardCallback(context->m_cookie, key, modifiers, down, 
repeat);
+}
+
+
+
+/**
+@brief Send joystick callback
+**/
+static void sSendJoystickCallback(uSynergyContext *context, uint8_t joyNum)
+{
+       int8_t *sticks;
+
+       // Skip if no callback is installed
+       if (context->m_joystickCallback == 0L)
+               return;
+
+       // Send callback
+       sticks = context->m_joystickSticks[joyNum];
+       context->m_joystickCallback(context->m_cookie, joyNum, 
context->m_joystickButtons[joyNum], sticks[0], sticks[1], sticks[2], sticks[3]);
+}
+
+
+
+/**
+@brief Parse a single client message, update state, send callbacks and send 
replies
+**/
+#define USYNERGY_IS_PACKET(pkt_id)     memcmp(message+4, pkt_id, 4)==0
+static void sProcessMessage(uSynergyContext *context, const uint8_t *message)
+{
+       // We have a packet!
+       if (memcmp(message+4, "Synergy", 7)==0)
+       {
+               // Welcome message
+               //              kMsgHello                       = 
"Synergy%2i%2i"
+               //              kMsgHelloBack           = "Synergy%2i%2i%s"
+               sAddString(context, "Synergy");
+               sAddUInt16(context, USYNERGY_PROTOCOL_MAJOR);
+               sAddUInt16(context, USYNERGY_PROTOCOL_MINOR);
+               sAddUInt32(context, (uint32_t)strlen(context->m_clientName));
+               sAddString(context, context->m_clientName);
+               if (!sSendReply(context))
+               {
+                       // Send reply failed, let's try to reconnect
+                       sTrace(context, "SendReply failed, trying to reconnect 
in a second");
+                       context->m_connected = USYNERGY_FALSE;
+                       context->m_sleepFunc(context->m_cookie, 1000);
+               }
+               else
+               {
+                       // Let's assume we're connected
+                       char buffer[256+1];
+                       sprintf(buffer, "Connected as client \"%s\"", 
context->m_clientName);
+                       sTrace(context, buffer);
+                       context->m_hasReceivedHello = USYNERGY_TRUE;
+               }
+               return;
+       }
+       else if (USYNERGY_IS_PACKET("QINF"))
+       {
+               // Screen info. Reply with DINF
+               //              kMsgQInfo                       = "QINF"
+               //              kMsgDInfo                       = 
"DINF%2i%2i%2i%2i%2i%2i%2i"
+               uint16_t x = 0, y = 0, warp = 0;
+               sAddString(context, "DINF");
+               sAddUInt16(context, x);
+               sAddUInt16(context, y);
+               sAddUInt16(context, context->m_clientWidth);
+               sAddUInt16(context, context->m_clientHeight);
+               sAddUInt16(context, warp);
+               sAddUInt16(context, 0);         // mx?
+               sAddUInt16(context, 0);         // my?
+               sSendReply(context);
+               return;
+       }
+       else if (USYNERGY_IS_PACKET("CIAK"))
+       {
+               // Do nothing?
+               //              kMsgCInfoAck            = "CIAK"
+               return;
+       }
+       else if (USYNERGY_IS_PACKET("CROP"))
+       {
+               // Do nothing?
+               //              kMsgCResetOptions       = "CROP"
+               return;
+       }
+       else if (USYNERGY_IS_PACKET("CINN"))
+       {
+               // Screen enter. Reply with CNOP
+               //              kMsgCEnter                      = 
"CINN%2i%2i%4i%2i"
+
+               // Obtain the Synergy sequence number
+               context->m_sequenceNumber = sNetToNative32(message + 12);
+               context->m_isCaptured = USYNERGY_TRUE;
+
+               // Call callback
+               if (context->m_screenActiveCallback != 0L)
+                       context->m_screenActiveCallback(context->m_cookie, 
USYNERGY_TRUE);
+       }
+       else if (USYNERGY_IS_PACKET("COUT"))
+       {
+               // Screen leave
+               //              kMsgCLeave                      = "COUT"
+               context->m_isCaptured = USYNERGY_FALSE;
+
+               // Call callback
+               if (context->m_screenActiveCallback != 0L)
+                       context->m_screenActiveCallback(context->m_cookie, 
USYNERGY_FALSE);
+       }
+       else if (USYNERGY_IS_PACKET("DMDN"))
+       {
+               // Mouse down
+               //              kMsgDMouseDown          = "DMDN%1i"
+               char btn = message[8]-1;
+               if (btn==2)
+                       context->m_mouseButtonRight             = USYNERGY_TRUE;
+               else if (btn==1)
+                       context->m_mouseButtonMiddle    = USYNERGY_TRUE;
+               else
+                       context->m_mouseButtonLeft              = USYNERGY_TRUE;
+               sSendMouseCallback(context);
+       }
+       else if (USYNERGY_IS_PACKET("DMUP"))
+       {
+               // Mouse up
+               //              kMsgDMouseUp            = "DMUP%1i"
+               char btn = message[8]-1;
+               if (btn==2)
+                       context->m_mouseButtonRight             = 
USYNERGY_FALSE;
+               else if (btn==1)
+                       context->m_mouseButtonMiddle    = USYNERGY_FALSE;
+               else
+                       context->m_mouseButtonLeft              = 
USYNERGY_FALSE;
+               sSendMouseCallback(context);
+       }
+       else if (USYNERGY_IS_PACKET("DMMV"))
+       {
+               // Mouse move. Reply with CNOP
+               //              kMsgDMouseMove          = "DMMV%2i%2i"
+               context->m_mouseX = sNetToNative16(message+8);
+               context->m_mouseY = sNetToNative16(message+10);
+               sSendMouseCallback(context);
+       }
+       else if (USYNERGY_IS_PACKET("DMWM"))
+       {
+               // Mouse wheel
+               //              kMsgDMouseWheel         = "DMWM%2i%2i"
+               //              kMsgDMouseWheel1_0      = "DMWM%2i"
+               context->m_mouseWheelX += sNetToNative16(message+8);
+               context->m_mouseWheelY += sNetToNative16(message+10);
+               sSendMouseCallback(context);
+       }
+       else if (USYNERGY_IS_PACKET("DKDN"))
+       {
+               // Key down
+               //              kMsgDKeyDown            = "DKDN%2i%2i%2i"
+               //              kMsgDKeyDown1_0         = "DKDN%2i%2i"
+               //uint16_t id = sNetToNative16(message+8);
+               uint16_t mod = sNetToNative16(message+10);
+               uint16_t key = sNetToNative16(message+12);
+               sSendKeyboardCallback(context, key, mod, USYNERGY_TRUE, 
USYNERGY_FALSE);
+       }
+       else if (USYNERGY_IS_PACKET("DKRP"))
+       {
+               // Key repeat
+               //              kMsgDKeyRepeat          = "DKRP%2i%2i%2i%2i"
+               //              kMsgDKeyRepeat1_0       = "DKRP%2i%2i%2i"
+               uint16_t mod = sNetToNative16(message+10);
+//             uint16_t count = sNetToNative16(message+12);
+               uint16_t key = sNetToNative16(message+14);
+               sSendKeyboardCallback(context, key, mod, USYNERGY_TRUE, 
USYNERGY_TRUE);
+       }
+       else if (USYNERGY_IS_PACKET("DKUP"))
+       {
+               // Key up
+               //              kMsgDKeyUp                      = 
"DKUP%2i%2i%2i"
+               //              kMsgDKeyUp1_0           = "DKUP%2i%2i"
+               //uint16 id=Endian::sNetToNative(sbuf[4]);
+               uint16_t mod = sNetToNative16(message+10);
+               uint16_t key = sNetToNative16(message+12);
+               sSendKeyboardCallback(context, key, mod, USYNERGY_FALSE, 
USYNERGY_FALSE);
+       }
+       else if (USYNERGY_IS_PACKET("DGBT"))
+       {
+               // Joystick buttons
+               //              kMsgDGameButtons        = "DGBT%1i%2i";
+               uint8_t joy_num = message[8];
+               if (joy_num<USYNERGY_NUM_JOYSTICKS)
+               {
+                       // Copy button state, then send callback
+                       context->m_joystickButtons[joy_num] = (message[9] << 8) 
| message[10];
+                       sSendJoystickCallback(context, joy_num);
+               }
+       }
+       else if (USYNERGY_IS_PACKET("DGST"))
+       {
+               // Joystick sticks
+               //              kMsgDGameSticks         = "DGST%1i%1i%1i%1i%1i";
+               uint8_t joy_num = message[8];
+               if (joy_num<USYNERGY_NUM_JOYSTICKS)
+               {
+                       // Copy stick state, then send callback
+                       memcpy(context->m_joystickSticks[joy_num], message+9, 
4);
+                       sSendJoystickCallback(context, joy_num);
+               }
+       }
+       else if (USYNERGY_IS_PACKET("DSOP"))
+       {
+               // Set options
+               //              kMsgDSetOptions         = "DSOP%4I"
+       }
+       else if (USYNERGY_IS_PACKET("CALV"))
+       {
+               // Keepalive, reply with CALV and then CNOP
+               //              kMsgCKeepAlive          = "CALV"
+               sAddString(context, "CALV");
+               sSendReply(context);
+               // now reply with CNOP
+       }
+       else if (USYNERGY_IS_PACKET("DCLP"))
+       {
+               // Clipboard message
+               //              kMsgDClipboard          = "DCLP%1i%4i%s"
+               //
+               // The clipboard message contains:
+               //              1 uint32:       The size of the message
+               //              4 chars:        The identifier ("DCLP")
+               //              1 uint8:        The clipboard index
+               //              1 uint32:       The sequence number. It's zero, 
because this message is always coming from the server?
+               //              1 uint32:       The total size of the remaining 
'string' (as per the Synergy %s string format (which is 1 uint32 for size 
followed by a char buffer (not necessarily null terminated)).
+               //              1 uint32:       The number of formats present 
in the message
+               // And then 'number of formats' times the following:
+               //              1 uint32:       The format of the clipboard data
+               //              1 uint32:       The size n of the clipboard data
+               //              n uint8:        The clipboard data
+               const uint8_t * parse_msg       = message+17;
+               uint32_t                num_formats = sNetToNative32(parse_msg);
+               parse_msg += 4;
+               for (; num_formats; num_formats--)
+               {
+                       // Parse clipboard format header
+                       uint32_t format = sNetToNative32(parse_msg);
+                       uint32_t size   = sNetToNative32(parse_msg+4);
+                       parse_msg += 8;
+
+                       // Call callback
+                       if (context->m_clipboardCallback)
+                               context->m_clipboardCallback(context->m_cookie, 
format, parse_msg, size);
+
+                       parse_msg += size;
+               }
+       }
+       else if (USYNERGY_IS_PACKET("CBYE"))
+       {
+               // Server is closing connection
+               sSetDisconnected(context);
+               sTrace(context, "Server has quit");
+               return;
+       }
+       else
+       {
+               // Unknown packet, could be any of these
+               //              kMsgCNoop                       = "CNOP"
+               //              kMsgCClose                      = "CBYE"
+               //              kMsgCClipboard          = "CCLP%1i%4i"
+               //              kMsgCScreenSaver        = "CSEC%1i"
+               //              kMsgDKeyRepeat          = "DKRP%2i%2i%2i%2i"
+               //              kMsgDKeyRepeat1_0       = "DKRP%2i%2i%2i"
+               //              kMsgDMouseRelMove       = "DMRM%2i%2i"
+               //              kMsgEIncompatible       = "EICV%2i%2i"
+               //              kMsgEBusy                       = "EBSY"
+               //              kMsgEUnknown            = "EUNK"
+               //              kMsgEBad                        = "EBAD"
+               char buffer[64];
+               sprintf(buffer, "Unknown packet '%c%c%c%c'", message[4], 
message[5], message[6], message[7]);
+               sTrace(context, buffer);
+               return;
+       }
+
+       // Reply with CNOP maybe?
+       sAddString(context, "CNOP");
+       sSendReply(context);
+}
+#undef USYNERGY_IS_PACKET
+
+
+
+
+/**
+@brief Update a connected context
+**/
+static void sUpdateContext(uSynergyContext *context)
+{
+       /* Receive data (blocking) */
+       int receive_size = USYNERGY_RECEIVE_BUFFER_SIZE - context->m_receiveOfs;
+       int num_received = 0;
+       int packlen = 0;
+       if (context->m_receiveFunc(context->m_cookie, context->m_receiveBuffer 
+ context->m_receiveOfs, receive_size, &num_received) == USYNERGY_FALSE)
+       {
+               /* Receive failed, let's try to reconnect */
+               char buffer[128];
+               sprintf(buffer, "Receive failed (%d bytes asked, %d bytes 
received), trying to reconnect in a second", receive_size, num_received);
+               sTrace(context, buffer);
+               sSetDisconnected(context);
+               context->m_sleepFunc(context->m_cookie, 1000);
+               return;
+       }
+       context->m_receiveOfs += num_received;
+
+       /*      If we didn't receive any data then we're probably still polling 
to get connected and
+               therefore not getting any data back. To avoid overloading the 
system with a Synergy
+               thread that would hammer on polling, we let it rest for a bit 
if there's no data. */
+       if (num_received == 0)
+               context->m_sleepFunc(context->m_cookie, 500);
+
+       /* Check for timeouts */
+       if (context->m_hasReceivedHello)
+       {
+               uint32_t cur_time = context->m_getTimeFunc();
+               if (num_received == 0)
+               {
+                       /* Timeout after 2 secs of inactivity (we received no 
CALV) */
+                       if ((cur_time - context->m_lastMessageTime) > 
USYNERGY_IDLE_TIMEOUT)
+                               sSetDisconnected(context);
+               }
+               else
+                       context->m_lastMessageTime = cur_time;
+       }
+
+       /* Eat packets */
+       for (;;)
+       {
+               /* Grab packet length and bail out if the packet goes beyond 
the end of the buffer */
+               packlen = sNetToNative32(context->m_receiveBuffer);
+               if (packlen+4 > context->m_receiveOfs)
+                       break;
+
+               /* Process message */
+               sProcessMessage(context, context->m_receiveBuffer);
+
+               /* Move packet to front of buffer */
+               memmove(context->m_receiveBuffer, 
context->m_receiveBuffer+packlen+4, context->m_receiveOfs-packlen-4);
+               context->m_receiveOfs -= packlen+4;
+       }
+
+       /* Throw away over-sized packets */
+       if (packlen > USYNERGY_RECEIVE_BUFFER_SIZE)
+       {
+               /* Oversized packet, ditch tail end */
+               char buffer[128];
+               sprintf(buffer, "Oversized packet: '%c%c%c%c' (length %d)", 
context->m_receiveBuffer[4], context->m_receiveBuffer[5], 
context->m_receiveBuffer[6], context->m_receiveBuffer[7], packlen);
+               sTrace(context, buffer);
+               num_received = context->m_receiveOfs-4; // 4 bytes for the size 
field
+               while (num_received != packlen)
+               {
+                       int buffer_left = packlen - num_received;
+                       int to_receive = buffer_left < 
USYNERGY_RECEIVE_BUFFER_SIZE ? buffer_left : USYNERGY_RECEIVE_BUFFER_SIZE;
+                       int ditch_received = 0;
+                       if (context->m_receiveFunc(context->m_cookie, 
context->m_receiveBuffer, to_receive, &ditch_received) == USYNERGY_FALSE)
+                       {
+                               /* Receive failed, let's try to reconnect */
+                               sTrace(context, "Receive failed, trying to 
reconnect in a second");
+                               sSetDisconnected(context);
+                               context->m_sleepFunc(context->m_cookie, 1000);
+                               break;
+                       }
+                       else
+                       {
+                               num_received += ditch_received;
+                       }
+               }
+               context->m_receiveOfs = 0;
+       }
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------
+//     Public interface
+//---------------------------------------------------------------------------------------------------------------------
+
+
+
+/**
+@brief Initialize uSynergy context
+**/
+void uSynergyInit(uSynergyContext *context)
+{
+       /* Zero memory */
+       memset(context, 0, sizeof(uSynergyContext));
+
+       /* Initialize to default state */
+       sSetDisconnected(context);
+}
+
+
+/**
+@brief Update uSynergy
+**/
+void uSynergyUpdate(uSynergyContext *context)
+{
+       if (context->m_connected)
+       {
+               /* Update context, receive data, call callbacks */
+               sUpdateContext(context);
+       }
+       else
+       {
+               /* Try to connect */
+               if (context->m_connectFunc(context->m_cookie))
+                       context->m_connected = USYNERGY_TRUE;
+       }
+}
+
+
+
+/**
+@brief Send clipboard data
+**/
+void uSynergySendClipboard(uSynergyContext *context, const char *text)
+{
+       // Calculate maximum size that will fit in a reply packet
+       uint32_t overhead_size =        4 +                                     
/* Message size */
+                                                               4 +             
                        /* Message ID */
+                                                               1 +             
                        /* Clipboard index */
+                                                               4 +             
                        /* Sequence number */
+                                                               4 +             
                        /* Rest of message size (because it's a Synergy string 
from here on) */
+                                                               4 +             
                        /* Number of clipboard formats */
+                                                               4 +             
                        /* Clipboard format */
+                                                               4;              
                        /* Clipboard data length */
+       uint32_t max_length = USYNERGY_REPLY_BUFFER_SIZE - overhead_size;
+
+       // Clip text to max length
+       uint32_t text_length = (uint32_t)strlen(text);
+       if (text_length > max_length)
+       {
+               char buffer[128];
+               sprintf(buffer, "Clipboard buffer too small, clipboard 
truncated at %d characters", max_length);
+               sTrace(context, buffer);
+               text_length = max_length;
+       }
+
+       // Assemble packet
+       sAddString(context, "DCLP");
+       sAddUInt8(context, 0);                                                  
/* Clipboard index */
+       sAddUInt32(context, context->m_sequenceNumber);
+       sAddUInt32(context, 4+4+4+text_length);                 /* Rest of 
message size: numFormats, format, length, data */
+       sAddUInt32(context, 1);                                                 
/* Number of formats (only text for now) */
+       sAddUInt32(context, USYNERGY_CLIPBOARD_FORMAT_TEXT);
+       sAddUInt32(context, text_length);
+       sAddString(context, text);
+       sSendReply(context);
+}

############################################################################

Commit:      fded36137d2ccdf30f756a48a42ea17dd41b11ad
Author:      Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx>
Date:        Wed Oct  1 06:47:27 2014 UTC

synergy: don't leak the BNotification and BBitmap objects

----------------------------------------------------------------------------

diff --git a/src/add-ons/input_server/devices/synergy/haiku-usynergy.cpp 
b/src/add-ons/input_server/devices/synergy/haiku-usynergy.cpp
index 69d3da6..6b0a3cf 100644
--- a/src/add-ons/input_server/devices/synergy/haiku-usynergy.cpp
+++ b/src/add-ons/input_server/devices/synergy/haiku-usynergy.cpp
@@ -1,6 +1,7 @@
 
 #include <Application.h>
 #include <Autolock.h>
+#include <Bitmap.h>
 #include <Clipboard.h>
 #include <FindDirectory.h>
 #include <Mime.h>
@@ -385,18 +386,19 @@ uSynergyGetTimeHaiku()
 void
 uSynergyTraceHaiku(uSynergyCookie cookie, const char *text)
 {
-       BNotification *notify = new BNotification(B_INFORMATION_NOTIFICATION);
+       BNotification notify(B_INFORMATION_NOTIFICATION);
        BString group("Synergy");
        BString content(text);
 
-       notify->SetGroup(group);
-       notify->SetContent(content);
+       notify.SetGroup(group);
+       notify.SetContent(content);
        BBitmap* bitmap = 
BTranslationUtils::GetBitmap("/boot/home/config/non-packaged/data/synergy-32.png");
        if (bitmap != NULL)
-               notify->SetIcon(bitmap);
+               notify.SetIcon(bitmap);
        else
                TRACE("synergy: couldn't load bitmap\n");
-       notify->Send();
+       notify.Send();
+       delete bitmap;
 }
 
 void

############################################################################

Commit:      81423a30f7034de7790bb5ae451a6cb2434be37f
Author:      Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx>
Date:        Wed Oct  1 10:47:19 2014 UTC

synergy: major cleanup/refactor

----------------------------------------------------------------------------

diff --git a/src/add-ons/input_server/devices/synergy/haiku-usynergy.cpp 
b/src/add-ons/input_server/devices/synergy/haiku-usynergy.cpp
index 6b0a3cf..591df07 100644
--- a/src/add-ons/input_server/devices/synergy/haiku-usynergy.cpp
+++ b/src/add-ons/input_server/devices/synergy/haiku-usynergy.cpp
@@ -1,4 +1,20 @@
-
+/*
+ * Copyright (c)
+ *      2014  Ed Robbins <edd.robbins@xxxxxxxxx>
+ *      2014  Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
 #include <Application.h>
 #include <Autolock.h>
 #include <Bitmap.h>
@@ -31,60 +47,88 @@
 
 #include "haiku-usynergy.h"
 
-#define FILE_UPDATED 'fiUp'
-
 
 #define TRACE_SYNERGY_DEVICE
 #ifdef TRACE_SYNERGY_DEVICE
-
-#      define CALLED(x...) \
-               debug_printf("%s:%s\n", "SynergyDevice", __FUNCTION__)
 #      define TRACE(x...) \
                do { debug_printf(x); } while (0)
-#      define LOG_EVENT(text...) debug_printf(text)
-#      define LOG_ERR(text...) TRACE(text)
 #else
 #      define TRACE(x...) do {} while (0)
-#      define CALLED(x...) TRACE(x)
-#      define LOG_ERR(text...) debug_printf(text)
-#      define LOG_EVENT(text...) TRACE(x)
 #endif
 
+#define FILE_UPDATED 'fiUp'
+
 
 const static uint32 kSynergyThreadPriority = B_FIRST_REAL_TIME_PRIORITY + 4;
 
+#define _U uSynergyInputServerDevice
+static bool uConnect(_U* device) {
+       return device->Connect();
+}
+static bool uSend(_U* device, const uint8* buffer, int length) {
+       return device->Send(buffer, length);
+}
+static bool uReceive(_U* device, uint8* buffer, int maxLength, int* outLength) 
{
+       return device->Receive(buffer, maxLength, outLength);
+}
+static void uSleep(void* unused, int milliseconds) {
+       snooze(milliseconds * 1000);
+}
+static uint32_t uGetTime() {
+       return system_time() / 1000;
+}
+static void uTrace(_U* device, const char* text) {
+       device->Trace(text);
+}
+static void uScreenActive(_U* device, bool active) {
+       device->ScreenActive(active);
+}
+static void uMouseCallback(_U* device, uint16 x, uint16 y, int16 wheelX, int16 
wheelY, bool buttonLeft, bool buttonRight, bool buttonMiddle) {
+       device->MouseCallback(x, y, wheelX, wheelY, buttonLeft, buttonRight, 
buttonMiddle);
+}
+static void uKeyboardCallback(_U* device, uint16 key, uint16 modifiers, bool 
isKeyDown, bool isKeyRepeat) {
+       device->KeyboardCallback(key, modifiers, isKeyDown, isKeyRepeat);
+}
+static void uJoystickCallback(_U* device, uint8_t joyNum, uint16_t buttons, 
int8_t leftStickX, int8_t leftStickY, int8_t rightStickX, int8_t rightStickY) {
+       device->JoystickCallback(joyNum, buttons, leftStickX, leftStickY, 
rightStickX, rightStickY);
+}
+static void uClipboardCallback(_U* device, enum uSynergyClipboardFormat 
format, const uint8_t* data, uint32_t size) {
+       device->ClipboardCallback(format, data, size);
+}
+#undef _U
+
+
 uSynergyInputServerDevice::uSynergyInputServerDevice()
        :
        BHandler("uSynergy Handler"),
        threadActive(false),
-       uSynergyHaikuContext(NULL),
-       synergyServerSocket(-1),
+       fContext(NULL),
+       fSocket(-1),
        fEnableSynergy(false),
        fServerAddress(NULL),
        fUpdateSettings(false),
        fKeymapLock("synergy keymap lock")
 {
-       CALLED();
-       uSynergyHaikuContext = 
(uSynergyContext*)malloc(sizeof(uSynergyContext));
-       uSynergyInit(uSynergyHaikuContext);
-
-       uSynergyHaikuContext->m_connectFunc             = uSynergyConnectHaiku;
-       uSynergyHaikuContext->m_receiveFunc             = uSynergyReceiveHaiku;
-       uSynergyHaikuContext->m_sendFunc                = uSynergySendHaiku;
-       uSynergyHaikuContext->m_getTimeFunc             = uSynergyGetTimeHaiku;
-       uSynergyHaikuContext->m_screenActiveCallback    = 
uSynergyScreenActiveCallbackHaiku;
-       uSynergyHaikuContext->m_mouseCallback           = 
uSynergyMouseCallbackHaiku;
-       uSynergyHaikuContext->m_keyboardCallback        = 
uSynergyKeyboardCallbackHaiku;
-       uSynergyHaikuContext->m_sleepFunc               = uSynergySleepHaiku;
-       uSynergyHaikuContext->m_traceFunc               = uSynergyTraceHaiku;
-       uSynergyHaikuContext->m_joystickCallback        = 
uSynergyJoystickCallbackHaiku;
-       uSynergyHaikuContext->m_clipboardCallback       = 
uSynergyClipboardCallbackHaiku;
-       uSynergyHaikuContext->m_clientName              = "haiku";
-       uSynergyHaikuContext->m_cookie                  = (uSynergyCookie)this;
+       fContext = (uSynergyContext*)malloc(sizeof(uSynergyContext));
+       uSynergyInit(fContext);
+
+       fContext->m_connectFunc                         = &uConnect;
+       fContext->m_receiveFunc                         = &uReceive;
+       fContext->m_sendFunc                            = &uSend;
+       fContext->m_getTimeFunc                         = &uGetTime;
+       fContext->m_screenActiveCallback        = &uScreenActive;
+       fContext->m_mouseCallback                       = &uMouseCallback;
+       fContext->m_keyboardCallback            = &uKeyboardCallback;
+       fContext->m_sleepFunc                           = &uSleep;
+       fContext->m_traceFunc                           = &uTrace;
+       fContext->m_joystickCallback            = &uJoystickCallback;
+       fContext->m_clipboardCallback           = &uClipboardCallback;
+       fContext->m_clientName                          = "haiku";
+       fContext->m_cookie                                      = 
(uSynergyCookie)this;
 
        BRect screenRect = BScreen().Frame();
-       uSynergyHaikuContext->m_clientWidth             = 
(uint16_t)screenRect.Width() + 1;
-       uSynergyHaikuContext->m_clientHeight            = 
(uint16_t)screenRect.Height() + 1;
+       fContext->m_clientWidth         = (uint16_t)screenRect.Width() + 1;
+       fContext->m_clientHeight        = (uint16_t)screenRect.Height() + 1;
 
        if (be_app->Lock()) {
                be_app->AddHandler(this);
@@ -93,7 +137,7 @@ uSynergyInputServerDevice::uSynergyInputServerDevice()
 
        BPath path;
        if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) == B_OK)
-               path.Append("kernel/drivers/synergy");
+               path.Append("synergy_settings");
 
        fFilename = new char[strlen(path.Path()) + 1];
        strcpy(fFilename, path.Path());
@@ -103,19 +147,23 @@ uSynergyInputServerDevice::uSynergyInputServerDevice()
        BPrivate::BPathMonitor::StartWatching(fFilename, B_WATCH_STAT | 
B_WATCH_FILES_ONLY, this);
 
        _UpdateSettings();
-
-       TRACE("synergy: monitoring settings file at '%s'\n", fFilename);
 }
 
+
 uSynergyInputServerDevice::~uSynergyInputServerDevice()
 {
-       free(uSynergyHaikuContext);
+       if (be_app->Lock()) {
+               be_app->RemoveHandler(this);
+               be_app->Unlock();
+       }
+
+       free(fContext);
 }
 
+
 status_t
 uSynergyInputServerDevice::InitCheck()
 {
-       CALLED();
        input_device_ref *devices[3];
 
        input_device_ref mouse = { "uSynergy Mouse", B_POINTING_DEVICE, (void 
*)this };
@@ -130,10 +178,10 @@ uSynergyInputServerDevice::InitCheck()
        return B_OK;
 }
 
+
 void
 uSynergyInputServerDevice::MessageReceived(BMessage* message)
 {
-       CALLED();
        switch (message->what) {
                case B_PATH_MONITOR:
                {
@@ -165,7 +213,7 @@ uSynergyInputServerDevice::MessageReceived(BMessage* 
message)
                                be_clipboard->Unlock();
                        }
                        if (len > 0 && text != NULL) {
-                               
uSynergySendClipboard(this->uSynergyHaikuContext, text);
+                               uSynergySendClipboard(fContext, text);
                                TRACE("synergy: data added to clipboard\n");
                        } else
                                TRACE("synergy: couldn't add data to 
clipboard\n");
@@ -175,12 +223,14 @@ uSynergyInputServerDevice::MessageReceived(BMessage* 
message)
        }
 }
 
+
 status_t
 uSynergyInputServerDevice::Start(const char* name, void* cookie)
 {
-       CALLED();
-       if (fServerAddress == NULL || fEnableSynergy == false)
+       if (fServerAddress.Length() == 0 || fEnableSynergy == false) {
+               TRACE("synergy: not enabled, or no server specified\n");
                return B_NO_ERROR;
+       }
 
        status_t status = B_OK;
        char threadName[B_OS_NAME_LENGTH];
@@ -189,11 +239,11 @@ uSynergyInputServerDevice::Start(const char* name, void* 
cookie)
        TRACE("synergy: thread active = %d\n", threadActive);
 
        if ((atomic_get_and_set((int32*)&threadActive, true) & true) == true) {
-               TRACE("synergy: skipping thread spawn\n");
-               goto clean;
+               TRACE("synergy: main thread already running\n");
+               return B_OK;
        }
 
-       uSynergyThread = spawn_thread(uSynergyThreadLoop, threadName, 
kSynergyThreadPriority, (void*)this->uSynergyHaikuContext);
+       uSynergyThread = spawn_thread(_MainLoop, threadName, 
kSynergyThreadPriority, (void*)this);
 
        if (uSynergyThread < 0) {
                threadActive = false;
@@ -202,34 +252,31 @@ uSynergyInputServerDevice::Start(const char* name, void* 
cookie)
        } else {
                be_clipboard->StartWatching(this);
                status = resume_thread(uSynergyThread);
-               TRACE("synergy: spawned uSynergyThreadLoop!\n");
        }
-clean:
+
        return status;
 }
 
+
 status_t
 uSynergyInputServerDevice::Stop(const char* name, void* cookie)
 {
-       CALLED();
        threadActive = false;
        // this will stop the thread as soon as it reads the next packet
        be_clipboard->StopWatching(this);
 
        if (uSynergyThread >= 0) {
                // unblock the thread, which might wait on a semaphore.
-               TRACE("synergy: asking thread to stop...\n");
                suspend_thread(uSynergyThread);
                resume_thread(uSynergyThread);
                status_t dummy;
                wait_for_thread(uSynergyThread, &dummy);
-               uSynergyThread = -1;
-               TRACE("synergy: all stopped\n");
        }
 
        return B_OK;
 }
 
+
 status_t
 uSynergyInputServerDevice::SystemShuttingDown()
 {
@@ -238,6 +285,7 @@ uSynergyInputServerDevice::SystemShuttingDown()
        return B_OK;
 }
 
+
 status_t
 uSynergyInputServerDevice::Control(const char* name, void* cookie, uint32 
command, BMessage* message)
 {
@@ -249,24 +297,28 @@ uSynergyInputServerDevice::Control(const char* name, 
void* cookie, uint32 comman
        return B_BAD_VALUE;
 }
 
-BMessage*
-uSynergyInputServerDevice::_BuildMouseMessage(uint32 what, uint64 when, uint32 
buttons, float x, float y) const
+
+status_t
+uSynergyInputServerDevice::_MainLoop(void* arg)
 {
-       BMessage* message = new BMessage(what);
-       if (message == NULL)
-               return NULL;
+       uSynergyInputServerDevice *inputDevice = 
(uSynergyInputServerDevice*)arg;
 
-       if (message->AddInt64("when", when) < B_OK
-           || message->AddInt32("buttons", buttons) < B_OK
-           || message->AddFloat("x", x) < B_OK
-           || message->AddFloat("y", y) < B_OK) {
-               delete message;
-               return NULL;
+       while (inputDevice->threadActive) {
+               uSynergyUpdate(inputDevice->fContext);
+
+               if (inputDevice->fUpdateSettings) {
+                       inputDevice->_UpdateSettings();
+                       inputDevice->fUpdateSettings = false;
+               }
        }
 
-       return message;
+       close(inputDevice->fSocket);
+       inputDevice->fSocket = -1;
+
+       return B_OK;
 }
 
+
 void
 uSynergyInputServerDevice::_UpdateSettings()
 {
@@ -276,115 +328,71 @@ uSynergyInputServerDevice::_UpdateSettings()
        fControlKey = fKeymap.KeyForModifier(B_LEFT_CONTROL_KEY);
        fCommandKey = fKeymap.KeyForModifier(B_LEFT_COMMAND_KEY);
 
-       void* handle = load_driver_settings("synergy");
+       void* handle = load_driver_settings(fFilename);
        if (handle == NULL)
                return;
 
        fEnableSynergy = get_driver_boolean_parameter(handle, "enable", false, 
false);
-       const char *server = get_driver_parameter(handle, "server", NULL, NULL);
-       TRACE("synergy: settings: enable = %s, server = %s\n", fEnableSynergy ? 
"yes" : "no", server == NULL ? "(null)" : server);
-       if (server != NULL)
-               fServerAddress.SetTo(server);
+       fServerAddress = get_driver_parameter(handle, "server", NULL, NULL);
 
        unload_driver_settings(handle);
 }
 
-status_t
-uSynergyInputServerDevice::uSynergyThreadLoop(void* arg)
-{
-       uSynergyContext *uSynergyHaikuContext = (uSynergyContext*)arg;
-       uSynergyInputServerDevice *inputDevice = 
(uSynergyInputServerDevice*)uSynergyHaikuContext->m_cookie;
-
-       while (inputDevice->threadActive) {
-               uSynergyUpdate(uSynergyHaikuContext);
 
-               if (inputDevice->fUpdateSettings) {
-                       inputDevice->_UpdateSettings();
-                       inputDevice->fUpdateSettings = false;
-               }
-       }
-
-       TRACE("synergy: exiting thread loop\n");
-
-       close(inputDevice->synergyServerSocket);
-       inputDevice->synergyServerSocket = -1;
-
-       return B_OK;
-}
-
-
-uSynergyBool
-uSynergyConnectHaiku(uSynergyCookie cookie)
+bool
+uSynergyInputServerDevice::Connect()
 {
-       CALLED();
-       uSynergyInputServerDevice *inputDevice = 
(uSynergyInputServerDevice*)cookie;
-
-       if (inputDevice->fServerAddress.Length() == 0 || 
inputDevice->fEnableSynergy == false)
+       if (fServerAddress.Length() == 0 || fEnableSynergy == false)
                goto exit;
 
        struct sockaddr_in server;
 
        server.sin_family = AF_INET;
        server.sin_port = htons(24800);
-       inet_aton(inputDevice->fServerAddress.String(), &server.sin_addr);
-       TRACE("synergy: connecting to %s:%d\n", 
inputDevice->fServerAddress.String(), 24800);
+       inet_aton(fServerAddress.String(), &server.sin_addr);
 
-       inputDevice->synergyServerSocket = socket(PF_INET, SOCK_STREAM, 0);
+       TRACE("synergy: connecting to %s:%d\n", fServerAddress.String(), 24800);
 
-       if (inputDevice->synergyServerSocket < 0) {
+       fSocket = socket(PF_INET, SOCK_STREAM, 0);
+       if (fSocket < 0) {
                TRACE("synergy: socket couldn't be created\n");
                goto exit;
        }
 
-       if (connect(inputDevice->synergyServerSocket, (struct 
sockaddr*)&server, sizeof(struct sockaddr)) < 0 ) {
-               TRACE("synergy: %s: %d\n", "failed to connect to remote host", 
errno);
-               close(inputDevice->synergyServerSocket);
-               inputDevice->synergyServerSocket = -1;
+       if (connect(fSocket, (struct sockaddr*)&server, sizeof(struct 
sockaddr)) < 0 ) {
+               TRACE("synergy: %s: %x\n", "failed to connect to remote host", 
errno);
+               close(fSocket);
+               fSocket = -1;
                goto exit;
        }
-       else {
-               TRACE("synergy: connected to remote host!!!\n");
-               return USYNERGY_TRUE;
-       }
+       else
+               return true;
 exit:
        snooze(1000000);
-       return USYNERGY_FALSE;
+       return false;
 }
 
-uSynergyBool
-uSynergySendHaiku(uSynergyCookie cookie, const uint8_t *buffer, int length)
-{
-       uSynergyInputServerDevice *inputDevice = 
(uSynergyInputServerDevice*)cookie;
-
-       if (send(inputDevice->synergyServerSocket, buffer, length, 0) != length)
-               return USYNERGY_FALSE;
-       return USYNERGY_TRUE;
-}
 
-uSynergyBool
-uSynergyReceiveHaiku(uSynergyCookie cookie, uint8_t *buffer, int maxLength, 
int* outLength)
+bool
+uSynergyInputServerDevice::Send(const uint8_t* buffer, int32_t length)
 {
-       uSynergyInputServerDevice *inputDevice = 
(uSynergyInputServerDevice*)cookie;
-
-       if ((*outLength = recv(inputDevice->synergyServerSocket, buffer, 
maxLength, 0)) == -1)
-               return USYNERGY_FALSE;
-       return USYNERGY_TRUE;
+       if (send(fSocket, buffer, length, 0) != length)
+               return false;
+       return true;
 }
 
-void
-uSynergySleepHaiku(uSynergyCookie cookie, int timeMs)
-{
-       snooze(timeMs * 1000);
-}
 
-uint32_t
-uSynergyGetTimeHaiku()
+bool
+uSynergyInputServerDevice::Receive(uint8_t *buffer, int maxLength, int* 
outLength)
 {
-       return system_time() / 1000; // return milliseconds, not microseconds
+       if ((*outLength = recv(fSocket, buffer, maxLength, 0)) == -1)
+               return false;
+       return true;
 }
 
+
 void
-uSynergyTraceHaiku(uSynergyCookie cookie, const char *text)
+uSynergyInputServerDevice::Trace(const char *text)
 {
        BNotification notify(B_INFORMATION_NOTIFICATION);
        BString group("Synergy");
@@ -395,29 +403,46 @@ uSynergyTraceHaiku(uSynergyCookie cookie, const char 
*text)
        BBitmap* bitmap = 
BTranslationUtils::GetBitmap("/boot/home/config/non-packaged/data/synergy-32.png");
        if (bitmap != NULL)
                notify.SetIcon(bitmap);
-       else
-               TRACE("synergy: couldn't load bitmap\n");
        notify.Send();
        delete bitmap;
 }
 
+
 void
-uSynergyScreenActiveCallbackHaiku(uSynergyCookie cookie, uSynergyBool active)
+uSynergyInputServerDevice::ScreenActive(bool active)
+{
+}
+
+
+BMessage*
+uSynergyInputServerDevice::_BuildMouseMessage(uint32 what, uint64 when, uint32 
buttons, float x, float y) const
 {
+       BMessage* message = new BMessage(what);
+       if (message == NULL)
+               return NULL;
 
+       if (message->AddInt64("when", when) < B_OK
+           || message->AddInt32("buttons", buttons) < B_OK
+           || message->AddFloat("x", x) < B_OK
+           || message->AddFloat("y", y) < B_OK) {
+               delete message;
+               return NULL;
+       }
+
+       return message;
 }
 
+
 void
-uSynergyMouseCallbackHaiku(uSynergyCookie cookie, uint16_t x, uint16_t y, 
int16_t wheelX, int16_t wheelY, uSynergyBool buttonLeft, uSynergyBool 
buttonRight, uSynergyBool buttonMiddle)
+uSynergyInputServerDevice::MouseCallback(uint16_t x, uint16_t y, int16_t 
wheelX, int16_t wheelY, uSynergyBool buttonLeft, uSynergyBool buttonRight, 
uSynergyBool buttonMiddle)
 {
-       uSynergyInputServerDevice       *inputDevice = 
(uSynergyInputServerDevice*)cookie;
        static uint32_t                  oldButtons = 0, oldPressedButtons = 0;
        uint32_t                         buttons = 0;
        static uint16_t                  oldX = 0, oldY = 0, clicks = 0;
        static int16_t                  oldWheelX = 0, oldWheelY = 0;
        static uint64                   oldWhen = system_time();
-       float                            xVal = (float)x / 
(float)inputDevice->uSynergyHaikuContext->m_clientWidth;
-       float                            yVal = (float)y / 
(float)inputDevice->uSynergyHaikuContext->m_clientHeight;
+       float                            xVal = (float)x / 
(float)fContext->m_clientWidth;
+       float                            yVal = (float)y / 
(float)fContext->m_clientHeight;
 
        int64 timestamp = system_time();
 
@@ -433,7 +458,7 @@ uSynergyMouseCallbackHaiku(uSynergyCookie cookie, uint16_t 
x, uint16_t y, int16_
 
        if (buttons != oldButtons) {
                bool pressedButton = buttons > 0;
-               BMessage* message = 
inputDevice->_BuildMouseMessage(pressedButton ? B_MOUSE_DOWN : B_MOUSE_UP, 
timestamp, buttons, xVal, yVal);
+               BMessage* message = _BuildMouseMessage(pressedButton ? 
B_MOUSE_DOWN : B_MOUSE_UP, timestamp, buttons, xVal, yVal);
                if (pressedButton) {
                        if ((buttons == oldPressedButtons) && ((timestamp - 
oldWhen) < 500000))
                                clicks++;
@@ -447,15 +472,15 @@ uSynergyMouseCallbackHaiku(uSynergyCookie cookie, 
uint16_t x, uint16_t y, int16_
                        clicks = 1;
 
                if (message != NULL)
-                       inputDevice->EnqueueMessage(message);
+                       EnqueueMessage(message);
 
                oldButtons = buttons;
        }
 
        if ((x != oldX) || (y != oldY)) {
-               BMessage* message = 
inputDevice->_BuildMouseMessage(B_MOUSE_MOVED, timestamp, buttons, xVal, yVal);
+               BMessage* message = _BuildMouseMessage(B_MOUSE_MOVED, 
timestamp, buttons, xVal, yVal);
                if (message != NULL)
-                       inputDevice->EnqueueMessage(message);
+                       EnqueueMessage(message);
                oldX = x;
                oldY = y;
        }
@@ -466,7 +491,7 @@ uSynergyMouseCallbackHaiku(uSynergyCookie cookie, uint16_t 
x, uint16_t y, int16_
                        if (message->AddInt64("when", timestamp) == B_OK
                            && message->AddFloat("be:wheel_delta_x", (oldWheelX 
- wheelX) / 120) == B_OK
                            && message->AddFloat("be:wheel_delta_y", (oldWheelY 
- wheelY) / 120) == B_OK)
-                               inputDevice->EnqueueMessage(message);
+                               EnqueueMessage(message);
                        else
                                delete message;
                }
@@ -475,36 +500,16 @@ uSynergyMouseCallbackHaiku(uSynergyCookie cookie, 
uint16_t x, uint16_t y, int16_
        }
 }
 
-/* Synergy modifier definitions */
-#define        SYNERGY_SHIFT           0x0001
-#define        SYNERGY_CONTROL         0x0002
-#define SYNERGY_ALT            0x0004
-#define SYNERGY_META           0x0008
-#define SYNERGY_SUPER          0x0010
-#define SYNERGY_ALTGR          0x0020
-#define SYNERGY_LEVEL5LOCK     0x0040
-#define SYNERGY_CAPSLOCK       0x1000
-#define SYNERGY_NUMLOCK                0x2000
-#define SYNERGY_SCROLLLOCK     0x4000
-#define EXTENDED_KEY           0xe000
 
 void
-uSynergyInputServerDevice::_ProcessKeyboard(uint16_t scancode, uint16_t 
_modifiers, bool isKeyDown, bool isKeyRepeat)
+uSynergyInputServerDevice::KeyboardCallback(uint16_t scancode, uint16_t 
_modifiers, bool isKeyDown, bool isKeyRepeat)
 {
        static uint32 lastScanCode = 0;
        static uint32 repeatCount = 1;
        static uint8 states[16];
 
-       bool isExtended = false;
-
-       if (scancode & EXTENDED_KEY != 0) {
-               isExtended = true;
-               TRACE("synergy: extended key\n");
-       }
-
        int64 timestamp = system_time();
 
-       TRACE("synergy: scancode = 0x%02x\n", scancode);
        uint32_t keycode = 0;
        if (scancode > 0 && scancode < sizeof(kATKeycodeMap)/sizeof(uint32))
                keycode = kATKeycodeMap[scancode - 1];
@@ -513,7 +518,8 @@ uSynergyInputServerDevice::_ProcessKeyboard(uint16_t 
scancode, uint16_t _modifie
                if (scancode > 0 && scancode < 
sizeof(kATKeycodeMap)/sizeof(uint32))
                        keycode = kATKeycodeMap[scancode - 1];
        }
-       TRACE("synergy: keycode = 0x%x\n", keycode);
+
+       TRACE("synergy: scancode = 0x%02x, keycode = 0x%x\n", scancode, 
keycode);
 
        if (keycode < 256) {
                if (isKeyDown)
@@ -522,45 +528,34 @@ uSynergyInputServerDevice::_ProcessKeyboard(uint16_t 
scancode, uint16_t _modifie
                        states[(keycode) >> 3] &= (!(1 << (7 - (keycode & 
0x7))));
        }
 
+#if false
        if (isKeyDown && keycode == 0x34 // DELETE KEY
                && (states[fCommandKey >> 3] & (1 << (7 - (fCommandKey & 0x7))))
                && (states[fControlKey >> 3] & (1 << (7 - (fControlKey & 
0x7))))) {
                TRACE("synergy: TeamMonitor called\n");
        }
+#endif
 
        uint32 modifiers = 0;
-       //TRACE("synergy: modifiers: ");
-       if (_modifiers & SYNERGY_SHIFT) {
-       //      TRACE("SHIFT ");
+
+       if (_modifiers & USYNERGY_MODIFIER_SHIFT)
                modifiers |= B_SHIFT_KEY | B_LEFT_SHIFT_KEY;
-       }
-       if (_modifiers & SYNERGY_CONTROL) {
-       //      TRACE("CONTROL ");
+       if (_modifiers & USYNERGY_MODIFIER_CTRL)
                modifiers |= B_CONTROL_KEY | B_LEFT_CONTROL_KEY;
-       }
-       if (_modifiers & SYNERGY_ALT) {
-       //      TRACE("COMMAND(ALT) ");
+       if (_modifiers & USYNERGY_MODIFIER_ALT)
                modifiers |= B_COMMAND_KEY | B_LEFT_COMMAND_KEY;
-       }
-       if (_modifiers & SYNERGY_META) {
-       //      TRACE("MENU(META) ");
+       if (_modifiers & USYNERGY_MODIFIER_META)
                modifiers |= B_MENU_KEY;
-       }
-       if (_modifiers & SYNERGY_SUPER) {
-       //      TRACE("OPTION(SUPER) ");
+       if (_modifiers & USYNERGY_MODIFIER_WIN)
                modifiers |= B_OPTION_KEY | B_LEFT_OPTION_KEY;
-       }
-       if (_modifiers & SYNERGY_ALTGR) {
-       //      TRACE("RIGHT_OPTION(ALTGR) ");
+       if (_modifiers & USYNERGY_MODIFIER_ALT_GR)
                modifiers |= B_RIGHT_OPTION_KEY | B_OPTION_KEY;
-       }
-       if (_modifiers & SYNERGY_CAPSLOCK)
+       if (_modifiers & USYNERGY_MODIFIER_CAPSLOCK)
                modifiers |= B_CAPS_LOCK;
-       if (_modifiers & SYNERGY_NUMLOCK)
+       if (_modifiers & USYNERGY_MODIFIER_NUMLOCK)
                modifiers |= B_NUM_LOCK;
-       if (_modifiers & SYNERGY_SCROLLLOCK)
+       if (_modifiers & USYNERGY_MODIFIER_SCROLLOCK)
                modifiers |= B_SCROLL_LOCK;
-       //TRACE("\n");
 
        //bool isLock
        //      = (modifiers & (B_CAPS_LOCK | B_NUM_LOCK | B_SCROLL_LOCK)) != 0;
@@ -591,10 +586,8 @@ uSynergyInputServerDevice::_ProcessKeyboard(uint16_t 
scancode, uint16_t _modifie
                }
        }
 
-       if (scancode == 0 || scancode == EXTENDED_KEY) {
-               TRACE("empty scancode\n");
+       if (scancode == 0)
                return;
-       }
 
        BMessage* msg = new BMessage;
        if (msg == NULL)
@@ -649,30 +642,26 @@ uSynergyInputServerDevice::_ProcessKeyboard(uint16_t 
scancode, uint16_t _modifie
        lastScanCode = isKeyDown ? scancode : 0;
 }
 
-void
-uSynergyKeyboardCallbackHaiku(uSynergyCookie cookie, uint16_t key, uint16_t 
modifiers, uSynergyBool down, uSynergyBool repeat)
-{
-       ((uSynergyInputServerDevice*)cookie)->_ProcessKeyboard(key, modifiers, 
down, repeat);
-}
 
 void
-uSynergyJoystickCallbackHaiku(uSynergyCookie cookie, uint8_t joyNum, uint16_t 
buttons, int8_t leftStickX, int8_t leftStickY, int8_t rightStickX, int8_t 
rightStickY)
+uSynergyInputServerDevice::JoystickCallback(uint8_t joyNum, uint16_t buttons, 
int8_t leftStickX, int8_t leftStickY, int8_t rightStickX, int8_t rightStickY)
 {
-
 }
 
+
 void
-uSynergyInputServerDevice::_PostClipboard(const BString &mimetype, const 
uint8_t *data, uint32_t size)
+uSynergyInputServerDevice::ClipboardCallback(enum uSynergyClipboardFormat 
format, const uint8_t *data, uint32_t size)
 {
+       if (format != USYNERGY_CLIPBOARD_FORMAT_TEXT)
+               return;
+
        if (be_clipboard->Lock()) {
                be_clipboard->Clear();
                BMessage *clip = be_clipboard->Data();
-               clip->AddData(mimetype, B_MIME_TYPE, data, size);
+               clip->AddData("text/plain", B_MIME_TYPE, data, size);
                status_t result = be_clipboard->Commit();
-               if (result != B_OK) {
+               if (result != B_OK)
                        TRACE("synergy: failed to commit data to clipboard\n");
-               } else
-                       TRACE("synergy: received clipboard data\n");
 
                be_clipboard->Unlock();
        } else {
@@ -680,13 +669,6 @@ uSynergyInputServerDevice::_PostClipboard(const BString 
&mimetype, const uint8_t
        }
 }
 
-void
-uSynergyClipboardCallbackHaiku(uSynergyCookie cookie, enum 
uSynergyClipboardFormat format, const uint8_t *data, uint32_t size)
-{
-       if (format == USYNERGY_CLIPBOARD_FORMAT_TEXT)
-               
((uSynergyInputServerDevice*)cookie)->_PostClipboard("text/plain", data, size);
-}
-
 
 extern "C" BInputServerDevice*
 instantiate_input_device()
diff --git a/src/add-ons/input_server/devices/synergy/haiku-usynergy.h 
b/src/add-ons/input_server/devices/synergy/haiku-usynergy.h
index cd33342..bfc8fe5 100644
--- a/src/add-ons/input_server/devices/synergy/haiku-usynergy.h
+++ b/src/add-ons/input_server/devices/synergy/haiku-usynergy.h
@@ -1,10 +1,24 @@
 /*
- * Copyright 2004-2008, Haiku.
- * Distributed under the terms of the MIT License.
+ * Copyright (c)
+ *      2014  Ed Robbins <edd.robbins@xxxxxxxxx>
+ *      2014  Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx>
  *
- * Authors:
- *             Stefano Ceccherini
+ * Based on MouseInputDevice.h by
+ *    Stefano Ceccherini Copyright 2004-2008, Haiku
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
+
 #ifndef USYNERGY_H
 #define USYNERGY_H
 
@@ -18,72 +32,53 @@
 #include "uSynergy.h"
 
 
-uSynergyBool      uSynergyConnectHaiku(uSynergyCookie cookie);
-uSynergyBool      uSynergySendHaiku(uSynergyCookie cookie, const uint8_t 
*buffer, int length);
-uSynergyBool      uSynergyReceiveHaiku(uSynergyCookie cookie, uint8_t *buffer, 
int maxLength, int* outLength);
-void              uSynergySleepHaiku(uSynergyCookie cookie, int timeMs);
-uint32_t          uSynergyGetTimeHaiku();
-void              uSynergyTraceHaiku(uSynergyCookie cookie, const char *text);
-void              uSynergyScreenActiveCallbackHaiku(uSynergyCookie cookie, 
uSynergyBool active);
-void              uSynergyMouseCallbackHaiku(uSynergyCookie cookie, uint16_t 
x, uint16_t y, int16_t wheelX, int16_t wheelY, uSynergyBool buttonLeft, 
uSynergyBool buttonRight, uSynergyBool buttonMiddle);
-void              uSynergyKeyboardCallbackHaiku(uSynergyCookie cookie, 
uint16_t key, uint16_t modifiers, uSynergyBool down, uSynergyBool repeat);
-void              uSynergyJoystickCallbackHaiku(uSynergyCookie cookie, uint8_t 
joyNum, uint16_t buttons, int8_t leftStickX, int8_t leftStickY, int8_t 
rightStickX, int8_t rightStickY);
-void              uSynergyClipboardCallbackHaiku(uSynergyCookie cookie, enum 
uSynergyClipboardFormat format, const uint8_t *data, uint32_t size);
-
 class uSynergyInputServerDevice : public BHandler, public BInputServerDevice {
        public:
-                                        uSynergyInputServerDevice();
-               virtual                 ~uSynergyInputServerDevice();
+                                                       
uSynergyInputServerDevice();
+       virtual                                 ~uSynergyInputServerDevice();
 
-               virtual status_t         InitCheck();
+       virtual status_t                InitCheck();
 
-               virtual void             MessageReceived(BMessage* message);
-               virtual status_t         Start(const char* name, void* cookie);
-               virtual status_t         Stop(const char* name, void* cookie);
-               virtual status_t         SystemShuttingDown();
+       virtual status_t                Control(const char* name, void* cookie, 
uint32 command, BMessage* message);
+       virtual status_t                Start(const char* name, void* cookie);
+       virtual status_t                Stop(const char* name, void* cookie);
+       virtual status_t                SystemShuttingDown();
 
+       virtual void                    MessageReceived(BMessage* message);
+
+       // Synergy Hooks
+               bool                            Connect();
+               bool                            Send(const uint8_t* buffer, 
int32_t length);
+               bool                            Receive(uint8_t* buffer, int 
maxLength, int* outLength);
+               void                            Trace(const char* text);
+               void                            ScreenActive(bool active);
+               void                            MouseCallback(uint16_t x, 
uint16_t y, int16_t wheelX, int16_t wheelY, bool buttonLeft, bool buttonRight, 
bool buttonMiddle);
+               void                            KeyboardCallback(uint16_t key, 
uint16_t modifiers, bool isKeyDown, bool isKeyRepeat);
+               void                            JoystickCallback(uint8_t 
joyNum, uint16_t buttons, int8_t leftStickX, int8_t leftStickY, int8_t 
rightStickX, int8_t rightStickY);
+               void                            ClipboardCallback(enum 
uSynergyClipboardFormat format, const uint8_t* data, uint32_t size);
 
-               virtual status_t         Control(const char* name, void* 
cookie, uint32 command, BMessage* message);
        private:
-               bool                     threadActive;
-               thread_id                uSynergyThread;
-               uSynergyContext         *uSynergyHaikuContext;
 
                BMessage*               _BuildMouseMessage(uint32 what, uint64 
when, uint32 buttons, float x, float y) const;
-               void                    _ProcessKeyboard(uint16_t scancode, 
uint16_t modifiers, bool isKeyDown, bool isKeyRepeat);
                void                    _UpdateSettings();
-               void                    _PostClipboard(const BString &mimetype, 
const uint8_t *data, uint32_t size);
-       public:
-               struct sockaddr_in       synergyServerData;
-               int                      synergyServerSocket;
-       private:
-               static status_t          uSynergyThreadLoop(void* arg);
+       static status_t         _MainLoop(void* arg);
 
-               uint32          fModifiers;
-               uint32          fCommandKey;
-               uint32          fControlKey;
-               char*           fFilename;
-               bool            fEnableSynergy;
-               BString         fServerAddress;
+               bool                            threadActive;
+               thread_id                       uSynergyThread;
+               uSynergyContext*        fContext;
+               int                                     fSocket;
 
-       volatile bool   fUpdateSettings;
+               uint32                          fModifiers;
+               uint32                          fCommandKey;
+               uint32                          fControlKey;
+               char*                           fFilename;
+               bool                            fEnableSynergy;
+               BString                         fServerAddress;
 
-               Keymap          fKeymap;
-               BLocker         fKeymapLock;
+       volatile bool                   fUpdateSettings;
 
-       public:
-               /* callbacks for uSynergy */
-               friend uSynergyBool      uSynergyConnectHaiku(uSynergyCookie 
cookie);
-               friend uSynergyBool      uSynergySendHaiku(uSynergyCookie 
cookie, const uint8_t *buffer, int length);
-               friend uSynergyBool      uSynergyReceiveHaiku(uSynergyCookie 
cookie, uint8_t *buffer, int maxLength, int* outLength);
-               friend void              uSynergySleepHaiku(uSynergyCookie 
cookie, int timeMs);
-               friend uint32_t          uSynergyGetTimeHaiku();
-               friend void              uSynergyTraceHaiku(uSynergyCookie 
cookie, const char *text);
-               friend void              
uSynergyScreenActiveCallbackHaiku(uSynergyCookie cookie, uSynergyBool active);
-               friend void              
uSynergyMouseCallbackHaiku(uSynergyCookie cookie, uint16_t x, uint16_t y, 
int16_t wheelX, int16_t wheelY, uSynergyBool buttonLeft, uSynergyBool 
buttonRight, uSynergyBool buttonMiddle);
-               friend void              
uSynergyKeyboardCallbackHaiku(uSynergyCookie cookie, uint16_t key, uint16_t 
modifiers, uSynergyBool down, uSynergyBool repeat);
-               friend void              
uSynergyJoystickCallbackHaiku(uSynergyCookie cookie, uint8_t joyNum, uint16_t 
buttons, int8_t leftStickX, int8_t leftStickY, int8_t rightStickX, int8_t 
rightStickY);
-               friend void              
uSynergyClipboardCallbackHaiku(uSynergyCookie cookie, enum 
uSynergyClipboardFormat format, const uint8_t *data, uint32_t size);
+               Keymap                          fKeymap;
+               BLocker                         fKeymapLock;
 };
 
 
diff --git a/src/add-ons/input_server/devices/synergy/uSynergy.h 
b/src/add-ons/input_server/devices/synergy/uSynergy.h
index 7d3b9a9..b8d58dc 100644
--- a/src/add-ons/input_server/devices/synergy/uSynergy.h
+++ b/src/add-ons/input_server/devices/synergy/uSynergy.h
@@ -68,10 +68,15 @@ extern "C" {
 /**
 @brief Boolean type
 **/
+#if defined(__cplusplus)
+typedef bool           uSynergyBool;
+#define                                USYNERGY_FALSE                          
        false
+#define                                USYNERGY_TRUE                           
        true
+#else
 typedef int                    uSynergyBool;
 #define                                USYNERGY_FALSE                          
        0                               /* False value */
 #define                                USYNERGY_TRUE                           
        1                               /* True value */
-
+#endif
 
 /**
 @brief User context type


Other related posts:

  • » [haiku-commits] BRANCH jessicah-github.synergy [81423a3] src/add-ons/input_server/devices/synergy - jessicah-github . synergy