imgui

FORK: Dear ImGui: Bloat-free Graphical User interface for C++ with minimal dependencies
git clone https://git.neptards.moe/neptards/imgui.git
Log | Files | Refs

uSynergy.h (16644B)


      1 /*
      2 uSynergy client -- Interface for the embedded Synergy client library
      3   version 1.0.0, July 7th, 2012
      4 
      5 Copyright (C) 2012 Synergy Si Ltd.
      6 Copyright (c) 2012 Alex Evans
      7 
      8 This software is provided 'as-is', without any express or implied
      9 warranty. In no event will the authors be held liable for any damages
     10 arising from the use of this software.
     11 
     12 Permission is granted to anyone to use this software for any purpose,
     13 including commercial applications, and to alter it and redistribute it
     14 freely, subject to the following restrictions:
     15 
     16    1. The origin of this software must not be misrepresented; you must not
     17    claim that you wrote the original software. If you use this software
     18    in a product, an acknowledgment in the product documentation would be
     19    appreciated but is not required.
     20 
     21    2. Altered source versions must be plainly marked as such, and must not be
     22    misrepresented as being the original software.
     23 
     24    3. This notice may not be removed or altered from any source
     25    distribution.
     26 */
     27 #include <stdint.h>
     28 
     29 #ifdef __cplusplus
     30 extern "C" {
     31 #endif
     32 
     33 
     34 
     35 //---------------------------------------------------------------------------------------------------------------------
     36 //	Configuration
     37 //---------------------------------------------------------------------------------------------------------------------
     38 
     39 
     40 
     41 /**
     42 @brief Determine endianness
     43 **/
     44 #if defined(USYNERGY_LITTLE_ENDIAN) && defined(USYNERGY_BIG_ENDIAN)
     45 	/* Ambiguous: both endians specified */
     46 	#error "Can't define both USYNERGY_LITTLE_ENDIAN and USYNERGY_BIG_ENDIAN"
     47 #elif !defined(USYNERGY_LITTLE_ENDIAN) && !defined(USYNERGY_BIG_ENDIAN)
     48 	/* Attempt to auto detect */
     49 	#if defined(__LITTLE_ENDIAN__) || defined(LITTLE_ENDIAN) || (_BYTE_ORDER == _LITTLE_ENDIAN)
     50 		#define USYNERGY_LITTLE_ENDIAN
     51 	#elif defined(__BIG_ENDIAN__) || defined(BIG_ENDIAN) || (_BYTE_ORDER == _BIG_ENDIAN)
     52 		#define USYNERGY_BIG_ENDIAN
     53 	#else
     54 		#error "Can't detect endian-nes, please defined either USYNERGY_LITTLE_ENDIAN or USYNERGY_BIG_ENDIAN";
     55 	#endif
     56 #else
     57 	/* User-specified endian-nes, nothing to do for us */
     58 #endif
     59 
     60 
     61 
     62 //---------------------------------------------------------------------------------------------------------------------
     63 //	Types and Constants
     64 //---------------------------------------------------------------------------------------------------------------------
     65 
     66 
     67 
     68 /**
     69 @brief Boolean type
     70 **/
     71 typedef int			uSynergyBool;
     72 #define				USYNERGY_FALSE					0				/* False value */
     73 #define				USYNERGY_TRUE					1				/* True value */
     74 
     75 
     76 /**
     77 @brief User context type
     78 
     79 The uSynergyCookie type is an opaque type that is used by uSynergy to communicate to the client. It is passed along to
     80 callback functions as context.
     81 **/
     82 typedef struct { int ignored; } *					uSynergyCookie;
     83 
     84 
     85 
     86 /**
     87 @brief Clipboard types
     88 **/
     89 enum uSynergyClipboardFormat
     90 {
     91 	USYNERGY_CLIPBOARD_FORMAT_TEXT					= 0,			/* Text format, UTF-8, newline is LF */
     92 	USYNERGY_CLIPBOARD_FORMAT_BITMAP				= 1,			/* Bitmap format, BMP 24/32bpp, BI_RGB */
     93 	USYNERGY_CLIPBOARD_FORMAT_HTML					= 2,			/* HTML format, HTML fragment, UTF-8, newline is LF */
     94 };
     95 
     96 
     97 
     98 /**
     99 @brief Constants and limits
    100 **/
    101 #define				USYNERGY_NUM_JOYSTICKS			4				/* Maximum number of supported joysticks */
    102 
    103 #define				USYNERGY_PROTOCOL_MAJOR			1				/* Major protocol version */
    104 #define				USYNERGY_PROTOCOL_MINOR			4				/* Minor protocol version */
    105 
    106 #define				USYNERGY_IDLE_TIMEOUT			2000			/* Timeout in milliseconds before reconnecting */
    107 
    108 #define				USYNERGY_TRACE_BUFFER_SIZE		1024			/* Maximum length of traced message */
    109 #define				USYNERGY_REPLY_BUFFER_SIZE		1024			/* Maximum size of a reply packet */
    110 #define				USYNERGY_RECEIVE_BUFFER_SIZE	4096			/* Maximum size of an incoming packet */
    111 
    112 
    113 
    114 /**
    115 @brief Keyboard constants
    116 **/
    117 #define				USYNERGY_MODIFIER_SHIFT			0x0001			/* Shift key modifier */
    118 #define				USYNERGY_MODIFIER_CTRL			0x0002			/* Ctrl key modifier */
    119 #define				USYNERGY_MODIFIER_ALT			0x0004			/* Alt key modifier */
    120 #define				USYNERGY_MODIFIER_META			0x0008			/* Meta key modifier */
    121 #define				USYNERGY_MODIFIER_WIN			0x0010			/* Windows key modifier */
    122 #define				USYNERGY_MODIFIER_ALT_GR		0x0020			/* AltGr key modifier */
    123 #define				USYNERGY_MODIFIER_LEVEL5LOCK	0x0040			/* Level5Lock key modifier */
    124 #define				USYNERGY_MODIFIER_CAPSLOCK		0x1000			/* CapsLock key modifier */
    125 #define				USYNERGY_MODIFIER_NUMLOCK		0x2000			/* NumLock key modifier */
    126 #define				USYNERGY_MODIFIER_SCROLLOCK		0x4000			/* ScrollLock key modifier */
    127 
    128 
    129 
    130 
    131 //---------------------------------------------------------------------------------------------------------------------
    132 //	Functions and Callbacks
    133 //---------------------------------------------------------------------------------------------------------------------
    134 
    135 
    136 
    137 /**
    138 @brief Connect function
    139 
    140 This function is called when uSynergy needs to connect to the host. It doesn't imply a network implementation or
    141 destination address, that must all be handled on the user side. The function should return USYNERGY_TRUE if a
    142 connection was established or USYNERGY_FALSE if it could not connect.
    143 
    144 When network errors occur (e.g. uSynergySend or uSynergyReceive fail) then the connect call will be called again
    145 so the implementation of the function must close any old connections and clean up resources before retrying.
    146 
    147 @param cookie		Cookie supplied in the Synergy context
    148 **/
    149 typedef uSynergyBool (*uSynergyConnectFunc)(uSynergyCookie cookie);
    150 
    151 
    152 
    153 /**
    154 @brief Send function
    155 
    156 This function is called when uSynergy needs to send something over the default connection. It should return
    157 USYNERGY_TRUE if sending succeeded and USYNERGY_FALSE otherwise. This function should block until the send
    158 operation is completed.
    159 
    160 @param cookie		Cookie supplied in the Synergy context
    161 @param buffer		Address of buffer to send
    162 @param length		Length of buffer to send
    163 **/
    164 typedef uSynergyBool (*uSynergySendFunc)(uSynergyCookie cookie, const uint8_t *buffer, int length);
    165 
    166 
    167 
    168 /**
    169 @brief Receive function
    170 
    171 This function is called when uSynergy needs to receive data from the default connection. It should return
    172 USYNERGY_TRUE if receiving data succeeded and USYNERGY_FALSE otherwise. This function should block until data
    173 has been received and wait for data to become available. If @a outLength is set to 0 upon completion it is
    174 assumed that the connection is alive, but still in a connecting state and needs time to settle.
    175 
    176 @param cookie		Cookie supplied in the Synergy context
    177 @param buffer		Address of buffer to receive data into
    178 @param maxLength	Maximum amount of bytes to write into the receive buffer
    179 @param outLength	Address of integer that receives the actual amount of bytes written into @a buffer
    180 **/
    181 typedef uSynergyBool (*uSynergyReceiveFunc)(uSynergyCookie cookie, uint8_t *buffer, int maxLength, int* outLength);
    182 
    183 
    184 
    185 /**
    186 @brief Thread sleep function
    187 
    188 This function is called when uSynergy wants to suspend operation for a while before retrying an operation. It
    189 is mostly used when a socket times out or disconnect occurs to prevent uSynergy from continuously hammering a
    190 network connection in case the network is down.
    191 
    192 @param cookie		Cookie supplied in the Synergy context
    193 @param timeMs		Time to sleep the current thread (in milliseconds)
    194 **/
    195 typedef void		(*uSynergySleepFunc)(uSynergyCookie cookie, int timeMs);
    196 
    197 
    198 
    199 /**
    200 @brief Get time function
    201 
    202 This function is called when uSynergy needs to know the current time. This is used to determine when timeouts
    203 have occured. The time base should be a cyclic millisecond time value.
    204 
    205 @returns			Time value in milliseconds
    206 **/
    207 typedef uint32_t	(*uSynergyGetTimeFunc)();
    208 
    209 
    210 
    211 /**
    212 @brief Trace function
    213 
    214 This function is called when uSynergy wants to trace something. It is optional to show these messages, but they
    215 are often useful when debugging. uSynergy only traces major events like connecting and disconnecting. Usually
    216 only a single trace is shown when the connection is established and no more trace are called.
    217 
    218 @param cookie		Cookie supplied in the Synergy context
    219 @param text			Text to be traced
    220 **/
    221 typedef void		(*uSynergyTraceFunc)(uSynergyCookie cookie, const char *text);
    222 
    223 
    224 
    225 /**
    226 @brief Screen active callback
    227 
    228 This callback is called when Synergy makes the screen active or inactive. This
    229 callback is usually sent when the mouse enters or leaves the screen.
    230 
    231 @param cookie		Cookie supplied in the Synergy context
    232 @param active		Activation flag, 1 if the screen has become active, 0 if the screen has become inactive
    233 **/
    234 typedef void		(*uSynergyScreenActiveCallback)(uSynergyCookie cookie, uSynergyBool active);
    235 
    236 
    237 
    238 /**
    239 @brief Mouse callback
    240 
    241 This callback is called when a mouse events happens. The mouse X and Y position,
    242 wheel and button state is communicated in the message. It's up to the user to
    243 interpret if this is a mouse up, down, double-click or other message.
    244 
    245 @param cookie		Cookie supplied in the Synergy context
    246 @param x			Mouse X position
    247 @param y			Mouse Y position
    248 @param wheelX		Mouse wheel X position
    249 @param wheelY		Mouse wheel Y position
    250 @param buttonLeft	Left button pressed status, 0 for released, 1 for pressed
    251 @param buttonMiddle	Middle button pressed status, 0 for released, 1 for pressed
    252 @param buttonRight	Right button pressed status, 0 for released, 1 for pressed
    253 **/
    254 typedef void		(*uSynergyMouseCallback)(uSynergyCookie cookie, uint16_t x, uint16_t y, int16_t wheelX, int16_t wheelY, uSynergyBool buttonLeft, uSynergyBool buttonRight, uSynergyBool buttonMiddle);
    255 
    256 
    257 
    258 /**
    259 @brief Key event callback
    260 
    261 This callback is called when a key is pressed or released.
    262 
    263 @param cookie		Cookie supplied in the Synergy context
    264 @param key			Key code of key that was pressed or released
    265 @param modifiers	Status of modifier keys (alt, shift, etc.)
    266 @param down			Down or up status, 1 is key is pressed down, 0 if key is released (up)
    267 @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
    268 **/
    269 typedef void		(*uSynergyKeyboardCallback)(uSynergyCookie cookie, uint16_t key, uint16_t modifiers, uSynergyBool down, uSynergyBool repeat);
    270 
    271 
    272 
    273 /**
    274 @brief Joystick event callback
    275 
    276 This callback is called when a joystick stick or button changes. It is possible that multiple callbacks are
    277 fired when different sticks or buttons change as these are individual messages in the packet stream. Each
    278 callback will contain all the valid state for the different axes and buttons. The last callback received will
    279 represent the most current joystick state.
    280 
    281 @param cookie		Cookie supplied in the Synergy context
    282 @param joyNum		Joystick number, always in the range [0 ... USYNERGY_NUM_JOYSTICKS>
    283 @param buttons		Button pressed mask
    284 @param leftStickX	Left stick X position, in range [-127 ... 127]
    285 @param leftStickY	Left stick Y position, in range [-127 ... 127]
    286 @param rightStickX	Right stick X position, in range [-127 ... 127]
    287 @param rightStickY	Right stick Y position, in range [-127 ... 127]
    288 **/
    289 typedef void		(*uSynergyJoystickCallback)(uSynergyCookie cookie, uint8_t joyNum, uint16_t buttons, int8_t leftStickX, int8_t leftStickY, int8_t rightStickX, int8_t rightStickY);
    290 
    291 
    292 
    293 /**
    294 @brief Clipboard event callback
    295 
    296 This callback is called when something is placed on the clipboard. Multiple callbacks may be fired for
    297 multiple clipboard formats if they are supported. The data provided is read-only and may not be modified
    298 by the application.
    299 
    300 @param cookie		Cookie supplied in the Synergy context
    301 @param format		Clipboard format
    302 @param data			Memory area containing the clipboard raw data
    303 @param size			Size of clipboard data
    304 **/
    305 typedef void		(*uSynergyClipboardCallback)(uSynergyCookie cookie, enum uSynergyClipboardFormat format, const uint8_t *data, uint32_t size);
    306 
    307 
    308 
    309 //---------------------------------------------------------------------------------------------------------------------
    310 //	Context
    311 //---------------------------------------------------------------------------------------------------------------------
    312 
    313 
    314 
    315 /**
    316 @brief uSynergy context
    317 **/
    318 typedef struct
    319 {
    320 	/* Mandatory configuration data, filled in by client */
    321 	uSynergyConnectFunc				m_connectFunc;									/* Connect function */
    322 	uSynergySendFunc				m_sendFunc;										/* Send data function */
    323 	uSynergyReceiveFunc				m_receiveFunc;									/* Receive data function */
    324 	uSynergySleepFunc				m_sleepFunc;									/* Thread sleep function */
    325 	uSynergyGetTimeFunc				m_getTimeFunc;									/* Get current time function */
    326 	const char*						m_clientName;									/* Name of Synergy Screen / Client */
    327 	uint16_t						m_clientWidth;									/* Width of screen */
    328 	uint16_t						m_clientHeight;									/* Height of screen */
    329 
    330 	/* Optional configuration data, filled in by client */
    331 	uSynergyCookie					m_cookie;										/* Cookie pointer passed to callback functions (can be NULL) */
    332 	uSynergyTraceFunc				m_traceFunc;									/* Function for tracing status (can be NULL) */
    333 	uSynergyScreenActiveCallback	m_screenActiveCallback;							/* Callback for entering and leaving screen */
    334 	uSynergyMouseCallback			m_mouseCallback;								/* Callback for mouse events */
    335 	uSynergyKeyboardCallback		m_keyboardCallback;								/* Callback for keyboard events */
    336 	uSynergyJoystickCallback		m_joystickCallback;								/* Callback for joystick events */
    337 	uSynergyClipboardCallback		m_clipboardCallback;							/* Callback for clipboard events */
    338 
    339 	/* State data, used internall by client, initialized by uSynergyInit() */
    340 	uSynergyBool					m_connected;									/* Is our socket connected? */
    341 	uSynergyBool					m_hasReceivedHello;								/* Have we received a 'Hello' from the server? */
    342 	uSynergyBool					m_isCaptured;									/* Is Synergy active (i.e. this client is receiving input messages?) */
    343 	uint32_t						m_lastMessageTime;								/* Time at which last message was received */
    344 	uint32_t						m_sequenceNumber;								/* Packet sequence number */
    345 	uint8_t							m_receiveBuffer[USYNERGY_RECEIVE_BUFFER_SIZE];	/* Receive buffer */
    346 	int								m_receiveOfs;									/* Receive buffer offset */
    347 	uint8_t							m_replyBuffer[USYNERGY_REPLY_BUFFER_SIZE];		/* Reply buffer */
    348 	uint8_t*						m_replyCur;										/* Write offset into reply buffer */
    349 	uint16_t						m_mouseX;										/* Mouse X position */
    350 	uint16_t						m_mouseY;										/* Mouse Y position */
    351 	int16_t							m_mouseWheelX;									/* Mouse wheel X position */
    352 	int16_t							m_mouseWheelY;									/* Mouse wheel Y position */
    353 	uSynergyBool					m_mouseButtonLeft;								/* Mouse left button */
    354 	uSynergyBool					m_mouseButtonRight;								/* Mouse right button */
    355 	uSynergyBool					m_mouseButtonMiddle;							/* Mouse middle button */
    356 	int8_t							m_joystickSticks[USYNERGY_NUM_JOYSTICKS][4];	/* Joystick stick position in 2 axes for 2 sticks */
    357 	uint16_t						m_joystickButtons[USYNERGY_NUM_JOYSTICKS];		/* Joystick button state */
    358 } uSynergyContext;
    359 
    360 
    361 
    362 //---------------------------------------------------------------------------------------------------------------------
    363 //	Interface
    364 //---------------------------------------------------------------------------------------------------------------------
    365 
    366 
    367 
    368 /**
    369 @brief Initialize uSynergy context
    370 
    371 This function initializes @a context for use. Call this function directly after
    372 creating the context, before filling in any configuration data in it. Not calling
    373 this function will cause undefined behavior.
    374 
    375 @param context	Context to be initialized
    376 **/
    377 extern void		uSynergyInit(uSynergyContext *context);
    378 
    379 
    380 
    381 /**
    382 @brief Update uSynergy
    383 
    384 This function updates uSynergy and does the bulk of the work. It does connection management,
    385 receiving data, reconnecting after errors or timeouts and so on. It assumes that networking
    386 operations are blocking and it can suspend the current thread if it needs to wait. It is
    387 best practice to call uSynergyUpdate from a background thread so it is responsive.
    388 
    389 Because uSynergy relies mostly on blocking calls it will mostly stay in thread sleep state
    390 waiting for system mutexes and won't eat much memory.
    391 
    392 uSynergyUpdate doesn't do any memory allocations or have any side effects beyond those of
    393 the callbacks it calls.
    394 
    395 @param context	Context to be updated
    396 **/
    397 extern void		uSynergyUpdate(uSynergyContext *context);
    398 
    399 
    400 
    401 /**
    402 @brief Send clipboard data
    403 
    404 This function sets new clipboard data and sends it to the server. Use this function if
    405 your client cuts or copies data onto the clipboard that it needs to share with the
    406 server.
    407 
    408 Currently there is only support for plaintext, but HTML and image data could be
    409 supported with some effort.
    410 
    411 @param context	Context to send clipboard data to
    412 @param text		Text to set to the clipboard
    413 **/
    414 extern void		uSynergySendClipboard(uSynergyContext *context, const char *text);
    415 
    416 
    417 
    418 #ifdef __cplusplus
    419 };
    420 #endif