📄 vnc-server.c
字号:
{
goto close_connection;
}
/* Receive ProtocolVersion the client wants to use */
if (GetMessageData(client_sock, &(message_buffer[0]), 12) == 0)
{
goto close_connection;
}
/* Check this is acceptable (RFB 003.xxx is okay) */
ProtocolOkay = 1;
for (i=0; i < 8; i++)
{
if (message_buffer[i] != server_ProtocolVersion[i])
{
ProtocolOkay = 0;
}
/* Store the protocol version - ignoring thr 'RFB ' part */
protocol_ver[i] = message_buffer[i + 4];
}
protocol_ver[7] = 0;
/*
ProtocolVersion Handshake - end
*/
/*
Authentication - begin
*/
/* Send Authentication scheme to be used to client */
if (ProtocolOkay == 0)
{
/* ProtocolVerion is not okay */
/* Generate the Bad ProtocolVerion message */
ptr_to_uint32 = (cyg_uint32 *) &(message_buffer[0]);
*ptr_to_uint32 = htonl(0);
ptr_to_uint32 = (cyg_uint32 *) &(message_buffer[4]);
*ptr_to_uint32 = htonl(strlen(bad_protocol));
strcpy(&(message_buffer[8]), bad_protocol);
if (send(client_sock, message_buffer, 8 + strlen(bad_protocol), 0) != (8 + strlen(bad_protocol)))
{
diag_printf("Call to send() failed\n");
}
goto close_connection;
}
else
{
/* ProtocolVerion is not okay - connect with no authentication*/
/* Generate the No Authentication message */
ptr_to_uint32 = (cyg_uint32 *) &(message_buffer[0]);
*ptr_to_uint32 = htonl((cyg_uint32)1);
if (send(client_sock, message_buffer, 4, 0) != 4)
{
diag_printf("Call to send() failed\n");
goto close_connection;
}
}
/*
Authentication - end
*/
/*
ClientInitialisation - begin
*/
/* Receive initialisation message from client (1 byte) */
if (GetMessageData(client_sock, &(message_buffer[0]), 1) == 0)
{
goto close_connection;
}
/* Do nothing with this as we only support 1 Client at a time */
/*
ClientInitialisation - end
*/
/*
ServerInitialisation - begin
*/
/* Create Initialisation message for client */
ptr_to_uint16 = (cyg_uint16 *) &(message_buffer[0]);
*ptr_to_uint16 = htons((cyg_uint16)CYGNUM_VNC_SERVER_FRAME_WIDTH);
ptr_to_uint16 = (cyg_uint16 *) &(message_buffer[2]);
*ptr_to_uint16 = htons((cyg_uint16)CYGNUM_VNC_SERVER_FRAME_HEIGHT);
message_buffer[4] = (cyg_uint8)BITS_PER_PIXEL;
message_buffer[5] = (cyg_uint8)PIXEL_DEPTH;
message_buffer[6] = (cyg_uint8)BIG_ENDIAN_FLAG;
message_buffer[7] = (cyg_uint8)TRUE_COLOUR_FLAG;
ptr_to_uint16 = (cyg_uint16 *) &(message_buffer[8]);
*ptr_to_uint16 = htons((cyg_uint16)RED_MAX);
ptr_to_uint16 = (cyg_uint16 *) &(message_buffer[10]);
*ptr_to_uint16 = htons((cyg_uint16)GREEN_MAX);
ptr_to_uint16 = (cyg_uint16 *) &(message_buffer[12]);
*ptr_to_uint16 = htons((cyg_uint16)BLUE_MAX);
message_buffer[14] = (cyg_uint8)RED_SHIFT;
message_buffer[15] = (cyg_uint8)GREEN_SHIFT;
message_buffer[16] = (cyg_uint8)BLUE_SHIFT;
ptr_to_uint32 = (cyg_uint32 *) &(message_buffer[20]);
*ptr_to_uint32 = htonl(strlen(desktop_name));
strcpy(&(message_buffer[24]), desktop_name);
if (send(client_sock, message_buffer, 24 + strlen(desktop_name), 0) != (24 + strlen(desktop_name)))
{
diag_printf("Call to send() failed\n");
}
/*
ServerInitialisation - end
*/
/* Cancel any outstanding Sound Bell requests */
cyg_mutex_lock(&SoundBell_lock);
SoundBellCount = 0;
cyg_mutex_unlock(&SoundBell_lock);
diag_printf("VNC client connected (RFB Protocol Ver: %s)\n", protocol_ver);
/* Main message handling loop */
while(1)
{
int num_of_encodings;
/* Receive 1st byte of message from client */
if (GetMessageData(client_sock, &(message_buffer[0]), 1) == 0)
{
goto close_connection;
}
switch(message_buffer[0])
{
case SET_PIXEL_FORMAT:
/* Get the remainder (19 bytes) of message */
if (GetMessageData(client_sock, &(message_buffer[1]), 19) == 0)
{
goto close_connection;
}
/* Check pixel format is as expected */
i = 0;
if (message_buffer[4] != BITS_PER_PIXEL)
{
diag_printf("SetPixelFormat message from client has incompatible bits-per-pixel field:\n");
diag_printf(" Expected: %d - Got: %d\n", BITS_PER_PIXEL, message_buffer[4]);
i++;
}
if (message_buffer[5] != PIXEL_DEPTH)
{
diag_printf("SetPixelFormat message from client has incompatible pixel-depth field:\n");
diag_printf(" Expected: %d - Got: %d\n", PIXEL_DEPTH, message_buffer[5]);
i++;
}
if (message_buffer[7] != TRUE_COLOUR_FLAG)
{
diag_printf("SetPixelFormat message from client has incompatible true-colour-flag field:\n");
diag_printf(" Expected: %d - Got: %d\n", TRUE_COLOUR_FLAG, message_buffer[7]);
i++;
}
ptr_to_uint16 = (cyg_uint16 *)&(message_buffer[8]);
if (htons(*ptr_to_uint16) != RED_MAX)
{
diag_printf("SetPixelFormat message from client has incompatible red-max field:\n");
diag_printf(" Expected: %d - Got: %d\n", RED_MAX, htons(*ptr_to_uint16));
i++;
}
ptr_to_uint16 = (cyg_uint16 *)&(message_buffer[10]);
if (htons(*ptr_to_uint16) != GREEN_MAX)
{
diag_printf("SetPixelFormat message from client has incompatible green-max field:\n");
diag_printf(" Expected: %d - Got: %d\n", GREEN_MAX, htons(*ptr_to_uint16));
i++;
}
ptr_to_uint16 = (cyg_uint16 *)&(message_buffer[12]);
if (htons(*ptr_to_uint16) != BLUE_MAX)
{
diag_printf("SetPixelFormat message from client has incompatible blue-max field:\n");
diag_printf(" Expected: %d - Got: %d\n", BLUE_MAX, htons(*ptr_to_uint16));
i++;
}
if (message_buffer[14] != RED_SHIFT)
{
diag_printf("SetPixelFormat message from client has incompatible red-shift field:\n");
diag_printf(" Expected: %d - Got: %d\n", RED_SHIFT, message_buffer[14]);
i++;
}
if (message_buffer[15] != GREEN_SHIFT)
{
diag_printf("SetPixelFormat message from client has incompatible green-shift field:\n");
diag_printf(" Expected: %d - Got: %d\n", GREEN_SHIFT, message_buffer[15]);
i++;
}
if (message_buffer[16] != BLUE_SHIFT)
{
diag_printf("SetPixelFormat message from client has incompatible blue-shift field:\n");
diag_printf(" Expected: %d - Got: %d\n", BLUE_SHIFT, message_buffer[16]);
i++;
}
if (i)
{
diag_printf("Disconnecting from client\n");
diag_printf("Please ensure the 'Auto select' is not enabled in your vncviewer options,\n");
diag_printf("then try connecting again.\n");
goto close_connection_quietly;
}
break;
case FIX_COLOUR_MAP_ENTRIES:
/* Not supported, just get the data from the buffer and ignore it */
/* Get the next 5 bytes of message */
if (GetMessageData(client_sock, &(message_buffer[1]), 5) == 0)
{
goto close_connection;
}
/* Calculate how many colour entries are in the buffer */
i = message_buffer[4]*255 + message_buffer[5];
i *= 6;
/* Get this amount of data from the buffer */
for (j = 0; j < i; j++)
{
if (GetMessageData(client_sock, &(message_buffer[6]), 6) == 0)
{
goto close_connection;
}
}
break;
case SET_ENCODINGS:
/* Get the next 3 bytes of message */
if (GetMessageData(client_sock, &(message_buffer[1]), 3) == 0)
{
goto close_connection;
}
num_of_encodings = message_buffer[2]*255 + message_buffer[3];
/* Get the remainder of message */
if (GetMessageData(client_sock, &(message_buffer[0]), 4 * num_of_encodings) == 0)
{
goto close_connection;
}
/* Clear the encoding type structure */
encoding_type.raw = 0;
encoding_type.copy_rectangle = 0;
encoding_type.rre = 0;
encoding_type.corre = 0;
encoding_type.hextile = 0;
for (i = 0; i < num_of_encodings; i++)
{
switch(message_buffer[3 + (i*4)])
{
case 0: /* Raw encoding */
encoding_type.raw = i + 1;
break;
case 1: /* Copy rectangle encoding */
encoding_type.copy_rectangle = i + 1;
break;
case 2: /* RRE encoding */
encoding_type.rre = i + 1;
break;
case 4: /* CoRRE encoding */
encoding_type.corre = i + 1;
break;
case 5: /* Hextile encoding */
encoding_type.hextile = i + 1;
break;
default: /* Unknown coding type - do nothing */
break;
}
}
if (!encoding_type.corre)
{
diag_printf("Warning: SetEncoding message from client does not support CoRRE Encoding\n");
diag_printf("Raw encoding will be used instead\n");
}
break;
case FRAME_BUFFER_UPDATE_REQ:
/* Get the remainder of message (9 bytes) */
if (GetMessageData(client_sock, &(message_buffer[1]), 9) == 0)
{
goto close_connection;
}
if (!message_buffer[1])
{
/* Non-incremental mode - mark the squares that need to be updated */
for (i = (message_buffer[2]*255 + message_buffer[3])/TILE_SIZE;
i <= (message_buffer[2]*255 + message_buffer[3] + message_buffer[6]*255 + message_buffer[7])/TILE_SIZE;
i++)
{
for (j = (message_buffer[4]*255 + message_buffer[5])/TILE_SIZE;
j <= (message_buffer[4]*255 + message_buffer[5] + message_buffer[8]*255 + message_buffer[9])/TILE_SIZE;
j++)
{
tile_updated[j][i] = 1;
}
}
}
/* Signal that there is now a pending update request */
cyg_mutex_lock(&client_active_lock);
update_req = 1;
cyg_cond_signal(&client_active_wait);
cyg_mutex_unlock(&client_active_lock);
break;
case KEY_EVENT:
/* Handle the key event */
/* Get the remainder of message (7 bytes) */
if (GetMessageData(client_sock, &(message_buffer[1]), 7) == 0)
{
goto close_connection;
}
#ifdef CYGPKG_VNC_SERVER_BUILD_KEYBOARD_DRIVER
/* Call the keyboard handle function */
vnc_kbd_handler(&(message_buffer[0]));
#endif
break;
case POINTER_EVENT:
/* Handle the pointer event */
/* Get the remainder of message (5 bytes) */
if (GetMessageData(client_sock, &(message_buffer[1]), 5) == 0)
{
goto close_connection;
}
/* Button mask: message_buffer[1] */
/* X-position: message_buffer[2]*255 + message_buffer[3] */
/* Y-position: message_buffer[4]*255 + message_buffer[5] */
#ifdef CYGPKG_VNC_SERVER_BUILD_MOUSE_DRIVER
/* Called the mouse handler function */
vnc_mouse_handler(&(message_buffer[0]));
#endif
break;
case CLIENT_CUT_TEXT:
/* Handle the client has cut text event */
/* Current we just get and discard the data */
/* In future it might be nice to expand the API to */
/* allow this data to be passed to the application */
/* Get the next 7 bytes of the message */
if (GetMessageData(client_sock, &(message_buffer[1]), 7) == 0)
{
goto close_connection;
}
ptr_to_uint32 = (cyg_uint32 *)&(message_buffer[4]);
temp_long = htonl(*ptr_to_uint32);
while (temp_long > 0)
{
/* Get the text in chunks MESSAGE_BUFFER_SIZE-1 characters */
if (temp_long > MESSAGE_BUFFER_SIZE-2)
{
if (GetMessageData(client_sock, &(message_buffer[0]), MESSAGE_BUFFER_SIZE-1) == 0)
{
goto close_connection;
}
message_buffer[MESSAGE_BUFFER_SIZE-1] = 0;
temp_long -= (MESSAGE_BUFFER_SIZE-1);
}
else
{
if (GetMessageData(client_sock, &(message_buffer[0]), temp_long) == 0)
{
goto close_connection;
}
message_buffer[temp_long] = 0;
temp_long = 0;
}
}
break;
default:
diag_printf("Unknown message from client\n");
}
}
close_connection:
diag_printf("VNC client disconnected\n");
close_connection_quietly:
/* Cancel any outstanding update requests */
cyg_mutex_lock(&client_active_lock);
update_req = 0;
cyg_mutex_unlock(&client_active_lock);
close(client_sock);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -