Index: net/vnc_server/current/ChangeLog =================================================================== RCS file: /cvs/ecos/ecos-opt/net/net/vnc_server/current/ChangeLog,v retrieving revision 1.1 diff -u -5 -b -p -r1.1 ChangeLog --- net/vnc_server/current/ChangeLog 27 Aug 2003 18:46:05 -0000 1.1 +++ net/vnc_server/current/ChangeLog 31 Aug 2003 14:11:01 -0000 @@ -1,5 +1,21 @@ +2003-08-31 Chris Garry + + * src/vnc-server.c: + Always send colour data to client in big endian format. + When doing frame updates, do not call send command until there + if 1460 bytes of data unless the data is all that is left for the + cuurent frame update (huge improvement with lwIP stack). + Fixed bug where VncPrintf() did not handle characters not defined + for the selected font. + VncPrintf() does not mark tiles for update when do_print argument + is not set. + + * tests/vnc-test.c: + Modifed the test to use select() function. Added more examples + of using the VNC server API. + 2003-08-22 Chris Garry * tests/vnc-test.c: * src/fonts/winFreeSystem14x16.c: Index: net/vnc_server/current/src/vnc-server.c =================================================================== RCS file: /cvs/ecos/ecos-opt/net/net/vnc_server/current/src/vnc-server.c,v retrieving revision 1.1 diff -u -5 -b -p -r1.1 vnc-server.c --- net/vnc_server/current/src/vnc-server.c 27 Aug 2003 18:46:05 -0000 1.1 +++ net/vnc_server/current/src/vnc-server.c 31 Aug 2003 14:11:09 -0000 @@ -50,11 +50,10 @@ // //========================================================================*/ #include /* CYGNUM_HAL_STACK_SIZE_MINIMUM & CYGNUM_HAL_STACK_SIZE_TYPICAL */ -#include /* CYG_BYTEORDER */ #include #include /* diag_printf */ #include #include #include @@ -79,10 +78,11 @@ void lwip_init(void); #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 */ @@ -123,24 +123,13 @@ void lwip_init(void); #define FRAME_BUFFER_UPDATE_REQ 3 #define KEY_EVENT 4 #define POINTER_EVENT 5 #define CLIENT_CUT_TEXT 6 -#if CYG_BYTEORDER == CYG_MSBFIRST -#define REQUESTED_BIG_ENDIAN_FLAG 1 /* We are big endian */ -#else -#define REQUESTED_BIG_ENDIAN_FLAG 0 /* We are little endian */ -#endif - -/* Give these variables initial values - they may be set again */ -/* after a SetPixelFormat message from the client */ -volatile int clr_byte0_shift = 0; -volatile int clr_byte1_shift = 8; - -/* Macro to split colour to bytes depending on required endian and so on */ -#define COLOUR2BYTE0(col) ((col>>clr_byte0_shift)&0xFF) -#define COLOUR2BYTE1(col) ((col>>clr_byte1_shift)&0xFF) +/* 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 *); @@ -412,10 +401,11 @@ static void client_handler(void *data) { diag_printf("accept() function failed"); exit(1); } + /* ProtocolVersion Handshake - begin */ /* Send ProtocolVersion we want to use to client */ @@ -522,11 +512,11 @@ static void client_handler(void *data) 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)REQUESTED_BIG_ENDIAN_FLAG; + 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); @@ -655,24 +645,10 @@ static void client_handler(void *data) 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; } - if ( (message_buffer[6] && !REQUESTED_BIG_ENDIAN_FLAG) - || (!message_buffer[6] && REQUESTED_BIG_ENDIAN_FLAG) ) - { - /* Colour values are stored in a different endianess */ - clr_byte0_shift = 8; - clr_byte1_shift = 0; - } - else - { - /* Colour values are stored in the same endianess */ - clr_byte0_shift = 0; - clr_byte1_shift = 8; - } - break; case FIX_COLOUR_MAP_ENTRIES: /* Not supported, just get the data from the buffer and ignore it */ @@ -896,11 +872,12 @@ static void frame_update(void *data) int num_updated_tiles; cyg_uint16 *ptr_to_uint16; static long rtc_resolution[] = CYGNUM_KERNEL_COUNTERS_RTC_RESOLUTION; /* These are declared static so they don't use thread stack memory */ - static cyg_uint8 FramebufferUpdate_msg[4 + 12 + TILE_SIZE*TILE_SIZE*BITS_PER_PIXEL/8]; + static cyg_uint8 FramebufferUpdate_msg[4 + 12 + TILE_SIZE*TILE_SIZE*BITS_PER_PIXEL/8 + 1460]; + static int FrameBufferPtr; /* Pointer to next space in buffer */ static int tile_updated_local[NUM_TILES_Y_AXIS][NUM_TILES_X_AXIS]; while(1) { /* Wait until client sends a frame update request */ @@ -936,16 +913,11 @@ static void frame_update(void *data) /* Fill in constant parts of FramebufferUpdate Message */ FramebufferUpdate_msg[0] = 0; /* Message-type */ FramebufferUpdate_msg[1] = 0; /* Padding */ ptr_to_uint16 = (cyg_uint16 *) &(FramebufferUpdate_msg[2]); *ptr_to_uint16 = htons(num_updated_tiles); /* Number-of-rectangles */ - - /* Send the first 4 bytes of the frame update message to the client */ - if (send(client_sock, FramebufferUpdate_msg, 4, 0) != 4) - { - goto wait_for_client; - } + FrameBufferPtr = 4; for (y_pos = 0; y_pos < NUM_TILES_Y_AXIS; y_pos++) { for (x_pos = 0; x_pos < NUM_TILES_X_AXIS; x_pos++) { @@ -957,51 +929,78 @@ static void frame_update(void *data) update_req = 0; /* Cancel the update request flag */ cyg_mutex_unlock(&client_active_lock); /* Unlock the mutex */ } /* Send current square data to client */ - ptr_to_uint16 = (cyg_uint16 *) &(FramebufferUpdate_msg[4-4]); - *ptr_to_uint16 = htons(x_pos * TILE_SIZE); /* x-position */ - ptr_to_uint16 = (cyg_uint16 *) &(FramebufferUpdate_msg[6-4]); - *ptr_to_uint16 = htons(y_pos * TILE_SIZE); /* y-position */ + + /* x-position */ + FramebufferUpdate_msg[FrameBufferPtr+0] = (x_pos * TILE_SIZE) / 256; + FramebufferUpdate_msg[FrameBufferPtr+1] = (x_pos * TILE_SIZE) % 256; + + /* y-position */ + FramebufferUpdate_msg[FrameBufferPtr+2] = (y_pos * TILE_SIZE) / 256; + FramebufferUpdate_msg[FrameBufferPtr+3] = (y_pos * TILE_SIZE) % 256; + /* Set width of tile in packet */ - ptr_to_uint16 = (cyg_uint16 *) &(FramebufferUpdate_msg[8-4]); if (x_pos == (NUM_TILES_X_AXIS -1)) { /* Last tile in X-axis */ - *ptr_to_uint16 = htons(LAST_TILE_WIDTH); /* Width */ + FramebufferUpdate_msg[FrameBufferPtr+4] = LAST_TILE_WIDTH / 256; + FramebufferUpdate_msg[FrameBufferPtr+5] = LAST_TILE_WIDTH % 256; } else { - *ptr_to_uint16 = htons(TILE_SIZE); /* Width */ + FramebufferUpdate_msg[FrameBufferPtr+4] = TILE_SIZE / 256; + FramebufferUpdate_msg[FrameBufferPtr+5] = TILE_SIZE % 256; } - ptr_to_uint16 = (cyg_uint16 *) &(FramebufferUpdate_msg[10-4]); if (y_pos == (NUM_TILES_Y_AXIS -1)) { /* Last tile in Y-axis */ - *ptr_to_uint16 = htons(LAST_TILE_HEIGHT); /* Height */ + FramebufferUpdate_msg[FrameBufferPtr+6] = LAST_TILE_HEIGHT / 256; + FramebufferUpdate_msg[FrameBufferPtr+7] = LAST_TILE_HEIGHT % 256; } else { - *ptr_to_uint16 = htons(TILE_SIZE); /* Height */ + FramebufferUpdate_msg[FrameBufferPtr+6] = TILE_SIZE / 256; + FramebufferUpdate_msg[FrameBufferPtr+7] = TILE_SIZE % 256; } /* Generate the packet data for this tile */ - packet_length = GenTileUpdateData(FramebufferUpdate_msg); + packet_length = GenTileUpdateData(&(FramebufferUpdate_msg[FrameBufferPtr])); /* Send the packet data for this tile to the client */ - if (send(client_sock, FramebufferUpdate_msg, packet_length, 0) != packet_length) + FrameBufferPtr += packet_length; + + if (FrameBufferPtr > 1460) + { + /* Send the data to the client */ + if (send(client_sock, FramebufferUpdate_msg, FrameBufferPtr, 0) != FrameBufferPtr) { goto wait_for_client; } + FrameBufferPtr = 0; + } + tile_updated_local[y_pos][x_pos] = 0; /* Clear the update bit for this square */ } } } + + if (FrameBufferPtr > 0) + { + /* Last data for this update, send it to the client */ + if (send(client_sock, FramebufferUpdate_msg, FrameBufferPtr, 0) != FrameBufferPtr) + { + goto wait_for_client; + } + + FrameBufferPtr = 0; + } + } else /* if (num_updated_tiles) */ { /* There was no new display data to send to the client */ /* Sleep for 1/20th second before checking again */ @@ -1052,12 +1051,10 @@ static void frame_update(void *data) * than CoRRE encoding for that particular tile. * *****************************************************************************/ static int GenTileUpdateData(cyg_uint8 *packet_buffer) { - cyg_uint16 *ptr_to_uint16; - cyg_uint32 *ptr_to_uint32; cyg_uint16 x_pos, y_pos; int i, j; int packet_length; int tile_width, tile_height; @@ -1067,37 +1064,35 @@ static int GenTileUpdateData(cyg_uint8 * vnc_colour_t bg_colour; int no_of_subrects, subrect_width, subrect_height; int k, l; no_of_subrects = 0; /* Set to no sub-rectangles to start with */ -#endif //CYGNUM_VNC_SERVER_USE_CORRE_ENCODING +#endif /* CYGNUM_VNC_SERVER_USE_CORRE_ENCODING */ packet_length = 20-4+(BITS_PER_PIXEL/8); /* Set to minimum packet length to start with */ /* Get the X and Y positions of this tile from the packet buffer */ - ptr_to_uint16 = (cyg_uint16 *) &(packet_buffer[4-4]); - x_pos = htons(*ptr_to_uint16); - ptr_to_uint16 = (cyg_uint16 *) &(packet_buffer[6-4]); - y_pos = htons(*ptr_to_uint16); + x_pos = packet_buffer[0] * 256 + packet_buffer[1]; + y_pos = packet_buffer[2] * 256 + packet_buffer[3]; /* Get the tile width and height from the packet buffer */ - ptr_to_uint16 = (cyg_uint16 *) &(packet_buffer[8-4]); - tile_width = htons(*ptr_to_uint16); - ptr_to_uint16 = (cyg_uint16 *) &(packet_buffer[10-4]); - tile_height = htons(*ptr_to_uint16); + tile_width = packet_buffer[4] * 256 + packet_buffer[5]; + tile_height = packet_buffer[6] * 256 + packet_buffer[7]; #ifdef CYGNUM_VNC_SERVER_USE_CORRE_ENCODING /* Set the encoding type to RRE */ if (!encoding_type.corre) { /* CoRRE encoding is not supported - just use raw encoding */ goto use_raw_encoding; } /* Set encoding type to CoRRE encoding in packet buffer */ - ptr_to_uint32 = (cyg_uint32 *) &(packet_buffer[12-4]); - *ptr_to_uint32 = htonl(4); /* Encoding-type = CoRRE encoding */ + packet_buffer[8+0] = 0; + packet_buffer[8+1] = 0; + packet_buffer[8+2] = 0; + packet_buffer[8+3] = 4; /* Copy tile from the main frame buffer to the local tile buffer */ for (i = 0; i < tile_height; i++) { for (j = 0; j < tile_width; j++) @@ -1111,27 +1106,27 @@ static int GenTileUpdateData(cyg_uint8 * /* Its quick!!! */ bg_colour = frame_buffer[y_pos][x_pos]; /* Set the background colour in the packet buffer */ #if BITS_PER_PIXEL == 8 - packet_buffer[20-4] = (vnc_colour_t) bg_colour; + packet_buffer[16] = (vnc_colour_t) bg_colour; #endif #if BITS_PER_PIXEL == 16 - packet_buffer[20-4] = COLOUR2BYTE0(bg_colour); - packet_buffer[20-4+1] = COLOUR2BYTE1(bg_colour); + packet_buffer[16] = COLOUR2BYTE0(bg_colour); + packet_buffer[16+1] = COLOUR2BYTE1(bg_colour); #endif #ifdef CYGNUM_VNC_SERVER_CORRE_ENCODING_HACK /* Add an initial sub-rectangle to paint the background the background colour */ /* This is required because of a known bug in the VNC viewer (x86 version) */ #if BITS_PER_PIXEL == 8 packet_buffer[packet_length] = (vnc_colour_t) bg_colour; packet_length++; #endif #if BITS_PER_PIXEL == 16 - packet_buffer[packet_length] = packet_buffer[20-4]; - packet_buffer[packet_length+1] = packet_buffer[20-4+1]; + packet_buffer[packet_length] = packet_buffer[16]; + packet_buffer[packet_length+1] = packet_buffer[16+1]; packet_length += 2; #endif packet_buffer[packet_length] = (cyg_uint8) 0; /* Sub-rect x-pos */ packet_buffer[packet_length+1] = (cyg_uint8) 0; /* Sub-rect y-pos*/ packet_buffer[packet_length+2] = (cyg_uint8) tile_width; /* Sub-rect width*/ @@ -1208,50 +1203,54 @@ static int GenTileUpdateData(cyg_uint8 * packet_buffer[packet_length] = (cyg_uint8) subrect_height; /* Sub-rect height*/ packet_length++; no_of_subrects++; /* Increment sub-rectangle count */ - if (packet_length >= 16-4 + tile_height*tile_width*(BITS_PER_PIXEL/8) - 6) + if (packet_length >= 12 + tile_height*tile_width*(BITS_PER_PIXEL/8) - 6) { /* The next sub-rectangle will make the packet size */ /* larger than a rew encoded packet - so just use raw */ goto use_raw_encoding; } } } } /* Fill in no_of_sub-rectangles field in packet buffer */ - ptr_to_uint32 = (cyg_uint32 *) &(packet_buffer[16-4]); - *ptr_to_uint32 = htonl(no_of_subrects); + packet_buffer[12+0] = 0; + packet_buffer[12+1] = 0; + packet_buffer[12+2] = no_of_subrects / 256; + packet_buffer[12+3] = no_of_subrects % 256; /* CoRRE data encoding for tile complete */ return packet_length; use_raw_encoding: -#endif //CYGNUM_VNC_SERVER_USE_CORRE_ENCODING +#endif /* CYGNUM_VNC_SERVER_USE_CORRE_ENCODING */ /* Create packet data using RAW encoding */ for (i = 0; i < tile_height; i++) { for (j = 0; j < tile_width; j++) { #if BITS_PER_PIXEL == 8 - packet_buffer[16-4 + tile_width * i + j] = frame_buffer[y_pos + i][x_pos + j]; + packet_buffer[12 + tile_width * i + j] = frame_buffer[y_pos + i][x_pos + j]; #endif #if BITS_PER_PIXEL == 16 - packet_buffer[16-4 + 2 * tile_width * i + 2*j] = COLOUR2BYTE0(frame_buffer[y_pos + i][x_pos + j]); - packet_buffer[16-4 + 2 * tile_width * i + 2*j+ 1] = COLOUR2BYTE1(frame_buffer[y_pos + i][x_pos + j]); + packet_buffer[12 + 2 * tile_width * i + 2*j] = COLOUR2BYTE0(frame_buffer[y_pos + i][x_pos + j]); + packet_buffer[12 + 2 * tile_width * i + 2*j+ 1] = COLOUR2BYTE1(frame_buffer[y_pos + i][x_pos + j]); #endif } } /* Set the encoding type to raw */ - ptr_to_uint32 = (cyg_uint32 *) &(packet_buffer[12-4]); - *ptr_to_uint32 = htonl(0); /* Encoding-type = raw */ + packet_buffer[8+0] = 0; + packet_buffer[8+1] = 0; + packet_buffer[8+2] = 0; + packet_buffer[8+3] = 0; - return (16-4 + tile_width*tile_height*(BITS_PER_PIXEL/8)); + return (12 + tile_width*tile_height*(BITS_PER_PIXEL/8)); } /*****************************************************************************/ /** Get message data function @@ -1599,10 +1598,17 @@ vnc_printf_return_t VncPrintf(MWCFONT* f y_pos += sel_font->height; char_pos++; continue; } + /* Check for characters not if the font - set to first char */ + if (buf[char_pos] < sel_font->firstchar) + { + buf[char_pos] = sel_font->firstchar; + } + + char_offset = ((cyg_uint8) buf[char_pos]) - sel_font->firstchar; /* Get the character width */ if (sel_font->width != 0) { @@ -1657,15 +1663,18 @@ vnc_printf_return_t VncPrintf(MWCFONT* f char_pos++; } /* Mark the required tiles for update */ + if (do_print) + { for (i = y/TILE_SIZE; i <= (y_max + sel_font->height)/TILE_SIZE; i++) { for (j = x/TILE_SIZE; j <= x_max/TILE_SIZE; j++) { tile_updated[i][j] = 1; + } } } ret_vals.width = x_max - x; ret_vals.height = y_max + sel_font->height - y; Index: net/vnc_server/current/tests/vnc-test.c =================================================================== RCS file: /cvs/ecos/ecos-opt/net/net/vnc_server/current/tests/vnc-test.c,v retrieving revision 1.1 diff -u -5 -b -p -r1.1 vnc-test.c --- net/vnc_server/current/tests/vnc-test.c 27 Aug 2003 18:46:06 -0000 1.1 +++ net/vnc_server/current/tests/vnc-test.c 31 Aug 2003 14:11:10 -0000 @@ -19,133 +19,219 @@ //========================================================================== #include #include /* Kernel API */ -#include /* Required for diag_printf */ +#include /* diag_printf() */ #include /* Cyg_ErrNo, ENOENT */ #include /* cyg_io_handle_t */ +#include /* select() functions */ +#include /* open() */ +#include /* read() */ +#include /* rand() */ int main() { - Cyg_ErrNo mouse_err, kbd_err; - cyg_io_handle_t mouse_handle, kbd_handle; + int mouse_handle = -1; + int kbd_handle = -1; cyg_uint8 mouse_data[8], kbd_data[4]; cyg_uint8 last_mouse_button = 0; cyg_uint32 mouse_len = 0; cyg_uint32 kbd_len = 0; vnc_printf_return_t print_area; cyg_uint16 text_y_pos; + int i, j; + cyg_uint16 bell_text_x_pos, bell_text_y_pos; /* Bell message text position */ + cyg_uint16 bell_text_width, bell_text_height; /* Bell text message size */ + + fd_set sock_desc; /* Set of descriptors for select */ + int max_handle; + + vnc_frame_format_t *display_info; + + int bell_text_state = 0; + char bell_message[] = "***** Click on a yellow pixel to sound the bell *****"; + + /* Get information about the display */ + display_info = VncGetInfo(); + + /* Initialise the VNC server display */ VncInit(VNC_WHITE); - mouse_err = cyg_io_lookup("/dev/vnc_mouse", &mouse_handle); /* Open mouse device */ - if (mouse_err == -ENOENT) + /* Open the mouse device */ + mouse_handle = open("/dev/vnc_mouse", O_RDONLY | O_NONBLOCK); + if (mouse_handle < 0) { - diag_printf("Could not open mouse device\n"); + diag_printf("Could not open mouse device: /dev/vnc_mouse\n"); } - kbd_err = cyg_io_lookup("/dev/vnc_kbd", &kbd_handle); /* Open keyboard device */ - if (kbd_err == -ENOENT) + /* Open the keyboard device */ + kbd_handle = open("/dev/vnc_kbd", O_RDONLY | O_NONBLOCK); + if (kbd_handle < 0) + { + diag_printf("Could not open kbd device: /dev/vnc_kbd\n"); + } + + /* Draw and label 16 rectangles using the 16 defined colours */ + VncFillRect(0, 0, 75, 50, VNC_BLACK); + VncPrintf(&font_helvR10, 1, VNC_WHITE, 1, 1, "BLACK"); + VncFillRect(75, 0, 150, 50, VNC_BLUE); + VncPrintf(&font_helvR10, 1, VNC_WHITE, 76, 1, "BLUE"); + VncFillRect(150, 0, 225, 50, VNC_GREEN); + VncPrintf(&font_helvR10, 1, VNC_WHITE, 151, 1, "GREEN"); + VncFillRect(225, 0, 300, 50, VNC_CYAN); + VncPrintf(&font_helvR10, 1, VNC_WHITE, 226, 1, "CYAN"); + + VncFillRect(0, 50, 75, 100, VNC_RED); + VncPrintf(&font_helvR10, 1, VNC_WHITE, 1, 51, "RED"); + VncFillRect(75, 50, 150, 100, VNC_MAGENTA); + VncPrintf(&font_helvR10, 1, VNC_WHITE, 76, 51, "MAGENTA"); + VncFillRect(150, 50, 225, 100, VNC_BROWN); + VncPrintf(&font_helvR10, 1, VNC_WHITE, 151, 51, "BROWN"); + VncFillRect(225, 50, 300, 100, VNC_GRAY); + VncPrintf(&font_helvR10, 1, VNC_WHITE, 226, 51, "GRAY"); + + VncFillRect(0, 100, 75, 150, VNC_LTGRAY); + VncPrintf(&font_helvR10, 1, VNC_BLACK, 1, 101, "LTGRAY"); + VncFillRect(75, 100, 150, 150, VNC_LTBLUE); + VncPrintf(&font_helvR10, 1, VNC_BLACK, 76, 101, "LTBLUE"); + VncFillRect(150, 100, 225, 150, VNC_LTGREEN); + VncPrintf(&font_helvR10, 1, VNC_BLACK, 151, 101, "LTGREEN"); + VncFillRect(225, 100, 300, 150, VNC_LTCYAN); + VncPrintf(&font_helvR10, 1, VNC_BLACK, 226, 101, "LTCYAN"); + + VncFillRect(0, 150, 75, 200, VNC_LTRED); + VncPrintf(&font_helvR10, 1, VNC_BLACK, 1, 151, "LTRED"); + VncFillRect(75, 150, 150, 200, VNC_LTMAGENTA); + VncPrintf(&font_helvR10, 1, VNC_BLACK, 76, 151, "LTMAGENTA"); + VncFillRect(150, 150, 225, 200, VNC_YELLOW); + VncPrintf(&font_helvR10, 1, VNC_BLACK, 151, 151, "YELLOW"); + VncFillRect(225, 150, 300, 200, VNC_WHITE); + VncPrintf(&font_helvR10, 1, VNC_BLACK, 226, 151, "WHITE"); + + /* Fade from black to while */ + for (i = 0; i < 256; i++) { - diag_printf("Could not open kbd device\n"); + VncDrawVertLine(i, 215, 265, VNC_RGB2COL(i, i, i)); } - VncFillRect(0, 0, 50, 50, VNC_BLACK); - VncFillRect(50, 0, 100, 50, VNC_BLUE); - VncFillRect(100, 0, 150, 50, VNC_GREEN); - VncFillRect(150, 0, 200, 50, VNC_CYAN); + VncPrintf(&font_helvR10, 1, VNC_WHITE, 1, 216, "GRAYSCALE"); - VncFillRect(0, 50, 50, 100, VNC_RED); - VncFillRect(50, 50, 100, 100, VNC_MAGENTA); - VncFillRect(100, 50, 150, 100, VNC_BROWN); - VncFillRect(150, 50, 200, 100, VNC_GRAY); + /* Draw a strip with random coloured pixels */ + for (i = 0; i < 256; i++) + { + for (j = 280; j < 330; j++) + { + VncDrawPixel( i, j, VNC_RGB2COL(rand()%256 , rand()%256, rand()%256) ); + } + } - VncFillRect(0, 100, 50, 150, VNC_LTGRAY); - VncFillRect(50, 100, 100, 150, VNC_LTBLUE); - VncFillRect(100, 100, 150, 150, VNC_LTGREEN); - VncFillRect(150, 100, 200, 150, VNC_LTCYAN); + /* Write a title for the bar of random colours */ + print_area = VncPrintf(&font_helvR10, 0, VNC_BLACK, 1, 281, "RANDOM"); + VncFillRect(1, 281, 1+print_area.width , 281+print_area.height, VNC_LTGRAY); + VncPrintf(&font_helvR10, 1, VNC_BLACK, 1, 281, "RANDOM"); - VncFillRect(0, 150, 50, 200, VNC_LTRED); - VncFillRect(50, 150, 100, 200, VNC_LTMAGENTA); - VncFillRect(100, 150, 150, 200, VNC_YELLOW); - VncFillRect(150, 150, 200, 200, VNC_WHITE); + /* Report the pixel format */ + if (display_info->rgb332) + { + VncPrintf(0, 1, VNC_BLACK, 1, 345, "Pixel format: RGB332"); + } + + if (display_info->rgb555) + { + VncPrintf(0, 1, VNC_BLACK, 1, 345, "Pixel format: RGB555"); + } - text_y_pos = 0; - print_area = VncPrintf(&font_rom8x8, 1, VNC_BLACK, 250, text_y_pos, "Hello World!\nUsing rom8x8 font"); + if (display_info->rgb565) + { + VncPrintf(0, 1, VNC_BLACK, 1, 345, "Pixel format: RGB565"); + } + + + /* Write text messages using each of the available fonts */ + text_y_pos = 5; + print_area = VncPrintf(&font_rom8x8, 1, VNC_BLACK, 350, text_y_pos, "Hello World!\nUsing rom8x8 font"); text_y_pos += (print_area.height * 1.5); - print_area = VncPrintf(&font_rom8x16, 1, VNC_BLUE, 250, text_y_pos, "Hello World!\nUsing rom8x16 font"); + print_area = VncPrintf(&font_rom8x16, 1, VNC_BLUE, 350, text_y_pos, "Hello World!\nUsing rom8x16 font"); text_y_pos += (print_area.height * 1.5); - print_area = VncPrintf(&font_winFreeSansSerif11x13, 1, VNC_CYAN, 250, text_y_pos, "Hello World!\nUsing winFreeSansSerif11x13 font"); + print_area = VncPrintf(&font_winFreeSansSerif11x13, 1, VNC_CYAN, 350, text_y_pos, "Hello World!\nUsing winFreeSansSerif11x13 font"); text_y_pos += (print_area.height * 1.5); - print_area = VncPrintf(0, 1, VNC_RED, 250, text_y_pos, "Hello World!\nUsing default (winFreeSystem14x16) font"); + print_area = VncPrintf(0, 1, VNC_RED, 350, text_y_pos, "Hello World!\nUsing default (winFreeSystem14x16) font"); text_y_pos += (print_area.height * 1.5); - print_area = VncPrintf(&font_helvB10, 1, VNC_MAGENTA, 250, text_y_pos, "Hello World!\nUsing helvB10 font"); + print_area = VncPrintf(&font_helvB10, 1, VNC_MAGENTA, 350, text_y_pos, "Hello World!\nUsing helvB10 font"); text_y_pos += (print_area.height * 1.5); - print_area = VncPrintf(&font_helvB12, 1, VNC_BROWN, 250, text_y_pos, "Hello World!\nUsing helvB12 font"); + print_area = VncPrintf(&font_helvB12, 1, VNC_BROWN, 350, text_y_pos, "Hello World!\nUsing helvB12 font"); text_y_pos += (print_area.height * 1.5); - print_area = VncPrintf(&font_helvR10, 1, VNC_GREEN, 250, text_y_pos, "Hello World!\nUsing helvR10 font"); + print_area = VncPrintf(&font_helvR10, 1, VNC_GREEN, 350, text_y_pos, "Hello World!\nUsing helvR10 font"); text_y_pos += (print_area.height * 1.5); - print_area = VncPrintf(&font_X5x7, 1, VNC_BLACK, 250, text_y_pos, "Hello World!\nUsing X5x7 font"); + print_area = VncPrintf(&font_X5x7, 1, VNC_BLACK, 350, text_y_pos, "Hello World!\nUsing X5x7 font"); text_y_pos += (print_area.height * 1.5); - print_area = VncPrintf(&font_X6x13, 1, VNC_LTRED, 250, text_y_pos, "Hello World!\nUsing X6x13 font"); + print_area = VncPrintf(&font_X6x13, 1, VNC_LTRED, 350, text_y_pos, "Hello World!\nUsing X6x13 font"); + /* Write the message about ringing the bell */ /* Get the details of the area the text will occupy */ - print_area = VncPrintf(0, 0, VNC_BLACK, 150, 400, "Click on a yellow pixel to sound the bell!!\n"); - /* Draw a background for the text */ - VncFillRect(150, 400, 150 + print_area.width, 400 + print_area.height, VNC_BLUE); + print_area = VncPrintf(0, 0, VNC_BLACK, 0, 0, "%s", bell_message); + bell_text_width = print_area.width; + bell_text_height = print_area.height; + + /* Calculate x position to center the bell text */ + bell_text_x_pos = (display_info->frame_width - bell_text_width) / 2; + + bell_text_y_pos = 400; /* y position always the same */ + + /* Draw a background for the bell text */ + VncFillRect(bell_text_x_pos, /* x1 */ + bell_text_y_pos, /* y1 */ + bell_text_x_pos + bell_text_width, /* x2 */ + bell_text_y_pos + bell_text_height, /* y2 */ + VNC_BLUE); /* Colour */ /* Write the text on the background */ - print_area = VncPrintf(0, 1, VNC_YELLOW, 150, 400, "Click on a yellow pixel to sound the bell!!\n"); + VncPrintf(0, 1, VNC_YELLOW, bell_text_x_pos, bell_text_y_pos, "%s", bell_message); + /* Initialse the max handle variable */ + max_handle = -1; + if (kbd_handle > max_handle) + { + max_handle = kbd_handle; + } + + if (mouse_handle > max_handle) + { + max_handle = mouse_handle; + } - diag_printf("mouse_handle: %d\n", mouse_handle); - diag_printf("kbd_handle: %d\n", kbd_handle); while(1) { + FD_ZERO(&sock_desc); /* Zero the socket set descriptor */ + if (kbd_handle) { - kbd_len = 4; /* Try to read 4 bytes from keyboard */ - cyg_io_read(kbd_handle, kbd_data, &kbd_len ); + FD_SET(kbd_handle, &sock_desc); /* Add the keyboard handle to the set */ } if (mouse_handle) { - mouse_len = 8; /* Try to read 8 bytes from mouse */ - cyg_io_read(mouse_handle, mouse_data, &mouse_len ); + FD_SET(mouse_handle, &sock_desc); /* Add the mouse handle to the set */ } - if (!mouse_len && !kbd_len) - { - /* There was no mouse or keyboard data */ - cyg_thread_delay(5); - } + /* Use select to wait until a keyboard or mouse event occurs*/ + select(max_handle+1, &sock_desc, NULL, NULL, NULL); - if (mouse_len) + /* Check for a keyboard event */ + if (FD_ISSET(kbd_handle, &sock_desc)) { - diag_printf("Mouse data: (%d, %d) - Button = 0x%x\n", - mouse_data[2]*256 + mouse_data[3], - mouse_data[4]*256 + mouse_data[5], - mouse_data[1]); + kbd_len = 4; - if (mouse_data[1] && !last_mouse_button) - { - /* Ring bell if mouse button is pressed on a yellow pixel */ - if (VncReadPixel(mouse_data[2]*256 + mouse_data[3], - mouse_data[4]*256 + mouse_data[5]) == VNC_YELLOW) + /* Read keyboard data until there is none left */ + while (kbd_len == 4) { - VncSoundBell(); - print_area = VncPrintf(0, 0, VNC_LTBLUE, 150, 400, "Click on a yellow pixel to sound the bell!!\n"); - VncFillRect(150, 400, 150 + print_area.width, 400 + print_area.height, VNC_YELLOW); - print_area = VncPrintf(0, 1, VNC_BLACK, 150, 400, "Click on a yellow pixel to sound the bell!!\n"); - } - } + /* Read 4 bytes from keyboard */ + kbd_len = read(kbd_handle, kbd_data, 4); - last_mouse_button = mouse_data[1]; - } - - if (kbd_len) + if (kbd_len == 4) { if (kbd_data[1]) { diag_printf("Keyboard data: keysym value 0x%x is pressed\n", kbd_data[2]*256 + kbd_data[3]); @@ -153,10 +239,68 @@ int main() else { diag_printf("Keyboard data: keysym value 0x%x is released\n", kbd_data[2]*256 + kbd_data[3]); } + } + } + } + + /* Check for a mouse event */ + if (FD_ISSET(mouse_handle, &sock_desc)) + { + mouse_len = 8; + + /* Read mouse data until there is none left */ + while (mouse_len == 8) + { + /* Read 8 bytes from mouse */ + mouse_len = read(mouse_handle, mouse_data, 8); + + if (mouse_len == 8) + { + if (mouse_data[1] && !last_mouse_button) + { + /* Ring bell and change colours of bell message text if the */ + /* mouse button is pressed on a yellow pixel */ + if (VncReadPixel(mouse_data[2]*256 + mouse_data[3], + mouse_data[4]*256 + mouse_data[5]) == VNC_YELLOW) + { + VncSoundBell(); /* Ring bell on the client */ + + if (bell_text_state) + { + bell_text_state = 0; + /* Draw a background for the text */ + VncFillRect(bell_text_x_pos, /* x1 */ + bell_text_y_pos, /* y1 */ + bell_text_x_pos + bell_text_width, /* x2 */ + bell_text_y_pos + bell_text_height, /* y2 */ + VNC_BLUE); /* Colour */ + /* Write the text on the background */ + print_area = VncPrintf(0, 1, VNC_YELLOW, bell_text_x_pos, bell_text_y_pos, "%s", bell_message); + + } + else + { + bell_text_state = 1; + /* Draw a background for the text */ + VncFillRect(bell_text_x_pos, /* x1 */ + bell_text_y_pos, /* y1 */ + bell_text_x_pos + bell_text_width, /* x2 */ + bell_text_y_pos + bell_text_height, /* y2 */ + VNC_YELLOW); /* Colour */ + /* Write the text on the background */ + print_area = VncPrintf(0, 1, VNC_BLUE, bell_text_x_pos, bell_text_y_pos, "%s", bell_message); + } + } + } + + last_mouse_button = mouse_data[1]; /* Save mouse button data */ + } + } + } } return 1; }