Skip to content

Commit 49741e9

Browse files
authored
Merge pull request #124 from bschaef14/rawfb-doublebuffer-support
Support for double buffered raw framebuffers Closes#106
2 parents 11da683 + 870d47e commit 49741e9

File tree

6 files changed

+86
-16
lines changed

6 files changed

+86
-16
lines changed

‎README‎

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16858,22 +16858,33 @@ er
1685816858
discussion below where the framebuffer is taken as that
1685916859
of another remote VNC server.
1686016860

16861-
Optional suffixes are ":R/G/B" and "+O" to specify
16862-
red, green, and blue masks (in hex) and an offset into
16863-
the memory object. If the masks are not provided x11vnc
16864-
guesses them based on the bpp (if the colors look wrong,
16865-
you need to provide the masks.)
16861+
Optional suffixes are ":R/G/B", "+O", and "#VWxVH" to
16862+
specify red, green, and blue masks (in hex), offset into
16863+
the memory object, and virtual width and height.
16864+
16865+
If the masks are not provided x11vnc guesses them based on
16866+
the bpp (if the colors look wrong, you need to provide the
16867+
masks.)
1686616868

1686716869
Another optional suffix is the Bytes Per Line which in
1686816870
some cases is not WxB/8. Specify it as WxHxB-BPL
1686916871
e.g. 800x600x16-2048. This could be a normal width
1687016872
1024 at 16bpp fb, but only width 800 shows up.
1687116873

16872-
So the full format is: mode:file@WxHxB:R/G/B+O-BPL
16874+
The last optional suffix is virtual dimensions VWxVH. Some
16875+
devices will double buffer the display in the framebuffer,
16876+
allowing updating contents of display and then "panning"
16877+
to the buffer via yoffset. x11vnc will map the virutal
16878+
size specified by the options stead of just WxH, and track
16879+
yoffset appropriately so remote clients get all updates to
16880+
the frame buffer.
16881+
16882+
So the full format is: mode:file@WxHxB:R/G/B+O-BPL#VWxVH
1687316883

1687416884
Examples:
1687516885
-rawfb shm:210337933@800x600x32:ff/ff00/ff0000
1687616886
-rawfb map:/dev/fb0@1024x768x32
16887+
-rawfb map:/dev/fb0@800x480x16#800x960
1687716888
-rawfb map:/tmp/Xvfb_screen0@640x480x8+3232
1687816889
-rawfb file:/tmp/my.pnm@250x200x24+37
1687916890
-rawfb file:/dev/urandom@128x128x8

‎src/linuxfb.c‎

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,31 @@ so, delete this exception statement from your version.
5353
char*console_guess(char*str, int*fd);
5454
voidconsole_key_command(rfbBooldown, rfbKeySymkeysym, rfbClientPtrclient);
5555
voidconsole_pointer_command(intmask, intx, inty, rfbClientPtrclient);
56+
voidlinux_dev_fb_msg(char*);
5657

58+
/* Returns offset into fb memory based on yoffset. */
59+
intrawfb_get_offset(int*fd)
60+
{
61+
#ifHAVE_LINUX_FB_H
62+
intoffset;
63+
structfb_var_screeninfovar_info;
64+
if (ioctl(*fd, FBIOGET_VSCREENINFO, &var_info)){
65+
perror("ioctl");
66+
return0;
67+
}
5768

58-
voidlinux_dev_fb_msg(char*);
69+
/* todo: How should x offset be handled? */
70+
if (var_info.xoffset!=0){
71+
rfbLog("rawfb xoffset handling not implemented");
72+
}
73+
74+
if (var_info.yoffset!=0){
75+
offset=main_bytes_per_line*var_info.yoffset;
76+
returnoffset;
77+
}
78+
#endif
79+
return0;
80+
}
5981

6082
char*console_guess(char*str, int*fd){
6183
char*q, *in=strdup(str);

‎src/linuxfb.h‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ so, delete this exception statement from your version.
3737
externchar*console_guess(char*str, int*fd);
3838
externvoidconsole_key_command(rfbBooldown, rfbKeySymkeysym, rfbClientPtrclient);
3939
externvoidconsole_pointer_command(intmask, intx, inty, rfbClientPtrclient);
40+
externintrawfb_get_offset(int*fd);
4041

4142

4243
#endif/* _X11VNC_LINUXFB_H */

‎src/screen.c‎

Lines changed: 41 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ static int choose_delay(double dt);
109109
intrawfb_reset=-1;
110110
intrawfb_dev_video=0;
111111
intrawfb_vnc_reflect=0;
112+
intrawfb_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;
19451947
if ((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){
19491950
raw_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+
19531965
if ((q=strrchr(str, ':')) !=NULL){
19541966
if (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
} elseif (strstr(str, "map:") ==str||strstr(str, "mmap:") ==str
21392151
||strstr(str, "file:") ==str){
21402152
/* map:/path/... or file:/path */
2141-
intfd, do_mmap=1, size;
2153+
intfd, do_mmap=1, size, vsize;
21422154
structstatsbuf;
21432155

21442156
if (*str=='f'){
@@ -2178,9 +2190,15 @@ if (db) fprintf(stderr, "initialize_raw_fb reset\n");
21782190
size=w*h*raw_fb_native_bpp/8+raw_fb_offset;
21792191
} elseif (xform24to32){
21802192
size=w*h*24/8+raw_fb_offset;
2193+
} elseif (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{
21822199
size=w*h*b/8+raw_fb_offset;
21832200
}
2201+
21842202
if (fstat(fd, &sbuf) ==0){
21852203
if (S_ISREG(sbuf.st_mode)){
21862204
if (0) size=sbuf.st_size;
@@ -2205,8 +2223,11 @@ if (db) fprintf(stderr, "initialize_raw_fb reset\n");
22052223

22062224
} elseif (do_mmap){
22072225
#ifLIBVNCSERVER_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

22112232
if (raw_fb_addr==MAP_FAILED||raw_fb_addr==NULL){
22122233
rfbLogEnable(1);
@@ -2223,8 +2244,13 @@ if (db) fprintf(stderr, "initialize_raw_fb reset\n");
22232244
raw_fb_mmap=size;
22242245

22252246
rfbLog("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+
}
22282254
last_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+
46554687
if(use_threads){
46564688
rfbClientPtrcl;
46574689
rfbClientIteratorPtriter=rfbGetClientIterator(screen);

‎src/x11vnc.h‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -541,6 +541,8 @@ extern char *rot_fb; /* used under -rotate */
541541
externchar*raw_fb;
542542
externchar*raw_fb_addr;
543543
externintraw_fb_offset;
544+
externintraw_fb_virt_x;
545+
externintraw_fb_virt_y;
544546
externintraw_fb_shm;
545547
externintraw_fb_mmap;
546548
externintraw_fb_seek;

‎src/x11vnc_defs.c‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,8 @@ char *rot_fb = NULL;
105105
char*raw_fb=NULL; /* when used should be main_fb */
106106
char*raw_fb_addr=NULL;
107107
intraw_fb_offset=0;
108+
intraw_fb_virt_x=0;
109+
intraw_fb_virt_y=0;
108110
intraw_fb_shm=0;
109111
intraw_fb_mmap=0;
110112
intraw_fb_seek=0;

0 commit comments

Comments
(0)