absurd的专栏

欢迎大家加入Linux Mobile Research,本圈子主要致力于基于linux的嵌入式系统的学习和研究,包括内核、驱动、GUI、MMI、软件设计方法和软件优化等方面,欢迎大家加入,无论是高手还是新手,一起学习共同进步。

李先静ID:absurd
971401次访问,排名25好友130人,关注者135
Only those who attempt the absurd can achieve the impossible.
absurd的文章
原创 368 篇
翻译 1 篇
转载 55 篇
评论 1494 篇
李先静的公告
Broncho linux手机平台是构建在linux 2.6 之上,采用GTK+作为GUI的手机平台。欢迎大家到broncho.cn上交流,网站还在建设之中,近期我们会陆续把整理好的文档和代码更新到上去。
最近评论
shijie1983:雅虎管理咨询
网络营销
特价机票
杭州特价机票
杭州打折机票
杭州机票
杭州化妆培训
shijie1983:杭州特价机票
杭州打折机票
杭州机票
杭州化妆培训
unailbobo:谢谢
unailbobo:关于1,我查看源码没有看到gdk_events_init里有关于mainloop的任何代码???
文章分类
收藏
相册
1.个人相册
2.设计备忘录用图
3.设计本质论用图
4.scim架构用图
6.临时文件
7.其它文件
8.研究笔记用图
marvell-linux
1.友情链接
aimself@CSDN(RSS)
directfb中文网站(RSS)
Eric's Little Hut
eye_of_back的专栏(RSS)
Linux Mobile Research
Phoenix@上海(RSS)
segments的专栏(RSS)
study's Blog(RSS)
tracestudio
伐木丁丁鸟鸣嘤嘤(RSS)
会飞的鱼的专栏(RSS)
创系的技术博客
小四的BLOG(RSS)
小马哥的博客(RSS)
开源电信(RSS)
御风剑客
新奇的BLOG
易军军的网络家
李吉群的专栏(RSS)
2.亲情链接
凤凰的幸福蓄水池(RSS)
我的相册
3.软界高手
Donald E. Knuth (RSS)
孟岩(RSS)
透明(RSS)
4.LinuxMobile
celinuxforum(RSS)
GPE(RSS)
maemo.org(RSS)
opensource.motorola
palowireless
5.XWindow
Jserv's blog(RSS)
Keith Packard(RSS)
6.技术资源
7.开源项目
freedesktop(RSS)
GNU(RSS)
GTK+(RSS)
matchbox(RSS)
pxa27x-linux/
8.我的BLOG镜像
absurd@chinaunix
absurd@msn
My English BLOG(RSS)
存档
软件项目交易
订阅我的博客
XML聚合  FeedSky

原创 DirectFB同时显示到X11和VNC上收藏

新一篇: DirectFB运行机制介绍 | 旧一篇: 多进程DirectFB用X11显示的死锁问题

DirectFB同时显示到X11和VNC上

转载时请注明出处和作者联系方式
作者联系方式:李先静 <xianjimli at hotmail dot com>

DirectFB可以使用多种后端作为输入输出设备,典型的有VNC、X11、SDL和fbdev等等,这种设计可以说非常巧妙了。但美中不足的是它在任意时刻只能使用一种后端,更换成其它后端需要重新起动DirectFB应用程序。大多数情况下,这也没有问题,但我想broncho手机在正常使用的情况下,还能通过VNC访问,这样就可以在PC上操作broncho手机的所有功能,甚至到把手机屏幕显示到投影仪上。

对于让DirectFB同时支持多个后端的情况,从设计的角度来看,当然是首选Composite模式,用一种新的后端把其它几个后端组合起来,即不用修改DirectFB框架,又不用修改现有的后端,改一下配置文件就行了。麻烦的是DirectFB-1.1.1中带的VNC根本就不能用,单进程的情况,那些问题我都修改掉了,支持多进程的情况遇到些困难了。最后懒得管它了,先给X11加上VNC功能试一下再说。


先编译LibVNCServer-0.9.1。从sf下载软件包,按正常方式编译即可。

接下来修改X11后端。

1.修改Makefile.am,连接VNC的库。


libdirectfb_x11_la_LDFLAGS = \
    $(X11_LIBS)    $(VNC_LIBS) \
    -avoid-version    \
    -module

2.初始化VNC

     int argc = 0;
     char** argv = NULL;

     D_DEBUG( "DirectFB/VNC: layer config properties\n");

     if(rfb_screen) /*!!! FIXME*/
         return DFB_OK;

     /* Set video mode */
     rfb_screen = rfbGetScreen(&argc, argv, config->width, config->height, 8,3,4);
    
     if(DFB_COLOR_BITS_PER_PIXEL(config->format) == DSPF_RGB16)
     {
        rfb_screen->serverFormat.redShift = 11;
        rfb_screen->serverFormat.greenShift = 5;
        rfb_screen->serverFormat.blueShift = 0;
        rfb_screen->serverFormat.redMax = 31;
        rfb_screen->serverFormat.greenMax = 63;
        rfb_screen->serverFormat.blueMax = 31;
     }
   
     rfb_screen->frameBuffer = malloc(rfb_screen->width * rfb_screen->height * rfb_screen->depth / 8) ;
    
     rfb_screen->kbdAddEvent = process_key_event;
     rfb_screen->ptrAddEvent = process_pointer_event;
     rfb_screen->newClientHook = newclient;
    
     rfbInitServer(rfb_screen);
    
     direct_thread_create( DTT_OUTPUT, vnc_server_thread, rfb_screen, "VNC Output" );
   
     if ( !(config->surface_caps & (DSCAPS_DOUBLE | DSCAPS_TRIPLE)) )
          direct_thread_create( DTT_OUTPUT, vnc_refresh_thread, rfb_screen, "VNC Refresh" );
 
     return DFB_OK;




3.更新VNC显示

static DFBResult
vnc_update_screen(void* src, int x, int y, int w, int h )
{
     int          i, j, k;
     void        *dst;
     int          pitch;
     DFBResult    ret;
     unsigned short* p = NULL;
     unsigned int* q = NULL;
     D_ASSERT( surface != NULL );
     D_ASSERT( rfb_screen != NULL );
     D_ASSERT( rfb_screen->frameBuffer != NULL );

     dst = rfb_screen->frameBuffer;
   
     if(g_vnc_client_nr > 0)
     {
        direct_memcpy( dst, src, w * h * rfb_screen->depth/8 );
        rfbMarkRectAsModified ( rfb_screen, x, y, x+w, y+h );
        printf("%s %d %d %d %d\n", __func__, x, y, w, h);
     }

     return DFB_OK;
}



4.处理VNC输入


static void
process_pointer_event(int buttonMask, int x, int y, rfbClientPtr cl)
{

    DFBInputEvent evt = {0};
    int button = 0;

    if( vncPointerDevice == NULL ){
        /* Attach to first input device */
        dfb_input_enumerate_devices( attach_pointer_device,NULL,
            DICAPS_BUTTONS|DICAPS_AXES);
        D_ASSERT(vncPointerDevice);
    }

    ClientData* cd=cl->clientData;
    if(buttonMask != cd->oldButtonMask ) {
        int mask = buttonMask^cd->oldButtonMask;
        if( mask & (1 << 0)) {
            button=DIBI_LEFT;
        } else if( mask & (1 << 1)) {
            button=DIBI_MIDDLE;
        } else if( mask & (1 << 2)) {
            button=DIBI_RIGHT;
        } else {
            return;
        }
        evt.flags = DIEF_NONE;
               
        if(cd->pressed)
        {
            evt.type = DIET_BUTTONRELEASE;
            cd->pressed=0;
            cd->oldButtonMask = 0;
        }else {
            evt.type = DIET_BUTTONPRESS;
            cd->pressed=1;
            cd->oldButtonMask=buttonMask;
        }
        evt.button=button;
        printf("%s %d %d %d %d\n", __func__, button, cd->pressed, x, y);
        dfb_input_dispatch( vncPointerDevice, &evt );
        cd->oldx=x;
        cd->oldy=y;
        return;
    }

    evt.type    = DIET_AXISMOTION;
    evt.flags   = DIEF_AXISABS;

    if( cd->oldx != x ) {
          evt.axis    = DIAI_X;
          evt.axisabs = x;
          dfb_input_dispatch( vncPointerDevice, &evt );
    }

    if( cd->oldy != y ) {
          evt.axis    = DIAI_Y;
          evt.axisabs = y;
          dfb_input_dispatch( vncPointerDevice, &evt );
    }
    cd->oldx=x;
    cd->oldy=y;

    dfb_input_dispatch( vncPointerDevice, &evt );
    rfbDefaultPtrAddEvent(buttonMask,x,y,cl);

}

static void
process_key_event(rfbBool down, rfbKeySym key, rfbClientPtr cl)
{
    DFBInputEvent evt;
    if( vncKeyboardDevice == NULL ){
        /* Attach to first input device */
        dfb_input_enumerate_devices( attach_keyboard_device,NULL, DICAPS_KEYS);
        D_ASSERT(vncKeyboardDevice);
    }
     if (down)
          evt.type = DIET_KEYPRESS;
     else
          evt.type = DIET_KEYRELEASE;
                                                                                 
     if (translate_key( key, &evt )) {
          dfb_input_dispatch( vncKeyboardDevice, &evt );
     }

}


5.处理VNC客户端连接

static void clientgone(rfbClientPtr cl)
{
  g_vnc_client_nr--;
  free(cl->clientData);

  return;
}

static enum rfbNewClientAction newclient(rfbClientPtr cl)
{
  g_vnc_client_nr++;
  cl->clientData = (void*)calloc(sizeof(ClientData),1);
  cl->clientGoneHook = clientgone;
  return RFB_CLIENT_ACCEPT;
}



编译完成后运行broncho,然后用VNC viewer连接到本机,效果如下:



色彩有点不对,有时间再看看。


~~end~~

发表于 @ 2008年06月09日 14:48:00|评论(loading...)|编辑|收藏

新一篇: DirectFB运行机制介绍 | 旧一篇: 多进程DirectFB用X11显示的死锁问题

评论:没有评论。

发表评论  


当前用户设置只有注册用户才能发表评论。如果你没有登录,请点击登录
Csdn Blog version 3.1a
Copyright © 李先静