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

📄 vnc-server.c

📁 一个小的RTOS具有UIP网络功能
💻 C
字号:
/* * Copyright (c) 2001, Adam Dunkels. * All rights reserved.  * * Redistribution and use in source and binary forms, with or without  * modification, are permitted provided that the following conditions  * are met:  * 1. Redistributions of source code must retain the above copyright  *    notice, this list of conditions and the following disclaimer.  * 2. Redistributions in binary form must reproduce the above copyright  *    notice, this list of conditions and the following disclaimer in the  *    documentation and/or other materials provided with the distribution.  * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *      This product includes software developed by Adam Dunkels. * 4. The name of the author may not be used to endorse or promote *    products derived from this software without specific prior *    written permission.   * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.   * * This file is part of the uIP TCP/IP stack. * * $Id: vnc-server.c,v 1.2 2003/08/24 22:41:31 adamdunkels Exp $ * *//* A micro implementation of a VNC server. VNC is a protocol for   remote network displays. See http://www.uk.research.att.com/vnc/   for information about VNC.   Initialization states:   VNC_VERSION (send version string)   VNC_AUTH    (send auth message)   VNC_INIT    (send init message)   Steady state:      VNC_RUNNING (send RFB updates, parse incoming messages)   What kind of message should be sent:   SEND_NONE   (No message)   SEND_BLANK  (Blank screen initially)   SEND_SCREEN (Send entire screen, initially)   SEND_UPDATE (Send incremental update)*/#include "uip.h"#include "vnc-server.h"#include "vnc-out.h"/* RFB server initial handshaking string. */#define RFB_SERVER_VERSION_STRING rfb_server_version_string/* "RFB 003.003" */static u8_t rfb_server_version_string[12] = {82,70,66,32,48,48,51,46,48,48,51,10};/* uVNC */static u8_t uvnc_name[4] = {117,86,78,67};#if 1#define PRINTF(x)#else#define PRINTF(x) printf x#endif/*-----------------------------------------------------------------------------------*/u8_tvnc_server_draw_rect(u8_t *ptr, u16_t x, u16_t y, u16_t w, u16_t h, u8_t c){  struct rfb_fb_update_rect_hdr *recthdr;  struct rfb_rre_hdr *rrehdr;  recthdr = (struct rfb_fb_update_rect_hdr *)ptr;  rrehdr = (struct rfb_rre_hdr *)(ptr + sizeof(struct rfb_fb_update_rect_hdr));    recthdr->rect.x = x;  recthdr->rect.y = y;  recthdr->rect.w = w;  recthdr->rect.h = h;   recthdr->encoding[0] =    recthdr->encoding[1] =    recthdr->encoding[2] = 0;  recthdr->encoding[3] = RFB_ENC_RRE;        rrehdr->subrects[0] =    rrehdr->subrects[1] = 0;  rrehdr->bgpixel = c;        return sizeof(struct rfb_fb_update_rect_hdr) + sizeof(struct rfb_rre_hdr);}/*-----------------------------------------------------------------------------------*/voidvnc_server_init(void){  vnc_out_init();}/*-----------------------------------------------------------------------------------*/static voidvnc_send_blank(struct vnc_server_state *vs){  switch(vs->type) {  case 0:	    vnc_out_send_blank(vs);    break;    /*  case 1:    vnc_stats_send_blank(vs);    break;   */  }}/*-----------------------------------------------------------------------------------*/static voidvnc_send_screen(struct vnc_server_state *vs){  switch(vs->type) {  case 0:	    vnc_out_send_screen(vs);    break;    /*  case 1:    vnc_stats_send_screen(vs);    break;*/  }}/*-----------------------------------------------------------------------------------*/static voidvnc_send_update(struct vnc_server_state *vs){  switch(vs->type) {  case 0:	    vnc_out_send_update(vs);    break;    /*  case 1:    vnc_stats_send_update(vs);    break;*/  }}/*-----------------------------------------------------------------------------------*/voidvnc_server_send_data(struct vnc_server_state *vs){  struct rfb_server_init *initmsg;    switch(vs->state) {  case VNC_VERSION:    uip_send(RFB_SERVER_VERSION_STRING, sizeof(RFB_SERVER_VERSION_STRING));    break;  case VNC_AUTH:    uip_appdata[0] = 0;    uip_appdata[1] = 0;    uip_appdata[2] = 0;    uip_appdata[3] = RFB_AUTH_NONE;    uip_send(uip_appdata, 4);    break;  case VNC_INIT:    initmsg = (struct rfb_server_init *)uip_appdata;    initmsg->width = htons(vs->width);    initmsg->height = htons(vs->height);    /* BGR233 pixel format. */    initmsg->format.bps = 8;    initmsg->format.depth = 8;    initmsg->format.endian = 1;    initmsg->format.truecolor = 1;    initmsg->format.red_max = htons(7);    initmsg->format.green_max = htons(7);    initmsg->format.blue_max = htons(3);    initmsg->format.red_shift = 0;    initmsg->format.green_shift = 3;    initmsg->format.blue_shift = 6;    initmsg->namelength[0] = 0;    initmsg->namelength[1] = 0;    initmsg->namelength[2] = 0;	        initmsg->namelength[3] = 4;    bcopy(uvnc_name, &uip_appdata[sizeof(struct rfb_server_init)], 4);    /*    uip_appdata[sizeof(struct rfb_server_init)+0] = 'u';    uip_appdata[sizeof(struct rfb_server_init)+1] = 'V';    uip_appdata[sizeof(struct rfb_server_init)+2] = 'N';    uip_appdata[sizeof(struct rfb_server_init)+3] = 'C';*/    uip_send(uip_appdata, sizeof(struct rfb_server_init) + 4);    break;  case VNC_RUNNING:    switch(vs->sendmsg) {    case SEND_NONE:      PRINTF(("Sending none\n"));      break;          case SEND_BLANK:    case SENT_BLANK:      PRINTF(("Sending blank\n"));      vnc_send_blank(vs);      break;          case SEND_SCREEN:      PRINTF(("Sending screen\n"));      vnc_send_screen(vs);      break;    case SEND_UPDATE:      PRINTF(("Sending update\n"));      vnc_send_update(vs);      break;    }    break;      default:    break;  }}/*-----------------------------------------------------------------------------------*/static voidvnc_key_event(struct vnc_server_state *vs){  switch(vs->type) {  case 0:	    vnc_out_key_event(vs);    break;    /*  case 1:    vnc_stats_key_event(vs);    break;*/  }}/*-----------------------------------------------------------------------------------*/static voidvnc_pointer_event(struct vnc_server_state *vs){  switch(vs->type) {  case 0:	    vnc_out_pointer_event(vs);    break;    /*  case 1:    vnc_stats_pointer_event(vs);    break;*/  }}/*-----------------------------------------------------------------------------------*/static u8_tvnc_read_data(struct vnc_server_state *vs){  u8_t *appdata;  u16_t len;  struct rfb_fb_update_request *req;  /*  u8_t niter;*/    len = uip_datalen();  appdata = (u8_t *)uip_appdata;    /* First, check if there is data left to discard since last read. */  if(vs->readlen > 0) {    appdata += vs->readlen;    if(len > vs->readlen) {      len -= vs->readlen;      vs->readlen = 0;    } else {      vs->readlen -= len;      len = 0;    }  }  if(vs->readlen != 0) {    return 1;  }  /* All data read and ignored, parse next message. */  /*  for(niter = 32; niter > 0 && len > 0; --niter) {*/  while(len > 0) {    switch(vs->state) {    case VNC_VERSION:    case VNC_VERSION2:      PRINTF(("Read in version\n"));      /* Receive and ignore client version string (12 bytes). */      vs->state = VNC_AUTH;      vs->readlen = 12;      break;          case VNC_AUTH:    case VNC_AUTH2:      PRINTF(("Read in auth \n"));      /* Read and discard initialization from client (1 byte). */      vs->readlen = 1;      vs->state = VNC_INIT;      break;          case VNC_INIT:    case VNC_INIT2:      PRINTF(("Read in init \n"));      vs->readlen = 0;      vs->state = VNC_RUNNING;          case VNC_RUNNING:      /* Handle all client events. */      switch(*appdata) {      case RFB_SET_PIXEL_FORMAT:	PRINTF(("Set pixel format\n"));	vs->readlen = sizeof(struct rfb_set_pixel_format);	/* Check if client runs with BGR233 format. If not, abort the	   connection. */	/* XXX: not implemented yet. */	break;	      case RFB_FIX_COLORMAP_ENTRIES:	PRINTF(("Fix colormap entries\n"));	return 0;	      case RFB_SET_ENCODINGS:	PRINTF(("Set encodings\n"));	vs->readlen = sizeof(struct rfb_set_encoding);	vs->readlen += htons(((struct rfb_set_encoding *)appdata)->encodings) * 4;	/* Make sure that client supports the encodings we use. */	/* XXX: not implemented yet. */	break;	      case RFB_FB_UPDATE_REQ:	PRINTF(("Update request\n"));	vs->update_requested = 1;	vs->readlen = sizeof(struct rfb_fb_update_request);	/* blank the screen initially */	req = (struct rfb_fb_update_request *)appdata;	if(req->incremental == 0) {	  /*	  vs->sendmsg = SEND_BLANK;*/	  vnc_out_update_area(vs, 0, 0, vs->w, vs->h);	}	break;	      case RFB_KEY_EVENT:	vs->readlen = sizeof(struct rfb_key_event);	vnc_key_event(vs);	break;	      case RFB_POINTER_EVENT:	vs->readlen = sizeof(struct rfb_pointer_event);	vnc_pointer_event(vs);	break;	      case RFB_CLIENT_CUT_TEXT:	PRINTF(("Client cut text\n"));	if(((struct rfb_client_cut_text *)appdata)->len[0] != 0 ||	   ((struct rfb_client_cut_text *)appdata)->len[1] != 0) {	  return 0;	  	}	vs->readlen = sizeof(struct rfb_client_cut_text) +	  (((struct rfb_client_cut_text *)appdata)->len[2] << 8) +	  ((struct rfb_client_cut_text *)appdata)->len[3];	/*	return 0;*/	break;	      default:	PRINTF(("Unknown message %d\n", *appdata));	return 0;      }      break;          default:      return 0;    }    if(vs->readlen > 0) {      if(len > vs->readlen) {	len -= vs->readlen;	appdata += vs->readlen;	vs->readlen = 0;      } else {	vs->readlen -= len;	len = 0;      }    } else {      /* Lost data. */      break;    }      }  /*  if(vs->readlen > 0) {    printf("More data %d\n", vs->readlen);    }*/    /*  uip_appdata = appdata;*/  return 1;}/*-----------------------------------------------------------------------------------*/static voidvnc_new(struct vnc_server_state *vs){  vs->counter = 0;  vs->readlen = 0;  vs->sendmsg = SEND_NONE;  vs->update_requested = 1;  switch(vs->type) {  case 0:	    vnc_out_new(vs);    break;    /*  case 1:    vnc_stats_new(vs);    break;*/  }}/*-----------------------------------------------------------------------------------*/static voidvnc_acked(struct vnc_server_state *vs){  switch(vs->state) {  case VNC_VERSION:    vs->state = VNC_VERSION2;    break;      case VNC_AUTH:    vs->state = VNC_AUTH2;    break;      case VNC_INIT:    vs->state = VNC_INIT2;    break;  case VNC_RUNNING:    switch(vs->type) {    case 0:	      vnc_out_acked(vs);      break;      /*    case 1:      vnc_stats_acked(vs);      break;*/    }    break;  }}/*-----------------------------------------------------------------------------------*/voidvnc_server_appcall(struct vnc_server_state *vs){    vs->type = htons(uip_conn->lport) - 5900;    if(uip_connected()) {          vnc_new(vs);    vs->state = VNC_VERSION;    vnc_server_send_data(vs);    return;  }  if(uip_acked()) {    PRINTF(("Acked\n"));    vnc_acked(vs);  }    if(uip_newdata()) {    PRINTF(("Newdata\n"));    vs->counter = 0;    if(vnc_read_data(vs) == 0) {      uip_abort();      return;    }  }    if(uip_rexmit()) {    PRINTF(("Rexmit\n"));  }      if(uip_newdata() ||     uip_rexmit() ||     uip_acked()) {    vnc_server_send_data(vs);  } else if(uip_poll()) {    ++vs->counter;    /* Abort connection after about 20 seconds of inactivity. */    if(vs->counter >= 40) {      uip_abort();      return;    }        vnc_out_poll(vs);  }  }/*-----------------------------------------------------------------------------------*/

⌨️ 快捷键说明

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