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

📄 vnc-server.c

📁 eCos/RedBoot for勤研ARM AnywhereII(4510) 含全部源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
//==========================================================================
//
//      vnc-server.c
//
//
//
//==========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Red Hat, Inc.
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later version.
//
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//==========================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s):    Chris Garry <cgarry@sweeneydesign.co.uk>
// Contributors:
// Date:         2003-08-22
// Purpose:
// Description:  VNC server for eCos
//
//####DESCRIPTIONEND####
//
//========================================================================*/


#include <cyg/hal/hal_arch.h>    /* CYGNUM_HAL_STACK_SIZE_MINIMUM & CYGNUM_HAL_STACK_SIZE_TYPICAL */
#include <pkgconf/system.h>
#include <cyg/infra/diag.h>      /* diag_printf */
#include <string.h>
#include <stdlib.h>
#include <vnc-server.h>

#ifdef CYGPKG_NET
/* eCos (BSD stack) include */
#include <network.h>
#else
/* eCos (lwIP stack) include */
#include <lwip/sys.h>           /* lwIP stack includes */
#define LWIP_COMPAT_SOCKETS 1
#include <lwip/sockets.h>
#include <lwip/inet.h>
#endif

#define BACKLOG             5       /* Number of pending connections queue will hold */
#define MESSAGE_BUFFER_SIZE 50
#define TILE_SIZE           CYGNUM_VNC_SERVER_TILE_SIZE
#define TRUE_COLOUR_FLAG    1       /* True colour is set */
#define BIG_ENDIAN_FLAG     1       /* Always send colour data big endian */

/* Various definitions for different pixel types */
#ifdef CYGNUM_VNC_SERVER_PIXEL_RGB332
#define BITS_PER_PIXEL      8      /* Bits per pixel */
#define PIXEL_DEPTH         8      /* Usefull bits per pixel */
#define RED_MAX             7
#define GREEN_MAX           7
#define BLUE_MAX            3
#define RED_SHIFT           5
#define GREEN_SHIFT         2
#define BLUE_SHIFT          0
#endif

#ifdef CYGNUM_VNC_SERVER_PIXEL_BGR233
#define BITS_PER_PIXEL      8      /* Bits per pixel */
#define PIXEL_DEPTH         8      /* Usefull bits per pixel */
#define RED_MAX             7
#define GREEN_MAX           7
#define BLUE_MAX            3
#define RED_SHIFT           0
#define GREEN_SHIFT         3
#define BLUE_SHIFT          6
#endif

#ifdef CYGNUM_VNC_SERVER_PIXEL_RGB555
#define BITS_PER_PIXEL      16     /* Bits per pixel */
#define PIXEL_DEPTH         15     /* Usefull bits per pixel */
#define RED_MAX             31
#define GREEN_MAX           31
#define BLUE_MAX            31
#define RED_SHIFT           10
#define GREEN_SHIFT         5
#define BLUE_SHIFT          0
#endif

#ifdef CYGNUM_VNC_SERVER_PIXEL_RGB565
#define BITS_PER_PIXEL      16     /* Bits per pixel */
#define PIXEL_DEPTH         16     /* Usefull bits per pixel */
#define RED_MAX             31
#define GREEN_MAX           63
#define BLUE_MAX            31
#define RED_SHIFT           11
#define GREEN_SHIFT         5
#define BLUE_SHIFT          0
#endif

#ifdef CYGNUM_VNC_SERVER_PIXEL_TRUECOLOR0888
#define BITS_PER_PIXEL      32     /* Bits per pixel */
#define PIXEL_DEPTH         24     /* Usefull bits per pixel */
#define RED_MAX             255
#define GREEN_MAX           255
#define BLUE_MAX            255
#define RED_SHIFT           16
#define GREEN_SHIFT         8
#define BLUE_SHIFT          0
#endif

/* Client to Server message types */
#define SET_PIXEL_FORMAT         0
#define FIX_COLOUR_MAP_ENTRIES   1
#define SET_ENCODINGS            2
#define FRAME_BUFFER_UPDATE_REQ  3
#define KEY_EVENT                4
#define POINTER_EVENT            5
#define CLIENT_CUT_TEXT          6

/* Macros to split colour to bytes */
#define COLOUR2BYTE1(col) ((col>>8)&0xFF)
#define COLOUR2BYTE0(col) (col&0xFF)

/* Function prototype */
static int GetMessageData(int, char *, int);
static int GenTileUpdateData(cyg_uint8 *);

/* Mouse handler funcrion - in vnc_mouse.c */
void vnc_mouse_handler(cyg_uint8 *data);
/* Keyboard handler funcrion - in vnc_kbd.c */
void vnc_kbd_handler(cyg_uint8 *data);


/* Thread function prototypes */
#ifdef CYGPKG_NET
cyg_thread_entry_t client_handler, frame_update;
#else
cyg_thread_entry_t tMain;
static void client_handler(void *);
static void frame_update(void *);
#endif

#ifdef CYGPKG_NET
/* Handles for the threads */
cyg_handle_t client_handler_hndl, frame_update_hndl;
/* Thread objects for the system to manipulate threads */
cyg_thread thread_s[2];
#else
cyg_handle_t lwip_startup_hndl;
cyg_thread thread_s;
#endif

/* Define size of each thread's stack */
#define MIN_STACK_SIZE (CYGNUM_HAL_STACK_SIZE_MINIMUM)
#define MAIN_STACK_SIZE (CYGNUM_HAL_STACK_SIZE_TYPICAL)

/* Allocate space for stacks */
#ifdef CYGPKG_NET
static char client_handler_stack[MAIN_STACK_SIZE];
static char frame_update_stack[MAIN_STACK_SIZE];
#else
static char lwip_startup_stack[MIN_STACK_SIZE];
#endif

/* Messages */
char server_ProtocolVersion[] = "RFB 003.003\n";
char bad_protocol[] = "Unsupported ProtocolVersion";
char sound_bell[] = "\2";
char desktop_name[] = CYGDAT_VNC_DESKTOP_NAME;

/* Frame Buffer */
volatile vnc_colour_t frame_buffer[CYGNUM_VNC_SERVER_FRAME_HEIGHT][CYGNUM_VNC_SERVER_FRAME_WIDTH];

/* Calculate the number of tiles in the X and Y directions */
#if (CYGNUM_VNC_SERVER_FRAME_HEIGHT % TILE_SIZE) != 0
#define NUM_TILES_Y_AXIS (CYGNUM_VNC_SERVER_FRAME_HEIGHT/TILE_SIZE + 1)
#define LAST_TILE_HEIGHT (CYGNUM_VNC_SERVER_FRAME_HEIGHT % TILE_SIZE)
#else
#define NUM_TILES_Y_AXIS (CYGNUM_VNC_SERVER_FRAME_HEIGHT/TILE_SIZE)
#define LAST_TILE_HEIGHT TILE_SIZE
#endif

#if (CYGNUM_VNC_SERVER_FRAME_WIDTH % TILE_SIZE) != 0
#define NUM_TILES_X_AXIS (CYGNUM_VNC_SERVER_FRAME_WIDTH/TILE_SIZE + 1)
#define LAST_TILE_WIDTH (CYGNUM_VNC_SERVER_FRAME_WIDTH % TILE_SIZE)
#else
#define NUM_TILES_X_AXIS (CYGNUM_VNC_SERVER_FRAME_WIDTH/TILE_SIZE)
#define LAST_TILE_WIDTH TILE_SIZE
#endif

/* Array for marking tiles that have been updated */
volatile int tile_updated[NUM_TILES_Y_AXIS][NUM_TILES_X_AXIS];

/* Conditional variable to signal that a client is connected and initialised */
cyg_mutex_t client_active_lock;
cyg_cond_t client_active_wait;
volatile int update_req;

/* Mutex and variable for sounding the client's bell */
cyg_mutex_t SoundBell_lock;
volatile int SoundBellCount;

volatile int client_sock;   /* Socket descriptor for client connection */


/* Variable to hold the frame format details */
vnc_frame_format_t frame_format = {CYGNUM_VNC_SERVER_FRAME_WIDTH,
                                   CYGNUM_VNC_SERVER_FRAME_HEIGHT,
                                   frame_buffer,
#ifdef CYGNUM_VNC_SERVER_PIXEL_RGB332
                                   1,
#else
                                   0,
#endif
#ifdef CYGNUM_VNC_SERVER_PIXEL_RGB555
                                   1,
#else
                                   0,
#endif
#ifdef CYGNUM_VNC_SERVER_PIXEL_RGB565
                                   1,
#else
                                   0,
#endif
#ifdef CYGNUM_VNC_SERVER_PIXEL_BGR233
                                   1,
#else
                                   0,
#endif
#ifdef CYGNUM_VNC_SERVER_PIXEL_TRUECOLOR0888
                                   1,
#else
                                   0,
#endif
};


/* Structure to hold the encoding type details */
volatile struct encoding_type_struct
{
    cyg_uint8 raw;
    cyg_uint8 copy_rectangle;
    cyg_uint8 rre;
    cyg_uint8 corre;
    cyg_uint8 hextile;
} encoding_type;


/*****************************************************************************/
/** System initializer
 *
 * This is called from the static constructor in init.cxx. It spawns
 * the main server thread and makes it ready to run.
 *
 *****************************************************************************/
__externC void cyg_vnc_server_startup(void)
{
#ifdef CYGPKG_NET
    /* BSD TCP/IP stack version */
    cyg_thread_create(CYGNUM_VNC_SERVER_PRIORITY,
                      client_handler,
                      0,
                      "ClientHandler",
                      (void *) client_handler_stack,
                      MAIN_STACK_SIZE,
                      &client_handler_hndl,
                      &thread_s[0]);

    cyg_thread_resume(client_handler_hndl);

#else
    /* lwIP TCP/IP stack version */
    cyg_thread_create(CYGNUM_VNC_SERVER_PRIORITY,
                      tMain,
                      0,
                      "lwIP_Startup",
                      (void *) lwip_startup_stack,
                      MIN_STACK_SIZE,
                      &lwip_startup_hndl,
                      &thread_s);

    cyg_thread_resume(lwip_startup_hndl);
#endif
}


#ifndef CYGPKG_NET
/* Startup thread for lwIP stack */
void tMain(cyg_addrword_t data)
{
    lwip_init();
    sys_thread_new(client_handler, (void *) 0, CYGNUM_VNC_SERVER_PRIORITY);
}
#endif


/*****************************************************************************/
/** Client Handler Thread.
 *
 *  @param  data     Ignored
 *
 *  This thread handles the client initialisation sequence.  Once the client
 *  is initialised this thread handles all received messages from the client,
 *  but does not send any data to the client.
 *
 *****************************************************************************/
#ifdef CYGPKG_NET
void client_handler(cyg_addrword_t data)
#else
static void client_handler(void *data)
#endif
{
    int server_sock;                /* Socket descriptor for server */
    struct sockaddr_in server_addr; /* Details of my IP address and port */
    struct sockaddr_in client_addr; /* Details of new connection IP address */
    int client_addr_size;

    int i, j;
    long int temp_long;
    char message_buffer[MESSAGE_BUFFER_SIZE];
    char protocol_ver[8];
    int message_len;
    int ProtocolOkay;
    cyg_uint32 *ptr_to_uint32;
    cyg_uint16 *ptr_to_uint16;

    if (CYGNUM_VNC_SERVER_DELAY)
    {
        cyg_thread_delay(CYGNUM_VNC_SERVER_DELAY);
    }

    /* Initialise mutex & cond vars */
    cyg_mutex_init(&client_active_lock);
    cyg_cond_init(&client_active_wait, &client_active_lock);
    update_req = 0;
    cyg_mutex_init(&SoundBell_lock);

    /* Create thread to handle frame_updates */
#ifdef CYGPKG_NET
    cyg_thread_create(CYGNUM_VNC_SERVER_PRIORITY,
                      frame_update,
                      0,
                      "FrameUpdate",
                      (void *) frame_update_stack,
                      MAIN_STACK_SIZE,
                      &frame_update_hndl,
                      &thread_s[1]);

    cyg_thread_resume(frame_update_hndl);
#else
    sys_thread_new(frame_update, (void *) 0, CYGNUM_VNC_SERVER_PRIORITY);
#endif

    /* 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;

    /* Clear the sound bell counter */
    SoundBellCount = 0;

#ifdef CYGPKG_NET
    /* Initialisation routine for BSD TCP/IP stack */
    init_all_network_interfaces();
#endif

    /* Create socket for incomming connections */
    if ((server_sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
    {
        diag_printf("socket() function failed\n");
        exit(1);
    }

    /* Construct the server address structure */
    memset(&server_addr, 0, sizeof(server_addr));  /* Fill entire structure with 0's */
    server_addr.sin_family      = AF_INET;         /* Internet address family */
    server_addr.sin_addr.s_addr = INADDR_ANY;      /* Autofill with my IP address */
    server_addr.sin_port        = htons(CYGNUM_VNC_SERVER_PORT);

    /* Bind socket to local address */
    if (bind(server_sock, (struct sockaddr *) &server_addr, sizeof(server_addr)) < 0)
    {
        diag_printf("bind() function failed");
        exit(1);
    }

    /* Set the socket to listen for incoming connections */
    if (listen(server_sock, BACKLOG) < 0)
    {
        diag_printf("listen() function failed");
        exit(1);
    }

    while(1)
    {

        /* Wait to accept a connection on this socket */
        client_addr_size = sizeof(client_addr);
        client_sock = (accept(server_sock, (struct sockaddr *) &client_addr, &client_addr_size));

        if(client_sock < 0)
        {
            diag_printf("accept() function failed");
            exit(1);
        }


        /*
          ProtocolVersion Handshake - begin
        */

        /* Send ProtocolVersion we want to use to client */
        message_len = diag_sprintf(message_buffer, "RFB 003.003\n");
        if (send(client_sock, message_buffer, message_len, 0) != message_len)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -