From 3b8109daecc1c12359d27896686ff63b7ec03a22 Mon Sep 17 00:00:00 2001 From: Denis Oliver Kropp Date: Thu, 21 Oct 2010 10:25:07 +0200 Subject: new update mechanism --- src/SourceWin32.cxx | 269 +++++++++++++++++++++++++++++++++------------------- 1 file changed, 171 insertions(+), 98 deletions(-) (limited to 'src/SourceWin32.cxx') diff --git a/src/SourceWin32.cxx b/src/SourceWin32.cxx index 1007e35..fd9a13c 100644 --- a/src/SourceWin32.cxx +++ b/src/SourceWin32.cxx @@ -3,17 +3,6 @@ namespace PluggIt { D_DEBUG_DOMAIN( PluggIt_SourceWin32, "PluggIt/SourceWin32", "PluggIt Source Win32" ); -#include "ScreenHooks.h" - -// Constants -const UINT RFB_SCREEN_UPDATE = RegisterWindowMessage("WinVNC.Update.DrawRect"); -const UINT RFB_COPYRECT_UPDATE = RegisterWindowMessage("WinVNC.Update.CopyRect"); -const UINT RFB_MOUSE_UPDATE = RegisterWindowMessage("WinVNC.Update.Mouse"); -const char szDesktopSink[] = "WinVNC desktop sink"; - -typedef BOOL (*SetHooksFn)(DWORD thread_id,UINT UpdateMsg,UINT CopyMsg,UINT MouseMsg,BOOL ddihook); - - class SourceWin32 extends Source, Runnable { private HINSTANCE m_hInstance; @@ -40,16 +29,10 @@ class SourceWin32 extends Source, Runnable private Updates m_updates; - private VIDEODRIVER m_driver; - private bool m_using_driver; - private pthread_mutex_t m_lock; private pthread_cond_t m_cond; - SetHooksFn SetHooks; - - public class Config extends Source::Config { friend class SourceWin32; @@ -61,23 +44,34 @@ class SourceWin32 extends Source, Runnable private WindowSelection m_selection; private std::string m_title; - private bool m_updating; - private bool m_use_driver; + private bool m_always_all; + private int m_interval_all; + private int m_interval_hot; public Config( WindowSelection selection, const std::string &title = std::string(), - bool updating = false, bool use_driver = true ) + bool always_all = false, int interval_all = 400, + int interval_hot = 100 ) { - m_selection = selection; - m_title = title; - m_updating = updating; - m_use_driver = use_driver; + m_selection = selection; + m_title = title; + m_always_all = always_all; + m_interval_all = interval_all; + m_interval_hot = interval_hot; } }; - public SourceWin32( View *view, const Config &config ) : Source( view, config ), m_updates(16) { + private const Config &m_config_win32; + + + public SourceWin32( View *view, const Config &config ) + : + Source( view, config ), + m_updates(16), + m_config_win32( config ) + { D_DEBUG_AT( PluggIt_SourceWin32, "%s( %p )\n", __FUNCTION__, view ); m_hInstance = GetModuleHandle( NULL ); @@ -119,7 +113,24 @@ class SourceWin32 extends Source, Runnable m_size.w = rect.right - rect.left; m_size.h = rect.bottom - rect.top; - queueUpdate( 0, 0, m_size.w - 1, m_size.h - 1 ); + +#define RECT_WIDTH 32 +#define RECT_HEIGHT 32 + + for (int y=0; y m_size.w - 1) + region.x2 = m_size.w - 1; + + if (region.y2 > m_size.h - 1) + region.y2 = m_size.h - 1; + + m_all_rects.push_back( DFBRectangle(region) ); + } + } + std::string t = getWindowTitle( m_window ); @@ -127,10 +138,6 @@ class SourceWin32 extends Source, Runnable D_INFO( "Source/Win32: Window %d,%d-%ux%u, name '%s'\n", m_position.x, m_position.y, m_size.w, m_size.h, t.c_str() ); - if (config.m_use_driver) - m_driver.VIDEODRIVER_start( m_position.x, m_position.y, m_size.w, m_size.h ); - - m_using_driver = m_driver.mypchangebuf != NULL; m_view->config( m_size ); @@ -219,45 +226,18 @@ class SourceWin32 extends Source, Runnable D_DEBUG_AT( PluggIt_SourceWin32, " -> %4d,%4d-%4dx%4d (%d regions, %d rectangles)\n", DFB_RECTANGLE_VALS_FROM_REGION( &bounding ), m_updates.num_regions(), rects.size() ); + /* + * (4) Update TV + */ + m_view->update( rects, (void*)((char*) m_pixels2 + m_pitch2 * (m_size.h - 1)), - m_pitch2 ); + m_updates.reset(); pthread_mutex_unlock( &m_lock ); - - - for (unsigned int i=0; iupdate( rects, (void*)((char*) m_pixels + m_pitch * (m_size.h - 1)), - m_pitch ); } } -/**********************************************************************************************************************/ - - private void queueUpdate( int x1, int y1, int x2, int y2 ) { - D_DEBUG_AT( PluggIt_SourceWin32, "%s( %d,%d-%dx%d )\n", __FUNCTION__, x1, y1, x2 - x1 + 1, y2 - y1 + 1 ); - - pthread_mutex_lock( &m_lock ); - - DFBRegion damage( x1, y1, x2, y2 ); - - m_updates.addRegion( damage ); - - pthread_cond_signal( &m_cond ); - - pthread_mutex_unlock( &m_lock ); - } - /**********************************************************************************************************************/ private static std::string getWindowTitle( HWND window ) { @@ -270,9 +250,6 @@ class SourceWin32 extends Source, Runnable return buf; } - -/**********************************************************************************************************************/ - class EnumContext { public const std::string &title; public HWND window; @@ -446,54 +423,150 @@ class SourceWin32 extends Source, Runnable /**********************************************************************************************************************/ - public virtual int MainLoop() { + private bool diffRect( const DFBRectangle_C &rect ) { + D_DEBUG_AT( PluggIt_SourceWin32, "(2) comparing %4d,%4d-%4dx%4d\n", + DFB_RECTANGLE_VALS( &rect ) ); - HMODULE hModule; - char szCurrentDir[MAX_PATH]; + DFBRegion region( rect ); - if (GetModuleFileName(NULL, szCurrentDir, MAX_PATH)) { - char* p = strrchr(szCurrentDir, '\\'); - if (p == NULL) return 0; - *p = '\0'; - strcat (szCurrentDir,"\\vnchooks.dll"); - } + for (int y = region.y1; y <= region.y2; y++) { + const u64 *p1 = (const u64*)( (const u8*)m_pixels + (m_size.h - 1 - y) * m_pitch ); + const u64 *p2 = (const u64*)( (const u8*)m_pixels2 + (m_size.h - 1 - y) * m_pitch2 ); - hModule = LoadLibrary( szCurrentDir ); - if (!hModule) - throw new Exception( "Failed to load vnchooks.dll!" ); + for (int x = region.x1/2; x <= region.x2/2; x++) { + if (p1[x] != p2[x]) + return true; + } + } - SetHooks = (SetHooksFn) GetProcAddress( hModule, "SetHooks" ); + return false; + } + private vector m_all_rects; + private vector m_hot_rects; - if (!SetHooks( - GetCurrentThreadId(), - RFB_SCREEN_UPDATE, - RFB_COPYRECT_UPDATE, - RFB_MOUSE_UPDATE, false - )) - throw new Exception( "Failed to set hooks!" ); + public virtual int MainLoop() { + long long last_all = 0; + while (true) { + bool all = true; + const vector *copy_rects; - MSG msg; + if (m_config_win32.m_always_all) { + usleep( m_config_win32.m_interval_all * 1000 ); - printf( " -> RFB_SCREEN_UPDATE = %u\n", RFB_SCREEN_UPDATE ); - printf( " -> RFB_COPYRECT_UPDATE = %u\n", RFB_COPYRECT_UPDATE ); + copy_rects = &m_all_rects; + } + else { + long long this_time = direct_clock_get_abs_millis(); - while (WaitMessage()/*GetMessage( &msg, 0, 0, 0 )*/) { - printf( " -> Dispatching event (id %u)...\n", msg.message ); + if (this_time - last_all >= m_config_win32.m_interval_all) { + last_all = this_time; - if (PeekMessage(&msg, NULL, NULL, NULL, PM_REMOVE)) { - if (msg.message == RFB_SCREEN_UPDATE) { - queueUpdate( (SHORT)LOWORD(msg.wParam), - (SHORT)HIWORD(msg.wParam), - (SHORT)LOWORD(msg.lParam) - 1, - (SHORT)HIWORD(msg.lParam) - 1 ); + copy_rects = &m_all_rects; } else { - TranslateMessage( &msg ); - DispatchMessage( &msg ); + if (m_hot_rects.empty()) { + usleep( 20000 ); + continue; + } + else + usleep( m_config_win32.m_interval_hot * 1000 ); + + copy_rects = &m_hot_rects; + + all = false; } } + + /* + * (1) Copy from desktop to bitmap + */ + if (all) { + D_DEBUG_AT( PluggIt_SourceWin32, "(1) copying all %4d,%4d-%4dx%4d\n", + 0, 0, m_size.w, m_size.h ); + + BitBlt( m_bitmap_dc, + 0, + 0, + m_size.w, + m_size.h, + m_window_dc, + 0, + 0, + SRCCOPY ); + } + else { + Updates copy( 32 ); + + for (unsigned int i=0; isize(); i++) { + copy.addRegion( DFBRegion(copy_rects->at(i)) ); + } + + vector rects; + + copy.GetRectangles( rects ); + + + for (unsigned int i=0; i diff_rects; + + for (unsigned int i=0; isize(); i++) { + if (diffRect( copy_rects->at(i) )) { + diff_rects.push_back( copy_rects->at(i) ); + } + } + + /* + * (3) Copy from bitmap to bitmap2 + */ + pthread_mutex_lock( &m_lock ); + + for (unsigned int i=0; i EXIT!\n" ); -- cgit