865 static int GenTileUpdateData(uint8_t *packet_buffer) |
859 static int GenTileUpdateData(uint8_t *packet_buffer) |
866 { |
860 { |
867 uint16_t x_pos, y_pos; |
861 uint16_t x_pos, y_pos; |
868 int i, j; |
862 int i, j; |
869 int tile_width, tile_height; |
863 int tile_width, tile_height; |
870 int packet_length; |
|
871 static vnc_color_t tile_buffer[TILE_SIZE][TILE_SIZE]; /* Buffer to hold tile to be encoded */ |
|
872 vnc_color_t pixel_colour; |
|
873 vnc_color_t bg_colour; |
|
874 int no_of_subrects, subrect_width, subrect_height; |
|
875 int k, l; |
|
876 |
|
877 no_of_subrects = 0; /* Set to no sub-rectangles to start with */ |
|
878 packet_length = 20-4+(Bits_Per_Pixel/8); /* Set to minimum packet length to start with */ |
|
879 |
864 |
880 /* Get the X and Y positions of this tile from the packet buffer */ |
865 /* Get the X and Y positions of this tile from the packet buffer */ |
881 x_pos = packet_buffer[0] * 256 + packet_buffer[1]; |
866 x_pos = packet_buffer[0] * 256 + packet_buffer[1]; |
882 y_pos = packet_buffer[2] * 256 + packet_buffer[3]; |
867 y_pos = packet_buffer[2] * 256 + packet_buffer[3]; |
883 |
868 |
884 /* Get the tile width and height from the packet buffer */ |
869 /* Get the tile width and height from the packet buffer */ |
885 tile_width = packet_buffer[4] * 256 + packet_buffer[5]; |
870 tile_width = packet_buffer[4] * 256 + packet_buffer[5]; |
886 tile_height = packet_buffer[6] * 256 + packet_buffer[7]; |
871 tile_height = packet_buffer[6] * 256 + packet_buffer[7]; |
887 |
|
888 /* Set the encoding type to RRE */ |
|
889 if (!encoding_type.corre) { |
|
890 /* CoRRE encoding is not supported - just use raw encoding */ |
|
891 goto use_raw_encoding; |
|
892 } |
|
893 |
|
894 /* Set encoding type to CoRRE encoding in packet buffer */ |
|
895 packet_buffer[8+0] = 0; |
|
896 packet_buffer[8+1] = 0; |
|
897 packet_buffer[8+2] = 0; |
|
898 packet_buffer[8+3] = 4; |
|
899 |
|
900 /* Copy tile from the main frame buffer to the local tile buffer */ |
|
901 for (i = 0; i < tile_height; i++) { |
|
902 for (j = 0; j < tile_width; j++) { |
|
903 tile_buffer[i][j] = frame_buffer[y_pos + i][x_pos + j]; |
|
904 } |
|
905 } |
|
906 |
|
907 /* Find the background colour */ |
|
908 /* We just assume the (0, 0) pixel in the tile is the bgcolour */ |
|
909 /* Its quick!!! */ |
|
910 bg_colour = frame_buffer[y_pos][x_pos]; |
|
911 |
|
912 /* Set the background colour in the packet buffer */ |
|
913 if (Bits_Per_Pixel == 8) { |
|
914 packet_buffer[16] = PixelConvert(bg_colour); /* (vnc_color_t) bg_colour; */ |
|
915 } else { |
|
916 packet_buffer[16] = COLOUR2BYTE0(bg_colour); |
|
917 packet_buffer[16+1] = COLOUR2BYTE1(bg_colour); |
|
918 } |
|
919 |
|
920 #ifdef CYGNUM_VNC_SERVER_CORRE_ENCODING_HACK |
|
921 /* Add an initial sub-rectangle to paint the background the background colour */ |
|
922 /* This is required because of a known bug in the VNC viewer (x86 version) */ |
|
923 //#if BITS_PER_PIXEL == 8 |
|
924 packet_buffer[packet_length] = (vnc_color_t) bg_colour; |
|
925 packet_length++; |
|
926 //#endif |
|
927 //#if BITS_PER_PIXEL == 16 |
|
928 // packet_buffer[packet_length] = packet_buffer[16]; |
|
929 // packet_buffer[packet_length+1] = packet_buffer[16+1]; |
|
930 // packet_length += 2; |
|
931 //#endif |
|
932 packet_buffer[packet_length] = (uint8_t) 0; /* Sub-rect x-pos */ |
|
933 packet_buffer[packet_length+1] = (uint8_t) 0; /* Sub-rect y-pos*/ |
|
934 packet_buffer[packet_length+2] = (uint8_t) tile_width; /* Sub-rect width*/ |
|
935 packet_buffer[packet_length+3] = (uint8_t) tile_height; /* Sub-rect height*/ |
|
936 packet_length += 4; |
|
937 no_of_subrects++; /* Increment sub-rectangle count */ |
|
938 #endif |
|
939 |
|
940 /* Scan trough tile and find sub-rectangles */ |
|
941 for (i = 0; i < tile_height; i++) { |
|
942 for (j = 0; j < tile_width; j++) { |
|
943 if (tile_buffer[i][j] != bg_colour) { |
|
944 /* This is a non-background pixel */ |
|
945 subrect_width = 1; |
|
946 pixel_colour = tile_buffer[i][j]; |
|
947 |
|
948 /* Extend the sub-rectangle to its maximum width */ |
|
949 for (subrect_width = 1; subrect_width <= tile_width-j-1; subrect_width++) { |
|
950 if (tile_buffer[i][j+subrect_width] != pixel_colour) { |
|
951 goto got_subrect_width; |
|
952 } |
|
953 } |
|
954 |
|
955 got_subrect_width: |
|
956 |
|
957 /* Extend the sub-rectangle to its maximum height */ |
|
958 for (subrect_height=1; subrect_height <= tile_height-i-1; subrect_height++) { |
|
959 for (k = j; k < j+subrect_width; k++) { |
|
960 if (tile_buffer[i+subrect_height][k] != pixel_colour) { |
|
961 goto got_subrect_height; |
|
962 } |
|
963 } |
|
964 } |
|
965 |
|
966 got_subrect_height: |
|
967 |
|
968 /* Delete the pixels for the sub-rectangle from the sub-rectangle */ |
|
969 for (k = i; k < i+subrect_height; k++) { |
|
970 for (l = j; l < j+subrect_width; l++) { |
|
971 tile_buffer[k][l] = bg_colour; |
|
972 } |
|
973 } |
|
974 |
|
975 /* Append new sub-rectangle data to the packet buffer */ |
|
976 if (Bits_Per_Pixel == 8) { |
|
977 packet_buffer[packet_length] = PixelConvert(pixel_colour); // (vnc_color_t) pixel_colour; |
|
978 packet_length++; |
|
979 } else { |
|
980 packet_buffer[packet_length] = COLOUR2BYTE0(pixel_colour); |
|
981 packet_buffer[packet_length+1] = COLOUR2BYTE1(pixel_colour); |
|
982 packet_length += 2; |
|
983 } |
|
984 |
|
985 packet_buffer[packet_length] = (uint8_t) j; /* Sub-rect x-pos */ |
|
986 packet_length++; |
|
987 |
|
988 packet_buffer[packet_length] = (uint8_t) i; /* Sub-rect y-pos*/ |
|
989 packet_length++; |
|
990 |
|
991 packet_buffer[packet_length] = (uint8_t) subrect_width; /* Sub-rect width*/ |
|
992 packet_length++; |
|
993 |
|
994 packet_buffer[packet_length] = (uint8_t) subrect_height; /* Sub-rect height*/ |
|
995 packet_length++; |
|
996 |
|
997 no_of_subrects++; /* Increment sub-rectangle count */ |
|
998 |
|
999 if (packet_length >= 12 + tile_height*tile_width*(BITS_PER_PIXEL/8) - 6) { |
|
1000 /* The next sub-rectangle will make the packet size */ |
|
1001 /* larger than a rew encoded packet - so just use raw */ |
|
1002 goto use_raw_encoding; |
|
1003 } |
|
1004 } |
|
1005 } |
|
1006 } |
|
1007 |
|
1008 /* Fill in no_of_sub-rectangles field in packet buffer */ |
|
1009 packet_buffer[12+0] = 0; |
|
1010 packet_buffer[12+1] = 0; |
|
1011 packet_buffer[12+2] = no_of_subrects / 256; |
|
1012 packet_buffer[12+3] = no_of_subrects % 256; |
|
1013 |
|
1014 /* CoRRE data encoding for tile complete */ |
|
1015 return packet_length; |
|
1016 |
|
1017 use_raw_encoding: |
|
1018 |
872 |
1019 /* Create packet data using RAW encoding */ |
873 /* Create packet data using RAW encoding */ |
1020 for (i = 0; i < tile_height; i++) { |
874 for (i = 0; i < tile_height; i++) { |
1021 for (j = 0; j < tile_width; j++) { |
875 for (j = 0; j < tile_width; j++) { |
1022 if (Bits_Per_Pixel == 8) { |
876 if (Bits_Per_Pixel == 8) { |