现在的位置: 首页 > 综合 > 正文

使用qvfb在X11下开发framebuffer应用程序

2013年08月21日 ⁄ 综合 ⁄ 共 2885字 ⁄ 字号 评论关闭

使用qvfb在X11下开发framebuffer应用程序

2007-10-18 11:32:59|  分类:Linux
|字号 订阅

qvfb是QT virtualframebuffer的缩写,是QT在X11下的一个framebuffer仿真器,有了它我们就可以利用X11下众多便利的工具来开发基于framebuffer的应用程序了。qvfb的原理很简单,它建立了一个systemV共享内存,用户只需将需要显示的图像按像素格式要求放到共享内存里qvfb就可以显示了。

System V共享内存连接的步骤是:

1.通过ftok拿到key
2.使用shmget拿到shmid
3.使用shmat连接到共享内存

这里需要注意的是,key的生成需要向ftok传入一个双方约定好的文件名,对于qvfb屏幕设备,这个文件是/tmp/.qtvfb_mouse-0。

qvfb创建的共享内存包含一个私有的数据头,用于指示像素格式、宽高等信息。这个头结构定义如下:
struct QVFbHeader
{
    int width;
    int height;
    int depth;
    int linestep;
    int dataoffset;
    int update[4];
    char dirty;
    int  numcols;
    unsigned int clut[256];
};

其中dataoffset是virtual framebuffer相对于头结构的偏移位置。向偏移后的地址写入数据就可以反应到qvfb上了。以下是一段示例,

    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)
            memset((char*)qvfb_data + qvfb_data->dataoffset, 0xff, 65535);

    }

Qtopia 里面的一段代码:

bool QVFbScreen::connect(const QString &displaySpec)
220 {
221     screen_optype=&QVFb_dummy;
222     screen_lastop=&QVFb_dummy;
223
224     if (displaySpec.indexOf(":Gray") >= 0)
225         grayscale = true;
226
227     key_t key = ftok(QByteArray(QT_VFB_MOUSE_PIPE).replace("%1", QByteArray::number(displayId)),      'b');
228
229     if (key == -1)
230         return false;
231
232     int shmId = shmget(key, 0, 0);
233     if (shmId != -1)
234         shmrgn = (unsigned char *)shmat(shmId, 0, 0);
235     else
236         return false;
237
238     if ((long)shmrgn == -1 || shmrgn == 0) {
239         qDebug("No shmrgn %ld", (long)shmrgn);
240         return false;
241     }
  hdr = (QVFbHeader *) shmrgn;
244     data = shmrgn + hdr->dataoffset;
245
246     dw = w = hdr->width;
247     dh = h = hdr->height;
248     d = hdr->depth;
249     lstep = hdr->linestep;
250
251     qDebug("Connected to VFB server: %d x %d x %d\n", w, h, d);
252     qDebug("\n\r FILE: %s \tFunction:%s\n",__FILE__,__FUNCTION__);
253
254     size = lstep * h;
255     mapsize = size;
256     screencols = hdr->numcols;
257     memcpy(screenclut, hdr->clut, sizeof(QRgb) * screencols);
 if (qApp->type() == QApplication::GuiServer) {
260         // We handle mouse and keyboard here
261         QWSServer::setDefaultMouse("None");
262         QWSServer::setDefaultKeyboard("None");
263         qDebug("\n\r$$$$$$$$$$$$New mouse , New Keyboard$$$$$$$$$$$$$$\n");
264         mouseHandler = new QVFbMouseHandler(displayId);
265         keyboardHandler = new QVFbKeyboardHandler(displayId);
266         if (hdr->dataoffset >= (int)sizeof(QVFbHeader)) {
267             hdr->serverVersion = QT_VERSION;
268         }
269     }
270
271     return true;
272 }
 void QVFbScreen::disconnect()
275 {
276     if ((long)shmrgn != -1 && shmrgn) {
277         if (qApp->type() == QApplication::GuiServer && hdr->dataoffset >=                             (int)sizeof(QVFbHeader)) {
278             hdr->serverVersion = 0;
279         }
280         shmdt((char*)shmrgn);
281     }
282     if (qApp->type() == QApplication::GuiServer) {
283         delete mouseHandler;
284         mouseHandler = 0;
285         delete keyboardHandler;
286         keyboardHandler = 0;
287     }
288 }

抱歉!评论已关闭.