summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Oliver Kropp <dok@directfb.org>2010-10-21 10:25:07 +0200
committerDenis Oliver Kropp <dok@directfb.org>2010-10-21 10:25:07 +0200
commit3b8109daecc1c12359d27896686ff63b7ec03a22 (patch)
tree3b7e995d2bcd4aa393128c4b0a07cc1ffa40d163
parentc172b4f8aa3731dd4cf7ae9886c73262c045205e (diff)
downloadpluggit-3b8109daecc1c12359d27896686ff63b7ec03a22.tar.gz
pluggit-3b8109daecc1c12359d27896686ff63b7ec03a22.tar.bz2
pluggit-3b8109daecc1c12359d27896686ff63b7ec03a22.zip
new update mechanism
-rw-r--r--src/Main.cxx129
-rw-r--r--src/Options.cxx42
-rw-r--r--src/SourceWin32.cxx269
-rw-r--r--src/classes.h3
4 files changed, 314 insertions, 129 deletions
diff --git a/src/Main.cxx b/src/Main.cxx
index 20e7d2c..0fb9fc0 100644
--- a/src/Main.cxx
+++ b/src/Main.cxx
@@ -3,23 +3,37 @@ namespace PluggIt {
D_DEBUG_DOMAIN( PluggIt_Main, "PluggIt/Main", "PluggIt Main" );
D_DEBUG_DOMAIN( PluggIt_View, "PluggIt/View", "PluggIt View" );
+#define NOTRCSOURCEMASK 0x20
+#define HK_REMOTEAPP DIKS_CUSTOM97
+
+
class Main extends View, Runnable
{
class Config {
public DFBDimension m_size;
public DFBPoint m_offset;
public DFBDimension m_resolution;
+ public DFBLocation m_destination;
public DFBSurfacePixelFormat m_format;
public std::string m_title;
public bool m_interactive;
- public bool m_updating;
- public bool m_use_driver;
+ public bool m_always_all;
+ public long m_interval_all;
+ public long m_interval_hot;
+ public long m_focus_timeout;
public Config() :
m_format(DSPF_UNKNOWN),
m_interactive(false),
- m_updating(false)
+ m_always_all(false),
+ m_interval_all(400),
+ m_interval_hot(100),
+ m_focus_timeout(0)
{
+ m_destination.x = 0.0f;
+ m_destination.y = 0.0f;
+ m_destination.w = 1.0f;
+ m_destination.h = 1.0f;
}
};
@@ -43,21 +57,29 @@ class Main extends View, Runnable
private bool m_view_visible;
private DFBSurfacePixelFormat m_view_format;
+ private u8 m_opacity;
+
+ private IDiVine *m_divine;
+
public Main() :
m_source(NULL),
- m_view_visible(false)
+ m_view_visible(false),
+ m_opacity(255)
{
D_DEBUG_AT( PluggIt_Main, "%s()\n", __FUNCTION__ );
m_options.addOption( new Options::OptionDimension( "-s", "--size", "<width>x<height>", "Size of view", m_config.m_size ) );
m_options.addOption( new Options::OptionPoint ( "-o", "--offset", "<x>,<y>", "Offset of view", m_config.m_offset ) );
m_options.addOption( new Options::OptionDimension( "-r", "--resolution", "<X>x<Y>", "Resolution of view", m_config.m_resolution ) );
+ m_options.addOption( new Options::OptionLocation ( "-d", "--destination", "<x>,<y>-<w>x<h>", "Destination location", m_config.m_destination ) );
m_options.addOption( new Options::OptionFormat ( "-f", "--format", "<pixelformat>", "Pixel format of view", m_config.m_format ) );
m_options.addOption( new Options::OptionString ( "-t", "--title", "<string>", "Title of window to show", m_config.m_title ) );
m_options.addOption( new Options::OptionBool ( "-i", "--interactive", "", "Use interactive window picking", m_config.m_interactive ) );
- m_options.addOption( new Options::OptionBool ( "-u", "--updating", "", "Update continuously", m_config.m_updating ) );
- m_options.addOption( new Options::OptionBool ( "-d", "--driver", "", "Use driver mode", m_config.m_use_driver ) );
+ m_options.addOption( new Options::OptionBool ( "-a", "--all", "", "Always all", m_config.m_always_all ) );
+ m_options.addOption( new Options::OptionLong ( "-A", "--inter-all", "<ms>", "Interval all", m_config.m_interval_all ) );
+ m_options.addOption( new Options::OptionLong ( "-H", "--inter-hot", "<ms>", "Interval hot", m_config.m_interval_hot ) );
+ m_options.addOption( new Options::OptionLong ( "-F", "--focus", "<seconds>", "Focus timeout", m_config.m_focus_timeout ) );
}
public void main( int argc, char *argv[] ) {
@@ -71,7 +93,29 @@ class Main extends View, Runnable
return;
initDFB();
- initSource();
+
+
+ DiVineCreate( &m_divine );
+
+#ifdef __WIN32__
+ SourceWin32::Config config( m_config.m_interactive ?
+ SourceWin32::Config::WINDOW_SELECTION_INTERACTIVE :
+ (m_config.m_title.size() > 0 ?
+ SourceWin32::Config::WINDOW_SELECTION_TITLE :
+ SourceWin32::Config::WINDOW_SELECTION_NONE), m_config.m_title,
+ m_config.m_always_all, m_config.m_interval_all, m_config.m_interval_hot );
+
+ m_source = new SourceWin32( this, config );
+#else
+ SourceX11::Config config( m_config.m_interactive ?
+ SourceX11::Config::WINDOW_SELECTION_INTERACTIVE :
+ (m_config.m_title.size() > 0 ?
+ SourceX11::Config::WINDOW_SELECTION_TITLE :
+ SourceX11::Config::WINDOW_SELECTION_NONE), m_config.m_title );
+
+ m_source = new SourceX11( this, config );
+#endif
+
Thread *thread = new Thread( this, "Main" );
@@ -115,7 +159,19 @@ class Main extends View, Runnable
up = true;
case DWET_KEYDOWN:
- key = CKeySend::MapDfbKeyEventToVK( event->key_symbol );
+ if (event->key_symbol == DIKS_0 && !up) {
+ m_opacity = (m_opacity == 255 ? 0 : 255);
+ m_window.SetOpacity( m_opacity );
+ }
+ else
+ key = CKeySend::MapDfbKeyEventToVK( event->key_symbol );
+ break;
+
+ case DWET_LOSTFOCUS:
+ if (m_config.m_focus_timeout) {
+ sleep( m_config.m_focus_timeout );
+ hk_SendKey( HK_REMOTEAPP, 0, 0, 1 );
+ }
break;
default:
@@ -143,29 +199,6 @@ class Main extends View, Runnable
m_events = m_dfb.CreateEventBuffer();
}
- private void initSource() {
- D_DEBUG_AT( PluggIt_Main, "%s()\n", __FUNCTION__ );
-
-#ifdef __WIN32__
- SourceWin32::Config config( m_config.m_interactive ?
- SourceWin32::Config::WINDOW_SELECTION_INTERACTIVE :
- (m_config.m_title.size() > 0 ?
- SourceWin32::Config::WINDOW_SELECTION_TITLE :
- SourceWin32::Config::WINDOW_SELECTION_NONE), m_config.m_title,
- m_config.m_updating, m_config.m_use_driver );
-
- m_source = new SourceWin32( this, config );
-#else
- SourceX11::Config config( m_config.m_interactive ?
- SourceX11::Config::WINDOW_SELECTION_INTERACTIVE :
- (m_config.m_title.size() > 0 ?
- SourceX11::Config::WINDOW_SELECTION_TITLE :
- SourceX11::Config::WINDOW_SELECTION_NONE), m_config.m_title );
-
- m_source = new SourceX11( this, config );
-#endif
- }
-
private void run() {
try {
m_source->MainLoop();
@@ -271,6 +304,14 @@ class Main extends View, Runnable
m_view_format = m_surface.GetPixelFormat();
m_window.AttachEventBuffer( m_events );
+
+
+ DFBWindowGeometry geometry;
+
+ geometry.mode = DWGM_LOCATION;
+ geometry.location = m_config.m_destination;
+
+ m_window.SetDstGeometry( &geometry );
}
m_view_size = size;
@@ -466,6 +507,32 @@ class Main extends View, Runnable
m_view_visible = true;
}
}
+
+ void
+ hk_SendKey( int keyname,
+ int src,
+ int sys,
+ int cmd )
+ {
+ if (m_divine) {
+ DFBResult ret;
+ DFBInputEvent event;
+
+ src |= NOTRCSOURCEMASK;
+
+ event.clazz = DFEC_INPUT;
+ event.type = DIET_KEYPRESS;
+ event.key_code = (((unsigned int)src & 0xff) << 24) | (((unsigned int)sys & 0xff) << 16) | ((unsigned int)cmd & 0xffff);
+ event.key_symbol = (DFBInputDeviceKeySymbol)keyname;
+ event.flags = (DFBInputEventFlags)(DIEF_KEYCODE | DIEF_KEYSYMBOL);
+
+ ret = m_divine->SendEvent( m_divine, &event );
+ if (ret)
+ D_DERROR( (DirectResult) ret, "IDiVine::SendEvent() failed!\n" );
+ }
+ else
+ D_ERROR( "IDiVine interface is null!\n" );
+ }
};
}
diff --git a/src/Options.cxx b/src/Options.cxx
index 27e8924..f68b0f3 100644
--- a/src/Options.cxx
+++ b/src/Options.cxx
@@ -196,6 +196,48 @@ class Options
}
};
+ public class OptionRectangle extends Option {
+ private DFBRectangle &m_value;
+
+ public OptionRectangle( const char *short_name,
+ const char *long_name,
+ const char *arg_name,
+ const char *arg_desc,
+ DFBRectangle &value ) : Option( short_name, long_name, arg_name, arg_desc ), m_value( value )
+ {
+ }
+
+ public virtual bool Parse( const char *arg ) {
+ if (sscanf( arg, "%d,%d-%dx%d", &m_value.x, &m_value.y, &m_value.w, &m_value.h ) != 4) {
+ D_ERROR( "Option/Rectangle: Invalid argument to '%s' or '%s'!\n", m_short_name, m_long_name );
+ return false;
+ }
+
+ return true;
+ }
+ };
+
+ public class OptionLocation extends Option {
+ private DFBLocation &m_value;
+
+ public OptionLocation( const char *short_name,
+ const char *long_name,
+ const char *arg_name,
+ const char *arg_desc,
+ DFBLocation &value ) : Option( short_name, long_name, arg_name, arg_desc ), m_value( value )
+ {
+ }
+
+ public virtual bool Parse( const char *arg ) {
+ if (sscanf( arg, "%f,%f-%fx%f", &m_value.x, &m_value.y, &m_value.w, &m_value.h ) != 4) {
+ D_ERROR( "Option/Location: Invalid argument to '%s' or '%s'!\n", m_short_name, m_long_name );
+ return false;
+ }
+
+ return true;
+ }
+ };
+
private vector<Option*> m_options;
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.h; y+=RECT_HEIGHT) {
+ for (int x=0; x<m_size.w; x+=RECT_WIDTH) {
+ DFBRegion region( x, y, x + RECT_WIDTH - 1, y + RECT_HEIGHT - 1 );
+
+ if (region.x2 > 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,47 +226,20 @@ 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; i<rects.size(); i++) {
- BitBlt( m_bitmap_dc,
- rects[i].x,
- rects[i].y,
- rects[i].w,
- rects[i].h,
- m_window_dc,
- rects[i].x,
- rects[i].y,
- SRCCOPY );
- }
-
-
- m_view->update( 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 ) {
char buf[1024] = { 0 };
@@ -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<DFBRectangle_C> m_all_rects;
+ private vector<DFBRectangle_C> 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<DFBRectangle_C> *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; i<copy_rects->size(); i++) {
+ copy.addRegion( DFBRegion(copy_rects->at(i)) );
+ }
+
+ vector<DFBRectangle_C> rects;
+
+ copy.GetRectangles( rects );
+
+
+ for (unsigned int i=0; i<rects.size(); i++) {
+ D_DEBUG_AT( PluggIt_SourceWin32, "(1) copying %4d,%4d-%4dx%4d\n",
+ DFB_RECTANGLE_VALS( &rects[i] ) );
+
+ BitBlt( m_bitmap_dc,
+ rects[i].x,
+ rects[i].y,
+ rects[i].w,
+ rects[i].h,
+ m_window_dc,
+ rects[i].x,
+ rects[i].y,
+ SRCCOPY );
+ }
+ }
+
+ /*
+ * (2) Build list of difference rectangles
+ */
+ vector<DFBRectangle_C> diff_rects;
+
+ for (unsigned int i=0; i<copy_rects->size(); 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<diff_rects.size(); i++) {
+ D_DEBUG_AT( PluggIt_SourceWin32, "(3) copying %4d,%4d-%4dx%4d\n",
+ DFB_RECTANGLE_VALS( &diff_rects[i] ) );
+
+ BitBlt( m_bitmap_dc2,
+ diff_rects[i].x,
+ diff_rects[i].y,
+ diff_rects[i].w,
+ diff_rects[i].h,
+ m_bitmap_dc,
+ diff_rects[i].x,
+ diff_rects[i].y,
+ SRCCOPY );
+
+ m_updates.addRegion( diff_rects[i] );
+ }
+
+ pthread_cond_signal( &m_cond );
+
+ pthread_mutex_unlock( &m_lock );
+
+
+ /*
+ * Update hot rectangles
+ */
+ if (all)
+ m_hot_rects = diff_rects;
}
printf( " -> EXIT!\n" );
diff --git a/src/classes.h b/src/classes.h
index 8f81e90..2d8228b 100644
--- a/src/classes.h
+++ b/src/classes.h
@@ -28,6 +28,9 @@ extern "C" {
#include <direct/util.h>
#include <gfx/convert.h>
+
+
+#include <divine.h>
}