vnc-server.c
来自「eCos操作系统源码」· C语言 代码 · 共 1,754 行 · 第 1/4 页
C
1,754 行
{ 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 + =
减小字号Ctrl + -
显示快捷键?