2010年3月14日 星期日

nano-X使用qwfb

qwfb是QT的virtual framebuffer也就是 framebuffer防真器,所以有些特性會跟framebuffer一樣。

先讓我們來看看他的用法吧!
1.若要使用它,那就要先知道他的溝通界面,那就參考下面吧!

struct QVFbHeader
{
int width; //宽度
int height; //高度
int depth; //色深
int linestep; //每一行的字节数 pitch
int dataoffset; //图像数据在共享内存中的偏移
int update[4]; //要更新的区域 x,y,w,h
char dirty; //是否更新,把它设为1,qvfb就会把update指定的区域显示到屏幕上
int numcols;//颜色数
unsigned int clut[256];//颜色索引
};

int main(const int argc,const char *argv[])
{
int key = ftok("/tmp/.qtvfb_mouse-0", 'b');
int shmid = shmget(key, 0, 0);
if (shmid !=-1)
{
struct QVFbHeader* qvfb_data = shmat(shmid, 0, 0);
if (qvfb_data != NULL)
{
int i,j;
char *ptr;
printf("width:%d\n",qvfb_data->width);
printf("height:%d\n",qvfb_data->height);
printf("depth:%d\n",qvfb_data->depth);
printf("linestep:%d\n",qvfb_data->linestep);
printf("dataoffset:%d\n",qvfb_data->dataoffset);
printf("update[0]:%d\n",qvfb_data->update[0]);
printf("update[1]:%d\n",qvfb_data->update[1]);
printf("update[2]:%d\n",qvfb_data->update[2]);
printf("update[3]:%d\n",qvfb_data->update[3]);
printf("dirty:%d\n",qvfb_data->dirty);
printf("numcols:%d\n",qvfb_data->numcols);
for(i=0;iheight;i++)
{
ptr = (char*)qvfb_data + qvfb_data->dataoffset+////qvfb_data->linestep*i;
for(j=0;jwidth;j++)
{
*ptr =0x00;//bule
ptr++;
*ptr = 0xff;//
ptr++;
*ptr = 0x00;//red
ptr++;
*ptr = 0x00;
ptr++;
}
}
}
//設定要更新的區域
qvfb_data->update[0]=0;
qvfb_data->update[1]=0;
qvfb_data->update[2]=qvfb_data->width;
qvfb_data->update[3]=qvfb_data->height;
qvfb_data->dirty=1; //更新畫面吧
}
printf("hello\n");
return 0;
}

2.因為要使nano-X 支援qwfb所以要修改一下,下面的檔案
src/driver/scr_fb.c
修改static PSD fb_open(PSD psd)成下列


typedef struct QVFbHeader
{
int width; //宽度
int height; //高度
int depth; //色深
int linestep; //每一行的字节数
int dataoffset; //图像数据在共享内存中的偏移
int update[4]; //要更新的区域
char dirty; //是否更新,把它设为1,qvfb就会把update指定的区域显示到屏幕上
int numcols; //颜色数
unsigned int clut[256]; //颜色索引
};

void flashdraw()
{
qvfb_data->update[0]=0;qvfb_data->update[1]=0;qvfb_data->update[2]=qvfb_data->width;qvfb_data->update[3]=qvfb_data->height;
qvfb_data->dirty=1;
}


/* init framebuffer*/
static PSD
fb_open(PSD psd)
{
char * env;
int type, visual;
PSUBDRIVER subdriver;

int key = ftok("/tmp/.qtvfb_mouse-0", 'b');
int shmid = shmget(key, 0, 0);
qvfb_data = (struct QVFbHeader *)shmat(shmid, 0, 0);
if (qvfb_data == NULL)
{
EPRINTF("2Error opening %s: %m", env);
return NULL;
}
psd->xres = psd->xvirtres = qvfb_data->width;
psd->yres = psd->yvirtres = qvfb_data->height;
psd->planes = 1;
psd->bpp = qvfb_data->depth;
psd->ncolors = (psd->bpp >= 24)? (1 <<>bpp);
psd->linelen = qvfb_data->linestep;
psd->size = 0;

psd->flags = PSF_SCREEN | PSF_HAVEBLIT;
psd->pixtype = MWPF_TRUECOLOR0888;

/* select a framebuffer subdriver based on planes and bpp*/
subdriver = select_fb_subdriver(psd);
if (!subdriver) {
EPRINTF("No driver for screen type %d visual %d bpp %d\n",
type, visual, psd->bpp);
goto fail;
}

/*
* set and initialize subdriver into screen driver
* psd->size is calculated by subdriver init
*/
if(!set_subdriver(psd, subdriver, TRUE)) {
EPRINTF("Driver initialize failed type %d visual %d bpp %d\n",
type, visual, psd->bpp);
goto fail;
}

/* remember original subdriver for portrait mode switching*/
pdrivers[0] = psd->orgsubdriver = subdriver;

/* mmap framebuffer into this address space*/
psd->size = (psd->size + getpagesize () - 1)
/ getpagesize () * getpagesize ();
psd->addr = (char*)qvfb_data + qvfb_data->dataoffset;

/* save original palette*/

/* setup direct color palette if required (ATI cards)*/
if(visual == FB_VISUAL_DIRECTCOLOR)
set_directcolor_palette(psd);

status = 2;
return psd; /* success*/

fail:
//close(fb);
return NULL;
}


3.改更了軟體為什麼qwfb上的東西為什麼不會自動更新呢?
因為它一定要改qvfb_data->dirty=1;才會真的畫出圖來。
因為我是選用RGB32模式的,所以我要修改fbline32.c的程式來讓他作更新,
因為發現檔案中每個畫面的function都會叫用DRAWOFF的marco,所以就好好的利用它一下吧!
#undef DRAWOFF
#define DRAWOFF flashdraw()

讓他執行到DRAWOFF時就去更新qwfb的畫面吧!





完工

沒有留言: