⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vnc-server.c

📁 eCos/RedBoot for勤研ARM AnywhereII(4510) 含全部源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
        {
            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 + -