/** @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); }
HRESULT CSensatronicsModelF::ProcessConfig(CXMLSensatronicsConfig* pXMLSensatronicsConfig) { CString sTrace(_T("")); HRESULT hr = S_OK; bool bTempUnitSet = false; if(pXMLSensatronicsConfig) { const CXMLSensatronicsConfig::SensorsContainer& sensorsContainer = pXMLSensatronicsConfig->getSensorsContainer(); CXMLSensatronicsConfig::SensorsContainer::const_iterator sensors_it = sensorsContainer.begin(); if(sensors_it != sensorsContainer.end()) { CXMLSensatronicsSensorConfig* pXMLSensatronicsSensorConfig = sensors_it->second; const CXMLSensatronicsSensorConfig::ProbesContainer& probesContainer = pXMLSensatronicsSensorConfig->getProbeElements(); CXMLSensatronicsSensorConfig::ProbesContainer::const_iterator probes_it = probesContainer.begin(); for(; probes_it != probesContainer.end(); ++probes_it) { CXMLSensatronicsProbeConfig* pXMLSensatronicsProbeConfig = probes_it->second; hr = ProcessProbeConfig(pXMLSensatronicsProbeConfig, &bTempUnitSet); } } } return hr; }
STDMETHODIMP CSensatronicsModelF::GetConfig(void) { HRESULT hr = S_OK; CString sTrace(_T("")); CComPtr<IDataConnector> pDataConnector = 0; hr = pDataConnector.CoCreateInstance(__uuidof(DataConnector)); if(SUCCEEDED(hr)) { CXMLSensatronicsConfig XMLSensatronicsConfig; LONG* plConfigHandler = (LONG*)&XMLSensatronicsConfig; // so we can pass this through to hr = pDataConnector->RequestModelFSerialComConfigData(m_bstrName.Copy(), m_bstrComPort.Copy(), plConfigHandler); if(SUCCEEDED(hr)) { hr = ProcessConfig(&XMLSensatronicsConfig); } } return hr; }
/** @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 (;;) { /* If less than 4 bytes left in buffer, we can't even get the next packet length yet */ if(context->m_receiveOfs < 4) return; /* 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; } }
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("DMRM")) { // Mouse relative. Reply with CNOP // kMsgDMouseRelMove = "DMRM%2i%2i" sSendMouseRelativeCallback(context, sNetToNative16(message+8), sNetToNative16(message+10)); } 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 { // 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" // 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); }