1 #ifndef RFBCLIENT_H
2 #define RFBCLIENT_H
3 
4 /**
5  * @defgroup libvncclient_api LibVNCClient API Reference
6  * @{
7  */
8 
9 /*
10  *  Copyright (C) 2000, 2001 Const Kaplinsky.  All Rights Reserved.
11  *  Copyright (C) 2000 Tridia Corporation.  All Rights Reserved.
12  *  Copyright (C) 1999 AT&T Laboratories Cambridge.  All Rights Reserved.
13  *
14  *  This is free software; you can redistribute it and/or modify
15  *  it under the terms of the GNU General Public License as published by
16  *  the Free Software Foundation; either version 2 of the License, or
17  *  (at your option) any later version.
18  *
19  *  This software is distributed in the hope that it will be useful,
20  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
21  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  *  GNU General Public License for more details.
23  *
24  *  You should have received a copy of the GNU General Public License
25  *  along with this software; if not, write to the Free Software
26  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
27  *  USA.
28  */
29 
30 /**
31  * @file rfbclient.h
32  */
33 
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37 #include <sys/time.h>
38 #include <unistd.h>
39 #include <rfb/rfbproto.h>
40 #include <rfb/keysym.h>
41 
42 #define rfbClientSwap16IfLE(s) \
43     (*(char *)&client->endianTest ? ((((s) & 0xff) << 8) | (((s) >> 8) & 0xff)) : (s))
44 
45 #define rfbClientSwap32IfLE(l) \
46     (*(char *)&client->endianTest ? ((((l) & 0xff000000) >> 24) | \
47 			     (((l) & 0x00ff0000) >> 8)  | \
48 			     (((l) & 0x0000ff00) << 8)  | \
49 			     (((l) & 0x000000ff) << 24))  : (l))
50 
51 #define rfbClientSwap64IfLE(l) \
52     (*(char *)&client->endianTest ? ((((l) & 0xff00000000000000ULL) >> 56) | \
53 			     (((l) & 0x00ff000000000000ULL) >> 40)  | \
54 			     (((l) & 0x0000ff0000000000ULL) >> 24)  | \
55 			     (((l) & 0x000000ff00000000ULL) >> 8)  | \
56 			     (((l) & 0x00000000ff000000ULL) << 8)  | \
57 			     (((l) & 0x0000000000ff0000ULL) << 24)  | \
58 			     (((l) & 0x000000000000ff00ULL) << 40)  | \
59 			     (((l) & 0x00000000000000ffULL) << 56))  : (l))
60 
61 #define FLASH_PORT_OFFSET 5400
62 #define LISTEN_PORT_OFFSET 5500
63 #define TUNNEL_PORT_OFFSET 5500
64 #define SERVER_PORT_OFFSET 5900
65 
66 #define DEFAULT_SSH_CMD "/usr/bin/ssh"
67 #define DEFAULT_TUNNEL_CMD  \
68   (DEFAULT_SSH_CMD " -f -L %L:localhost:%R %H sleep 20")
69 #define DEFAULT_VIA_CMD     \
70   (DEFAULT_SSH_CMD " -f -L %L:%H:%R %G sleep 20")
71 
72 #if(defined __cplusplus)
73 extern "C"
74 {
75 #endif
76 
77 /** vncrec */
78 
79 typedef struct {
80   FILE* file;
81   struct timeval tv;
82   rfbBool readTimestamp;
83   rfbBool doNotSleep;
84 } rfbVNCRec;
85 
86 /** client data */
87 
88 typedef struct rfbClientData {
89 	void* tag;
90 	void* data;
91 	struct rfbClientData* next;
92 } rfbClientData;
93 
94 /** app data (belongs into rfbClient?) */
95 
96 typedef struct {
97   rfbBool shareDesktop;
98   rfbBool viewOnly;
99 
100   const char* encodingsString;
101 
102   rfbBool useBGR233;
103   int nColours;
104   rfbBool forceOwnCmap;
105   rfbBool forceTrueColour;
106   int requestedDepth;
107 
108   int compressLevel;
109   int qualityLevel;
110   rfbBool enableJPEG;
111   rfbBool useRemoteCursor;
112   rfbBool palmVNC;  /**< use palmvnc specific SetScale (vs ultravnc) */
113   int scaleSetting; /**< 0 means no scale set, else 1/scaleSetting */
114 } AppData;
115 
116 /** For GetCredentialProc callback function to return */
117 typedef union _rfbCredential
118 {
119   /** X509 (VeNCrypt) */
120   struct
121   {
122     char *x509CACertFile;
123     char *x509CACrlFile;
124     char *x509ClientCertFile;
125     char *x509ClientKeyFile;
126   } x509Credential;
127   /** Plain (VeNCrypt), MSLogon (UltraVNC) */
128   struct
129   {
130     char *username;
131     char *password;
132   } userCredential;
133 } rfbCredential;
134 
135 #define rfbCredentialTypeX509 1
136 #define rfbCredentialTypeUser 2
137 
138 struct _rfbClient;
139 
140 /**
141  * Handles a text chat message. If your application should accept text messages
142  * from the server, define a function with this prototype and set
143  * client->HandleTextChat to a pointer to that function subsequent to your
144  * rfbGetClient() call.
145  * @param client The client which called the text chat handler
146  * @param value  text length if text != NULL, or one of rfbTextChatOpen,
147  * rfbTextChatClose, rfbTextChatFinished if text == NULL
148  * @param text The text message from the server
149  */
150 typedef void (*HandleTextChatProc)(struct _rfbClient* client, int value, char *text);
151 /**
152  * Handles XVP server messages. If your application sends XVP messages to the
153  * server, you'll want to handle the server's XVP_FAIL and XVP_INIT responses.
154  * Define a function with this prototype and set client->HandleXvpMsg to a
155  * pointer to that function subsequent to your rfbGetClient() call.
156  * @param client The client which called the XVP message handler
157  * @param version The highest XVP extension version that the server supports
158  * @param opcode The opcode. 0 is XVP_FAIL, 1 is XVP_INIT
159  */
160 typedef void (*HandleXvpMsgProc)(struct _rfbClient* client, uint8_t version, uint8_t opcode);
161 typedef void (*HandleKeyboardLedStateProc)(struct _rfbClient* client, int value, int pad);
162 typedef rfbBool (*HandleCursorPosProc)(struct _rfbClient* client, int x, int y);
163 typedef void (*SoftCursorLockAreaProc)(struct _rfbClient* client, int x, int y, int w, int h);
164 typedef void (*SoftCursorUnlockScreenProc)(struct _rfbClient* client);
165 typedef void (*GotFrameBufferUpdateProc)(struct _rfbClient* client, int x, int y, int w, int h);
166 typedef void (*FinishedFrameBufferUpdateProc)(struct _rfbClient* client);
167 typedef char* (*GetPasswordProc)(struct _rfbClient* client);
168 typedef rfbCredential* (*GetCredentialProc)(struct _rfbClient* client, int credentialType);
169 typedef rfbBool (*MallocFrameBufferProc)(struct _rfbClient* client);
170 typedef void (*GotXCutTextProc)(struct _rfbClient* client, const char *text, int textlen);
171 typedef void (*BellProc)(struct _rfbClient* client);
172 
173 typedef void (*GotCursorShapeProc)(struct _rfbClient* client, int xhot, int yhot, int width, int height, int bytesPerPixel);
174 typedef void (*GotCopyRectProc)(struct _rfbClient* client, int src_x, int src_y, int w, int h, int dest_x, int dest_y);
175 
176 typedef struct _rfbClient {
177 	uint8_t* frameBuffer;
178 	int width, height;
179 
180 	int endianTest;
181 
182 	AppData appData;
183 
184 	const char* programName;
185 	char* serverHost;
186 	int serverPort; /**< if -1, then use file recorded by vncrec */
187 	rfbBool listenSpecified;
188 	int listenPort, flashPort;
189 
190 	struct {
191 		int x, y, w, h;
192 	} updateRect;
193 
194 	/** Note that the CoRRE encoding uses this buffer and assumes it is big enough
195 	   to hold 255 * 255 * 32 bits -> 260100 bytes.  640*480 = 307200 bytes.
196 	   Hextile also assumes it is big enough to hold 16 * 16 * 32 bits.
197 	   Tight encoding assumes BUFFER_SIZE is at least 16384 bytes. */
198 
199 #define RFB_BUFFER_SIZE (640*480)
200 	char buffer[RFB_BUFFER_SIZE];
201 
202 	/* rfbproto.c */
203 
204 	int sock;
205 	rfbBool canUseCoRRE;
206 	rfbBool canUseHextile;
207 	char *desktopName;
208 	rfbPixelFormat format;
209 	rfbServerInitMsg si;
210 
211 	/* sockets.c */
212 #define RFB_BUF_SIZE 8192
213 	char buf[RFB_BUF_SIZE];
214 	char *bufoutptr;
215 	int buffered;
216 
217 	/* The zlib encoding requires expansion/decompression/deflation of the
218 	   compressed data in the "buffer" above into another, result buffer.
219 	   However, the size of the result buffer can be determined precisely
220 	   based on the bitsPerPixel, height and width of the rectangle.  We
221 	   allocate this buffer one time to be the full size of the buffer. */
222 
223 	/* Ultra Encoding uses this buffer too */
224 
225 	int ultra_buffer_size;
226 	char *ultra_buffer;
227 
228 	int raw_buffer_size;
229 	char *raw_buffer;
230 
231 #ifdef LIBVNCSERVER_HAVE_LIBZ
232 	z_stream decompStream;
233 	rfbBool decompStreamInited;
234 #endif
235 
236 
237 #ifdef LIBVNCSERVER_HAVE_LIBZ
238 	/*
239 	 * Variables for the ``tight'' encoding implementation.
240 	 */
241 
242 	/** Separate buffer for compressed data. */
243 #define ZLIB_BUFFER_SIZE 30000
244 	char zlib_buffer[ZLIB_BUFFER_SIZE];
245 
246 	/* Four independent compression streams for zlib library. */
247 	z_stream zlibStream[4];
248 	rfbBool zlibStreamActive[4];
249 
250 	/* Filter stuff. Should be initialized by filter initialization code. */
251 	rfbBool cutZeros;
252 	int rectWidth, rectColors;
253 	char tightPalette[256*4];
254 	uint8_t tightPrevRow[2048*3*sizeof(uint16_t)];
255 
256 #ifdef LIBVNCSERVER_HAVE_LIBJPEG
257 	/** JPEG decoder state. */
258 	rfbBool jpegError;
259 
260 	struct jpeg_source_mgr* jpegSrcManager;
261 	void* jpegBufferPtr;
262 	size_t jpegBufferLen;
263 
264 #endif
265 #endif
266 
267 
268 	/* cursor.c */
269 	uint8_t *rcSource, *rcMask;
270 
271 	/** private data pointer */
272 	rfbClientData* clientData;
273 
274 	rfbVNCRec* vncRec;
275 
276 	/* Keyboard State support (is 'Caps Lock' set on the remote display???) */
277 	int KeyboardLedStateEnabled;
278 	int CurrentKeyboardLedState;
279 
280 	int canHandleNewFBSize;
281 
282 	/* hooks */
283 	HandleTextChatProc         HandleTextChat;
284 	HandleKeyboardLedStateProc HandleKeyboardLedState;
285 	HandleCursorPosProc HandleCursorPos;
286 	SoftCursorLockAreaProc SoftCursorLockArea;
287 	SoftCursorUnlockScreenProc SoftCursorUnlockScreen;
288 	GotFrameBufferUpdateProc GotFrameBufferUpdate;
289 	/** the pointer returned by GetPassword will be freed after use! */
290 	GetPasswordProc GetPassword;
291 	MallocFrameBufferProc MallocFrameBuffer;
292 	GotXCutTextProc GotXCutText;
293 	BellProc Bell;
294 
295 	GotCursorShapeProc GotCursorShape;
296 	GotCopyRectProc GotCopyRect;
297 
298 	/** Which messages are supported by the server
299 	 * This is a *guess* for most servers.
300 	 * (If we can even detect the type of server)
301 	 *
302 	 * If the server supports the "rfbEncodingSupportedMessages"
303 	 * then this will be updated when the encoding is received to
304 	 * accurately reflect the servers capabilities.
305 	 */
306 	rfbSupportedMessages supportedMessages;
307 
308 	/** negotiated protocol version */
309 	int major, minor;
310 
311 	/** The selected security types */
312 	uint32_t authScheme, subAuthScheme;
313 
314 	/** The TLS session for Anonymous TLS and VeNCrypt */
315 	void* tlsSession;
316 
317 	/** To support security types that requires user input (except VNC password
318 	 * authentication), for example VeNCrypt and MSLogon, this callback function
319 	 * must be set before the authentication. Otherwise, it implicates that the
320 	 * caller application does not support it and related security types should
321 	 * be bypassed.
322 	 */
323 	GetCredentialProc GetCredential;
324 
325 	/** The 0-terminated security types supported by the client.
326 	 * Set by function SetClientAuthSchemes() */
327 	uint32_t *clientAuthSchemes;
328 
329 	/** When the server is a repeater, this specifies the final destination */
330 	char *destHost;
331 	int destPort;
332 
333         /** the QoS IP DSCP for this client */
334         int QoS_DSCP;
335 
336         /** hook to handle xvp server messages */
337 	HandleXvpMsgProc           HandleXvpMsg;
338 
339 	/* listen.c */
340         int listenSock;
341 
342 	FinishedFrameBufferUpdateProc FinishedFrameBufferUpdate;
343 
344 	char *listenAddress;
345         /* IPv6 listen socket, address and port*/
346         int listen6Sock;
347         char* listen6Address;
348         int listen6Port;
349 } rfbClient;
350 
351 /* cursor.c */
352 
353 extern rfbBool HandleCursorShape(rfbClient* client,int xhot, int yhot, int width, int height, uint32_t enc);
354 
355 /* listen.c */
356 
357 extern void listenForIncomingConnections(rfbClient* viewer);
358 extern int listenForIncomingConnectionsNoFork(rfbClient* viewer, int usec_timeout);
359 
360 /* rfbproto.c */
361 
362 extern rfbBool rfbEnableClientLogging;
363 typedef void (*rfbClientLogProc)(const char *format, ...);
364 extern rfbClientLogProc rfbClientLog,rfbClientErr;
365 extern rfbBool ConnectToRFBServer(rfbClient* client,const char *hostname, int port);
366 extern rfbBool ConnectToRFBRepeater(rfbClient* client,const char *repeaterHost, int repeaterPort, const char *destHost, int destPort);
367 extern void SetClientAuthSchemes(rfbClient* client,const uint32_t *authSchemes, int size);
368 extern rfbBool InitialiseRFBConnection(rfbClient* client);
369 /**
370  * Sends format and encoding parameters to the server. Your application can
371  * modify the 'client' data structure directly. However some changes to this
372  * structure must be communicated back to the server. For instance, if you
373  * change the encoding to hextile, the server needs to know that it should send
374  * framebuffer updates in hextile format. Likewise if you change the pixel
375  * format of the framebuffer, the server must be notified about this as well.
376  * Call this function to propagate your changes of the local 'client' structure
377  * over to the server.
378  * @li Encoding type
379  * @li RFB protocol extensions announced via pseudo-encodings
380  * @li Framebuffer pixel format (like RGB vs ARGB)
381  * @li Remote cursor support
382  * @param client The client in which the format or encodings have been changed
383  * @return true if the format or encodings were sent to the server successfully,
384  * false otherwise
385  */
386 extern rfbBool SetFormatAndEncodings(rfbClient* client);
387 extern rfbBool SendIncrementalFramebufferUpdateRequest(rfbClient* client);
388 /**
389  * Sends a framebuffer update request to the server. A VNC client may request an
390  * update from the server at any time. You can also specify which portions of
391  * the screen you want updated. This can be handy if a pointer is at certain
392  * location and the user pressed a mouse button, for instance. Then you can
393  * immediately request an update of the region around the pointer from the
394  * server.
395  * @note The coordinate system is a left-handed Cartesian coordinate system with
396  * the Z axis (unused) pointing out of the screen. Alternately you can think of
397  * it as a right-handed Cartesian coordinate system with the Z axis pointing
398  * into the screen. The origin is at the upper left corner of the framebuffer.
399  * @param client The client through which to send the request
400  * @param x The horizontal position of the update request rectangle
401  * @param y The vertical position of the update request rectangle
402  * @param w The width of the update request rectangle
403  * @param h The height of the update request rectangle
404  * @param incremental false: server sends rectangle even if nothing changed.
405  * true: server only sends changed parts of rectangle.
406  * @return true if the update request was sent successfully, false otherwise
407  */
408 extern rfbBool SendFramebufferUpdateRequest(rfbClient* client,
409 					 int x, int y, int w, int h,
410 					 rfbBool incremental);
411 extern rfbBool SendScaleSetting(rfbClient* client,int scaleSetting);
412 /**
413  * Sends a pointer event to the server. A pointer event includes a cursor
414  * location and a button mask. The button mask indicates which buttons on the
415  * pointing device are pressed. Each button is represented by a bit in the
416  * button mask. A 1 indicates the button is pressed while a 0 indicates that it
417  * is not pressed. You may use these pre-defined button masks by ORing them
418  * together: rfbButton1Mask, rfbButton2Mask, rfbButton3Mask, rfbButton4Mask
419  * rfbButton5Mask
420  * @note  The cursor location is relative to the client's framebuffer, not the
421  * client's screen itself.
422  * @note The coordinate system is a left-handed Cartesian coordinate system with
423  * the Z axis (unused) pointing out of the screen. Alternately you can think of
424  * it as a right-handed Cartesian coordinate system with the Z axis pointing
425  * into the screen. The origin is at the upper left corner of the screen.
426  * @param client The client through which to send the pointer event
427  * @param x the horizontal location of the cursor
428  * @param y the vertical location of the cursor
429  * @param buttonMask the button mask indicating which buttons are pressed
430  * @return true if the pointer event was sent successfully, false otherwise
431  */
432 extern rfbBool SendPointerEvent(rfbClient* client,int x, int y, int buttonMask);
433 /**
434  * Sends a key event to the server. If your application is not merely a VNC
435  * viewer (i.e. it controls the server), you'll want to send the keys that the
436  * user presses to the server. Use this function to do that.
437  * @param client The client through which to send the key event
438  * @param key An rfbKeySym defined in rfb/keysym.h
439  * @param down true if this was a key down event, false otherwise
440  * @return true if the key event was send successfully, false otherwise
441  */
442 extern rfbBool SendKeyEvent(rfbClient* client,uint32_t key, rfbBool down);
443 /**
444  * Places a string on the server's clipboard. Use this function if you want to
445  * be able to copy and paste between the server and your application. For
446  * instance, when your application is notified that the user copied some text
447  * onto the clipboard, you would call this function to synchronize the server's
448  * clipboard with your local clipboard.
449  * @param client The client structure through which to send the client cut text
450  * message
451  * @param str The string to send (doesn't need to be NULL terminated)
452  * @param len The length of the string
453  * @return true if the client cut message was sent successfully, false otherwise
454  */
455 extern rfbBool SendClientCutText(rfbClient* client,char *str, int len);
456 /**
457  * Handles messages from the RFB server. You must call this function
458  * intermittently so LibVNCClient can parse messages from the server. For
459  * example, if your app has a draw loop, you could place a call to this
460  * function within that draw loop.
461  * @note You must call WaitForMessage() before you call this function.
462  * @param client The client which will handle the RFB server messages
463  * @return true if the client was able to handle the RFB server messages, false
464  * otherwise
465  */
466 extern rfbBool HandleRFBServerMessage(rfbClient* client);
467 
468 /**
469  * Sends a text chat message to the server.
470  * @param client The client through which to send the message
471  * @param text The text to send
472  * @return true if the text was sent successfully, false otherwise
473  */
474 extern rfbBool TextChatSend(rfbClient* client, char *text);
475 /**
476  * Opens a text chat window on the server.
477  * @param client The client through which to send the message
478  * @return true if the window was opened successfully, false otherwise
479  */
480 extern rfbBool TextChatOpen(rfbClient* client);
481 /**
482  * Closes the text chat window on the server.
483  * @param client The client through which to send the message
484  * @return true if the window was closed successfully, false otherwise
485  */
486 extern rfbBool TextChatClose(rfbClient* client);
487 extern rfbBool TextChatFinish(rfbClient* client);
488 extern rfbBool PermitServerInput(rfbClient* client, int enabled);
489 extern rfbBool SendXvpMsg(rfbClient* client, uint8_t version, uint8_t code);
490 
491 extern void PrintPixelFormat(rfbPixelFormat *format);
492 
493 extern rfbBool SupportsClient2Server(rfbClient* client, int messageType);
494 extern rfbBool SupportsServer2Client(rfbClient* client, int messageType);
495 
496 /* client data */
497 
498 /**
499  * Associates a client data tag with the given pointer. LibVNCClient has
500  * several events to which you can associate your own handlers. These handlers
501  * have the client structure as one of their parameters. Sometimes, you may want
502  * to make data from elsewhere in your application available to these handlers
503  * without using a global variable. To do this, you call
504  * rfbClientSetClientData() and associate the data with a tag. Then, your
505  * handler can call rfbClientGetClientData() and get the a pointer to the data
506  * associated with that tag.
507  * @param client The client in which to set the client data
508  * @param tag A unique tag which identifies the data
509  * @param data A pointer to the data to associate with the tag
510  */
511 void rfbClientSetClientData(rfbClient* client, void* tag, void* data);
512 /**
513  * Returns a pointer to the client data associated with the given tag. See the
514  * the documentation for rfbClientSetClientData() for a discussion of how you
515  * can use client data.
516  * @param client The client from which to get the client data
517  * @param tag The tag which identifies the client data
518  * @return a pointer to the client data
519  */
520 void* rfbClientGetClientData(rfbClient* client, void* tag);
521 
522 /* protocol extensions */
523 
524 typedef struct _rfbClientProtocolExtension {
525 	int* encodings;
526 	/** returns TRUE if the encoding was handled */
527 	rfbBool (*handleEncoding)(rfbClient* cl,
528 		rfbFramebufferUpdateRectHeader* rect);
529 	/** returns TRUE if it handled the message */
530 	rfbBool (*handleMessage)(rfbClient* cl,
531 		 rfbServerToClientMsg* message);
532 	struct _rfbClientProtocolExtension* next;
533 } rfbClientProtocolExtension;
534 
535 void rfbClientRegisterExtension(rfbClientProtocolExtension* e);
536 
537 /* sockets.c */
538 
539 extern rfbBool errorMessageOnReadFailure;
540 
541 extern rfbBool ReadFromRFBServer(rfbClient* client, char *out, unsigned int n);
542 extern rfbBool WriteToRFBServer(rfbClient* client, char *buf, int n);
543 extern int FindFreeTcpPort(void);
544 extern int ListenAtTcpPort(int port);
545 extern int ListenAtTcpPortAndAddress(int port, const char *address);
546 extern int ConnectClientToTcpAddr(unsigned int host, int port);
547 extern int ConnectClientToTcpAddr6(const char *hostname, int port);
548 extern int ConnectClientToUnixSock(const char *sockFile);
549 extern int AcceptTcpConnection(int listenSock);
550 extern rfbBool SetNonBlocking(int sock);
551 extern rfbBool SetDSCP(int sock, int dscp);
552 
553 extern rfbBool StringToIPAddr(const char *str, unsigned int *addr);
554 extern rfbBool SameMachine(int sock);
555 /**
556  * Waits for an RFB message to arrive from the server. Before handling a message
557  * with HandleRFBServerMessage(), you must wait for your client to receive one.
558  * This function blocks until a message is received. You may specify a timeout
559  * in microseconds. Once this number of microseconds have elapsed, the function
560  * will return.
561  * @param client The client to cause to wait until a message is received
562  * @param usecs The timeout in microseconds
563  * @return the return value of the underlying select() call
564  */
565 extern int WaitForMessage(rfbClient* client,unsigned int usecs);
566 
567 /* vncviewer.c */
568 /**
569  * Allocates and returns a pointer to an rfbClient structure. This will probably
570  * be the first LibVNCClient function your client code calls. Most libVNCClient
571  * functions operate on an rfbClient structure, and this function allocates
572  * memory for that structure. When you're done with the rfbClient structure
573  * pointer this function returns, you should free the memory rfbGetClient()
574  * allocated by calling rfbClientCleanup().
575  *
576  * A pixel is one dot on the screen. The number of bytes in a pixel will depend
577  * on the number of samples in that pixel and the number of bits in each sample.
578  * A sample represents one of the primary colors in a color model. The RGB
579  * color model uses red, green, and blue samples respectively. Suppose you
580  * wanted to use 16-bit RGB color: You would have three samples per pixel (one
581  * for each primary color), five bits per sample (the quotient of 16 RGB bits
582  * divided by three samples), and two bytes per pixel (the smallest multiple of
583  * eight bits in which the 16-bit pixel will fit). If you wanted 32-bit RGB
584  * color, you would have three samples per pixel again, eight bits per sample
585  * (since that's how 32-bit color is defined), and four bytes per pixel (the
586  * smallest multiple of eight bits in which the 32-bit pixel will fit.
587  * @param bitsPerSample The number of bits in a sample
588  * @param samplesPerPixel The number of samples in a pixel
589  * @param bytesPerPixel The number of bytes in a pixel
590  * @return a pointer to the allocated rfbClient structure
591  */
592 rfbClient* rfbGetClient(int bitsPerSample,int samplesPerPixel,int bytesPerPixel);
593 /**
594  * Initializes the client. The format is {PROGRAM_NAME, [OPTIONS]..., HOST}. This
595  * function does not initialize the program name if the rfbClient's program
596  * name is set already. The options are as follows:
597  * <table>
598  * <tr><th>Option</th><th>Description</th></tr>
599  * <tr><td>-listen</td><td>Listen for incoming connections.</td></tr>
600  * <tr><td>-listennofork</td><td>Listen for incoming connections without forking.
601  * </td></tr>
602  * <tr><td>-play</td><td>Set this client to replay a previously recorded session.</td></tr>
603  * <tr><td>-encodings</td><td>Set the encodings to use. The next item in the
604  * argv array is the encodings string, consisting of comma separated encodings like 'tight,ultra,raw'.</td></tr>
605  * <tr><td>-compress</td><td>Set the compression level. The next item in the
606  * argv array is the compression level as an integer. Ranges from 0 (lowest) to 9 (highest).
607  * </td></tr>
608  * <tr><td>-scale</td><td>Set the scaling level. The next item in the
609  * argv array is the scaling level as an integer. The screen will be scaled down by this factor.</td></tr>
610  * <tr><td>-qosdscp</td><td>Set the Quality of Service Differentiated Services
611  * Code Point (QoS DSCP). The next item in the argv array is the code point as
612  * an integer.</td></tr>
613  * <tr><td>-repeaterdest</td><td>Set a VNC repeater address. The next item in the argv array is
614  * the repeater's address as a string.</td></tr>
615  * </table>
616  *
617  * The host may include a port number (delimited by a ':').
618  * @param client The client to initialize
619  * @param argc The number of arguments to the initializer
620  * @param argv The arguments to the initializer as an array of NULL terminated
621  * strings
622  * @return true if the client was initialized successfully, false otherwise.
623  */
624 rfbBool rfbInitClient(rfbClient* client,int* argc,char** argv);
625 /**
626  * Cleans up the client structure and releases the memory allocated for it. You
627  * should call this when you're done with the rfbClient structure that you
628  * allocated with rfbGetClient().
629  * @note rfbClientCleanup() does not touch client->frameBuffer.
630  * @param client The client to clean up
631  */
632 void rfbClientCleanup(rfbClient* client);
633 
634 #if(defined __cplusplus)
635 }
636 #endif
637 
638 /**
639  * @}
640  */
641 
642 /**
643  @page libvncclient_doc LibVNCClient Documentation
644  @section example_code Example Code
645  See SDLvncviewer.c for a rather complete client example.
646 */
647 
648 #endif
649