• DirectFB同时显示到X11和VNC上


    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~~
  • 相关阅读:
    变焦与对焦的区别
    教你在Zuul中增加Filter过滤请求
    FEIGN开启对HYSTRIX支持
    Feign使用Hystrix
    Spring Boot中使用Redis小结
    Spring 中的事件机制 ApplicationEventPublisher
    SpringBoot+EasyExcel实现Excel的导出
    SpringBoot–集成验证码kaptcha实现验证码功能
    Spring Cloud使用Feign调用服务接口
    Spring cloud ReadTimeout 问题解决
  • 原文地址:https://www.cnblogs.com/zhangyunlin/p/6167637.html
Copyright © 2020-2023  润新知