summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Clock.cxx32
-rw-r--r--src/Exception.cxx59
-rw-r--r--src/Exception.h18
-rw-r--r--src/FPS.cxx43
-rw-r--r--src/Main.cxx415
-rw-r--r--src/Makefile.am38
-rw-r--r--src/Makefile.in545
-rw-r--r--src/Makefile.win62
-rw-r--r--src/Options.cxx275
-rw-r--r--src/OutOfMemoryException.cxx10
-rw-r--r--src/Random.cxx11
-rw-r--r--src/Runnable.cxx9
-rw-r--r--src/Scaler.cxx170
-rw-r--r--src/ScreenHooks.h34
-rw-r--r--src/Source.cxx22
-rw-r--r--src/SourceWin32.cxx653
-rw-r--r--src/SourceX11.cxx534
-rw-r--r--src/Thread.cxx71
-rw-r--r--src/Updates.cxx78
-rw-r--r--src/View.cxx13
-rw-r--r--src/classes.cpp4047
-rw-r--r--src/classes.h64
-rwxr-xr-xsrc/gen_classes.sh33
-rw-r--r--src/main.c11
-rw-r--r--src/stretch_hvx_16.h469
-rw-r--r--src/stretch_hvx_32.h168
-rw-r--r--src/stretch_hvx_N.h42
-rw-r--r--src/stretch_up_down_16.h68
-rw-r--r--src/stretch_up_down_32.h68
-rw-r--r--src/stretch_up_down_table.h59
-rw-r--r--src/videodriver.cpp905
-rw-r--r--src/videodriver.h76
-rw-r--r--src/videodrivercheck.cpp154
33 files changed, 9256 insertions, 0 deletions
diff --git a/src/Clock.cxx b/src/Clock.cxx
new file mode 100644
index 0000000..bacf373
--- /dev/null
+++ b/src/Clock.cxx
@@ -0,0 +1,32 @@
+namespace PluggIt {
+
+class Clock
+{
+ private long long base;
+ private char str[20];
+
+ public Clock() {
+ Reset();
+ }
+
+ public void Reset() {
+ base = direct_clock_get_micros();
+ }
+
+ public float GetTime() {
+ return (direct_clock_get_micros() - base) / 1000000.0f;
+ }
+
+ public const char *GetString() {
+ float time = GetTime();
+ int seconds = (int) time;
+ int minutes = seconds / 60;
+
+ snprintf( str, sizeof(str), "%02d:%02d", minutes, seconds );
+
+ return str;
+ }
+};
+
+}
+
diff --git a/src/Exception.cxx b/src/Exception.cxx
new file mode 100644
index 0000000..2d19769
--- /dev/null
+++ b/src/Exception.cxx
@@ -0,0 +1,59 @@
+namespace PluggIt {
+
+class Exception
+{
+ private string m_message;
+
+
+ public Exception( string message ) {
+ m_message = message;
+ }
+
+ public Exception( const char *format, ... ) D_FORMAT_PRINTF(2) {
+ va_list args;
+ int len;
+ char buf[200];
+ char *ptr = buf;
+
+ va_start( args, format );
+ len = vsnprintf( buf, sizeof(buf), format, args );
+ va_end( args );
+
+ if (len < 0)
+ abort();
+
+ if (len >= (int)sizeof(buf)) {
+ ptr = (char*) malloc( len+1 );
+ if (!ptr)
+ abort();
+
+ va_start( args, format );
+ len = vsnprintf( ptr, len+1, format, args );
+ va_end( args );
+
+ if (len < 0) {
+ free( ptr );
+ abort();
+ }
+ }
+
+ m_message = string( ptr );
+
+ if (ptr != buf)
+ free( ptr );
+ }
+
+ public string getMessage() {
+ return m_message;
+ }
+
+
+ friend std::ostream &operator << (std::ostream &stream, Exception *ex) {
+ stream << ex->getMessage();
+
+ return stream;
+ }
+};
+
+}
+
diff --git a/src/Exception.h b/src/Exception.h
new file mode 100644
index 0000000..821f569
--- /dev/null
+++ b/src/Exception.h
@@ -0,0 +1,18 @@
+#include <string>
+
+namespace PluggIt {
+
+class Exception
+{
+public:
+ Exception( std::string message );
+
+ Exception( const char *format, ... ) D_FORMAT_PRINTF(2);
+
+ std::string getMessage();
+
+ friend std::ostream &operator << (std::ostream &stream, Exception *ex);
+};
+
+}
+
diff --git a/src/FPS.cxx b/src/FPS.cxx
new file mode 100644
index 0000000..3c0dd54
--- /dev/null
+++ b/src/FPS.cxx
@@ -0,0 +1,43 @@
+namespace PluggIt {
+
+class FPS
+{
+ private int frames;
+ private char str[20];
+
+ private Clock clock;
+
+
+ public FPS() {
+ Reset();
+ }
+
+ public void Reset() {
+ frames = 0;
+ str[0] = 0;
+
+ clock.Reset();
+ }
+
+ public void Count( float interval ) {
+ float time = clock.GetTime();
+
+ frames++;
+
+ if (time >= interval) {
+ float fps = frames / time;
+
+ snprintf( str, sizeof(str), "%.1f", fps );
+
+ frames = 0;
+ clock.Reset();
+ }
+ }
+
+ public const char *GetFPS() {
+ return str;
+ }
+};
+
+}
+
diff --git a/src/Main.cxx b/src/Main.cxx
new file mode 100644
index 0000000..10013d8
--- /dev/null
+++ b/src/Main.cxx
@@ -0,0 +1,415 @@
+namespace PluggIt {
+
+D_DEBUG_DOMAIN( PluggIt_Main, "PluggIt/Main", "PluggIt Main" );
+D_DEBUG_DOMAIN( PluggIt_View, "PluggIt/View", "PluggIt View" );
+
+class Main extends View
+{
+ class Config {
+ public DFBDimension m_size;
+ public DFBPoint m_offset;
+ public DFBDimension m_resolution;
+ public DFBSurfacePixelFormat m_format;
+ public std::string m_title;
+ public bool m_interactive;
+ public bool m_updating;
+ public bool m_use_driver;
+
+ public Config() :
+ m_format(DSPF_UNKNOWN),
+ m_interactive(false),
+ m_updating(false)
+ {
+ }
+ };
+
+
+ private Config m_config;
+ private Options m_options;
+ private Scaler m_scaler;
+
+ private IDirectFB m_dfb;
+ private IDirectFBDisplayLayer m_layer;
+ private IDirectFBWindow m_window;
+ private IDirectFBSurface m_surface;
+ private IDirectFBEventBuffer m_events;
+
+ private Source *m_source;
+
+ private DFBDimension m_source_resolution;
+
+ private DFBDimension m_view_size;
+ private DFBDimension m_view_resolution;
+ private bool m_view_visible;
+ private DFBSurfacePixelFormat m_view_format;
+
+
+ public Main() :
+ m_source(NULL),
+ m_view_visible(false)
+ {
+ 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::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 ) );
+ }
+
+ public void main( int argc, char *argv[] ) {
+ D_DEBUG_AT( PluggIt_Main, "%s()\n", __FUNCTION__ );
+
+ try {
+ /* Initialize DirectFB. */
+ DirectFB::Init( &argc, &argv );
+
+ if (!m_options.parseCommandLine( argc, argv ))
+ return;
+
+ initDFB();
+ initSource();
+
+ run();
+ }
+ catch (DFBException *e) {
+ cerr << endl;
+ cerr << "Caught exception!" << endl;
+ cerr << " ==> " << e << endl;
+ }
+ catch (Exception *e) {
+ cerr << endl;
+ cerr << "Caught exception!" << endl;
+ cerr << " ==> " << e << endl;
+ }
+ }
+
+ private void initDFB() {
+ D_DEBUG_AT( PluggIt_Main, "%s()\n", __FUNCTION__ );
+
+ /* Create the super interface. */
+ m_dfb = DirectFB::Create();
+
+ m_layer = m_dfb.GetDisplayLayer( DLID_PRIMARY );
+
+ 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() {
+ m_source->MainLoop();
+ }
+
+ public virtual void config( DFBDimension &source_resolution ) {
+ D_DEBUG_AT( PluggIt_View, "%s( %u, %u )\n", __FUNCTION__, source_resolution.w, source_resolution.h );
+
+ /* Ignore bogus events */
+ if (m_source_resolution == source_resolution) {
+ D_DEBUG_AT( PluggIt_View, " -> unchanged source size\n" );
+ return;
+ }
+
+ m_source_resolution = source_resolution;
+
+
+ /* Calculate view resolution */
+ DFBDimension resolution = m_config.m_resolution;
+
+ if (!resolution.w) {
+ if (!resolution.h) {
+ resolution = source_resolution;
+
+ D_DEBUG_AT( PluggIt_View, " -> no width/height\n" );
+ }
+ else {
+ resolution.w = resolution.h * source_resolution.w / source_resolution.h;
+
+ D_DEBUG_AT( PluggIt_View, " -> no width\n" );
+ }
+ }
+ else if (!resolution.h) {
+ resolution.h = resolution.w * source_resolution.h / source_resolution.w;
+
+ D_DEBUG_AT( PluggIt_View, " -> no height\n" );
+ }
+
+ D_DEBUG_AT( PluggIt_View, " -> resolution %ux%u\n", resolution.w, resolution.h );
+
+
+ /* Calculate view size */
+ DFBDimension size = m_config.m_size;
+
+ if (!size.w) {
+ if (!size.h) {
+ size = resolution;
+
+ D_DEBUG_AT( PluggIt_View, " -> no width/height\n" );
+ }
+ else {
+ size.w = size.h * resolution.w / resolution.h;
+
+ D_DEBUG_AT( PluggIt_View, " -> no width\n" );
+ }
+ }
+ else if (!size.h) {
+ size.h = size.w * resolution.h / resolution.w;
+
+ D_DEBUG_AT( PluggIt_View, " -> no height\n" );
+ }
+
+ D_DEBUG_AT( PluggIt_View, " -> %ux%u\n", size.w, size.h );
+
+
+ if (m_view_resolution == resolution)
+ D_DEBUG_AT( PluggIt_View, " -> unchanged view resolution\n" );
+
+ if (m_view_size == size) {
+ D_DEBUG_AT( PluggIt_View, " -> unchanged view size\n" );
+ return;
+ }
+
+ if (m_window)
+ m_window.Resize( size.w, size.h );
+ else {
+ /* Create the window. */
+ DFBWindowDescription desc;
+
+ desc.flags = (DFBWindowDescriptionFlags)( DWDESC_POSX | DWDESC_POSY |
+ DWDESC_WIDTH | DWDESC_HEIGHT | DWDESC_PIXELFORMAT );
+ desc.posx = 0;
+ desc.posy = 0;
+ desc.width = size.w;
+ desc.height = size.h;
+ desc.pixelformat = m_config.m_format;
+
+ m_window = m_layer.CreateWindow( desc );
+
+ m_surface = m_window.GetSurface();
+
+ m_view_format = m_surface.GetPixelFormat();
+
+ m_window.AttachEventBuffer( m_events );
+ }
+
+ m_view_size = size;
+ m_view_resolution = resolution;
+
+
+ D_DEBUG_AT( PluggIt_View, " -> view size %4ux%4u\n", m_view_size.w, m_view_size.h );
+ D_DEBUG_AT( PluggIt_View, " -> view resolution %4ux%4u\n", m_view_resolution.w, m_view_resolution.h );
+ D_DEBUG_AT( PluggIt_View, " -> source resolution %4ux%4u\n", m_source_resolution.w, m_source_resolution.h );
+ }
+
+ public virtual void update( const vector<DFBRectangle_C> &rects,
+ void *ptr,
+ int pitch )
+ {
+ unsigned int i;
+ DFBRegion clip( m_view_size );
+ const DFBPoint &offset = m_config.m_offset;
+ bool first = true;
+ DFBRegion flip;
+
+ D_DEBUG_AT( PluggIt_View, "%s( [%u], %p, %d )\n", __FUNCTION__, rects.size(), ptr, pitch );
+
+ D_ASSERT( rects.size() > 0 );
+ D_ASSERT( ptr != NULL );
+
+// m_dfb.WaitIdle();
+
+ if (m_source_resolution == m_view_resolution) {
+ D_DEBUG_AT( PluggIt_View, " -> unscaled %4dx%4d\n",
+ m_source_resolution.w, m_source_resolution.h );
+
+ if (m_view_format == DSPF_RGB16) {
+ int tp = ((m_view_size.w * 2) + 7) & ~7;
+ void *tmp = malloc( tp * m_view_size.h );
+
+ for (i=0; i<rects.size(); i++) {
+ D_DEBUG_AT( PluggIt_View, " -> [%2d] %4d,%4d-%4dx%4d (original)\n",
+ i, DFB_RECTANGLE_VALS( &rects[i] ) );
+
+ DFBRegion region( DFBRectangle(rects[i]) - offset );
+
+ D_DEBUG_AT( PluggIt_View, " -> %4d,%4d-%4dx%4d (translated)\n",
+ DFB_RECTANGLE_VALS_FROM_REGION( &region ) );
+
+ ptr = (void*)((char*) ptr + offset.x * 4 + offset.y * pitch);
+
+ /* Clip update against our resolution */
+ if (dfb_region_region_intersect( &region, &clip )) {
+ D_DEBUG_AT( PluggIt_View, " -> %4d,%4d-%4dx%4d (clipped update)\n",
+ DFB_RECTANGLE_VALS_FROM_REGION( &region ) );
+
+ DFBRectangle rect( region );
+
+ dfb_convert_to_rgb16( DSPF_RGB32,
+ (void*)((char*) ptr + rect.x * 4 + rect.y * pitch), pitch,
+ m_view_size.h, (u16*) tmp, tp, rect.w, rect.h );
+
+ m_surface.Write( (char*) tmp + DFB_BYTES_PER_LINE( m_view_format, region.x1 ) + region.y1 * tp, tp, &rect );
+
+ if (first) {
+ first = false;
+ flip = region;
+ }
+ else
+ flip.unionWith( region );
+ //m_surface.Flip( &region );
+ }
+ }
+
+ free( tmp );
+ }
+ else {
+ for (i=0; i<rects.size(); i++) {
+ D_DEBUG_AT( PluggIt_View, " -> [%2d] %4d,%4d-%4dx%4d (original)\n",
+ i, DFB_RECTANGLE_VALS( &rects[i] ) );
+
+ DFBRegion region( DFBRectangle(rects[i]) - offset );
+
+ D_DEBUG_AT( PluggIt_View, " -> %4d,%4d-%4dx%4d (translated)\n",
+ DFB_RECTANGLE_VALS_FROM_REGION( &region ) );
+
+ ptr = (void*)((char*) ptr + offset.x * 4 + offset.y * pitch);
+
+ /* Clip update against our resolution */
+ if (dfb_region_region_intersect( &region, &clip )) {
+ D_DEBUG_AT( PluggIt_View, " -> %4d,%4d-%4dx%4d (clipped update)\n",
+ DFB_RECTANGLE_VALS_FROM_REGION( &region ) );
+
+ DFBRectangle rect( region );
+
+ if (m_view_format == DSPF_ARGB) {
+ u32 *p = (u32*)((char*) ptr + rect.x * 4 + rect.y * pitch);
+
+ for (int y=0; y<rect.h; y++) {
+ for (int x=0; x<rect.w; x++)
+ p[x] |= 0xff000000;
+
+ p = (u32*)((char*) p + pitch);
+ }
+ }
+
+ D_DEBUG_AT( PluggIt_View, " -> Write...\n" );
+ m_surface.Write( (char*) ptr + DFB_BYTES_PER_LINE( m_view_format, region.x1 ) + region.y1 * pitch, pitch, &rect );
+ D_DEBUG_AT( PluggIt_View, " -> Write done.\n" );
+
+ if (first) {
+ first = false;
+ flip = region;
+ }
+ else
+ flip.unionWith( region );
+ //m_surface.Flip( &region );
+ }
+ }
+ }
+ }
+ else {
+ int tp = ((m_view_size.w * 4) + 7) & ~7;
+ void *tmp = malloc( tp * m_view_size.h );
+
+ D_DEBUG_AT( PluggIt_View, " -> scaled %4dx%4d => %4dx%4d\n",
+ m_source_resolution.w, m_source_resolution.h,
+ m_view_resolution.w, m_view_resolution.h );
+
+ for (i=0; i<rects.size(); i++) {
+ D_DEBUG_AT( PluggIt_View, " -> [%2d] %4d,%4d-%4dx%4d (original)\n",
+ i, DFB_RECTANGLE_VALS( &rects[i] ) );
+
+ DFBRegion region( DFBRectangle(rects[i]) - offset );
+
+ D_DEBUG_AT( PluggIt_View, " -> %4d,%4d-%4dx%4d (translated)\n",
+ DFB_RECTANGLE_VALS_FROM_REGION( &region ) );
+
+ ptr = (void*)((char*) ptr + offset.x * 4 + offset.y * pitch);
+
+ /* Transform source updates to view resolution */
+ region.x1 = region.x1 * m_view_resolution.w / m_source_resolution.w;
+ region.y1 = region.y1 * m_view_resolution.h / m_source_resolution.h;
+ region.x2 = region.x2 * m_view_resolution.w / m_source_resolution.w;
+ region.y2 = region.y2 * m_view_resolution.h / m_source_resolution.h;
+
+ if (region.x1 > 0)
+ region.x1--;
+
+ if (region.y1 > 0)
+ region.y1--;
+
+ if (region.x2 < m_view_resolution.w-1)
+ region.x2++;
+ if (region.x2 < m_view_resolution.w-1)
+ region.x2++;
+
+ if (region.y2 < m_view_resolution.h-1)
+ region.y2++;
+ if (region.y2 < m_view_resolution.h-1)
+ region.y2++;
+
+ D_DEBUG_AT( PluggIt_View, " -> %4d,%4d-%4dx%4d (scaled)\n",
+ DFB_RECTANGLE_VALS_FROM_REGION( &region ) );
+
+ /* Clip update against our resolution */
+ if (dfb_region_region_intersect( &region, &clip )) {
+ D_DEBUG_AT( PluggIt_View, " -> %4d,%4d-%4dx%4d (clipped)\n",
+ DFB_RECTANGLE_VALS_FROM_REGION( &region ) );
+
+ DFBRectangle rect( region );
+
+ m_scaler.scale( m_view_format, tmp, tp, ptr, pitch,
+ m_source_resolution.w, m_source_resolution.h,
+ m_view_resolution.w, m_view_resolution.h, region );
+
+ m_surface.Write( (char*) tmp + DFB_BYTES_PER_LINE( m_view_format, region.x1 ) + region.y1 * tp, tp, &rect );
+
+ if (first) {
+ first = false;
+ flip = region;
+ }
+ else
+ flip.unionWith( region );
+ //m_surface.Flip( &region );
+ }
+ }
+
+ free( tmp );
+ }
+
+ m_surface.Flip( &flip );
+
+ if (!m_view_visible) {
+ m_window.SetOpacity( 0xff );
+
+ m_view_visible = true;
+ }
+ }
+};
+
+}
+
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644
index 0000000..9cee335
--- /dev/null
+++ b/src/Makefile.am
@@ -0,0 +1,38 @@
+## Makefile.am for PluggIt/src
+
+AM_CPPFLAGS = -DDATADIR=\"@DATADIR@/\"
+
+INCLUDES = @DFB_CFLAGS@
+LDADD = @DFB_LIBS@ -lX11 -lXext -lXdamage
+
+bin_PROGRAMS = pluggit
+
+pluggit_SOURCES = \
+ classes.cpp
+
+pluggit_LDADD = $(LDADD)
+
+CLASSES = \
+ Exception.cxx \
+ OutOfMemoryException.cxx \
+ \
+ Clock.cxx \
+ FPS.cxx \
+ Options.cxx \
+ Random.cxx \
+ Updates.cxx \
+ \
+ Runnable.cxx \
+ Thread.cxx \
+ \
+ Scaler.cxx \
+ \
+ View.cxx \
+ Source.cxx \
+ SourceX11.cxx \
+ \
+ Main.cxx
+
+classes.cpp: $(CLASSES) *.h Makefile gen_classes.sh main.c
+ ./gen_classes.sh $(CLASSES) > classes.cpp
+
diff --git a/src/Makefile.in b/src/Makefile.in
new file mode 100644
index 0000000..90a45f1
--- /dev/null
+++ b/src/Makefile.in
@@ -0,0 +1,545 @@
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+bin_PROGRAMS = pluggit$(EXEEXT)
+subdir = src
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__installdirs = "$(DESTDIR)$(bindir)"
+PROGRAMS = $(bin_PROGRAMS)
+am_pluggit_OBJECTS = classes.$(OBJEXT)
+pluggit_OBJECTS = $(am_pluggit_OBJECTS)
+am__DEPENDENCIES_1 =
+pluggit_DEPENDENCIES = $(am__DEPENDENCIES_1)
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+CXXLD = $(CXX)
+CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(pluggit_SOURCES)
+DIST_SOURCES = $(pluggit_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATADIR = @DATADIR@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DFB_CFLAGS = @DFB_CFLAGS@
+DFB_LIBS = @DFB_LIBS@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+lt_ECHO = @lt_ECHO@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+AM_CPPFLAGS = -DDATADIR=\"@DATADIR@/\"
+INCLUDES = @DFB_CFLAGS@
+LDADD = @DFB_LIBS@ -lX11 -lXext -lXdamage
+pluggit_SOURCES = \
+ classes.cpp
+
+pluggit_LDADD = $(LDADD)
+CLASSES = \
+ Exception.cxx \
+ OutOfMemoryException.cxx \
+ \
+ Clock.cxx \
+ FPS.cxx \
+ Options.cxx \
+ Random.cxx \
+ Updates.cxx \
+ \
+ Runnable.cxx \
+ Thread.cxx \
+ \
+ Scaler.cxx \
+ \
+ View.cxx \
+ Source.cxx \
+ SourceX11.cxx \
+ \
+ Main.cxx
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .cpp .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+install-binPROGRAMS: $(bin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)"
+ @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed 's/$(EXEEXT)$$//' | \
+ while read p p1; do if test -f $$p || test -f $$p1; \
+ then echo "$$p"; echo "$$p"; else :; fi; \
+ done | \
+ sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \
+ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
+ sed 'N;N;N;s,\n, ,g' | \
+ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
+ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+ if ($$2 == $$4) files[d] = files[d] " " $$1; \
+ else { print "f", $$3 "/" $$4, $$1; } } \
+ END { for (d in files) print "f", d, files[d] }' | \
+ while read type dir files; do \
+ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+ test -z "$$files" || { \
+ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \
+ } \
+ ; done
+
+uninstall-binPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
+ files=`for p in $$list; do echo "$$p"; done | \
+ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
+ -e 's/$$/$(EXEEXT)/' `; \
+ test -n "$$list" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(bindir)" && rm -f $$files
+
+clean-binPROGRAMS:
+ @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+pluggit$(EXEEXT): $(pluggit_OBJECTS) $(pluggit_DEPENDENCIES)
+ @rm -f pluggit$(EXEEXT)
+ $(CXXLINK) $(pluggit_OBJECTS) $(pluggit_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/classes.Po@am__quote@
+
+.cpp.o:
+@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $<
+
+.cpp.obj:
+@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.cpp.lo:
+@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(PROGRAMS)
+installdirs:
+ for dir in "$(DESTDIR)$(bindir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am: install-binPROGRAMS
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-binPROGRAMS
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \
+ clean-generic clean-libtool ctags distclean distclean-compile \
+ distclean-generic distclean-libtool distclean-tags distdir dvi \
+ dvi-am html html-am info info-am install install-am \
+ install-binPROGRAMS install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+ pdf pdf-am ps ps-am tags uninstall uninstall-am \
+ uninstall-binPROGRAMS
+
+
+classes.cpp: $(CLASSES) *.h Makefile gen_classes.sh main.c
+ ./gen_classes.sh $(CLASSES) > classes.cpp
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/Makefile.win b/src/Makefile.win
new file mode 100644
index 0000000..8205892
--- /dev/null
+++ b/src/Makefile.win
@@ -0,0 +1,62 @@
+## Makefile.am for PluggIt/src
+
+DFB = /cygdrive/c/DirectFB
+PPDFB = /cygdrive/c/++DFB
+
+INCLUDES = -I. \
+ -I$(DFB)/include \
+ -I$(DFB)/lib \
+ -I$(DFB)/src \
+ -I$(PPDFB)/include
+
+CPPFLAGS = \
+ -D__WIN32__
+
+LDADD = \
+ $(DFB)/proxy/dispatcher/*.o \
+ $(DFB)/proxy/requestor/*.o \
+ -lppdfb -ldirectfb -lvoodoo -lfusion -ldirect \
+ -lgdi32 -luser32 -lversion
+ #-lX11 -lXext -lXdamage -lXfixes
+
+all: /tmp/pluggit
+
+OBJECTS = \
+ classes.o \
+ videodriver.o \
+ videodrivercheck.o
+
+/tmp/pluggit: $(OBJECTS)
+ $(CXX) $+ $(LDADD) -o /tmp/pluggit
+
+.cpp.o:
+ $(CXX) -o $@ -c $< $(INCLUDES) $(CPPFLAGS)
+
+
+CLASSES = \
+ Exception.cxx \
+ OutOfMemoryException.cxx \
+ \
+ Clock.cxx \
+ FPS.cxx \
+ Options.cxx \
+ Random.cxx \
+ Updates.cxx \
+ \
+ Runnable.cxx \
+ Thread.cxx \
+ \
+ Scaler.cxx \
+ \
+ View.cxx \
+ Source.cxx \
+ SourceWin32.cxx \
+ \
+ Main.cxx
+
+
+export CPPFLAGS
+
+classes.cpp: $(CLASSES) *.h Makefile.win gen_classes.sh main.c
+ ./gen_classes.sh $(CLASSES) > classes.cpp
+
diff --git a/src/Options.cxx b/src/Options.cxx
new file mode 100644
index 0000000..27e8924
--- /dev/null
+++ b/src/Options.cxx
@@ -0,0 +1,275 @@
+namespace PluggIt {
+
+static const DirectFBPixelFormatNames(m_formats);
+
+class Options
+{
+ class Option {
+ friend class Options;
+
+ protected const char *m_short_name;
+ protected const char *m_long_name;
+ protected const char *m_arg_name;
+ protected const char *m_arg_desc;
+ protected bool m_need_arg;
+
+ public Option( const char *short_name,
+ const char *long_name,
+ const char *arg_name,
+ const char *arg_desc )
+ {
+ m_short_name = short_name;
+ m_long_name = long_name;
+ m_arg_name = arg_name;
+ m_arg_desc = arg_desc;
+ m_need_arg = true;
+ }
+
+ public virtual bool Parse( const char *arg ) = 0;
+ };
+
+ public class OptionBool extends Option {
+ private bool &m_value;
+
+ public OptionBool( const char *short_name,
+ const char *long_name,
+ const char *arg_name,
+ const char *arg_desc,
+ bool &value ) : Option( short_name, long_name, arg_name, arg_desc ), m_value( value )
+ {
+ m_need_arg = false;
+ }
+
+ public virtual bool Parse( const char *arg ) {
+ m_value = true;
+
+ return true;
+ }
+ };
+
+ public class OptionLong extends Option {
+ private long &m_value;
+ private int m_base;
+
+ public OptionLong( const char *short_name,
+ const char *long_name,
+ const char *arg_name,
+ const char *arg_desc,
+ long &value,
+ int base = 10 ) : Option( short_name, long_name, arg_name, arg_desc ), m_value( value )
+ {
+ m_base = base;
+ }
+
+ public virtual bool Parse( const char *arg ) {
+ long ret;
+ char *end;
+
+ ret = strtol( arg, &end, m_base );
+
+ if (*end) {
+ D_ERROR( "Option/Long: Invalid argument to '%s' or '%s'!\n", m_short_name, m_long_name );
+ return false;
+ }
+
+ m_value = ret;
+
+ return true;
+ }
+ };
+
+ public class OptionULong extends Option {
+ private unsigned long &m_value;
+ private int m_base;
+
+ public OptionULong( const char *short_name,
+ const char *long_name,
+ const char *arg_name,
+ const char *arg_desc,
+ unsigned long &value,
+ int base = 10 ) : Option( short_name, long_name, arg_name, arg_desc ), m_value( value )
+ {
+ m_base = base;
+ }
+
+ public virtual bool Parse( const char *arg ) {
+ unsigned long ret;
+ char *end;
+
+ ret = strtoul( arg, &end, m_base );
+
+ if (*end) {
+ D_ERROR( "Option/ULong: Invalid argument to '%s' or '%s'!\n", m_short_name, m_long_name );
+ return false;
+ }
+
+ m_value = ret;
+
+ return true;
+ }
+ };
+
+ public class OptionFormat extends Option {
+ private DFBSurfacePixelFormat &m_value;
+
+ public OptionFormat( const char *short_name,
+ const char *long_name,
+ const char *arg_name,
+ const char *arg_desc,
+ DFBSurfacePixelFormat &value ) : Option( short_name, long_name, arg_name, arg_desc ), m_value( value )
+ {
+ }
+
+ public virtual bool Parse( const char *arg ) {
+ unsigned int i;
+
+ for (i=0; i<D_ARRAY_SIZE(m_formats); i++) {
+ if (!strcasecmp( m_formats[i].name, arg )) {
+ m_value = m_formats[i].format;
+
+ return true;
+ }
+ }
+
+ D_ERROR( "Option/Format: Unknown format '%s' passed to '%s' or '%s'!\n", arg, m_short_name, m_long_name );
+
+ return false;
+ }
+ };
+
+ public class OptionString extends Option {
+ private std::string &m_value;
+
+ public OptionString( const char *short_name,
+ const char *long_name,
+ const char *arg_name,
+ const char *arg_desc,
+ std::string &value ) : Option( short_name, long_name, arg_name, arg_desc ), m_value( value )
+ {
+ }
+
+ public virtual bool Parse( const char *arg ) {
+ m_value = arg;
+ return true;
+ }
+ };
+
+ public class OptionPoint extends Option {
+ private DFBPoint &m_value;
+
+ public OptionPoint( const char *short_name,
+ const char *long_name,
+ const char *arg_name,
+ const char *arg_desc,
+ DFBPoint &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", &m_value.x, &m_value.y ) != 2) {
+ D_ERROR( "Option/Point: Invalid argument to '%s' or '%s'!\n", m_short_name, m_long_name );
+ return false;
+ }
+
+ return true;
+ }
+ };
+
+ public class OptionDimension extends Option {
+ private DFBDimension &m_value;
+
+ public OptionDimension( const char *short_name,
+ const char *long_name,
+ const char *arg_name,
+ const char *arg_desc,
+ DFBDimension &value ) : Option( short_name, long_name, arg_name, arg_desc ), m_value( value )
+ {
+ }
+
+ public virtual bool Parse( const char *arg ) {
+ if (sscanf( arg, "%dx%d", &m_value.w, &m_value.h ) != 2) {
+ D_ERROR( "Option/Dimension: Invalid argument to '%s' or '%s'!\n", m_short_name, m_long_name );
+ return false;
+ }
+
+ return true;
+ }
+ };
+
+
+
+ private vector<Option*> m_options;
+
+ public void addOption( Option *option ) {
+ m_options.push_back( option );
+ }
+
+ public bool parseCommandLine( int argc, char *argv[] ) {
+ int n;
+
+ for (n = 1; n < argc; n++) {
+ bool ok = false;
+ const char *arg = argv[n];
+
+ if (strcmp (arg, "-h") == 0 || strcmp (arg, "--help") == 0) {
+ printUsage (argv[0]);
+ return false;
+ }
+
+ if (strcmp (arg, "-v") == 0 || strcmp (arg, "--version") == 0) {
+// fprintf (stderr, "dfbscreen version %s\n", DIRECTFB_VERSION);
+ return false;
+ }
+
+ vector<Option*>::iterator itr = m_options.begin();
+
+ for (; itr != m_options.end(); itr++) {
+ Option *option = *itr;
+
+ if (!strcmp (arg, option->m_short_name) || !strcmp (arg, option->m_long_name)) {
+ if (option->m_need_arg && ++n == argc) {
+ printUsage (argv[0]);
+ return false;
+ }
+
+ if (!option->Parse( argv[n] ))
+ return false;
+
+ ok = true;
+
+ break;
+ }
+ }
+
+ if (!ok) {
+ printUsage (argv[0]);
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ public void printUsage( const char *prg_name ) {
+ //fprintf (stderr, "\nDirectFB Screen Configuration (version %s)\n\n", DIRECTFB_VERSION);
+ fprintf (stderr, "Usage: %s [options]\n\n", prg_name);
+ fprintf (stderr, "Options:\n");
+ fprintf (stderr, " -h --help Show this help message\n");
+ fprintf (stderr, " -v --version Print version information\n");
+
+
+ vector<Option*>::const_iterator itr = m_options.begin();
+
+ for (; itr != m_options.end(); itr++) {
+ const Option *option = *itr;
+
+ fprintf( stderr, " %-3s %-16s %-12s %s\n",
+ option->m_short_name, option->m_long_name, option->m_arg_name, option->m_arg_desc );
+ }
+
+ fprintf( stderr, "\n" );
+ }
+};
+
+}
+
diff --git a/src/OutOfMemoryException.cxx b/src/OutOfMemoryException.cxx
new file mode 100644
index 0000000..9fee368
--- /dev/null
+++ b/src/OutOfMemoryException.cxx
@@ -0,0 +1,10 @@
+namespace PluggIt {
+
+class OutOfMemoryException extends Exception
+{
+ public OutOfMemoryException() : Exception( "Out of memory!" ) {
+ }
+};
+
+}
+
diff --git a/src/Random.cxx b/src/Random.cxx
new file mode 100644
index 0000000..62c53a3
--- /dev/null
+++ b/src/Random.cxx
@@ -0,0 +1,11 @@
+namespace PluggIt {
+
+class Random
+{
+ public static float nextFloat( float min, float max ) {
+ return min + rand() * (max - min) / (float) RAND_MAX;
+ }
+};
+
+}
+
diff --git a/src/Runnable.cxx b/src/Runnable.cxx
new file mode 100644
index 0000000..5a5bed8
--- /dev/null
+++ b/src/Runnable.cxx
@@ -0,0 +1,9 @@
+namespace PluggIt {
+
+class Runnable
+{
+ public virtual void run() = 0;
+};
+
+}
+
diff --git a/src/Scaler.cxx b/src/Scaler.cxx
new file mode 100644
index 0000000..9e9af3c
--- /dev/null
+++ b/src/Scaler.cxx
@@ -0,0 +1,170 @@
+namespace PluggIt {
+
+D_DEBUG_DOMAIN( PluggIt_Scaler, "PluggIt/Scaler", "PluggIt Scaler" );
+
+
+typedef struct {
+ DFBRegion clip;
+ const void *colors;
+ unsigned long protect;
+ unsigned long key;
+} StretchCtx;
+
+typedef void (*StretchHVx)( void *dst,
+ int dpitch,
+ const void *src,
+ int spitch,
+ int width,
+ int height,
+ int dst_width,
+ int dst_height,
+ const StretchCtx *ctx );
+
+#define STRETCH_NONE 0
+#define STRETCH_SRCKEY 1
+#define STRETCH_PROTECT 2
+#define STRETCH_SRCKEY_PROTECT 3
+#define STRETCH_NUM 4
+
+#define PIXEL_RGB16(r,g,b) ( (((r)&0xF8) << 8) | \
+ (((g)&0xFC) << 3) | \
+ (((b)&0xF8) >> 3) )
+
+/**********************************************************************************************************************/
+/*** 16 bit RGB 565 scalers *******************************************************************************************/
+/**********************************************************************************************************************/
+
+#define DST_FORMAT DSPF_RGB16
+#define TABLE_NAME stretch_hvx_RGB16
+#define FUNC_NAME(UPDOWN,K,P,F) stretch_hvx_RGB16_ ## UPDOWN ## _ ## K ## P ## _ ## F
+#define SHIFT_R5 5
+#define SHIFT_R6 6
+#define X_F81F 0xf81f
+#define X_07E0 0x07e0
+#define MASK_RGB 0xffff
+
+#define FORMAT_RGB16
+#include "stretch_up_down_16.h"
+#undef FORMAT_RGB16
+
+#undef DST_FORMAT
+#undef TABLE_NAME
+#undef FUNC_NAME
+#undef SHIFT_R5
+#undef SHIFT_R6
+#undef X_F81F
+#undef X_07E0
+#undef MASK_RGB
+
+/**********************************************************************************************************************/
+/*** 32 bit RGB 8888 scalers ******************************************************************************************/
+/**********************************************************************************************************************/
+
+#define DST_FORMAT DSPF_ARGB
+#define TABLE_NAME stretch_hvx_ARGB
+#define FUNC_NAME(UPDOWN,K,P,F) stretch_hvx_ARGB_ ## UPDOWN ## _ ## K ## P ## _ ## F
+#define SHIFT_R8 8
+#define SHIFT_L8 8
+#define X_00FF00FF 0x00ff00ff
+#define X_FF00FF00 0xff00ff00
+#define MASK_RGB 0x00ffffff
+
+#define FORMAT_ARGB
+#include "stretch_up_down_32.h"
+#undef FORMAT_ARGB
+
+#undef DST_FORMAT
+#undef TABLE_NAME
+#undef FUNC_NAME
+#undef SHIFT_R8
+#undef SHIFT_L8
+#undef X_00FF00FF
+#undef X_FF00FF00
+#undef MASK_RGB
+
+/**********************************************************************************************************************/
+/*** 32 bit RGB 8888 scalers ******************************************************************************************/
+/**********************************************************************************************************************/
+
+#define DST_FORMAT DSPF_RGB32
+#define TABLE_NAME stretch_hvx_RGB32
+#define FUNC_NAME(UPDOWN,K,P,F) stretch_hvx_RGB32_ ## UPDOWN ## _ ## K ## P ## _ ## F
+#define SHIFT_R8 8
+#define SHIFT_L8 8
+#define X_00FF00FF 0x00ff00ff
+#define X_FF00FF00 0x0000ff00
+#define MASK_RGB 0x00ffffff
+
+#define FORMAT_RGB32
+#include "stretch_up_down_32.h"
+#undef FORMAT_RGB32
+
+#undef DST_FORMAT
+#undef TABLE_NAME
+#undef FUNC_NAME
+#undef SHIFT_R8
+#undef SHIFT_L8
+#undef X_00FF00FF
+#undef X_FF00FF00
+#undef MASK_RGB
+
+
+class Scaler
+{
+
+ public Scaler() {
+ }
+
+ public void scale( DFBSurfacePixelFormat format,
+ void *dst,
+ int dpitch,
+ const void *src,
+ int spitch,
+ int width,
+ int height,
+ int dst_width,
+ int dst_height,
+ const DFBRegion &clip )
+ {
+ D_DEBUG_AT( PluggIt_Scaler, "%s( %s, %p [%d], %p [%d], %dx%d -> %dx%d, clip %4d,%4d-%4dx%4d )\n",
+ __FUNCTION__, dfb_pixelformat_name( format ), dst, dpitch, src, spitch, width, height,
+ dst_width, dst_height, DFB_RECTANGLE_VALS_FROM_REGION( &clip ) );
+
+
+ StretchCtx ctx;
+
+ ctx.clip = clip;
+
+ switch (format) {
+ case DSPF_RGB16:
+ if (width <= dst_width || height <= dst_height)
+ stretch_hvx_RGB16_up____DSPF_RGB32( dst, dpitch, src, spitch, width, height, dst_width, dst_height, &ctx );
+ else
+ stretch_hvx_RGB16_down____DSPF_RGB32( dst, dpitch, src, spitch, width, height, dst_width, dst_height, &ctx );
+ break;
+
+ case DSPF_RGB32:
+ if (width <= dst_width || height <= dst_height)
+ stretch_hvx_RGB32_up____DSPF_RGB32( dst, dpitch, src, spitch, width, height, dst_width, dst_height, &ctx );
+ else
+ stretch_hvx_RGB32_down____DSPF_RGB32( dst, dpitch, src, spitch, width, height, dst_width, dst_height, &ctx );
+ break;
+
+ case DSPF_ARGB:
+ if (width <= dst_width || height <= dst_height)
+ stretch_hvx_ARGB_up____DSPF_RGB32( dst, dpitch, src, spitch, width, height, dst_width, dst_height, &ctx );
+ else
+ stretch_hvx_ARGB_down____DSPF_RGB32( dst, dpitch, src, spitch, width, height, dst_width, dst_height, &ctx );
+ break;
+
+ default:
+ D_UNIMPLEMENTED();
+ break;
+ }
+ }
+};
+
+
+
+}
+
diff --git a/src/ScreenHooks.h b/src/ScreenHooks.h
new file mode 100644
index 0000000..ea40b6b
--- /dev/null
+++ b/src/ScreenHooks.h
@@ -0,0 +1,34 @@
+// Copyright (C) 2008, 2009, 2010 GlavSoft LLC.
+// All rights reserved.
+//
+//-------------------------------------------------------------------------
+// This file is part of the TightVNC software. Please visit our Web site:
+//
+// http://www.tightvnc.com/
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//-------------------------------------------------------------------------
+//
+
+#ifndef __SCREENHOOKS_H__
+#define __SCREENHOOKS_H__
+
+extern "C"
+{
+ __declspec(dllexport) bool setHook(HWND targedWinHwnd);
+ __declspec(dllexport) bool unsetHook();
+}
+
+#endif
diff --git a/src/Source.cxx b/src/Source.cxx
new file mode 100644
index 0000000..871e796
--- /dev/null
+++ b/src/Source.cxx
@@ -0,0 +1,22 @@
+namespace PluggIt {
+
+class Source
+{
+ protected class Config {
+ protected Config() {}
+ };
+
+
+ protected View *m_view;
+ protected const Config &m_config;
+
+ public Source( View *view, const Config &config ) : m_config(config) {
+ m_view = view;
+ }
+
+
+ public virtual int MainLoop() = 0;
+};
+
+}
+
diff --git a/src/SourceWin32.cxx b/src/SourceWin32.cxx
new file mode 100644
index 0000000..25ac45b
--- /dev/null
+++ b/src/SourceWin32.cxx
@@ -0,0 +1,653 @@
+namespace PluggIt {
+
+D_DEBUG_DOMAIN( PluggIt_SourceWin32, "PluggIt/SourceWin32", "PluggIt Source Win32" );
+
+
+#include "ScreenHooks.h"
+
+const UINT specIpcCode = RegisterWindowMessage("HOOK.MESSAGE.CODE");
+
+
+class SourceWin32 extends Source, Runnable
+{
+ private HINSTANCE m_hInstance;
+
+ private HWND m_root;
+ private HWND m_window;
+
+ private DFBPoint m_position;
+ private DFBDimension m_size;
+
+ private HBITMAP m_bitmap;
+ private void *m_pixels;
+ private int m_pitch;
+
+ private HBITMAP m_bitmap2;
+ private void *m_pixels2;
+ private int m_pitch2;
+
+ private HDC m_window_dc;
+ private HDC m_bitmap_dc;
+ private HDC m_bitmap_dc2;
+
+ private Thread *m_thread;
+
+ 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;
+
+
+ public class Config extends Source::Config {
+ friend class SourceWin32;
+
+ public typedef enum {
+ WINDOW_SELECTION_NONE,
+ WINDOW_SELECTION_TITLE,
+ WINDOW_SELECTION_INTERACTIVE
+ } WindowSelection;
+
+ private WindowSelection m_selection;
+ private std::string m_title;
+ private bool m_updating;
+ private bool m_use_driver;
+
+
+ public Config( WindowSelection selection,
+ const std::string &title = std::string(),
+ bool updating = false, bool use_driver = true )
+ {
+ m_selection = selection;
+ m_title = title;
+ m_updating = updating;
+ m_use_driver = use_driver;
+ }
+ };
+
+
+ public SourceWin32( View *view, const Config &config ) : Source( view, config ), m_updates(16) {
+ D_DEBUG_AT( PluggIt_SourceWin32, "%s( %p )\n", __FUNCTION__, view );
+
+ m_hInstance = GetModuleHandle( NULL );
+
+ D_DEBUG_AT( PluggIt_SourceWin32, " -> hInstance %p\n", m_hInstance );
+
+
+ m_root = GetDesktopWindow();
+
+ switch (config.m_selection) {
+ case Config::WINDOW_SELECTION_NONE:
+ m_window = m_root;
+ break;
+
+ case Config::WINDOW_SELECTION_TITLE:
+ m_window = findWindow( config.m_title );
+ if (m_window == 0)
+ throw new Exception( "Could not find window with title containing '%s'\n", config.m_title.c_str() );
+ break;
+
+ case Config::WINDOW_SELECTION_INTERACTIVE:
+ pickWindow();
+ if (m_window == 0)
+ throw new Exception( "Could not interactively pick a window\n" );
+ break;
+
+ default:
+ throw new Exception( "Invalid window selection method\n" );
+ }
+
+
+ RECT rect;
+
+ GetClientRect( m_window, &rect );
+
+ m_position.x = rect.left;
+ m_position.y = rect.top;
+
+ 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 );
+
+
+ std::string t = getWindowTitle( m_window );
+
+ 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 );
+
+
+ m_window_dc = GetDC( m_window );
+ m_bitmap_dc = CreateCompatibleDC( m_window_dc );
+ m_bitmap_dc2 = CreateCompatibleDC( m_window_dc );
+
+
+ BITMAPINFO bitmap_info = {{
+ biSize: sizeof(BITMAPINFOHEADER),
+ biWidth: m_size.w,
+ biHeight: m_size.h,
+ biPlanes: 1,
+ biBitCount: 32,
+ biCompression: BI_RGB,
+ biSizeImage: 0,
+ biXPelsPerMeter: 0,
+ biYPelsPerMeter: 0,
+ biClrUsed: 0,
+ biClrImportant: 0,
+ }};
+
+ m_bitmap = CreateDIBSection( m_window_dc, &bitmap_info, DIB_RGB_COLORS, &m_pixels, NULL, 0 );
+ m_bitmap2 = CreateDIBSection( m_window_dc, &bitmap_info, DIB_RGB_COLORS, &m_pixels2, NULL, 0 );
+
+
+ BITMAP bitmap;
+
+ GetObject( m_bitmap, sizeof(BITMAP), &bitmap );
+
+ m_pitch = bitmap.bmWidthBytes;
+
+ GetObject( m_bitmap2, sizeof(BITMAP), &bitmap );
+
+ m_pitch2 = bitmap.bmWidthBytes;
+
+
+ SelectObject( m_bitmap_dc, m_bitmap );
+ SelectObject( m_bitmap_dc2, m_bitmap2 );
+
+
+ pthread_mutex_init( &m_lock, NULL );
+ pthread_cond_init( &m_cond, NULL );
+
+
+ if (!m_using_driver) {
+ HWND w;
+
+ WNDCLASSEX wndClass;
+
+ ZeroMemory( &wndClass, sizeof(wndClass) );
+
+ wndClass.cbSize = sizeof(wndClass);
+ wndClass.style = CS_HREDRAW | CS_VREDRAW;
+ wndClass.lpfnWndProc = MsgWndProc;
+ wndClass.cbClsExtra = 0;
+ wndClass.cbWndExtra = 0;
+ wndClass.hInstance = GetModuleHandle(NULL);
+ wndClass.hIcon = NULL;
+ wndClass.hIconSm = NULL;
+ wndClass.hCursor = LoadCursor( NULL, IDC_UPARROW );
+ wndClass.hbrBackground = (HBRUSH) GetStockObject( NULL_BRUSH );
+ wndClass.lpszMenuName = NULL;
+ wndClass.lpszClassName = "MsgWindow";
+
+ if (!RegisterClassEx( &wndClass ))
+ throw new Exception( "RegisterClassEx() failed!" );
+
+
+ w = CreateWindowEx( 0,
+ "MsgWindow",
+ "MsgWindow",
+ WS_POPUP,// | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_BORDER,
+ CW_USEDEFAULT,
+ CW_USEDEFAULT,
+ 1,
+ 1,
+ NULL,
+ NULL,
+ GetModuleHandle(NULL),
+ this );
+
+ if (!setHook( w ))
+ throw new Exception( "Failed to set hooks!" );
+ }
+
+
+ /* Create the thread object. */
+ m_thread = new Thread( this, "SourceWin32" );
+
+ m_thread->start();
+ }
+
+ virtual ~SourceWin32() {
+ m_thread->interrupt();
+ m_thread->join();
+ delete m_thread;
+
+ pthread_mutex_destroy( &m_lock );
+ pthread_cond_destroy( &m_cond );
+
+ DeleteDC( m_window_dc );
+ DeleteDC( m_bitmap_dc );
+ DeleteDC( m_bitmap_dc2 );
+
+ DeleteObject( m_bitmap );
+ DeleteObject( m_bitmap2 );
+ }
+
+ private void addRect( const RECT &rect ) {
+ if (rect.left >= rect.right)
+ return;
+
+ if (rect.top >= rect.bottom)
+ return;
+
+ DFBRegion region( rect.left,
+ rect.top,
+ rect.right - 1,
+ rect.bottom - 1 );
+
+ m_updates.addRegion( region );
+ }
+
+ private void run() {
+ if (m_using_driver) {
+ D_ASSERT( m_driver.mypchangebuf != NULL );
+
+ unsigned int counter = m_driver.mypchangebuf->counter;
+ unsigned int i;
+
+ long long last_time = direct_clock_get_abs_millis();
+
+ D_DEBUG_AT( PluggIt_SourceWin32, "%s()\n", __FUNCTION__ );
+
+ while (!m_thread->isInterrupted()) {
+ if (m_driver.mypchangebuf->counter < 1 ||
+ m_driver.mypchangebuf->counter >= MAXCHANGES_BUF ||
+ counter == m_driver.mypchangebuf->counter)
+ usleep( 10000 );
+
+ if (counter != m_driver.mypchangebuf->counter) {
+ D_DEBUG_AT( PluggIt_SourceWin32, " -> counter: %d -> %d\n", counter, m_driver.mypchangebuf->counter );
+
+ if (counter < m_driver.mypchangebuf->counter) {
+ for (i=counter+1; i<=m_driver.mypchangebuf->counter; i++) {
+ addRect( m_driver.mypchangebuf->pointrect[i].rect );
+ }
+ }
+ else if (counter > m_driver.mypchangebuf->counter) {
+ for (i=counter+1; i<MAXCHANGES_BUF; i++) {
+ addRect( m_driver.mypchangebuf->pointrect[i].rect );
+ }
+ for (i=1; i<=m_driver.mypchangebuf->counter; i++) {
+ addRect( m_driver.mypchangebuf->pointrect[i].rect );
+ }
+ }
+
+ counter = m_driver.mypchangebuf->counter;
+ }
+
+ if (direct_clock_get_abs_millis() - last_time > 2000) {
+ DFBRegion region( 0,
+ 0,
+ m_size.w - 1,
+ m_size.h - 1 );
+
+ m_updates.addRegion( region );
+
+ last_time = direct_clock_get_abs_millis();
+ }
+
+ if (m_updates.num_regions() > 0) {
+ vector<DFBRectangle_C> rects;
+
+ m_updates.GetRectangles( rects );
+
+
+ const DFBRegion &bounding = m_updates.bounding();
+
+ 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() );
+
+ m_updates.reset();
+
+ flushUpdates( rects );
+ }
+ }
+ }
+ else {
+ D_DEBUG_AT( PluggIt_SourceWin32, "%s()\n", __FUNCTION__ );
+
+ long long last_time = direct_clock_get_abs_millis();
+
+ while (!m_thread->isInterrupted()) {
+ if (((const Config&)m_config).m_updating) {
+ usleep( 100000 );
+
+ queueUpdate( 0, 0, m_size.w - 1, m_size.h - 1 );
+
+ pthread_mutex_lock( &m_lock );
+ }
+ else {
+ pthread_mutex_lock( &m_lock );
+
+ if (m_updates.num_regions() == 0)
+ usleep( 10000 );
+ //pthread_cond_wait( &m_cond, &m_lock );
+ }
+
+ if (direct_clock_get_abs_millis() - last_time > 2000) {
+ DFBRegion region( 0,
+ 0,
+ m_size.w - 1,
+ m_size.h - 1 );
+
+ m_updates.addRegion( region );
+
+ last_time = direct_clock_get_abs_millis();
+ }
+
+
+ vector<DFBRectangle_C> rects;
+
+ if (m_updates.num_regions() > 0) {
+ m_updates.GetRectangles( rects );
+
+
+ const DFBRegion &bounding = m_updates.bounding();
+
+ 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() );
+
+ m_updates.reset();
+ }
+
+ pthread_mutex_unlock( &m_lock );
+
+ if (!rects.empty())
+ flushUpdates( rects );
+ }
+ }
+ }
+
+/**********************************************************************************************************************/
+
+ 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_mutex_unlock( &m_lock );
+
+ pthread_cond_signal( &m_cond );
+ }
+
+ private bool flushUpdates( vector<DFBRectangle_C> &rects ) {
+ D_DEBUG_AT( PluggIt_SourceWin32, "%s()\n", __FUNCTION__ );
+
+ if (m_using_driver) {
+ m_view->update( rects, m_driver.myframebuffer, m_pitch );
+ }
+ else {
+ 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 );
+ }
+
+ D_DEBUG_AT( PluggIt_SourceWin32, " -> flush done\n" );
+
+ return true;
+ }
+
+
+
+/**********************************************************************************************************************/
+
+ private static std::string getWindowTitle( HWND window ) {
+ char buf[1024] = { 0 };
+
+ GetWindowText( window, buf, sizeof(buf) );
+
+ D_DEBUG_AT( PluggIt_SourceWin32, "%s( %p ) -> '%s'\n", __FUNCTION__, window, buf );
+
+ return buf;
+ }
+
+
+/**********************************************************************************************************************/
+
+ class EnumContext {
+ public const std::string &title;
+ public HWND window;
+
+ public EnumContext( const std::string &title ) : title(title), window(0) {}
+ };
+
+ private static BOOL CALLBACK enumWindowsProc( HWND hwnd,
+ LPARAM lParam )
+ {
+ EnumContext *ctx = reinterpret_cast<EnumContext *>( lParam );
+
+ D_DEBUG_AT( PluggIt_SourceWin32, "%s( %p )\n", __FUNCTION__, hwnd );
+
+ std::string title = getWindowTitle( hwnd );
+
+ if (title == ctx->title || title.find( ctx->title ) < title.size())
+ ctx->window = hwnd;
+
+ return ctx->window == NULL;
+ }
+
+ private HWND findWindow( const std::string &title ) {
+ D_DEBUG_AT( PluggIt_SourceWin32, "%s( %s )\n", __FUNCTION__, title.c_str() );
+
+ EnumContext ctx( title );
+
+ EnumWindows( enumWindowsProc, reinterpret_cast<LPARAM>( &ctx ) );
+
+ return ctx.window;
+ }
+
+
+/**********************************************************************************************************************/
+
+ static LRESULT CALLBACK WndProc( HWND hwnd, // handle to window
+ UINT uMsg, // message identifier
+ WPARAM wParam, // first message parameter
+ LPARAM lParam ) // second message parameter
+ {
+ static SourceWin32 *thiz;
+ POINT point;
+ CREATESTRUCT *create;
+
+ switch (uMsg) {
+ case WM_CREATE:
+ create = reinterpret_cast<LPCREATESTRUCT>( lParam );
+ thiz = reinterpret_cast<SourceWin32 *>( create->lpCreateParams );
+
+ SetCursor( LoadCursor( NULL, IDC_CROSS ) );
+ break;
+
+ case WM_LBUTTONDOWN:
+ ShowWindow( hwnd, SW_HIDE );
+
+
+ GetCursorPos( &point );
+
+ D_DEBUG_AT( PluggIt_SourceWin32, " -> Cursor position is %ld,%ld\n", point.x, point.y );
+
+
+ thiz->m_window = WindowFromPoint( point );
+ if (thiz->m_window) {
+ HWND parent;
+
+ while ((parent = GetParent( thiz->m_window )) != NULL)
+ thiz->m_window = parent;
+ }
+
+ D_DEBUG_AT( PluggIt_SourceWin32, " -> Window at cursor is %p: %s\n",
+ thiz->m_window, getWindowTitle( thiz->m_window ).c_str() );
+
+ DestroyWindow( hwnd );
+ break;
+
+ case WM_TIMER:
+ if (wParam == 666)
+ DestroyWindow( hwnd );
+ break;
+
+ case WM_DESTROY:
+ KillTimer( hwnd, 666 );
+ PostQuitMessage( 0 );
+ break;
+
+ default:
+ SetTimer( hwnd, 666, 5000, NULL );
+
+ return DefWindowProc( hwnd, uMsg, wParam, lParam );
+ }
+
+ return 0;
+ }
+
+ private void pickWindow() {
+ D_DEBUG_AT( PluggIt_SourceWin32, "%s()\n", __FUNCTION__ );
+
+ HDC hdc;
+
+ hdc = GetDC( NULL );
+ if (!hdc)
+ throw new Exception( "GetDC() returned NULL" );
+
+ RECT rect;
+
+ GetClipBox( hdc, &rect );
+
+ D_DEBUG_AT( PluggIt_SourceWin32, " -> Desktop size: %ldx%ld\n",
+ rect.right - rect.left, rect.bottom - rect.top );
+
+ ReleaseDC( NULL, hdc );
+
+
+
+ WNDCLASSEX wndClass;
+
+ ZeroMemory( &wndClass, sizeof(wndClass) );
+
+ wndClass.cbSize = sizeof(wndClass);
+ wndClass.style = CS_HREDRAW | CS_VREDRAW;
+ wndClass.lpfnWndProc = WndProc;
+ wndClass.cbClsExtra = 0;
+ wndClass.cbWndExtra = 0;
+ wndClass.hInstance = m_hInstance;
+ wndClass.hIcon = NULL;
+ wndClass.hIconSm = NULL;
+ wndClass.hCursor = LoadCursor( NULL, IDC_UPARROW );
+ wndClass.hbrBackground = (HBRUSH) GetStockObject( NULL_BRUSH );
+ wndClass.lpszMenuName = NULL;
+ wndClass.lpszClassName = "GrabWindow";
+
+ if (!RegisterClassEx( &wndClass ))
+ throw new Exception( "RegisterClassEx() failed!\n" );
+
+
+ AdjustWindowRect( &rect, WS_CAPTION, FALSE );
+
+
+ HWND grabwin;
+
+ grabwin = CreateWindowEx( 0,
+ "GrabWindow",
+ "GrabWindow",
+ WS_POPUP,// | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_BORDER,
+ CW_USEDEFAULT,
+ CW_USEDEFAULT,
+ rect.right - rect.left,
+ rect.bottom - rect.top,
+ NULL,
+ NULL,
+ m_hInstance,
+ this );
+
+ SetWindowLong( grabwin, GWL_EXSTYLE,
+ GetWindowLong( grabwin, GWL_EXSTYLE ) | WS_EX_TRANSPARENT | WS_EX_TOPMOST );
+
+ ShowWindow( grabwin, SW_SHOW );
+
+
+
+ MSG msg;
+
+ while (GetMessage( &msg, 0, 0, 0 )) {
+ TranslateMessage( &msg );
+
+ D_DEBUG_AT( PluggIt_SourceWin32, " -> Dispatching event (id %u)...\n", msg.message );
+
+ DispatchMessage( &msg );
+ }
+ }
+
+/**********************************************************************************************************************/
+
+ static LRESULT CALLBACK MsgWndProc( HWND hwnd, // handle to window
+ UINT uMsg, // message identifier
+ WPARAM wParam, // first message parameter
+ LPARAM lParam ) // second message parameter
+ {
+ static SourceWin32 *thiz;
+ CREATESTRUCT *create;
+
+ switch (uMsg) {
+ case WM_CREATE:
+ create = reinterpret_cast<LPCREATESTRUCT>( lParam );
+ thiz = reinterpret_cast<SourceWin32 *>( create->lpCreateParams );
+ break;
+
+ case WM_DESTROY:
+ PostQuitMessage( 0 );
+ break;
+
+ default:
+ if (uMsg == specIpcCode) {
+ int x1 = wParam >> 16;
+ int y1 = wParam & 0xffff;
+ int x2 = lParam >> 16;
+ int y2 = lParam & 0xffff;
+
+ if (x1 < x2 && y1 < y2)
+ thiz->queueUpdate( x1, y1, x2 - 1, y2 - 1 );
+
+ break;
+ }
+
+ return DefWindowProc( hwnd, uMsg, wParam, lParam );
+ }
+
+ return 0;
+ }
+
+ public virtual int MainLoop() {
+ MSG msg;
+
+ while (GetMessage( &msg, 0, 0, 0 )) {
+ TranslateMessage( &msg );
+ DispatchMessage( &msg );
+ }
+
+ return 0;
+ }
+};
+
+}
+
diff --git a/src/SourceX11.cxx b/src/SourceX11.cxx
new file mode 100644
index 0000000..339c8e7
--- /dev/null
+++ b/src/SourceX11.cxx
@@ -0,0 +1,534 @@
+extern "C" {
+#include <limits.h>
+}
+
+namespace PluggIt {
+
+D_DEBUG_DOMAIN( PluggIt_SourceX11, "PluggIt/SourceX11", "PluggIt Source X11" );
+
+
+class SourceX11 extends Source, Runnable
+{
+ private Display *m_display;
+ private Screen *m_screen;
+ private Window m_window;
+ private Window m_root;
+
+ private DFBPoint m_position;
+ private DFBDimension m_size;
+ private unsigned int m_depth;
+
+ private XImage *m_image;
+ private Pixmap m_pixmap;
+
+ private Bool m_shm;
+ private int m_shm_major;
+ private int m_shm_minor;
+ private XShmSegmentInfo m_shm_info;
+
+ private Damage m_xdamage;
+ private int m_xdamage_notify_event;
+ private XserverRegion m_xdamage_region;
+ private GC m_xdamage_copy_gc;
+
+ private Thread *m_thread;
+
+ private Updates m_updates;
+
+
+
+ public class Config extends Source::Config {
+ friend class SourceX11;
+
+ public typedef enum {
+ WINDOW_SELECTION_NONE,
+ WINDOW_SELECTION_TITLE,
+ WINDOW_SELECTION_INTERACTIVE
+ } WindowSelection;
+
+ private WindowSelection m_selection;
+ private std::string m_title;
+
+
+ public Config( WindowSelection selection, const std::string &title = std::string() ) {
+ m_selection = selection;
+ m_title = title;
+ }
+ };
+
+
+ public SourceX11( View *view, const Config &config ) : m_updates(16), Source( view, config ) {
+ D_DEBUG_AT( PluggIt_SourceX11, "%s( %p )\n", __FUNCTION__, view );
+
+ XInitThreads();
+
+ m_display = XOpenDisplay( getenv("DISPLAY") );
+ if (!m_display)
+ throw new Exception( "Error in XOpenDisplay for '%s'!\n", getenv("DISPLAY") );
+
+ XLockDisplay( m_display );
+
+ m_screen = DefaultScreenOfDisplay( m_display );
+ m_root = RootWindowOfScreen( m_screen );
+
+ switch (config.m_selection) {
+ case Config::WINDOW_SELECTION_NONE:
+ m_window = m_root;
+ break;
+
+ case Config::WINDOW_SELECTION_TITLE:
+ m_window = findWindow( config.m_title );
+ if (m_window == None)
+ throw new Exception( "Could not find window with title containing '%s'\n", config.m_title.c_str() );
+ break;
+
+ case Config::WINDOW_SELECTION_INTERACTIVE:
+ m_window = pickWindow();
+ if (m_window == None)
+ throw new Exception( "Could not interactively pick a window\n" );
+ break;
+
+ default:
+ throw new Exception( "Invalid window selection method\n" );
+ }
+
+ unsigned int tmp_u;
+ int tmp_i;
+
+ XGetGeometry( m_display, m_window, &m_root, &m_position.x, &m_position.y,
+ (unsigned int*) &m_size.w, (unsigned int*) &m_size.h, &tmp_u, &m_depth );
+
+
+ std::string t = getWindowTitle( m_window );
+
+ D_INFO( "Source/X11: Window %d,%d-%ux%u, depth %u, name '%s'\n",
+ m_position.x, m_position.y, m_size.w, m_size.h, m_depth, t.c_str() );
+
+
+ if (XShmQueryExtension( m_display ))
+ XShmQueryVersion( m_display, &m_shm_major, &m_shm_minor, &m_shm );
+
+ initXDamage();
+
+ if (m_shm) {
+ if (!initXShmImage()) {
+ m_shm = false;
+
+ initXImage();
+ }
+ }
+ else
+ initXImage();
+
+ XUnlockDisplay( m_display );
+
+
+ m_view->config( m_size );
+
+
+ /* Create the thread object. */
+ m_thread = new Thread( this, "SourceX11" );
+
+ m_thread->start();
+ }
+
+ virtual ~SourceX11() {
+ XDestroyImage( m_image );
+
+ if (m_shm) {
+ XShmDetach( m_display, &m_shm_info );
+
+ shmdt( m_shm_info.shmaddr );
+ }
+ }
+
+
+/**********************************************************************************************************************/
+
+ private void run() {
+ D_DEBUG_AT( PluggIt_SourceX11, "%s()\n", __FUNCTION__ );
+
+ XLockDisplay( m_display );
+
+ while (true) {
+ XEvent event;
+
+ XNextEvent( m_display, &event );
+
+ if (event.type == m_xdamage_notify_event)
+ handleXDamage( reinterpret_cast<XDamageNotifyEvent*>( &event ) );
+
+ if (!XPending( m_display ))
+ flushXDamage();
+ }
+
+ XUnlockDisplay( m_display );
+ }
+
+
+/**********************************************************************************************************************/
+
+ private void initXDamage() {
+ int event_base, error_base;
+ int major, minor;
+ XGCValues values;
+
+ D_DEBUG_AT( PluggIt_SourceX11, "%s()\n", __FUNCTION__ );
+
+ if (!XDamageQueryExtension( m_display, &event_base, &error_base ))
+ throw new Exception( "XDamageQueryExtension" );
+
+ if (!XDamageQueryVersion( m_display, &major, &minor ) || major != 1)
+ throw new Exception( "XDamageQueryVersion" );
+
+ m_xdamage_notify_event = event_base + XDamageNotify;
+
+ m_xdamage = XDamageCreate( m_display, m_window, XDamageReportDeltaRectangles );
+ if (m_xdamage == None)
+ throw new Exception( "XDamageCreate" );
+
+ m_xdamage_region = XFixesCreateRegion( m_display, NULL, 0 );
+ if (m_xdamage_region == None) {
+ XDamageDestroy( m_display, m_xdamage );
+ m_xdamage = None;
+ throw new Exception( "XFixesCreateRegion" );
+ }
+
+ values.subwindow_mode = IncludeInferiors;
+
+ m_xdamage_copy_gc = XCreateGC( m_display, m_window, GCSubwindowMode, &values );
+ }
+
+ private void handleXDamage( const XDamageNotifyEvent *event ) {
+ D_DEBUG_AT( PluggIt_SourceX11, "%s()\n", __FUNCTION__ );
+
+ D_DEBUG_AT( PluggIt_SourceX11, " -> %4d,%4d-%4dx%4d\n",
+ event->area.x, event->area.y, event->area.width, event->area.height );
+
+
+ DFBRegion damage( event->area.x, event->area.y,
+ event->area.x + event->area.width - 1,
+ event->area.y + event->area.height - 1 );
+
+ m_updates.addRegion( damage );
+ }
+
+ private void flushXDamage() {
+ vector<DFBRectangle_C> rects;
+
+ D_DEBUG_AT( PluggIt_SourceX11, "%s()\n", __FUNCTION__ );
+
+ m_updates.GetRectangles( rects );
+
+ if (rects.empty())
+ return;
+
+ const DFBRegion &bounding = m_updates.bounding();
+
+ D_DEBUG_AT( PluggIt_SourceX11, " -> %4d,%4d-%4dx%4d (%d regions, %d rectangles)\n",
+ DFB_RECTANGLE_VALS_FROM_REGION( &bounding ), m_updates.num_regions(), rects.size() );
+
+ m_updates.reset();
+
+
+ XRectangle xdamage[rects.size()];
+
+ for (int i=0; i<rects.size(); i++) {
+ D_DEBUG_AT( PluggIt_SourceX11, " -> [%2d] %4d,%4d-%4dx%4d\n", i, DFB_RECTANGLE_VALS( &rects[i] ) );
+
+ xdamage[i].x = rects[i].x;
+ xdamage[i].y = rects[i].y;
+ xdamage[i].width = rects[i].w;
+ xdamage[i].height = rects[i].h;
+ }
+
+ XFixesSetRegion( m_display, m_xdamage_region, xdamage, rects.size() );
+ XDamageSubtract( m_display, m_xdamage, m_xdamage_region, None );
+
+
+ if (m_shm) {
+ for (int i=0; i<rects.size(); i++) {
+ XCopyArea( m_display,
+ m_window,
+ m_pixmap,
+ m_xdamage_copy_gc,
+ rects[i].x,
+ rects[i].y,
+ rects[i].w,
+ rects[i].h,
+ rects[i].x,
+ rects[i].y );
+ }
+
+ XSync( m_display, False );
+ }
+ else {
+ for (int i=0; i<rects.size(); i++) {
+ XGetSubImage( m_display,
+ m_window,
+ rects[i].x,
+ rects[i].y,
+ rects[i].w,
+ rects[i].h,
+ AllPlanes,
+ ZPixmap,
+ m_image,
+ rects[i].x,
+ rects[i].y );
+ }
+
+ XSync( m_display, False );
+ }
+
+ for (int i=0; i<rects.size(); i++) {
+ D_DEBUG_AT( PluggIt_SourceX11, " -> [%2d] %4d,%4d-%4dx%4d\n", i, DFB_RECTANGLE_VALS( &rects[i] ) );
+ }
+
+ m_view->update( rects, m_image->data, m_image->bytes_per_line );
+ }
+
+/**********************************************************************************************************************/
+
+ private bool initXShmImage() {
+ m_image = XShmCreateImage( m_display,
+ DefaultVisual( m_display, 0 ),
+ m_depth,
+ ZPixmap,
+ NULL,
+ &m_shm_info,
+ m_size.w,
+ m_size.h );
+ if (!m_image)
+ return false;
+
+ m_shm_info.shmid = shmget( IPC_PRIVATE, m_image->bytes_per_line * m_image->height, IPC_CREAT | 0600 );
+ if (m_shm_info.shmid == -1) {
+ XDestroyImage( m_image );
+ return false;
+ }
+
+ m_shm_info.readOnly = False;
+ m_shm_info.shmaddr = (char*) shmat( m_shm_info.shmid, 0, 0 );
+
+ if (m_shm_info.shmaddr == (char*) -1) {
+ shmctl( m_shm_info.shmid, IPC_RMID, 0 );
+ XDestroyImage( m_image );
+ return false;
+ }
+
+ m_image->data = m_shm_info.shmaddr;
+
+
+ XShmAttach( m_display, &m_shm_info );
+ XSync( m_display, False );
+
+ shmctl( m_shm_info.shmid, IPC_RMID, 0 );
+
+
+ m_pixmap = XShmCreatePixmap( m_display, m_window, m_image->data, &m_shm_info,
+ m_image->width, m_image->height, m_image->depth );
+ if (!m_pixmap) {
+ shmdt( m_shm_info.shmaddr );
+ XShmDetach( m_display, &m_shm_info );
+ XDestroyImage( m_image );
+ return false;
+ }
+
+ return true;
+ }
+
+ private void initXImage() {
+ m_image = XCreateImage( m_display,
+ DefaultVisual( m_display, 0 ),
+ m_depth,
+ ZPixmap,
+ 0,
+ NULL,
+ m_size.w,
+ m_size.h,
+ 32,
+ 0 );
+ if (!m_image)
+ throw new Exception( "XCreateImage" );
+
+ m_image->data = (char*) malloc( m_image->bytes_per_line * m_image->height );
+ if (!m_image->data) {
+ XDestroyImage( m_image );
+ throw new OutOfMemoryException();
+ }
+ }
+
+
+/**********************************************************************************************************************/
+
+ private std::string getWindowTitle( Window window ) {
+ std::string str;
+ char *name = NULL;
+ Atom actual_type;
+ int format;
+ unsigned long n;
+ unsigned long extra;
+
+ XGetWindowProperty( m_display, window, XA_WM_NAME, 0L, 100L,
+ False, AnyPropertyType, &actual_type, &format, &n,
+ &extra, (unsigned char **) &name );
+
+ D_DEBUG_AT( PluggIt_SourceX11, "%s( %u ) -> '%s'\n", __FUNCTION__, window, name );
+
+ if (name) {
+ str.append( name );
+
+ XFree( name );
+ }
+
+ return str;
+ }
+
+ private Window checkWindow( Window window,
+ const std::string &title )
+ {
+ std::string t;
+ Window w = None, root, parent, *children;
+ unsigned int num_children;
+
+ D_DEBUG_AT( PluggIt_SourceX11, "%s( %u, %s )\n", __FUNCTION__, window, title.c_str() );
+
+ t = getWindowTitle( window );
+ if (t == title || t.find( title ) < t.size())
+ return window;
+
+ XQueryTree( m_display, window, &root, &parent, &children, &num_children );
+
+ for (unsigned int i=0; i<num_children; i++) {
+ w = checkWindow( children[i], title );
+ if (w)
+ break;
+ }
+
+ XFree( children );
+
+ return w;
+ }
+
+ private Window findWindow( const std::string &title ) {
+ Window win;
+
+ D_DEBUG_AT( PluggIt_SourceX11, "%s( %s )\n", __FUNCTION__, title.c_str() );
+
+ win = checkWindow( m_root, title );
+ if (win)
+ return lookupManagedWindow( win );
+
+ D_DEBUG_AT( PluggIt_SourceX11, " -> not found\n" );
+
+ return None;
+ }
+
+
+/**********************************************************************************************************************/
+
+ private Window pickWindow() {
+ int loops;
+ Window win = None;
+
+ D_DEBUG_AT( PluggIt_SourceX11, "%s()\n", __FUNCTION__ );
+
+ D_DEBUG_AT( PluggIt_SourceX11, " -> Grabbing pointer...\n" );
+
+ XGrabPointer( m_display, m_root, False, ButtonPressMask | PointerMotionMask,
+ GrabModeAsync, GrabModeAsync, None, XCreateFontCursor( m_display, XC_cross ), CurrentTime );
+
+ for (loops=0; loops < 100 && win == None; loops++) {
+ XEvent event;
+
+ D_DEBUG_AT( PluggIt_SourceX11, " -> Waiting for event...\n" );
+
+ if (!XPending( m_display )) {
+ usleep( 40000 );
+ continue;
+ }
+
+ XNextEvent( m_display, &event );
+
+ D_DEBUG_AT( PluggIt_SourceX11, " -> event type %d\n", event.type );
+
+ switch (event.type) {
+ case ButtonPress:
+ D_DEBUG_AT( PluggIt_SourceX11, " -> button %d press at %d,%d\n",
+ event.xbutton.button, event.xbutton.x, event.xbutton.y );
+
+ D_DEBUG_AT( PluggIt_SourceX11, " -> sub window %u: '%s'\n",
+ event.xbutton.subwindow, getWindowTitle( event.xbutton.subwindow ).c_str() );
+
+ win = lookupManagedWindow( event.xbutton.subwindow );
+ break;
+
+ default:
+ break;
+ }
+
+ loops = 0;
+ }
+
+ XUngrabPointer( m_display, CurrentTime );
+
+ return win;
+ }
+
+
+/**********************************************************************************************************************/
+
+ private Window lookupManagedWindow( Window window ) {
+ int i, result;
+ unsigned long nitems;
+ unsigned long bytes_after;
+ unsigned long *prop;
+ Atom ret_type = None;
+ int ret_format;
+ Atom wm_state_atom;
+
+ D_DEBUG_AT( PluggIt_SourceX11, "%s()\n", __FUNCTION__ );
+
+ wm_state_atom = XInternAtom( m_display, "WM_STATE", False );
+
+
+ D_DEBUG_AT( PluggIt_SourceX11, " -> Retrieving WM_STATE (Atom %d)...\n", wm_state_atom );
+
+ result = XGetWindowProperty( m_display, window, wm_state_atom,
+ 0, LONG_MAX, False, wm_state_atom,
+ &ret_type, &ret_format, &nitems,
+ &bytes_after, (unsigned char**) &prop );
+ if (result == Success) {
+ XFree( prop );
+
+ if (ret_type == wm_state_atom) {
+ D_DEBUG_AT( PluggIt_SourceX11, " -> OK\n" );
+ return window;
+ }
+ }
+
+
+
+ Window root;
+ Window parent;
+ Window *children = NULL;
+ Window win = None;
+ unsigned int num_children;
+
+ result = XQueryTree( m_display, window, &root, &parent, &children, &num_children );
+ if (!result)
+ return None;
+
+ for (i=0; i<num_children && win == None; i++)
+ win = lookupManagedWindow( children[i] );
+
+ if (children)
+ XFree (children);
+
+ return win;
+ }
+
+};
+
+}
+
diff --git a/src/Thread.cxx b/src/Thread.cxx
new file mode 100644
index 0000000..a8f1e32
--- /dev/null
+++ b/src/Thread.cxx
@@ -0,0 +1,71 @@
+namespace PluggIt {
+
+class Thread
+{
+ private Runnable *m_target;
+ private string m_name;
+
+ private DirectThread *m_thread;
+ private volatile bool m_interrupted;
+
+
+ public Thread( Runnable *target, string name = "" ) {
+ m_target = target;
+ m_name = name;
+
+ m_thread = NULL;
+ m_interrupted = false;
+ }
+
+ virtual ~Thread() {
+ if (m_thread)
+ direct_thread_destroy( m_thread );
+ }
+
+ public bool start() {
+ if (m_thread)
+ return false;
+
+ m_thread = direct_thread_create( DTT_DEFAULT, main, m_target, m_name.c_str() );
+
+ return m_thread != NULL;
+ }
+
+ public bool interrupt() {
+ if (!m_thread)
+ return false;
+
+ m_interrupted = true;
+
+ return true;
+ }
+
+ public bool isInterrupted() {
+ return m_interrupted;
+ }
+
+ public bool join() {
+ if (!m_thread)
+ return false;
+
+ direct_thread_join( m_thread );
+ direct_thread_destroy( m_thread );
+
+ m_thread = NULL;
+ m_interrupted = false;
+
+ return true;
+ }
+
+
+ private static void *main( DirectThread *thread, void *arg ) {
+ Runnable *target = (Runnable*) arg;
+
+ target->run();
+
+ return NULL;
+ }
+};
+
+}
+
diff --git a/src/Updates.cxx b/src/Updates.cxx
new file mode 100644
index 0000000..49f69d5
--- /dev/null
+++ b/src/Updates.cxx
@@ -0,0 +1,78 @@
+namespace PluggIt {
+
+class Updates
+{
+ private DFBUpdates m_updates;
+ private DFBRegion *m_regions;
+
+ public Updates( unsigned int max_regions = 8 ) {
+ m_regions = (DFBRegion*) D_CALLOC( max_regions ?: 1, sizeof(DFBRegion) );
+
+ dfb_updates_init( &m_updates, m_regions, max_regions );
+ }
+
+ virtual ~Updates() {
+ dfb_updates_deinit( &m_updates );
+
+ D_FREE( m_regions );
+ }
+
+
+ public void addRegion( const DFBRegion &region ) {
+ dfb_updates_add( &m_updates, &region );
+ }
+
+ public DFBRegion bounding() const {
+ return m_updates.bounding;
+ }
+
+ public void get_rectangles( DFBRectangle *ret_rects, int *ret_num ) {
+ dfb_updates_get_rectangles( &m_updates, ret_rects, ret_num );
+ }
+
+ public unsigned int num_regions() const {
+ return m_updates.num_regions;
+ }
+
+ public void reset() {
+ dfb_updates_reset( &m_updates );
+ }
+
+
+ public void GetRectangles( vector<DFBRectangle_C> &rects ) {
+ D_MAGIC_ASSERT( &m_updates, DFBUpdates );
+ D_ASSERT( m_updates.regions != NULL );
+ D_ASSERT( m_updates.num_regions >= 0 );
+ D_ASSERT( m_updates.num_regions <= m_updates.max_regions );
+
+ switch (m_updates.num_regions) {
+ case 0:
+ break;
+
+ default: {
+ int n, d, total, bounding;
+
+ dfb_updates_stat( &m_updates, &total, &bounding );
+
+ n = m_updates.max_regions - m_updates.num_regions + 1;
+ d = n + 1;
+
+ /* Try to optimize updates. Use individual regions only if not too much overhead. */
+ if (total < bounding * n / d) {
+ for (n=0; n<m_updates.num_regions; n++)
+ rects.push_back( DFBRectangle( m_updates.regions[n] ) );
+
+ break;
+ }
+ }
+ /* fall through */
+
+ case 1:
+ rects.push_back( DFBRectangle( m_updates.bounding ) );
+ break;
+ }
+ }
+};
+
+}
+
diff --git a/src/View.cxx b/src/View.cxx
new file mode 100644
index 0000000..d7f3195
--- /dev/null
+++ b/src/View.cxx
@@ -0,0 +1,13 @@
+namespace PluggIt {
+
+class View
+{
+ public virtual void config( DFBDimension &size ) = 0;
+
+ public virtual void update( const vector<DFBRectangle_C> &rects,
+ void *ptr,
+ int pitch ) = 0;
+};
+
+}
+
diff --git a/src/classes.cpp b/src/classes.cpp
new file mode 100644
index 0000000..a0ecb67
--- /dev/null
+++ b/src/classes.cpp
@@ -0,0 +1,4047 @@
+# 1 "classes.h"
+#define DIRECT_ENABLE_DEBUG
+
+
+#include <iostream>
+#include <vector>
+
+using namespace std;
+
+
+/*
+ * ++DFB
+ */
+#include <++dfb.h>
+
+
+
+/*
+ * Direct
+ */
+extern "C" {
+#include <stdarg.h>
+
+#include <direct/clock.h>
+#include <direct/debug.h>
+#include <direct/memcpy.h>
+#include <direct/messages.h>
+#include <direct/thread.h>
+#include <direct/util.h>
+
+#include <gfx/convert.h>
+}
+
+
+/*
+ * Win32
+ */
+#ifdef __WIN32__
+#define CreateWindow CreateWindowWin32
+#include <windows.h>
+#include <wingdi.h>
+#include <winuser.h>
+#include "videodriver.h"
+#undef CreateWindow
+
+#else
+
+/*
+ * X11
+ */
+extern "C" {
+#include <X11/Xlib.h> /* fundamentals X datas structures */
+#include <X11/Xutil.h> /* datas definitions for various functions */
+#include <X11/keysym.h> /* for a perfect use of keyboard events */
+#include <X11/Xatom.h>
+#include <X11/cursorfont.h>
+
+#include <X11/extensions/XShm.h>
+#include <X11/extensions/Xdamage.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+}
+
+#endif
+
+class Exception;
+class OutOfMemoryException;
+class Clock;
+class FPS;
+class Options;
+class Random;
+class Updates;
+class Runnable;
+class Thread;
+class Scaler;
+class View;
+class Source;
+class SourceWin32;
+class Main;
+# 1 "Exception.cxx"
+# 1 "<built-in>"
+# 1 "<command-line>"
+# 1 "Exception.cxx"
+namespace PluggIt {
+
+class Exception
+{
+ private: string m_message;
+
+
+ public: Exception( string message ) {
+ m_message = message;
+ }
+
+ public: Exception( const char *format, ... ) D_FORMAT_PRINTF(2) {
+ va_list args;
+ int len;
+ char buf[200];
+ char *ptr = buf;
+
+ va_start( args, format );
+ len = vsnprintf( buf, sizeof(buf), format, args );
+ va_end( args );
+
+ if (len < 0)
+ abort();
+
+ if (len >= (int)sizeof(buf)) {
+ ptr = (char*) malloc( len+1 );
+ if (!ptr)
+ abort();
+
+ va_start( args, format );
+ len = vsnprintf( ptr, len+1, format, args );
+ va_end( args );
+
+ if (len < 0) {
+ free( ptr );
+ abort();
+ }
+ }
+
+ m_message = string( ptr );
+
+ if (ptr != buf)
+ free( ptr );
+ }
+
+ public: string getMessage() {
+ return m_message;
+ }
+
+
+ friend std::ostream &operator << (std::ostream &stream, Exception *ex) {
+ stream << ex->getMessage();
+
+ return stream;
+ }
+};
+
+}
+# 1 "OutOfMemoryException.cxx"
+# 1 "<built-in>"
+# 1 "<command-line>"
+# 1 "OutOfMemoryException.cxx"
+namespace PluggIt {
+
+class OutOfMemoryException :public Exception
+{
+ public: OutOfMemoryException() : Exception( "Out of memory!" ) {
+ }
+};
+
+}
+# 1 "Clock.cxx"
+# 1 "<built-in>"
+# 1 "<command-line>"
+# 1 "Clock.cxx"
+namespace PluggIt {
+
+class Clock
+{
+ private: long long base;
+ private: char str[20];
+
+ public: Clock() {
+ Reset();
+ }
+
+ public: void Reset() {
+ base = direct_clock_get_micros();
+ }
+
+ public: float GetTime() {
+ return (direct_clock_get_micros() - base) / 1000000.0f;
+ }
+
+ public: const char *GetString() {
+ float time = GetTime();
+ int seconds = (int) time;
+ int minutes = seconds / 60;
+
+ snprintf( str, sizeof(str), "%02d:%02d", minutes, seconds );
+
+ return str;
+ }
+};
+
+}
+# 1 "FPS.cxx"
+# 1 "<built-in>"
+# 1 "<command-line>"
+# 1 "FPS.cxx"
+namespace PluggIt {
+
+class FPS
+{
+ private: int frames;
+ private: char str[20];
+
+ private: Clock clock;
+
+
+ public: FPS() {
+ Reset();
+ }
+
+ public: void Reset() {
+ frames = 0;
+ str[0] = 0;
+
+ clock.Reset();
+ }
+
+ public: void Count( float interval ) {
+ float time = clock.GetTime();
+
+ frames++;
+
+ if (time >= interval) {
+ float fps = frames / time;
+
+ snprintf( str, sizeof(str), "%.1f", fps );
+
+ frames = 0;
+ clock.Reset();
+ }
+ }
+
+ public: const char *GetFPS() {
+ return str;
+ }
+};
+
+}
+# 1 "Options.cxx"
+# 1 "<built-in>"
+# 1 "<command-line>"
+# 1 "Options.cxx"
+namespace PluggIt {
+
+static const DirectFBPixelFormatNames(m_formats);
+
+class Options
+{
+ class Option {
+ friend class Options;
+
+ protected: const char *m_short_name;
+ protected: const char *m_long_name;
+ protected: const char *m_arg_name;
+ protected: const char *m_arg_desc;
+ protected: bool m_need_arg;
+
+ public: Option( const char *short_name,
+ const char *long_name,
+ const char *arg_name,
+ const char *arg_desc )
+ {
+ m_short_name = short_name;
+ m_long_name = long_name;
+ m_arg_name = arg_name;
+ m_arg_desc = arg_desc;
+ m_need_arg = true;
+ }
+
+ public: virtual bool Parse( const char *arg ) = 0;
+ };
+
+ public: class OptionBool :public Option {
+ private: bool &m_value;
+
+ public: OptionBool( const char *short_name,
+ const char *long_name,
+ const char *arg_name,
+ const char *arg_desc,
+ bool &value ) : Option( short_name, long_name, arg_name, arg_desc ), m_value( value )
+ {
+ m_need_arg = false;
+ }
+
+ public: virtual bool Parse( const char *arg ) {
+ m_value = true;
+
+ return true;
+ }
+ };
+
+ public: class OptionLong :public Option {
+ private: long &m_value;
+ private: int m_base;
+
+ public: OptionLong( const char *short_name,
+ const char *long_name,
+ const char *arg_name,
+ const char *arg_desc,
+ long &value,
+ int base = 10 ) : Option( short_name, long_name, arg_name, arg_desc ), m_value( value )
+ {
+ m_base = base;
+ }
+
+ public: virtual bool Parse( const char *arg ) {
+ long ret;
+ char *end;
+
+ ret = strtol( arg, &end, m_base );
+
+ if (*end) {
+ D_ERROR( "Option/Long: Invalid argument to '%s' or '%s'!\n", m_short_name, m_long_name );
+ return false;
+ }
+
+ m_value = ret;
+
+ return true;
+ }
+ };
+
+ public: class OptionULong :public Option {
+ private: unsigned long &m_value;
+ private: int m_base;
+
+ public: OptionULong( const char *short_name,
+ const char *long_name,
+ const char *arg_name,
+ const char *arg_desc,
+ unsigned long &value,
+ int base = 10 ) : Option( short_name, long_name, arg_name, arg_desc ), m_value( value )
+ {
+ m_base = base;
+ }
+
+ public: virtual bool Parse( const char *arg ) {
+ unsigned long ret;
+ char *end;
+
+ ret = strtoul( arg, &end, m_base );
+
+ if (*end) {
+ D_ERROR( "Option/ULong: Invalid argument to '%s' or '%s'!\n", m_short_name, m_long_name );
+ return false;
+ }
+
+ m_value = ret;
+
+ return true;
+ }
+ };
+
+ public: class OptionFormat :public Option {
+ private: DFBSurfacePixelFormat &m_value;
+
+ public: OptionFormat( const char *short_name,
+ const char *long_name,
+ const char *arg_name,
+ const char *arg_desc,
+ DFBSurfacePixelFormat &value ) : Option( short_name, long_name, arg_name, arg_desc ), m_value( value )
+ {
+ }
+
+ public: virtual bool Parse( const char *arg ) {
+ unsigned int i;
+
+ for (i=0; i<D_ARRAY_SIZE(m_formats); i++) {
+ if (!strcasecmp( m_formats[i].name, arg )) {
+ m_value = m_formats[i].format;
+
+ return true;
+ }
+ }
+
+ D_ERROR( "Option/Format: Unknown format '%s' passed to '%s' or '%s'!\n", arg, m_short_name, m_long_name );
+
+ return false;
+ }
+ };
+
+ public: class OptionString :public Option {
+ private: std::string &m_value;
+
+ public: OptionString( const char *short_name,
+ const char *long_name,
+ const char *arg_name,
+ const char *arg_desc,
+ std::string &value ) : Option( short_name, long_name, arg_name, arg_desc ), m_value( value )
+ {
+ }
+
+ public: virtual bool Parse( const char *arg ) {
+ m_value = arg;
+ return true;
+ }
+ };
+
+ public: class OptionPoint :public Option {
+ private: DFBPoint &m_value;
+
+ public: OptionPoint( const char *short_name,
+ const char *long_name,
+ const char *arg_name,
+ const char *arg_desc,
+ DFBPoint &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", &m_value.x, &m_value.y ) != 2) {
+ D_ERROR( "Option/Point: Invalid argument to '%s' or '%s'!\n", m_short_name, m_long_name );
+ return false;
+ }
+
+ return true;
+ }
+ };
+
+ public: class OptionDimension :public Option {
+ private: DFBDimension &m_value;
+
+ public: OptionDimension( const char *short_name,
+ const char *long_name,
+ const char *arg_name,
+ const char *arg_desc,
+ DFBDimension &value ) : Option( short_name, long_name, arg_name, arg_desc ), m_value( value )
+ {
+ }
+
+ public: virtual bool Parse( const char *arg ) {
+ if (sscanf( arg, "%dx%d", &m_value.w, &m_value.h ) != 2) {
+ D_ERROR( "Option/Dimension: Invalid argument to '%s' or '%s'!\n", m_short_name, m_long_name );
+ return false;
+ }
+
+ return true;
+ }
+ };
+
+
+
+ private: vector<Option*> m_options;
+
+ public: void addOption( Option *option ) {
+ m_options.push_back( option );
+ }
+
+ public: bool parseCommandLine( int argc, char *argv[] ) {
+ int n;
+
+ for (n = 1; n < argc; n++) {
+ bool ok = false;
+ const char *arg = argv[n];
+
+ if (strcmp (arg, "-h") == 0 || strcmp (arg, "--help") == 0) {
+ printUsage (argv[0]);
+ return false;
+ }
+
+ if (strcmp (arg, "-v") == 0 || strcmp (arg, "--version") == 0) {
+
+ return false;
+ }
+
+ vector<Option*>::iterator itr = m_options.begin();
+
+ for (; itr != m_options.end(); itr++) {
+ Option *option = *itr;
+
+ if (!strcmp (arg, option->m_short_name) || !strcmp (arg, option->m_long_name)) {
+ if (option->m_need_arg && ++n == argc) {
+ printUsage (argv[0]);
+ return false;
+ }
+
+ if (!option->Parse( argv[n] ))
+ return false;
+
+ ok = true;
+
+ break;
+ }
+ }
+
+ if (!ok) {
+ printUsage (argv[0]);
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ public: void printUsage( const char *prg_name ) {
+
+ fprintf (stderr, "Usage: %s [options]\n\n", prg_name);
+ fprintf (stderr, "Options:\n");
+ fprintf (stderr, " -h --help Show this help message\n");
+ fprintf (stderr, " -v --version Print version information\n");
+
+
+ vector<Option*>::const_iterator itr = m_options.begin();
+
+ for (; itr != m_options.end(); itr++) {
+ const Option *option = *itr;
+
+ fprintf( stderr, " %-3s %-16s %-12s %s\n",
+ option->m_short_name, option->m_long_name, option->m_arg_name, option->m_arg_desc );
+ }
+
+ fprintf( stderr, "\n" );
+ }
+};
+
+}
+# 1 "Random.cxx"
+# 1 "<built-in>"
+# 1 "<command-line>"
+# 1 "Random.cxx"
+namespace PluggIt {
+
+class Random
+{
+ public: static float nextFloat( float min, float max ) {
+ return min + rand() * (max - min) / (float) RAND_MAX;
+ }
+};
+
+}
+# 1 "Updates.cxx"
+# 1 "<built-in>"
+# 1 "<command-line>"
+# 1 "Updates.cxx"
+namespace PluggIt {
+
+class Updates
+{
+ private: DFBUpdates m_updates;
+ private: DFBRegion *m_regions;
+
+ public: Updates( unsigned int max_regions = 8 ) {
+ m_regions = (DFBRegion*) D_CALLOC( max_regions ?: 1, sizeof(DFBRegion) );
+
+ dfb_updates_init( &m_updates, m_regions, max_regions );
+ }
+
+ virtual ~Updates() {
+ dfb_updates_deinit( &m_updates );
+
+ D_FREE( m_regions );
+ }
+
+
+ public: void addRegion( const DFBRegion &region ) {
+ dfb_updates_add( &m_updates, &region );
+ }
+
+ public: DFBRegion bounding() const {
+ return m_updates.bounding;
+ }
+
+ public: void get_rectangles( DFBRectangle *ret_rects, int *ret_num ) {
+ dfb_updates_get_rectangles( &m_updates, ret_rects, ret_num );
+ }
+
+ public: unsigned int num_regions() const {
+ return m_updates.num_regions;
+ }
+
+ public: void reset() {
+ dfb_updates_reset( &m_updates );
+ }
+
+
+ public: void GetRectangles( vector<DFBRectangle_C> &rects ) {
+ D_MAGIC_ASSERT( &m_updates, DFBUpdates );
+ D_ASSERT( m_updates.regions != NULL );
+ D_ASSERT( m_updates.num_regions >= 0 );
+ D_ASSERT( m_updates.num_regions <= m_updates.max_regions );
+
+ switch (m_updates.num_regions) {
+ case 0:
+ break;
+
+ default: {
+ int n, d, total, bounding;
+
+ dfb_updates_stat( &m_updates, &total, &bounding );
+
+ n = m_updates.max_regions - m_updates.num_regions + 1;
+ d = n + 1;
+
+
+ if (total < bounding * n / d) {
+ for (n=0; n<m_updates.num_regions; n++)
+ rects.push_back( DFBRectangle( m_updates.regions[n] ) );
+
+ break;
+ }
+ }
+
+
+ case 1:
+ rects.push_back( DFBRectangle( m_updates.bounding ) );
+ break;
+ }
+ }
+};
+
+}
+# 1 "Runnable.cxx"
+# 1 "<built-in>"
+# 1 "<command-line>"
+# 1 "Runnable.cxx"
+namespace PluggIt {
+
+class Runnable
+{
+ public: virtual void run() = 0;
+};
+
+}
+# 1 "Thread.cxx"
+# 1 "<built-in>"
+# 1 "<command-line>"
+# 1 "Thread.cxx"
+namespace PluggIt {
+
+class Thread
+{
+ private: Runnable *m_target;
+ private: string m_name;
+
+ private: DirectThread *m_thread;
+ private: volatile bool m_interrupted;
+
+
+ public: Thread( Runnable *target, string name = "" ) {
+ m_target = target;
+ m_name = name;
+
+ m_thread = NULL;
+ m_interrupted = false;
+ }
+
+ virtual ~Thread() {
+ if (m_thread)
+ direct_thread_destroy( m_thread );
+ }
+
+ public: bool start() {
+ if (m_thread)
+ return false;
+
+ m_thread = direct_thread_create( DTT_DEFAULT, main, m_target, m_name.c_str() );
+
+ return m_thread != NULL;
+ }
+
+ public: bool interrupt() {
+ if (!m_thread)
+ return false;
+
+ m_interrupted = true;
+
+ return true;
+ }
+
+ public: bool isInterrupted() {
+ return m_interrupted;
+ }
+
+ public: bool join() {
+ if (!m_thread)
+ return false;
+
+ direct_thread_join( m_thread );
+ direct_thread_destroy( m_thread );
+
+ m_thread = NULL;
+ m_interrupted = false;
+
+ return true;
+ }
+
+
+ private: static void *main( DirectThread *thread, void *arg ) {
+ Runnable *target = (Runnable*) arg;
+
+ target->run();
+
+ return NULL;
+ }
+};
+
+}
+# 1 "Scaler.cxx"
+# 1 "<built-in>"
+# 1 "<command-line>"
+# 1 "Scaler.cxx"
+namespace PluggIt {
+
+D_DEBUG_DOMAIN( PluggIt_Scaler, "PluggIt/Scaler", "PluggIt Scaler" );
+
+
+typedef struct {
+ DFBRegion clip;
+ const void *colors;
+ unsigned long protect;
+ unsigned long key;
+} StretchCtx;
+
+typedef void (*StretchHVx)( void *dst,
+ int dpitch,
+ const void *src,
+ int spitch,
+ int width,
+ int height,
+ int dst_width,
+ int dst_height,
+ const StretchCtx *ctx );
+# 47 "Scaler.cxx"
+# 1 "stretch_up_down_16.h" 1
+# 20 "stretch_up_down_16.h"
+# 1 "stretch_hvx_N.h" 1
+# 9 "stretch_hvx_N.h"
+static void stretch_hvx_RGB16_up____DSPF_RGB16
+# 1 "stretch_hvx_16.h" 1
+# 35 "stretch_hvx_16.h"
+ ( void *dst,
+ int dpitch,
+ const void *src,
+ int spitch,
+ int width,
+ int height,
+ int dst_width,
+ int dst_height,
+ const StretchCtx *ctx )
+{
+ long x, y, r = 0;
+ long head = ((((unsigned long) dst) & 2) >> 1) ^ (ctx->clip.x1 & 1);
+ long cw = ctx->clip.x2 - ctx->clip.x1 + 1;
+ long ch = ctx->clip.y2 - ctx->clip.y1 + 1;
+ long tail = (cw - head) & 1;
+ long w2 = (cw - head) / 2;
+ long hfraq = ((long)(width - 1) << 18) / (long)(dst_width);
+ long vfraq = ((long)(height - 1) << 18) / (long)(dst_height);
+ long dp4 = dpitch / 4;
+ long point0 = 0 + ctx->clip.x1 * hfraq;
+ long point = point0;
+ long line = 0 + ctx->clip.y1 * vfraq;
+ long ratios[cw];
+ u32 *dst32;
+
+
+
+
+
+
+ u32 _lbT[w2+8];
+ u32 _lbB[w2+8];
+
+ u32 *lbX;
+ u32 *lbT = (u32*)((((unsigned long)(&_lbT[0])) + 31) & ~31);
+ u32 *lbB = (u32*)((((unsigned long)(&_lbB[0])) + 31) & ~31);
+
+ long lineT = -2000;
+
+ for (x=0; x<cw; x++) {
+ ratios[x] = ( ((point) & 0x3ffff) >> (18-6) );
+
+ point += hfraq;
+ }
+
+ do {} while (0);
+
+
+ dst = (void*)((char*) dst + ctx->clip.x1 * 2 + ctx->clip.y1 * dpitch);
+
+ dst32 = (u32*) dst;
+
+ if (head) {
+ u32 dpT, dpB, L, R;
+
+ u16 *dst16 = (u16*) dst;
+
+ point = point0;
+
+ for (y=0; y<ch; y++) {
+ long X = ( ((line) & 0x3ffff) >> (18-5) );
+
+ const u16 *srcT = (const u16 *)((char*) src + spitch * ( (((line)) >> 18) ));
+ const u16 *srcB = (const u16 *)((char*) src + spitch * ( (((line)) >> 18) + 1 ));
+
+
+
+
+ long pl = ( (((point)) >> 18) );
+ do {} while (0);
+
+ D_ASSERT( pl >= 0 );
+ D_ASSERT( pl < width-1 );
+ L = (srcT[pl]);
+ R = (srcT[pl+1]);
+
+ dpT = (((((R & 0xf81f)-(L & 0xf81f))*ratios[r] + ((L & 0xf81f)<<6)) & (0xf81f<<6)) +
+ ((((R & 0x07e0)-(L & 0x07e0))*ratios[r] + ((L & 0x07e0)<<6)) & (0x07e0<<6))) >> 6;
+
+ L = (srcB[pl]);
+ R = (srcB[pl+1]);
+
+ dpB = (((((R & 0xf81f)-(L & 0xf81f))*ratios[r] + ((L & 0xf81f)<<6)) & (0xf81f<<6)) +
+ ((((R & 0x07e0)-(L & 0x07e0))*ratios[r] + ((L & 0x07e0)<<6)) & (0x07e0<<6))) >> 6;
+# 138 "stretch_hvx_16.h"
+ dst16[0] = ((((((dpB & 0xf81f) - (dpT & 0xf81f))*X) >> 5) + (dpT & 0xf81f)) & 0xf81f) +
+ ((((((dpB>>5) & (0x07e0>>5)) - ((dpT>>5) & (0x07e0>>5)))*X) + (dpT & 0x07e0)) & 0x07e0);
+
+
+ dst16 += dpitch / 2;
+ line += vfraq;
+ }
+
+
+ point0 += hfraq;
+ dst32 = (u32*)((char*) dst + 2);
+
+
+ line = 0 + ctx->clip.y1 * vfraq;
+ }
+
+
+
+
+ for (y=0; y<ch; y++) {
+ long X;
+ long nlT = ( (((line)) >> 18) );
+
+ D_ASSERT( nlT >= 0 );
+ D_ASSERT( nlT < height-1 );
+
+
+
+
+ if (nlT != lineT) {
+ u32 L, R, dpT, dpB;
+ const u16 *srcT = (const u16 *)((char*) src + spitch * nlT);
+ const u16 *srcB = (const u16 *)((char*) src + spitch * (nlT + 1));
+ long diff = nlT - lineT;
+
+ if (diff > 1) {
+
+
+
+ for (x=0, r=head, point=point0; x<w2; x++) {
+
+
+
+ long pl = ( (((point)) >> 18) );
+ do {} while (0);
+
+ D_ASSERT( pl >= 0 );
+ D_ASSERT( pl < width-1 );
+ L = (srcT[pl]);
+ R = (srcT[pl+1]);
+
+ dpT = (((((R & 0xf81f)-(L & 0xf81f))*ratios[r] + ((L & 0xf81f)<<6)) & (0xf81f<<6)) +
+ ((((R & 0x07e0)-(L & 0x07e0))*ratios[r] + ((L & 0x07e0)<<6)) & (0x07e0<<6)))
+
+
+
+ >> 6;
+
+
+ L = (srcB[pl]);
+ R = (srcB[pl+1]);
+
+ dpB = (((((R & 0xf81f)-(L & 0xf81f))*ratios[r] + ((L & 0xf81f)<<6)) & (0xf81f<<6)) +
+ ((((R & 0x07e0)-(L & 0x07e0))*ratios[r] + ((L & 0x07e0)<<6)) & (0x07e0<<6)))
+
+
+
+ >> 6;
+
+
+ point += hfraq;
+ r++;
+
+
+ pl = ( (((point)) >> 18) );
+ do {} while (0);
+
+ D_ASSERT( pl >= 0 );
+ D_ASSERT( pl < width-1 );
+
+ L = (srcT[pl]);
+ R = (srcT[pl+1]);
+
+ dpT |= (((((R & 0xf81f)-(L & 0xf81f))*ratios[r] + ((L & 0xf81f)<<6)) & (0xf81f<<6)) +
+ ((((R & 0x07e0)-(L & 0x07e0))*ratios[r] + ((L & 0x07e0)<<6)) & (0x07e0<<6)))
+
+
+
+ << (16-6);
+
+
+ L = (srcB[pl]);
+ R = (srcB[pl+1]);
+
+ dpB |= (((((R & 0xf81f)-(L & 0xf81f))*ratios[r] + ((L & 0xf81f)<<6)) & (0xf81f<<6)) +
+ ((((R & 0x07e0)-(L & 0x07e0))*ratios[r] + ((L & 0x07e0)<<6)) & (0x07e0<<6)))
+
+
+
+ << (16-6);
+
+
+ point += hfraq;
+ r++;
+
+
+ lbT[x] = dpT;
+ lbB[x] = dpB;
+ }
+ }
+ else {
+
+ lbX = lbT;
+ lbT = lbB;
+ lbB = lbX;
+
+
+
+
+ for (x=0, r=head, point=point0; x<w2; x++) {
+
+
+
+ long pl = ( (((point)) >> 18) );
+ do {} while (0);
+
+ D_ASSERT( pl >= 0 );
+ D_ASSERT( pl < width-1 );
+ L = (srcB[pl]);
+ R = (srcB[pl+1]);
+
+ dpB = (((((R & 0xf81f)-(L & 0xf81f))*ratios[r] + ((L & 0xf81f)<<6)) & (0xf81f<<6)) +
+ ((((R & 0x07e0)-(L & 0x07e0))*ratios[r] + ((L & 0x07e0)<<6)) & (0x07e0<<6)))
+
+
+
+ >> 6;
+
+
+ point += hfraq;
+ r++;
+
+
+ pl = ( (((point)) >> 18) );
+ do {} while (0);
+
+ D_ASSERT( pl >= 0 );
+ D_ASSERT( pl < width-1 );
+
+ L = (srcB[pl]);
+ R = (srcB[pl+1]);
+
+ dpB |= (((((R & 0xf81f)-(L & 0xf81f))*ratios[r] + ((L & 0xf81f)<<6)) & (0xf81f<<6)) +
+ ((((R & 0x07e0)-(L & 0x07e0))*ratios[r] + ((L & 0x07e0)<<6)) & (0x07e0<<6)))
+
+
+
+ << (16-6);
+
+
+ point += hfraq;
+ r++;
+
+
+ lbB[x] = dpB;
+ }
+ }
+
+ lineT = nlT;
+ }
+
+
+
+
+ X = ( ((line) & 0x3ffff) >> (18-5) );
+
+ for (x=0; x<w2; x++) {
+# 371 "stretch_hvx_16.h"
+ dst32[x] = ((((((lbB[x] & ((0x07e0<<16) | 0xf81f)) - (lbT[x] & ((0x07e0<<16) | 0xf81f)))*X) >> 5) + (lbT[x] & ((0x07e0<<16) | 0xf81f))) & ((0x07e0<<16) | 0xf81f)) +
+ ((((((lbB[x]>>5) & (((0xf81f<<16) | 0x07e0)>>5)) - ((lbT[x]>>5) & (((0xf81f<<16) | 0x07e0)>>5)))*X) + (lbT[x] & ((0xf81f<<16) | 0x07e0))) & ((0xf81f<<16) | 0x07e0));
+
+
+ }
+
+ dst32 += dp4;
+ line += vfraq;
+ }
+
+ if (tail) {
+ u32 dpT, dpB, L, R;
+
+ u16 *dst16 = (u16*)((char*) dst + cw * 2 - 2);
+
+
+ line = 0 + ctx->clip.y1 * vfraq;
+
+ for (y=0; y<ch; y++) {
+ long X = ( ((line) & 0x3ffff) >> (18-5) );
+
+ const u16 *srcT = (const u16 *)((char*) src + spitch * ( (((line)) >> 18) ));
+ const u16 *srcB = (const u16 *)((char*) src + spitch * ( (((line)) >> 18) + 1 ));
+
+
+
+
+ long pl = ( (((point)) >> 18) );
+ do {} while (0);
+
+ D_ASSERT( pl >= 0 );
+ D_ASSERT( pl < width-1 );
+ L = (srcT[pl]);
+ R = (srcT[pl+1]);
+
+ dpT = (((((R & 0xf81f)-(L & 0xf81f))*ratios[r] + ((L & 0xf81f)<<6)) & (0xf81f<<6)) +
+ ((((R & 0x07e0)-(L & 0x07e0))*ratios[r] + ((L & 0x07e0)<<6)) & (0x07e0<<6))) >> 6;
+
+ L = (srcB[pl]);
+ R = (srcB[pl+1]);
+
+ dpB = (((((R & 0xf81f)-(L & 0xf81f))*ratios[r] + ((L & 0xf81f)<<6)) & (0xf81f<<6)) +
+ ((((R & 0x07e0)-(L & 0x07e0))*ratios[r] + ((L & 0x07e0)<<6)) & (0x07e0<<6))) >> 6;
+# 434 "stretch_hvx_16.h"
+ dst16[0] = ((((((dpB & 0xf81f) - (dpT & 0xf81f))*X) >> 5) + (dpT & 0xf81f)) & 0xf81f) +
+ ((((((dpB>>5) & (0x07e0>>5)) - ((dpT>>5) & (0x07e0>>5)))*X) + (dpT & 0x07e0)) & 0x07e0);
+
+
+ dst16 += dpitch / 2;
+ line += vfraq;
+ }
+ }
+}
+# 11 "stretch_hvx_N.h" 2
+# 20 "stretch_hvx_N.h"
+static void stretch_hvx_RGB16_up____DSPF_RGB32
+# 1 "stretch_hvx_16.h" 1
+# 35 "stretch_hvx_16.h"
+ ( void *dst,
+ int dpitch,
+ const void *src,
+ int spitch,
+ int width,
+ int height,
+ int dst_width,
+ int dst_height,
+ const StretchCtx *ctx )
+{
+ long x, y, r = 0;
+ long head = ((((unsigned long) dst) & 2) >> 1) ^ (ctx->clip.x1 & 1);
+ long cw = ctx->clip.x2 - ctx->clip.x1 + 1;
+ long ch = ctx->clip.y2 - ctx->clip.y1 + 1;
+ long tail = (cw - head) & 1;
+ long w2 = (cw - head) / 2;
+ long hfraq = ((long)(width - 1) << 18) / (long)(dst_width);
+ long vfraq = ((long)(height - 1) << 18) / (long)(dst_height);
+ long dp4 = dpitch / 4;
+ long point0 = 0 + ctx->clip.x1 * hfraq;
+ long point = point0;
+ long line = 0 + ctx->clip.y1 * vfraq;
+ long ratios[cw];
+ u32 *dst32;
+
+
+
+
+
+
+ u32 _lbT[w2+8];
+ u32 _lbB[w2+8];
+
+ u32 *lbX;
+ u32 *lbT = (u32*)((((unsigned long)(&_lbT[0])) + 31) & ~31);
+ u32 *lbB = (u32*)((((unsigned long)(&_lbB[0])) + 31) & ~31);
+
+ long lineT = -2000;
+
+ for (x=0; x<cw; x++) {
+ ratios[x] = ( ((point) & 0x3ffff) >> (18-6) );
+
+ point += hfraq;
+ }
+
+ do {} while (0);
+
+
+ dst = (void*)((char*) dst + ctx->clip.x1 * 2 + ctx->clip.y1 * dpitch);
+
+ dst32 = (u32*) dst;
+
+ if (head) {
+ u32 dpT, dpB, L, R;
+
+ u16 *dst16 = (u16*) dst;
+
+ point = point0;
+
+ for (y=0; y<ch; y++) {
+ long X = ( ((line) & 0x3ffff) >> (18-5) );
+
+ const u32 *srcT = (const u32 *)((char*) src + spitch * ( (((line)) >> 18) ));
+ const u32 *srcB = (const u32 *)((char*) src + spitch * ( (((line)) >> 18) + 1 ));
+
+
+
+
+ long pl = ( (((point)) >> 18) );
+ do {} while (0);
+
+ D_ASSERT( pl >= 0 );
+ D_ASSERT( pl < width-1 );
+ L = ( (((((srcT[pl]) & 0xff0000) >> 16)&0xF8) << 8) | (((((srcT[pl]) & 0x00ff00) >> 8)&0xFC) << 3) | (((((srcT[pl]) & 0x0000ff))&0xF8) >> 3) );
+ R = ( (((((srcT[pl+1]) & 0xff0000) >> 16)&0xF8) << 8) | (((((srcT[pl+1]) & 0x00ff00) >> 8)&0xFC) << 3) | (((((srcT[pl+1]) & 0x0000ff))&0xF8) >> 3) );
+
+ dpT = (((((R & 0xf81f)-(L & 0xf81f))*ratios[r] + ((L & 0xf81f)<<6)) & (0xf81f<<6)) +
+ ((((R & 0x07e0)-(L & 0x07e0))*ratios[r] + ((L & 0x07e0)<<6)) & (0x07e0<<6))) >> 6;
+
+ L = ( (((((srcB[pl]) & 0xff0000) >> 16)&0xF8) << 8) | (((((srcB[pl]) & 0x00ff00) >> 8)&0xFC) << 3) | (((((srcB[pl]) & 0x0000ff))&0xF8) >> 3) );
+ R = ( (((((srcB[pl+1]) & 0xff0000) >> 16)&0xF8) << 8) | (((((srcB[pl+1]) & 0x00ff00) >> 8)&0xFC) << 3) | (((((srcB[pl+1]) & 0x0000ff))&0xF8) >> 3) );
+
+ dpB = (((((R & 0xf81f)-(L & 0xf81f))*ratios[r] + ((L & 0xf81f)<<6)) & (0xf81f<<6)) +
+ ((((R & 0x07e0)-(L & 0x07e0))*ratios[r] + ((L & 0x07e0)<<6)) & (0x07e0<<6))) >> 6;
+# 138 "stretch_hvx_16.h"
+ dst16[0] = ((((((dpB & 0xf81f) - (dpT & 0xf81f))*X) >> 5) + (dpT & 0xf81f)) & 0xf81f) +
+ ((((((dpB>>5) & (0x07e0>>5)) - ((dpT>>5) & (0x07e0>>5)))*X) + (dpT & 0x07e0)) & 0x07e0);
+
+
+ dst16 += dpitch / 2;
+ line += vfraq;
+ }
+
+
+ point0 += hfraq;
+ dst32 = (u32*)((char*) dst + 2);
+
+
+ line = 0 + ctx->clip.y1 * vfraq;
+ }
+
+
+
+
+ for (y=0; y<ch; y++) {
+ long X;
+ long nlT = ( (((line)) >> 18) );
+
+ D_ASSERT( nlT >= 0 );
+ D_ASSERT( nlT < height-1 );
+
+
+
+
+ if (nlT != lineT) {
+ u32 L, R, dpT, dpB;
+ const u32 *srcT = (const u32 *)((char*) src + spitch * nlT);
+ const u32 *srcB = (const u32 *)((char*) src + spitch * (nlT + 1));
+ long diff = nlT - lineT;
+
+ if (diff > 1) {
+
+
+
+ for (x=0, r=head, point=point0; x<w2; x++) {
+
+
+
+ long pl = ( (((point)) >> 18) );
+ do {} while (0);
+
+ D_ASSERT( pl >= 0 );
+ D_ASSERT( pl < width-1 );
+ L = ( (((((srcT[pl]) & 0xff0000) >> 16)&0xF8) << 8) | (((((srcT[pl]) & 0x00ff00) >> 8)&0xFC) << 3) | (((((srcT[pl]) & 0x0000ff))&0xF8) >> 3) );
+ R = ( (((((srcT[pl+1]) & 0xff0000) >> 16)&0xF8) << 8) | (((((srcT[pl+1]) & 0x00ff00) >> 8)&0xFC) << 3) | (((((srcT[pl+1]) & 0x0000ff))&0xF8) >> 3) );
+
+ dpT = (((((R & 0xf81f)-(L & 0xf81f))*ratios[r] + ((L & 0xf81f)<<6)) & (0xf81f<<6)) +
+ ((((R & 0x07e0)-(L & 0x07e0))*ratios[r] + ((L & 0x07e0)<<6)) & (0x07e0<<6)))
+
+
+
+ >> 6;
+
+
+ L = ( (((((srcB[pl]) & 0xff0000) >> 16)&0xF8) << 8) | (((((srcB[pl]) & 0x00ff00) >> 8)&0xFC) << 3) | (((((srcB[pl]) & 0x0000ff))&0xF8) >> 3) );
+ R = ( (((((srcB[pl+1]) & 0xff0000) >> 16)&0xF8) << 8) | (((((srcB[pl+1]) & 0x00ff00) >> 8)&0xFC) << 3) | (((((srcB[pl+1]) & 0x0000ff))&0xF8) >> 3) );
+
+ dpB = (((((R & 0xf81f)-(L & 0xf81f))*ratios[r] + ((L & 0xf81f)<<6)) & (0xf81f<<6)) +
+ ((((R & 0x07e0)-(L & 0x07e0))*ratios[r] + ((L & 0x07e0)<<6)) & (0x07e0<<6)))
+
+
+
+ >> 6;
+
+
+ point += hfraq;
+ r++;
+
+
+ pl = ( (((point)) >> 18) );
+ do {} while (0);
+
+ D_ASSERT( pl >= 0 );
+ D_ASSERT( pl < width-1 );
+
+ L = ( (((((srcT[pl]) & 0xff0000) >> 16)&0xF8) << 8) | (((((srcT[pl]) & 0x00ff00) >> 8)&0xFC) << 3) | (((((srcT[pl]) & 0x0000ff))&0xF8) >> 3) );
+ R = ( (((((srcT[pl+1]) & 0xff0000) >> 16)&0xF8) << 8) | (((((srcT[pl+1]) & 0x00ff00) >> 8)&0xFC) << 3) | (((((srcT[pl+1]) & 0x0000ff))&0xF8) >> 3) );
+
+ dpT |= (((((R & 0xf81f)-(L & 0xf81f))*ratios[r] + ((L & 0xf81f)<<6)) & (0xf81f<<6)) +
+ ((((R & 0x07e0)-(L & 0x07e0))*ratios[r] + ((L & 0x07e0)<<6)) & (0x07e0<<6)))
+
+
+
+ << (16-6);
+
+
+ L = ( (((((srcB[pl]) & 0xff0000) >> 16)&0xF8) << 8) | (((((srcB[pl]) & 0x00ff00) >> 8)&0xFC) << 3) | (((((srcB[pl]) & 0x0000ff))&0xF8) >> 3) );
+ R = ( (((((srcB[pl+1]) & 0xff0000) >> 16)&0xF8) << 8) | (((((srcB[pl+1]) & 0x00ff00) >> 8)&0xFC) << 3) | (((((srcB[pl+1]) & 0x0000ff))&0xF8) >> 3) );
+
+ dpB |= (((((R & 0xf81f)-(L & 0xf81f))*ratios[r] + ((L & 0xf81f)<<6)) & (0xf81f<<6)) +
+ ((((R & 0x07e0)-(L & 0x07e0))*ratios[r] + ((L & 0x07e0)<<6)) & (0x07e0<<6)))
+
+
+
+ << (16-6);
+
+
+ point += hfraq;
+ r++;
+
+
+ lbT[x] = dpT;
+ lbB[x] = dpB;
+ }
+ }
+ else {
+
+ lbX = lbT;
+ lbT = lbB;
+ lbB = lbX;
+
+
+
+
+ for (x=0, r=head, point=point0; x<w2; x++) {
+
+
+
+ long pl = ( (((point)) >> 18) );
+ do {} while (0);
+
+ D_ASSERT( pl >= 0 );
+ D_ASSERT( pl < width-1 );
+ L = ( (((((srcB[pl]) & 0xff0000) >> 16)&0xF8) << 8) | (((((srcB[pl]) & 0x00ff00) >> 8)&0xFC) << 3) | (((((srcB[pl]) & 0x0000ff))&0xF8) >> 3) );
+ R = ( (((((srcB[pl+1]) & 0xff0000) >> 16)&0xF8) << 8) | (((((srcB[pl+1]) & 0x00ff00) >> 8)&0xFC) << 3) | (((((srcB[pl+1]) & 0x0000ff))&0xF8) >> 3) );
+
+ dpB = (((((R & 0xf81f)-(L & 0xf81f))*ratios[r] + ((L & 0xf81f)<<6)) & (0xf81f<<6)) +
+ ((((R & 0x07e0)-(L & 0x07e0))*ratios[r] + ((L & 0x07e0)<<6)) & (0x07e0<<6)))
+
+
+
+ >> 6;
+
+
+ point += hfraq;
+ r++;
+
+
+ pl = ( (((point)) >> 18) );
+ do {} while (0);
+
+ D_ASSERT( pl >= 0 );
+ D_ASSERT( pl < width-1 );
+
+ L = ( (((((srcB[pl]) & 0xff0000) >> 16)&0xF8) << 8) | (((((srcB[pl]) & 0x00ff00) >> 8)&0xFC) << 3) | (((((srcB[pl]) & 0x0000ff))&0xF8) >> 3) );
+ R = ( (((((srcB[pl+1]) & 0xff0000) >> 16)&0xF8) << 8) | (((((srcB[pl+1]) & 0x00ff00) >> 8)&0xFC) << 3) | (((((srcB[pl+1]) & 0x0000ff))&0xF8) >> 3) );
+
+ dpB |= (((((R & 0xf81f)-(L & 0xf81f))*ratios[r] + ((L & 0xf81f)<<6)) & (0xf81f<<6)) +
+ ((((R & 0x07e0)-(L & 0x07e0))*ratios[r] + ((L & 0x07e0)<<6)) & (0x07e0<<6)))
+
+
+
+ << (16-6);
+
+
+ point += hfraq;
+ r++;
+
+
+ lbB[x] = dpB;
+ }
+ }
+
+ lineT = nlT;
+ }
+
+
+
+
+ X = ( ((line) & 0x3ffff) >> (18-5) );
+
+ for (x=0; x<w2; x++) {
+# 371 "stretch_hvx_16.h"
+ dst32[x] = ((((((lbB[x] & ((0x07e0<<16) | 0xf81f)) - (lbT[x] & ((0x07e0<<16) | 0xf81f)))*X) >> 5) + (lbT[x] & ((0x07e0<<16) | 0xf81f))) & ((0x07e0<<16) | 0xf81f)) +
+ ((((((lbB[x]>>5) & (((0xf81f<<16) | 0x07e0)>>5)) - ((lbT[x]>>5) & (((0xf81f<<16) | 0x07e0)>>5)))*X) + (lbT[x] & ((0xf81f<<16) | 0x07e0))) & ((0xf81f<<16) | 0x07e0));
+
+
+ }
+
+ dst32 += dp4;
+ line += vfraq;
+ }
+
+ if (tail) {
+ u32 dpT, dpB, L, R;
+
+ u16 *dst16 = (u16*)((char*) dst + cw * 2 - 2);
+
+
+ line = 0 + ctx->clip.y1 * vfraq;
+
+ for (y=0; y<ch; y++) {
+ long X = ( ((line) & 0x3ffff) >> (18-5) );
+
+ const u32 *srcT = (const u32 *)((char*) src + spitch * ( (((line)) >> 18) ));
+ const u32 *srcB = (const u32 *)((char*) src + spitch * ( (((line)) >> 18) + 1 ));
+
+
+
+
+ long pl = ( (((point)) >> 18) );
+ do {} while (0);
+
+ D_ASSERT( pl >= 0 );
+ D_ASSERT( pl < width-1 );
+ L = ( (((((srcT[pl]) & 0xff0000) >> 16)&0xF8) << 8) | (((((srcT[pl]) & 0x00ff00) >> 8)&0xFC) << 3) | (((((srcT[pl]) & 0x0000ff))&0xF8) >> 3) );
+ R = ( (((((srcT[pl+1]) & 0xff0000) >> 16)&0xF8) << 8) | (((((srcT[pl+1]) & 0x00ff00) >> 8)&0xFC) << 3) | (((((srcT[pl+1]) & 0x0000ff))&0xF8) >> 3) );
+
+ dpT = (((((R & 0xf81f)-(L & 0xf81f))*ratios[r] + ((L & 0xf81f)<<6)) & (0xf81f<<6)) +
+ ((((R & 0x07e0)-(L & 0x07e0))*ratios[r] + ((L & 0x07e0)<<6)) & (0x07e0<<6))) >> 6;
+
+ L = ( (((((srcB[pl]) & 0xff0000) >> 16)&0xF8) << 8) | (((((srcB[pl]) & 0x00ff00) >> 8)&0xFC) << 3) | (((((srcB[pl]) & 0x0000ff))&0xF8) >> 3) );
+ R = ( (((((srcB[pl+1]) & 0xff0000) >> 16)&0xF8) << 8) | (((((srcB[pl+1]) & 0x00ff00) >> 8)&0xFC) << 3) | (((((srcB[pl+1]) & 0x0000ff))&0xF8) >> 3) );
+
+ dpB = (((((R & 0xf81f)-(L & 0xf81f))*ratios[r] + ((L & 0xf81f)<<6)) & (0xf81f<<6)) +
+ ((((R & 0x07e0)-(L & 0x07e0))*ratios[r] + ((L & 0x07e0)<<6)) & (0x07e0<<6))) >> 6;
+# 434 "stretch_hvx_16.h"
+ dst16[0] = ((((((dpB & 0xf81f) - (dpT & 0xf81f))*X) >> 5) + (dpT & 0xf81f)) & 0xf81f) +
+ ((((((dpB>>5) & (0x07e0>>5)) - ((dpT>>5) & (0x07e0>>5)))*X) + (dpT & 0x07e0)) & 0x07e0);
+
+
+ dst16 += dpitch / 2;
+ line += vfraq;
+ }
+ }
+}
+# 22 "stretch_hvx_N.h" 2
+# 21 "stretch_up_down_16.h" 2
+# 49 "stretch_up_down_16.h"
+# 1 "stretch_hvx_N.h" 1
+# 9 "stretch_hvx_N.h"
+static void stretch_hvx_RGB16_down____DSPF_RGB16
+# 1 "stretch_hvx_16.h" 1
+# 35 "stretch_hvx_16.h"
+ ( void *dst,
+ int dpitch,
+ const void *src,
+ int spitch,
+ int width,
+ int height,
+ int dst_width,
+ int dst_height,
+ const StretchCtx *ctx )
+{
+ long x, y, r = 0;
+ long head = ((((unsigned long) dst) & 2) >> 1) ^ (ctx->clip.x1 & 1);
+ long cw = ctx->clip.x2 - ctx->clip.x1 + 1;
+ long ch = ctx->clip.y2 - ctx->clip.y1 + 1;
+ long tail = (cw - head) & 1;
+ long w2 = (cw - head) / 2;
+ long hfraq = ((long)(width - 0) << 18) / (long)(dst_width);
+ long vfraq = ((long)(height - 0) << 18) / (long)(dst_height);
+ long dp4 = dpitch / 4;
+ long point0 = hfraq + ctx->clip.x1 * hfraq;
+ long point = point0;
+ long line = vfraq + ctx->clip.y1 * vfraq;
+ long ratios[cw];
+ u32 *dst32;
+
+
+
+
+
+
+ u32 _lbT[w2+8];
+ u32 _lbB[w2+8];
+
+ u32 *lbX;
+ u32 *lbT = (u32*)((((unsigned long)(&_lbT[0])) + 31) & ~31);
+ u32 *lbB = (u32*)((((unsigned long)(&_lbB[0])) + 31) & ~31);
+
+ long lineT = -2000;
+
+ for (x=0; x<cw; x++) {
+ ratios[x] = ( (((((point)) & 0x3ffff) ? : 0x40000) << 6) / (hfraq) );
+
+ point += hfraq;
+ }
+
+ do {} while (0);
+
+
+ dst = (void*)((char*) dst + ctx->clip.x1 * 2 + ctx->clip.y1 * dpitch);
+
+ dst32 = (u32*) dst;
+
+ if (head) {
+ u32 dpT, dpB, L, R;
+
+ u16 *dst16 = (u16*) dst;
+
+ point = point0;
+
+ for (y=0; y<ch; y++) {
+ long X = ( (((((line)) & 0x3ffff) ? : 0x40000) << 5) / (vfraq) );
+
+ const u16 *srcT = (const u16 *)((char*) src + spitch * ( (((line)-1) >> 18) - 1 ));
+ const u16 *srcB = (const u16 *)((char*) src + spitch * ( (((line)-1) >> 18) ));
+
+
+
+
+ long pl = ( (((point)-1) >> 18) - 1 );
+ do {} while (0);
+
+ D_ASSERT( pl >= 0 );
+ D_ASSERT( pl < width-1 );
+ L = (srcT[pl]);
+ R = (srcT[pl+1]);
+
+ dpT = (((((R & 0xf81f)-(L & 0xf81f))*ratios[r] + ((L & 0xf81f)<<6)) & (0xf81f<<6)) +
+ ((((R & 0x07e0)-(L & 0x07e0))*ratios[r] + ((L & 0x07e0)<<6)) & (0x07e0<<6))) >> 6;
+
+ L = (srcB[pl]);
+ R = (srcB[pl+1]);
+
+ dpB = (((((R & 0xf81f)-(L & 0xf81f))*ratios[r] + ((L & 0xf81f)<<6)) & (0xf81f<<6)) +
+ ((((R & 0x07e0)-(L & 0x07e0))*ratios[r] + ((L & 0x07e0)<<6)) & (0x07e0<<6))) >> 6;
+# 138 "stretch_hvx_16.h"
+ dst16[0] = ((((((dpB & 0xf81f) - (dpT & 0xf81f))*X) >> 5) + (dpT & 0xf81f)) & 0xf81f) +
+ ((((((dpB>>5) & (0x07e0>>5)) - ((dpT>>5) & (0x07e0>>5)))*X) + (dpT & 0x07e0)) & 0x07e0);
+
+
+ dst16 += dpitch / 2;
+ line += vfraq;
+ }
+
+
+ point0 += hfraq;
+ dst32 = (u32*)((char*) dst + 2);
+
+
+ line = vfraq + ctx->clip.y1 * vfraq;
+ }
+
+
+
+
+ for (y=0; y<ch; y++) {
+ long X;
+ long nlT = ( (((line)-1) >> 18) - 1 );
+
+ D_ASSERT( nlT >= 0 );
+ D_ASSERT( nlT < height-1 );
+
+
+
+
+ if (nlT != lineT) {
+ u32 L, R, dpT, dpB;
+ const u16 *srcT = (const u16 *)((char*) src + spitch * nlT);
+ const u16 *srcB = (const u16 *)((char*) src + spitch * (nlT + 1));
+ long diff = nlT - lineT;
+
+ if (diff > 1) {
+
+
+
+ for (x=0, r=head, point=point0; x<w2; x++) {
+
+
+
+ long pl = ( (((point)-1) >> 18) - 1 );
+ do {} while (0);
+
+ D_ASSERT( pl >= 0 );
+ D_ASSERT( pl < width-1 );
+ L = (srcT[pl]);
+ R = (srcT[pl+1]);
+
+ dpT = (((((R & 0xf81f)-(L & 0xf81f))*ratios[r] + ((L & 0xf81f)<<6)) & (0xf81f<<6)) +
+ ((((R & 0x07e0)-(L & 0x07e0))*ratios[r] + ((L & 0x07e0)<<6)) & (0x07e0<<6)))
+
+
+
+ >> 6;
+
+
+ L = (srcB[pl]);
+ R = (srcB[pl+1]);
+
+ dpB = (((((R & 0xf81f)-(L & 0xf81f))*ratios[r] + ((L & 0xf81f)<<6)) & (0xf81f<<6)) +
+ ((((R & 0x07e0)-(L & 0x07e0))*ratios[r] + ((L & 0x07e0)<<6)) & (0x07e0<<6)))
+
+
+
+ >> 6;
+
+
+ point += hfraq;
+ r++;
+
+
+ pl = ( (((point)-1) >> 18) - 1 );
+ do {} while (0);
+
+ D_ASSERT( pl >= 0 );
+ D_ASSERT( pl < width-1 );
+
+ L = (srcT[pl]);
+ R = (srcT[pl+1]);
+
+ dpT |= (((((R & 0xf81f)-(L & 0xf81f))*ratios[r] + ((L & 0xf81f)<<6)) & (0xf81f<<6)) +
+ ((((R & 0x07e0)-(L & 0x07e0))*ratios[r] + ((L & 0x07e0)<<6)) & (0x07e0<<6)))
+
+
+
+ << (16-6);
+
+
+ L = (srcB[pl]);
+ R = (srcB[pl+1]);
+
+ dpB |= (((((R & 0xf81f)-(L & 0xf81f))*ratios[r] + ((L & 0xf81f)<<6)) & (0xf81f<<6)) +
+ ((((R & 0x07e0)-(L & 0x07e0))*ratios[r] + ((L & 0x07e0)<<6)) & (0x07e0<<6)))
+
+
+
+ << (16-6);
+
+
+ point += hfraq;
+ r++;
+
+
+ lbT[x] = dpT;
+ lbB[x] = dpB;
+ }
+ }
+ else {
+
+ lbX = lbT;
+ lbT = lbB;
+ lbB = lbX;
+
+
+
+
+ for (x=0, r=head, point=point0; x<w2; x++) {
+
+
+
+ long pl = ( (((point)-1) >> 18) - 1 );
+ do {} while (0);
+
+ D_ASSERT( pl >= 0 );
+ D_ASSERT( pl < width-1 );
+ L = (srcB[pl]);
+ R = (srcB[pl+1]);
+
+ dpB = (((((R & 0xf81f)-(L & 0xf81f))*ratios[r] + ((L & 0xf81f)<<6)) & (0xf81f<<6)) +
+ ((((R & 0x07e0)-(L & 0x07e0))*ratios[r] + ((L & 0x07e0)<<6)) & (0x07e0<<6)))
+
+
+
+ >> 6;
+
+
+ point += hfraq;
+ r++;
+
+
+ pl = ( (((point)-1) >> 18) - 1 );
+ do {} while (0);
+
+ D_ASSERT( pl >= 0 );
+ D_ASSERT( pl < width-1 );
+
+ L = (srcB[pl]);
+ R = (srcB[pl+1]);
+
+ dpB |= (((((R & 0xf81f)-(L & 0xf81f))*ratios[r] + ((L & 0xf81f)<<6)) & (0xf81f<<6)) +
+ ((((R & 0x07e0)-(L & 0x07e0))*ratios[r] + ((L & 0x07e0)<<6)) & (0x07e0<<6)))
+
+
+
+ << (16-6);
+
+
+ point += hfraq;
+ r++;
+
+
+ lbB[x] = dpB;
+ }
+ }
+
+ lineT = nlT;
+ }
+
+
+
+
+ X = ( (((((line)) & 0x3ffff) ? : 0x40000) << 5) / (vfraq) );
+
+ for (x=0; x<w2; x++) {
+# 371 "stretch_hvx_16.h"
+ dst32[x] = ((((((lbB[x] & ((0x07e0<<16) | 0xf81f)) - (lbT[x] & ((0x07e0<<16) | 0xf81f)))*X) >> 5) + (lbT[x] & ((0x07e0<<16) | 0xf81f))) & ((0x07e0<<16) | 0xf81f)) +
+ ((((((lbB[x]>>5) & (((0xf81f<<16) | 0x07e0)>>5)) - ((lbT[x]>>5) & (((0xf81f<<16) | 0x07e0)>>5)))*X) + (lbT[x] & ((0xf81f<<16) | 0x07e0))) & ((0xf81f<<16) | 0x07e0));
+
+
+ }
+
+ dst32 += dp4;
+ line += vfraq;
+ }
+
+ if (tail) {
+ u32 dpT, dpB, L, R;
+
+ u16 *dst16 = (u16*)((char*) dst + cw * 2 - 2);
+
+
+ line = vfraq + ctx->clip.y1 * vfraq;
+
+ for (y=0; y<ch; y++) {
+ long X = ( (((((line)) & 0x3ffff) ? : 0x40000) << 5) / (vfraq) );
+
+ const u16 *srcT = (const u16 *)((char*) src + spitch * ( (((line)-1) >> 18) - 1 ));
+ const u16 *srcB = (const u16 *)((char*) src + spitch * ( (((line)-1) >> 18) ));
+
+
+
+
+ long pl = ( (((point)-1) >> 18) - 1 );
+ do {} while (0);
+
+ D_ASSERT( pl >= 0 );
+ D_ASSERT( pl < width-1 );
+ L = (srcT[pl]);
+ R = (srcT[pl+1]);
+
+ dpT = (((((R & 0xf81f)-(L & 0xf81f))*ratios[r] + ((L & 0xf81f)<<6)) & (0xf81f<<6)) +
+ ((((R & 0x07e0)-(L & 0x07e0))*ratios[r] + ((L & 0x07e0)<<6)) & (0x07e0<<6))) >> 6;
+
+ L = (srcB[pl]);
+ R = (srcB[pl+1]);
+
+ dpB = (((((R & 0xf81f)-(L & 0xf81f))*ratios[r] + ((L & 0xf81f)<<6)) & (0xf81f<<6)) +
+ ((((R & 0x07e0)-(L & 0x07e0))*ratios[r] + ((L & 0x07e0)<<6)) & (0x07e0<<6))) >> 6;
+# 434 "stretch_hvx_16.h"
+ dst16[0] = ((((((dpB & 0xf81f) - (dpT & 0xf81f))*X) >> 5) + (dpT & 0xf81f)) & 0xf81f) +
+ ((((((dpB>>5) & (0x07e0>>5)) - ((dpT>>5) & (0x07e0>>5)))*X) + (dpT & 0x07e0)) & 0x07e0);
+
+
+ dst16 += dpitch / 2;
+ line += vfraq;
+ }
+ }
+}
+# 11 "stretch_hvx_N.h" 2
+# 20 "stretch_hvx_N.h"
+static void stretch_hvx_RGB16_down____DSPF_RGB32
+# 1 "stretch_hvx_16.h" 1
+# 35 "stretch_hvx_16.h"
+ ( void *dst,
+ int dpitch,
+ const void *src,
+ int spitch,
+ int width,
+ int height,
+ int dst_width,
+ int dst_height,
+ const StretchCtx *ctx )
+{
+ long x, y, r = 0;
+ long head = ((((unsigned long) dst) & 2) >> 1) ^ (ctx->clip.x1 & 1);
+ long cw = ctx->clip.x2 - ctx->clip.x1 + 1;
+ long ch = ctx->clip.y2 - ctx->clip.y1 + 1;
+ long tail = (cw - head) & 1;
+ long w2 = (cw - head) / 2;
+ long hfraq = ((long)(width - 0) << 18) / (long)(dst_width);
+ long vfraq = ((long)(height - 0) << 18) / (long)(dst_height);
+ long dp4 = dpitch / 4;
+ long point0 = hfraq + ctx->clip.x1 * hfraq;
+ long point = point0;
+ long line = vfraq + ctx->clip.y1 * vfraq;
+ long ratios[cw];
+ u32 *dst32;
+
+
+
+
+
+
+ u32 _lbT[w2+8];
+ u32 _lbB[w2+8];
+
+ u32 *lbX;
+ u32 *lbT = (u32*)((((unsigned long)(&_lbT[0])) + 31) & ~31);
+ u32 *lbB = (u32*)((((unsigned long)(&_lbB[0])) + 31) & ~31);
+
+ long lineT = -2000;
+
+ for (x=0; x<cw; x++) {
+ ratios[x] = ( (((((point)) & 0x3ffff) ? : 0x40000) << 6) / (hfraq) );
+
+ point += hfraq;
+ }
+
+ do {} while (0);
+
+
+ dst = (void*)((char*) dst + ctx->clip.x1 * 2 + ctx->clip.y1 * dpitch);
+
+ dst32 = (u32*) dst;
+
+ if (head) {
+ u32 dpT, dpB, L, R;
+
+ u16 *dst16 = (u16*) dst;
+
+ point = point0;
+
+ for (y=0; y<ch; y++) {
+ long X = ( (((((line)) & 0x3ffff) ? : 0x40000) << 5) / (vfraq) );
+
+ const u32 *srcT = (const u32 *)((char*) src + spitch * ( (((line)-1) >> 18) - 1 ));
+ const u32 *srcB = (const u32 *)((char*) src + spitch * ( (((line)-1) >> 18) ));
+
+
+
+
+ long pl = ( (((point)-1) >> 18) - 1 );
+ do {} while (0);
+
+ D_ASSERT( pl >= 0 );
+ D_ASSERT( pl < width-1 );
+ L = ( (((((srcT[pl]) & 0xff0000) >> 16)&0xF8) << 8) | (((((srcT[pl]) & 0x00ff00) >> 8)&0xFC) << 3) | (((((srcT[pl]) & 0x0000ff))&0xF8) >> 3) );
+ R = ( (((((srcT[pl+1]) & 0xff0000) >> 16)&0xF8) << 8) | (((((srcT[pl+1]) & 0x00ff00) >> 8)&0xFC) << 3) | (((((srcT[pl+1]) & 0x0000ff))&0xF8) >> 3) );
+
+ dpT = (((((R & 0xf81f)-(L & 0xf81f))*ratios[r] + ((L & 0xf81f)<<6)) & (0xf81f<<6)) +
+ ((((R & 0x07e0)-(L & 0x07e0))*ratios[r] + ((L & 0x07e0)<<6)) & (0x07e0<<6))) >> 6;
+
+ L = ( (((((srcB[pl]) & 0xff0000) >> 16)&0xF8) << 8) | (((((srcB[pl]) & 0x00ff00) >> 8)&0xFC) << 3) | (((((srcB[pl]) & 0x0000ff))&0xF8) >> 3) );
+ R = ( (((((srcB[pl+1]) & 0xff0000) >> 16)&0xF8) << 8) | (((((srcB[pl+1]) & 0x00ff00) >> 8)&0xFC) << 3) | (((((srcB[pl+1]) & 0x0000ff))&0xF8) >> 3) );
+
+ dpB = (((((R & 0xf81f)-(L & 0xf81f))*ratios[r] + ((L & 0xf81f)<<6)) & (0xf81f<<6)) +
+ ((((R & 0x07e0)-(L & 0x07e0))*ratios[r] + ((L & 0x07e0)<<6)) & (0x07e0<<6))) >> 6;
+# 138 "stretch_hvx_16.h"
+ dst16[0] = ((((((dpB & 0xf81f) - (dpT & 0xf81f))*X) >> 5) + (dpT & 0xf81f)) & 0xf81f) +
+ ((((((dpB>>5) & (0x07e0>>5)) - ((dpT>>5) & (0x07e0>>5)))*X) + (dpT & 0x07e0)) & 0x07e0);
+
+
+ dst16 += dpitch / 2;
+ line += vfraq;
+ }
+
+
+ point0 += hfraq;
+ dst32 = (u32*)((char*) dst + 2);
+
+
+ line = vfraq + ctx->clip.y1 * vfraq;
+ }
+
+
+
+
+ for (y=0; y<ch; y++) {
+ long X;
+ long nlT = ( (((line)-1) >> 18) - 1 );
+
+ D_ASSERT( nlT >= 0 );
+ D_ASSERT( nlT < height-1 );
+
+
+
+
+ if (nlT != lineT) {
+ u32 L, R, dpT, dpB;
+ const u32 *srcT = (const u32 *)((char*) src + spitch * nlT);
+ const u32 *srcB = (const u32 *)((char*) src + spitch * (nlT + 1));
+ long diff = nlT - lineT;
+
+ if (diff > 1) {
+
+
+
+ for (x=0, r=head, point=point0; x<w2; x++) {
+
+
+
+ long pl = ( (((point)-1) >> 18) - 1 );
+ do {} while (0);
+
+ D_ASSERT( pl >= 0 );
+ D_ASSERT( pl < width-1 );
+ L = ( (((((srcT[pl]) & 0xff0000) >> 16)&0xF8) << 8) | (((((srcT[pl]) & 0x00ff00) >> 8)&0xFC) << 3) | (((((srcT[pl]) & 0x0000ff))&0xF8) >> 3) );
+ R = ( (((((srcT[pl+1]) & 0xff0000) >> 16)&0xF8) << 8) | (((((srcT[pl+1]) & 0x00ff00) >> 8)&0xFC) << 3) | (((((srcT[pl+1]) & 0x0000ff))&0xF8) >> 3) );
+
+ dpT = (((((R & 0xf81f)-(L & 0xf81f))*ratios[r] + ((L & 0xf81f)<<6)) & (0xf81f<<6)) +
+ ((((R & 0x07e0)-(L & 0x07e0))*ratios[r] + ((L & 0x07e0)<<6)) & (0x07e0<<6)))
+
+
+
+ >> 6;
+
+
+ L = ( (((((srcB[pl]) & 0xff0000) >> 16)&0xF8) << 8) | (((((srcB[pl]) & 0x00ff00) >> 8)&0xFC) << 3) | (((((srcB[pl]) & 0x0000ff))&0xF8) >> 3) );
+ R = ( (((((srcB[pl+1]) & 0xff0000) >> 16)&0xF8) << 8) | (((((srcB[pl+1]) & 0x00ff00) >> 8)&0xFC) << 3) | (((((srcB[pl+1]) & 0x0000ff))&0xF8) >> 3) );
+
+ dpB = (((((R & 0xf81f)-(L & 0xf81f))*ratios[r] + ((L & 0xf81f)<<6)) & (0xf81f<<6)) +
+ ((((R & 0x07e0)-(L & 0x07e0))*ratios[r] + ((L & 0x07e0)<<6)) & (0x07e0<<6)))
+
+
+
+ >> 6;
+
+
+ point += hfraq;
+ r++;
+
+
+ pl = ( (((point)-1) >> 18) - 1 );
+ do {} while (0);
+
+ D_ASSERT( pl >= 0 );
+ D_ASSERT( pl < width-1 );
+
+ L = ( (((((srcT[pl]) & 0xff0000) >> 16)&0xF8) << 8) | (((((srcT[pl]) & 0x00ff00) >> 8)&0xFC) << 3) | (((((srcT[pl]) & 0x0000ff))&0xF8) >> 3) );
+ R = ( (((((srcT[pl+1]) & 0xff0000) >> 16)&0xF8) << 8) | (((((srcT[pl+1]) & 0x00ff00) >> 8)&0xFC) << 3) | (((((srcT[pl+1]) & 0x0000ff))&0xF8) >> 3) );
+
+ dpT |= (((((R & 0xf81f)-(L & 0xf81f))*ratios[r] + ((L & 0xf81f)<<6)) & (0xf81f<<6)) +
+ ((((R & 0x07e0)-(L & 0x07e0))*ratios[r] + ((L & 0x07e0)<<6)) & (0x07e0<<6)))
+
+
+
+ << (16-6);
+
+
+ L = ( (((((srcB[pl]) & 0xff0000) >> 16)&0xF8) << 8) | (((((srcB[pl]) & 0x00ff00) >> 8)&0xFC) << 3) | (((((srcB[pl]) & 0x0000ff))&0xF8) >> 3) );
+ R = ( (((((srcB[pl+1]) & 0xff0000) >> 16)&0xF8) << 8) | (((((srcB[pl+1]) & 0x00ff00) >> 8)&0xFC) << 3) | (((((srcB[pl+1]) & 0x0000ff))&0xF8) >> 3) );
+
+ dpB |= (((((R & 0xf81f)-(L & 0xf81f))*ratios[r] + ((L & 0xf81f)<<6)) & (0xf81f<<6)) +
+ ((((R & 0x07e0)-(L & 0x07e0))*ratios[r] + ((L & 0x07e0)<<6)) & (0x07e0<<6)))
+
+
+
+ << (16-6);
+
+
+ point += hfraq;
+ r++;
+
+
+ lbT[x] = dpT;
+ lbB[x] = dpB;
+ }
+ }
+ else {
+
+ lbX = lbT;
+ lbT = lbB;
+ lbB = lbX;
+
+
+
+
+ for (x=0, r=head, point=point0; x<w2; x++) {
+
+
+
+ long pl = ( (((point)-1) >> 18) - 1 );
+ do {} while (0);
+
+ D_ASSERT( pl >= 0 );
+ D_ASSERT( pl < width-1 );
+ L = ( (((((srcB[pl]) & 0xff0000) >> 16)&0xF8) << 8) | (((((srcB[pl]) & 0x00ff00) >> 8)&0xFC) << 3) | (((((srcB[pl]) & 0x0000ff))&0xF8) >> 3) );
+ R = ( (((((srcB[pl+1]) & 0xff0000) >> 16)&0xF8) << 8) | (((((srcB[pl+1]) & 0x00ff00) >> 8)&0xFC) << 3) | (((((srcB[pl+1]) & 0x0000ff))&0xF8) >> 3) );
+
+ dpB = (((((R & 0xf81f)-(L & 0xf81f))*ratios[r] + ((L & 0xf81f)<<6)) & (0xf81f<<6)) +
+ ((((R & 0x07e0)-(L & 0x07e0))*ratios[r] + ((L & 0x07e0)<<6)) & (0x07e0<<6)))
+
+
+
+ >> 6;
+
+
+ point += hfraq;
+ r++;
+
+
+ pl = ( (((point)-1) >> 18) - 1 );
+ do {} while (0);
+
+ D_ASSERT( pl >= 0 );
+ D_ASSERT( pl < width-1 );
+
+ L = ( (((((srcB[pl]) & 0xff0000) >> 16)&0xF8) << 8) | (((((srcB[pl]) & 0x00ff00) >> 8)&0xFC) << 3) | (((((srcB[pl]) & 0x0000ff))&0xF8) >> 3) );
+ R = ( (((((srcB[pl+1]) & 0xff0000) >> 16)&0xF8) << 8) | (((((srcB[pl+1]) & 0x00ff00) >> 8)&0xFC) << 3) | (((((srcB[pl+1]) & 0x0000ff))&0xF8) >> 3) );
+
+ dpB |= (((((R & 0xf81f)-(L & 0xf81f))*ratios[r] + ((L & 0xf81f)<<6)) & (0xf81f<<6)) +
+ ((((R & 0x07e0)-(L & 0x07e0))*ratios[r] + ((L & 0x07e0)<<6)) & (0x07e0<<6)))
+
+
+
+ << (16-6);
+
+
+ point += hfraq;
+ r++;
+
+
+ lbB[x] = dpB;
+ }
+ }
+
+ lineT = nlT;
+ }
+
+
+
+
+ X = ( (((((line)) & 0x3ffff) ? : 0x40000) << 5) / (vfraq) );
+
+ for (x=0; x<w2; x++) {
+# 371 "stretch_hvx_16.h"
+ dst32[x] = ((((((lbB[x] & ((0x07e0<<16) | 0xf81f)) - (lbT[x] & ((0x07e0<<16) | 0xf81f)))*X) >> 5) + (lbT[x] & ((0x07e0<<16) | 0xf81f))) & ((0x07e0<<16) | 0xf81f)) +
+ ((((((lbB[x]>>5) & (((0xf81f<<16) | 0x07e0)>>5)) - ((lbT[x]>>5) & (((0xf81f<<16) | 0x07e0)>>5)))*X) + (lbT[x] & ((0xf81f<<16) | 0x07e0))) & ((0xf81f<<16) | 0x07e0));
+
+
+ }
+
+ dst32 += dp4;
+ line += vfraq;
+ }
+
+ if (tail) {
+ u32 dpT, dpB, L, R;
+
+ u16 *dst16 = (u16*)((char*) dst + cw * 2 - 2);
+
+
+ line = vfraq + ctx->clip.y1 * vfraq;
+
+ for (y=0; y<ch; y++) {
+ long X = ( (((((line)) & 0x3ffff) ? : 0x40000) << 5) / (vfraq) );
+
+ const u32 *srcT = (const u32 *)((char*) src + spitch * ( (((line)-1) >> 18) - 1 ));
+ const u32 *srcB = (const u32 *)((char*) src + spitch * ( (((line)-1) >> 18) ));
+
+
+
+
+ long pl = ( (((point)-1) >> 18) - 1 );
+ do {} while (0);
+
+ D_ASSERT( pl >= 0 );
+ D_ASSERT( pl < width-1 );
+ L = ( (((((srcT[pl]) & 0xff0000) >> 16)&0xF8) << 8) | (((((srcT[pl]) & 0x00ff00) >> 8)&0xFC) << 3) | (((((srcT[pl]) & 0x0000ff))&0xF8) >> 3) );
+ R = ( (((((srcT[pl+1]) & 0xff0000) >> 16)&0xF8) << 8) | (((((srcT[pl+1]) & 0x00ff00) >> 8)&0xFC) << 3) | (((((srcT[pl+1]) & 0x0000ff))&0xF8) >> 3) );
+
+ dpT = (((((R & 0xf81f)-(L & 0xf81f))*ratios[r] + ((L & 0xf81f)<<6)) & (0xf81f<<6)) +
+ ((((R & 0x07e0)-(L & 0x07e0))*ratios[r] + ((L & 0x07e0)<<6)) & (0x07e0<<6))) >> 6;
+
+ L = ( (((((srcB[pl]) & 0xff0000) >> 16)&0xF8) << 8) | (((((srcB[pl]) & 0x00ff00) >> 8)&0xFC) << 3) | (((((srcB[pl]) & 0x0000ff))&0xF8) >> 3) );
+ R = ( (((((srcB[pl+1]) & 0xff0000) >> 16)&0xF8) << 8) | (((((srcB[pl+1]) & 0x00ff00) >> 8)&0xFC) << 3) | (((((srcB[pl+1]) & 0x0000ff))&0xF8) >> 3) );
+
+ dpB = (((((R & 0xf81f)-(L & 0xf81f))*ratios[r] + ((L & 0xf81f)<<6)) & (0xf81f<<6)) +
+ ((((R & 0x07e0)-(L & 0x07e0))*ratios[r] + ((L & 0x07e0)<<6)) & (0x07e0<<6))) >> 6;
+# 434 "stretch_hvx_16.h"
+ dst16[0] = ((((((dpB & 0xf81f) - (dpT & 0xf81f))*X) >> 5) + (dpT & 0xf81f)) & 0xf81f) +
+ ((((((dpB>>5) & (0x07e0>>5)) - ((dpT>>5) & (0x07e0>>5)))*X) + (dpT & 0x07e0)) & 0x07e0);
+
+
+ dst16 += dpitch / 2;
+ line += vfraq;
+ }
+ }
+}
+# 22 "stretch_hvx_N.h" 2
+# 50 "stretch_up_down_16.h" 2
+# 48 "Scaler.cxx" 2
+# 73 "Scaler.cxx"
+# 1 "stretch_up_down_32.h" 1
+# 20 "stretch_up_down_32.h"
+# 1 "stretch_hvx_N.h" 1
+# 9 "stretch_hvx_N.h"
+static void stretch_hvx_ARGB_up____DSPF_ARGB
+# 1 "stretch_hvx_32.h" 1
+# 11 "stretch_hvx_32.h"
+ ( void *dst,
+ int dpitch,
+ const void *src,
+ int spitch,
+ int width,
+ int height,
+ int dst_width,
+ int dst_height,
+ const StretchCtx *ctx )
+{
+ long x, y = 0;
+ long cw = ctx->clip.x2 - ctx->clip.x1 + 1;
+ long ch = ctx->clip.y2 - ctx->clip.y1 + 1;
+ long hfraq = ((long)(width - 1) << 18) / (long)(dst_width);
+ long vfraq = ((long)(height - 1) << 18) / (long)(dst_height);
+ long dp4 = dpitch / 4;
+ long point0 = 0 + ctx->clip.x1 * hfraq;
+ long point = point0;
+ long line = 0 + ctx->clip.y1 * vfraq;
+ long ratios[cw];
+ u32 *dst32;
+
+
+
+
+
+ u32 _lbT[cw+8];
+ u32 _lbB[cw+8];
+
+ u32 *lbX;
+ u32 *lbT = (u32*)((((unsigned long)(&_lbT[0])) + 31) & ~31);
+ u32 *lbB = (u32*)((((unsigned long)(&_lbB[0])) + 31) & ~31);
+
+ long lineT = -2000;
+
+ for (x=0; x<cw; x++) {
+ ratios[x] = ( ((point) & 0x3ffff) >> (18-8) );
+
+ point += hfraq;
+ }
+
+ do {} while (0);
+
+ dst = (void*)((char*) dst + ctx->clip.x1 * 4 + ctx->clip.y1 * dpitch);
+
+ dst32 = (u32*) dst;
+
+
+
+
+ for (y=0; y<ch; y++) {
+ long X;
+ long nlT = ( (((line)) >> 18) );
+
+ D_ASSERT( nlT >= 0 );
+ D_ASSERT( nlT < height-1 );
+
+
+
+
+ if (nlT != lineT) {
+ u32 L, R;
+ const u32 *srcT = (const u32 *)((const char*) src + spitch * nlT);
+ const u32 *srcB = (const u32 *)((const char*) src + spitch * (nlT + 1));
+ long diff = nlT - lineT;
+
+ if (diff > 1) {
+
+
+
+ for (x=0, point=point0; x<cw; x++, point += hfraq) {
+ long pl = ( (((point)) >> 18) );
+ do {} while (0);
+
+ D_ASSERT( pl >= 0 );
+ D_ASSERT( pl < width-1 );
+
+ L = (srcT[pl]);
+ R = (srcT[pl+1]);
+
+ lbT[x]= ((((((R & 0x00ff00ff) - (L & 0x00ff00ff))*ratios[x]) >> 8) + (L & 0x00ff00ff)) & 0x00ff00ff) +
+ ((((((R>>8) & 0x00ff00ff) - ((L>>8) & 0x00ff00ff))*ratios[x]) + (L & 0xff00ff00)) & 0xff00ff00);
+
+ L = (srcB[pl]);
+ R = (srcB[pl+1]);
+
+ lbB[x] = ((((((R & 0x00ff00ff) - (L & 0x00ff00ff))*ratios[x]) >> 8) + (L & 0x00ff00ff)) & 0x00ff00ff) +
+ ((((((R>>8) & 0x00ff00ff) - ((L>>8) & 0x00ff00ff))*ratios[x]) + (L & 0xff00ff00)) & 0xff00ff00);
+ }
+ }
+ else {
+
+ lbX = lbT;
+ lbT = lbB;
+ lbB = lbX;
+
+
+
+
+ for (x=0, point=point0; x<cw; x++, point += hfraq) {
+ long pl = ( (((point)) >> 18) );
+ do {} while (0);
+
+ D_ASSERT( pl >= 0 );
+ D_ASSERT( pl < width-1 );
+
+ L = (srcB[pl]);
+ R = (srcB[pl+1]);
+
+ lbB[x] = ((((((R & 0x00ff00ff) - (L & 0x00ff00ff))*ratios[x]) >> 8) + (L & 0x00ff00ff)) & 0x00ff00ff) +
+ ((((((R>>8) & 0x00ff00ff) - ((L>>8) & 0x00ff00ff))*ratios[x]) + (L & 0xff00ff00)) & 0xff00ff00);
+ }
+ }
+
+ lineT = nlT;
+ }
+
+
+
+
+ X = ( ((line) & 0x3ffff) >> (18-8) );
+
+ for (x=0; x<cw; x++) {
+# 149 "stretch_hvx_32.h"
+ dst32[x] = ((((((lbB[x] & 0x00ff00ff) - (lbT[x] & 0x00ff00ff))*X) >> 8) + (lbT[x] & 0x00ff00ff)) & 0x00ff00ff) +
+ ((((((lbB[x]>>8) & 0x00ff00ff) - ((lbT[x]>>8) & 0x00ff00ff))*X) + (lbT[x] & 0xff00ff00)) & 0xff00ff00);
+
+ }
+
+ dst32 += dp4;
+ line += vfraq;
+ }
+}
+# 11 "stretch_hvx_N.h" 2
+# 33 "stretch_hvx_N.h"
+static void stretch_hvx_ARGB_up____DSPF_RGB32
+# 1 "stretch_hvx_32.h" 1
+# 11 "stretch_hvx_32.h"
+ ( void *dst,
+ int dpitch,
+ const void *src,
+ int spitch,
+ int width,
+ int height,
+ int dst_width,
+ int dst_height,
+ const StretchCtx *ctx )
+{
+ long x, y = 0;
+ long cw = ctx->clip.x2 - ctx->clip.x1 + 1;
+ long ch = ctx->clip.y2 - ctx->clip.y1 + 1;
+ long hfraq = ((long)(width - 1) << 18) / (long)(dst_width);
+ long vfraq = ((long)(height - 1) << 18) / (long)(dst_height);
+ long dp4 = dpitch / 4;
+ long point0 = 0 + ctx->clip.x1 * hfraq;
+ long point = point0;
+ long line = 0 + ctx->clip.y1 * vfraq;
+ long ratios[cw];
+ u32 *dst32;
+
+
+
+
+
+ u32 _lbT[cw+8];
+ u32 _lbB[cw+8];
+
+ u32 *lbX;
+ u32 *lbT = (u32*)((((unsigned long)(&_lbT[0])) + 31) & ~31);
+ u32 *lbB = (u32*)((((unsigned long)(&_lbB[0])) + 31) & ~31);
+
+ long lineT = -2000;
+
+ for (x=0; x<cw; x++) {
+ ratios[x] = ( ((point) & 0x3ffff) >> (18-8) );
+
+ point += hfraq;
+ }
+
+ do {} while (0);
+
+ dst = (void*)((char*) dst + ctx->clip.x1 * 4 + ctx->clip.y1 * dpitch);
+
+ dst32 = (u32*) dst;
+
+
+
+
+ for (y=0; y<ch; y++) {
+ long X;
+ long nlT = ( (((line)) >> 18) );
+
+ D_ASSERT( nlT >= 0 );
+ D_ASSERT( nlT < height-1 );
+
+
+
+
+ if (nlT != lineT) {
+ u32 L, R;
+ const u32 *srcT = (const u32 *)((const char*) src + spitch * nlT);
+ const u32 *srcB = (const u32 *)((const char*) src + spitch * (nlT + 1));
+ long diff = nlT - lineT;
+
+ if (diff > 1) {
+
+
+
+ for (x=0, point=point0; x<cw; x++, point += hfraq) {
+ long pl = ( (((point)) >> 18) );
+ do {} while (0);
+
+ D_ASSERT( pl >= 0 );
+ D_ASSERT( pl < width-1 );
+
+ L = ((srcT[pl]) | 0xff000000);
+ R = ((srcT[pl+1]) | 0xff000000);
+
+ lbT[x]= ((((((R & 0x00ff00ff) - (L & 0x00ff00ff))*ratios[x]) >> 8) + (L & 0x00ff00ff)) & 0x00ff00ff) +
+ ((((((R>>8) & 0x00ff00ff) - ((L>>8) & 0x00ff00ff))*ratios[x]) + (L & 0xff00ff00)) & 0xff00ff00);
+
+ L = ((srcB[pl]) | 0xff000000);
+ R = ((srcB[pl+1]) | 0xff000000);
+
+ lbB[x] = ((((((R & 0x00ff00ff) - (L & 0x00ff00ff))*ratios[x]) >> 8) + (L & 0x00ff00ff)) & 0x00ff00ff) +
+ ((((((R>>8) & 0x00ff00ff) - ((L>>8) & 0x00ff00ff))*ratios[x]) + (L & 0xff00ff00)) & 0xff00ff00);
+ }
+ }
+ else {
+
+ lbX = lbT;
+ lbT = lbB;
+ lbB = lbX;
+
+
+
+
+ for (x=0, point=point0; x<cw; x++, point += hfraq) {
+ long pl = ( (((point)) >> 18) );
+ do {} while (0);
+
+ D_ASSERT( pl >= 0 );
+ D_ASSERT( pl < width-1 );
+
+ L = ((srcB[pl]) | 0xff000000);
+ R = ((srcB[pl+1]) | 0xff000000);
+
+ lbB[x] = ((((((R & 0x00ff00ff) - (L & 0x00ff00ff))*ratios[x]) >> 8) + (L & 0x00ff00ff)) & 0x00ff00ff) +
+ ((((((R>>8) & 0x00ff00ff) - ((L>>8) & 0x00ff00ff))*ratios[x]) + (L & 0xff00ff00)) & 0xff00ff00);
+ }
+ }
+
+ lineT = nlT;
+ }
+
+
+
+
+ X = ( ((line) & 0x3ffff) >> (18-8) );
+
+ for (x=0; x<cw; x++) {
+# 149 "stretch_hvx_32.h"
+ dst32[x] = ((((((lbB[x] & 0x00ff00ff) - (lbT[x] & 0x00ff00ff))*X) >> 8) + (lbT[x] & 0x00ff00ff)) & 0x00ff00ff) +
+ ((((((lbB[x]>>8) & 0x00ff00ff) - ((lbT[x]>>8) & 0x00ff00ff))*X) + (lbT[x] & 0xff00ff00)) & 0xff00ff00);
+
+ }
+
+ dst32 += dp4;
+ line += vfraq;
+ }
+}
+# 35 "stretch_hvx_N.h" 2
+# 21 "stretch_up_down_32.h" 2
+# 49 "stretch_up_down_32.h"
+# 1 "stretch_hvx_N.h" 1
+# 9 "stretch_hvx_N.h"
+static void stretch_hvx_ARGB_down____DSPF_ARGB
+# 1 "stretch_hvx_32.h" 1
+# 11 "stretch_hvx_32.h"
+ ( void *dst,
+ int dpitch,
+ const void *src,
+ int spitch,
+ int width,
+ int height,
+ int dst_width,
+ int dst_height,
+ const StretchCtx *ctx )
+{
+ long x, y = 0;
+ long cw = ctx->clip.x2 - ctx->clip.x1 + 1;
+ long ch = ctx->clip.y2 - ctx->clip.y1 + 1;
+ long hfraq = ((long)(width - 0) << 18) / (long)(dst_width);
+ long vfraq = ((long)(height - 0) << 18) / (long)(dst_height);
+ long dp4 = dpitch / 4;
+ long point0 = hfraq + ctx->clip.x1 * hfraq;
+ long point = point0;
+ long line = vfraq + ctx->clip.y1 * vfraq;
+ long ratios[cw];
+ u32 *dst32;
+
+
+
+
+
+ u32 _lbT[cw+8];
+ u32 _lbB[cw+8];
+
+ u32 *lbX;
+ u32 *lbT = (u32*)((((unsigned long)(&_lbT[0])) + 31) & ~31);
+ u32 *lbB = (u32*)((((unsigned long)(&_lbB[0])) + 31) & ~31);
+
+ long lineT = -2000;
+
+ for (x=0; x<cw; x++) {
+ ratios[x] = ( (((((point)) & 0x3ffff) ? : 0x40000) << 8) / (hfraq) );
+
+ point += hfraq;
+ }
+
+ do {} while (0);
+
+ dst = (void*)((char*) dst + ctx->clip.x1 * 4 + ctx->clip.y1 * dpitch);
+
+ dst32 = (u32*) dst;
+
+
+
+
+ for (y=0; y<ch; y++) {
+ long X;
+ long nlT = ( (((line)-1) >> 18) - 1 );
+
+ D_ASSERT( nlT >= 0 );
+ D_ASSERT( nlT < height-1 );
+
+
+
+
+ if (nlT != lineT) {
+ u32 L, R;
+ const u32 *srcT = (const u32 *)((const char*) src + spitch * nlT);
+ const u32 *srcB = (const u32 *)((const char*) src + spitch * (nlT + 1));
+ long diff = nlT - lineT;
+
+ if (diff > 1) {
+
+
+
+ for (x=0, point=point0; x<cw; x++, point += hfraq) {
+ long pl = ( (((point)-1) >> 18) - 1 );
+ do {} while (0);
+
+ D_ASSERT( pl >= 0 );
+ D_ASSERT( pl < width-1 );
+
+ L = (srcT[pl]);
+ R = (srcT[pl+1]);
+
+ lbT[x]= ((((((R & 0x00ff00ff) - (L & 0x00ff00ff))*ratios[x]) >> 8) + (L & 0x00ff00ff)) & 0x00ff00ff) +
+ ((((((R>>8) & 0x00ff00ff) - ((L>>8) & 0x00ff00ff))*ratios[x]) + (L & 0xff00ff00)) & 0xff00ff00);
+
+ L = (srcB[pl]);
+ R = (srcB[pl+1]);
+
+ lbB[x] = ((((((R & 0x00ff00ff) - (L & 0x00ff00ff))*ratios[x]) >> 8) + (L & 0x00ff00ff)) & 0x00ff00ff) +
+ ((((((R>>8) & 0x00ff00ff) - ((L>>8) & 0x00ff00ff))*ratios[x]) + (L & 0xff00ff00)) & 0xff00ff00);
+ }
+ }
+ else {
+
+ lbX = lbT;
+ lbT = lbB;
+ lbB = lbX;
+
+
+
+
+ for (x=0, point=point0; x<cw; x++, point += hfraq) {
+ long pl = ( (((point)-1) >> 18) - 1 );
+ do {} while (0);
+
+ D_ASSERT( pl >= 0 );
+ D_ASSERT( pl < width-1 );
+
+ L = (srcB[pl]);
+ R = (srcB[pl+1]);
+
+ lbB[x] = ((((((R & 0x00ff00ff) - (L & 0x00ff00ff))*ratios[x]) >> 8) + (L & 0x00ff00ff)) & 0x00ff00ff) +
+ ((((((R>>8) & 0x00ff00ff) - ((L>>8) & 0x00ff00ff))*ratios[x]) + (L & 0xff00ff00)) & 0xff00ff00);
+ }
+ }
+
+ lineT = nlT;
+ }
+
+
+
+
+ X = ( (((((line)) & 0x3ffff) ? : 0x40000) << 8) / (vfraq) );
+
+ for (x=0; x<cw; x++) {
+# 149 "stretch_hvx_32.h"
+ dst32[x] = ((((((lbB[x] & 0x00ff00ff) - (lbT[x] & 0x00ff00ff))*X) >> 8) + (lbT[x] & 0x00ff00ff)) & 0x00ff00ff) +
+ ((((((lbB[x]>>8) & 0x00ff00ff) - ((lbT[x]>>8) & 0x00ff00ff))*X) + (lbT[x] & 0xff00ff00)) & 0xff00ff00);
+
+ }
+
+ dst32 += dp4;
+ line += vfraq;
+ }
+}
+# 11 "stretch_hvx_N.h" 2
+# 33 "stretch_hvx_N.h"
+static void stretch_hvx_ARGB_down____DSPF_RGB32
+# 1 "stretch_hvx_32.h" 1
+# 11 "stretch_hvx_32.h"
+ ( void *dst,
+ int dpitch,
+ const void *src,
+ int spitch,
+ int width,
+ int height,
+ int dst_width,
+ int dst_height,
+ const StretchCtx *ctx )
+{
+ long x, y = 0;
+ long cw = ctx->clip.x2 - ctx->clip.x1 + 1;
+ long ch = ctx->clip.y2 - ctx->clip.y1 + 1;
+ long hfraq = ((long)(width - 0) << 18) / (long)(dst_width);
+ long vfraq = ((long)(height - 0) << 18) / (long)(dst_height);
+ long dp4 = dpitch / 4;
+ long point0 = hfraq + ctx->clip.x1 * hfraq;
+ long point = point0;
+ long line = vfraq + ctx->clip.y1 * vfraq;
+ long ratios[cw];
+ u32 *dst32;
+
+
+
+
+
+ u32 _lbT[cw+8];
+ u32 _lbB[cw+8];
+
+ u32 *lbX;
+ u32 *lbT = (u32*)((((unsigned long)(&_lbT[0])) + 31) & ~31);
+ u32 *lbB = (u32*)((((unsigned long)(&_lbB[0])) + 31) & ~31);
+
+ long lineT = -2000;
+
+ for (x=0; x<cw; x++) {
+ ratios[x] = ( (((((point)) & 0x3ffff) ? : 0x40000) << 8) / (hfraq) );
+
+ point += hfraq;
+ }
+
+ do {} while (0);
+
+ dst = (void*)((char*) dst + ctx->clip.x1 * 4 + ctx->clip.y1 * dpitch);
+
+ dst32 = (u32*) dst;
+
+
+
+
+ for (y=0; y<ch; y++) {
+ long X;
+ long nlT = ( (((line)-1) >> 18) - 1 );
+
+ D_ASSERT( nlT >= 0 );
+ D_ASSERT( nlT < height-1 );
+
+
+
+
+ if (nlT != lineT) {
+ u32 L, R;
+ const u32 *srcT = (const u32 *)((const char*) src + spitch * nlT);
+ const u32 *srcB = (const u32 *)((const char*) src + spitch * (nlT + 1));
+ long diff = nlT - lineT;
+
+ if (diff > 1) {
+
+
+
+ for (x=0, point=point0; x<cw; x++, point += hfraq) {
+ long pl = ( (((point)-1) >> 18) - 1 );
+ do {} while (0);
+
+ D_ASSERT( pl >= 0 );
+ D_ASSERT( pl < width-1 );
+
+ L = ((srcT[pl]) | 0xff000000);
+ R = ((srcT[pl+1]) | 0xff000000);
+
+ lbT[x]= ((((((R & 0x00ff00ff) - (L & 0x00ff00ff))*ratios[x]) >> 8) + (L & 0x00ff00ff)) & 0x00ff00ff) +
+ ((((((R>>8) & 0x00ff00ff) - ((L>>8) & 0x00ff00ff))*ratios[x]) + (L & 0xff00ff00)) & 0xff00ff00);
+
+ L = ((srcB[pl]) | 0xff000000);
+ R = ((srcB[pl+1]) | 0xff000000);
+
+ lbB[x] = ((((((R & 0x00ff00ff) - (L & 0x00ff00ff))*ratios[x]) >> 8) + (L & 0x00ff00ff)) & 0x00ff00ff) +
+ ((((((R>>8) & 0x00ff00ff) - ((L>>8) & 0x00ff00ff))*ratios[x]) + (L & 0xff00ff00)) & 0xff00ff00);
+ }
+ }
+ else {
+
+ lbX = lbT;
+ lbT = lbB;
+ lbB = lbX;
+
+
+
+
+ for (x=0, point=point0; x<cw; x++, point += hfraq) {
+ long pl = ( (((point)-1) >> 18) - 1 );
+ do {} while (0);
+
+ D_ASSERT( pl >= 0 );
+ D_ASSERT( pl < width-1 );
+
+ L = ((srcB[pl]) | 0xff000000);
+ R = ((srcB[pl+1]) | 0xff000000);
+
+ lbB[x] = ((((((R & 0x00ff00ff) - (L & 0x00ff00ff))*ratios[x]) >> 8) + (L & 0x00ff00ff)) & 0x00ff00ff) +
+ ((((((R>>8) & 0x00ff00ff) - ((L>>8) & 0x00ff00ff))*ratios[x]) + (L & 0xff00ff00)) & 0xff00ff00);
+ }
+ }
+
+ lineT = nlT;
+ }
+
+
+
+
+ X = ( (((((line)) & 0x3ffff) ? : 0x40000) << 8) / (vfraq) );
+
+ for (x=0; x<cw; x++) {
+# 149 "stretch_hvx_32.h"
+ dst32[x] = ((((((lbB[x] & 0x00ff00ff) - (lbT[x] & 0x00ff00ff))*X) >> 8) + (lbT[x] & 0x00ff00ff)) & 0x00ff00ff) +
+ ((((((lbB[x]>>8) & 0x00ff00ff) - ((lbT[x]>>8) & 0x00ff00ff))*X) + (lbT[x] & 0xff00ff00)) & 0xff00ff00);
+
+ }
+
+ dst32 += dp4;
+ line += vfraq;
+ }
+}
+# 35 "stretch_hvx_N.h" 2
+# 50 "stretch_up_down_32.h" 2
+# 74 "Scaler.cxx" 2
+# 99 "Scaler.cxx"
+# 1 "stretch_up_down_32.h" 1
+# 20 "stretch_up_down_32.h"
+# 1 "stretch_hvx_N.h" 1
+# 9 "stretch_hvx_N.h"
+static void stretch_hvx_RGB32_up____DSPF_RGB32
+# 1 "stretch_hvx_32.h" 1
+# 11 "stretch_hvx_32.h"
+ ( void *dst,
+ int dpitch,
+ const void *src,
+ int spitch,
+ int width,
+ int height,
+ int dst_width,
+ int dst_height,
+ const StretchCtx *ctx )
+{
+ long x, y = 0;
+ long cw = ctx->clip.x2 - ctx->clip.x1 + 1;
+ long ch = ctx->clip.y2 - ctx->clip.y1 + 1;
+ long hfraq = ((long)(width - 1) << 18) / (long)(dst_width);
+ long vfraq = ((long)(height - 1) << 18) / (long)(dst_height);
+ long dp4 = dpitch / 4;
+ long point0 = 0 + ctx->clip.x1 * hfraq;
+ long point = point0;
+ long line = 0 + ctx->clip.y1 * vfraq;
+ long ratios[cw];
+ u32 *dst32;
+
+
+
+
+
+ u32 _lbT[cw+8];
+ u32 _lbB[cw+8];
+
+ u32 *lbX;
+ u32 *lbT = (u32*)((((unsigned long)(&_lbT[0])) + 31) & ~31);
+ u32 *lbB = (u32*)((((unsigned long)(&_lbB[0])) + 31) & ~31);
+
+ long lineT = -2000;
+
+ for (x=0; x<cw; x++) {
+ ratios[x] = ( ((point) & 0x3ffff) >> (18-8) );
+
+ point += hfraq;
+ }
+
+ do {} while (0);
+
+ dst = (void*)((char*) dst + ctx->clip.x1 * 4 + ctx->clip.y1 * dpitch);
+
+ dst32 = (u32*) dst;
+
+
+
+
+ for (y=0; y<ch; y++) {
+ long X;
+ long nlT = ( (((line)) >> 18) );
+
+ D_ASSERT( nlT >= 0 );
+ D_ASSERT( nlT < height-1 );
+
+
+
+
+ if (nlT != lineT) {
+ u32 L, R;
+ const u32 *srcT = (const u32 *)((const char*) src + spitch * nlT);
+ const u32 *srcB = (const u32 *)((const char*) src + spitch * (nlT + 1));
+ long diff = nlT - lineT;
+
+ if (diff > 1) {
+
+
+
+ for (x=0, point=point0; x<cw; x++, point += hfraq) {
+ long pl = ( (((point)) >> 18) );
+ do {} while (0);
+
+ D_ASSERT( pl >= 0 );
+ D_ASSERT( pl < width-1 );
+
+ L = (srcT[pl]);
+ R = (srcT[pl+1]);
+
+ lbT[x]= ((((((R & 0x00ff00ff) - (L & 0x00ff00ff))*ratios[x]) >> 8) + (L & 0x00ff00ff)) & 0x00ff00ff) +
+ ((((((R>>8) & 0x00ff00ff) - ((L>>8) & 0x00ff00ff))*ratios[x]) + (L & 0x0000ff00)) & 0x0000ff00);
+
+ L = (srcB[pl]);
+ R = (srcB[pl+1]);
+
+ lbB[x] = ((((((R & 0x00ff00ff) - (L & 0x00ff00ff))*ratios[x]) >> 8) + (L & 0x00ff00ff)) & 0x00ff00ff) +
+ ((((((R>>8) & 0x00ff00ff) - ((L>>8) & 0x00ff00ff))*ratios[x]) + (L & 0x0000ff00)) & 0x0000ff00);
+ }
+ }
+ else {
+
+ lbX = lbT;
+ lbT = lbB;
+ lbB = lbX;
+
+
+
+
+ for (x=0, point=point0; x<cw; x++, point += hfraq) {
+ long pl = ( (((point)) >> 18) );
+ do {} while (0);
+
+ D_ASSERT( pl >= 0 );
+ D_ASSERT( pl < width-1 );
+
+ L = (srcB[pl]);
+ R = (srcB[pl+1]);
+
+ lbB[x] = ((((((R & 0x00ff00ff) - (L & 0x00ff00ff))*ratios[x]) >> 8) + (L & 0x00ff00ff)) & 0x00ff00ff) +
+ ((((((R>>8) & 0x00ff00ff) - ((L>>8) & 0x00ff00ff))*ratios[x]) + (L & 0x0000ff00)) & 0x0000ff00);
+ }
+ }
+
+ lineT = nlT;
+ }
+
+
+
+
+ X = ( ((line) & 0x3ffff) >> (18-8) );
+
+ for (x=0; x<cw; x++) {
+# 149 "stretch_hvx_32.h"
+ dst32[x] = ((((((lbB[x] & 0x00ff00ff) - (lbT[x] & 0x00ff00ff))*X) >> 8) + (lbT[x] & 0x00ff00ff)) & 0x00ff00ff) +
+ ((((((lbB[x]>>8) & 0x00ff00ff) - ((lbT[x]>>8) & 0x00ff00ff))*X) + (lbT[x] & 0x0000ff00)) & 0x0000ff00);
+
+ }
+
+ dst32 += dp4;
+ line += vfraq;
+ }
+}
+# 11 "stretch_hvx_N.h" 2
+# 21 "stretch_up_down_32.h" 2
+# 49 "stretch_up_down_32.h"
+# 1 "stretch_hvx_N.h" 1
+# 9 "stretch_hvx_N.h"
+static void stretch_hvx_RGB32_down____DSPF_RGB32
+# 1 "stretch_hvx_32.h" 1
+# 11 "stretch_hvx_32.h"
+ ( void *dst,
+ int dpitch,
+ const void *src,
+ int spitch,
+ int width,
+ int height,
+ int dst_width,
+ int dst_height,
+ const StretchCtx *ctx )
+{
+ long x, y = 0;
+ long cw = ctx->clip.x2 - ctx->clip.x1 + 1;
+ long ch = ctx->clip.y2 - ctx->clip.y1 + 1;
+ long hfraq = ((long)(width - 0) << 18) / (long)(dst_width);
+ long vfraq = ((long)(height - 0) << 18) / (long)(dst_height);
+ long dp4 = dpitch / 4;
+ long point0 = hfraq + ctx->clip.x1 * hfraq;
+ long point = point0;
+ long line = vfraq + ctx->clip.y1 * vfraq;
+ long ratios[cw];
+ u32 *dst32;
+
+
+
+
+
+ u32 _lbT[cw+8];
+ u32 _lbB[cw+8];
+
+ u32 *lbX;
+ u32 *lbT = (u32*)((((unsigned long)(&_lbT[0])) + 31) & ~31);
+ u32 *lbB = (u32*)((((unsigned long)(&_lbB[0])) + 31) & ~31);
+
+ long lineT = -2000;
+
+ for (x=0; x<cw; x++) {
+ ratios[x] = ( (((((point)) & 0x3ffff) ? : 0x40000) << 8) / (hfraq) );
+
+ point += hfraq;
+ }
+
+ do {} while (0);
+
+ dst = (void*)((char*) dst + ctx->clip.x1 * 4 + ctx->clip.y1 * dpitch);
+
+ dst32 = (u32*) dst;
+
+
+
+
+ for (y=0; y<ch; y++) {
+ long X;
+ long nlT = ( (((line)-1) >> 18) - 1 );
+
+ D_ASSERT( nlT >= 0 );
+ D_ASSERT( nlT < height-1 );
+
+
+
+
+ if (nlT != lineT) {
+ u32 L, R;
+ const u32 *srcT = (const u32 *)((const char*) src + spitch * nlT);
+ const u32 *srcB = (const u32 *)((const char*) src + spitch * (nlT + 1));
+ long diff = nlT - lineT;
+
+ if (diff > 1) {
+
+
+
+ for (x=0, point=point0; x<cw; x++, point += hfraq) {
+ long pl = ( (((point)-1) >> 18) - 1 );
+ do {} while (0);
+
+ D_ASSERT( pl >= 0 );
+ D_ASSERT( pl < width-1 );
+
+ L = (srcT[pl]);
+ R = (srcT[pl+1]);
+
+ lbT[x]= ((((((R & 0x00ff00ff) - (L & 0x00ff00ff))*ratios[x]) >> 8) + (L & 0x00ff00ff)) & 0x00ff00ff) +
+ ((((((R>>8) & 0x00ff00ff) - ((L>>8) & 0x00ff00ff))*ratios[x]) + (L & 0x0000ff00)) & 0x0000ff00);
+
+ L = (srcB[pl]);
+ R = (srcB[pl+1]);
+
+ lbB[x] = ((((((R & 0x00ff00ff) - (L & 0x00ff00ff))*ratios[x]) >> 8) + (L & 0x00ff00ff)) & 0x00ff00ff) +
+ ((((((R>>8) & 0x00ff00ff) - ((L>>8) & 0x00ff00ff))*ratios[x]) + (L & 0x0000ff00)) & 0x0000ff00);
+ }
+ }
+ else {
+
+ lbX = lbT;
+ lbT = lbB;
+ lbB = lbX;
+
+
+
+
+ for (x=0, point=point0; x<cw; x++, point += hfraq) {
+ long pl = ( (((point)-1) >> 18) - 1 );
+ do {} while (0);
+
+ D_ASSERT( pl >= 0 );
+ D_ASSERT( pl < width-1 );
+
+ L = (srcB[pl]);
+ R = (srcB[pl+1]);
+
+ lbB[x] = ((((((R & 0x00ff00ff) - (L & 0x00ff00ff))*ratios[x]) >> 8) + (L & 0x00ff00ff)) & 0x00ff00ff) +
+ ((((((R>>8) & 0x00ff00ff) - ((L>>8) & 0x00ff00ff))*ratios[x]) + (L & 0x0000ff00)) & 0x0000ff00);
+ }
+ }
+
+ lineT = nlT;
+ }
+
+
+
+
+ X = ( (((((line)) & 0x3ffff) ? : 0x40000) << 8) / (vfraq) );
+
+ for (x=0; x<cw; x++) {
+# 149 "stretch_hvx_32.h"
+ dst32[x] = ((((((lbB[x] & 0x00ff00ff) - (lbT[x] & 0x00ff00ff))*X) >> 8) + (lbT[x] & 0x00ff00ff)) & 0x00ff00ff) +
+ ((((((lbB[x]>>8) & 0x00ff00ff) - ((lbT[x]>>8) & 0x00ff00ff))*X) + (lbT[x] & 0x0000ff00)) & 0x0000ff00);
+
+ }
+
+ dst32 += dp4;
+ line += vfraq;
+ }
+}
+# 11 "stretch_hvx_N.h" 2
+# 50 "stretch_up_down_32.h" 2
+# 100 "Scaler.cxx" 2
+# 112 "Scaler.cxx"
+class Scaler
+{
+
+ public: Scaler() {
+ }
+
+ public: void scale( DFBSurfacePixelFormat format,
+ void *dst,
+ int dpitch,
+ const void *src,
+ int spitch,
+ int width,
+ int height,
+ int dst_width,
+ int dst_height,
+ const DFBRegion &clip )
+ {
+ D_DEBUG_AT( PluggIt_Scaler, "%s( %s, %p [%d], %p [%d], %dx%d -> %dx%d, clip %4d,%4d-%4dx%4d )\n",
+ __FUNCTION__, dfb_pixelformat_name( format ), dst, dpitch, src, spitch, width, height,
+ dst_width, dst_height, DFB_RECTANGLE_VALS_FROM_REGION( &clip ) );
+
+
+ StretchCtx ctx;
+
+ ctx.clip = clip;
+
+ switch (format) {
+ case DSPF_RGB16:
+ if (width <= dst_width || height <= dst_height)
+ stretch_hvx_RGB16_up____DSPF_RGB32( dst, dpitch, src, spitch, width, height, dst_width, dst_height, &ctx );
+ else
+ stretch_hvx_RGB16_down____DSPF_RGB32( dst, dpitch, src, spitch, width, height, dst_width, dst_height, &ctx );
+ break;
+
+ case DSPF_RGB32:
+ if (width <= dst_width || height <= dst_height)
+ stretch_hvx_RGB32_up____DSPF_RGB32( dst, dpitch, src, spitch, width, height, dst_width, dst_height, &ctx );
+ else
+ stretch_hvx_RGB32_down____DSPF_RGB32( dst, dpitch, src, spitch, width, height, dst_width, dst_height, &ctx );
+ break;
+
+ case DSPF_ARGB:
+ if (width <= dst_width || height <= dst_height)
+ stretch_hvx_ARGB_up____DSPF_RGB32( dst, dpitch, src, spitch, width, height, dst_width, dst_height, &ctx );
+ else
+ stretch_hvx_ARGB_down____DSPF_RGB32( dst, dpitch, src, spitch, width, height, dst_width, dst_height, &ctx );
+ break;
+
+ default:
+ D_UNIMPLEMENTED();
+ break;
+ }
+ }
+};
+
+
+
+}
+# 1 "View.cxx"
+# 1 "<built-in>"
+# 1 "<command-line>"
+# 1 "View.cxx"
+namespace PluggIt {
+
+class View
+{
+ public: virtual void config( DFBDimension &size ) = 0;
+
+ public: virtual void update( const vector<DFBRectangle_C> &rects,
+ void *ptr,
+ int pitch ) = 0;
+};
+
+}
+# 1 "Source.cxx"
+# 1 "<built-in>"
+# 1 "<command-line>"
+# 1 "Source.cxx"
+namespace PluggIt {
+
+class Source
+{
+ protected: class Config {
+ protected: Config() {}
+ };
+
+
+ protected: View *m_view;
+ protected: const Config &m_config;
+
+ public: Source( View *view, const Config &config ) : m_config(config) {
+ m_view = view;
+ }
+
+
+ public: virtual int MainLoop() = 0;
+};
+
+}
+# 1 "SourceWin32.cxx"
+# 1 "<built-in>"
+# 1 "<command-line>"
+# 1 "SourceWin32.cxx"
+namespace PluggIt {
+
+D_DEBUG_DOMAIN( PluggIt_SourceWin32, "PluggIt/SourceWin32", "PluggIt Source Win32" );
+
+
+# 1 "ScreenHooks.h" 1
+# 28 "ScreenHooks.h"
+extern "C"
+{
+ __attribute__((dllexport)) bool setHook(HWND targedWinHwnd);
+ __attribute__((dllexport)) bool unsetHook();
+}
+# 7 "SourceWin32.cxx" 2
+
+const UINT specIpcCode = RegisterWindowMessage("HOOK.MESSAGE.CODE");
+
+
+class SourceWin32 :public Source, Runnable
+{
+ private: HINSTANCE m_hInstance;
+
+ private: HWND m_root;
+ private: HWND m_window;
+
+ private: DFBPoint m_position;
+ private: DFBDimension m_size;
+
+ private: HBITMAP m_bitmap;
+ private: void *m_pixels;
+ private: int m_pitch;
+
+ private: HBITMAP m_bitmap2;
+ private: void *m_pixels2;
+ private: int m_pitch2;
+
+ private: HDC m_window_dc;
+ private: HDC m_bitmap_dc;
+ private: HDC m_bitmap_dc2;
+
+ private: Thread *m_thread;
+
+ 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;
+
+
+ public: class Config :public Source::Config {
+ friend class SourceWin32;
+
+ public: typedef enum {
+ WINDOW_SELECTION_NONE,
+ WINDOW_SELECTION_TITLE,
+ WINDOW_SELECTION_INTERACTIVE
+ } WindowSelection;
+
+ private: WindowSelection m_selection;
+ private: std::string m_title;
+ private: bool m_updating;
+ private: bool m_use_driver;
+
+
+ public: Config( WindowSelection selection,
+ const std::string &title = std::string(),
+ bool updating = false, bool use_driver = true )
+ {
+ m_selection = selection;
+ m_title = title;
+ m_updating = updating;
+ m_use_driver = use_driver;
+ }
+ };
+
+
+ public: SourceWin32( View *view, const Config &config ) : Source( view, config ), m_updates(16) {
+ D_DEBUG_AT( PluggIt_SourceWin32, "%s( %p )\n", __FUNCTION__, view );
+
+ m_hInstance = GetModuleHandle( NULL );
+
+ D_DEBUG_AT( PluggIt_SourceWin32, " -> hInstance %p\n", m_hInstance );
+
+
+ m_root = GetDesktopWindow();
+
+ switch (config.m_selection) {
+ case Config::WINDOW_SELECTION_NONE:
+ m_window = m_root;
+ break;
+
+ case Config::WINDOW_SELECTION_TITLE:
+ m_window = findWindow( config.m_title );
+ if (m_window == 0)
+ throw new Exception( "Could not find window with title containing '%s'\n", config.m_title.c_str() );
+ break;
+
+ case Config::WINDOW_SELECTION_INTERACTIVE:
+ pickWindow();
+ if (m_window == 0)
+ throw new Exception( "Could not interactively pick a window\n" );
+ break;
+
+ default:
+ throw new Exception( "Invalid window selection method\n" );
+ }
+
+
+ RECT rect;
+
+ GetClientRect( m_window, &rect );
+
+ m_position.x = rect.left;
+ m_position.y = rect.top;
+
+ 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 );
+
+
+ std::string t = getWindowTitle( m_window );
+
+ 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 );
+
+
+ m_window_dc = GetDC( m_window );
+ m_bitmap_dc = CreateCompatibleDC( m_window_dc );
+ m_bitmap_dc2 = CreateCompatibleDC( m_window_dc );
+
+
+ BITMAPINFO bitmap_info = {{
+ biSize: sizeof(BITMAPINFOHEADER),
+ biWidth: m_size.w,
+ biHeight: m_size.h,
+ biPlanes: 1,
+ biBitCount: 32,
+ biCompression: BI_RGB,
+ biSizeImage: 0,
+ biXPelsPerMeter: 0,
+ biYPelsPerMeter: 0,
+ biClrUsed: 0,
+ biClrImportant: 0,
+ }};
+
+ m_bitmap = CreateDIBSection( m_window_dc, &bitmap_info, DIB_RGB_COLORS, &m_pixels, NULL, 0 );
+ m_bitmap2 = CreateDIBSection( m_window_dc, &bitmap_info, DIB_RGB_COLORS, &m_pixels2, NULL, 0 );
+
+
+ BITMAP bitmap;
+
+ GetObject( m_bitmap, sizeof(BITMAP), &bitmap );
+
+ m_pitch = bitmap.bmWidthBytes;
+
+ GetObject( m_bitmap2, sizeof(BITMAP), &bitmap );
+
+ m_pitch2 = bitmap.bmWidthBytes;
+
+
+ SelectObject( m_bitmap_dc, m_bitmap );
+ SelectObject( m_bitmap_dc2, m_bitmap2 );
+
+
+ pthread_mutex_init( &m_lock, NULL );
+ pthread_cond_init( &m_cond, NULL );
+
+
+ if (!m_using_driver) {
+ HWND w;
+
+ WNDCLASSEX wndClass;
+
+ ZeroMemory( &wndClass, sizeof(wndClass) );
+
+ wndClass.cbSize = sizeof(wndClass);
+ wndClass.style = CS_HREDRAW | CS_VREDRAW;
+ wndClass.lpfnWndProc = MsgWndProc;
+ wndClass.cbClsExtra = 0;
+ wndClass.cbWndExtra = 0;
+ wndClass.hInstance = GetModuleHandle(NULL);
+ wndClass.hIcon = NULL;
+ wndClass.hIconSm = NULL;
+ wndClass.hCursor = LoadCursor( NULL, IDC_UPARROW );
+ wndClass.hbrBackground = (HBRUSH) GetStockObject( NULL_BRUSH );
+ wndClass.lpszMenuName = NULL;
+ wndClass.lpszClassName = "MsgWindow";
+
+ if (!RegisterClassEx( &wndClass ))
+ throw new Exception( "RegisterClassEx() failed!" );
+
+
+ w = CreateWindowEx( 0,
+ "MsgWindow",
+ "MsgWindow",
+ WS_POPUP,
+ CW_USEDEFAULT,
+ CW_USEDEFAULT,
+ 1,
+ 1,
+ NULL,
+ NULL,
+ GetModuleHandle(NULL),
+ this );
+
+ if (!setHook( w ))
+ throw new Exception( "Failed to set hooks!" );
+ }
+
+
+
+ m_thread = new Thread( this, "SourceWin32" );
+
+ m_thread->start();
+ }
+
+ virtual ~SourceWin32() {
+ m_thread->interrupt();
+ m_thread->join();
+ delete m_thread;
+
+ pthread_mutex_destroy( &m_lock );
+ pthread_cond_destroy( &m_cond );
+
+ DeleteDC( m_window_dc );
+ DeleteDC( m_bitmap_dc );
+ DeleteDC( m_bitmap_dc2 );
+
+ DeleteObject( m_bitmap );
+ DeleteObject( m_bitmap2 );
+ }
+
+ private: void addRect( const RECT &rect ) {
+ if (rect.left >= rect.right)
+ return;
+
+ if (rect.top >= rect.bottom)
+ return;
+
+ DFBRegion region( rect.left,
+ rect.top,
+ rect.right - 1,
+ rect.bottom - 1 );
+
+ m_updates.addRegion( region );
+ }
+
+ private: void run() {
+ if (m_using_driver) {
+ D_ASSERT( m_driver.mypchangebuf != NULL );
+
+ unsigned int counter = m_driver.mypchangebuf->counter;
+ unsigned int i;
+
+ long long last_time = direct_clock_get_abs_millis();
+
+ D_DEBUG_AT( PluggIt_SourceWin32, "%s()\n", __FUNCTION__ );
+
+ while (!m_thread->isInterrupted()) {
+ if (m_driver.mypchangebuf->counter < 1 ||
+ m_driver.mypchangebuf->counter >= MAXCHANGES_BUF ||
+ counter == m_driver.mypchangebuf->counter)
+ usleep( 10000 );
+
+ if (counter != m_driver.mypchangebuf->counter) {
+ D_DEBUG_AT( PluggIt_SourceWin32, " -> counter: %d -> %d\n", counter, m_driver.mypchangebuf->counter );
+
+ if (counter < m_driver.mypchangebuf->counter) {
+ for (i=counter+1; i<=m_driver.mypchangebuf->counter; i++) {
+ addRect( m_driver.mypchangebuf->pointrect[i].rect );
+ }
+ }
+ else if (counter > m_driver.mypchangebuf->counter) {
+ for (i=counter+1; i<MAXCHANGES_BUF; i++) {
+ addRect( m_driver.mypchangebuf->pointrect[i].rect );
+ }
+ for (i=1; i<=m_driver.mypchangebuf->counter; i++) {
+ addRect( m_driver.mypchangebuf->pointrect[i].rect );
+ }
+ }
+
+ counter = m_driver.mypchangebuf->counter;
+ }
+
+ if (direct_clock_get_abs_millis() - last_time > 2000) {
+ DFBRegion region( 0,
+ 0,
+ m_size.w - 1,
+ m_size.h - 1 );
+
+ m_updates.addRegion( region );
+
+ last_time = direct_clock_get_abs_millis();
+ }
+
+ if (m_updates.num_regions() > 0) {
+ vector<DFBRectangle_C> rects;
+
+ m_updates.GetRectangles( rects );
+
+
+ const DFBRegion &bounding = m_updates.bounding();
+
+ 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() );
+
+ m_updates.reset();
+
+ flushUpdates( rects );
+ }
+ }
+ }
+ else {
+ D_DEBUG_AT( PluggIt_SourceWin32, "%s()\n", __FUNCTION__ );
+
+ long long last_time = direct_clock_get_abs_millis();
+
+ while (!m_thread->isInterrupted()) {
+ if (((const Config&)m_config).m_updating) {
+ usleep( 100000 );
+
+ queueUpdate( 0, 0, m_size.w - 1, m_size.h - 1 );
+
+ pthread_mutex_lock( &m_lock );
+ }
+ else {
+ pthread_mutex_lock( &m_lock );
+
+ if (m_updates.num_regions() == 0)
+ usleep( 10000 );
+
+ }
+
+ if (direct_clock_get_abs_millis() - last_time > 2000) {
+ DFBRegion region( 0,
+ 0,
+ m_size.w - 1,
+ m_size.h - 1 );
+
+ m_updates.addRegion( region );
+
+ last_time = direct_clock_get_abs_millis();
+ }
+
+
+ vector<DFBRectangle_C> rects;
+
+ if (m_updates.num_regions() > 0) {
+ m_updates.GetRectangles( rects );
+
+
+ const DFBRegion &bounding = m_updates.bounding();
+
+ 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() );
+
+ m_updates.reset();
+ }
+
+ pthread_mutex_unlock( &m_lock );
+
+ if (!rects.empty())
+ flushUpdates( rects );
+ }
+ }
+ }
+
+
+
+ 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_mutex_unlock( &m_lock );
+
+ pthread_cond_signal( &m_cond );
+ }
+
+ private: bool flushUpdates( vector<DFBRectangle_C> &rects ) {
+ D_DEBUG_AT( PluggIt_SourceWin32, "%s()\n", __FUNCTION__ );
+
+ if (m_using_driver) {
+ m_view->update( rects, m_driver.myframebuffer, m_pitch );
+ }
+ else {
+ 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 );
+ }
+
+ D_DEBUG_AT( PluggIt_SourceWin32, " -> flush done\n" );
+
+ return true;
+ }
+
+
+
+
+
+ private: static std::string getWindowTitle( HWND window ) {
+ char buf[1024] = { 0 };
+
+ GetWindowText( window, buf, sizeof(buf) );
+
+ D_DEBUG_AT( PluggIt_SourceWin32, "%s( %p ) -> '%s'\n", __FUNCTION__, window, buf );
+
+ return buf;
+ }
+
+
+
+
+ class EnumContext {
+ public: const std::string &title;
+ public: HWND window;
+
+ public: EnumContext( const std::string &title ) : title(title), window(0) {}
+ };
+
+ private: static BOOL CALLBACK enumWindowsProc( HWND hwnd,
+ LPARAM lParam )
+ {
+ EnumContext *ctx = reinterpret_cast<EnumContext *>( lParam );
+
+ D_DEBUG_AT( PluggIt_SourceWin32, "%s( %p )\n", __FUNCTION__, hwnd );
+
+ std::string title = getWindowTitle( hwnd );
+
+ if (title == ctx->title || title.find( ctx->title ) < title.size())
+ ctx->window = hwnd;
+
+ return ctx->window == NULL;
+ }
+
+ private: HWND findWindow( const std::string &title ) {
+ D_DEBUG_AT( PluggIt_SourceWin32, "%s( %s )\n", __FUNCTION__, title.c_str() );
+
+ EnumContext ctx( title );
+
+ EnumWindows( enumWindowsProc, reinterpret_cast<LPARAM>( &ctx ) );
+
+ return ctx.window;
+ }
+
+
+
+
+ static LRESULT CALLBACK WndProc( HWND hwnd,
+ UINT uMsg,
+ WPARAM wParam,
+ LPARAM lParam )
+ {
+ static SourceWin32 *thiz;
+ POINT point;
+ CREATESTRUCT *create;
+
+ switch (uMsg) {
+ case WM_CREATE:
+ create = reinterpret_cast<LPCREATESTRUCT>( lParam );
+ thiz = reinterpret_cast<SourceWin32 *>( create->lpCreateParams );
+
+ SetCursor( LoadCursor( NULL, IDC_CROSS ) );
+ break;
+
+ case WM_LBUTTONDOWN:
+ ShowWindow( hwnd, SW_HIDE );
+
+
+ GetCursorPos( &point );
+
+ D_DEBUG_AT( PluggIt_SourceWin32, " -> Cursor position is %ld,%ld\n", point.x, point.y );
+
+
+ thiz->m_window = WindowFromPoint( point );
+ if (thiz->m_window) {
+ HWND parent;
+
+ while ((parent = GetParent( thiz->m_window )) != NULL)
+ thiz->m_window = parent;
+ }
+
+ D_DEBUG_AT( PluggIt_SourceWin32, " -> Window at cursor is %p: %s\n",
+ thiz->m_window, getWindowTitle( thiz->m_window ).c_str() );
+
+ DestroyWindow( hwnd );
+ break;
+
+ case WM_TIMER:
+ if (wParam == 666)
+ DestroyWindow( hwnd );
+ break;
+
+ case WM_DESTROY:
+ KillTimer( hwnd, 666 );
+ PostQuitMessage( 0 );
+ break;
+
+ default:
+ SetTimer( hwnd, 666, 5000, NULL );
+
+ return DefWindowProc( hwnd, uMsg, wParam, lParam );
+ }
+
+ return 0;
+ }
+
+ private: void pickWindow() {
+ D_DEBUG_AT( PluggIt_SourceWin32, "%s()\n", __FUNCTION__ );
+
+ HDC hdc;
+
+ hdc = GetDC( NULL );
+ if (!hdc)
+ throw new Exception( "GetDC() returned NULL" );
+
+ RECT rect;
+
+ GetClipBox( hdc, &rect );
+
+ D_DEBUG_AT( PluggIt_SourceWin32, " -> Desktop size: %ldx%ld\n",
+ rect.right - rect.left, rect.bottom - rect.top );
+
+ ReleaseDC( NULL, hdc );
+
+
+
+ WNDCLASSEX wndClass;
+
+ ZeroMemory( &wndClass, sizeof(wndClass) );
+
+ wndClass.cbSize = sizeof(wndClass);
+ wndClass.style = CS_HREDRAW | CS_VREDRAW;
+ wndClass.lpfnWndProc = WndProc;
+ wndClass.cbClsExtra = 0;
+ wndClass.cbWndExtra = 0;
+ wndClass.hInstance = m_hInstance;
+ wndClass.hIcon = NULL;
+ wndClass.hIconSm = NULL;
+ wndClass.hCursor = LoadCursor( NULL, IDC_UPARROW );
+ wndClass.hbrBackground = (HBRUSH) GetStockObject( NULL_BRUSH );
+ wndClass.lpszMenuName = NULL;
+ wndClass.lpszClassName = "GrabWindow";
+
+ if (!RegisterClassEx( &wndClass ))
+ throw new Exception( "RegisterClassEx() failed!\n" );
+
+
+ AdjustWindowRect( &rect, WS_CAPTION, FALSE );
+
+
+ HWND grabwin;
+
+ grabwin = CreateWindowEx( 0,
+ "GrabWindow",
+ "GrabWindow",
+ WS_POPUP,
+ CW_USEDEFAULT,
+ CW_USEDEFAULT,
+ rect.right - rect.left,
+ rect.bottom - rect.top,
+ NULL,
+ NULL,
+ m_hInstance,
+ this );
+
+ SetWindowLong( grabwin, GWL_EXSTYLE,
+ GetWindowLong( grabwin, GWL_EXSTYLE ) | WS_EX_TRANSPARENT | WS_EX_TOPMOST );
+
+ ShowWindow( grabwin, SW_SHOW );
+
+
+
+ MSG msg;
+
+ while (GetMessage( &msg, 0, 0, 0 )) {
+ TranslateMessage( &msg );
+
+ D_DEBUG_AT( PluggIt_SourceWin32, " -> Dispatching event (id %u)...\n", msg.message );
+
+ DispatchMessage( &msg );
+ }
+ }
+
+
+
+ static LRESULT CALLBACK MsgWndProc( HWND hwnd,
+ UINT uMsg,
+ WPARAM wParam,
+ LPARAM lParam )
+ {
+ static SourceWin32 *thiz;
+ CREATESTRUCT *create;
+
+ switch (uMsg) {
+ case WM_CREATE:
+ create = reinterpret_cast<LPCREATESTRUCT>( lParam );
+ thiz = reinterpret_cast<SourceWin32 *>( create->lpCreateParams );
+ break;
+
+ case WM_DESTROY:
+ PostQuitMessage( 0 );
+ break;
+
+ default:
+ if (uMsg == specIpcCode) {
+ int x1 = wParam >> 16;
+ int y1 = wParam & 0xffff;
+ int x2 = lParam >> 16;
+ int y2 = lParam & 0xffff;
+
+ if (x1 < x2 && y1 < y2)
+ thiz->queueUpdate( x1, y1, x2 - 1, y2 - 1 );
+
+ break;
+ }
+
+ return DefWindowProc( hwnd, uMsg, wParam, lParam );
+ }
+
+ return 0;
+ }
+
+ public: virtual int MainLoop() {
+ MSG msg;
+
+ while (GetMessage( &msg, 0, 0, 0 )) {
+ TranslateMessage( &msg );
+ DispatchMessage( &msg );
+ }
+
+ return 0;
+ }
+};
+
+}
+# 1 "Main.cxx"
+# 1 "<built-in>"
+# 1 "<command-line>"
+# 1 "Main.cxx"
+namespace PluggIt {
+
+D_DEBUG_DOMAIN( PluggIt_Main, "PluggIt/Main", "PluggIt Main" );
+D_DEBUG_DOMAIN( PluggIt_View, "PluggIt/View", "PluggIt View" );
+
+class Main :public View
+{
+ class Config {
+ public: DFBDimension m_size;
+ public: DFBPoint m_offset;
+ public: DFBDimension m_resolution;
+ public: DFBSurfacePixelFormat m_format;
+ public: std::string m_title;
+ public: bool m_interactive;
+ public: bool m_updating;
+ public: bool m_use_driver;
+
+ public: Config() :
+ m_format(DSPF_UNKNOWN),
+ m_interactive(false),
+ m_updating(false)
+ {
+ }
+ };
+
+
+ private: Config m_config;
+ private: Options m_options;
+ private: Scaler m_scaler;
+
+ private: IDirectFB m_dfb;
+ private: IDirectFBDisplayLayer m_layer;
+ private: IDirectFBWindow m_window;
+ private: IDirectFBSurface m_surface;
+ private: IDirectFBEventBuffer m_events;
+
+ private: Source *m_source;
+
+ private: DFBDimension m_source_resolution;
+
+ private: DFBDimension m_view_size;
+ private: DFBDimension m_view_resolution;
+ private: bool m_view_visible;
+ private: DFBSurfacePixelFormat m_view_format;
+
+
+ public: Main() :
+ m_source(NULL),
+ m_view_visible(false)
+ {
+ 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::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 ) );
+ }
+
+ public: void main( int argc, char *argv[] ) {
+ D_DEBUG_AT( PluggIt_Main, "%s()\n", __FUNCTION__ );
+
+ try {
+
+ DirectFB::Init( &argc, &argv );
+
+ if (!m_options.parseCommandLine( argc, argv ))
+ return;
+
+ initDFB();
+ initSource();
+
+ run();
+ }
+ catch (DFBException *e) {
+ cerr << endl;
+ cerr << "Caught exception!" << endl;
+ cerr << " ==> " << e << endl;
+ }
+ catch (Exception *e) {
+ cerr << endl;
+ cerr << "Caught exception!" << endl;
+ cerr << " ==> " << e << endl;
+ }
+ }
+
+ private: void initDFB() {
+ D_DEBUG_AT( PluggIt_Main, "%s()\n", __FUNCTION__ );
+
+
+ m_dfb = DirectFB::Create();
+
+ m_layer = m_dfb.GetDisplayLayer( DLID_PRIMARY );
+
+ m_events = m_dfb.CreateEventBuffer();
+ }
+
+ private: void initSource() {
+ D_DEBUG_AT( PluggIt_Main, "%s()\n", __FUNCTION__ );
+
+
+ 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 );
+# 122 "Main.cxx"
+ }
+
+ private: void run() {
+ m_source->MainLoop();
+ }
+
+ public: virtual void config( DFBDimension &source_resolution ) {
+ D_DEBUG_AT( PluggIt_View, "%s( %u, %u )\n", __FUNCTION__, source_resolution.w, source_resolution.h );
+
+
+ if (m_source_resolution == source_resolution) {
+ D_DEBUG_AT( PluggIt_View, " -> unchanged source size\n" );
+ return;
+ }
+
+ m_source_resolution = source_resolution;
+
+
+
+ DFBDimension resolution = m_config.m_resolution;
+
+ if (!resolution.w) {
+ if (!resolution.h) {
+ resolution = source_resolution;
+
+ D_DEBUG_AT( PluggIt_View, " -> no width/height\n" );
+ }
+ else {
+ resolution.w = resolution.h * source_resolution.w / source_resolution.h;
+
+ D_DEBUG_AT( PluggIt_View, " -> no width\n" );
+ }
+ }
+ else if (!resolution.h) {
+ resolution.h = resolution.w * source_resolution.h / source_resolution.w;
+
+ D_DEBUG_AT( PluggIt_View, " -> no height\n" );
+ }
+
+ D_DEBUG_AT( PluggIt_View, " -> resolution %ux%u\n", resolution.w, resolution.h );
+
+
+
+ DFBDimension size = m_config.m_size;
+
+ if (!size.w) {
+ if (!size.h) {
+ size = resolution;
+
+ D_DEBUG_AT( PluggIt_View, " -> no width/height\n" );
+ }
+ else {
+ size.w = size.h * resolution.w / resolution.h;
+
+ D_DEBUG_AT( PluggIt_View, " -> no width\n" );
+ }
+ }
+ else if (!size.h) {
+ size.h = size.w * resolution.h / resolution.w;
+
+ D_DEBUG_AT( PluggIt_View, " -> no height\n" );
+ }
+
+ D_DEBUG_AT( PluggIt_View, " -> %ux%u\n", size.w, size.h );
+
+
+ if (m_view_resolution == resolution)
+ D_DEBUG_AT( PluggIt_View, " -> unchanged view resolution\n" );
+
+ if (m_view_size == size) {
+ D_DEBUG_AT( PluggIt_View, " -> unchanged view size\n" );
+ return;
+ }
+
+ if (m_window)
+ m_window.Resize( size.w, size.h );
+ else {
+
+ DFBWindowDescription desc;
+
+ desc.flags = (DFBWindowDescriptionFlags)( DWDESC_POSX | DWDESC_POSY |
+ DWDESC_WIDTH | DWDESC_HEIGHT | DWDESC_PIXELFORMAT );
+ desc.posx = 0;
+ desc.posy = 0;
+ desc.width = size.w;
+ desc.height = size.h;
+ desc.pixelformat = m_config.m_format;
+
+ m_window = m_layer.CreateWindow( desc );
+
+ m_surface = m_window.GetSurface();
+
+ m_view_format = m_surface.GetPixelFormat();
+
+ m_window.AttachEventBuffer( m_events );
+ }
+
+ m_view_size = size;
+ m_view_resolution = resolution;
+
+
+ D_DEBUG_AT( PluggIt_View, " -> view size %4ux%4u\n", m_view_size.w, m_view_size.h );
+ D_DEBUG_AT( PluggIt_View, " -> view resolution %4ux%4u\n", m_view_resolution.w, m_view_resolution.h );
+ D_DEBUG_AT( PluggIt_View, " -> source resolution %4ux%4u\n", m_source_resolution.w, m_source_resolution.h );
+ }
+
+ public: virtual void update( const vector<DFBRectangle_C> &rects,
+ void *ptr,
+ int pitch )
+ {
+ unsigned int i;
+ DFBRegion clip( m_view_size );
+ const DFBPoint &offset = m_config.m_offset;
+ bool first = true;
+ DFBRegion flip;
+
+ D_DEBUG_AT( PluggIt_View, "%s( [%u], %p, %d )\n", __FUNCTION__, rects.size(), ptr, pitch );
+
+ D_ASSERT( rects.size() > 0 );
+ D_ASSERT( ptr != NULL );
+
+
+
+ if (m_source_resolution == m_view_resolution) {
+ D_DEBUG_AT( PluggIt_View, " -> unscaled %4dx%4d\n",
+ m_source_resolution.w, m_source_resolution.h );
+
+ if (m_view_format == DSPF_RGB16) {
+ int tp = ((m_view_size.w * 2) + 7) & ~7;
+ void *tmp = malloc( tp * m_view_size.h );
+
+ for (i=0; i<rects.size(); i++) {
+ D_DEBUG_AT( PluggIt_View, " -> [%2d] %4d,%4d-%4dx%4d (original)\n",
+ i, DFB_RECTANGLE_VALS( &rects[i] ) );
+
+ DFBRegion region( DFBRectangle(rects[i]) - offset );
+
+ D_DEBUG_AT( PluggIt_View, " -> %4d,%4d-%4dx%4d (translated)\n",
+ DFB_RECTANGLE_VALS_FROM_REGION( &region ) );
+
+ ptr = (void*)((char*) ptr + offset.x * 4 + offset.y * pitch);
+
+
+ if (dfb_region_region_intersect( &region, &clip )) {
+ D_DEBUG_AT( PluggIt_View, " -> %4d,%4d-%4dx%4d (clipped update)\n",
+ DFB_RECTANGLE_VALS_FROM_REGION( &region ) );
+
+ DFBRectangle rect( region );
+
+ dfb_convert_to_rgb16( DSPF_RGB32,
+ (void*)((char*) ptr + rect.x * 4 + rect.y * pitch), pitch,
+ m_view_size.h, (u16*) tmp, tp, rect.w, rect.h );
+
+ m_surface.Write( (char*) tmp + DFB_BYTES_PER_LINE( m_view_format, region.x1 ) + region.y1 * tp, tp, &rect );
+
+ if (first) {
+ first = false;
+ flip = region;
+ }
+ else
+ flip.unionWith( region );
+
+ }
+ }
+
+ free( tmp );
+ }
+ else {
+ for (i=0; i<rects.size(); i++) {
+ D_DEBUG_AT( PluggIt_View, " -> [%2d] %4d,%4d-%4dx%4d (original)\n",
+ i, DFB_RECTANGLE_VALS( &rects[i] ) );
+
+ DFBRegion region( DFBRectangle(rects[i]) - offset );
+
+ D_DEBUG_AT( PluggIt_View, " -> %4d,%4d-%4dx%4d (translated)\n",
+ DFB_RECTANGLE_VALS_FROM_REGION( &region ) );
+
+ ptr = (void*)((char*) ptr + offset.x * 4 + offset.y * pitch);
+
+
+ if (dfb_region_region_intersect( &region, &clip )) {
+ D_DEBUG_AT( PluggIt_View, " -> %4d,%4d-%4dx%4d (clipped update)\n",
+ DFB_RECTANGLE_VALS_FROM_REGION( &region ) );
+
+ DFBRectangle rect( region );
+
+ if (m_view_format == DSPF_ARGB) {
+ u32 *p = (u32*)((char*) ptr + rect.x * 4 + rect.y * pitch);
+
+ for (int y=0; y<rect.h; y++) {
+ for (int x=0; x<rect.w; x++)
+ p[x] |= 0xff000000;
+
+ p = (u32*)((char*) p + pitch);
+ }
+ }
+
+ D_DEBUG_AT( PluggIt_View, " -> Write...\n" );
+ m_surface.Write( (char*) ptr + DFB_BYTES_PER_LINE( m_view_format, region.x1 ) + region.y1 * pitch, pitch, &rect );
+ D_DEBUG_AT( PluggIt_View, " -> Write done.\n" );
+
+ if (first) {
+ first = false;
+ flip = region;
+ }
+ else
+ flip.unionWith( region );
+
+ }
+ }
+ }
+ }
+ else {
+ int tp = ((m_view_size.w * 4) + 7) & ~7;
+ void *tmp = malloc( tp * m_view_size.h );
+
+ D_DEBUG_AT( PluggIt_View, " -> scaled %4dx%4d => %4dx%4d\n",
+ m_source_resolution.w, m_source_resolution.h,
+ m_view_resolution.w, m_view_resolution.h );
+
+ for (i=0; i<rects.size(); i++) {
+ D_DEBUG_AT( PluggIt_View, " -> [%2d] %4d,%4d-%4dx%4d (original)\n",
+ i, DFB_RECTANGLE_VALS( &rects[i] ) );
+
+ DFBRegion region( DFBRectangle(rects[i]) - offset );
+
+ D_DEBUG_AT( PluggIt_View, " -> %4d,%4d-%4dx%4d (translated)\n",
+ DFB_RECTANGLE_VALS_FROM_REGION( &region ) );
+
+ ptr = (void*)((char*) ptr + offset.x * 4 + offset.y * pitch);
+
+
+ region.x1 = region.x1 * m_view_resolution.w / m_source_resolution.w;
+ region.y1 = region.y1 * m_view_resolution.h / m_source_resolution.h;
+ region.x2 = region.x2 * m_view_resolution.w / m_source_resolution.w;
+ region.y2 = region.y2 * m_view_resolution.h / m_source_resolution.h;
+
+ if (region.x1 > 0)
+ region.x1--;
+
+ if (region.y1 > 0)
+ region.y1--;
+
+ if (region.x2 < m_view_resolution.w-1)
+ region.x2++;
+ if (region.x2 < m_view_resolution.w-1)
+ region.x2++;
+
+ if (region.y2 < m_view_resolution.h-1)
+ region.y2++;
+ if (region.y2 < m_view_resolution.h-1)
+ region.y2++;
+
+ D_DEBUG_AT( PluggIt_View, " -> %4d,%4d-%4dx%4d (scaled)\n",
+ DFB_RECTANGLE_VALS_FROM_REGION( &region ) );
+
+
+ if (dfb_region_region_intersect( &region, &clip )) {
+ D_DEBUG_AT( PluggIt_View, " -> %4d,%4d-%4dx%4d (clipped)\n",
+ DFB_RECTANGLE_VALS_FROM_REGION( &region ) );
+
+ DFBRectangle rect( region );
+
+ m_scaler.scale( m_view_format, tmp, tp, ptr, pitch,
+ m_source_resolution.w, m_source_resolution.h,
+ m_view_resolution.w, m_view_resolution.h, region );
+
+ m_surface.Write( (char*) tmp + DFB_BYTES_PER_LINE( m_view_format, region.x1 ) + region.y1 * tp, tp, &rect );
+
+ if (first) {
+ first = false;
+ flip = region;
+ }
+ else
+ flip.unionWith( region );
+
+ }
+ }
+
+ free( tmp );
+ }
+
+ m_surface.Flip( &flip );
+
+ if (!m_view_visible) {
+ m_window.SetOpacity( 0xff );
+
+ m_view_visible = true;
+ }
+ }
+};
+
+}
+extern "C" {
+# 1 "main.c"
+# 1 "<built-in>"
+# 1 "<command-line>"
+# 1 "main.c"
+
+int
+main( int argc, char *argv[] )
+{
+ PluggIt::Main *main = new PluggIt::Main();
+
+ main->main( argc, argv );
+
+ delete main;
+}
+}
diff --git a/src/classes.h b/src/classes.h
new file mode 100644
index 0000000..4809afb
--- /dev/null
+++ b/src/classes.h
@@ -0,0 +1,64 @@
+#define DIRECT_ENABLE_DEBUG
+
+
+#include <iostream>
+#include <vector>
+
+using namespace std;
+
+
+/*
+ * ++DFB
+ */
+#include <++dfb.h>
+
+
+
+/*
+ * Direct
+ */
+extern "C" {
+#include <stdarg.h>
+
+#include <direct/clock.h>
+#include <direct/debug.h>
+#include <direct/memcpy.h>
+#include <direct/messages.h>
+#include <direct/thread.h>
+#include <direct/util.h>
+
+#include <gfx/convert.h>
+}
+
+
+/*
+ * Win32
+ */
+#ifdef __WIN32__
+#define CreateWindow CreateWindowWin32
+#include <windows.h>
+#include <wingdi.h>
+#include <winuser.h>
+#include "videodriver.h"
+#undef CreateWindow
+
+#else
+
+/*
+ * X11
+ */
+extern "C" {
+#include <X11/Xlib.h> /* fundamentals X datas structures */
+#include <X11/Xutil.h> /* datas definitions for various functions */
+#include <X11/keysym.h> /* for a perfect use of keyboard events */
+#include <X11/Xatom.h>
+#include <X11/cursorfont.h>
+
+#include <X11/extensions/XShm.h>
+#include <X11/extensions/Xdamage.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+}
+
+#endif
+
diff --git a/src/gen_classes.sh b/src/gen_classes.sh
new file mode 100755
index 0000000..dc5847d
--- /dev/null
+++ b/src/gen_classes.sh
@@ -0,0 +1,33 @@
+#!/bin/sh -e
+
+CLASSES=
+SOURCES=
+
+while test -n "$1"; do
+ SOURCES="$SOURCES $1"
+ CLASSES="$CLASSES `echo "$1" | sed 's/\.cxx//'`"
+ shift
+done
+
+echo '# 1 "classes.h"'
+cat classes.h
+
+
+for i in $CLASSES; do
+ echo "class $i;"
+done
+
+for i in $SOURCES; do
+ cpp $CPPFLAGS $i |
+ sed 's/public/public:/' |
+ sed 's/protected/protected:/' |
+ sed 's/private/private:/' |
+ sed 's/extends/:public/'
+done
+
+
+echo 'extern "C" {'
+
+cpp main.c
+
+echo '}'
diff --git a/src/main.c b/src/main.c
new file mode 100644
index 0000000..c9fa208
--- /dev/null
+++ b/src/main.c
@@ -0,0 +1,11 @@
+
+int
+main( int argc, char *argv[] )
+{
+ PluggIt::Main *main = new PluggIt::Main();
+
+ main->main( argc, argv );
+
+ delete main;
+}
+
diff --git a/src/stretch_hvx_16.h b/src/stretch_hvx_16.h
new file mode 100644
index 0000000..a661648
--- /dev/null
+++ b/src/stretch_hvx_16.h
@@ -0,0 +1,469 @@
+#ifndef SOURCE_LOOKUP
+#define SOURCE_LOOKUP(x) (x)
+#define SOURCE_LOOKUP_AUTO
+#endif
+
+#ifndef SOURCE_TYPE
+#define SOURCE_TYPE u16
+#define SOURCE_TYPE_AUTO
+#endif
+
+
+#define SHIFT_L5 SHIFT_R5
+#define SHIFT_L6 SHIFT_R6
+#define SHIFT_L10 (16-SHIFT_L6)
+
+#define X_003F (X_07E0>>SHIFT_R5)
+
+#define X_003E07C0 (X_F81F<<SHIFT_L6)
+#define X_0001F800 (X_07E0<<SHIFT_L6)
+
+#define X_07E0F81F ((X_07E0<<16) | X_F81F)
+#define X_F81F07E0 ((X_F81F<<16) | X_07E0)
+
+#define X_F81FF81F ((X_F81F<<16) | X_F81F)
+#define X_07E007E0 ((X_07E0<<16) | X_07E0)
+
+#define X_07C0F83F (X_F81F07E0>>SHIFT_R5)
+
+#if 0
+#define HVX_DEBUG(x...) direct_log_printf( NULL, x )
+#else
+#define HVX_DEBUG(x...) do {} while (0)
+#endif
+
+/* stretch_hvx_up/down_16_KPI */( void *dst,
+ int dpitch,
+ const void *src,
+ int spitch,
+ int width,
+ int height,
+ int dst_width,
+ int dst_height,
+ const StretchCtx *ctx )
+{
+ long x, y, r = 0;
+ long head = ((((unsigned long) dst) & 2) >> 1) ^ (ctx->clip.x1 & 1);
+ long cw = ctx->clip.x2 - ctx->clip.x1 + 1;
+ long ch = ctx->clip.y2 - ctx->clip.y1 + 1;
+ long tail = (cw - head) & 1;
+ long w2 = (cw - head) / 2;
+ long hfraq = ((long)(width - MINUS_1) << 18) / (long)(dst_width);
+ long vfraq = ((long)(height - MINUS_1) << 18) / (long)(dst_height);
+ long dp4 = dpitch / 4;
+ long point0 = POINT_0 + ctx->clip.x1 * hfraq;
+ long point = point0;
+ long line = LINE_0 + ctx->clip.y1 * vfraq;
+ long ratios[cw];
+ u32 *dst32;
+
+#if defined (COLOR_KEY) || defined (KEY_PROTECT)
+ u32 dt;
+ u16 l_, h_;
+#endif
+
+ u32 _lbT[w2+8];
+ u32 _lbB[w2+8];
+
+ u32 *lbX;
+ u32 *lbT = (u32*)((((unsigned long)(&_lbT[0])) + 31) & ~31);
+ u32 *lbB = (u32*)((((unsigned long)(&_lbB[0])) + 31) & ~31);
+
+ long lineT = -2000;
+
+ for (x=0; x<cw; x++) {
+ ratios[x] = POINT_TO_RATIO( point, hfraq );
+
+ point += hfraq;
+ }
+
+ HVX_DEBUG(" %s %dx%d -> %dx%d (0x%lx, 0x%lx) prot %lx, key %lx\n",
+ __FUNCTION__, width, height, dst_width, dst_height, hfraq, vfraq, ctx->protect, ctx->key );
+
+ dst = (void*)((char*) dst + ctx->clip.x1 * 2 + ctx->clip.y1 * dpitch);
+
+ dst32 = (u32*) dst;
+
+ if (head) {
+ u32 dpT, dpB, L, R;
+
+ u16 *dst16 = (u16*) dst;
+
+ point = point0;
+
+ for (y=0; y<ch; y++) {
+ long X = LINE_TO_RATIO( line, vfraq );
+
+ const SOURCE_TYPE *srcT = (const SOURCE_TYPE *)((char*) src + spitch * LINE_T( line, vfraq ));
+ const SOURCE_TYPE *srcB = (const SOURCE_TYPE *)((char*) src + spitch * LINE_B( line, vfraq ));
+
+ /*
+ * Horizontal interpolation
+ */
+ long pl = POINT_L( point, hfraq );
+ HVX_DEBUG("h,%ld %lu (%lu/%lu) 0x%x 0x%x\n", y, pl,
+ POINT_L( point, hfraq ), POINT_R( point, hfraq ), point, ratios[r] );
+ D_ASSERT( pl >= 0 );
+ D_ASSERT( pl < width-1 );
+ L = SOURCE_LOOKUP(srcT[pl]);
+ R = SOURCE_LOOKUP(srcT[pl+1]);
+
+ dpT = (((((R & X_F81F)-(L & X_F81F))*ratios[r] + ((L & X_F81F)<<SHIFT_L6)) & X_003E07C0) +
+ ((((R & X_07E0)-(L & X_07E0))*ratios[r] + ((L & X_07E0)<<SHIFT_L6)) & X_0001F800)) >> SHIFT_R6;
+
+ L = SOURCE_LOOKUP(srcB[pl]);
+ R = SOURCE_LOOKUP(srcB[pl+1]);
+
+ dpB = (((((R & X_F81F)-(L & X_F81F))*ratios[r] + ((L & X_F81F)<<SHIFT_L6)) & X_003E07C0) +
+ ((((R & X_07E0)-(L & X_07E0))*ratios[r] + ((L & X_07E0)<<SHIFT_L6)) & X_0001F800)) >> SHIFT_R6;
+
+ /*
+ * Vertical interpolation
+ */
+#if defined (COLOR_KEY) || defined (KEY_PROTECT)
+ l_ = ((((((dpB & X_F81F) - (dpT & X_F81F))*X) >> SHIFT_R5) + (dpT & X_F81F)) & X_F81F) +
+ ((((((dpB>>SHIFT_R5) & X_003F) - ((dpT>>SHIFT_R5) & X_003F))*X) + (dpT & X_07E0)) & X_07E0);
+#ifdef COLOR_KEY
+ if ((l_ & MASK_RGB) != (COLOR_KEY))
+#endif
+#ifdef KEY_PROTECT
+ /* Write to destination with color key protection */
+ dst16[0] = ((l_ & MASK_RGB) == KEY_PROTECT) ? l_^1 : l_;
+#else
+ /* Write to destination without color key protection */
+ dst16[0] = l_;
+#endif
+#else
+ /* Write to destination without color key protection */
+ dst16[0] = ((((((dpB & X_F81F) - (dpT & X_F81F))*X) >> SHIFT_R5) + (dpT & X_F81F)) & X_F81F) +
+ ((((((dpB>>SHIFT_R5) & X_003F) - ((dpT>>SHIFT_R5) & X_003F))*X) + (dpT & X_07E0)) & X_07E0);
+#endif
+
+ dst16 += dpitch / 2;
+ line += vfraq;
+ }
+
+ /* Adjust */
+ point0 += hfraq;
+ dst32 = (u32*)((char*) dst + 2);
+
+ /* Reset */
+ line = LINE_0 + ctx->clip.y1 * vfraq;
+ }
+
+ /*
+ * Scale line by line.
+ */
+ for (y=0; y<ch; y++) {
+ long X;
+ long nlT = LINE_T( line, vfraq );
+
+ D_ASSERT( nlT >= 0 );
+ D_ASSERT( nlT < height-1 );
+
+ /*
+ * Fill line buffer(s) ?
+ */
+ if (nlT != lineT) {
+ u32 L, R, dpT, dpB;
+ const SOURCE_TYPE *srcT = (const SOURCE_TYPE *)((char*) src + spitch * nlT);
+ const SOURCE_TYPE *srcB = (const SOURCE_TYPE *)((char*) src + spitch * (nlT + 1));
+ long diff = nlT - lineT;
+
+ if (diff > 1) {
+ /*
+ * Two output pixels per step.
+ */
+ for (x=0, r=head, point=point0; x<w2; x++) {
+ /*
+ * Horizontal interpolation
+ */
+ long pl = POINT_L( point, hfraq );
+ HVX_DEBUG("%ld,%ld %lu (%lu/%lu) 0x%x 0x%x\n", x, y, pl,
+ POINT_L( point, hfraq ), POINT_R( point, hfraq ), point, ratios[r] );
+ D_ASSERT( pl >= 0 );
+ D_ASSERT( pl < width-1 );
+ L = SOURCE_LOOKUP(srcT[pl]);
+ R = SOURCE_LOOKUP(srcT[pl+1]);
+
+ dpT = (((((R & X_F81F)-(L & X_F81F))*ratios[r] + ((L & X_F81F)<<SHIFT_L6)) & X_003E07C0) +
+ ((((R & X_07E0)-(L & X_07E0))*ratios[r] + ((L & X_07E0)<<SHIFT_L6)) & X_0001F800))
+#ifdef WORDS_BIGENDIAN
+ << SHIFT_L10;
+#else
+ >> SHIFT_R6;
+#endif
+
+ L = SOURCE_LOOKUP(srcB[pl]);
+ R = SOURCE_LOOKUP(srcB[pl+1]);
+
+ dpB = (((((R & X_F81F)-(L & X_F81F))*ratios[r] + ((L & X_F81F)<<SHIFT_L6)) & X_003E07C0) +
+ ((((R & X_07E0)-(L & X_07E0))*ratios[r] + ((L & X_07E0)<<SHIFT_L6)) & X_0001F800))
+#ifdef WORDS_BIGENDIAN
+ << SHIFT_L10;
+#else
+ >> SHIFT_R6;
+#endif
+
+ point += hfraq;
+ r++;
+
+
+ pl = POINT_L( point, hfraq );
+ HVX_DEBUG("%ld,%ld %lu (%lu/%lu) 0x%x 0x%x\n", x, y, pl,
+ POINT_L( point, hfraq ), POINT_R( point, hfraq ), point, ratios[r] );
+ D_ASSERT( pl >= 0 );
+ D_ASSERT( pl < width-1 );
+
+ L = SOURCE_LOOKUP(srcT[pl]);
+ R = SOURCE_LOOKUP(srcT[pl+1]);
+
+ dpT |= (((((R & X_F81F)-(L & X_F81F))*ratios[r] + ((L & X_F81F)<<SHIFT_L6)) & X_003E07C0) +
+ ((((R & X_07E0)-(L & X_07E0))*ratios[r] + ((L & X_07E0)<<SHIFT_L6)) & X_0001F800))
+#ifdef WORDS_BIGENDIAN
+ >> SHIFT_R6;
+#else
+ << SHIFT_L10;
+#endif
+
+ L = SOURCE_LOOKUP(srcB[pl]);
+ R = SOURCE_LOOKUP(srcB[pl+1]);
+
+ dpB |= (((((R & X_F81F)-(L & X_F81F))*ratios[r] + ((L & X_F81F)<<SHIFT_L6)) & X_003E07C0) +
+ ((((R & X_07E0)-(L & X_07E0))*ratios[r] + ((L & X_07E0)<<SHIFT_L6)) & X_0001F800))
+#ifdef WORDS_BIGENDIAN
+ >> SHIFT_R6;
+#else
+ << SHIFT_L10;
+#endif
+
+ point += hfraq;
+ r++;
+
+ /* Store */
+ lbT[x] = dpT;
+ lbB[x] = dpB;
+ }
+ }
+ else {
+ /* Swap */
+ lbX = lbT;
+ lbT = lbB;
+ lbB = lbX;
+
+ /*
+ * Two output pixels per step.
+ */
+ for (x=0, r=head, point=point0; x<w2; x++) {
+ /*
+ * Horizontal interpolation
+ */
+ long pl = POINT_L( point, hfraq );
+ HVX_DEBUG("%ld,%ld %lu (%lu/%lu) 0x%x 0x%x\n", x, y, pl,
+ POINT_L( point, hfraq ), POINT_R( point, hfraq ), point, ratios[r] );
+ D_ASSERT( pl >= 0 );
+ D_ASSERT( pl < width-1 );
+ L = SOURCE_LOOKUP(srcB[pl]);
+ R = SOURCE_LOOKUP(srcB[pl+1]);
+
+ dpB = (((((R & X_F81F)-(L & X_F81F))*ratios[r] + ((L & X_F81F)<<SHIFT_L6)) & X_003E07C0) +
+ ((((R & X_07E0)-(L & X_07E0))*ratios[r] + ((L & X_07E0)<<SHIFT_L6)) & X_0001F800))
+#ifdef WORDS_BIGENDIAN
+ << SHIFT_L10;
+#else
+ >> SHIFT_R6;
+#endif
+
+ point += hfraq;
+ r++;
+
+
+ pl = POINT_L( point, hfraq );
+ HVX_DEBUG("%ld,%ld %lu (%lu/%lu) 0x%x 0x%x\n", x, y, pl,
+ POINT_L( point, hfraq ), POINT_R( point, hfraq ), point, ratios[r] );
+ D_ASSERT( pl >= 0 );
+ D_ASSERT( pl < width-1 );
+
+ L = SOURCE_LOOKUP(srcB[pl]);
+ R = SOURCE_LOOKUP(srcB[pl+1]);
+
+ dpB |= (((((R & X_F81F)-(L & X_F81F))*ratios[r] + ((L & X_F81F)<<SHIFT_L6)) & X_003E07C0) +
+ ((((R & X_07E0)-(L & X_07E0))*ratios[r] + ((L & X_07E0)<<SHIFT_L6)) & X_0001F800))
+#ifdef WORDS_BIGENDIAN
+ >> SHIFT_R6;
+#else
+ << SHIFT_L10;
+#endif
+
+ point += hfraq;
+ r++;
+
+ /* Store */
+ lbB[x] = dpB;
+ }
+ }
+
+ lineT = nlT;
+ }
+
+ /*
+ * Vertical interpolation
+ */
+ X = LINE_TO_RATIO( line, vfraq );
+
+ for (x=0; x<w2; x++) {
+#if defined (COLOR_KEY) || defined (KEY_PROTECT)
+#ifdef HAS_ALPHA
+ dt = ((((((lbB[x] & X_F81FF81F) - (lbT[x] & X_F81FF81F))*X) >> SHIFT_R5) + (lbT[x] & X_F81FF81F)) & X_F81FF81F) +
+ ((((((lbB[x]>>SHIFT_R5) & X_F81FF81F) - ((lbT[x]>>SHIFT_R5) & X_F81FF81F))*X) + (lbT[x] & X_07E007E0)) & X_07E007E0);
+#else
+ dt = ((((((lbB[x] & X_07E0F81F) - (lbT[x] & X_07E0F81F))*X) >> SHIFT_R5) + (lbT[x] & X_07E0F81F)) & X_07E0F81F) +
+ ((((((lbB[x]>>SHIFT_R5) & X_07C0F83F) - ((lbT[x]>>SHIFT_R5) & X_07C0F83F))*X) + (lbT[x] & X_F81F07E0)) & X_F81F07E0);
+#endif
+
+ /* Get two new pixels. */
+ l_ = dt;
+ h_ = dt >> 16;
+
+#ifdef COLOR_KEY
+ if ((l_ & MASK_RGB) != (COLOR_KEY)) {
+ if ((h_ & MASK_RGB) != (COLOR_KEY)) {
+#ifdef KEY_PROTECT
+ /* Write to destination with color key protection */
+ dst32[x] = ((((h_ & MASK_RGB) == KEY_PROTECT) ? h_^1 : h_) << 16) | (((l_ & MASK_RGB) == KEY_PROTECT) ? l_^1 : l_);
+#else
+ /* Write to destination without color key protection */
+ dst32[x] = dt;
+#endif
+ }
+ else {
+ u16 *_dst16 = (u16*) &dst32[x];
+
+#ifdef KEY_PROTECT
+ /* Write to destination with color key protection */
+ *_dst16 = (((l_ & MASK_RGB) == KEY_PROTECT) ? l_^1 : l_);
+#else
+ /* Write to destination without color key protection */
+ *_dst16 = l_;
+#endif
+ }
+ }
+ else if ((h_ & MASK_RGB) != (COLOR_KEY)) {
+ u16 *_dst16 = ((u16*) &dst32[x]) + 1;
+
+#ifdef KEY_PROTECT
+ /* Write to destination with color key protection */
+ *_dst16 = (((h_ & MASK_RGB) == KEY_PROTECT) ? h_^1 : h_);
+#else
+ /* Write to destination without color key protection */
+ *_dst16 = h_;
+#endif
+ }
+#else
+ /* Write to destination with color key protection */
+ dst32[x] = ((((h_ & MASK_RGB) == KEY_PROTECT) ? h_^1 : h_) << 16) | (((l_ & MASK_RGB) == KEY_PROTECT) ? l_^1 : l_);
+#endif
+#else
+#ifdef HAS_ALPHA
+ dst32[x] = ((((((lbB[x] & X_F81FF81F) - (lbT[x] & X_F81FF81F))*X) >> SHIFT_R5) + (lbT[x] & X_F81FF81F)) & X_F81FF81F) +
+ ((((((lbB[x]>>SHIFT_R5) & X_F81FF81F) - ((lbT[x]>>SHIFT_R5) & X_F81FF81F))*X) + (lbT[x] & X_07E007E0)) & X_07E007E0);
+#else
+ dst32[x] = ((((((lbB[x] & X_07E0F81F) - (lbT[x] & X_07E0F81F))*X) >> SHIFT_R5) + (lbT[x] & X_07E0F81F)) & X_07E0F81F) +
+ ((((((lbB[x]>>SHIFT_R5) & X_07C0F83F) - ((lbT[x]>>SHIFT_R5) & X_07C0F83F))*X) + (lbT[x] & X_F81F07E0)) & X_F81F07E0);
+#endif
+#endif
+ }
+
+ dst32 += dp4;
+ line += vfraq;
+ }
+
+ if (tail) {
+ u32 dpT, dpB, L, R;
+
+ u16 *dst16 = (u16*)((char*) dst + cw * 2 - 2);
+
+ /* Reset */
+ line = LINE_0 + ctx->clip.y1 * vfraq;
+
+ for (y=0; y<ch; y++) {
+ long X = LINE_TO_RATIO( line, vfraq );
+
+ const SOURCE_TYPE *srcT = (const SOURCE_TYPE *)((char*) src + spitch * LINE_T( line, vfraq ));
+ const SOURCE_TYPE *srcB = (const SOURCE_TYPE *)((char*) src + spitch * LINE_B( line, vfraq ));
+
+ /*
+ * Horizontal interpolation
+ */
+ long pl = POINT_L( point, hfraq );
+ HVX_DEBUG("t,%ld %lu (%lu/%lu) 0x%x 0x%x\n", y, pl,
+ POINT_L( point, hfraq ), POINT_R( point, hfraq ), point, ratios[r] );
+ D_ASSERT( pl >= 0 );
+ D_ASSERT( pl < width-1 );
+ L = SOURCE_LOOKUP(srcT[pl]);
+ R = SOURCE_LOOKUP(srcT[pl+1]);
+
+ dpT = (((((R & X_F81F)-(L & X_F81F))*ratios[r] + ((L & X_F81F)<<SHIFT_L6)) & X_003E07C0) +
+ ((((R & X_07E0)-(L & X_07E0))*ratios[r] + ((L & X_07E0)<<SHIFT_L6)) & X_0001F800)) >> SHIFT_R6;
+
+ L = SOURCE_LOOKUP(srcB[pl]);
+ R = SOURCE_LOOKUP(srcB[pl+1]);
+
+ dpB = (((((R & X_F81F)-(L & X_F81F))*ratios[r] + ((L & X_F81F)<<SHIFT_L6)) & X_003E07C0) +
+ ((((R & X_07E0)-(L & X_07E0))*ratios[r] + ((L & X_07E0)<<SHIFT_L6)) & X_0001F800)) >> SHIFT_R6;
+
+ /*
+ * Vertical interpolation
+ */
+#if defined (COLOR_KEY) || defined (KEY_PROTECT)
+ l_ = ((((((dpB & X_F81F) - (dpT & X_F81F))*X) >> SHIFT_R5) + (dpT & X_F81F)) & X_F81F) +
+ ((((((dpB>>SHIFT_R5) & X_003F) - ((dpT>>SHIFT_R5) & X_003F))*X) + (dpT & X_07E0)) & X_07E0);
+
+#ifdef COLOR_KEY
+ if ((l_ & MASK_RGB) != (COLOR_KEY))
+#endif
+#ifdef KEY_PROTECT
+ /* Write to destination with color key protection */
+ dst16[0] = ((l_ & MASK_RGB) == KEY_PROTECT) ? l_^1 : l_;
+#else
+ /* Write to destination without color key protection */
+ dst16[0] = l_;
+#endif
+#else
+ /* Write to destination without color key protection */
+ dst16[0] = ((((((dpB & X_F81F) - (dpT & X_F81F))*X) >> SHIFT_R5) + (dpT & X_F81F)) & X_F81F) +
+ ((((((dpB>>SHIFT_R5) & X_003F) - ((dpT>>SHIFT_R5) & X_003F))*X) + (dpT & X_07E0)) & X_07E0);
+#endif
+
+ dst16 += dpitch / 2;
+ line += vfraq;
+ }
+ }
+}
+
+
+#undef SHIFT_L6
+#undef SHIFT_L10
+
+#undef X_003F
+
+#undef X_003E07C0
+#undef X_0001F800
+
+#undef X_07E0F81F
+#undef X_F81F07E0
+
+#undef X_07C0F83F
+
+
+
+#ifdef SOURCE_LOOKUP_AUTO
+#undef SOURCE_LOOKUP_AUTO
+#undef SOURCE_LOOKUP
+#endif
+
+#ifdef SOURCE_TYPE_AUTO
+#undef SOURCE_TYPE_AUTO
+#undef SOURCE_TYPE
+#endif
+
diff --git a/src/stretch_hvx_32.h b/src/stretch_hvx_32.h
new file mode 100644
index 0000000..7a86403
--- /dev/null
+++ b/src/stretch_hvx_32.h
@@ -0,0 +1,168 @@
+#ifndef SOURCE_LOOKUP
+#define SOURCE_LOOKUP(x) (x)
+#define SOURCE_LOOKUP_AUTO
+#endif
+
+#ifndef SOURCE_TYPE
+#define SOURCE_TYPE u32
+#define SOURCE_TYPE_AUTO
+#endif
+
+/* stretch_hvx_up/down_32_KPI */( void *dst,
+ int dpitch,
+ const void *src,
+ int spitch,
+ int width,
+ int height,
+ int dst_width,
+ int dst_height,
+ const StretchCtx *ctx )
+{
+ long x, y = 0;
+ long cw = ctx->clip.x2 - ctx->clip.x1 + 1;
+ long ch = ctx->clip.y2 - ctx->clip.y1 + 1;
+ long hfraq = ((long)(width - MINUS_1) << 18) / (long)(dst_width);
+ long vfraq = ((long)(height - MINUS_1) << 18) / (long)(dst_height);
+ long dp4 = dpitch / 4;
+ long point0 = POINT_0 + ctx->clip.x1 * hfraq;
+ long point = point0;
+ long line = LINE_0 + ctx->clip.y1 * vfraq;
+ long ratios[cw];
+ u32 *dst32;
+
+#if defined (COLOR_KEY) || defined (KEY_PROTECT)
+ u32 dt;
+#endif
+
+ u32 _lbT[cw+8];
+ u32 _lbB[cw+8];
+
+ u32 *lbX;
+ u32 *lbT = (u32*)((((unsigned long)(&_lbT[0])) + 31) & ~31);
+ u32 *lbB = (u32*)((((unsigned long)(&_lbB[0])) + 31) & ~31);
+
+ long lineT = -2000;
+
+ for (x=0; x<cw; x++) {
+ ratios[x] = POINT_TO_RATIO( point, hfraq );
+
+ point += hfraq;
+ }
+
+ HVX_DEBUG("%dx%d -> %dx%d (0x%x, 0x%x)\n", width, height, dst_width, dst_height, hfraq, vfraq );
+
+ dst = (void*)((char*) dst + ctx->clip.x1 * 4 + ctx->clip.y1 * dpitch);
+
+ dst32 = (u32*) dst;
+
+ /*
+ * Scale line by line.
+ */
+ for (y=0; y<ch; y++) {
+ long X;
+ long nlT = LINE_T( line, vfraq );
+
+ D_ASSERT( nlT >= 0 );
+ D_ASSERT( nlT < height-1 );
+
+ /*
+ * Fill line buffer(s) ?
+ */
+ if (nlT != lineT) {
+ u32 L, R;
+ const SOURCE_TYPE *srcT = (const SOURCE_TYPE *)((const char*) src + spitch * nlT);
+ const SOURCE_TYPE *srcB = (const SOURCE_TYPE *)((const char*) src + spitch * (nlT + 1));
+ long diff = nlT - lineT;
+
+ if (diff > 1) {
+ /*
+ * Horizontal interpolation
+ */
+ for (x=0, point=point0; x<cw; x++, point += hfraq) {
+ long pl = POINT_L( point, hfraq );
+ HVX_DEBUG("%ld,%ld %lu (%lu/%lu) 0x%x 0x%x\n", x, y, pl,
+ POINT_L( point, hfraq ), POINT_R( point, hfraq ), point, ratios[r] );
+ D_ASSERT( pl >= 0 );
+ D_ASSERT( pl < width-1 );
+
+ L = SOURCE_LOOKUP(srcT[pl]);
+ R = SOURCE_LOOKUP(srcT[pl+1]);
+
+ lbT[x]= ((((((R & X_00FF00FF) - (L & X_00FF00FF))*ratios[x]) >> SHIFT_R8) + (L & X_00FF00FF)) & X_00FF00FF) +
+ ((((((R>>SHIFT_R8) & X_00FF00FF) - ((L>>SHIFT_R8) & X_00FF00FF))*ratios[x]) + (L & X_FF00FF00)) & X_FF00FF00);
+
+ L = SOURCE_LOOKUP(srcB[pl]);
+ R = SOURCE_LOOKUP(srcB[pl+1]);
+
+ lbB[x] = ((((((R & X_00FF00FF) - (L & X_00FF00FF))*ratios[x]) >> SHIFT_R8) + (L & X_00FF00FF)) & X_00FF00FF) +
+ ((((((R>>SHIFT_R8) & X_00FF00FF) - ((L>>SHIFT_R8) & X_00FF00FF))*ratios[x]) + (L & X_FF00FF00)) & X_FF00FF00);
+ }
+ }
+ else {
+ /* Swap */
+ lbX = lbT;
+ lbT = lbB;
+ lbB = lbX;
+
+ /*
+ * Horizontal interpolation
+ */
+ for (x=0, point=point0; x<cw; x++, point += hfraq) {
+ long pl = POINT_L( point, hfraq );
+ HVX_DEBUG("%ld,%ld %lu (%lu/%lu) 0x%x 0x%x\n", x, y, pl,
+ POINT_L( point, hfraq ), POINT_R( point, hfraq ), point, ratios[r] );
+ D_ASSERT( pl >= 0 );
+ D_ASSERT( pl < width-1 );
+
+ L = SOURCE_LOOKUP(srcB[pl]);
+ R = SOURCE_LOOKUP(srcB[pl+1]);
+
+ lbB[x] = ((((((R & X_00FF00FF) - (L & X_00FF00FF))*ratios[x]) >> SHIFT_R8) + (L & X_00FF00FF)) & X_00FF00FF) +
+ ((((((R>>SHIFT_R8) & X_00FF00FF) - ((L>>SHIFT_R8) & X_00FF00FF))*ratios[x]) + (L & X_FF00FF00)) & X_FF00FF00);
+ }
+ }
+
+ lineT = nlT;
+ }
+
+ /*
+ * Vertical interpolation
+ */
+ X = LINE_TO_RATIO( line, vfraq );
+
+ for (x=0; x<cw; x++) {
+#if defined (COLOR_KEY) || defined (KEY_PROTECT)
+ dt = ((((((lbB[x] & X_00FF00FF) - (lbT[x] & X_00FF00FF))*X) >> SHIFT_R8) + (lbT[x] & X_00FF00FF)) & X_00FF00FF) +
+ ((((((lbB[x]>>SHIFT_R8) & X_00FF00FF) - ((lbT[x]>>SHIFT_R8) & X_00FF00FF))*X) + (lbT[x] & X_FF00FF00)) & X_FF00FF00);
+#ifdef COLOR_KEY
+ if (dt != (COLOR_KEY))
+#endif
+#ifdef KEY_PROTECT
+ /* Write to destination with color key protection */
+ dst32[x] = ((dt & MASK_RGB) == KEY_PROTECT) ? dt^1 : dt;
+#else
+ /* Write to destination without color key protection */
+ dst32[x] = dt;
+#endif
+#else
+ /* Write to destination without color key protection */
+ dst32[x] = ((((((lbB[x] & X_00FF00FF) - (lbT[x] & X_00FF00FF))*X) >> SHIFT_R8) + (lbT[x] & X_00FF00FF)) & X_00FF00FF) +
+ ((((((lbB[x]>>SHIFT_R8) & X_00FF00FF) - ((lbT[x]>>SHIFT_R8) & X_00FF00FF))*X) + (lbT[x] & X_FF00FF00)) & X_FF00FF00);
+#endif
+ }
+
+ dst32 += dp4;
+ line += vfraq;
+ }
+}
+
+#ifdef SOURCE_LOOKUP_AUTO
+#undef SOURCE_LOOKUP_AUTO
+#undef SOURCE_LOOKUP
+#endif
+
+#ifdef SOURCE_TYPE_AUTO
+#undef SOURCE_TYPE_AUTO
+#undef SOURCE_TYPE
+#endif
+
diff --git a/src/stretch_hvx_N.h b/src/stretch_hvx_N.h
new file mode 100644
index 0000000..168f4e0
--- /dev/null
+++ b/src/stretch_hvx_N.h
@@ -0,0 +1,42 @@
+#if UPDOWN == 1
+#define FUNC_NAME_(K,P,F) FUNC_NAME(up,K,P,F)
+#else
+#define FUNC_NAME_(K,P,F) FUNC_NAME(down,K,P,F)
+#endif
+
+
+/* NONE */
+static void FUNC_NAME_(_,_,DST_FORMAT)
+#include STRETCH_HVX_N_H
+
+
+/* FIXME: DST_FORMAT == DSPF_RGB16 doesn't work */
+#ifdef FORMAT_RGB16
+/* RGB16 <- RGB32 */
+#define SOURCE_TYPE u32
+#define SOURCE_LOOKUP(x) PIXEL_RGB16( ((x) & 0xff0000) >> 16, \
+ ((x) & 0x00ff00) >> 8, \
+ ((x) & 0x0000ff) )
+static void FUNC_NAME_(_,_,DSPF_RGB32)
+#include STRETCH_HVX_N_H
+
+#undef SOURCE_LOOKUP
+#undef SOURCE_TYPE
+#endif
+
+
+/* FIXME: DST_FORMAT == DSPF_ARGB doesn't work */
+#ifdef FORMAT_ARGB
+/* ARGB <- RGB32 */
+#define SOURCE_TYPE u32
+#define SOURCE_LOOKUP(x) ((x) | 0xff000000)
+static void FUNC_NAME_(_,_,DSPF_RGB32)
+#include STRETCH_HVX_N_H
+
+#undef SOURCE_LOOKUP
+#undef SOURCE_TYPE
+#endif
+
+
+#undef FUNC_NAME_
+
diff --git a/src/stretch_up_down_16.h b/src/stretch_up_down_16.h
new file mode 100644
index 0000000..103dfc3
--- /dev/null
+++ b/src/stretch_up_down_16.h
@@ -0,0 +1,68 @@
+#define STRETCH_HVX_N_H "stretch_hvx_16.h"
+#define uN u16
+
+/**********************************************************************************************************************/
+/* Upscaling */
+
+#define POINT_0 0
+#define LINE_0 0
+#define MINUS_1 1
+#define POINT_TO_RATIO(p,ps) ( ((p) & 0x3ffff) >> (18-SHIFT_L6) )
+#define LINE_TO_RATIO(l,ls) ( ((l) & 0x3ffff) >> (18-SHIFT_L5) )
+
+#define POINT_L(p,ps) ( (((p)) >> 18) )
+#define POINT_R(p,ps) ( (((p)) >> 18) + 1 )
+
+#define LINE_T(l,ls) ( (((l)) >> 18) )
+#define LINE_B(l,ls) ( (((l)) >> 18) + 1 )
+
+#define UPDOWN 1
+#include "stretch_hvx_N.h"
+#undef UPDOWN
+
+#undef POINT_0
+#undef LINE_0
+#undef MINUS_1
+#undef POINT_TO_RATIO
+#undef LINE_TO_RATIO
+#undef POINT_L
+#undef POINT_R
+#undef LINE_T
+#undef LINE_B
+
+/**********************************************************************************************************************/
+/* Downscaling */
+
+#define POINT_0 hfraq
+#define LINE_0 vfraq
+#define MINUS_1 0
+#define POINT_TO_RATIO(p,ps) ( (((((p)) & 0x3ffff) ? : 0x40000) << SHIFT_L6) / (ps) )
+#define LINE_TO_RATIO(l,ls) ( (((((l)) & 0x3ffff) ? : 0x40000) << SHIFT_L5) / (ls) )
+
+#define POINT_L(p,ps) ( (((p)-1) >> 18) - 1 )
+#define POINT_R(p,ps) ( (((p)-1) >> 18) )
+
+#define LINE_T(l,ls) ( (((l)-1) >> 18) - 1 )
+#define LINE_B(l,ls) ( (((l)-1) >> 18) )
+
+#define UPDOWN 0
+#include "stretch_hvx_N.h"
+#undef UPDOWN
+
+#undef POINT_0
+#undef LINE_0
+#undef MINUS_1
+#undef POINT_TO_RATIO
+#undef LINE_TO_RATIO
+#undef POINT_L
+#undef POINT_R
+#undef LINE_T
+#undef LINE_B
+
+/**********************************************************************************************************************/
+
+#undef STRETCH_HVX_N_H
+#undef uN
+
+//#include "stretch_up_down_table.h"
+
diff --git a/src/stretch_up_down_32.h b/src/stretch_up_down_32.h
new file mode 100644
index 0000000..7f2aacc
--- /dev/null
+++ b/src/stretch_up_down_32.h
@@ -0,0 +1,68 @@
+#define STRETCH_HVX_N_H "stretch_hvx_32.h"
+#define uN u32
+
+/**********************************************************************************************************************/
+/* Upscaling */
+
+#define POINT_0 0
+#define LINE_0 0
+#define MINUS_1 1
+#define POINT_TO_RATIO(p,ps) ( ((p) & 0x3ffff) >> (18-SHIFT_L8) )
+#define LINE_TO_RATIO(l,ls) ( ((l) & 0x3ffff) >> (18-SHIFT_L8) )
+
+#define POINT_L(p,ps) ( (((p)) >> 18) )
+#define POINT_R(p,ps) ( (((p)) >> 18) + 1 )
+
+#define LINE_T(l,ls) ( (((l)) >> 18) )
+#define LINE_B(l,ls) ( (((l)) >> 18) + 1 )
+
+#define UPDOWN 1
+#include "stretch_hvx_N.h"
+#undef UPDOWN
+
+#undef POINT_0
+#undef LINE_0
+#undef MINUS_1
+#undef POINT_TO_RATIO
+#undef LINE_TO_RATIO
+#undef POINT_L
+#undef POINT_R
+#undef LINE_T
+#undef LINE_B
+
+/**********************************************************************************************************************/
+/* Downscaling */
+
+#define POINT_0 hfraq
+#define LINE_0 vfraq
+#define MINUS_1 0
+#define POINT_TO_RATIO(p,ps) ( (((((p)) & 0x3ffff) ? : 0x40000) << SHIFT_L8) / (ps) )
+#define LINE_TO_RATIO(l,ls) ( (((((l)) & 0x3ffff) ? : 0x40000) << SHIFT_L8) / (ls) )
+
+#define POINT_L(p,ps) ( (((p)-1) >> 18) - 1 )
+#define POINT_R(p,ps) ( (((p)-1) >> 18) )
+
+#define LINE_T(l,ls) ( (((l)-1) >> 18) - 1 )
+#define LINE_B(l,ls) ( (((l)-1) >> 18) )
+
+#define UPDOWN 0
+#include "stretch_hvx_N.h"
+#undef UPDOWN
+
+#undef POINT_0
+#undef LINE_0
+#undef MINUS_1
+#undef POINT_TO_RATIO
+#undef LINE_TO_RATIO
+#undef POINT_L
+#undef POINT_R
+#undef LINE_T
+#undef LINE_B
+
+/**********************************************************************************************************************/
+
+#undef STRETCH_HVX_N_H
+#undef uN
+
+//#include "stretch_up_down_table.h"
+
diff --git a/src/stretch_up_down_table.h b/src/stretch_up_down_table.h
new file mode 100644
index 0000000..32f208b
--- /dev/null
+++ b/src/stretch_up_down_table.h
@@ -0,0 +1,59 @@
+/**********************************************************************************************************************/
+/* Function table */
+
+static const StretchFunctionTable TABLE_NAME = {
+#define FUNC_NAME_(K,P,F) FUNC_NAME(up,K,P,F)
+ .f[DFB_PIXELFORMAT_INDEX(DST_FORMAT)].up[STRETCH_NONE] = FUNC_NAME_(_,_,DST_FORMAT),
+ .f[DFB_PIXELFORMAT_INDEX(DST_FORMAT)].up[STRETCH_PROTECT] = FUNC_NAME_(_,P,DST_FORMAT),
+ .f[DFB_PIXELFORMAT_INDEX(DST_FORMAT)].up[STRETCH_SRCKEY] = FUNC_NAME_(K,_,DST_FORMAT),
+ .f[DFB_PIXELFORMAT_INDEX(DST_FORMAT)].up[STRETCH_SRCKEY_PROTECT] = FUNC_NAME_(K,P,DST_FORMAT),
+ .f[DFB_PIXELFORMAT_INDEX(DSPF_LUT8)].up[STRETCH_NONE] = FUNC_NAME_(_,_,DSPF_LUT8),
+ .f[DFB_PIXELFORMAT_INDEX(DSPF_LUT8)].up[STRETCH_PROTECT] = FUNC_NAME_(_,P,DSPF_LUT8),
+ .f[DFB_PIXELFORMAT_INDEX(DSPF_LUT8)].up[STRETCH_SRCKEY] = FUNC_NAME_(K,_,DSPF_LUT8),
+ .f[DFB_PIXELFORMAT_INDEX(DSPF_LUT8)].up[STRETCH_SRCKEY_PROTECT] = FUNC_NAME_(K,P,DSPF_LUT8),
+#undef FUNC_NAME_
+
+#define FUNC_NAME_(K,P,F) FUNC_NAME(down,K,P,F)
+ .f[DFB_PIXELFORMAT_INDEX(DST_FORMAT)].down[STRETCH_NONE] = FUNC_NAME_(_,_,DST_FORMAT),
+ .f[DFB_PIXELFORMAT_INDEX(DST_FORMAT)].down[STRETCH_PROTECT] = FUNC_NAME_(_,P,DST_FORMAT),
+ .f[DFB_PIXELFORMAT_INDEX(DST_FORMAT)].down[STRETCH_SRCKEY] = FUNC_NAME_(K,_,DST_FORMAT),
+ .f[DFB_PIXELFORMAT_INDEX(DST_FORMAT)].down[STRETCH_SRCKEY_PROTECT] = FUNC_NAME_(K,P,DST_FORMAT),
+ .f[DFB_PIXELFORMAT_INDEX(DSPF_LUT8)].down[STRETCH_NONE] = FUNC_NAME_(_,_,DSPF_LUT8),
+ .f[DFB_PIXELFORMAT_INDEX(DSPF_LUT8)].down[STRETCH_PROTECT] = FUNC_NAME_(_,P,DSPF_LUT8),
+ .f[DFB_PIXELFORMAT_INDEX(DSPF_LUT8)].down[STRETCH_SRCKEY] = FUNC_NAME_(K,_,DSPF_LUT8),
+ .f[DFB_PIXELFORMAT_INDEX(DSPF_LUT8)].down[STRETCH_SRCKEY_PROTECT] = FUNC_NAME_(K,P,DSPF_LUT8),
+#undef FUNC_NAME_
+
+/* FIXME: DST_FORMAT == DSPF_RGB16 doesn't work */
+#ifdef FORMAT_RGB16
+#define FUNC_NAME_(K,P,F) FUNC_NAME(up,K,P,F)
+ .f[DFB_PIXELFORMAT_INDEX(DSPF_ARGB4444)].up[STRETCH_NONE] = FUNC_NAME_(_,_,DSPF_ARGB4444),
+ .f[DFB_PIXELFORMAT_INDEX(DSPF_ARGB4444)].up[STRETCH_PROTECT] = FUNC_NAME_(_,P,DSPF_ARGB4444),
+ .f[DFB_PIXELFORMAT_INDEX(DSPF_ARGB4444)].up[STRETCH_SRCKEY] = FUNC_NAME_(K,_,DSPF_ARGB4444),
+ .f[DFB_PIXELFORMAT_INDEX(DSPF_ARGB4444)].up[STRETCH_SRCKEY_PROTECT] = FUNC_NAME_(K,P,DSPF_ARGB4444),
+#undef FUNC_NAME_
+#define FUNC_NAME_(K,P,F) FUNC_NAME(down,K,P,F)
+ .f[DFB_PIXELFORMAT_INDEX(DSPF_ARGB4444)].down[STRETCH_NONE] = FUNC_NAME_(_,_,DSPF_ARGB4444),
+ .f[DFB_PIXELFORMAT_INDEX(DSPF_ARGB4444)].down[STRETCH_PROTECT] = FUNC_NAME_(_,P,DSPF_ARGB4444),
+ .f[DFB_PIXELFORMAT_INDEX(DSPF_ARGB4444)].down[STRETCH_SRCKEY] = FUNC_NAME_(K,_,DSPF_ARGB4444),
+ .f[DFB_PIXELFORMAT_INDEX(DSPF_ARGB4444)].down[STRETCH_SRCKEY_PROTECT] = FUNC_NAME_(K,P,DSPF_ARGB4444),
+#undef FUNC_NAME_
+#endif
+
+/* FIXME: DST_FORMAT == DSPF_ARGB4444 doesn't work */
+#ifdef FORMAT_ARGB4444
+#define FUNC_NAME_(K,P,F) FUNC_NAME(up,K,P,F)
+ .f[DFB_PIXELFORMAT_INDEX(DSPF_RGB16)].up[STRETCH_NONE] = FUNC_NAME_(_,_,DSPF_RGB16),
+ .f[DFB_PIXELFORMAT_INDEX(DSPF_RGB16)].up[STRETCH_PROTECT] = FUNC_NAME_(_,P,DSPF_RGB16),
+ .f[DFB_PIXELFORMAT_INDEX(DSPF_RGB16)].up[STRETCH_SRCKEY] = FUNC_NAME_(K,_,DSPF_RGB16),
+ .f[DFB_PIXELFORMAT_INDEX(DSPF_RGB16)].up[STRETCH_SRCKEY_PROTECT] = FUNC_NAME_(K,P,DSPF_RGB16),
+#undef FUNC_NAME_
+#define FUNC_NAME_(K,P,F) FUNC_NAME(down,K,P,F)
+ .f[DFB_PIXELFORMAT_INDEX(DSPF_RGB16)].down[STRETCH_NONE] = FUNC_NAME_(_,_,DSPF_RGB16),
+ .f[DFB_PIXELFORMAT_INDEX(DSPF_RGB16)].down[STRETCH_PROTECT] = FUNC_NAME_(_,P,DSPF_RGB16),
+ .f[DFB_PIXELFORMAT_INDEX(DSPF_RGB16)].down[STRETCH_SRCKEY] = FUNC_NAME_(K,_,DSPF_RGB16),
+ .f[DFB_PIXELFORMAT_INDEX(DSPF_RGB16)].down[STRETCH_SRCKEY_PROTECT] = FUNC_NAME_(K,P,DSPF_RGB16),
+#undef FUNC_NAME_
+#endif
+};
+
diff --git a/src/videodriver.cpp b/src/videodriver.cpp
new file mode 100644
index 0000000..644fa9e
--- /dev/null
+++ b/src/videodriver.cpp
@@ -0,0 +1,905 @@
+#define VC_EXTRALEAN
+
+#include <winsock2.h>
+#include <stdio.h>
+#include <process.h>
+#include <assert.h>
+//#include <crtdbg.h>
+#include <locale.h>
+#include <time.h>
+//#include <tchar.h>
+#include <windows.h>
+#include <io.h>
+
+extern "C" {
+#include <direct/util.h>
+}
+
+#include "Exception.h"
+
+#include "videodriver.h"
+
+//#include <StrSafe.h>
+static const char* driverName = "mv video hook driver2";
+
+#define MAP1 1030
+#define UNMAP1 1031
+#define CURSOREN 1060
+#define CURSORDIS 1061
+
+#define _T(x) (x)
+
+VIDEODRIVER::VIDEODRIVER()
+{
+ mypVideoMemory=NULL;
+ mypchangebuf=NULL;
+ myframebuffer=NULL;
+ shared_buffer_size=0;
+}
+
+void
+VIDEODRIVER::VIDEODRIVER_start(int x,int y,int w,int h)
+{
+ blocked=true;
+ oldaantal=1;
+ mypVideoMemory=NULL;
+ OSVER=OSVersion();
+ if (OSVER==OSWIN2000||OSVER==OSWIN2003||OSVER==OSWINXP||OSVER==OSWINXP64) {
+ if (Mirror_driver_attach_XP(x,y,w,h)) {
+ if (GetDcMirror()!=NULL) {
+ mypVideoMemory=VideoMemory_GetSharedMemory();
+ mypchangebuf=(PCHANGES_BUF)mypVideoMemory;
+ myframebuffer=mypVideoMemory+sizeof(CHANGES_BUF);
+ }
+ else {
+ mypVideoMemory=NULL;
+ }
+ }
+ else {
+ mypVideoMemory=NULL;
+ }
+ }
+ if (OSVER==OSVISTA) {
+ if (Mirror_driver_Vista(1,x,y,w,h)) {
+ if (GetDcMirror()!=NULL) {
+ mypVideoMemory=VideoMemory_GetSharedMemory();
+ mypchangebuf=(PCHANGES_BUF)mypVideoMemory;
+ myframebuffer=mypVideoMemory+sizeof(CHANGES_BUF);
+ //if (mypVideoMemory==NULL) MessageBox(NULL,"MVideo driver failed", NULL, MB_OK);
+ }
+ else {
+ // MessageBox(NULL,"Video driver failed", NULL, MB_OK);
+////////////////////////////////////////////////////////////////////////////////
+ if (Mirror_driver_attach_XP(x,y,w,h)) {
+ if (GetDcMirror()!=NULL) {
+ mypVideoMemory=VideoMemory_GetSharedMemory();
+ mypchangebuf=(PCHANGES_BUF)mypVideoMemory;
+ myframebuffer=mypVideoMemory+sizeof(CHANGES_BUF);
+ }
+ else {
+ mypVideoMemory=NULL;
+ }
+ }
+ else {
+ mypVideoMemory=NULL;
+ }
+////////////////////////////////////////////////////////////////////////////////
+ //mypVideoMemory=NULL;
+ }
+ }
+ else {
+ mypVideoMemory=NULL;
+ }
+ }
+ blocked=false;
+}
+
+void
+VIDEODRIVER::VIDEODRIVER_Stop()
+{
+ OSVER=OSVersion();
+ if (OSVER==OSWIN2000||OSVER==OSWIN2003||OSVER==OSWINXP||OSVER==OSWINXP64) {
+ Mirror_driver_detach_XP();
+ if (mypVideoMemory!=NULL) VideoMemory_ReleaseSharedMemory(mypVideoMemory);
+ }
+ if (OSVER==OSVISTA) {
+ Mirror_driver_Vista(0,0,0,0,0);
+ if (mypVideoMemory!=NULL) VideoMemory_ReleaseSharedMemory(mypVideoMemory);
+ }
+ mypVideoMemory=NULL;
+ mypchangebuf=NULL;
+ myframebuffer=NULL;
+
+
+}
+
+
+VIDEODRIVER::~VIDEODRIVER()
+{
+ //mypVideoMemory=NULL;
+ OSVER=OSVersion();
+ if (OSVER==OSWIN2000||OSVER==OSWIN2003||OSVER==OSWINXP||OSVER==OSWINXP64) {
+ Mirror_driver_detach_XP();
+ if (mypVideoMemory!=NULL) VideoMemory_ReleaseSharedMemory(mypVideoMemory);
+ }
+ if (OSVER==OSVISTA) {
+ Mirror_driver_Vista(0,0,0,0,0);
+ if (mypVideoMemory!=NULL) VideoMemory_ReleaseSharedMemory(mypVideoMemory);
+ }
+
+}
+
+void VIDEODRIVER::VideoMemory_ReleaseSharedMemory(PCHAR pVideoMemory)
+{
+ UnmapViewOfFile(pVideoMemory);
+}
+
+PCHAR VIDEODRIVER::VideoMemory_GetSharedMemory(void)
+{
+ PCHAR pVideoMemory=NULL;
+ HANDLE hMapFile, hFile, hFile0,hFile1;
+ hFile=NULL;
+
+ hFile0 = CreateFile("c:\\video0.dat", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
+ hFile1 = CreateFile("c:\\video1.dat", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
+
+ if ((hFile0 && hFile0 != INVALID_HANDLE_VALUE) && !(hFile1 && hFile1 != INVALID_HANDLE_VALUE)) hFile=hFile0;
+ if ((hFile1 && hFile1 != INVALID_HANDLE_VALUE) && !(hFile0 && hFile0 != INVALID_HANDLE_VALUE)) hFile=hFile1;
+ if ((hFile0 && hFile0 != INVALID_HANDLE_VALUE) && (hFile1 && hFile1 != INVALID_HANDLE_VALUE)) {
+ DWORD size0=GetFileSize(hFile0,NULL);
+ DWORD size1=GetFileSize(hFile1,NULL);
+ if (size0==shared_buffer_size) hFile=hFile0;
+ if (size1==shared_buffer_size) hFile=hFile1;
+ if (size1==shared_buffer_size && size0==shared_buffer_size) {
+ //find last modification time
+ FILETIME createt0, lastWriteTime0, lastAccessTime0;
+ GetFileTime( hFile0, &createt0, &lastAccessTime0, &lastWriteTime0);
+ FILETIME createt1, lastWriteTime1, lastAccessTime1;
+ GetFileTime( hFile0, &createt1, &lastAccessTime1, &lastWriteTime1);
+ LONG result=CompareFileTime(&lastWriteTime0,&lastWriteTime1);
+ if (result==0 || result== 1) hFile=hFile0;
+ else hFile=hFile1;
+
+ }
+
+ }
+
+
+ if (hFile && hFile != INVALID_HANDLE_VALUE) {
+ hMapFile = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, 0, NULL);
+
+ if (hMapFile && hMapFile != INVALID_HANDLE_VALUE) {
+ pVideoMemory = (char *) MapViewOfFile(hMapFile, FILE_MAP_READ, 0, 0, 0);
+
+ CloseHandle(hMapFile);
+ }
+
+ CloseHandle(hFile);
+ }
+ else {
+ throw new PluggIt::Exception( "Error video.dat \n" );
+ }
+
+ return pVideoMemory;
+}
+
+bool
+VIDEODRIVER::Mirror_driver_Vista(DWORD dwAttach,int x,int y,int w,int h)
+{
+ HDESK hdeskInput;
+ HDESK hdeskCurrent;
+ pEnumDisplayDevices pd;
+ HMODULE hUser32=LoadLibrary("USER32");
+ pd = (pEnumDisplayDevices)GetProcAddress( hUser32, "EnumDisplayDevicesA");
+
+ BOOL bED = TRUE;
+ DEVMODE devmode;
+
+ FillMemory(&devmode, sizeof(DEVMODE), 0);
+ devmode.dmSize = sizeof(DEVMODE);
+ devmode.dmDriverExtra = 0;
+
+ // Make sure we have a display on this thread.
+ BOOL change = EnumDisplaySettings(NULL,
+ ENUM_CURRENT_SETTINGS,
+ &devmode);
+
+ devmode.dmFields = DM_BITSPERPEL |
+ DM_PELSWIDTH |
+ DM_PELSHEIGHT |
+ DM_POSITION ;
+
+ if (change) {
+ // query all display devices in the system until we hit a primary
+ // display device. Using it get the width and height of the primary
+ // so we can use that for the mirror driver. Also enumerate the
+ // display devices installed on this machine untill we hit
+ // our favourate mirrored driver, then extract the device name string
+ // of the format '\\.\DISPLAY#'
+// MessageBox(NULL, "change ok", NULL, MB_OK);
+
+ DISPLAY_DEVICE dispDevice;
+
+ FillMemory(&dispDevice, sizeof(DISPLAY_DEVICE), 0);
+
+ dispDevice.cb = sizeof(DISPLAY_DEVICE);
+
+ LPSTR deviceName = NULL;
+
+ devmode.dmDeviceName[0] = '\0';
+
+ INT devNum = 0;
+ BOOL result;
+ DWORD cxPrimary = 0xFFFFFFFF;
+ DWORD cyPrimary = 0xFFFFFFFF;
+
+ // First enumerate for Primary display device:
+ while (result = (*pd)(NULL,
+ devNum,
+ &dispDevice,
+ 0)) {
+// MessageBox(NULL, &dispDevice.DeviceString[0], NULL, MB_OK);
+ if (dispDevice.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE) {
+ // Primary device. Find out its dmPelsWidht and dmPelsHeight.
+ EnumDisplaySettings(dispDevice.DeviceName,
+ ENUM_CURRENT_SETTINGS,
+ &devmode);
+
+ cxPrimary = devmode.dmPelsWidth;
+ cyPrimary = devmode.dmPelsHeight;
+ break;
+ }
+ devNum++;
+ }
+#if defined(MIRROR_24)
+ if (devmode.dmBitsPerPel == 24)
+ devmode.dmBitsPerPel = 32;
+#endif
+ if (devmode.dmBitsPerPel!=8 && devmode.dmBitsPerPel!=16 && devmode.dmBitsPerPel!=32) {
+ if (hUser32) FreeLibrary(hUser32);
+ return false;
+ }
+ shared_buffer_size=devmode.dmBitsPerPel/8*w*h+sizeof(CHANGES_BUF);
+
+ // error check
+ if (!result) {
+// MessageBox(NULL, driverName, NULL, MB_OK);
+ if (hUser32) FreeLibrary(hUser32);
+ return false;
+ }
+
+ if (cxPrimary == 0xffffffff || cyPrimary == 0xffffffff) {
+// MessageBox(NULL,"cxPrimary or cyPrimary not valid", NULL, MB_OK);
+ if (hUser32) FreeLibrary(hUser32);
+ return false;
+ }
+
+ // Enumerate again for the mirror driver:
+ devNum = 0;
+ while (result = (*pd)(NULL,
+ devNum,
+ &dispDevice,
+ 0)) {
+ if (strcmp(&dispDevice.DeviceString[0], driverName) == 0)
+ break;
+
+ devNum++;
+ }
+
+ // error check
+ if (!result) {
+// MessageBox(NULL,driverName, NULL, MB_OK);
+ if (hUser32) FreeLibrary(hUser32);
+ return false;
+ }
+
+// printf("DevNum:%d\nName:%s\nString:%s\nID:%s\nKey:%s\n\n",
+// devNum,
+// &dispDevice.DeviceName[0],
+// &dispDevice.DeviceString[0],
+// &dispDevice.DeviceID[0],
+// &dispDevice.DeviceKey[0]);
+
+ CHAR deviceNum[MAX_PATH];
+ LPSTR deviceSub;
+
+ // Simply extract 'DEVICE#' from registry key. This will depend
+ // on how many mirrored devices your driver has and which ones
+ // you intend to use.
+
+ strupr(&dispDevice.DeviceKey[0]);
+
+ deviceSub = strstr(&dispDevice.DeviceKey[0],
+ "\\DEVICE");
+
+ if (!deviceSub)
+ direct_snputs(&deviceNum[0], "DEVICE0", sizeof(deviceNum));
+ else
+ direct_snputs(&deviceNum[0], ++deviceSub, sizeof(deviceNum));
+
+ // Reset the devmode for mirror driver use:
+ int depth=devmode.dmBitsPerPel;
+ FillMemory(&devmode, sizeof(DEVMODE), 0);
+ devmode.dmSize = sizeof(DEVMODE);
+ devmode.dmDriverExtra = 0;
+ devmode.dmBitsPerPel=depth;
+
+ devmode.dmFields = DM_BITSPERPEL |
+ DM_PELSWIDTH |
+ DM_PELSHEIGHT |
+ DM_POSITION;
+
+ direct_snputs((LPSTR)&devmode.dmDeviceName[0], "mv2", sizeof(devmode.dmDeviceName));
+ deviceName = (LPSTR)&dispDevice.DeviceName[0];
+
+ if (bED) {
+ // Attach and detach information is sent via the dmPelsWidth/Height
+ // of the devmode.
+ //
+// MessageBox(NULL,"bED", NULL, MB_OK);
+ if (dwAttach == 0) {
+ devmode.dmPelsWidth = 0;
+ devmode.dmPelsHeight = 0;
+ }
+ else {
+ devmode.dmPelsWidth=w;
+ devmode.dmPelsHeight=h;
+ devmode.dmPosition.x=x;
+ devmode.dmPosition.y=y;
+ }
+ // Update the mirror device's registry data with the devmode. Dont
+ // do a mode change.
+
+/////////////////////////
+ hdeskCurrent = GetThreadDesktop(GetCurrentThreadId());
+ if (hdeskCurrent != NULL) {
+ hdeskInput = OpenInputDesktop(0, FALSE, MAXIMUM_ALLOWED);
+ if (hdeskInput != NULL) {
+ SetThreadDesktop(hdeskInput);
+ }
+ }
+
+
+ INT code =
+ ChangeDisplaySettingsEx(deviceName,
+ &devmode,
+ NULL,
+ (CDS_UPDATEREGISTRY | CDS_RESET|CDS_GLOBAL),
+ NULL
+ );
+// GetDispCode(code);
+ if (code!=0) {
+ if (hUser32) FreeLibrary(hUser32);
+ return false;
+ }
+ // Now do the real mode change to take mirror driver changes into
+ // effect.
+ code = ChangeDisplaySettingsEx(NULL,
+ NULL,
+ NULL,
+ 0,
+ NULL);
+
+ SetThreadDesktop(hdeskCurrent);
+ CloseDesktop(hdeskInput);
+
+ if (code!=0) {
+ if (hUser32) FreeLibrary(hUser32);
+ return false;
+ }
+ if (hUser32) FreeLibrary(hUser32);
+ return true;
+ }
+ if (hUser32) FreeLibrary(hUser32);
+ return false;
+ }
+ if (hUser32) FreeLibrary(hUser32);
+ return false;
+}
+
+
+
+void
+VIDEODRIVER::Mirror_driver_detach_XP()
+{
+ HDESK hdeskInput;
+ HDESK hdeskCurrent;
+ pEnumDisplayDevices pd;
+ HMODULE hUser32=LoadLibrary("USER32");
+ pd = (pEnumDisplayDevices)GetProcAddress( hUser32, "EnumDisplayDevicesA");
+
+ DEVMODE devmode;
+
+ FillMemory(&devmode, sizeof(DEVMODE), 0);
+
+ devmode.dmSize = sizeof(DEVMODE);
+ devmode.dmDriverExtra = 0;
+
+ BOOL change = EnumDisplaySettings(NULL,
+ ENUM_CURRENT_SETTINGS,
+ &devmode);
+
+ devmode.dmFields = DM_BITSPERPEL |
+ DM_PELSWIDTH |
+ DM_PELSHEIGHT;
+
+ if (change) {
+ // query all display devices in the system until we hit
+ // our favourate mirrored driver, then extract the device name string
+ // of the format '\\.\DISPLAY#'
+
+ DISPLAY_DEVICE dispDevice;
+
+ FillMemory(&dispDevice, sizeof(DISPLAY_DEVICE), 0);
+
+ dispDevice.cb = sizeof(DISPLAY_DEVICE);
+
+ LPSTR deviceName = NULL;
+
+ devmode.dmDeviceName[0] = '\0';
+
+ INT devNum = 0;
+ BOOL result;
+
+ while (result = (*pd)(NULL,
+ devNum,
+ &dispDevice,
+ 0)) {
+ printf("Driver '%s' found.\n", &dispDevice.DeviceString[0]);
+ if (strcmp(&dispDevice.DeviceString[0], driverName) == 0)
+ break;
+
+ devNum++;
+ }
+
+ if (!result) {
+ printf("No '%s' found.\n", driverName);
+ if (hUser32) FreeLibrary(hUser32);
+ return;
+ }
+
+ printf("DevNum:%d\nName:%s\nString:%s\nID:%s\nKey:%s\n\n",
+ devNum,
+ &dispDevice.DeviceName[0],
+ &dispDevice.DeviceString[0],
+ &dispDevice.DeviceID[0],
+ &dispDevice.DeviceKey[0]);
+
+ CHAR deviceNum[MAX_PATH];
+ LPSTR deviceSub;
+
+ // Simply extract 'DEVICE#' from registry key. This will depend
+ // on how many mirrored devices your driver has and which ones
+ // you intend to use.
+
+ strupr(&dispDevice.DeviceKey[0]);
+
+ deviceSub = strstr(&dispDevice.DeviceKey[0],
+ "\\DEVICE");
+
+ if (!deviceSub)
+ direct_snputs(&deviceNum[0], "DEVICE0", sizeof(deviceNum));
+ else
+ direct_snputs(&deviceNum[0], ++deviceSub, sizeof(deviceNum));
+
+ // Add 'Attach.ToDesktop' setting.
+ //
+ {
+ HKEY hKeyProfileMirror = (HKEY)0;
+ if (RegCreateKey(HKEY_LOCAL_MACHINE,
+ _T("SYSTEM\\CurrentControlSet\\Hardware Profiles\\Current\\System\\CurrentControlSet\\Services\\mv2"),
+ &hKeyProfileMirror) != ERROR_SUCCESS) {
+ if (hUser32) FreeLibrary(hUser32);
+ return;
+ }
+
+ HKEY hKeyDevice = (HKEY)0;
+ if (RegCreateKey(hKeyProfileMirror,
+ _T(&deviceNum[0]),
+ &hKeyDevice) != ERROR_SUCCESS) {
+ if (hUser32) FreeLibrary(hUser32);
+ return;
+ }
+
+ DWORD one = 0;
+ if (RegSetValueEx(hKeyDevice,
+ _T("Attach.ToDesktop"),
+ 0,
+ REG_DWORD,
+ (unsigned char *)&one,
+ 4) != ERROR_SUCCESS) {
+ if (hUser32) FreeLibrary(hUser32);
+ return;
+ }
+ RegCloseKey(hKeyProfileMirror);
+ RegCloseKey(hKeyDevice);
+ }
+ {
+ deviceSub = strstr(&dispDevice.DeviceKey[0],
+ "SYSTEM");
+
+ HKEY hKeyProfileMirror = (HKEY)0;
+ if (RegCreateKey(HKEY_LOCAL_MACHINE,
+ _T("SYSTEM\\CurrentControlSet\\Hardware Profiles\\Current"),
+ &hKeyProfileMirror) != ERROR_SUCCESS) {
+ if (hUser32) FreeLibrary(hUser32);
+ return;
+ }
+
+ HKEY hKeyDevice = (HKEY)0;
+ if (RegCreateKey(hKeyProfileMirror,
+ _T(deviceSub),
+ &hKeyDevice) != ERROR_SUCCESS) {
+ if (hUser32) FreeLibrary(hUser32);
+ return;
+ }
+
+ DWORD one = 0;
+ if (RegSetValueEx(hKeyDevice,
+ _T("Attach.ToDesktop"),
+ 0,
+ REG_DWORD,
+ (unsigned char *)&one,
+ 4) != ERROR_SUCCESS) {
+ if (hUser32) FreeLibrary(hUser32);
+ return;
+ }
+ RegCloseKey(hKeyProfileMirror);
+ RegCloseKey(hKeyDevice);
+ }
+
+
+ FillMemory(&devmode, sizeof(DEVMODE), 0);
+
+ devmode.dmSize = sizeof(DEVMODE);
+ devmode.dmDriverExtra = 0;
+
+ direct_snputs((LPSTR)&devmode.dmDeviceName[0], "mv2", sizeof(devmode.dmDeviceName));
+ deviceName = (LPSTR)&dispDevice.DeviceName[0];
+ devmode.dmBitsPerPel=32;
+ // add 'Default.*' settings to the registry under above hKeyProfile\mirror\device
+ hdeskCurrent = GetThreadDesktop(GetCurrentThreadId());
+ if (hdeskCurrent != NULL) {
+ hdeskInput = OpenInputDesktop(0, FALSE, MAXIMUM_ALLOWED);
+ if (hdeskInput != NULL) {
+ SetThreadDesktop(hdeskInput);
+ }
+ }
+
+ INT code =
+ ChangeDisplaySettingsEx(deviceName,
+ &devmode,
+ NULL,
+ CDS_UPDATEREGISTRY,
+ NULL
+ );
+
+// GetDispCode(code);
+
+ code = ChangeDisplaySettingsEx(deviceName,
+ &devmode,
+ NULL,
+ 0,
+ NULL
+ );
+
+ SetThreadDesktop(hdeskCurrent);
+ CloseDesktop(hdeskInput);
+
+ }
+ if (hUser32) FreeLibrary(hUser32);
+}
+
+//BOOL
+//Activate_video_driver();
+
+bool
+VIDEODRIVER::Mirror_driver_attach_XP(int x,int y,int w,int h)
+{
+ HDESK hdeskInput;
+ HDESK hdeskCurrent;
+
+ pEnumDisplayDevices pd;
+ HMODULE hUser32=LoadLibrary("USER32");
+ pd = (pEnumDisplayDevices)GetProcAddress( hUser32, "EnumDisplayDevicesA");
+
+ DEVMODE devmode;
+
+ FillMemory(&devmode, sizeof(DEVMODE), 0);
+
+ devmode.dmSize = sizeof(DEVMODE);
+ devmode.dmDriverExtra = 0;
+
+ BOOL change = EnumDisplaySettings(NULL,
+ ENUM_CURRENT_SETTINGS,
+ &devmode);
+
+ devmode.dmFields = DM_BITSPERPEL |
+ DM_PELSWIDTH |
+ DM_POSITION |
+ DM_PELSHEIGHT;
+
+#if defined(MIRROR_24)
+ // for 24 bit mode, have the mirror driver use 32 bit.
+ if (devmode.dmBitsPerPel == 24)
+ devmode.dmBitsPerPel = 32;
+#endif
+ if (devmode.dmBitsPerPel!=8 && devmode.dmBitsPerPel!=16 && devmode.dmBitsPerPel!=32) {
+ if (hUser32) FreeLibrary(hUser32);
+ return false;
+ }
+
+ shared_buffer_size=devmode.dmBitsPerPel/8*w*h+sizeof(CHANGES_BUF);
+
+ if (change) {
+ // query all display devices in the system until we hit
+ // our favourate mirrored driver, then extract the device name string
+ // of the format '\\.\DISPLAY#'
+
+ DISPLAY_DEVICE dispDevice;
+
+ FillMemory(&dispDevice, sizeof(DISPLAY_DEVICE), 0);
+
+ dispDevice.cb = sizeof(DISPLAY_DEVICE);
+
+ LPSTR deviceName = NULL;
+
+ devmode.dmDeviceName[0] = '\0';
+
+ INT devNum = 0;
+ BOOL result;
+
+ while (result = (*pd)(NULL,
+ devNum,
+ &dispDevice,
+ 0)) {
+ if (strcmp(&dispDevice.DeviceString[0], driverName) == 0)
+ break;
+
+ devNum++;
+ }
+
+ if (!result) {
+ printf("No '%s' found.\n", driverName);
+ if (hUser32) FreeLibrary(hUser32);
+ return false;
+ }
+
+ printf("DevNum:%d\nName:%s\nString:%s\nID:%s\nKey:%s\n\n",
+ devNum,
+ &dispDevice.DeviceName[0],
+ &dispDevice.DeviceString[0],
+ &dispDevice.DeviceID[0],
+ &dispDevice.DeviceKey[0]);
+
+ CHAR deviceNum[MAX_PATH];
+ LPSTR deviceSub;
+
+ // Simply extract 'DEVICE#' from registry key. This will depend
+ // on how many mirrored devices your driver has and which ones
+ // you intend to use.
+
+ strupr(&dispDevice.DeviceKey[0]);
+
+ deviceSub = strstr(&dispDevice.DeviceKey[0],
+ "\\DEVICE");
+
+ if (!deviceSub)
+ direct_snputs(&deviceNum[0], "DEVICE0", MAX_PATH);
+ else
+ direct_snputs(&deviceNum[0], ++deviceSub, MAX_PATH);
+
+ // Add 'Attach.ToDesktop' setting.
+ //
+
+ HKEY hKeyProfileMirror = (HKEY)0;
+ if (RegCreateKey(HKEY_LOCAL_MACHINE,
+ _T("SYSTEM\\CurrentControlSet\\Hardware Profiles\\Current\\System\\CurrentControlSet\\Services\\mv2"),
+ &hKeyProfileMirror) != ERROR_SUCCESS) {
+ if (hUser32) FreeLibrary(hUser32);
+ return false;
+ }
+
+ HKEY hKeyDevice = (HKEY)0;
+ if (RegCreateKey(hKeyProfileMirror,
+ _T(&deviceNum[0]),
+ &hKeyDevice) != ERROR_SUCCESS) {
+ if (hUser32) FreeLibrary(hUser32);
+ return false;
+ }
+
+ DWORD one = 1;
+ if (RegSetValueEx(hKeyDevice,
+ _T("Attach.ToDesktop"),
+ 0,
+ REG_DWORD,
+ (unsigned char *)&one,
+ 4) != ERROR_SUCCESS) {
+ if (hUser32) FreeLibrary(hUser32);
+ return false;
+ }
+ int depth=devmode.dmBitsPerPel;
+
+ FillMemory(&devmode, sizeof(DEVMODE), 0);
+
+ devmode.dmSize = sizeof(DEVMODE);
+ devmode.dmDriverExtra = 0;
+
+ direct_snputs((LPSTR)&devmode.dmDeviceName[0], "mv2", 32);
+
+ devmode.dmFields = DM_BITSPERPEL |
+ DM_PELSWIDTH |
+ DM_POSITION |
+ DM_PELSHEIGHT;
+ deviceName = (LPSTR)&dispDevice.DeviceName[0];
+ devmode.dmPelsWidth=w;
+ devmode.dmPelsHeight=h;
+ devmode.dmPosition.x=x;
+ devmode.dmPosition.y=y;
+ devmode.dmBitsPerPel=depth;
+
+ hdeskCurrent = GetThreadDesktop(GetCurrentThreadId());
+ if (hdeskCurrent != NULL) {
+ hdeskInput = OpenInputDesktop(0, FALSE, MAXIMUM_ALLOWED);
+ if (hdeskInput != NULL) {
+ SetThreadDesktop(hdeskInput);
+ }
+ }
+
+ // add 'Default.*' settings to the registry under above hKeyProfile\mirror\device
+ INT code =
+ ChangeDisplaySettingsEx(deviceName,
+ &devmode,
+ NULL,
+ CDS_UPDATEREGISTRY,
+ NULL
+ );
+
+// GetDispCode(code);
+ if (code!=0) {
+ if (hUser32) FreeLibrary(hUser32);
+ return false;
+ }
+ code = ChangeDisplaySettingsEx(deviceName,
+ &devmode,
+ NULL,
+ 0,
+ NULL
+ );
+
+ SetThreadDesktop(hdeskCurrent);
+ CloseDesktop(hdeskInput);
+
+ RegCloseKey(hKeyProfileMirror);
+ RegCloseKey(hKeyDevice);
+ if (code!=0) {
+ if (hUser32) FreeLibrary(hUser32);
+ return false;
+ }
+ if (hUser32) FreeLibrary(hUser32);
+ return true;
+ }
+ if (hUser32) FreeLibrary(hUser32);
+ return false;
+}
+
+int
+VIDEODRIVER::OSVersion()
+{
+ OSVERSIONINFOEX osvi;
+ SYSTEM_INFO si;
+ PGNSI pGNSI;
+ BOOL bOsVersionInfoEx;
+
+ ZeroMemory(&si, sizeof(SYSTEM_INFO));
+ ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
+ osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
+ if ( !(bOsVersionInfoEx = GetVersionEx ((OSVERSIONINFO *) &osvi)) ) {
+ osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
+ if (! GetVersionEx ( (OSVERSIONINFO *) &osvi) )
+ return FALSE;
+ }
+ pGNSI = (PGNSI) GetProcAddress(
+ GetModuleHandle(TEXT("kernel32.dll")),
+ "GetNativeSystemInfo");
+ if (NULL != pGNSI)
+ pGNSI(&si);
+ else GetSystemInfo(&si);
+
+ switch (osvi.dwPlatformId) {
+ case VER_PLATFORM_WIN32_NT:
+
+ // Test for the specific product.
+
+ if ( osvi.dwMajorVersion == 6) {
+ return OSVISTA;
+ }
+
+ if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2 ) {
+ if ( osvi.wProductType == VER_NT_WORKSTATION &&
+ si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64) {
+ return OSWINXP64;
+ }
+ else return OSWIN2003;
+ }
+
+ if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1 )
+ return OSWINXP;
+
+ if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0 )
+ return OSWIN2000;
+
+ if ( osvi.dwMajorVersion <= 4 )
+ return OSOLD;
+
+ }
+ return OSOLD;
+}
+
+
+HDC
+VIDEODRIVER::GetDcMirror()
+{
+ typedef BOOL (WINAPI* pEnumDisplayDevices)(PVOID,DWORD,PVOID,DWORD);
+ HDC m_hrootdc=NULL;
+ pEnumDisplayDevices pd;
+ static const char* driverName = "mv video hook driver2";
+ BOOL DriverFound;
+ DEVMODE devmode;
+ FillMemory(&devmode, sizeof(DEVMODE), 0);
+ devmode.dmSize = sizeof(DEVMODE);
+ devmode.dmDriverExtra = 0;
+ BOOL change = EnumDisplaySettings(NULL,ENUM_CURRENT_SETTINGS,&devmode);
+ devmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
+ HMODULE hUser32=LoadLibrary("USER32");
+ pd = (pEnumDisplayDevices)GetProcAddress( hUser32, "EnumDisplayDevicesA");
+ if (pd) {
+ LPSTR deviceName=NULL;
+ DISPLAY_DEVICE dd;
+ ZeroMemory(&dd, sizeof(dd));
+ dd.cb = sizeof(dd);
+ devmode.dmDeviceName[0] = '\0';
+ INT devNum = 0;
+ BOOL result;
+ DriverFound=false;
+ while (result = (*pd)(NULL,devNum, &dd,0)) {
+ if (strcmp((const char *)&dd.DeviceString[0], driverName) == 0) {
+ DriverFound=true;
+ break;
+ }
+ devNum++;
+ }
+ if (DriverFound) {
+ deviceName = (LPSTR)&dd.DeviceName[0];
+ m_hrootdc = CreateDC("DISPLAY",deviceName,NULL,NULL);
+ if (m_hrootdc) DeleteDC(m_hrootdc);
+ }
+ }
+ if (hUser32) FreeLibrary(hUser32);
+
+ return m_hrootdc;
+}
+
+BOOL
+VIDEODRIVER:: HardwareCursor()
+{
+ HDC gdc;
+ int returnvalue;
+ gdc = GetDC(NULL);
+ returnvalue= ExtEscape(gdc, MAP1, 0, NULL, NULL, NULL);
+ returnvalue= ExtEscape(gdc, CURSOREN, 0, NULL, NULL, NULL);
+ ReleaseDC(NULL,gdc);
+ return true;
+}
+
+BOOL
+VIDEODRIVER:: NoHardwareCursor()
+{
+ HDC gdc;
+ int returnvalue;
+ gdc = GetDC(NULL);
+ returnvalue= ExtEscape(gdc, CURSORDIS, 0, NULL, NULL, NULL);
+ ReleaseDC(NULL,gdc);
+ return true;
+}
+
diff --git a/src/videodriver.h b/src/videodriver.h
new file mode 100644
index 0000000..fefa489
--- /dev/null
+++ b/src/videodriver.h
@@ -0,0 +1,76 @@
+#ifndef _VIDEOD_H
+#define _VIDEOD_H
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <windows.h>
+
+//#include <tchar.h>
+#include <winbase.h>
+#include <winreg.h>
+//#include <StrSafe.h>
+
+#define MAXCHANGES_BUF 2000
+
+#define OSVISTA 6
+#define OSWINXP 5
+#define OSWIN2000 5
+#define OSWIN2003 5
+#define OSOLD 4
+#define OSWINXP64 7
+
+#define SCREEN_SCREEN 11
+#define BLIT 12
+#define SOLIDFILL 13
+#define BLEND 14
+#define TRANS 15
+#define PLG 17
+#define TEXTOUT 18
+
+typedef BOOL (WINAPI* pEnumDisplayDevices)(PVOID,DWORD,PVOID,DWORD);
+typedef LONG (WINAPI* pChangeDisplaySettingsExA)(LPCSTR,LPDEVMODEA,HWND,DWORD,LPVOID);
+typedef void (WINAPI *PGNSI)(LPSYSTEM_INFO);
+typedef struct _CHANGES_RECORD {
+ ULONG type; //screen_to_screen, blit, newcache,oldcache
+ RECT rect;
+ POINT point;
+}CHANGES_RECORD;
+typedef CHANGES_RECORD *PCHANGES_RECORD;
+typedef struct _CHANGES_BUF {
+ ULONG counter;
+ CHANGES_RECORD pointrect[MAXCHANGES_BUF];
+}CHANGES_BUF;
+typedef CHANGES_BUF *PCHANGES_BUF;
+
+class VIDEODRIVER {
+public:
+ VIDEODRIVER();
+ void VIDEODRIVER_start(int x,int y,int w,int h);
+ void VIDEODRIVER_Stop();
+ virtual ~VIDEODRIVER();
+ BOOL HardwareCursor();
+ BOOL NoHardwareCursor();
+
+ ULONG oldaantal;
+ PCHAR mypVideoMemory;
+ PCHAR myframebuffer;
+ PCHANGES_BUF mypchangebuf;
+ BOOL blocked;
+ DWORD shared_buffer_size;
+
+
+protected:
+ int OSVersion();
+ bool Mirror_driver_attach_XP(int x,int y,int w,int h);
+ void Mirror_driver_detach_XP();
+ bool Mirror_driver_Vista(DWORD dwAttach,int x,int y,int w,int h);
+ PCHAR VideoMemory_GetSharedMemory(void);
+ void VideoMemory_ReleaseSharedMemory(PCHAR pVideoMemory);
+ HDC GetDcMirror();
+
+ int OSVER;
+
+};
+
+#endif
diff --git a/src/videodrivercheck.cpp b/src/videodrivercheck.cpp
new file mode 100644
index 0000000..93a407f
--- /dev/null
+++ b/src/videodrivercheck.cpp
@@ -0,0 +1,154 @@
+#include <windows.h>
+#include <stdlib.h>
+//#include "vncOSVersion.h"
+
+typedef BOOL (WINAPI* pEnumDisplayDevices)(PVOID,DWORD,PVOID,DWORD);
+
+/*bool CheckDriver2(void)
+{
+ SC_HANDLE schMaster;
+ SC_HANDLE schSlave;
+
+ schMaster = OpenSCManager (NULL, NULL, SC_MANAGER_ALL_ACCESS);
+
+ schSlave = OpenService (schMaster, "vnccom", SERVICE_ALL_ACCESS);
+
+ if (schSlave == NULL)
+ {
+ CloseServiceHandle(schMaster);
+ return false;
+ }
+ else
+ {
+ CloseServiceHandle (schSlave);
+ CloseServiceHandle(schMaster);
+ return true;
+ }
+}*/
+
+
+///////////////////////////////////////////////////////////////////
+BOOL GetDllProductVersion(char* dllName, char *vBuffer, int size)
+{
+ char *versionInfo;
+ void *lpBuffer;
+ unsigned int cBytes;
+ DWORD rBuffer;
+
+ if( !dllName || !vBuffer )
+ return(FALSE);
+
+// DWORD sName = GetModuleFileName(NULL, fileName, sizeof(fileName));
+// FYI only
+ DWORD sVersion = GetFileVersionInfoSize(dllName, &rBuffer);
+ if (sVersion==0) return (FALSE);
+ versionInfo = new char[sVersion];
+
+ BOOL resultVersion = GetFileVersionInfo(dllName,
+ NULL,
+ sVersion,
+ versionInfo);
+
+ BOOL resultValue = VerQueryValue(versionInfo,
+
+TEXT("\\StringFileInfo\\040904b0\\ProductVersion"),
+ &lpBuffer,
+ &cBytes);
+
+ if( !resultValue )
+ {
+ resultValue = VerQueryValue(versionInfo,TEXT("\\StringFileInfo\\000004b0\\ProductVersion"),
+ &lpBuffer,
+ &cBytes);
+
+ }
+
+ if( resultValue )
+ {
+ strncpy(vBuffer, (char *) lpBuffer, size);
+ delete versionInfo;
+ return(TRUE);
+ }
+ else
+ {
+ *vBuffer = '\0';
+ delete versionInfo;
+ return(FALSE);
+ }
+}
+
+///////////////////////////////////////////////////////////////////
+
+bool
+CheckVideoDriver(bool Box)
+{
+ typedef BOOL (WINAPI* pEnumDisplayDevices)(PVOID,DWORD,PVOID,DWORD);
+ HDC m_hrootdc=NULL;
+ pEnumDisplayDevices pd;
+ static const char* driverName = "mv video hook driver2";
+ BOOL DriverFound;
+ DEVMODE devmode;
+ FillMemory(&devmode, sizeof(DEVMODE), 0);
+ devmode.dmSize = sizeof(DEVMODE);
+ devmode.dmDriverExtra = 0;
+ BOOL change = EnumDisplaySettings(NULL,ENUM_CURRENT_SETTINGS,&devmode);
+ devmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
+ HMODULE hUser32=LoadLibrary("USER32");
+ pd = (pEnumDisplayDevices)GetProcAddress( hUser32, "EnumDisplayDevicesA");
+ if (pd)
+ {
+ LPSTR deviceName=NULL;
+ DISPLAY_DEVICE dd;
+ ZeroMemory(&dd, sizeof(dd));
+ dd.cb = sizeof(dd);
+ devmode.dmDeviceName[0] = '\0';
+ INT devNum = 0;
+ BOOL result;
+ DriverFound=false;
+ while (result = (*pd)(NULL,devNum, &dd,0))
+ {
+ if (strcmp((const char *)&dd.DeviceString[0], driverName) == 0)
+ {
+ DriverFound=true;
+ break;
+ }
+ devNum++;
+ }
+ if (DriverFound)
+ {
+ if (hUser32) FreeLibrary(hUser32);
+ if(Box)
+ {
+ char buf[512];
+ GetDllProductVersion((char*)"mv2.dll",buf,512);
+ if (dd.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP)
+ {
+ strcat(buf," driver Active");
+ HDC testdc=NULL;
+ deviceName = (LPSTR)&dd.DeviceName[0];
+ testdc = CreateDC("DISPLAY",deviceName,NULL,NULL);
+ if (testdc)
+ {
+ DeleteDC(testdc);
+ strcat(buf," access ok");
+ }
+ else
+ {
+ strcat(buf," access denied, permission problem");
+ }
+ }
+ else
+ strcat(buf," driver Not Active");
+
+ MessageBox(NULL,buf,"driver info: required version 1.22",0);
+ }
+ return true;
+ //deviceName = (LPSTR)&dd.DeviceName[0];
+ //m_hrootdc = CreateDC("DISPLAY",deviceName,NULL,NULL);
+ //if (m_hrootdc) DeleteDC(m_hrootdc);
+ }
+ else if(Box) MessageBox(NULL,"Driver not found: Perhaps you need to reboot after install","driver info: required version 1.22",0);
+ }
+ if (hUser32) FreeLibrary(hUser32);
+ return false;
+}