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 + -
显示快捷键?