vnc-server.c
来自「eCos操作系统源码」· C语言 代码 · 共 1,754 行 · 第 1/4 页
C
1,754 行
//==========================================================================//// 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_NETcyg_thread_entry_t client_handler, frame_update;#elsecyg_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];#elsecyg_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_NETstatic char client_handler_stack[MAIN_STACK_SIZE];static char frame_update_stack[MAIN_STACK_SIZE];#elsestatic 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_NETvoid client_handler(cyg_addrword_t data)#elsestatic 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 + =
减小字号Ctrl + -
显示快捷键?