@@ -109,6 +109,7 @@ static int choose_delay(double dt);
109109int rawfb_reset = -1 ;
110110int rawfb_dev_video = 0 ;
111111int rawfb_vnc_reflect = 0 ;
112+ int rawfb_double_buffer = 0 ;
112113
113114/*
114115 * X11 and rfb display/screen related routines
@@ -1942,14 +1943,25 @@ if (db) fprintf(stderr, "initialize_raw_fb reset\n");
19421943
19431944
19441945/* +O offset */
1946+ char * end ;
19451947if ((q = strrchr (str , '+' )) != NULL ){
1946- if (sscanf (q , "+%d" , & raw_fb_offset ) == 1 ){
1947- * q = '\0' ;
1948- } else {
1948+ end = q ;
1949+ if (sscanf (q , "+%d" , & raw_fb_offset ) != 1 ){
19491950raw_fb_offset = 0 ;
19501951 }
19511952 }
1952- /* :R/G/B masks */
1953+
1954+ /* #VWxVH virtual dimensions */
1955+ if ((q = strrchr (str , '#' )) != NULL ){
1956+ if (q < end ) end = q ;
1957+ if (sscanf (q , "#%dx%d" , & raw_fb_virt_x , & raw_fb_virt_y ) != 2 ){
1958+ raw_fb_virt_x = 0 ;
1959+ raw_fb_virt_y = 0 ;
1960+ }
1961+ }
1962+
1963+ if (end != NULL ) * end = '\0' ;
1964+
19531965if ((q = strrchr (str , ':' )) != NULL ){
19541966if (sscanf (q , ":%lx/%lx/%lx" , & rm , & gm , & bm ) == 3 ){
19551967* q = '\0' ;
@@ -2138,7 +2150,7 @@ if (db) fprintf(stderr, "initialize_raw_fb reset\n");
21382150 } else if (strstr (str , "map:" ) == str || strstr (str , "mmap:" ) == str
21392151|| strstr (str , "file:" ) == str ){
21402152/* map:/path/... or file:/path */
2141- int fd , do_mmap = 1 , size ;
2153+ int fd , do_mmap = 1 , size , vsize ;
21422154struct stat sbuf ;
21432155
21442156if (* str == 'f' ){
@@ -2178,9 +2190,15 @@ if (db) fprintf(stderr, "initialize_raw_fb reset\n");
21782190size = w * h * raw_fb_native_bpp /8 + raw_fb_offset ;
21792191 } else if (xform24to32 ){
21802192size = w * h * 24 /8 + raw_fb_offset ;
2193+ } else if (raw_fb_virt_x != 0 && raw_fb_virt_y != 0 ){
2194+ size = w * h * b /8 ;
2195+ vsize = raw_fb_virt_x * raw_fb_virt_y * b /8 ;
2196+ rawfb_double_buffer = 1 ;
2197+ rfbLog ("virtual size: %d" , vsize );
21812198 } else {
21822199size = w * h * b /8 + raw_fb_offset ;
21832200 }
2201+
21842202if (fstat (fd , & sbuf ) == 0 ){
21852203if (S_ISREG (sbuf .st_mode )){
21862204if (0 ) size = sbuf .st_size ;
@@ -2205,8 +2223,11 @@ if (db) fprintf(stderr, "initialize_raw_fb reset\n");
22052223
22062224 } else if (do_mmap ){
22072225#if LIBVNCSERVER_HAVE_MMAP
2208- raw_fb_addr = mmap (0 , size , PROT_READ , MAP_SHARED ,
2209- fd , 0 );
2226+ if (vsize != 0 ){
2227+ raw_fb_addr = mmap (0 , vsize , PROT_READ , MAP_SHARED , fd , 0 );
2228+ } else {
2229+ raw_fb_addr = mmap (0 , size , PROT_READ , MAP_SHARED , fd , 0 );
2230+ }
22102231
22112232if (raw_fb_addr == MAP_FAILED || raw_fb_addr == NULL ){
22122233rfbLogEnable (1 );
@@ -2223,8 +2244,13 @@ if (db) fprintf(stderr, "initialize_raw_fb reset\n");
22232244raw_fb_mmap = size ;
22242245
22252246rfbLog ("rawfb: mmap file: %s\n" , q );
2226- rfbLog (" w: %d h: %d b: %d addr: %p sz: %d\n" , w , h ,
2227- b , raw_fb_addr , size );
2247+ if (vsize != 0 ){
2248+ rfbLog (" w: %d h: %d b: %d addr: %p sz: %d\n" , w , h ,
2249+ b , raw_fb_addr , vsize );
2250+ } else {
2251+ rfbLog (" w: %d h: %d b: %d addr: %p sz: %d\n" , w , h ,
2252+ b , raw_fb_addr , size );
2253+ }
22282254last_mode = RAWFB_MMAP ;
22292255 }
22302256#else
@@ -4652,6 +4678,12 @@ void watch_loop(void){
46524678/* Now, for scanning and drawing soft cursors (i.e. writing to the framebuffer),
46534679 make sure we're not sending any updates to clients (i.e. reading the framebuffer).
46544680 Otherwise we get flicker! */
4681+
4682+ /* Update offset in case local framebuffer is double buffered */
4683+ if (rawfb_double_buffer ){
4684+ raw_fb_offset = rawfb_get_offset (& raw_fb_fd );
4685+ }
4686+
46554687if (use_threads ){
46564688rfbClientPtr cl ;
46574689rfbClientIteratorPtr iter = rfbGetClientIterator (screen );
0 commit comments