void vncDesktopThread::PollWindow(rfb::Region2D &rgn, HWND hwnd) { // Are we set to low-load polling? if (m_server->PollOnEventOnly()) { // Yes, so only poll if the remote user has done something if (!m_server->RemoteEventReceived()) { return; } } // Does the client want us to poll only console windows? if (m_desktop->m_server->PollConsoleOnly()) { char classname[20]; // Yes, so check that this is a console window... if (GetClassName(hwnd, classname, sizeof(classname))) { if ((strcmp(classname, "tty") != 0) && (strcmp(classname, "ConsoleWindowClass") != 0)) { return; } } } RECT rect; // Get the rectangle if (GetWindowRect(hwnd, &rect)) { //Buffer coordinates rect.left-=m_desktop->m_ScreenOffsetx; rect.right-=m_desktop->m_ScreenOffsetx; rect.top-=m_desktop->m_ScreenOffsety; rect.bottom-=m_desktop->m_ScreenOffsety; rfb::Rect wrect = rfb::Rect(rect).intersect(m_desktop->m_Cliprect); if (!wrect.is_empty()) { rgn.assign_union(wrect); } } }
bool vncDesktopThread::Handle_Ringbuffer(mystruct *ringbuffer,rfb::Region2D &rgncache) { bool returnvalue=false; //vnclog.Print(LL_INTERR, VNCLOG("counter,g_Oldcounter %i %i \n"),ringbuffer->counter,g_Oldcounter); if (ringbuffer->counter==g_Oldcounter) return 0; int counter=ringbuffer->counter; if (counter<1 || counter>1999) return 0; if (g_Oldcounter<counter) { for (int i =g_Oldcounter+1; i<=counter;i++) { if (ringbuffer->type[i]==0) { rfb::Rect rect; rect.tl = rfb::Point(ringbuffer->rect1[i].left, ringbuffer->rect1[i].top); rect.br = rfb::Point(ringbuffer->rect1[i].right, ringbuffer->rect1[i].bottom); //Buffer coordinates rect.tl.x-=m_desktop->m_ScreenOffsetx; rect.br.x-=m_desktop->m_ScreenOffsetx; rect.tl.y-=m_desktop->m_ScreenOffsety; rect.br.y-=m_desktop->m_ScreenOffsety; vnclog.Print(LL_INTERR, VNCLOG("REct %i %i %i %i \n"),rect.tl.x,rect.br.x,rect.tl.y,rect.br.y); /*#ifdef _DEBUG char szText[256]; DWORD error=GetLastError(); sprintf(szText,"REct1 %i %i %i %i \n",rect.tl.x,rect.br.x,rect.tl.y,rect.br.y); SetLastError(0); OutputDebugString(szText); #endif*/ rect = rect.intersect(m_desktop->m_Cliprect); if (!rect.is_empty()) { /*#ifdef _DEBUG char szText[256]; DWORD error=GetLastError(); sprintf(szText,"REctXXXXXXXXXXX %i %i %i %i \n",rect.tl.x,rect.br.x,rect.tl.y,rect.br.y); SetLastError(0); OutputDebugString(szText); #endif*/ returnvalue=true; rgncache.assign_union(rect); } } if (ringbuffer->type[i]==2 || ringbuffer->type[i]==4) { /*if (MyGetCursorInfo) { MyCURSORINFO cinfo; cinfo.cbSize=sizeof(MyCURSORINFO); MyGetCursorInfo(&cinfo); m_desktop->SetCursor(cinfo.hCursor); //vnclog.Print(LL_INTERR, VNCLOG("Cursor %i \n"),cinfo.hCursor); }*/ } } } else { int i = 0; for (i =g_Oldcounter+1;i<2000;i++) { if (ringbuffer->type[i]==0 ) { rfb::Rect rect; rect.tl = rfb::Point(ringbuffer->rect1[i].left, ringbuffer->rect1[i].top); rect.br = rfb::Point(ringbuffer->rect1[i].right, ringbuffer->rect1[i].bottom); //Buffer coordinates rect.tl.x-=m_desktop->m_ScreenOffsetx; rect.br.x-=m_desktop->m_ScreenOffsetx; rect.tl.y-=m_desktop->m_ScreenOffsety; rect.br.y-=m_desktop->m_ScreenOffsety; //vnclog.Print(LL_INTERR, VNCLOG("REct %i %i %i %i \n"),rect.tl.x,rect.br.x,rect.tl.y,rect.br.y); /*#ifdef _DEBUG char szText[256]; DWORD error=GetLastError(); sprintf(szText,"REct2 %i %i %i %i \n",rect.tl.x,rect.br.x,rect.tl.y,rect.br.y); SetLastError(0); OutputDebugString(szText); #endif */ rect = rect.intersect(m_desktop->m_Cliprect); if (!rect.is_empty()) { returnvalue=true; rgncache.assign_union(rect); } } if (ringbuffer->type[i]==2 || ringbuffer->type[i]==4) { /*if (MyGetCursorInfo) { MyCURSORINFO cinfo; cinfo.cbSize=sizeof(MyCURSORINFO); MyGetCursorInfo(&cinfo); m_desktop->SetCursor(cinfo.hCursor); //vnclog.Print(LL_INTERR, VNCLOG("Cursor %i \n"),cinfo.hCursor); }*/ } } for (i=1;i<=counter;i++) { if (ringbuffer->type[i]==0 ) { rfb::Rect rect; rect.tl = rfb::Point(ringbuffer->rect1[i].left, ringbuffer->rect1[i].top); rect.br = rfb::Point(ringbuffer->rect1[i].right, ringbuffer->rect1[i].bottom); //Buffer coordinates rect.tl.x-=m_desktop->m_ScreenOffsetx; rect.br.x-=m_desktop->m_ScreenOffsetx; rect.tl.y-=m_desktop->m_ScreenOffsety; rect.br.y-=m_desktop->m_ScreenOffsety; //vnclog.Print(LL_INTERR, VNCLOG("REct %i %i %i %i \n"),rect.tl.x,rect.br.x,rect.tl.y,rect.br.y); rect = rect.intersect(m_desktop->m_Cliprect); if (!rect.is_empty()) { returnvalue=true; rgncache.assign_union(rect); } } if (ringbuffer->type[i]==2 || ringbuffer->type[i]==4) { /*if (MyGetCursorInfo) { MyCURSORINFO cinfo; cinfo.cbSize=sizeof(MyCURSORINFO); MyGetCursorInfo(&cinfo); m_desktop->SetCursor(cinfo.hCursor); //vnclog.Print(LL_INTERR, VNCLOG("Cursor %i \n"),cinfo.hCursor); }*/ } } } g_Oldcounter=counter; return returnvalue; }
void vncDesktopThread::do_polling(HANDLE& threadHandle, rfb::Region2D& rgncache, int& fullpollcounter, bool cursormoved) { // POLL PROBLEM AREAS // We add specific areas of the screen to the region cache, // causing them to be fetched for processing. // if can_be_hooked==false, hooking is temp disabled, use polling if (m_desktop->SetHook && g_obIPC.listall()!=NULL && m_desktop->can_be_hooked) { DWORD dwTId(0); if (threadHandle==NULL) threadHandle = CreateThread(NULL, 0, hookwatch, this, 0, &dwTId); if (Handle_Ringbuffer(g_obIPC.listall(),rgncache)) return; } DWORD lTime = timeGetTime(); m_desktop->m_buffer.SetAccuracy(m_desktop->m_server->TurboMode() ? 8 : 4); if (cursormoved) m_lLastMouseMoveTime = lTime; if ((m_desktop->m_server->PollFullScreen() && !cursormoved) || (!m_desktop->can_be_hooked && !cursormoved)) { int timeSinceLastMouseMove = lTime - m_lLastMouseMoveTime; if (timeSinceLastMouseMove > 15) // 150 ms pause after a Mouse move { ++fullpollcounter; // THIS FUNCTION IS A PIG. It uses too much CPU on older machines (PIII, P4) if (m_desktop->FastDetectChanges(rgncache, m_desktop->GetSize(), 0, true)) capture=false; // force full screen scan every three seconds after the mouse stops moving if (fullpollcounter > 20) { rgncache.assign_union(m_desktop->m_Cliprect); fullpollcounter = 0; } } } HWND hWndToPoll = 0; if (m_desktop->m_server->PollForeground() || !m_desktop->can_be_hooked) { // Get the window rectangle for the currently selected window hWndToPoll = GetForegroundWindow(); if (hWndToPoll != NULL) PollWindow(rgncache, hWndToPoll); } if (m_desktop->m_server->PollUnderCursor() || !m_desktop->can_be_hooked) { // Find the mouse position POINT mousepos; if (GetCursorPos(&mousepos)) { mousepos.x=g_dpi.UnscaleX(mousepos.x); mousepos.y=g_dpi.UnscaleY(mousepos.y); // Find the window under the mouse HWND hwnd = WindowFromPoint(mousepos); // exclude the foreground window (done above) and desktop if (hwnd != NULL && hwnd != hWndToPoll && hwnd != GetDesktopWindow()) PollWindow(rgncache, hwnd); } } }
//////////////////////////////////////////////////////////////////////////////////// // Modif rdv@2002 - v1.1.x - videodriver void vncDesktopThread::copy_bitmaps_to_buffer(ULONG i,rfb::Region2D &rgncache,rfb::UpdateTracker &tracker) { rfb::Rect rect; int x = m_desktop->pchanges_buf->pointrect[i].rect.left; int w = m_desktop->pchanges_buf->pointrect[i].rect.right-m_desktop->pchanges_buf->pointrect[i].rect.left; int y = m_desktop->pchanges_buf->pointrect[i].rect.top; int h = m_desktop->pchanges_buf->pointrect[i].rect.bottom-m_desktop->pchanges_buf->pointrect[i].rect.top; //vnclog.Print(LL_INTINFO, VNCLOG("Driver ************* %i %i %i %i \n"),x,y,w,h); if (!ClipRect(&x, &y, &w, &h, m_desktop->m_bmrect.tl.x, m_desktop->m_bmrect.tl.y, m_desktop->m_bmrect.br.x-m_desktop->m_bmrect.tl.x, m_desktop->m_bmrect.br.y-m_desktop->m_bmrect.tl.y)) return; //vnclog.Print(LL_INTINFO, VNCLOG("Driver ************* %i %i %i %i \n"),x,y,w,h); rect.tl.x = x; rect.br.x = x+w; rect.tl.y = y; rect.br.y = y+h; switch(m_desktop->pchanges_buf->pointrect[i].type) { case SCREEN_SCREEN: { int dx=m_desktop->pchanges_buf->pointrect[i].point.x; int dy=m_desktop->pchanges_buf->pointrect[i].point.y; if (!m_screen_moved && (dx==0 || dy==0) ) { //// Fix in case !Cliprect int xx=x; int yy=y; int hh=h; int ww=w; if (ClipRect(&xx,&yy,&ww,&hh,m_desktop->m_bmrect.tl.x, m_desktop->m_bmrect.tl.y, m_desktop->m_bmrect.br.x-m_desktop->m_bmrect.tl.x, m_desktop->m_bmrect.br.y-m_desktop->m_bmrect.tl.y)) { rect.tl.x=xx; rect.tl.y=yy; rect.br.x=xx+ww; rect.br.y=yy+hh; rgncache.assign_union(rect); } ////////////////////// // Fix Eckerd x=x+dx;; y=y+dy;; if (!ClipRect(&x,&y,&w,&h,m_desktop->m_bmrect.tl.x, m_desktop->m_bmrect.tl.y, m_desktop->m_bmrect.br.x-m_desktop->m_bmrect.tl.x, m_desktop->m_bmrect.br.y-m_desktop->m_bmrect.tl.y)) return; ////////////////////// // Fix Eckerd rect.tl.x=x-dx; rect.tl.y=y-dy; rect.br.x=x+w-dx; rect.br.y=y+h-dy; rfb::Point delta = rfb::Point(-dx,-dy); rgncache.assign_union(rect); tracker.add_copied(rect, delta); // vnclog.Print(LL_INTINFO, VNCLOG("Copyrect \n")); } else { rgncache.assign_union(rect); } break; } case SOLIDFILL: case TEXTOUT: case BLEND: case TRANS: case PLG: case BLIT:; rgncache.assign_union(rect); break; default: break; } }
bool vncDesktopThread::handle_display_change(HANDLE& threadHandle, rfb::Region2D& rgncache, rfb::SimpleUpdateTracker& clipped_updates, rfb::ClippedUpdateTracker& updates) { if ((m_desktop->m_displaychanged || //WM_DISPLAYCHANGE !vncService::InputDesktopSelected() || //handle logon and screensaver desktops m_desktop->m_SWtoDesktop || //switch from SW to full desktop or visa versa m_desktop->m_hookswitch|| //hook change request m_desktop->asked_display!=m_desktop->m_buffer.GetDisplay() //monitor change request ) ) { // We need to wait until viewer has send if he support Size changes if (!m_server->All_clients_initialalized()) { Sleep(30); vnclog.Print(LL_INTERR, VNCLOG("Wait for viewer init \n")); } //logging if (m_desktop->m_displaychanged) vnclog.Print(LL_INTERR, VNCLOG("++++Screensize changed \n")); if (m_desktop->m_SWtoDesktop) vnclog.Print(LL_INTERR, VNCLOG("m_SWtoDesktop \n")); if (m_desktop->m_hookswitch) vnclog.Print(LL_INTERR, VNCLOG("m_hookswitch \n")); if (m_desktop->asked_display!=m_desktop->m_buffer.GetDisplay()) vnclog.Print(LL_INTERR, VNCLOG("desktop switch %i %i \n"),m_desktop->asked_display,m_desktop->m_buffer.GetDisplay()); if (!m_server->IsThereFileTransBusy()) if (!vncService::InputDesktopSelected()) vnclog.Print(LL_INTERR, VNCLOG("++++InputDesktopSelected \n")); BOOL screensize_changed=false; BOOL monitor_changed=false; rfbServerInitMsg oldscrinfo; //******************************************************* // Lock Buffers from here //******************************************************* { if (XRichCursorEnabled) m_server->UpdateCursorShape(); /// We lock all buffers,,and also back the client thread update mechanism omni_mutex_lock l(m_desktop->m_update_lock); #ifdef _DEBUG char szText[256]; sprintf(szText," ++++++ Mutex lock display changes\n"); OutputDebugString(szText); #endif // We remove all queue updates from the tracker m_server->Clear_Update_Tracker(); // Also clear the current updates rgncache.clear(); // Also clear the copy_rect updates clipped_updates.clear(); // TESTTESTTEST // Are all updates cleared....old updates could generate bounding errors // any other queues to clear ? Yep cursor positions m_desktop->m_cursorpos.tl.x=0; m_desktop->m_cursorpos.tl.y=0; m_desktop->m_cursorpos.br.x=0; m_desktop->m_cursorpos.br.y=0; //keep a copy of the old screen size, so we can check for changes later on oldscrinfo = m_desktop->m_scrinfo; if (m_desktop->asked_display!=m_desktop->m_buffer.GetDisplay()) { m_desktop->Checkmonitors(); m_desktop->asked_display=m_desktop->m_buffer.GetDisplay(); int old_monitor=m_desktop->current_monitor; m_desktop->current_monitor=1; if (m_desktop->asked_display==2 && m_desktop->nr_monitors>1) m_desktop->current_monitor=2; if (m_desktop->asked_display==3 && m_desktop->nr_monitors>1) m_desktop->current_monitor=3; vnclog.Print(LL_INTERR, VNCLOG("OLd Current mon %i %i \n"),old_monitor,m_desktop->current_monitor); if ( old_monitor!=m_desktop->current_monitor) monitor_changed=true; } //******************************************************* // Reinitialize buffers,color, etc // monitor change, for non driver, use another buffer //******************************************************* if (!m_server->IsThereFileTransBusy()) if (m_desktop->m_displaychanged || !vncService::InputDesktopSelected() || m_desktop->m_hookswitch || (monitor_changed && !m_desktop->m_videodriver)) { // Attempt to close the old hooks // shutdown(true) driver is reinstalled without shutdown,(shutdown need a 640x480x8 switch) vnclog.Print(LL_INTERR, VNCLOG("m_desktop->Shutdown")); monitor_changed=false; if (!m_desktop->Shutdown()) { vnclog.Print(LL_INTERR, VNCLOG("Shutdown KillAuthClients\n")); m_server->KillAuthClients(); return false; } bool fHookDriverWanted = (FALSE != m_desktop->m_hookdriver); Sleep(1000); vnclog.Print(LL_INTERR, VNCLOG("m_desktop->Startup")); if (m_desktop->Startup() != 0) { vnclog.Print(LL_INTERR, VNCLOG("Startup KillAuthClients\n")); m_server->KillAuthClients(); SetEvent(m_desktop->restart_event); return false; } if (m_desktop->m_videodriver) { if (!XRichCursorEnabled) m_desktop->m_videodriver->HardwareCursor(); else m_desktop->m_videodriver->NoHardwareCursor(); } m_server->SetScreenOffset(m_desktop->m_ScreenOffsetx,m_desktop->m_ScreenOffsety,m_desktop->nr_monitors); // sf@2003 - After a new Startup(), we check if the required video driver // is actually available. If not, we force hookdll // No need for m_hookswitch again because the driver is NOT available anyway. // All the following cases are now handled: // 1. Desktop thread starts with "Video Driver" checked and no video driver available... // -> HookDll forced (handled by the first InitHookSettings() after initial Startup() call // 2. Desktop Thread starts without "Video Driver" checked but available driver // then the user checks "Video Driver" -> Video Driver used // 3. Desktop thread starts with "Video Driver" and available driver used // Then driver is switched off (-> hookDll) // Then the driver is switched on again (-> hook driver used again) // 4. Desktop thread starts without "Video Driver" checked and no driver available // then the users checks "Video Driver" if (fHookDriverWanted && m_desktop->m_videodriver == NULL) { vnclog.Print(LL_INTERR, VNCLOG("m_videodriver == NULL \n")); m_desktop->SethookMechanism(true, false); // InitHookSettings() would work as well; } stop_hookwatch=true; vnclog.Print(LL_INTERR, VNCLOG("threadHandle \n")); if (threadHandle) { WaitForSingleObject( threadHandle, INFINITE ); CloseHandle(threadHandle); stop_hookwatch=false; threadHandle=NULL; } vnclog.Print(LL_INTERR, VNCLOG("threadHandle2 \n")); } //******************************************************* // end reinit //******************************************************* if ((m_desktop->m_scrinfo.framebufferWidth != oldscrinfo.framebufferWidth) || (m_desktop->m_scrinfo.framebufferHeight != oldscrinfo.framebufferHeight || m_desktop->m_SWtoDesktop==TRUE )) { screensize_changed=true; vnclog.Print(LL_INTINFO, VNCLOG("SCR: new screen format %dx%dx%d\n"), m_desktop->m_scrinfo.framebufferWidth, m_desktop->m_scrinfo.framebufferHeight, m_desktop->m_scrinfo.format.bitsPerPixel); } m_desktop->m_displaychanged = FALSE; m_desktop->m_hookswitch = FALSE; m_desktop->Hookdll_Changed = m_desktop->On_Off_hookdll; // Set the hooks again if necessary ! m_desktop->m_SWtoDesktop=FALSE; //**************************************************************************** //************* SCREEN SIZE CHANGED //**************************************************************************** if (screensize_changed) { vnclog.Print(LL_INTERR, VNCLOG("Size changed\n")); POINT CursorPos; m_desktop->SWinit(); m_desktop->GetQuarterSize(); GetCursorPos(&CursorPos); CursorPos.x=g_dpi.UnscaleX(CursorPos.x); CursorPos.y=g_dpi.UnscaleY(CursorPos.y); CursorPos.x -= m_desktop->m_ScreenOffsetx; CursorPos.y -= m_desktop->m_ScreenOffsety; m_desktop->m_cursorpos.tl = CursorPos; m_desktop->m_cursorpos.br = rfb::Point(GetSystemMetrics(SM_CXCURSOR), GetSystemMetrics(SM_CYCURSOR)).translate(CursorPos); m_server->SetSWOffset(m_desktop->m_SWOffsetx,m_desktop->m_SWOffsety); // Adjust the UpdateTracker clip region updates.set_clip_region(m_desktop->m_Cliprect); m_desktop->m_buffer.ClearCache(); } if (monitor_changed) { // we are using the driver, so a monitor change is a view change, like a special kind of single window // m_desktop->current_monitor is the new monitor we want to see // monitor size mymonitor[m_desktop->current_monitor-1] // m_SWOffset is used by the encoders to send the correct coordinates to the viewer // Cliprect, buffer coordinates m_desktop->m_SWOffsetx=m_desktop->mymonitor[m_desktop->current_monitor-1].offsetx-m_desktop->mymonitor[2].offsetx; m_desktop->m_SWOffsety=m_desktop->mymonitor[m_desktop->current_monitor-1].offsety-m_desktop->mymonitor[2].offsety; m_server->SetSWOffset(m_desktop->m_SWOffsetx,m_desktop->m_SWOffsety); m_desktop->m_Cliprect.tl.x=m_desktop->mymonitor[m_desktop->current_monitor-1].offsetx-m_desktop->mymonitor[2].offsetx; m_desktop->m_Cliprect.tl.y=m_desktop->mymonitor[m_desktop->current_monitor-1].offsety-m_desktop->mymonitor[2].offsety; m_desktop->m_Cliprect.br.x=m_desktop->mymonitor[m_desktop->current_monitor-1].offsetx+ m_desktop->mymonitor[m_desktop->current_monitor-1].Width-m_desktop->mymonitor[2].offsetx; m_desktop->m_Cliprect.br.y=m_desktop->mymonitor[m_desktop->current_monitor-1].offsety+ m_desktop->mymonitor[m_desktop->current_monitor-1].Height-m_desktop->mymonitor[2].offsety; vnclog.Print(LL_INTERR, VNCLOG("***********###############************ %i %i %i %i %i %i\n"),m_desktop->m_SWOffsetx,m_desktop->m_SWOffsety ,m_desktop->m_Cliprect.tl.x,m_desktop->m_Cliprect.tl.y,m_desktop->m_Cliprect.br.x,m_desktop->m_Cliprect.br.y); rgncache.assign_union(rfb::Region2D(m_desktop->m_Cliprect)); updates.set_clip_region(m_desktop->m_Cliprect); m_desktop->m_buffer.ClearCache(); m_desktop->m_buffer.BlackBack(); } m_desktop->m_buffer.ClearCache(); m_desktop->m_buffer.BlackBack(); InvalidateRect(NULL,NULL,TRUE); rgncache.assign_union(rfb::Region2D(m_desktop->m_Cliprect)); if (memcmp(&m_desktop->m_scrinfo.format, &oldscrinfo.format, sizeof(rfbPixelFormat)) != 0) { vnclog.Print(LL_INTERR, VNCLOG("Format changed\n")); m_server->UpdatePalette(false); // changed no lock ok m_server->UpdateLocalFormat(false); // changed no lock ok } if (screensize_changed) { screensize_changed=false; m_server->SetNewSWSize(m_desktop->m_scrinfo.framebufferWidth,m_desktop->m_scrinfo.framebufferHeight,FALSE);//changed no lock ok m_server->SetScreenOffset(m_desktop->m_ScreenOffsetx,m_desktop->m_ScreenOffsety,m_desktop->nr_monitors);// no lock ok } if (monitor_changed) { monitor_changed=false; m_server->SetNewSWSize(m_desktop->mymonitor[m_desktop->current_monitor-1].Width,m_desktop->mymonitor[m_desktop->current_monitor-1].Height,TRUE); //changed no lock ok } #ifdef _DEBUG //char szText[256]; sprintf(szText," ++++++ Mutex unlock display changes\n"); OutputDebugString(szText); #endif }// end lock } return true; }
// Modif rdv@2002 - v1.1.x - videodriver BOOL vncDesktopThread::handle_driver_changes(rfb::Region2D &rgncache,rfb::UpdateTracker &tracker) { omni_mutex_lock l(m_desktop->m_videodriver_lock); int oldaantal=m_desktop->m_videodriver->oldaantal; int counter=m_desktop->pchanges_buf->counter; // int nr_updates=m_desktop->pchanges_buf->pointrect[0].type; // vnclog.Print(LL_INTERR, VNCLOG("updates, rects %i\n"),oldaantal-counter); if (oldaantal==counter) return FALSE; if (counter<1 || counter >1999) return FALSE; // m_desktop->pchanges_buf->pointrect[0].type=0; if (!m_server->SingleWindow()) m_screen_moved=m_desktop->CalcCopyRects(tracker); else m_screen_moved=true; /// HEITE01E // buffer was overloaded, so we use the bounding rect /* if (nr_updates>2000) { rfb::Rect rect; int x = m_desktop->pchanges_buf->pointrect[0].rect.left; int w = m_desktop->pchanges_buf->pointrect[0].rect.right-m_desktop->pchanges_buf->pointrect[0].rect.left; int y = m_desktop->pchanges_buf->pointrect[0].rect.top; int h = m_desktop->pchanges_buf->pointrect[0].rect.bottom-m_desktop->pchanges_buf->pointrect[0].rect.top; if (ClipRect(&x, &y, &w, &h, m_desktop->m_bmrect.tl.x, m_desktop->m_bmrect.tl.y, m_desktop->m_bmrect.br.x-m_desktop->m_bmrect.tl.x, m_desktop->m_bmrect.br.y-m_desktop->m_bmrect.tl.y)) { rect.tl.x = x; rect.br.x = x+w; rect.tl.y = y; rect.br.y = y+h; rgncache=rgncache.union_(rect); m_desktop->m_videodriver->oldaantal=counter; } return TRUE; }*/ if (m_server->SingleWindow()) m_screen_moved=true; if (oldaantal<counter) { for (int i =oldaantal+1; i<=counter;i++) { copy_bitmaps_to_buffer(i,rgncache,tracker); } } else { int i = 0; for (i =oldaantal+1;i<MAXCHANGES_BUF;i++) { copy_bitmaps_to_buffer(i,rgncache,tracker); } for (i=1;i<=counter;i++) { copy_bitmaps_to_buffer(i,rgncache,tracker); } } // vnclog.Print(LL_INTINFO, VNCLOG("Nr rects %i \n"),rgncache.Numrects()); m_desktop->m_videodriver->oldaantal=counter; // A lot updates left after combining // This generates an overflow // We expand each single update to minimum 32x32 if (rgncache.Numrects()>150) { rfb::Region2D rgntemp; rfb::RectVector rects; rfb::RectVector::iterator i; rgncache.get_rects(rects, 1, 1); for (i = rects.begin(); i != rects.end(); i++) { rfb::Rect rect = *i; rect.tl.x=rect.tl.x/32*32; rect.tl.y=rect.tl.y/32*32; rect.br.x=rect.br.x/32*32+32; rect.br.y=rect.br.y/32*32+32; if (rect.br.x>m_desktop->m_bmrect.br.x) rect.br.x=m_desktop->m_bmrect.br.x; if (rect.br.y>m_desktop->m_bmrect.br.y) rect.br.y=m_desktop->m_bmrect.br.y; rgntemp.assign_union(rect); } //Still to many little updates //Use the bounding rectangle for updates if (rgntemp.Numrects()>50) { Rect brect=rgntemp.get_bounding_rect(); rgncache.clear(); rgncache.assign_union(brect); } else { rgncache.clear(); rgncache.assign_union(rgntemp); } } return TRUE; }