You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and dots ('.'), can be up to 35 characters long. Letters must be lowercase.
		
		
		
		
		
			
		
			
				
					
					
						
							420 lines
						
					
					
						
							16 KiB
						
					
					
				
			
		
		
	
	
							420 lines
						
					
					
						
							16 KiB
						
					
					
				/* | 
						|
uSynergy client -- Interface for the embedded Synergy client library | 
						|
  version 1.0.0, July 7th, 2012 | 
						|
 | 
						|
Copyright (C) 2012 Synergy Si Ltd. | 
						|
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 <stdint.h> | 
						|
 | 
						|
#ifdef __cplusplus | 
						|
extern "C" { | 
						|
#endif | 
						|
 | 
						|
 | 
						|
 | 
						|
//--------------------------------------------------------------------------------------------------------------------- | 
						|
//	Configuration | 
						|
//--------------------------------------------------------------------------------------------------------------------- | 
						|
 | 
						|
 | 
						|
 | 
						|
/** | 
						|
@brief Determine endianness | 
						|
**/ | 
						|
#if defined(USYNERGY_LITTLE_ENDIAN) && defined(USYNERGY_BIG_ENDIAN) | 
						|
	/* Ambiguous: both endians specified */ | 
						|
	#error "Can't define both USYNERGY_LITTLE_ENDIAN and USYNERGY_BIG_ENDIAN" | 
						|
#elif !defined(USYNERGY_LITTLE_ENDIAN) && !defined(USYNERGY_BIG_ENDIAN) | 
						|
	/* Attempt to auto detect */ | 
						|
	#if defined(__LITTLE_ENDIAN__) || defined(LITTLE_ENDIAN) || (_BYTE_ORDER == _LITTLE_ENDIAN) | 
						|
		#define USYNERGY_LITTLE_ENDIAN | 
						|
	#elif defined(__BIG_ENDIAN__) || defined(BIG_ENDIAN) || (_BYTE_ORDER == _BIG_ENDIAN) | 
						|
		#define USYNERGY_BIG_ENDIAN | 
						|
	#else | 
						|
		#error "Can't detect endian-nes, please defined either USYNERGY_LITTLE_ENDIAN or USYNERGY_BIG_ENDIAN"; | 
						|
	#endif | 
						|
#else | 
						|
	/* User-specified endian-nes, nothing to do for us */ | 
						|
#endif | 
						|
 | 
						|
 | 
						|
 | 
						|
//--------------------------------------------------------------------------------------------------------------------- | 
						|
//	Types and Constants | 
						|
//--------------------------------------------------------------------------------------------------------------------- | 
						|
 | 
						|
 | 
						|
 | 
						|
/** | 
						|
@brief Boolean type | 
						|
**/ | 
						|
typedef int			uSynergyBool; | 
						|
#define				USYNERGY_FALSE					0				/* False value */ | 
						|
#define				USYNERGY_TRUE					1				/* True value */ | 
						|
 | 
						|
 | 
						|
/** | 
						|
@brief User context type | 
						|
 | 
						|
The uSynergyCookie type is an opaque type that is used by uSynergy to communicate to the client. It is passed along to | 
						|
callback functions as context. | 
						|
**/ | 
						|
typedef struct { int ignored; } *					uSynergyCookie; | 
						|
 | 
						|
 | 
						|
 | 
						|
/** | 
						|
@brief Clipboard types | 
						|
**/ | 
						|
enum uSynergyClipboardFormat | 
						|
{ | 
						|
	USYNERGY_CLIPBOARD_FORMAT_TEXT					= 0,			/* Text format, UTF-8, newline is LF */ | 
						|
	USYNERGY_CLIPBOARD_FORMAT_BITMAP				= 1,			/* Bitmap format, BMP 24/32bpp, BI_RGB */ | 
						|
	USYNERGY_CLIPBOARD_FORMAT_HTML					= 2,			/* HTML format, HTML fragment, UTF-8, newline is LF */ | 
						|
}; | 
						|
 | 
						|
 | 
						|
 | 
						|
/** | 
						|
@brief Constants and limits | 
						|
**/ | 
						|
#define				USYNERGY_NUM_JOYSTICKS			4				/* Maximum number of supported joysticks */ | 
						|
 | 
						|
#define				USYNERGY_PROTOCOL_MAJOR			1				/* Major protocol version */ | 
						|
#define				USYNERGY_PROTOCOL_MINOR			4				/* Minor protocol version */ | 
						|
 | 
						|
#define				USYNERGY_IDLE_TIMEOUT			2000			/* Timeout in milliseconds before reconnecting */ | 
						|
 | 
						|
#define				USYNERGY_TRACE_BUFFER_SIZE		1024			/* Maximum length of traced message */ | 
						|
#define				USYNERGY_REPLY_BUFFER_SIZE		1024			/* Maximum size of a reply packet */ | 
						|
#define				USYNERGY_RECEIVE_BUFFER_SIZE	4096			/* Maximum size of an incoming packet */ | 
						|
 | 
						|
 | 
						|
 | 
						|
/** | 
						|
@brief Keyboard constants | 
						|
**/ | 
						|
#define				USYNERGY_MODIFIER_SHIFT			0x0001			/* Shift key modifier */ | 
						|
#define				USYNERGY_MODIFIER_CTRL			0x0002			/* Ctrl key modifier */ | 
						|
#define				USYNERGY_MODIFIER_ALT			0x0004			/* Alt key modifier */ | 
						|
#define				USYNERGY_MODIFIER_META			0x0008			/* Meta key modifier */ | 
						|
#define				USYNERGY_MODIFIER_WIN			0x0010			/* Windows key modifier */ | 
						|
#define				USYNERGY_MODIFIER_ALT_GR		0x0020			/* AltGr key modifier */ | 
						|
#define				USYNERGY_MODIFIER_LEVEL5LOCK	0x0040			/* Level5Lock key modifier */ | 
						|
#define				USYNERGY_MODIFIER_CAPSLOCK		0x1000			/* CapsLock key modifier */ | 
						|
#define				USYNERGY_MODIFIER_NUMLOCK		0x2000			/* NumLock key modifier */ | 
						|
#define				USYNERGY_MODIFIER_SCROLLOCK		0x4000			/* ScrollLock key modifier */ | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
//--------------------------------------------------------------------------------------------------------------------- | 
						|
//	Functions and Callbacks | 
						|
//--------------------------------------------------------------------------------------------------------------------- | 
						|
 | 
						|
 | 
						|
 | 
						|
/** | 
						|
@brief Connect function | 
						|
 | 
						|
This function is called when uSynergy needs to connect to the host. It doesn't imply a network implementation or | 
						|
destination address, that must all be handled on the user side. The function should return USYNERGY_TRUE if a | 
						|
connection was established or USYNERGY_FALSE if it could not connect. | 
						|
 | 
						|
When network errors occur (e.g. uSynergySend or uSynergyReceive fail) then the connect call will be called again | 
						|
so the implementation of the function must close any old connections and clean up resources before retrying. | 
						|
 | 
						|
@param cookie		Cookie supplied in the Synergy context | 
						|
**/ | 
						|
typedef uSynergyBool (*uSynergyConnectFunc)(uSynergyCookie cookie); | 
						|
 | 
						|
 | 
						|
 | 
						|
/** | 
						|
@brief Send function | 
						|
 | 
						|
This function is called when uSynergy needs to send something over the default connection. It should return | 
						|
USYNERGY_TRUE if sending succeeded and USYNERGY_FALSE otherwise. This function should block until the send | 
						|
operation is completed. | 
						|
 | 
						|
@param cookie		Cookie supplied in the Synergy context | 
						|
@param buffer		Address of buffer to send | 
						|
@param length		Length of buffer to send | 
						|
**/ | 
						|
typedef uSynergyBool (*uSynergySendFunc)(uSynergyCookie cookie, const uint8_t *buffer, int length); | 
						|
 | 
						|
 | 
						|
 | 
						|
/** | 
						|
@brief Receive function | 
						|
 | 
						|
This function is called when uSynergy needs to receive data from the default connection. It should return | 
						|
USYNERGY_TRUE if receiving data succeeded and USYNERGY_FALSE otherwise. This function should block until data | 
						|
has been received and wait for data to become available. If @a outLength is set to 0 upon completion it is | 
						|
assumed that the connection is alive, but still in a connecting state and needs time to settle. | 
						|
 | 
						|
@param cookie		Cookie supplied in the Synergy context | 
						|
@param buffer		Address of buffer to receive data into | 
						|
@param maxLength	Maximum amount of bytes to write into the receive buffer | 
						|
@param outLength	Address of integer that receives the actual amount of bytes written into @a buffer | 
						|
**/ | 
						|
typedef uSynergyBool (*uSynergyReceiveFunc)(uSynergyCookie cookie, uint8_t *buffer, int maxLength, int* outLength); | 
						|
 | 
						|
 | 
						|
 | 
						|
/** | 
						|
@brief Thread sleep function | 
						|
 | 
						|
This function is called when uSynergy wants to suspend operation for a while before retrying an operation. It | 
						|
is mostly used when a socket times out or disconnect occurs to prevent uSynergy from continuously hammering a | 
						|
network connection in case the network is down. | 
						|
 | 
						|
@param cookie		Cookie supplied in the Synergy context | 
						|
@param timeMs		Time to sleep the current thread (in milliseconds) | 
						|
**/ | 
						|
typedef void		(*uSynergySleepFunc)(uSynergyCookie cookie, int timeMs); | 
						|
 | 
						|
 | 
						|
 | 
						|
/** | 
						|
@brief Get time function | 
						|
 | 
						|
This function is called when uSynergy needs to know the current time. This is used to determine when timeouts | 
						|
have occured. The time base should be a cyclic millisecond time value. | 
						|
 | 
						|
@returns			Time value in milliseconds | 
						|
**/ | 
						|
typedef uint32_t	(*uSynergyGetTimeFunc)(); | 
						|
 | 
						|
 | 
						|
 | 
						|
/** | 
						|
@brief Trace function | 
						|
 | 
						|
This function is called when uSynergy wants to trace something. It is optional to show these messages, but they | 
						|
are often useful when debugging. uSynergy only traces major events like connecting and disconnecting. Usually | 
						|
only a single trace is shown when the connection is established and no more trace are called. | 
						|
 | 
						|
@param cookie		Cookie supplied in the Synergy context | 
						|
@param text			Text to be traced | 
						|
**/ | 
						|
typedef void		(*uSynergyTraceFunc)(uSynergyCookie cookie, const char *text); | 
						|
 | 
						|
 | 
						|
 | 
						|
/** | 
						|
@brief Screen active callback | 
						|
 | 
						|
This callback is called when Synergy makes the screen active or inactive. This | 
						|
callback is usually sent when the mouse enters or leaves the screen. | 
						|
 | 
						|
@param cookie		Cookie supplied in the Synergy context | 
						|
@param active		Activation flag, 1 if the screen has become active, 0 if the screen has become inactive | 
						|
**/ | 
						|
typedef void		(*uSynergyScreenActiveCallback)(uSynergyCookie cookie, uSynergyBool active); | 
						|
 | 
						|
 | 
						|
 | 
						|
/** | 
						|
@brief Mouse callback | 
						|
 | 
						|
This callback is called when a mouse events happens. The mouse X and Y position, | 
						|
wheel and button state is communicated in the message. It's up to the user to | 
						|
interpret if this is a mouse up, down, double-click or other message. | 
						|
 | 
						|
@param cookie		Cookie supplied in the Synergy context | 
						|
@param x			Mouse X position | 
						|
@param y			Mouse Y position | 
						|
@param wheelX		Mouse wheel X position | 
						|
@param wheelY		Mouse wheel Y position | 
						|
@param buttonLeft	Left button pressed status, 0 for released, 1 for pressed | 
						|
@param buttonMiddle	Middle button pressed status, 0 for released, 1 for pressed | 
						|
@param buttonRight	Right button pressed status, 0 for released, 1 for pressed | 
						|
**/ | 
						|
typedef void		(*uSynergyMouseCallback)(uSynergyCookie cookie, uint16_t x, uint16_t y, int16_t wheelX, int16_t wheelY, uSynergyBool buttonLeft, uSynergyBool buttonRight, uSynergyBool buttonMiddle); | 
						|
 | 
						|
 | 
						|
 | 
						|
/** | 
						|
@brief Key event callback | 
						|
 | 
						|
This callback is called when a key is pressed or released. | 
						|
 | 
						|
@param cookie		Cookie supplied in the Synergy context | 
						|
@param key			Key code of key that was pressed or released | 
						|
@param modifiers	Status of modifier keys (alt, shift, etc.) | 
						|
@param down			Down or up status, 1 is key is pressed down, 0 if key is released (up) | 
						|
@param repeat		Repeat flag, 1 if the key is down because the key is repeating, 0 if the key is initially pressed by the user | 
						|
**/ | 
						|
typedef void		(*uSynergyKeyboardCallback)(uSynergyCookie cookie, uint16_t key, uint16_t modifiers, uSynergyBool down, uSynergyBool repeat); | 
						|
 | 
						|
 | 
						|
 | 
						|
/** | 
						|
@brief Joystick event callback | 
						|
 | 
						|
This callback is called when a joystick stick or button changes. It is possible that multiple callbacks are | 
						|
fired when different sticks or buttons change as these are individual messages in the packet stream. Each | 
						|
callback will contain all the valid state for the different axes and buttons. The last callback received will | 
						|
represent the most current joystick state. | 
						|
 | 
						|
@param cookie		Cookie supplied in the Synergy context | 
						|
@param joyNum		Joystick number, always in the range [0 ... USYNERGY_NUM_JOYSTICKS> | 
						|
@param buttons		Button pressed mask | 
						|
@param leftStickX	Left stick X position, in range [-127 ... 127] | 
						|
@param leftStickY	Left stick Y position, in range [-127 ... 127] | 
						|
@param rightStickX	Right stick X position, in range [-127 ... 127] | 
						|
@param rightStickY	Right stick Y position, in range [-127 ... 127] | 
						|
**/ | 
						|
typedef void		(*uSynergyJoystickCallback)(uSynergyCookie cookie, uint8_t joyNum, uint16_t buttons, int8_t leftStickX, int8_t leftStickY, int8_t rightStickX, int8_t rightStickY); | 
						|
 | 
						|
 | 
						|
 | 
						|
/** | 
						|
@brief Clipboard event callback | 
						|
 | 
						|
This callback is called when something is placed on the clipboard. Multiple callbacks may be fired for | 
						|
multiple clipboard formats if they are supported. The data provided is read-only and may not be modified | 
						|
by the application. | 
						|
 | 
						|
@param cookie		Cookie supplied in the Synergy context | 
						|
@param format		Clipboard format | 
						|
@param data			Memory area containing the clipboard raw data | 
						|
@param size			Size of clipboard data | 
						|
**/ | 
						|
typedef void		(*uSynergyClipboardCallback)(uSynergyCookie cookie, enum uSynergyClipboardFormat format, const uint8_t *data, uint32_t size); | 
						|
 | 
						|
 | 
						|
 | 
						|
//--------------------------------------------------------------------------------------------------------------------- | 
						|
//	Context | 
						|
//--------------------------------------------------------------------------------------------------------------------- | 
						|
 | 
						|
 | 
						|
 | 
						|
/** | 
						|
@brief uSynergy context | 
						|
**/ | 
						|
typedef struct | 
						|
{ | 
						|
	/* Mandatory configuration data, filled in by client */ | 
						|
	uSynergyConnectFunc				m_connectFunc;									/* Connect function */ | 
						|
	uSynergySendFunc				m_sendFunc;										/* Send data function */ | 
						|
	uSynergyReceiveFunc				m_receiveFunc;									/* Receive data function */ | 
						|
	uSynergySleepFunc				m_sleepFunc;									/* Thread sleep function */ | 
						|
	uSynergyGetTimeFunc				m_getTimeFunc;									/* Get current time function */ | 
						|
	const char*						m_clientName;									/* Name of Synergy Screen / Client */ | 
						|
	uint16_t						m_clientWidth;									/* Width of screen */ | 
						|
	uint16_t						m_clientHeight;									/* Height of screen */ | 
						|
 | 
						|
	/* Optional configuration data, filled in by client */ | 
						|
	uSynergyCookie					m_cookie;										/* Cookie pointer passed to callback functions (can be NULL) */ | 
						|
	uSynergyTraceFunc				m_traceFunc;									/* Function for tracing status (can be NULL) */ | 
						|
	uSynergyScreenActiveCallback	m_screenActiveCallback;							/* Callback for entering and leaving screen */ | 
						|
	uSynergyMouseCallback			m_mouseCallback;								/* Callback for mouse events */ | 
						|
	uSynergyKeyboardCallback		m_keyboardCallback;								/* Callback for keyboard events */ | 
						|
	uSynergyJoystickCallback		m_joystickCallback;								/* Callback for joystick events */ | 
						|
	uSynergyClipboardCallback		m_clipboardCallback;							/* Callback for clipboard events */ | 
						|
 | 
						|
	/* State data, used internall by client, initialized by uSynergyInit() */ | 
						|
	uSynergyBool					m_connected;									/* Is our socket connected? */ | 
						|
	uSynergyBool					m_hasReceivedHello;								/* Have we received a 'Hello' from the server? */ | 
						|
	uSynergyBool					m_isCaptured;									/* Is Synergy active (i.e. this client is receiving input messages?) */ | 
						|
	uint32_t						m_lastMessageTime;								/* Time at which last message was received */ | 
						|
	uint32_t						m_sequenceNumber;								/* Packet sequence number */ | 
						|
	uint8_t							m_receiveBuffer[USYNERGY_RECEIVE_BUFFER_SIZE];	/* Receive buffer */ | 
						|
	int								m_receiveOfs;									/* Receive buffer offset */ | 
						|
	uint8_t							m_replyBuffer[USYNERGY_REPLY_BUFFER_SIZE];		/* Reply buffer */ | 
						|
	uint8_t*						m_replyCur;										/* Write offset into reply buffer */ | 
						|
	uint16_t						m_mouseX;										/* Mouse X position */ | 
						|
	uint16_t						m_mouseY;										/* Mouse Y position */ | 
						|
	int16_t							m_mouseWheelX;									/* Mouse wheel X position */ | 
						|
	int16_t							m_mouseWheelY;									/* Mouse wheel Y position */ | 
						|
	uSynergyBool					m_mouseButtonLeft;								/* Mouse left button */ | 
						|
	uSynergyBool					m_mouseButtonRight;								/* Mouse right button */ | 
						|
	uSynergyBool					m_mouseButtonMiddle;							/* Mouse middle button */ | 
						|
	int8_t							m_joystickSticks[USYNERGY_NUM_JOYSTICKS][4];	/* Joystick stick position in 2 axes for 2 sticks */ | 
						|
	uint16_t						m_joystickButtons[USYNERGY_NUM_JOYSTICKS];		/* Joystick button state */ | 
						|
} uSynergyContext; | 
						|
 | 
						|
 | 
						|
 | 
						|
//--------------------------------------------------------------------------------------------------------------------- | 
						|
//	Interface | 
						|
//--------------------------------------------------------------------------------------------------------------------- | 
						|
 | 
						|
 | 
						|
 | 
						|
/** | 
						|
@brief Initialize uSynergy context | 
						|
 | 
						|
This function initializes @a context for use. Call this function directly after | 
						|
creating the context, before filling in any configuration data in it. Not calling | 
						|
this function will cause undefined behavior. | 
						|
 | 
						|
@param context	Context to be initialized | 
						|
**/ | 
						|
extern void		uSynergyInit(uSynergyContext *context); | 
						|
 | 
						|
 | 
						|
 | 
						|
/** | 
						|
@brief Update uSynergy | 
						|
 | 
						|
This function updates uSynergy and does the bulk of the work. It does connection management, | 
						|
receiving data, reconnecting after errors or timeouts and so on. It assumes that networking | 
						|
operations are blocking and it can suspend the current thread if it needs to wait. It is | 
						|
best practice to call uSynergyUpdate from a background thread so it is responsive. | 
						|
 | 
						|
Because uSynergy relies mostly on blocking calls it will mostly stay in thread sleep state | 
						|
waiting for system mutexes and won't eat much memory. | 
						|
 | 
						|
uSynergyUpdate doesn't do any memory allocations or have any side effects beyond those of | 
						|
the callbacks it calls. | 
						|
 | 
						|
@param context	Context to be updated | 
						|
**/ | 
						|
extern void		uSynergyUpdate(uSynergyContext *context); | 
						|
 | 
						|
 | 
						|
 | 
						|
/** | 
						|
@brief Send clipboard data | 
						|
 | 
						|
This function sets new clipboard data and sends it to the server. Use this function if | 
						|
your client cuts or copies data onto the clipboard that it needs to share with the | 
						|
server. | 
						|
 | 
						|
Currently there is only support for plaintext, but HTML and image data could be | 
						|
supported with some effort. | 
						|
 | 
						|
@param context	Context to send clipboard data to | 
						|
@param text		Text to set to the clipboard | 
						|
**/ | 
						|
extern void		uSynergySendClipboard(uSynergyContext *context, const char *text); | 
						|
 | 
						|
 | 
						|
 | 
						|
#ifdef __cplusplus | 
						|
}; | 
						|
#endif
 | 
						|
 |