乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      VNC源碼閱讀

       我是小丑1 2011-08-09

      VNC源碼閱讀--VNC圖像更新機(jī)制  

      2010-09-25 17:20:41|  分類: 默認(rèn)分類 |  標(biāo)簽: |字號(hào) 訂閱

      VNC源碼閱讀--VNC圖像更新機(jī)制
      2009-09-29 14:33

      VNC的圖像更新機(jī)制核心為,桌面區(qū)域更新記錄策略和更新區(qū)域通知策略。桌面更新區(qū)域記錄主要是通過(guò)hooks記錄桌面上變化的矩形區(qū)域,只記錄更新的矩形區(qū)不記錄具體更新的數(shù)據(jù)。更新區(qū)域記錄步驟大致如下:1.wm_hooks截獲桌面變化的相關(guān)消息,并轉(zhuǎn)化為自定義的消息發(fā)送給WMHooksThread線程處理。 2. WMHooksThread 中用SimpleUpdateTracker new_changes記錄新的更新區(qū)域.3.把SimpleUpdateTracker new_changes更新拷貝到SDisplay中。4.每次要發(fā)送桌面更新的時(shí)候,把SDisplay中記錄的更新區(qū)域傳給VNCServerST 對(duì)象中。更新區(qū)域的通知主要有poll和push兩種機(jī)制。push是服務(wù)器每隔10ms檢查有沒(méi)有更新,如果有更新則主動(dòng)把更新推送給客戶端,poll機(jī)制則是客戶端主動(dòng)請(qǐng)求更新,客戶端通過(guò)發(fā)送framebufferupdate請(qǐng)求某一個(gè)區(qū)域更新,服務(wù)器處理該消息發(fā)送相應(yīng)的更新。詳細(xì)分析如下:

      1.Wm_hooks截獲消息并轉(zhuǎn)化為自定義的消息發(fā)送給WMHooksThread線程處理。

      Wm_hooks自定義的消息:

      UINT WM_HK_WindowChanged = RegisterWindowMessage(_T("RFB.WM_Hooks.WindowChanged"));

      UINT WM_HK_WindowClientAreaChanged = UINT WM_HK_WindowBorderChanged = RegisterWindowMessage(_T("RFB.WM_Hooks.WindowBorderChanged"));

      UINT WM_HK_RectangleChanged = RegisterWindowMessage(_T("RFB.WM_Hooks.RectangleChanged"));

      UINT WM_HK_CursorChanged = RegisterWindowMessage(_T("RFB.WM_Hooks.CursorChanged"));

      鉤子截獲到消息以后,把它轉(zhuǎn)化為自定義的消息,然后發(fā)送給WMHooksThread線程處理,消息轉(zhuǎn)化如下:

      邊框更新消息:WM_NCPAINT,WM_NCACTIVATE

      客戶區(qū)域更新消息:BM_SETCHECK, BM_SETSTATE,EM_SETSEL,WM_CHAR,WM_ENABLE,WM_KEYUP,WM_LBUTTONUP,WM_MBUTTONUP,WM_PALETTECHANGED,WM_RBUTTONUP,WM_SYSCOLORCHANGE,WM_SETTEXT。

      窗口改變消息:WM_HSCROLL,WM_VSCROLL,482,485。

      矩形區(qū)更新消息:WM_DESTROY

      窗口客戶區(qū)消息:WM_PAINT

      鼠標(biāo)消息:WM_NCMOUSEMOVE,WM_MOUSEMOVE

      2 . WMHooksThread 中用SimpleUpdateTracker new_changes記錄新的更新區(qū)域

      WMHooksThread::run() 函數(shù)中先判斷出矩形區(qū)域改變的大小,然后調(diào)用NotifyHooksRegion(const Region& r)把改變的區(qū)域記錄到SimpleUpdateTracker new_changes中。

      NotifyHooksRegion(const Region& r) {

      Lock l(hook_mgr_lock);

      std::list<WMHooks*>::iterator i;

      for (i=hooks.begin(); i!=hooks.end(); i++) {

          (*i)->new_changes.add_changed(r);

          if (!(*i)->notified) {

            (*i)->notified = true;

            PostMessage((*i)->getHandle(), WM_USER, 0, 0); // 把消息通知到clipper見(jiàn)下面一個(gè)處理函數(shù)

          }

      }

      }

      3.把更新區(qū)域拷貝到SDisplay中

      rfb::win32::WMHooks::processMessage(UINT msg, WPARAM wParam, LPARAM lParam) {

      switch (msg) {

      case WM_USER:

          {

            Sleep(0);

            Lock l(hook_mgr_lock);

            notified = false;

            new_changes.get_update(*clipper); //把更新通知到clipper中

            new_changes.clear();

          }

          break;

      }

      return MsgWindow::processMessage(msg, wParam, lParam);

      }

      Cliper在下面設(shè)置

      rfb::win32::WMHooks::setUpdateTracker(UpdateTracker* ut) {

      if (clipper) delete clipper;

      clipper = new ClippedUpdateTracker(*ut);

      clipper->set_clip_region(clip_region);

      return AddHook(this);

      }

      UpdateTracker* ut 為void SDisplay::start(VNCServer*vs)中設(shè)置 core->using_hooks = core->wm_hooks.setUpdateTracker(this);

      4.把SDisplay中記錄的數(shù)據(jù)傳給VNCServerST 對(duì)象

      在 SDisplay::processEvent(HANDLE event) {

      try_update = flushChangeTracker() || try_update; //把變化的區(qū)域拷貝到VNCServerST中

            if (try_update)

              server->tryUpdate();          //把更新發(fā)送給服務(wù)器

      }

      flushChangeTracker()實(shí)現(xiàn)如下:

      bool SDisplay::flushChangeTracker() {

      if (change_tracker.is_empty())

          return false;

      change_tracker.translate(screenRect.tl.negate());

      change_tracker.get_update(*server); //server 實(shí)際指向VNCServerST 對(duì)象該函數(shù)把SDisplay中的更新拷貝到VNCServerST中。

      change_tracker.clear();

      return true;

      }

      兩種數(shù)據(jù)更新方式:Push機(jī)制和Pull機(jī)制

      Push:

      SdisplayCore 中IntervalTimer cursorTimer定時(shí)器,每隔10ms嘗試著檢查一下是否有更新,如果有更新就發(fā)送更新給客戶端。

      第一步:

      LRESULT SDisplayCore::processMessage(UINT msg, WPARAM wParam, LPARAM lParam) {

      case TIMER_CURSOR:

           display->triggerUpdate(); //SDisplay* display;

      }

      第二步:

      void SDisplay::triggerUpdate() {

           if (core)

               SetEvent(updateEvent); //使事件對(duì)象為受信狀態(tài)

      }

      第三步:

      SDisplay::processEvent(HANDLE event) {

           if (event == updateEvent) {

               if (try_update)

                         server->tryUpdate(); // VNCServer* server指針 指向子類VNCServerST

      }

      }

      第四步:向每一個(gè)連接的客戶端發(fā)送更新

      void VNCServerST::tryUpdate()

      {

           std::list<VNCSConnectionST*>::iterator ci, ci_next;

           for (ci = clients.begin(); ci != clients.end(); ci = ci_next) {

               ci_next = ci; ci_next++;

               (*ci)->writeFramebufferUpdateOrClose();

           }

      }

      第五步:

      void VNCSConnectionST::writeFramebufferUpdateOrClose()

      {

           try {

               writeFramebufferUpdate();

           } catch(rdr::Exception &e) {

               close(e.str());

           }

      }

      第六步:SimpleUpdateTracker updates對(duì)象記錄更新的區(qū)域,如果屏幕有更新則發(fā)送更新

      void VNCSConnectionST::writeFramebufferUpdate(){

      if (!update.is_empty() || writer()->needFakeUpdate() || drawRenderedCursor) {

               int nRects = update.numRects() + (drawRenderedCursor ? 1 : 0);

               writer()->writeFramebufferUpdateStart(nRects);

               Region updatedRegion;

               writer()->writeRects(update, &image_getter, &updatedRegion); // SmsgWriter *

               updates.subtract(updatedRegion);

               if (drawRenderedCursor)

                    writeRenderedCursorRect();

               writer()->writeFramebufferUpdateEnd();

               requested.clear();

           }

      }

      第七步:利用RFB協(xié)議發(fā)送更新

      void SMsgWriterV3::writeFramebufferUpdateStart(int nRects)

      {

           startMsg(msgTypeFramebufferUpdate);

           os->pad(1);

           if (wsccb) nRects++;

           if (needSetDesktopSize) nRects++;

           os->writeU16(nRects);

           nRectsInUpdate = 0;

           nRectsInHeader = nRects;

           if (wsccb) {

               wsccb->writeSetCursorCallback();

               wsccb = 0;

           }


        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶 評(píng)論公約

        類似文章 更多