Malc's idea seems to work so take that for what it's worth :)<jadamcze> cheriff: ps3 fb is ARGB8888, libvncserver doesn't seem to support converting from that format
<jadamcze> There appears to be no magic option to get the colours right. afaict.
<malc> just add one to fb_ea if you're not using the alpha...
Hi, I find this useful, so thought I might share. It takes whatever format /dev/fb0 is set to, and uses it as input for a simple VNC server.
Caveats:
- resends entire buffer each frame
probably not secure much
colours seem mixed up, either an endian or pixel format issue
Try using ps3-video-mode to change the size of the framebuffer, and hence the performance.. 720p seems to work nicely for me on a 100MB network.
You need to have libvncserver properly installed. Gentoo just emerged it properly for me.
Credits: mostly ripped from the provided sample applications
Building:
Code: Select all
make main.o
gcc -o main main.o -lvncserver
./main
Code: Select all
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <rfb/rfb.h>
#include <rfb/keysym.h>
#include <linux/fb.h>
#include <linux/kd.h>
#include <asm/ps3fb.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <sys/mman.h>
typedef struct ClientData {
rfbBool oldButton;
int oldx,oldy;
} ClientData;
rfbClientPtr gcl = NULL;
static void doptr(int buttonMask,int x,int y,rfbClientPtr cl){
}
static void dokey(rfbBool down,rfbKeySym key,rfbClientPtr cl)
{
}
static void clientgone(rfbClientPtr cl)
{
free(cl->clientData);
gcl = NULL;
}
static enum rfbNewClientAction newclient(rfbClientPtr cl)
{
cl->clientData = (void*)calloc(sizeof(ClientData),1);
cl->clientGoneHook = clientgone;
gcl = cl;
return RFB_CLIENT_ACCEPT;
}
int main(int argc, char *argv[]){
int fd = open("/dev/fb0", O_RDWR);
struct ps3fb_ioctl_res res;
ioctl(fd, PS3FB_IOCTL_SCREENINFO, (unsigned long)&res);
printf("xres: %d, yres: %d, xoff: %d, yoff: %d, num_frames: %d\n",
res.xres, res.yres, res.xoff, res.yoff, res.num_frames);
unsigned int length = res.xres * res.yres * 4 * res.num_frames;
int bpp = 4;
void * buffer = mmap(NULL, length, PROT_WRITE, MAP_SHARED, fd, 0);
rfbScreenInfoPtr rfbScreen =
rfbGetScreen(&argc,argv, res.xres, res.yres,8,3,bpp);
rfbScreen->desktopName = "PS3 VNC";
rfbScreen->frameBuffer = buffer;
rfbScreen->alwaysShared = TRUE;
rfbScreen->ptrAddEvent = doptr;
rfbScreen->kbdAddEvent = dokey;
rfbScreen->newClientHook = newclient;
rfbScreen->httpDir = "../classes";
rfbScreen->httpEnableProxyConnect = TRUE;
rfbInitServer(rfbScreen);
while(1){
rfbMarkRectAsModified(rfbScreen, 0,0,res.xres, res.yres);
rfbProcessEvents(rfbScreen,1);
if (gcl){
rfbSendUpdateBuf(gcl);
}
}
}