Qt/Embedded 2.3.10:
authorMichael Lauer <mickey@vanille-media.de>
Thu, 30 Jun 2005 19:30:36 +0000 (19:30 +0000)
committerOpenEmbedded Project <openembedded-devel@lists.openembedded.org>
Thu, 30 Jun 2005 19:30:36 +0000 (19:30 +0000)
- Fix linuxfb overflow with offscreen pixmaps
- Fix qte calling ::sync() instead of QScreen::sync()
- Fix rotation in W100 accellerated driver
All patches courtesy QtE Uberhacker Manuel Teira - thanks a lot, Manuel.

packages/qte/qte-2.3.10/c7x0-w100-accel.patch
packages/qte/qte-2.3.10/fix-linuxfb-offscreenoverflow.patch [new file with mode: 0644]
packages/qte/qte-2.3.10/fix-qscreen-sync.patch [new file with mode: 0644]
packages/qte/qte_2.3.10.bb

index 5cff746..f2e07bd 100644 (file)
@@ -67,6 +67,15 @@ Manuel Teira <manuel.teira@telefonica.net>
  #if !defined(QT_NO_QWS_TRANSFORMED)
      { "Transformed", qt_get_screen_transformed, 0 },
  #endif
+@@ -6039,6 +6046,8 @@
+           qt_screen = driverTable[i].qt_get_screen( display_id );
+           if ( qt_screen ) {
+               if ( qt_screen->connect( spec ) ) {
++                printf( "[%d]:Connected to screen '%s'\n", 
++                        getpid(), driverTable[i].name );
+                   return qt_screen;
+               } else {
+                   delete qt_screen;
 --- /dev/null
 +++ qt-2.3.10/src/3rdparty/kernel/aticore/aticore.h
 @@ -0,0 +1,567 @@
@@ -639,7 +648,8 @@ Manuel Teira <manuel.teira@telefonica.net>
 +#endif
 --- /dev/null
 +++ qt-2.3.10/src/kernel/qgfxw100_qws.cpp
-@@ -0,0 +1,1466 @@
+@@ -0,0 +1,2283 @@
++ /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil -*- */
 +/***************************************************************************
 +
 +** Imageon driver for qte using libAticore
@@ -673,1431 +683,2247 @@ Manuel Teira <manuel.teira@telefonica.net>
 +class W100Control {
 +public:
 +
-+  typedef enum Loglevel {
-+    ERROR = 0,
-+    WARNING,
-+    INFO
-+  };
-+
-+  typedef enum Opcodes {
-+    DRAWLINE = 1,
-+    DRAWPOINT,
-+    DRAWPOINTS,
-+    FILLRECT,
-+    SCROLL,
-+    BITBLT,
-+    POLYLINE,
-+    EOO
-+  };
-+
-+  typedef struct Opcode {
-+    QString str;
-+    int index;
-+    bool accelerated;
-+    int hits;
-+    int misses;
-+  };
-+
-+  static Opcode lOpcodes[];
-+
-+  static QString level2str( int level )
-+  {
-+    switch( level ) {
-+    case ERROR:
-+      return QString( "ERROR" );
-+      break;
-+    case WARNING:
-+      return QString( "WARNING" );
-+      break;
-+    case INFO:
-+      return QString( "INFO" );
-+      break;
-+    default:
-+      return QString( "UNKNOWN" );
-+      break;
-+    }
-+  }
-+
-+  W100Control():
-+    m_loglevel( 0 ),
-+    m_enabled( 0 )
-+  {
-+    m_loglevel = 0;
-+    char *var;
-+    if ( var = getenv( "W100_DEBUG" ) ) {
-+      if ( strtol( var, 0, 0 ) == 1 ) {
-+      m_enabled = 1;
-+      }
-+    }
-+
-+    if ( m_enabled ) {
-+      if ( var = getenv( "W100_DEBUGLEVEL" ) ) {
-+      if ( ( m_loglevel = strtol( var, 0, 0 ) ) < 0 ) {
-+        m_loglevel = 0;
-+      }
-+      }
-+
-+      QString path( "/mnt/card/w100/w100debug.log" );
-+      if ( var = getenv( "W100_DEBUGPATH" ) ) {
-+      path = QString( var ) + "/w100debug.log";
-+      } 
-+      m_logfile = fopen( path.latin1(), "w" );
-+      if ( m_logfile == NULL ) m_enabled = 0;
-+    }
-+
-+    Opcode *opcodePtr = lOpcodes;
-+    int i = 1;
-+    while ( opcodePtr->index != EOO ) {
-+      if ( opcodePtr->index != i ) {
-+      fprintf( stderr, "Opcode list is not ordered!!\n" );
-+      abort();
-+      }
-+
-+      QString varName = "W100_ACCEL_" + opcodePtr->str;
-+      char *varPtr;
-+      if ( ( varPtr = getenv( varName.latin1() ) )  ) {
-+      if ( ( strtol( varPtr, NULL, 0 ) == 0 ) ||
-+           ( strcmp( varPtr, "false" ) == 0 ) )  {
-+        opcodePtr->accelerated = false;
-+      }
-+      }
-+      opcodePtr++;
-+      i++;
-+    }
-+  }
-+
-+  ~W100Control()
-+  {
-+    //Dump statistics about any opcode
-+    Opcode *opcodePtr = lOpcodes;
-+    while ( opcodePtr->index != EOO ) {
-+      log( WARNING, "Opcode %s. Accelerated=%s. Hits=%d. Misses=%d",
-+         opcodePtr->str.latin1(),
-+         opcodePtr->accelerated ? "true" : "false",
-+         opcodePtr->hits,
-+         opcodePtr->misses );
-+      opcodePtr++;
-+    }
-+    if ( m_enabled && m_logfile ) {
-+      fclose( m_logfile );
-+    }
-+  }
-+
-+  bool accelerated( int opcode )
-+  {
-+    if ( opcode < EOO ) {
-+      return lOpcodes[opcode].accelerated;
++    typedef enum Loglevel {
++        ERROR = 0,
++        WARNING,
++        INFO
++    };
++
++    typedef enum Opcodes {
++        DRAWLINE = 0,
++        DRAWPOINT,
++        DRAWPOINTS,
++        FILLRECT,
++        SCROLL,
++        BITBLT,
++        POLYLINE,
++        EOO
++    };
++
++    typedef struct Opcode {
++        QString str;
++        int index;
++        bool accelerated;
++        int hits;
++        int misses;
++    };
++
++    static Opcode lOpcodes[];
++
++    static QString level2str( int level )
++    {
++        switch( level ) {
++        case ERROR:
++            return QString( "ERROR" );
++            break;
++        case WARNING:
++            return QString( "WARNING" );
++            break;
++        case INFO:
++            return QString( "INFO" );
++            break;
++        default:
++            return QString( "UNKNOWN" );
++            break;
++        }
++    }
++
++    W100Control():
++        m_loglevel( 0 ),
++        m_enabled( 0 )
++    {
++        m_loglevel = 0;
++        char *var;
++        if ( var = getenv( "W100_DEBUG" ) ) {
++            if ( strtol( var, 0, 0 ) == 1 ) {
++                m_enabled = 1;
++            }
++        }
++
++        if ( m_enabled ) {
++            if ( var = getenv( "W100_DEBUGLEVEL" ) ) {
++                if ( ( m_loglevel = strtol( var, 0, 0 ) ) < 0 ) {
++                    m_loglevel = 0;
++                }
++            }
++
++            QString path( "/mnt/card/w100/w100debug.log" );
++            if ( var = getenv( "W100_DEBUGPATH" ) ) {
++                path = QString( var ) + "/w100debug.log";
++            } 
++            m_logfile = fopen( path.latin1(), "a" );
++            if ( m_logfile == NULL ) m_enabled = 0;
++        }
++
++        Opcode *opcodePtr = lOpcodes;
++        while ( opcodePtr->index != EOO ) {
++            QString varName = "W100_ACCEL_" + opcodePtr->str;
++            char *varPtr;
++            if ( ( varPtr = getenv( varName.latin1() ) )  ) {
++                if ( ( strtol( varPtr, NULL, 0 ) == 0 ) ||
++                     ( strcmp( varPtr, "false" ) == 0 ) )  {
++                    opcodePtr->accelerated = false;
++                }
++            }
++            opcodePtr++;
++        }
++    }
++
++    ~W100Control()
++    {
++        //Dump statistics about any opcode
++        Opcode *opcodePtr = lOpcodes;
++        while ( opcodePtr->index != EOO ) {
++            log( WARNING, "Opcode %s. Accelerated=%s. Hits=%d. Misses=%d",
++                 opcodePtr->str.latin1(),
++                 opcodePtr->accelerated ? "true" : "false",
++                 opcodePtr->hits,
++                 opcodePtr->misses );
++            opcodePtr++;
++        }
++        if ( m_enabled && m_logfile ) {
++            fclose( m_logfile );
++        }
++    }
++
++    bool accelerated( int opcode )
++    {
++        if ( opcode < EOO ) {
++            return lOpcodes[opcode].accelerated;
++        }
++        return false;
++    }
++
++    void addHit( int opcode )
++    {
++        lOpcodes[opcode].hits++;
++    }
++
++    void addMiss( int opcode )
++    {
++        lOpcodes[opcode].misses++;
++    }
++
++    void log( int level, const char *fmt, ... )
++    {
++        if ( m_enabled && ( level <= m_loglevel ) ) {
++            char buffer[1024];
++            va_list ap;
++            va_start( ap, fmt );
++            vsnprintf( buffer, 1023, fmt, ap );
++            va_end( ap );
++            fprintf( m_logfile, "%d:%s:%s\n", getpid(),
++                     level2str( level ).latin1(), 
++                     buffer );
++            fflush( m_logfile );
++        }
 +    }
-+    return false;
-+  }
-+
-+  void addHit( int opcode )
-+  {
-+    lOpcodes[opcode].hits++;
-+    ( *lastop ) = opcode;
-+  }
-+
-+  int lastOp( void ) const
-+  {
-+    return ( *lastop );
-+  }
-+
-+  void addMiss( int opcode )
-+  {
-+    lOpcodes[opcode].misses++;
-+  }
-+
-+  void log( int level, const char *fmt, ... )
-+  {
-+    if ( m_enabled && ( level <= m_loglevel ) ) {
-+      char buffer[1024];
-+      va_list ap;
-+      va_start( ap, fmt );
-+      vsnprintf( buffer, 1023, fmt, ap );
-+      va_end( ap );
-+      fprintf( m_logfile, "%d:%s:%s\n", getpid(),
-+             level2str( level ).latin1(), 
-+             buffer );
-+    }
-+  }
 +
 +private:
-+  FILE *m_logfile;
-+  int m_loglevel;
-+  bool m_enabled;
++    FILE *m_logfile;
++    int m_loglevel;
++    bool m_enabled;
 +};
 +
 +W100Control::Opcode W100Control::lOpcodes[] = {
-+  { "DRAWLINE",   W100Control::DRAWLINE,   true, 0, 0 },
-+  { "DRAWPOINT",  W100Control::DRAWPOINT,  true, 0, 0 },
-+  { "DRAWPOINTS", W100Control::DRAWPOINTS, true, 0, 0 },
-+  { "FILLRECT",   W100Control::FILLRECT,   true, 0, 0 },
-+  { "SCROLL",     W100Control::SCROLL,     true, 0, 0 },
-+  { "BITBLT",     W100Control::BITBLT,     true, 0, 0 },
-+  { "POLYLINE",   W100Control::POLYLINE,   true, 0, 0 },
-+  { ""      ,     W100Control::EOO,        false, 0, 0 }
++    { "DRAWLINE",   W100Control::DRAWLINE,   true, 0, 0 },
++    { "DRAWPOINT",  W100Control::DRAWPOINT,  true, 0, 0 },
++    { "DRAWPOINTS", W100Control::DRAWPOINTS, true, 0, 0 },
++    { "FILLRECT",   W100Control::FILLRECT,   true, 0, 0 },
++    { "SCROLL",     W100Control::SCROLL,     true, 0, 0 },
++    { "BITBLT",     W100Control::BITBLT,     true, 0, 0 },
++    { "POLYLINE",   W100Control::POLYLINE,   true, 0, 0 },
++    { ""      ,     W100Control::EOO,        false, 0, 0 }
 +};
 +
 +W100Control control;
 +
 +static int W100_ProcessAttach( void )
 +{
-+  return( AtiCore_ProcessAttach() );
++    return( AtiCore_ProcessAttach() );
 +}
 +
 +static int W100_ProcessDetach( void )
 +{
-+  return( AtiCore_ProcessDetach() );
++    return( AtiCore_ProcessDetach() );
 +}
 +
 +static int W100_AllocateSurface( uint16_t *handle, uint32_t *offset,
-+                               uint32_t size, uint32_t direction )
++                                 uint32_t size, uint32_t direction )
 +{
-+  int retcode = AtiCore_AllocateSurface( handle, offset, size, direction );
-+  return( retcode );
++    return( AtiCore_AllocateSurface( handle, offset, size, direction ) );
 +}
 +
 +static int W100_DestroySurface( uint16_t handle )
 +{
-+  int retcode = AtiCore_DestroySurface( handle );
-+  return( retcode );
++    return( AtiCore_DestroySurface( handle ) );
 +}
 +
 +static int W100_DrawPixel( int npoints, ATI_POINT *points )
 +{
-+  return( AtiCore_DrawPixel( npoints, points ) );
++    return( AtiCore_DrawPixel( npoints, points ) );
 +}
 +
 +static int W100_SetRopOperation( uint32_t rop )
 +{
-+  return( AtiCore_SetRopOperation( rop ) );
++    return( AtiCore_SetRopOperation( rop ) );
 +}
 +
 +static int W100_SetDstType( uint32_t dtype )
 +{
-+  return( AtiCore_SetDstType( dtype ) );
++    return( AtiCore_SetDstType( dtype ) );
 +}
 +
 +static int W100_SetSrcType( uint32_t stype )
 +{
-+  return( AtiCore_SetSrcType( stype ) );
++    return( AtiCore_SetSrcType( stype ) );
 +}
 +
 +static int W100_SetSrcClippingRect( ATI_CLIPRECT *cliprect )
 +{
-+  return( AtiCore_SetSrcClippingRect( cliprect ) );
++    return( AtiCore_SetSrcClippingRect( cliprect ) );
 +}
 +
-+
 +static int W100_SetDstClippingRect( ATI_CLIPRECT *cliprect )
 +{
-+  return( AtiCore_SetDstClippingRect( cliprect ) );
++    return( AtiCore_SetDstClippingRect( cliprect ) );
 +}
 +
 +static int W100_SetSrcPitchOffset( int pitch, int offset )
 +{
-+  return( AtiCore_SetSrcPitchOffset( pitch, offset ) );
++    return( AtiCore_SetSrcPitchOffset( pitch, offset ) );
 +}
 +
 +static int W100_SetDstPitchOffset( int pitch, int offset )
 +{
-+  return( AtiCore_SetDstPitchOffset( pitch, offset ) );
++    return( AtiCore_SetDstPitchOffset( pitch, offset ) );
 +}
 +
 +static int W100_BitBltFilpRotate( int flags, 
-+                                ATI_RECT *dstRect,
-+                                ATI_RECT *srcRect )
++                                  ATI_RECT *dstRect,
++                                  ATI_RECT *srcRect )
 +{
-+  return( AtiCore_BitBltFilpRotate( flags, dstRect, srcRect ) );
++    return( AtiCore_BitBltFilpRotate( flags, dstRect, srcRect ) );
 +}
 +
 +static int W100_StretchBlt( ATI_STRETCH *option,
-+                          ATI_POINT *point,
-+                          ATI_RECT *srcRect )
++                            ATI_POINT *point,
++                            ATI_RECT *srcRect )
 +{
-+  return( AtiCore_StretchBlt( option, point, srcRect ) );
++    return( AtiCore_StretchBlt( option, point, srcRect ) );
 +}
 +
 +static int W100_WaitComplete( int msec )
 +{
-+  return( AtiCore_WaitComplete( msec ) );
++    return( AtiCore_WaitComplete( msec ) );
 +}
 +
 +static int W100_AllocOverlay( uint16_t *handle ) 
 +{
-+  return( AtiCore_AllocOverlay( handle ) );
++    return( AtiCore_AllocOverlay( handle ) );
 +}
 +
 +static int W100_ReleaseOverlay( uint16_t handle )
 +{
-+  return( AtiCore_ReleaseOverlay( handle ) );
++    return( AtiCore_ReleaseOverlay( handle ) );
 +}
 +
 +static int W100_SetupOverlay( uint16_t handle, ATI_OVERLAYPROP *prop )
 +{
-+  return( AtiCore_SetupOverlay( handle, prop ) );
++    return( AtiCore_SetupOverlay( handle, prop ) );
 +}
 +
 +static int W100_SetupOverlayExtended( uint16_t handle, ATI_EXTENDEDOVERLAYPROP *prop )
 +{
-+  return( AtiCore_SetupOverlayExtended( handle, prop ) );
++    return( AtiCore_SetupOverlayExtended( handle, prop ) );
 +}
 +
 +static int W100_SetOverlayOnOff( uint16_t handle, int isShow )
 +{
-+  return( AtiCore_SetOverlayOnOff( handle, isShow ) );
++    return( AtiCore_SetOverlayOnOff( handle, isShow ) );
 +}
 +
 +static int W100_SetOverlayPos( uint16_t handle, uint16_t x, uint16_t y )
 +{
-+  return( AtiCore_SetOverlayPos( handle, x, y ) );
++    return( AtiCore_SetOverlayPos( handle, x, y ) );
 +}
 +
 +static int W100_SetupMemoryTransfer( uint32_t offset, uint32_t *regdata )
 +{
-+  return( AtiCore_SetupMemoryTransfer( offset, regdata ) );
++    return( AtiCore_SetupMemoryTransfer( offset, regdata ) );
 +}
 +
 +static int W100_TerminateMemoryTransfer( void )
 +{
-+  return( AtiCore_TerminateMemoryTransfer() );
++    return( AtiCore_TerminateMemoryTransfer() );
 +}
 +
 +static int W100_GetFrontBufferPitchOffset( uint32_t *pitch, uint32_t *offset )
 +{
-+  return( AtiCore_GetFrontBufferPitchOffset( pitch, offset ) );
++    return( AtiCore_GetFrontBufferPitchOffset( pitch, offset ) );
 +}
 +
 +static int W100_SetDisplayBrightness( int bri )
 +{
-+  return( AtiCore_SetDisplayBrightness( bri ) );
++    return( AtiCore_SetDisplayBrightness( bri ) );
 +}
 +
 +static int W100_GetAvailableVideoMem( uint32_t *internal, uint32_t *external )
 +{
-+  return( GetAvailableVideoMem( internal, external ) );
++    return( GetAvailableVideoMem( internal, external ) );
 +}
 +
 +static int W100_SetupGraphicWindow( ATI_GRAPHICWINDOW *win )
 +{
-+  return( AtiCore_SetupGraphicWindow( ( void * ) win ) );
++    return( AtiCore_SetupGraphicWindow( ( void * ) win ) );
 +}
 +
 +static int W100_ProcessAttachSpecialMode( int mode )
 +{
-+  return( AtiCore_ProcessAttachSpecialMode( mode ) );
++    return( AtiCore_ProcessAttachSpecialMode( mode ) );
 +}
 +
 +static int W100_SetGraphicWindowPos( int x, int y )
 +{
-+  return( AtiCore_SetGraphicWindowPos( x, y ) );
++    return( AtiCore_SetGraphicWindowPos( x, y ) );
 +}
 +
 +static int W100_SetFrontBuffer( int offset, int a, int b )
 +{
-+  return( AtiCore_SetFrontBuffer( offset, a, b ) );
++    return( AtiCore_SetFrontBuffer( offset, a, b ) );
 +}
 +
 +static int W100_SetGraphicWindowOnOff( int val )
 +{
-+  return( AtiCore_SetGraphicWindowOnOff( val ) );
++    return( AtiCore_SetGraphicWindowOnOff( val ) );
 +}
 +
 +static unsigned long ccolor( unsigned int rgb )
 +{
-+  unsigned char r = ( rgb & 0xff0000 ) >> 19;
-+  unsigned char g = ( rgb & 0xff00 ) >> 10;
-+  unsigned char b = ( rgb & 0xff ) >> 3;
-+  return ( ( ( ( unsigned short )0x1f & r ) << 11 ) |
-+         ( ( ( unsigned short )0x3f & g ) << 5 ) |
-+         ( ( ( unsigned short )0x1f & b ) )  ); 
++    unsigned char r = ( rgb & 0xff0000 ) >> 19;
++    unsigned char g = ( rgb & 0xff00 ) >> 10;
++    unsigned char b = ( rgb & 0xff ) >> 3;
++    return ( ( ( ( unsigned short )0x1f & r ) << 11 ) |
++             ( ( ( unsigned short )0x3f & g ) << 5 ) |
++             ( ( ( unsigned short )0x1f & b ) )  ); 
 +}
 +
 +static int W100_SetFrgColour( int val )
 +{
-+  return( AtiCore_SetFrgColour( ccolor( val ) ) );
++    return( AtiCore_SetFrgColour( ccolor( val ) ) );
 +}
 +
 +static int W100_BrushType( int type, unsigned int pattern )
 +{
-+  return( AtiCore_BrushType( type, &pattern ) );
++    return( AtiCore_BrushType( type, &pattern ) );
 +}
 +
 +static int W100_PaintRect( int flags, ATI_RECT *rect )
 +{
-+  return( AtiCore_PaintRect( flags, rect ) );
++    return( AtiCore_PaintRect( flags, rect ) );
 +}
 +
 +static int W100_Polyline( int npoints, ATI_POINT *points )
 +{
-+  return( AtiCore_Polyline( npoints, points ) );
++    return( AtiCore_Polyline( npoints, points ) );
 +}
 +
 +static int W100_GetPitchOffsetProperty( void *pitch, void *offset )
 +{
-+  return( AtiCore_GetPitchOffsetProperty( pitch, offset ) );
++    return( AtiCore_GetPitchOffsetProperty( pitch, offset ) );
 +}
 +
 +static int W100_CursorOnOff( int a, int b )
 +{
-+  return( AtiCore_CursorOnOff( a, b ) );
++    return( AtiCore_CursorOnOff( a, b ) );
 +}
 +
 +static int W100_BitBlt( int flags, ATI_RECT *dst, ATI_RECT *src )
 +{
-+  return( AtiCore_BitBlt( flags, dst, src ) );
++    return( AtiCore_BitBlt( flags, dst, src ) );
 +}
 +
 +static int W100_WakeUpCall( void )
 +{
-+  return( AtiCore_WakeUpCall() );
++    return( AtiCore_WakeUpCall() );
 +}
 +
++class QW100Screen;
++static QW100Screen *qt_w100_screen = 0;
++
++class QW100Screen : public QLinuxFbScreen {
++public:
++    class HWSurface {
++    public:
++        HWSurface( void ):
++            m_handle( 0 ),
++            m_offset( 0 ),
++            m_addr( 0 ),
++            m_size( 0 ),
++            m_internal( false ),
++            m_clientid( -1 ) {};
++        HWSurface( unsigned short handle,
++                   uint32_t sOffset,
++                   unsigned char *localAddr, 
++                   int amount,
++                   bool internal,
++                   int clientid ):
++            m_handle( handle ),
++            m_offset( sOffset ),
++            m_addr( localAddr ),
++            m_size( amount ),
++            m_internal( internal ),
++            m_clientid( clientid ) {};
++        HWSurface( uint32_t sOffset, 
++                   unsigned char *localAddr,
++                   bool internal,
++                   int amount ):
++            m_handle( 0 ),
++            m_offset( sOffset ),
++            m_addr( localAddr ),
++            m_size( amount ),
++            m_internal( internal ),
++            m_clientid( -1 ) {};
++        bool operator!=( HWSurface &other ) {
++            return( m_offset == other.getSOffset() );
++        };
++        HWSurface &operator=( const HWSurface &c ) {
++            m_handle = c.getHandle();
++            m_offset = c.getSOffset();
++            m_addr = c.getAddr();
++            m_size = c.getSize();
++            m_clientid= c.getCId();
++            m_internal = c.internal();
++            return( *this );
++        };
++        unsigned short getHandle( void ) const { return m_handle; };
++        uint32_t getSOffset( void ) const { return m_offset; };
++        unsigned char *getAddr( void ) const { return m_addr; };
++        unsigned int getSize( void ) const { return m_size; };
++        int getCId( void ) const { return m_clientid; };
++        bool internal( void ) const { return m_internal; };
++
++    private:
++        unsigned short m_handle;
++        uint32_t m_offset;
++        unsigned char *m_addr;
++        int m_size;
++        bool m_internal;
++        int m_clientid;
++    };
++    
++    QW100Screen( int display_id );
++    virtual ~QW100Screen();
++    virtual bool connect( const QString &spec );
++    virtual void disconnect( void );
++    virtual bool initDevice();
++    virtual void shutdownDevice();
++    virtual void restore();
++    virtual bool useOffscreen() { return true; }
++    virtual QGfx * createGfx( unsigned char *, int, int, int, int);
++    virtual uchar *cache( int amount, int optim );
++    virtual void uncache( uchar *c );
++    virtual bool onCard( unsigned char *p ) const;
++    virtual bool onCard( unsigned char *p, ulong& offset ) const;
++    QMap< uchar*, HWSurface > *getPSurfaceMap( void ) const;
++    void clearCache( int clientId );
++
++    // Rotation stuff
++    enum Transformation { None, Rot90, Rot180, Rot270 };
++    void setTransformation( Transformation t );
++    Transformation transformation() const;
++    virtual bool isTransformed() const { return trans != None; };
++    virtual QSize mapToDevice( const QSize & ) const;
++    virtual QSize mapFromDevice( const QSize & ) const;
++    virtual QPoint mapToDevice( const QPoint &, const QSize & ) const;
++    virtual QPoint mapFromDevice( const QPoint &, const QSize & ) const;
++    virtual QRect mapToDevice( const QRect &, const QSize & ) const;
++    virtual QRect mapFromDevice( const QRect &, const QSize & ) const;
++    virtual QImage mapToDevice( const QImage & ) const;
++    virtual QImage mapFromDevice( const QImage & ) const;
++    virtual QRegion mapToDevice( const QRegion &, const QSize & ) const;
++    virtual QRegion mapFromDevice( const QRegion &, const QSize & ) const;
++    virtual int transformOrientation() const;
++
++protected:
++    bool w100init();
++    void w100shutdown();
++    Transformation trans;
++    static Transformation getTransSpec( const QString &dspec );
++    static void clearCache( QScreen *instance, int clientId );
++    QMap< uchar*, HWSurface > surfaceMap;
++    int vramoffset;
++    virtual int pixmapLinestepAlignment() { return 128; }
++};
 +
 +template <const int depth, const int type>
 +class QGfxW100 : public QGfxRaster<depth,type> {
 +
 +public:
-+  QGfxW100( unsigned char *b, int w, int h );
-+  virtual void drawLine( int, int, int, int);
-+  virtual void fillRect( int, int, int, int);
-+  virtual void blt( int, int, int, int, int, int );
-+  virtual void sync();
-+  virtual void setOffset( int x, int y );
-+  virtual void setPen( const QPen & p );
-+  
-+  virtual void drawPolyline( const QPointArray &, int, int );
-+  virtual void drawPolygon( const QPointArray &, bool, int, int );
-+  virtual void drawPoint( int, int );
-+  virtual void drawPoints( const QPointArray &, int, int );
-+  virtual void scroll( int, int, int, int, int, int );
++    QGfxW100( unsigned char *b, int w, int h );
++    virtual void drawLine( int, int, int, int);
++    virtual void fillRect( int, int, int, int);
++    virtual void blt( int, int, int, int, int, int );
++    virtual void sync();
++    virtual void setOffset( int x, int y );
++    virtual void setPen( const QPen & p );
 +  
++    virtual void drawPolyline( const QPointArray &, int, int );
++    virtual void drawPolygon( const QPointArray &, bool, int, int );
++    virtual void drawPoint( int, int );
++    virtual void drawPoints( const QPointArray &, int, int );
++    virtual void scroll( int, int, int, int, int, int );
++    virtual void tiledBlt( int rx, int ry, int w, int h );
++
++    inline int tx( int x, int y ) {
++        switch ( qt_w100_screen->transformation() ) {
++        case QW100Screen::Rot90:
++            return y - this->xoffs + this->yoffs;
++        case QW100Screen::Rot180:
++            return ( this->width - x - 1) - this->xoffs - this->xoffs;
++        case QW100Screen::Rot270:
++            return ( this->height - y - 1) - this->xoffs - this->yoffs;
++        default:
++            return x;
++        }
++    }
++    inline int ty( int x, int y ) {
++        switch ( qt_w100_screen->transformation() ) {
++        case QW100Screen::Rot90:
++            return (this->width - x - 1) - this->yoffs - this->xoffs;
++        case QW100Screen::Rot180:
++            return (this->height - y - 1) - this->yoffs - this->yoffs;
++        case QW100Screen::Rot270:
++            return x - this->yoffs + this->xoffs;
++        default:
++            return y;
++        }
++    }
 +
-+private:
-+  bool checkDest( bool setsrc = false );
-+  bool checkSourceDest();
++protected:
++    bool checkDest( bool setsrc = false );
++    bool checkSourceDest();
++    virtual void setSourceWidgetOffset( int x, int y );
++    void processSpans( int n, QPoint* point, int* width );
++    bool inDraw;
++
++    virtual void dDrawLine( int, int, int, int);
++    virtual void dFillRect( int, int, int, int);
++    virtual void dBlt( int, int, int, int, int, int );
++    void dDrawPolyline( const QPointArray &, int, int );
++    void dDrawPolygon( const QPointArray &, bool, int, int );
++    void dDrawPoint( int, int );
++    void dDrawPoints( const QPointArray &, int, int );
++    void dScroll( int, int, int, int, int, int );
++    void dTiledBlt( int rx, int ry, int w, int h );
 +};
 +
 +template<const int depth,const int type>
 +QGfxW100<depth,type>::QGfxW100( unsigned char * b, int w, int h )
-+  : QGfxRaster<depth,type>(b, w, h)
++    : QGfxRaster<depth,type>(b, w, h),
++      inDraw( false )
 +{
 +}
 +
-+
 +template<const int depth,const int type>
 +inline void QGfxW100<depth,type>::setOffset( int x, int y )
 +{
-+  QGfxRaster<depth,type>::setOffset( x, y );
++    QGfxRaster<depth,type>::setOffset( x, y );
 +}
 +
 +static QString penStyleStr( const QPen &pen ) 
 +{
-+  QString res;
-+  switch( pen.style() ) {
-+  case Qt::NoPen:
-+    res = "NoPen";
-+    break;
-+  case Qt::SolidLine:
-+    res = "SolidLine";
-+    break;
-+  case Qt::DashLine:
-+    res = "DashLine";
-+    break;
-+  case Qt::DotLine:
-+    res = "DotLine";
-+    break;
-+  case Qt::DashDotLine:
-+    res = "DashDotLine";
-+    break;
-+  case Qt::DashDotDotLine:
-+    res = "DashDotDotLine";
-+    break;
-+  default:
-+    res = "Unknown";
-+  }
-+  return res;
++    QString res;
++    switch( pen.style() ) {
++    case Qt::NoPen:
++        res = "NoPen";
++        break;
++    case Qt::SolidLine:
++        res = "SolidLine";
++        break;
++    case Qt::DashLine:
++        res = "DashLine";
++        break;
++    case Qt::DotLine:
++        res = "DotLine";
++        break;
++    case Qt::DashDotLine:
++        res = "DashDotLine";
++        break;
++    case Qt::DashDotDotLine:
++        res = "DashDotDotLine";
++        break;
++    default:
++        res = "Unknown";
++    }
++    return res;
 +}
 +
 +template<const int depth, const int type>
 +inline void QGfxW100<depth,type>::setPen( const QPen &p )
 +{
-+  QGfxRaster<depth,type>::setPen( p );
++    QGfxRaster<depth,type>::setPen( p );
 +}
 +
 +template<const int depth,const int type>
 +inline bool QGfxW100<depth,type>::checkSourceDest()
 +{
-+  if ( !checkDest() ) {
-+    return FALSE;
-+  }
++    if ( !checkDest() ) {
++        return FALSE;
++    }
 +
-+  int sourcepixelpitch;
-+  ulong src_buffer_offset;
-+  if ( this->srctype == this->SourcePen ) {
-+    src_buffer_offset = -1;
-+    return FALSE;
-+  } else {
-+    if ( !qt_screen->onCard( this->srcbits, src_buffer_offset ) ) {
-+      return FALSE;
++    int sourcepixelpitch;
++    ulong src_buffer_offset;
++    if ( this->srctype == this->SourcePen ) {
++        src_buffer_offset = -1;
++        return FALSE;
++    } else {
++        if ( !qt_screen->onCard( this->srcbits, src_buffer_offset ) ) {
++            return FALSE;
++        }
++        sourcepixelpitch = ( this->srclinestep * 8 ) / this->srcdepth;
++        W100_SetSrcPitchOffset( sourcepixelpitch,
++                                src_buffer_offset );
 +    }
-+    sourcepixelpitch = ( this->srclinestep * 8 ) / this->srcdepth;
-+    W100_SetSrcPitchOffset( sourcepixelpitch,
-+                          src_buffer_offset );
-+  }
-+  return TRUE;
++    return TRUE;
 +}
 +
 +template< const int depth, const int type>
 +inline bool QGfxW100<depth, type>::checkDest( bool setsrc )
 +{
-+  //Main framebuffer should be registered as a hardware surface
-+  ulong buffer_offset;
-+  if ( !qt_screen->onCard( this->buffer, buffer_offset ) ) {
-+    return FALSE;
-+  }
-+  int pixelstep = ( this->linestep() * 8 ) / depth;
-+  W100_SetDstPitchOffset( pixelstep, buffer_offset );
-+  if ( setsrc ) {
-+    W100_SetSrcPitchOffset( pixelstep, buffer_offset );
-+  }
-+  return TRUE;
++    //Main framebuffer should be registered as a hardware surface
++    ulong buffer_offset;
++    if ( !qt_screen->onCard( this->buffer, buffer_offset ) ) {
++        return FALSE;
++    }
++    int pixelstep = ( this->linestep() * 8 ) / depth;
++    W100_SetDstPitchOffset( pixelstep, buffer_offset );
++    if ( setsrc ) {
++        W100_SetSrcPitchOffset( pixelstep, buffer_offset );
++    }
++    return TRUE;
 +}
 +
 +template<const int depth,const int type>
 +void QGfxW100<depth,type>::drawLine( int x1, int y1, int x2, int y2 )
 +{
-+  // No point going any further if the window isn't visible
-+  if( this->ncliprect < 1 ) {
-+    return;
-+  }
-+
-+  if ( !control.accelerated( W100Control::DRAWLINE ) ) {
-+    control.addMiss( W100Control::DRAWLINE );
-+    QGfxRaster<depth,type>::drawLine( x1, y1, x2, y2 );
-+    return;
-+  }
-+
-+  // Only handle 'normal' lines
-+  if ( ( this->cpen.style() != this->SolidLine ) || 
-+       ( this->myrop != this->CopyROP ) ||
-+       ( this->cpen.width() > 1 ) ||
-+       ( this->dashedLines ) ) {
-+    control.addMiss( W100Control::DRAWLINE );
-+    QGfxRaster<depth,type>::drawLine(x1,y1,x2,y2);
-+    return;
-+  }
-+
-+  // Stop anyone else trying to access optype/lastop/the graphics engine
-+  // to avoid synchronization problems with other processes
-+  QWSDisplay::grab( TRUE );
-+  if ( !checkDest() ) {
-+    QWSDisplay::ungrab();
-+    control.addMiss( W100Control::DRAWLINE );
-+    QGfxRaster<depth,type>::drawLine( x1, y1, x2, y2);
-+    return;
-+  }
-+
-+  // Note that the last operation used the 2d engine
-+  ( *optype ) = 1;
-+
-+
-+
-+  // Add the offset of the gfx - used to make the origin the right
-+  // place for windows
-+  x1 = x1 + this->xoffs;
-+  y1 = y1 + this->yoffs;
-+  x2 = x2 + this->xoffs;
-+  y2 = y2 + this->yoffs;
-+
-+  // Only cope with lines going from left to right
-+  // - swap them round if this isn't TRUE
-+  if ( x1 > x2 ) {
-+    int x3 = x2;
-+    int y3 = y2;
-+    x2 = x1;
-+    y2 = y1;
-+    x1 = x3;
-+    y1 = y3;
-+  }
-+
-+  GFX_START( QRect( x1, 
-+                  y1 < y2 ? y1 : y2, 
-+                  ( x2 - x1  + 1 ), 
-+                  QABS( y2 - y1 ) + 1 ) );
-+
-+  // The clip region is defined as a series of rectangles
-+  // We repeatedly set up the hardware clip rectangle to one of
-+  // these rectangles and re-draw the line - an alternative approach
-+  // would be to clip to the rectangle in software
++    if ( inDraw ) {
++        dDrawLine( x1, y1, x2, y2 );
++    } else {
++        inDraw = true;
++        dDrawLine( tx(x1,y1), ty(x1,y1),
++                   tx(x2,y2), ty(x2,y2) );
++        inDraw = false;
++    }
++}
++
++template<const int depth,const int type>
++void QGfxW100<depth,type>::dDrawLine( int x1, int y1, int x2, int y2 )
++{
++    // No point going any further if the window isn't visible
++    if( this->ncliprect < 1 ) {
++        return;
++    }
++
++    if ( !control.accelerated( W100Control::DRAWLINE ) ) {
++        control.addMiss( W100Control::DRAWLINE );
++        QGfxRaster<depth,type>::drawLine( x1, y1, x2, y2 );
++        return;
++    }
++
++    // Only handle 'normal' lines
++    if ( ( this->cpen.style() != this->SolidLine ) || 
++         ( this->myrop != this->CopyROP ) ||
++         ( this->cpen.width() > 1 ) ||
++         ( this->dashedLines ) ) {
++        control.addMiss( W100Control::DRAWLINE );
++        QGfxRaster<depth,type>::drawLine( x1, y1, x2, y2);
++        return;
++    }
++
++    // Stop anyone else trying to access optype/lastop/the graphics engine
++    // to avoid synchronization problems with other processes
++    QWSDisplay::grab( true );
++    if ( !checkDest() ) {
++        QWSDisplay::ungrab();
++        control.addMiss( W100Control::DRAWLINE );
++        QGfxRaster<depth,type>::drawLine( x1, y1, x2, y2 );
++        return;
++    }
++
++    // Note that the last operation used the 2d engine
++    ( *optype ) = 1;
++
++
++
++    // Add the offset of the gfx - used to make the origin the right
++    // place for windows
++    x1 += this->xoffs;
++    y1 += this->yoffs;
++    x2 += this->xoffs;
++    y2 += this->yoffs;
++
++    // Only cope with lines going from left to right
++    // - swap them round if this isn't TRUE
++    if ( x1 > x2 ) {
++        int x3 = x2;
++        int y3 = y2;
++        x2 = x1;
++        y2 = y1;
++        x1 = x3;
++        y1 = y3;
++    }
++
++    GFX_START( QRect( x1, 
++                      y1 < y2 ? y1 : y2, 
++                      ( x2 - x1  + 1 ), 
++                      QABS( y2 - y1 ) + 1 ) );
++
++    // The clip region is defined as a series of rectangles
++    // We repeatedly set up the hardware clip rectangle to one of
++    // these rectangles and re-draw the line - an alternative approach
++    // would be to clip to the rectangle in software
 +    
 +
 +
-+  /*
-+   * Just a dirty hack. Comment it out for now
-+   if ( this->dashedLines ) {
-+   W100_BrushType( 4, 0xaaaaaaaa );
-+   } else {
-+   W100_BrushType( 6, 0 );
-+   }
-+   switch( this->cpen.style() ) {
-+   case Qt::NoPen:
-+   //W100DEBUG( "Using pen style NoPen" );
-+   break;
-+   case Qt::SolidLine:
-+   //W100DEBUG( "Using pen style SolidLine" );
-+   break;
-+   case Qt::DashLine:
-+   //W100DEBUG( "Using pen style DashLine" );
-+   break;
-+   case Qt::DotLine:
-+   //W100DEBUG( "Using pen style DotLine" );
-+   break;
-+   case Qt::DashDotLine:
-+   //W100DEBUG( "Using pen style DashDotLine" );
-+   break;
-+   case Qt::DashDotDotLine:
-+   //W100DEBUG( "Using pen style DashDotDotLine" );
-+   break;
-+   default:
-+   //W100DEBUG( "Using unknown type of pen" );
-+   }
-+  */
-+
-+  //if ( control.lastOp() != W100Control::DRAWLINE &&
-+  //control.lastOp() != W100Control::POLYLINE ) {
-+  W100_SetDstType( DSTTYPE_16BPP_1555 );
-+  W100_SetSrcType( SRCTYPE_EQU_DST );
-+  W100_SetRopOperation( ROP3_PATCOPY );
-+  W100_BrushType( 6, 0 );
-+  //}
-+  W100_SetFrgColour( this->cpen.color().rgb() );
-+  control.addHit( W100Control::DRAWLINE );
-+
-+  //The imageon seems not to write on the edge of the clip
-+  //for the polyline op. 
-+  //We are using a three points array repeating the last point
-+  //to get the last single point painted.
-+  ATI_POINT points[3];
-+  points[0].XCoord = x1;
-+  points[0].YCoord = y1;
-+  points[1].XCoord = x2;
-+  points[1].YCoord = y2;
-+  points[2].XCoord = x2;
-+  points[2].YCoord = y2;
-+  for ( int loopc = 0 ; loopc < this->ncliprect; loopc++ ) {
-+    ATI_CLIPRECT clip;
-+    clip.X_Top_Left = this->cliprect[loopc].x();
-+    clip.Y_Top_Left = this->cliprect[loopc].y();
-+    clip.X_Bottom_Right = this->cliprect[loopc].right() + 1;
-+    clip.Y_Bottom_Right = this->cliprect[loopc].bottom() + 1;
-+    W100_SetDstClippingRect( &clip );
-+
-+    W100_Polyline( 3, points );
-+  }
-+
-+  // Software mouse cursor stuff
-+  GFX_END;
-+
-+  // Release display again - not doing so will cause Qt/Embedded applications
-+  // to deadlock
-+  QWSDisplay::ungrab();
++    /*
++     * Just a dirty hack. Comment it out for now
++     if ( this->dashedLines ) {
++     W100_BrushType( 4, 0xaaaaaaaa );
++     } else {
++     W100_BrushType( 6, 0 );
++     }
++     switch( this->cpen.style() ) {
++     case Qt::NoPen:
++     //W100DEBUG( "Using pen style NoPen" );
++     break;
++     case Qt::SolidLine:
++     //W100DEBUG( "Using pen style SolidLine" );
++     break;
++     case Qt::DashLine:
++     //W100DEBUG( "Using pen style DashLine" );
++     break;
++     case Qt::DotLine:
++     //W100DEBUG( "Using pen style DotLine" );
++     break;
++     case Qt::DashDotLine:
++     //W100DEBUG( "Using pen style DashDotLine" );
++     break;
++     case Qt::DashDotDotLine:
++     //W100DEBUG( "Using pen style DashDotDotLine" );
++     break;
++     default:
++     //W100DEBUG( "Using unknown type of pen" );
++     }
++    */
++
++    //if ( control.lastOp() != W100Control::DRAWLINE &&
++    //control.lastOp() != W100Control::POLYLINE ) {
++    W100_SetDstType( DSTTYPE_16BPP_1555 );
++    W100_SetSrcType( SRCTYPE_EQU_DST );
++    W100_SetRopOperation( ROP3_PATCOPY );
++    W100_BrushType( 6, 0 );
++    //}
++    W100_SetFrgColour( this->cpen.color().rgb() );
++    control.addHit( W100Control::DRAWLINE );
++
++    //The imageon seems not to write on the edge of the clip
++    //for the polyline op. 
++    //We are using a three points array repeating the last point
++    //to get the last single point painted.
++    ATI_POINT points[3];
++    points[0].XCoord = x1;
++    points[0].YCoord = y1;
++    points[1].XCoord = x2;
++    points[1].YCoord = y2;
++    points[2].XCoord = x2;
++    points[2].YCoord = y2;
++    for ( int loopc = 0 ; loopc < this->ncliprect; loopc++ ) {
++        ATI_CLIPRECT clip;
++        clip.X_Top_Left = this->cliprect[loopc].x();
++        clip.Y_Top_Left = this->cliprect[loopc].y();
++        clip.X_Bottom_Right = this->cliprect[loopc].right() + 1;
++        clip.Y_Bottom_Right = this->cliprect[loopc].bottom() + 1;
++        W100_SetDstClippingRect( &clip );
++
++        W100_Polyline( 3, points );
++    }
 +
-+}
++    // Software mouse cursor stuff
++    GFX_END;
 +
++    // Release display again - not doing so will cause Qt/Embedded applications
++    // to deadlock
++    QWSDisplay::ungrab();
++}
 +
 +template< const int depth, const int type >
 +void QGfxW100< depth, type>::drawPolyline( const QPointArray &a, 
-+                                         int index, 
-+                                         int npoints )
++                                           int index, 
++                                           int npoints )
 +{
++    if ( inDraw ) {
++        dDrawPolyline( a, index, npoints );
++    } else {
++        inDraw = true;
++        QPointArray na( npoints );
++    
++        for ( int i = 0; i < npoints; i++ ) {
++            int x, y;
++            a.point( i+index, &x, &y );
++            na.setPoint( i, tx(x,y), ty(x,y) );
++        }
++    
++        dDrawPolyline( na, 0, npoints );
++        inDraw = false;
++    }
++}
 +
-+  if ( ( this->ncliprect < 1 ) || ( npoints < 1 ) ) {
-+    return;
-+  }
++template< const int depth, const int type >
++void QGfxW100< depth, type>::dDrawPolyline( const QPointArray &a, 
++                                            int index, 
++                                            int npoints )
++{
++    if ( ( this->ncliprect < 1 ) || ( npoints < 1 ) ) {
++        return;
++    }
 +
-+  if ( !control.accelerated( W100Control::POLYLINE ) ) {
-+    control.addMiss( W100Control::POLYLINE );
-+    QGfxRaster<depth,type>::drawPolyline( a, index, npoints );
-+    return;
-+  }
++    if ( !control.accelerated( W100Control::POLYLINE ) ) {
++        control.addMiss( W100Control::POLYLINE );
++        QGfxRaster<depth,type>::drawPolyline( a, index, npoints );
++        return;
++    }
 +
-+  if ( this->cpen.style() != this->SolidLine ||
-+       this->myrop != this->CopyROP ) {
-+    control.addMiss( W100Control::POLYLINE );
-+    QGfxRaster<depth,type>::drawPolyline( a, index, npoints );
-+    return;
-+  }
++    if ( this->cpen.style() != this->SolidLine ||
++         this->myrop != this->CopyROP ) {
++        control.addMiss( W100Control::POLYLINE );
++        QGfxRaster<depth,type>::drawPolyline( a, index, npoints );
++        return;
++    }
 +
-+  QWSDisplay::grab( TRUE );
-+  if ( !checkDest() ) {
-+    QWSDisplay::ungrab();
-+    control.addMiss( W100Control::POLYLINE );
-+    QGfxRaster<depth,type>::drawPolyline( a, index, npoints );
-+    return;
-+  }
++    QWSDisplay::grab( TRUE );
++    if ( !checkDest() ) {
++        QWSDisplay::ungrab();
++        control.addMiss( W100Control::POLYLINE );
++        QGfxRaster<depth,type>::drawPolyline( a, index, npoints );
++        return;
++    }
 +
-+  ( *optype ) = 1;
++    ( *optype ) = 1;
 +
-+  //if ( control.lastOp() != W100Control::POLYLINE &&
-+  //control.lastOp() != W100Control::DRAWLINE ) {
++    //if ( control.lastOp() != W100Control::POLYLINE &&
++    //control.lastOp() != W100Control::DRAWLINE ) {
 +
-+  W100_SetDstType( DSTTYPE_16BPP_1555 );
-+  W100_SetSrcType( SRCTYPE_EQU_DST );
-+  W100_SetRopOperation( ROP3_PATCOPY );
-+  W100_BrushType( 6, 0 );
++    W100_SetDstType( DSTTYPE_16BPP_1555 );
++    W100_SetSrcType( SRCTYPE_EQU_DST );
++    W100_SetRopOperation( ROP3_PATCOPY );
++    W100_BrushType( 6, 0 );
 +  
-+  //}
++    //}
 +
-+  W100_SetFrgColour( this->cpen.color().rgb() );
++    W100_SetFrgColour( this->cpen.color().rgb() );
 +
-+  control.addHit( W100Control::POLYLINE );
++    control.addHit( W100Control::POLYLINE );
 +
-+  ATI_POINT *points = new ATI_POINT[ npoints + 1 ];
++    ATI_POINT *points = new ATI_POINT[ npoints + 1 ];
 +
-+  for ( int i = 0; i < npoints; i++ ) {
-+    points[i].XCoord = a[ i + index ].x() + this->xoffs;
-+    points[i].YCoord = a[ i + index ].y() + this->yoffs;
-+  }
-+  //Hack to get the last point of the last line painted
-+  points[ npoints ] = points[ npoints - 1 ];
++    for ( int i = 0; i < npoints; i++ ) {
++        points[i].XCoord = a[i+index].x() + this->xoffs;
++        points[i].YCoord = a[i+index].y() + this->yoffs;
++    }
++    //Hack to get the last point of the last line painted
++    points[ npoints ] = points[ npoints - 1 ];
 +
 +
-+  GFX_START( clipbounds );
-+  W100_SetFrgColour( this->cpen.color().rgb() );
-+  W100_SetRopOperation( ROP3_PATCOPY );
-+  for ( int loopc = 0; loopc < this->ncliprect; loopc++ ) {
-+    ATI_CLIPRECT clip;
-+    clip.X_Top_Left = this->cliprect[loopc].x();
-+    clip.Y_Top_Left = this->cliprect[loopc].y();
-+    clip.X_Bottom_Right = this->cliprect[loopc].right() + 1;
-+    clip.Y_Bottom_Right = this->cliprect[loopc].bottom() + 1;
-+    W100_SetDstClippingRect( &clip );
-+    W100_Polyline( npoints + 1, points );
-+  }
-+  GFX_END;
++    GFX_START( clipbounds );
++    W100_SetFrgColour( this->cpen.color().rgb() );
++    W100_SetRopOperation( ROP3_PATCOPY );
++    for ( int loopc = 0; loopc < this->ncliprect; loopc++ ) {
++        ATI_CLIPRECT clip;
++        clip.X_Top_Left = this->cliprect[loopc].x();
++        clip.Y_Top_Left = this->cliprect[loopc].y();
++        clip.X_Bottom_Right = this->cliprect[loopc].right() + 1;
++        clip.Y_Bottom_Right = this->cliprect[loopc].bottom() + 1;
++        W100_SetDstClippingRect( &clip );
++        W100_Polyline( npoints + 1, points );
++    }
++    GFX_END;
 +
-+  delete [] points;
++    delete [] points;
 +    
-+  QWSDisplay::ungrab();
++    QWSDisplay::ungrab();
 +}
 +
++
 +template< const int depth, const int type >
-+void QGfxW100< depth, type>::drawPolygon( const QPointArray &a, bool b, int c, int d )
++void QGfxW100< depth, type>::drawPolygon( const QPointArray &a, 
++                                          bool w, int index, 
++                                          int npoints )
 +{
-+  QGfxRaster<depth,type>::drawPolygon( a, b, c, d );
++    if ( inDraw  || this->cpen.style()==this->NoPen || this->patternedbrush ) {
++        //slowpath
++        dDrawPolygon( a, w, index, npoints );
++    } else {
++        inDraw = TRUE;
++        QPointArray na( npoints );
++
++        for ( int i = 0; i < npoints; i++ ) {
++            int x,y;
++            a.point( i+index, &x, &y );
++            na.setPoint( i, tx(x,y), ty(x,y) );
++        }
++        dDrawPolygon( na, w, 0, npoints );
++        inDraw = FALSE;
++    }
 +}
 +
 +template< const int depth, const int type >
-+void QGfxW100< depth, type>::drawPoint( int a, int b )
++void QGfxW100< depth, type>::dDrawPolygon( const QPointArray &a, bool w, int index, int npoints )
 +{
++    QGfxRaster<depth,type>::drawPolygon( a, w, index, npoints );
++}
 +
-+  if ( this->ncliprect < 1 ) {
-+    //W100DEBUG( "ncliprect=%d", this->ncliprect );
-+    return;
-+  }
++template< const int depth, const int type >
++void QGfxW100< depth, type>::drawPoint( int x, int y )
++{
++    dDrawPoint( tx( x, y ), ty( x, y ) );
++}
 +
-+  if ( !control.accelerated( W100Control::DRAWPOINT) ) {
-+    control.addMiss( W100Control::DRAWPOINT );
-+    QGfxRaster<depth,type>::drawPoint( a, b );
-+    return;
-+  }
++template< const int depth, const int type >
++void QGfxW100< depth, type>::dDrawPoint( int x, int y )
++{
 +
-+  if ( this->cpen.style() != this->SolidLine ||
-+       this->myrop != this->CopyROP ) {
-+    control.addMiss( W100Control::DRAWPOINT );
-+    QGfxRaster<depth,type>::drawPoint( a, b );
-+    return;
-+  }
++    if ( this->ncliprect < 1 ) {
++        //W100DEBUG( "ncliprect=%d", this->ncliprect );
++        return;
++    }
 +
-+  QWSDisplay::grab( TRUE );
-+  if ( !checkDest() ) {
-+    QWSDisplay::ungrab();
-+    control.addMiss( W100Control::DRAWPOINT );
-+    QGfxRaster<depth,type>::drawPoint( a, b );
-+    return;
-+  }
++    if ( !control.accelerated( W100Control::DRAWPOINT) ) {
++        control.addMiss( W100Control::DRAWPOINT );
++        QGfxRaster<depth,type>::drawPoint( x, y );
++        return;
++    }
 +
-+  control.addHit( W100Control::DRAWPOINT );
-+  ( *optype ) = 1;
++    if ( this->cpen.style() != this->SolidLine ||
++         this->myrop != this->CopyROP ) {
++        control.addMiss( W100Control::DRAWPOINT );
++        QGfxRaster<depth,type>::drawPoint( x, y );
++        return;
++    }
++
++    QWSDisplay::grab( TRUE );
++    if ( !checkDest() ) {
++        QWSDisplay::ungrab();
++        control.addMiss( W100Control::DRAWPOINT );
++        QGfxRaster<depth,type>::drawPoint( x, y );
++        return;
++    }
++
++    control.addHit( W100Control::DRAWPOINT );
++    ( *optype ) = 1;
 +  
-+  ATI_POINT point;
-+  point.XCoord = a + this->xoffs;
-+  point.YCoord = b + this->yoffs;
-+
-+  GFX_START( clipbounds );
-+  W100_SetFrgColour( this->cpen.color().rgb() );
-+  W100_SetRopOperation( ROP3_PATCOPY );
-+  for ( int loopc = 0; loopc < this->ncliprect; loopc++ ) {
-+    ATI_CLIPRECT clip;
-+    clip.X_Top_Left = this->cliprect[loopc].x();
-+    clip.Y_Top_Left = this->cliprect[loopc].y();
-+    clip.X_Bottom_Right = this->cliprect[loopc].right() + 1;
-+    clip.Y_Bottom_Right = this->cliprect[loopc].bottom() + 1;
-+    W100_SetDstClippingRect( &clip );
-+    W100_DrawPixel( 1, &point );
-+  }
-+  GFX_END;
-+  QWSDisplay::ungrab();
++    ATI_POINT point;
++    point.XCoord = x + this->xoffs;
++    point.YCoord = y + this->yoffs;
++
++    GFX_START( clipbounds );
++    W100_SetFrgColour( this->cpen.color().rgb() );
++    W100_SetRopOperation( ROP3_PATCOPY );
++    for ( int loopc = 0; loopc < this->ncliprect; loopc++ ) {
++        ATI_CLIPRECT clip;
++        clip.X_Top_Left = this->cliprect[loopc].x();
++        clip.Y_Top_Left = this->cliprect[loopc].y();
++        clip.X_Bottom_Right = this->cliprect[loopc].right() + 1;
++        clip.Y_Bottom_Right = this->cliprect[loopc].bottom() + 1;
++        W100_SetDstClippingRect( &clip );
++        W100_DrawPixel( 1, &point );
++    }
++    GFX_END;
++    QWSDisplay::ungrab();
 +}
 +
 +template< const int depth, const int type >
 +void QGfxW100< depth, type>::drawPoints( const QPointArray &a, 
-+                                       int index, 
-+                                       int npoints )
-+{
-+  if ( ( this->ncliprect < 1 ) || ( npoints < 1 ) ) {
-+    return;
-+  }
-+
-+  if ( !control.accelerated( W100Control::DRAWPOINTS ) ) {
-+    control.addMiss( W100Control::DRAWPOINTS );
-+    QGfxRaster<depth,type>::drawPoints( a, index, npoints );
-+    return;
-+  }
-+
-+  if ( this->cpen.style() != this->SolidLine ||
-+       this->myrop != this->CopyROP ) {
-+    control.addMiss( W100Control::DRAWPOINTS );
-+    QGfxRaster<depth,type>::drawPoints( a, index, npoints );
-+    return;
-+  }
-+
-+  QWSDisplay::grab( TRUE );
-+  if ( !checkDest() ) {
-+    QWSDisplay::ungrab();
-+    control.addMiss( W100Control::DRAWPOINTS );
-+    QGfxRaster<depth,type>::drawPoints( a, index, npoints );
-+    return;
-+  }
++                                         int index, 
++                                         int npoints )
++{
++    QPointArray na( npoints );
++
++    for ( int i = 0; i < npoints; i++ ) {
++        int x, y;
++        a.point( i+index, &x, &y );
++        na.setPoint( i, tx( x, y ), ty( x, y ) );
++    }
 +
-+  control.addHit( W100Control::DRAWPOINTS );
-+  ( *optype ) = 1;
++    dDrawPoints( na, 0, npoints );
++}
++
++template< const int depth, const int type >
++void QGfxW100< depth, type>::dDrawPoints( const QPointArray &a, 
++                                          int index, 
++                                          int npoints )
++{
++    if ( ( this->ncliprect < 1 ) || ( npoints < 1 ) ) {
++        return;
++    }
++
++    if ( !control.accelerated( W100Control::DRAWPOINTS ) ) {
++        control.addMiss( W100Control::DRAWPOINTS );
++        QGfxRaster<depth,type>::drawPoints( a, index, npoints );
++        return;
++    }
++
++    if ( this->cpen.style() != this->SolidLine ||
++         this->myrop != this->CopyROP ) {
++        control.addMiss( W100Control::DRAWPOINTS );
++        QGfxRaster<depth,type>::drawPoints( a, index, npoints );
++        return;
++    }
++
++    QWSDisplay::grab( TRUE );
++    if ( !checkDest() ) {
++        QWSDisplay::ungrab();
++        control.addMiss( W100Control::DRAWPOINTS );
++        QGfxRaster<depth,type>::drawPoints( a, index, npoints );
++        return;
++    }
++
++    control.addHit( W100Control::DRAWPOINTS );
++    ( *optype ) = 1;
 +  
-+  ATI_POINT *points = new ATI_POINT[ npoints ];
-+  for ( int i = 0; i < npoints; i++ ) {
-+    points[i].XCoord = a[ i + index ].x() + this->xoffs;
-+    points[i].YCoord = a[ i + index ].y() + this->yoffs;
-+  }
-+
-+  GFX_START( clipbounds );
-+  W100_SetFrgColour( this->cpen.color().rgb() );
-+  W100_SetRopOperation( ROP3_PATCOPY );
-+  for ( int loopc = 0; loopc < this->ncliprect; loopc++ ) {
-+    ATI_CLIPRECT clip;
-+    clip.X_Top_Left = this->cliprect[loopc].x();
-+    clip.Y_Top_Left = this->cliprect[loopc].y();
-+    clip.X_Bottom_Right = this->cliprect[loopc].right() + 1;
-+    clip.Y_Bottom_Right = this->cliprect[loopc].bottom() + 1;
-+    W100_SetDstClippingRect( &clip );
-+    W100_DrawPixel( npoints, points );
-+  }
-+  GFX_END;
-+
-+  delete [] points;
-+  QWSDisplay::ungrab();
++    ATI_POINT *points = new ATI_POINT[ npoints ];
++    for ( int i = 0; i < npoints; i++ ) {
++        points[i].XCoord = a[i+index].x() + this->xoffs;
++        points[i].YCoord = a[i+index].y() + this->yoffs;
++    }
++
++    GFX_START( clipbounds );
++    W100_SetFrgColour( this->cpen.color().rgb() );
++    W100_SetRopOperation( ROP3_PATCOPY );
++    for ( int loopc = 0; loopc < this->ncliprect; loopc++ ) {
++        ATI_CLIPRECT clip;
++        clip.X_Top_Left = this->cliprect[loopc].x();
++        clip.Y_Top_Left = this->cliprect[loopc].y();
++        clip.X_Bottom_Right = this->cliprect[loopc].right() + 1;
++        clip.Y_Bottom_Right = this->cliprect[loopc].bottom() + 1;
++        W100_SetDstClippingRect( &clip );
++        W100_DrawPixel( npoints, points );
++    }
++    GFX_END;
++
++    delete [] points;
++    QWSDisplay::ungrab();
++}
++
++template <const int depth, const int type>
++void QGfxW100<depth,type>::scroll( int x, int y, int w, int h, int sx, int sy )
++{
++    if ( w == 0 || h == 0 )
++        return;
++    QRect r;
++    QRect s;
++    if ( inDraw ) {
++        r = QRect( x, y, w, h );
++        s = QRect( sx, sy, w, h );
++    } else {
++        r.setCoords( tx(x,y), ty(x,y), tx(x+w-1,y+h-1), ty(x+w-1,y+h-1) );
++        s.setCoords( tx(sx,sy), ty(sx,sy), tx(sx+w-1,sy+h-1), ty(sx+w-1,sy+h-1) );
++        r = r.normalize();
++        s = s.normalize();
++    }
++    dScroll( r.x(), r.y(), r.width(), r.height(), s.x(), s.y() );
 +}
 +
 +
 +template< const int depth, const int type >
-+void QGfxW100< depth, type>::scroll( int rx, int ry,
-+                                   int w, int h, 
-+                                   int sx, int sy )
-+{
-+  if ( !control.accelerated( W100Control::SCROLL ) ) {
-+    control.addMiss( W100Control::SCROLL );
-+    QGfxRaster<depth,type>::scroll( rx, ry, w, h, sx, sy );
-+    return;
-+  }
++void QGfxW100< depth, type>::dScroll( int rx, int ry,
++                                      int w, int h, 
++                                      int sx, int sy )
++{
++    if ( !control.accelerated( W100Control::SCROLL ) ) {
++        control.addMiss( W100Control::SCROLL );
++        QGfxRaster<depth,type>::scroll( rx, ry, w, h, sx, sy );
++        return;
++    }
 +
-+  if ( this->ncliprect < 1 ) return;
++    if ( this->ncliprect < 1 ) return;
 +
-+  if ( ( w < 1 )  || ( h < 1 ) ) return;
++    if ( ( w < 1 )  || ( h < 1 ) ) return;
 +
-+  int dy = sy - ry;
-+  int dx = sx - rx;
++    int dy = sy - ry;
++    int dx = sx - rx;
 +
-+  if ( dx == 0 && dy == 0 ) return;
++    if ( dx == 0 && dy == 0 ) return;
 +
 +
-+  QWSDisplay::grab( TRUE );
++    QWSDisplay::grab( TRUE );
 +
-+  if ( checkDest( true ) ) {
++    if ( checkDest( true ) ) {
 +
 +
-+    rx += this->xoffs;
-+    sx += this->xoffs;
-+    ry += this->yoffs;
-+    sy += this->yoffs;
++        rx += this->xoffs;
++        sx += this->xoffs;
++        ry += this->yoffs;
++        sy += this->yoffs;
 +
-+    GFX_START( QRect( QMIN( rx , sx  ),
-+                    QMIN( ry , sy  ),
-+                    w + QABS( dx ) + 1,
-+                    h + QABS( dy ) + 1 ) );
-+    ( *optype ) = 1;
++        GFX_START( QRect( QMIN( rx , sx  ),
++                          QMIN( ry , sy  ),
++                          w + QABS( dx ) + 1,
++                          h + QABS( dy ) + 1 ) );
++        ( *optype ) = 1;
 +
 +
-+    //if ( control.lastOp() != W100Control::SCROLL ) {
-+    W100_SetRopOperation( ROP3_SRCCOPY );
-+    W100_SetDstType( DSTTYPE_16BPP_1555 );
-+    W100_SetSrcType( SRCTYPE_EQU_DST );
-+    //}
++        //if ( control.lastOp() != W100Control::SCROLL ) {
++        W100_SetRopOperation( ROP3_SRCCOPY );
++        W100_SetDstType( DSTTYPE_16BPP_1555 );
++        W100_SetSrcType( SRCTYPE_EQU_DST );
++        //}
 +
-+    control.addHit( W100Control::SCROLL );
++        control.addHit( W100Control::SCROLL );
 +
-+    ATI_RECT srcrect, dstrect;
++        ATI_RECT srcrect, dstrect;
 +
-+    srcrect.XCoord = sx;
-+    srcrect.YCoord = sy;
-+    srcrect.Width = w;
-+    srcrect.Height = h;
-+    dstrect.XCoord = rx;
-+    dstrect.YCoord = ry;
-+    dstrect.Width = w;
-+    dstrect.Height = h;
++        srcrect.XCoord = sx;
++        srcrect.YCoord = sy;
++        srcrect.Width = w;
++        srcrect.Height = h;
++        dstrect.XCoord = rx;
++        dstrect.YCoord = ry;
++        dstrect.Width = w;
++        dstrect.Height = h;
++        control.log( W100Control::WARNING, 
++                     "scroll [%d,%d,%d,%d] ->[%d,%d,%d,%d]",
++                     sx, sy, w, h, rx, ry, w, h );
++        for ( int loopc = 0; loopc < this->ncliprect; loopc++ ) {
++            ATI_CLIPRECT clip;
++            clip.X_Top_Left     = this->cliprect[ loopc ].x();
++            clip.Y_Top_Left     = this->cliprect[ loopc ].y();
++            clip.X_Bottom_Right = this->cliprect[ loopc ].right() + 1;
++            clip.Y_Bottom_Right = this->cliprect[ loopc ].bottom() + 1;
 +
-+    for ( int loopc = 0; loopc < this->ncliprect; loopc++ ) {
-+      ATI_CLIPRECT clip;
-+      clip.X_Top_Left     = this->cliprect[ loopc ].x();
-+      clip.Y_Top_Left     = this->cliprect[ loopc ].y();
-+      clip.X_Bottom_Right = this->cliprect[ loopc ].right() + 1;
-+      clip.Y_Bottom_Right = this->cliprect[ loopc ].bottom() + 1;
-+      W100_SetDstClippingRect( &clip );
-+      W100_BitBlt( 1, &dstrect, &srcrect );
-+    }
-+    GFX_END;
-+    QWSDisplay::ungrab();
++            W100_SetDstClippingRect( &clip );
++            W100_BitBlt( 1, &dstrect, &srcrect );
++        }
++        GFX_END;
++        QWSDisplay::ungrab();
 +
-+  } else {
-+    QWSDisplay::ungrab();
-+    // software fallback
-+    control.addMiss( W100Control::SCROLL );
-+    QGfxRaster<depth,type>::scroll( rx, ry, w, h, sx, sy );
-+  }
++    } else {
++        QWSDisplay::ungrab();
++        // software fallback
++        control.addMiss( W100Control::SCROLL );
++        QGfxRaster<depth,type>::scroll( rx, ry, w, h, sx, sy );
++    }
 +}
 +
-+
++template< const int depth, const int type >
++void QGfxW100< depth, type>::fillRect( int x, int y, int w, int h )
++{
++    if ( w == 0 || h == 0 )
++        return;
++    QRect r( x, y, w, h );
++    r.setCoords( tx( x, y ), ty( x, y ), 
++                 tx( x + w - 1, y + h - 1 ), ty( x + w - 1, y + h - 1 ) );
++    r = r.normalize();
++    inDraw = TRUE;
++    dFillRect( r.x(), r.y(), r.width(), r.height() );
++    inDraw = FALSE;
++}
 +  
 +template< const int depth, const int type >
-+void QGfxW100< depth, type>::fillRect( int rx, int ry, int w, int h )
++void QGfxW100< depth, type>::dFillRect( int rx, int ry, int w, int h )
 +{
++    if ( w <= 0 || h <= 0 || this->ncliprect < 1 ) return;
++
++    if ( !control.accelerated( W100Control::FILLRECT ) ) {
++        control.addMiss( W100Control::FILLRECT );
++        QGfxRaster<depth,type>::fillRect( rx, ry, w, h );
++        return;
++    }
++
++    if ( ( this->cbrush.style() != this->NoBrush ) && 
++         ( this->cbrush.style() != this->SolidPattern ) ) {
++        control.addMiss( W100Control::FILLRECT );
++        QGfxRaster<depth,type>::fillRect( rx, ry, w, h );
++        return;
++    }
++
++    if ( !checkDest() || ( this->myrop != this->CopyROP ) ) {
++        control.addMiss( W100Control::FILLRECT );
++        QGfxRaster<depth,type>::fillRect( rx, ry, w, h );
++        return;
++    }
++
++    QWSDisplay::grab( TRUE );
++    rx += this->xoffs;
++    ry += this->yoffs;
++
++    GFX_START( QRect( rx, ry, w + 1, h + 1 ) );
 +
-+  if ( w <= 0 || h <= 0 || this->ncliprect < 1 ) return;
++    ( *optype ) = 1;
++    //if ( control.lastOp() != W100Control::FILLRECT ) {
++    W100_SetDstType( DSTTYPE_16BPP_1555 );
++    W100_SetSrcType( SRCTYPE_EQU_DST );
++    W100_SetRopOperation( ROP3_PATCOPY );
++    W100_BrushType( 6, 0 );
++    //}
++    W100_SetFrgColour( this->cbrush.color().rgb() );
++
++    control.addHit( W100Control::FILLRECT );
++
++    if ( this->cbrush.style() != this->NoBrush ) {
++        //Using all the cliprects
++        for ( int loopc = 0; loopc < this->ncliprect; loopc++ ) {
++            ATI_CLIPRECT clip;
++            ATI_RECT rect;
++
++            clip.X_Top_Left     = this->cliprect[ loopc ].x();
++            clip.Y_Top_Left     = this->cliprect[ loopc ].y();
++            clip.X_Bottom_Right = this->cliprect[ loopc ].right() + 1;
++            clip.Y_Bottom_Right = this->cliprect[ loopc ].bottom() + 1;
++
++            W100_SetDstClippingRect( &clip );
++            rect.XCoord = rx;
++            rect.YCoord = ry;
++            rect.Width  = w;
++            rect.Height = h;
++            W100_PaintRect( 1, &rect );
++        }
++    }
++    GFX_END;
++      
++    QWSDisplay::ungrab();
++}
 +
-+  if ( !control.accelerated( W100Control::FILLRECT ) ) {
-+    control.addMiss( W100Control::FILLRECT );
-+    QGfxRaster<depth,type>::fillRect( rx, ry, w, h );
-+    return;
-+  }
++template <const int depth, const int type>
++void QGfxW100<depth,type>::blt( int x, int y, int w, int h, int sx, int sy )
++{
++    if ( w == 0 || h == 0 )
++        return;
++    QRect r;
++    int rsx;
++    int rsy;
++    if ( inDraw ) {
++        r = QRect( x, y, w, h );
++        rsx = sx;
++        rsy = sy;
++    } else {
++        r.setCoords( tx(x,y), ty(x,y), tx(x+w-1,y+h-1), ty(x+w-1,y+h-1) );
++        r = r.normalize();
++        switch ( qt_w100_screen->transformation() ) {
++        case QW100Screen::Rot90:
++            rsx = sy;
++            rsy = this->srcwidth - sx - w;
++            break;
++        case QW100Screen::Rot180:
++            rsx = this->srcwidth - sx - w;
++            rsy = this->srcheight - sy - h;
++            break;
++        case QW100Screen::Rot270:
++            rsx = this->srcheight - sy - h;
++            rsy = sx;
++            break;
++        default:
++            rsx = sx;
++            rsy = sy;
++            break;
++        }
++    }
++    dBlt( r.x(), r.y(), r.width(), r.height(), rsx, rsy );
++}
 +
-+  if ( ( this->cbrush.style() != this->NoBrush ) && 
-+       ( this->cbrush.style() != this->SolidPattern ) ) {
-+    control.addMiss( W100Control::FILLRECT );
-+    QGfxRaster<depth,type>::fillRect( rx, ry, w, h );
-+    return;
-+  }
++template< const int depth, const int type >
++inline void QGfxW100< depth, type>::dBlt( int rx, int ry, 
++                                          int w, int h,
++                                          int sx, int sy )
++{
++    if ( !w || !h || this->ncliprect < 1 ) {
++        return;
++    }
 +
-+  if ( !checkDest() || ( this->myrop != this->CopyROP ) ) {
-+    control.addMiss( W100Control::FILLRECT );
-+    QGfxRaster<depth,type>::fillRect(rx,ry,w,h);
-+    return;
-+  }
++    if ( !control.accelerated( W100Control::BITBLT ) ) {
++        control.addMiss( W100Control::BITBLT );
++        QGfxRaster<depth,type>::blt( rx, ry, w, h, sx, sy );
++        return;
++    }
 +
-+  QWSDisplay::grab( TRUE );
-+  rx += this->xoffs;
-+  ry += this->yoffs;
++    if ( this->alphatype == this->BigEndianMask ||
++         this->alphatype == this->LittleEndianMask ||
++         this->alphatype == this->SeparateAlpha ||
++         this->srctype == this->SourcePen ||
++         ( this->myrop != this->CopyROP ) ) {
++        control.addMiss( W100Control::BITBLT );
++        QGfxRaster<depth,type>::blt( rx, ry, w, h, sx, sy );
++        return;
++    }
 +
-+  GFX_START( QRect( rx, ry, w+1, h+1 ) );
++    if( ( this->srcdepth != 16 ) || this->alphatype != this->IgnoreAlpha ) {
++        control.addMiss( W100Control::BITBLT );
++        QGfxRaster<depth,type>::blt( rx, ry, w, h, sx, sy );
++        return;
++    }
 +
-+  ( *optype ) = 1;
-+  control.log( W100Control::INFO, "QGfxW100::fillRect( +%d+%d %dx%d )",
-+             rx, ry, w, h );
++    QWSDisplay::grab( TRUE );
 +
++    if( checkSourceDest() ) {
++        GFX_START( QRect( rx + xoffs, ry + yoffs ,
++                          w + 1, h + 1 ) );
++        ( *optype ) = 1;
 +
-+  //if ( control.lastOp() != W100Control::FILLRECT ) {
-+  W100_SetDstType( DSTTYPE_16BPP_1555 );
-+  W100_SetSrcType( SRCTYPE_EQU_DST );
-+  W100_SetRopOperation( ROP3_PATCOPY );
-+  W100_BrushType( 6, 0 );
-+  //}
-+  W100_SetFrgColour( this->cbrush.color().rgb() );
++        //if ( control.lastOp() != W100Control::BITBLT ) {
++        W100_SetRopOperation( ROP3_SRCCOPY );
++        W100_SetDstType( DSTTYPE_16BPP_1555 );
++        W100_SetSrcType( SRCTYPE_EQU_DST );
++        //}
 +
-+  control.addHit( W100Control::FILLRECT );
++        control.addHit( W100Control::BITBLT );
 +
-+  if ( this->cbrush.style() != this->NoBrush ) {
-+    //Using all the cliprects
-+    for ( int loopc = 0; loopc < this->ncliprect; loopc++ ) {
-+      ATI_CLIPRECT clip;
-+      ATI_RECT rect;
-+
-+      clip.X_Top_Left     = this->cliprect[ loopc ].x();
-+      clip.Y_Top_Left     = this->cliprect[ loopc ].y();
-+      clip.X_Bottom_Right = this->cliprect[ loopc ].right() + 1;
-+      clip.Y_Bottom_Right = this->cliprect[ loopc ].bottom() + 1;
-+
-+      W100_SetDstClippingRect( &clip );
-+      rect.XCoord = rx;
-+      rect.YCoord = ry;
-+      rect.Width  = w;
-+      rect.Height = h;
-+      W100_PaintRect( 1, &rect );
-+    }
-+  }
-+  GFX_END;
++        ATI_RECT rect1;
++        ATI_RECT rect2;
++      
++        rx += this->xoffs;
++        ry += this->yoffs;
++
++        rect1.XCoord = this->srcwidgetoffs.x() + sx;
++        rect1.YCoord = this->srcwidgetoffs.y() + sy;
++        rect1.Width  = w;
++        rect1.Height = h;
++        rect2.XCoord = rx;
++        rect2.YCoord = ry;
++        rect2.Width = w;
++        rect2.Height = h;
++        for(int loopc = 0; loopc < this->ncliprect; loopc++ ) {
++            ATI_CLIPRECT clip;
++            clip.X_Top_Left     = this->cliprect[ loopc ].x();
++            clip.Y_Top_Left     = this->cliprect[ loopc ].y();
++            clip.X_Bottom_Right = this->cliprect[ loopc ].right() + 1;
++            clip.Y_Bottom_Right = this->cliprect[ loopc ].bottom() + 1;
++            W100_SetDstClippingRect( &clip );
++            W100_BitBlt( 1, &rect2, &rect1 );
++        }
++        GFX_END;
 +      
-+  QWSDisplay::ungrab();
++        QWSDisplay::ungrab();
++        return;
++    } else {
++        QWSDisplay::ungrab();
++        // software fallback
++        control.addMiss( W100Control::BITBLT );
++        QGfxRaster<depth,type>::blt( rx, ry, 
++                                     w, h, sx, sy );
++    }
 +}
 +
-+template< const int depth, const int type >
-+inline void QGfxW100< depth, type>::blt( int rx, int ry, 
-+                                       int w, int h,
-+                                       int sx, int sy )
-+{
-+  control.log( W100Control::INFO, "QGfxW100::blt( +%d+%d %dx%d )",
-+             rx, ry, w, h );
-+  if ( !w || !h || this->ncliprect < 1 ) {
-+    return;
-+  }
-+
-+  if ( !control.accelerated( W100Control::BITBLT ) ) {
-+    control.addMiss( W100Control::BITBLT );
-+    QGfxRaster<depth,type>::blt(rx,ry,w,h,sx,sy);
-+    return;
-+  }
-+
-+  if ( this->alphatype == this->BigEndianMask ||
-+       this->alphatype == this->LittleEndianMask ||
-+       this->alphatype == this->SeparateAlpha ||
-+       this->srctype == this->SourcePen ||
-+       ( this->myrop != this->CopyROP ) ) {
-+    control.addMiss( W100Control::BITBLT );
-+    QGfxRaster<depth,type>::blt(rx,ry,w,h,sx,sy);
-+    return;
-+  }
-+
-+  if( ( this->srcdepth != 16 ) || this->alphatype != this->IgnoreAlpha ) {
-+    control.addMiss( W100Control::BITBLT );
-+    QGfxRaster<depth,type>::blt(rx,ry,w,h,sx,sy);
-+    return;
-+  }
-+
-+  QWSDisplay::grab( TRUE );
-+
-+  if( checkSourceDest() ) {
-+    GFX_START( QRect( rx + xoffs, ry + yoffs , w+1, h+1 ) );
-+    ( *optype ) = 1;
-+
-+    //if ( control.lastOp() != W100Control::BITBLT ) {
-+    W100_SetRopOperation( ROP3_SRCCOPY );
-+    W100_SetDstType( DSTTYPE_16BPP_1555 );
-+    W100_SetSrcType( SRCTYPE_EQU_DST );
-+    //}
 +
-+    control.addHit( W100Control::BITBLT );
++template <const int depth, const int type>
++void QGfxW100<depth,type>::tiledBlt( int rx,int ry,int w,int h )
++{
++    if ( w <= 0 || h <= 0 )
++        return;
++    QRect r;
++    if ( inDraw ) {
++        r = QRect(rx,ry,w,h);
++    } else {
++        r.setCoords( tx(rx,ry), ty(rx,ry), tx(rx+w-1,ry+h-1), ty(rx+w-1,ry+h-1) );
++        r = r.normalize();
++    }
 +
-+    ATI_RECT rect1;
-+    ATI_RECT rect2;
-+      
-+    rect1.XCoord = this->srcwidgetoffs.x() + sx;
-+    rect1.YCoord = this->srcwidgetoffs.y() + sy;
-+    rect1.Width  = w;
-+    rect1.Height = h;
-+    rect2.XCoord = this->xoffs + rx;
-+    rect2.YCoord = this->yoffs + ry;
-+    rect2.Width = w;
-+    rect2.Height = h;
-+    for(int loopc = 0; loopc < this->ncliprect; loopc++ ) {
-+      ATI_CLIPRECT clip;
-+      clip.X_Top_Left     = this->cliprect[ loopc ].x();
-+      clip.Y_Top_Left     = this->cliprect[ loopc ].y();
-+      clip.X_Bottom_Right = this->cliprect[ loopc ].right() + 1;
-+      clip.Y_Bottom_Right = this->cliprect[ loopc ].bottom() + 1;
-+      W100_SetDstClippingRect( &clip );
-+      W100_BitBlt( 1, &rect2, &rect1 );
++    inDraw = TRUE;
++
++    QPoint oldBrushOffs = this->brushoffs;
++    int brx, bry;
++    switch ( qt_w100_screen->transformation() ) {
++    case QW100Screen::Rot90:
++        brx = this->brushoffs.y();
++        bry = this->srcwidth - this->brushoffs.x() - w;
++        break;
++    case QW100Screen::Rot180:
++        brx = this->srcwidth - this->brushoffs.x() - w;
++        bry = this->srcheight - this->brushoffs.y() - h;
++        break;
++    case QW100Screen::Rot270:
++        brx = this->srcheight - this->brushoffs.y() - h;
++        bry = this->brushoffs.x();
++        break;
++    default:
++        brx = this->brushoffs.x();
++        bry = this->brushoffs.y();
++        break;
 +    }
-+    GFX_END;
-+      
-+    QWSDisplay::ungrab();
-+    return;
-+  } else {
-+    QWSDisplay::ungrab();
-+    // software fallback
-+    control.addMiss( W100Control::BITBLT );
-+    QGfxRaster<depth,type>::blt( rx, ry, w, h, sx, sy );
-+  }
++    this->brushoffs = QPoint( brx, bry );
++
++    int oldsw = this->srcwidth;
++    int oldsh = this->srcheight;
++    QSize s = qt_screen->mapToDevice( QSize(this->srcwidth,this->srcheight) );
++    this->srcwidth = s.width();
++    this->srcheight = s.height();
++
++    dTiledBlt( r.x(), r.y(), r.width(), r.height() );
++
++    this->srcwidth = oldsw;
++    this->srcheight = oldsh;
++    this->brushoffs = oldBrushOffs;
++    inDraw = FALSE;
 +}
 +
 +
++template <const int depth, const int type>
++void QGfxW100<depth,type>::dTiledBlt( int rx,int ry, int w,int h )
++{
++    if ( this->srcwidth == 0 || this->srcheight == 0 )
++        return;
++    QGfxRaster<depth,type>::tiledBlt( rx, ry, w, h );
++}
++
 +template<const int depth,const int type>
 +void QGfxW100<depth,type>::sync()
 +{
-+  W100_WaitComplete( -1 );
++    W100_WaitComplete( -1 );
++}
++
++template <const int depth, const int type>
++void QGfxW100<depth,type>::setSourceWidgetOffset(int x, int y)
++{
++    if ( this->srcbits == this->buffer ) {
++        switch ( qt_w100_screen->transformation() ) {
++        case QW100Screen::Rot90:
++            this->srcwidgetoffs = QPoint( y, this->width - x - this->srcwidth );
++            break;
++        case QW100Screen::Rot180:
++            this->srcwidgetoffs = QPoint( this->width - x - this->srcwidth, this->height - y - this->srcheight );
++            break;
++        case QW100Screen::Rot270:
++            this->srcwidgetoffs = QPoint( this->height - y - this->srcheight, x );
++            break;
++        default:
++            this->srcwidgetoffs = QPoint( x, y );
++            break;
++        }
++    } else {
++        this->srcwidgetoffs = QPoint( x, y );
++    }
++}
++
++template <const int depth, const int type>
++void QGfxW100<depth,type>::processSpans( int n, QPoint* point, int* width )
++{
++    if ( inDraw || 
++         this->patternedbrush && 
++         this->srcwidth != 0 && 
++         this->srcheight != 0 ) {
++        //in the patternedbrush case, we let blt do the transformation
++        // so we leave inDraw false.
++        QGfxRaster<depth,type>::processSpans( n, point, width );
++    } else {
++        inDraw = true;
++        while (n--) {
++            if ( *width > 0 ) {
++                int x=tx(point->x(),point->y())+this->xoffs;
++                int y=ty(point->x(),point->y())+this->yoffs;
++
++                switch( qt_w100_screen->transformation() ) {
++                case QW100Screen::Rot90:
++                    this->vline( x, y-(*width-1), y );
++                    break;
++                case QW100Screen::Rot180:
++                    this->hline( x - (*width-1), x, y );
++                    break;
++                case QW100Screen::Rot270:
++                    this->vline( x, y, y+*width-1 );
++                    break;
++                default:
++                    this->hline( x, x+*width-1, y );
++                    break;
++                }
++            }
++            point++;
++            width++;
++        }
++        inDraw = false;
++    }
 +}
 +
-+class QW100Screen : public QLinuxFbScreen {
 +
-+public:
-+  class HWSurface {
-+  public:
-+    HWSurface( void ):
-+      m_handle( 0 ),
-+      m_offset( 0 ),
-+      m_addr( 0 ),
-+      m_size( 0 ),
-+      m_internal( false ),
-+      m_clientid( -1 ) {};
-+    HWSurface( unsigned short handle,
-+             uint32_t sOffset,
-+             unsigned char *localAddr, 
-+             int amount,
-+             bool internal,
-+             int clientid ):
-+      m_handle( handle ),
-+      m_offset( sOffset ),
-+      m_addr( localAddr ),
-+      m_size( amount ),
-+      m_internal( internal ),
-+      m_clientid( clientid ) {};
-+    HWSurface( uint32_t sOffset, 
-+             unsigned char *localAddr,
-+             bool internal,
-+             int amount ):
-+      m_handle( 0 ),
-+      m_offset( sOffset ),
-+      m_addr( localAddr ),
-+      m_size( amount ),
-+      m_internal( internal ),
-+      m_clientid( -1 ) {};
-+    bool operator!=( HWSurface &other ) {
-+      return( m_offset == other.getSOffset() );
-+    };
-+    HWSurface &operator=( const HWSurface &c ) {
-+      m_handle = c.getHandle();
-+      m_offset = c.getSOffset();
-+      m_addr = c.getAddr();
-+      m_size = c.getSize();
-+      m_clientid= c.getCId();
-+      m_internal = c.internal();
-+      return( *this );
-+    };
-+    unsigned short getHandle( void ) const { return m_handle; };
-+    uint32_t getSOffset( void ) const { return m_offset; };
-+    unsigned char *getAddr( void ) const { return m_addr; };
-+    unsigned int getSize( void ) const { return m_size; };
-+    int getCId( void ) const { return m_clientid; };
-+    bool internal( void ) const { return m_internal; };
-+
-+  private:
-+    unsigned short m_handle;
-+    uint32_t m_offset;
-+    unsigned char *m_addr;
-+    int m_size;
-+    bool m_internal;
-+    int m_clientid;
-+  };
-+    
-+  QW100Screen( int display_id );
-+  virtual ~QW100Screen();
-+  virtual bool connect( const QString &spec );
-+  virtual void disconnect( void );
-+  virtual bool initDevice();
-+  virtual void shutdownDevice();
-+  virtual bool useOffscreen() { return TRUE; }
-+  virtual QGfx * createGfx( unsigned char *, int, int, int, int);
-+  virtual uchar *cache( int amount, int optim );
-+  virtual void uncache( uchar *c );
-+  virtual bool onCard( unsigned char *p ) const;
-+  virtual bool onCard( unsigned char *p, ulong& offset ) const;
-+  QMap< uchar*, HWSurface > *getPSurfaceMap( void ) const;
-+  void clearCache( int clientId );
-+protected:
-+  static void clearCache( QScreen *instance, int clientId );
-+  QMap< uchar*, HWSurface > surfaceMap;
-+  int vramoffset;
-+  virtual int pixmapLinestepAlignment() { return 128; }
-+};
 +
 +QW100Screen::QW100Screen( int display_id )
-+  :QLinuxFbScreen( display_id )
++    :QLinuxFbScreen( display_id ),
++     vramoffset( 0 )
++{
++    qt_w100_screen = this;
++    vramoffset = 0;
++    clearCacheFunc = &clearCache;
++    trans = None;
++}
++
++static const char *trans2str( QW100Screen::Transformation t )
++{
++    switch( t ) {
++    case QW100Screen::None:
++        return "None";
++        break;
++    case QW100Screen::Rot90:
++        return "Rot90";
++        break;
++    case QW100Screen::Rot180:
++        return "Rot180";
++        break;
++    case QW100Screen::Rot270:
++        return "Rot270";
++        break;
++    default:
++        return "Unknown";
++        break;
++    }
++}
++
++QW100Screen::Transformation QW100Screen::getTransSpec( const QString &dspec )
 +{
-+  vramoffset = ( w == 320 ) ? 0: 0x0f000000;
-+  clearCacheFunc = &clearCache;
++    Transformation mytrans = None;
++    if ( dspec.find( ":Rot270" ) >= 0 ) {
++        mytrans = Rot270;
++    } else if ( dspec.find( ":Rot180" ) >= 0 ) {
++        mytrans = Rot180;
++    } else if ( dspec.find( ":Rot90" ) >= 0 ) {
++        mytrans = Rot90;
++    }
++    return mytrans;
 +}
 +
 +bool QW100Screen::connect( const QString &displaySpec )
 +{
-+
-+  if ( QLinuxFbScreen::connect( displaySpec ) ) {
-+    if ( W100_ProcessAttach() ) {
-+      W100_ProcessAttachSpecialMode( ( w == 480 ) ? 0xaaab:0xaaaa );
-+      surfaceMap.insert( 0, HWSurface( vramoffset, 
-+                                     data , false, 
-+                                     w*h*d/8 ) );
-+      canaccel = TRUE;
-+      return TRUE;
++    control.log( W100Control::WARNING, "QW100Screen::connect('%s')",
++                 displaySpec.latin1() );
++    trans = getTransSpec( displaySpec );
++
++    if ( QLinuxFbScreen::connect( displaySpec ) ) {
++        vramoffset = ( w == 320 ) ? 0 : 0x0f000000;
++        if ( W100_ProcessAttach() ) {
++            W100_ProcessAttachSpecialMode( ( w == 480 ) ? 0xaaab : 0xaaaa );
++            surfaceMap.clear();
++            surfaceMap.insert( 0, HWSurface( vramoffset, 
++                                             data , false, 
++                                             w*h*d/8 ) );
++            canaccel = true;
++            QSize s = mapFromDevice( QSize( w, h ) );
++            w = s.width();
++            h = s.height();
++            return true;
++        }
 +    }
-+  }
-+  return FALSE;
++    return false;
 +}
 +
 +void QW100Screen::disconnect( void )
 +{
-+  QLinuxFbScreen::disconnect();
-+  W100_ProcessDetach();
++    control.log( W100Control::WARNING, "QW100Screen::disconnect()" );
++    W100_ProcessDetach();
++    QLinuxFbScreen::disconnect();
++    printf( "[%d]QW100Screen disconnected with %d surfaces\n", 
++            getpid(), surfaceMap.count() );
++    surfaceMap.clear();
 +}
 +
 +QW100Screen::~QW100Screen()
 +{
 +}
 +
-+bool QW100Screen::initDevice()
++bool QW100Screen::w100init()
 +{
-+  ATI_GRAPHICWINDOW win;
-+  ATI_CLIPRECT      clip;
-+  uint16_t overlay;
-+  int ret;
-+  uint32_t extm, intm;
-+  W100_GetAvailableVideoMem( &intm, &extm );
-+  ret = W100_CursorOnOff( 1, 0 );
-+  ret = W100_CursorOnOff( 2, 0 );
-+  ret = W100_CursorOnOff( 3, 0 );
-+  win.dummy1 = 0;
-+  win.Size.XCoord = 0;
-+  win.Size.YCoord = 0;
-+  win.Size.Width = w;
-+  win.Size.Height = h;
-+  win.Width = w > h ? h : w;
-+  win.Height = w > h ? w : h;
-+  win.Flag = DSTTYPE_16BPP_444; //(5)
-+    
-+  ret = W100_SetupGraphicWindow( &win );
-+  if ( !ret ) {
-+    return FALSE;
-+  }
-+  ret = W100_SetGraphicWindowPos( 0, 0 );
-+
-+  ret = W100_SetFrontBuffer( vramoffset, 0, 0 );
-+  ret = W100_SetDstPitchOffset( w, vramoffset );
-+  ret = W100_SetDstType( DSTTYPE_16BPP_444 );
-+  ret = W100_SetSrcPitchOffset( w, vramoffset );
-+  ret = W100_SetSrcType( SRCTYPE_SOLID_COLOR_BLT );
-+  clip.X_Top_Left = 0;
-+  clip.Y_Top_Left = 0;
-+  clip.X_Bottom_Right = w;
-+  clip.Y_Bottom_Right = h;
-+  ret = W100_SetDstClippingRect( &clip );
++    control.log( W100Control::WARNING, 
++                 "QW100Screen::w100init(%dx%d)", dw, dh );
++    ATI_GRAPHICWINDOW win;
++    ATI_CLIPRECT      clip;
++    int ret;
++
++    win.dummy1 = 0;
++    win.Size.XCoord = 0;
++    win.Size.YCoord = 0;
++    win.Size.Width = dw;
++    win.Size.Height = dh;
++    win.Width = dw > dh ? dh : dw;
++    win.Height = dw > dh ? dw : dh;
++    win.Flag = DSTTYPE_16BPP_444;
 +    
-+  clip.X_Top_Left = 0xE000;
-+  clip.Y_Top_Left = 0xE000;
-+  clip.X_Bottom_Right = 0x1FFF;
-+  clip.Y_Bottom_Right = 0x1FFF;
++    ret = W100_SetupGraphicWindow( &win );
++    if ( !ret ) {
++        return false;
++    }
++    ret = W100_SetGraphicWindowPos( 0, 0 );
++
++    ret = W100_SetFrontBuffer( vramoffset, 0, 0 );
++    ret = W100_SetDstPitchOffset( dw, vramoffset );
++    ret = W100_SetDstType( DSTTYPE_16BPP_444 );
++    ret = W100_SetSrcPitchOffset( dw, vramoffset );
++    ret = W100_SetSrcType( SRCTYPE_SOLID_COLOR_BLT );
++    clip.X_Top_Left = 0;
++    clip.Y_Top_Left = 0;
++    clip.X_Bottom_Right = dw;
++    clip.Y_Bottom_Right = dh;
++    ret = W100_SetDstClippingRect( &clip );
 +    
-+  ret = W100_SetSrcClippingRect( &clip );
-+  ret = W100_SetRopOperation( ROP3_SRCCOPY );
-+  ret = W100_SetGraphicWindowOnOff( 1 );
++    clip.X_Top_Left = 0xE000;
++    clip.Y_Top_Left = 0xE000;
++    clip.X_Bottom_Right = 0x1FFF;
++    clip.Y_Bottom_Right = 0x1FFF;
 +    
-+  ret = W100_AllocOverlay( &overlay );
-+  ret = W100_SetOverlayOnOff( overlay, 0 );
-+  ret = W100_ReleaseOverlay( overlay );
-+  ret = W100_SetDstPitchOffset( w, vramoffset );
-+  ret = W100_SetDstClippingRect( NULL );
-+  
-+  if ( QLinuxFbScreen::initDevice() ) {
-+    //HACK
-+    //Some sprite corruption seems to be avoided
-+    //reserving some upper memory on the offscreen framebuffer memory
-+    QLinuxFbScreen::cache( 65535 * 2, 0 );
++    ret = W100_SetSrcClippingRect( &clip );
++    ret = W100_SetGraphicWindowOnOff( 1 );
 +    return true;
-+  }
-+  return false;
++}
++
++void QW100Screen::w100shutdown()
++{
++}
++
++bool QW100Screen::initDevice()
++{
++    control.log( W100Control::WARNING, "initDevice( dw=%d, dh=%d )",
++                 dw, dh );
++
++    if ( !w100init() ) return false;
++
++    if ( QLinuxFbScreen::initDevice() ) {
++        //HACK
++        //Some sprite corruption seems to be avoided
++        //reserving some upper memory on the offscreen framebuffer memory
++        QLinuxFbScreen::cache( 65535 * 2, 0 );
++        return true;
++    }
++    return false;
 +}
 +
 +void QW100Screen::shutdownDevice()
 +{
-+  QLinuxFbScreen::shutdownDevice();
-+  W100_ProcessDetach();
++    control.log( W100Control::WARNING, "Shutting down device" );
++    QLinuxFbScreen::shutdownDevice();
++}
++
++void QW100Screen::restore()
++{
++    control.log( W100Control::WARNING, "Restoring W100..." );
++    /*
++      W100_WakeUpCall();
++      initDevice();
++      QLinuxFbScreen::restore();
++    */
++    control.log( W100Control::WARNING, "Restoring done" );
 +}
 +
++
 +QGfx *QW100Screen::createGfx( unsigned char *b,
-+                            int w, int h, int d, int linestep )
++                              int w, int h, int d, int linestep )
 +{
-+  //We need ALL the gfx created to be QGfxW100 to allow software
-+  //drawing syncing after hardware operations
-+  QGfx * ret=0;
-+  if ( false ) {
++    //We need ALL the gfx created to be QGfxW100 to allow software
++    //drawing syncing after hardware operations
++    QGfx * ret=0;
++    if ( false ) {
 +#ifndef QT_NO_QWS_DEPTH_1
-+  } else if ( d == 1 ) {
-+    ret = new QGfxW100<1,0>( b, w, h );
++    } else if ( d == 1 ) {
++        ret = new QGfxW100<1,0>( b, w, h );
 +#endif
 +#ifndef QT_NO_QWS_DEPTH_4
-+  } else if ( d == 4 ) {
-+    ret = new QGfxW100<4,0>( b, w, h );
++    } else if ( d == 4 ) {
++        ret = new QGfxW100<4,0>( b, w, h );
 +#endif
 +#ifndef QT_NO_QWS_DEPTH_8
-+  } else if ( d == 8 ) {
-+    ret = new QGfxW100<8,0>( b, w, h );
++    } else if ( d == 8 ) {
++        ret = new QGfxW100<8,0>( b, w, h );
 +#endif
 +#ifndef QT_NO_QWS_DEPTH_16    
-+  } else if  ( d == 16 ) {
-+    ret = new QGfxW100<16,0>( b, w, h );
++    } else if  ( d == 16 ) {
++        ret = new QGfxW100<16,0>( b, w, h );
 +#endif
 +#ifndef QT_NO_QWS_DEPTH_24
-+  } else if ( d == 24 ) {
-+    ret = new QGfxW100<24,0>( b, w, h );
++    } else if ( d == 24 ) {
++        ret = new QGfxW100<24,0>( b, w, h );
 +#endif
 +#ifndef QT_NO_QWS_DEPTH_32
-+  } else if ( d == 32 ) {
-+    ret = new QGfxW100<32,0>( b, w, h );
++    } else if ( d == 32 ) {
++        ret = new QGfxW100<32,0>( b, w, h );
 +#endif
-+  } else {
-+    qFatal( "Unsupported depth %d\n", d );
-+    ret = 0;
-+  }
++    } else {
++        qFatal( "Unsupported depth %d\n", d );
++        ret = 0;
++    }
 +
-+  ret->setLineStep( linestep );
-+  return ret;    
++    ret->setLineStep( linestep );
++    return ret;
 +}
 +
-+static int sinternal = 0;
-+static int sexternal = 0;
 +
 +uchar *QW100Screen::cache( int amount, int optim )
 +{
-+  unsigned short hSurface = 0;
-+  uint32_t surfaceOffset = 0;
-+  uchar* localAddr = 0;
-+  bool internal = false;
-+
-+  /* The size must have 0xF bit zeroed (16 multiple)*/
-+  /* Perhaps this is not needed anymore, after setting
-+   * QW100Screen::pixmapLinestepAlignment to 128
-+   */
-+  amount = ( amount & 0x0F ) ? ( amount | 0x10 ) & ~0x0F : amount;
-+
-+  /* Experimenting memory corruption with the
-+   * internal AtiCore memory allocation routines
-+   * disabled for now
-+   */
++    unsigned short hSurface = 0;
++    uint32_t surfaceOffset = 0;
++    uchar* localAddr = 0;
++    bool internal = false;
++
++    /* The size must have 0xF bit zeroed (16 multiple)*/
++    /* Perhaps this is not needed anymore, after setting
++     * QW100Screen::pixmapLinestepAlignment to 128
++     */
++    amount = ( amount & 0x0F ) ? ( amount | 0x10 ) & ~0x0F : amount;
++
++    /* Experimenting memory corruption with the
++     * internal AtiCore memory allocation routines
++     * disabled for now
++     */
 +#if 1
-+  if ( !( localAddr = QLinuxFbScreen::cache( amount, optim ) ) ) {
-+    return( 0 );
-+  }
-+  surfaceOffset = vramoffset + ( uint32_t ) localAddr - ( uint32_t )data;
++    if ( !( localAddr = QLinuxFbScreen::cache( amount, optim ) ) ) {
++        return( 0 );
++    }
++    surfaceOffset = vramoffset + ( uint32_t ) localAddr - ( uint32_t )data;
 +
 +#else
-+  int retcode = 0;
-+  qt_fbdpy->grab();
-+  retcode = W100_AllocateSurface( &hSurface,
-+                                &surfaceOffset,
-+                                amount, 1 );
-+  qt_fbdpy->ungrab();
-+  if ( retcode ) {
-+    internal = true;
-+    W100_SetupMemoryTransfer( surfaceOffset, (uint32_t*) &localAddr );
-+    W100_TerminateMemoryTransfer();
-+  } else {
-+    // Try to use the offscreen framebuffer memory
-+    // to allocate the surface. Use the qgfxlinuxfb routines
-+    if ( !( localAddr = QLinuxFbScreen::cache( amount, optim ) ) ) {
-+      return( 0 );
++    int retcode = 0;
++    qt_fbdpy->grab( true );
++    retcode = W100_AllocateSurface( &hSurface,
++                                    &surfaceOffset,
++                                    amount, 1 );
++    qt_fbdpy->ungrab();
++    if ( retcode ) {
++        internal = true;
++        W100_SetupMemoryTransfer( surfaceOffset, (uint32_t*) &localAddr );
++        W100_TerminateMemoryTransfer();
++    } else {
++        // Try to use the offscreen framebuffer memory
++        // to allocate the surface. Use the qgfxlinuxfb routines
++        if ( !( localAddr = QLinuxFbScreen::cache( amount, optim ) ) ) {
++            return( 0 );
++        }
++        //Distance between physical vram start and surface should be
++        //the same than distance between logical addresses
++        surfaceOffset = vramoffset + ( uint32_t ) localAddr - ( uint32_t ) data;
 +    }
-+    //Distance between physical vram start and surface should be
-+    //the same than distance between logical addresses
-+    surfaceOffset = vramoffset + ( uint32_t ) localAddr - ( uint32_t ) data;
-+  }
 +#endif
 +    
-+  HWSurface surface( hSurface, surfaceOffset,
-+                   localAddr, amount, 
-+                   internal,
-+                   qws_client_id );
-+#if 0
-+  if ( internal ) {
-+    sinternal++;
-+  } else {
-+    sexternal++;
-+  }
-+#endif
-+  surfaceMap.insert( surface.getAddr(), surface );
-+  return( ( uchar* ) localAddr );
++    HWSurface surface( hSurface, surfaceOffset,
++                       localAddr, amount, 
++                       internal,
++                       qws_client_id );
++    surfaceMap.insert( surface.getAddr(), surface );
++    return( ( uchar* ) localAddr );
 +}
 +
 +void QW100Screen::uncache( uchar *c )
 +{
-+  QMap< uchar*, HWSurface >::Iterator itr;
-+  if ( ( itr = surfaceMap.find( c ) ) != surfaceMap.end() ) {
-+    if ( itr.data().internal() ) {
-+      qt_fbdpy->grab();
-+      W100_DestroySurface( itr.data().getHandle() );
-+      qt_fbdpy->ungrab();
-+      --sinternal;
-+    } else {
-+      --sexternal;
-+      QLinuxFbScreen::uncache( c );
++    QMap< uchar*, HWSurface >::Iterator itr;
++    if ( ( itr = surfaceMap.find( c ) ) != surfaceMap.end() ) {
++        W100_WaitComplete( -1 );
++        if ( itr.data().internal() ) {
++            qt_fbdpy->grab( true );
++            W100_DestroySurface( itr.data().getHandle() );
++            qt_fbdpy->ungrab();
++        } else {
++            QLinuxFbScreen::uncache( c );
++        }
++        surfaceMap.remove( itr );
 +    }
-+    surfaceMap.remove( itr );
-+  } 
 +}
 +
 +bool QW100Screen::onCard( uchar *p ) const
 +{
-+  QMap< uchar*, HWSurface >::ConstIterator itr = surfaceMap.begin();
-+  for ( ; itr != surfaceMap.end(); itr++ ) {
-+    uchar *begin;
-+    if ( ( begin = itr.data().getAddr() ) <= p ) {
-+      if ( ( itr.data().getSize() + begin ) >= p ) {
-+      return TRUE;
-+      }
++    QMap< uchar*, HWSurface >::ConstIterator itr = surfaceMap.begin();
++    for ( ; itr != surfaceMap.end(); itr++ ) {
++        uchar *begin;
++        if ( ( begin = itr.data().getAddr() ) <= p ) {
++            if ( ( itr.data().getSize() + begin ) >= p ) {
++                return TRUE;
++            }
++        }
 +    }
-+  }
-+  return FALSE;
++    return FALSE;
 +}
 +
 +bool QW100Screen::onCard( unsigned char *p, ulong& offset ) const
 +{
-+  QMap< uchar*, HWSurface >::ConstIterator itr;
-+  for ( itr = surfaceMap.begin(); itr != surfaceMap.end(); itr++ ) {
-+    uchar *begin;
-+    if ( ( begin = itr.data().getAddr() ) <= p ) {
-+      if ( ( itr.data().getSize() + begin ) >= p ) {
-+      offset = itr.data().getSOffset() + ( p - begin );
-+      return TRUE;
-+      }
++    QMap< uchar*, HWSurface >::ConstIterator itr;
++    for ( itr = surfaceMap.begin(); itr != surfaceMap.end(); itr++ ) {
++        uchar *begin;
++        if ( ( begin = itr.data().getAddr() ) <= p ) {
++            if ( ( itr.data().getSize() + begin ) >= p ) {
++                offset = itr.data().getSOffset() + ( p - begin );
++                return TRUE;
++            }
++        }
 +    }
-+  }
-+  return FALSE;
++    return FALSE;
 +}
 +
 +QMap< uchar*, QW100Screen::HWSurface > 
 +*QW100Screen::getPSurfaceMap( void ) const
 +{
-+  return ( QMap<uchar*,HWSurface> *) &surfaceMap;
++    return ( QMap<uchar*,HWSurface> *) &surfaceMap;
 +}
 +
 +void QW100Screen::clearCache( int clientId )
 +{
-+  QMap< uchar*, HWSurface >::Iterator itr = surfaceMap.begin();
-+  while ( itr != surfaceMap.end() ) {
-+    if ( itr.data().getCId() == clientId ) {
-+      if ( itr.data().internal() ) {
-+      qt_fbdpy->grab();
-+      W100_DestroySurface( itr.data().getHandle() );
-+      qt_fbdpy->ungrab();
-+      --sinternal;
-+      } else {
-+      QLinuxFbScreen::uncache( itr.data().getAddr() );
-+      --sexternal;
-+      }
-+      surfaceMap.remove( itr );
++    printf( "[%d] CLEARING CACHE FOR %d\n", getpid(), clientId );
++    control.log( W100Control::WARNING, "Cleaning cache for '%d'", clientId );
++    QMap< uchar*, HWSurface >::Iterator itr = surfaceMap.begin();
++    while ( itr != surfaceMap.end() ) {
++        if ( itr.data().getCId() == clientId ) {
++            if ( itr.data().internal() ) {
++                qt_fbdpy->grab();
++                W100_DestroySurface( itr.data().getHandle() );
++                qt_fbdpy->ungrab();
++            }
++            surfaceMap.remove( itr );
++        }
++        itr++;
 +    }
-+    itr++;
-+  }
++    QLinuxFbScreen::clearCache( this, clientId );
 +}
 +
 +void QW100Screen::clearCache( QScreen *instance, int clientId )
 +{
-+  QW100Screen *screen = ( QW100Screen * )instance;
-+  screen->clearCache( clientId );
++    QW100Screen *screen = reinterpret_cast<QW100Screen *> ( instance );
++    screen->clearCache( clientId );
++}
++
++void QW100Screen::setTransformation( Transformation t )
++{
++    qt_fbdpy->grab( true );
++    trans = t;
++  
++    QSize s = mapFromDevice( QSize( dw,dh ) );
++    w = s.width();
++    h = s.height();
++    qt_fbdpy->ungrab();
++}
++
++QW100Screen::Transformation QW100Screen::transformation( void ) const
++{
++    return trans;
++}
++
++QSize QW100Screen::mapToDevice( const QSize &s ) const
++{
++    if ( trans == Rot90 || trans == Rot270 ) {
++        return QSize( s.height(), s.width() );
++    }
++
++    return s;
++}
++
++QSize QW100Screen::mapFromDevice( const QSize &s ) const
++{
++    if ( trans == Rot90 || trans == Rot270 ) {
++        return QSize( s.height(), s.width() );
++    }
++
++    return s;
++}
++
++QPoint QW100Screen::mapToDevice( const QPoint &p, const QSize &s ) const
++{
++    QPoint rp( p );
++
++    switch ( trans ) {
++      case Rot90:
++          rp.setX( p.y() );
++          rp.setY( s.width() - p.x() - 1 );
++          break;
++      case Rot180:
++          rp.setX( s.width() - p.x() - 1 );
++          rp.setY( s.height() - p.y() - 1 );
++          break;
++      case Rot270:
++          rp.setX( s.height() - p.y() - 1 );
++          rp.setY( p.x() );
++          break;
++      default:
++          break;
++    }
++
++    return rp;
++}
++
++QPoint QW100Screen::mapFromDevice( const QPoint &p, const QSize &s ) const
++{
++    QPoint rp( p );
++
++    switch ( trans ) {
++      case Rot90:
++          rp.setX( s.height() - p.y() - 1 );
++          rp.setY( p.x() );
++          break;
++      case Rot180:
++          rp.setX( s.width() - p.x() - 1 );
++          rp.setY( s.height() - p.y() - 1 );
++          break;
++      case Rot270:
++          rp.setX( p.y() );
++          rp.setY( s.width() - p.x() - 1 );
++          break;
++      default:
++          break;
++    }
++
++    return rp;
++}
++
++QRect QW100Screen::mapToDevice( const QRect &r, const QSize &s ) const
++{
++    QRect tr;
++    switch ( trans ) {
++      case Rot90:
++          tr.setCoords( r.y(), s.width() - r.x() - 1,
++                      r.bottom(), s.width() - r.right() - 1 );
++          break;
++      case Rot180:
++          tr.setCoords( s.width() - r.x() - 1, s.height() - r.y() - 1,
++                      s.width() - r.right() - 1, s.height() - r.bottom() - 1 );
++          break;
++      case Rot270:
++          tr.setCoords( s.height() - r.y() - 1, r.x(),
++                      s.height() - r.bottom() - 1, r.right() );
++          break;
++      default:
++          tr = r;
++          break;
++    }
++
++    return tr.normalize();
++}
++
++QRect QW100Screen::mapFromDevice( const QRect &r, const QSize &s ) const
++{
++    QRect tr;
++    switch ( trans ) {
++      case Rot90:
++          tr.setCoords( s.height() - r.y() - 1, r.x(),
++                      s.height() - r.bottom() - 1, r.right() );
++          break;
++      case Rot180:
++          tr.setCoords( s.width() - r.x() - 1, s.height() - r.y() - 1,
++                      s.width() - r.right() - 1, s.height() - r.bottom() - 1 );
++          break;
++      case Rot270:
++          tr.setCoords( r.y(), s.width() - r.x() - 1,
++                      r.bottom(), s.width() - r.right() - 1 );
++          break;
++      default:
++          tr = r;
++          break;
++    }
++
++    return tr.normalize();
++}
++
++template<class T>
++static inline void rotateLoopTemplate( uchar *src, int srcBytesPerLine,
++                                       uchar *dst, int dstBytesPerLine, 
++                                       int width, int height,
++                                       QW100Screen::Transformation trans, 
++                                       bool mapToDevice )
++{
++    int dstXAdd = 0;
++    int dstYAdd = 0;
++    int dstXOfs = 0;
++    int dstYOfs = 0;
++    int srcYAdd = srcBytesPerLine - width * sizeof(T);
++
++    if ( !mapToDevice ) {
++        if ( trans == QW100Screen::Rot90 )
++            trans = QW100Screen::Rot270;
++        else if ( trans == QW100Screen::Rot270 )
++            trans = QW100Screen::Rot90;
++    }
++
++    switch ( trans ) {
++      case QW100Screen::Rot90:
++          dstXOfs = 0;
++          dstYOfs = width - 1;
++          dstXAdd = -dstBytesPerLine;
++          dstYAdd = 1 * sizeof(T) + width * dstBytesPerLine;
++          break;
++      case QW100Screen::Rot270:
++          dstXOfs = height - 1;
++          dstYOfs = 0;
++          dstXAdd = dstBytesPerLine;
++          dstYAdd = -1 * sizeof(T) - width * dstBytesPerLine;
++          break;
++      default:
++          dstXOfs = width - 1;
++          dstYOfs = height - 1;
++          dstXAdd = -1 * sizeof(T);
++          dstYAdd = -dstBytesPerLine + width * sizeof(T);
++          break;
++    };
++
++    T *dstPtr = (T *)(dst + dstYOfs * dstBytesPerLine) + dstXOfs;
++    T *srcPtr = (T *)src;
++    for ( int y = 0; y < height; y++ ) {
++        for ( int x = 0; x < width; x++ ) {
++            *dstPtr = *srcPtr++;
++            dstPtr = (T *)((uchar*)dstPtr + dstXAdd); // add dstXAdd number of bytes
++        }
++        srcPtr = (T *)((uchar*)srcPtr + srcYAdd); // add srcYAdd number of bytes
++        dstPtr = (T *)((uchar*)dstPtr + dstYAdd); // add dstYAdd number of bytes
++    }
++}
++
++QImage QW100Screen::mapToDevice( const QImage &img ) const
++{
++    if ( img.isNull() || trans == None )
++        return img;
++
++    int iw = img.width();
++    int ih = img.height();
++    int w = iw;
++    int h = ih;
++    if ( trans == Rot90 || trans == Rot270 ) {
++        w = ih;
++        h = iw;
++    }
++
++    QImage rimg( w, h, img.depth(), img.numColors(), img.bitOrder() );
++
++    for ( int i = 0; i < img.numColors(); i++ ) {
++        rimg.colorTable()[i] = img.colorTable()[i];
++    }
++
++    // Optimized image rotation code for nice bit depths
++    int d = img.depth();
++    if ( d == 8 || d == 16 || d == 32 ) {
++        int srcBytesPerLine = img.bytesPerLine();
++        int dstBytesPerLine = rimg.bytesPerLine();
++        uchar *srcBits = img.bits();
++        uchar *dstBits = rimg.bits();
++        switch ( d ) {
++          case 8:
++            rotateLoopTemplate<uchar>( srcBits, srcBytesPerLine, dstBits, dstBytesPerLine, iw, ih, trans, TRUE );
++            break;
++          case 16:
++            rotateLoopTemplate<ushort>( srcBits, srcBytesPerLine, dstBits, dstBytesPerLine, iw, ih, trans, TRUE );
++            break;
++          case 32:
++            rotateLoopTemplate<uint>( srcBits, srcBytesPerLine, dstBits, dstBytesPerLine, iw, ih, trans, TRUE );
++            break;
++        }
++        rimg.setAlphaBuffer( img.hasAlphaBuffer() );
++        rimg.setOffset( img.offset() );
++        return rimg;
++    }
++
++    // Slower fall back code for image rotation for 1-bit and other depths
++#define ROTATE_LOOP( X, Y, VAL ) \
++                  for ( int y = 0; y < ih; y++ ) { \
++                      for ( int x = 0; x < iw; x++ ) { \
++                          rimg.setPixel( X, Y, VAL ); \
++                      } \
++                  } \
++                  break;
++
++    if ( img.depth() > 8 ) {
++        switch ( trans ) {
++          case Rot90:
++            ROTATE_LOOP( y, iw - x - 1, img.pixel(x, y) )
++                case Rot270:
++                ROTATE_LOOP( ih - y - 1, x, img.pixel(x, y) );
++          default:
++            ROTATE_LOOP( iw - x - 1, ih - y - 1, img.pixel(x, y) );
++        }
++    } else {
++        switch ( trans ) {
++          case Rot90:
++            ROTATE_LOOP( y, iw - x - 1, img.pixelIndex(x, y) );
++          case Rot270:
++            ROTATE_LOOP( ih - y - 1, x, img.pixelIndex(x, y) );
++          default:
++            ROTATE_LOOP( iw - x - 1, ih - y - 1, img.pixelIndex(x, y) );
++        }
++    }
++
++#undef ROTATE_LOOP
++
++    rimg.setAlphaBuffer( img.hasAlphaBuffer() );
++    rimg.setOffset( img.offset() );
++
++    return rimg;
++}
++
++QImage QW100Screen::mapFromDevice( const QImage &img ) const
++{
++    if ( img.isNull() || trans == None )
++        return img;
++
++    int iw = img.width();
++    int ih = img.height();
++    int w = iw;
++    int h = ih;
++    if ( trans == Rot90 || trans == Rot270 ) {
++        w = ih;
++        h = iw;
++    }
++
++    QImage rimg( w, h, img.depth(), img.numColors(), img.bitOrder() );
++
++    for ( int i = 0; i < img.numColors(); i++ ) {
++        rimg.colorTable()[i] = img.colorTable()[i];
++    }
++
++    // Optimized image rotation code for nice bit depths
++    int d = img.depth();
++    if ( d == 8 || d == 16 || d == 32 ) {
++        int srcBytesPerLine = img.bytesPerLine();
++        int dstBytesPerLine = rimg.bytesPerLine();
++        uchar *srcBits = img.bits();
++        uchar *dstBits = rimg.bits();
++        switch ( d ) {
++          case 8:
++            rotateLoopTemplate<uchar>( srcBits, srcBytesPerLine, dstBits, dstBytesPerLine, iw, ih, trans, FALSE );
++            break;
++          case 16:
++            rotateLoopTemplate<ushort>( srcBits, srcBytesPerLine, dstBits, dstBytesPerLine, iw, ih, trans, FALSE );
++            break;
++          case 32:
++            rotateLoopTemplate<uint>( srcBits, srcBytesPerLine, dstBits, dstBytesPerLine, iw, ih, trans, FALSE );
++            break;
++        }
++        rimg.setAlphaBuffer( img.hasAlphaBuffer() );
++        rimg.setOffset( img.offset() );
++        return rimg;
++    }
++
++    // Slower fall back code for image rotation for 1-bit and other depths
++#define ROTATE_LOOP( X, Y, VAL ) \
++                  for ( int y = 0; y < ih; y++ ) { \
++                      for ( int x = 0; x < iw; x++ ) { \
++                          rimg.setPixel( X, Y, VAL ); \
++                      } \
++                  } \
++                  break;
++
++    if ( img.depth() > 8 ) {
++        switch ( trans ) {
++          case Rot90:
++            ROTATE_LOOP( ih - y - 1, x, img.pixel(x, y) );
++          case Rot270:
++            ROTATE_LOOP( y, iw - x - 1, img.pixel(x, y) )
++                default:
++            ROTATE_LOOP( iw - x - 1, ih - y - 1, img.pixel(x, y) );
++        }
++    } else {
++        switch ( trans ) {
++          case Rot90:
++            ROTATE_LOOP( ih - y - 1, x, img.pixelIndex(x, y) );
++          case Rot270:
++            ROTATE_LOOP( y, iw - x - 1, img.pixelIndex(x, y) );
++          default:
++            ROTATE_LOOP( iw - x - 1, ih - y - 1, img.pixelIndex(x, y) );
++        }
++    }
++
++#undef ROTATE_LOOP
++
++    rimg.setAlphaBuffer( img.hasAlphaBuffer() );
++    rimg.setOffset( img.offset() );
++
++    return rimg;
++}
++
++QRegion QW100Screen::mapToDevice( const QRegion &rgn, const QSize &s ) const
++{
++    if ( trans == None )
++        return rgn;
++
++    QRegion trgn;
++    QArray<QRect> a = rgn.rects();
++    QRect tr;
++    const QRect *r = a.data();
++
++    int w = s.width();
++    int h = s.height();
++    int size = a.size();
++
++    switch ( trans ) {
++      case Rot270:
++          for ( int i = 0; i < size; i++, r++ ) {
++            tr.setCoords( h - r->y() - 1, r->x(),
++                          h - r->bottom() - 1, r->right() );
++            trgn |= tr.normalize();
++          }
++          break;
++      case Rot90:
++          for ( int i = 0; i < size; i++, r++ ) {
++            tr.setCoords( r->y(), w - r->x() - 1,
++                          r->bottom(), w - r->right() - 1 );
++            trgn |= tr.normalize();
++          }
++          break;
++      case Rot180:
++          for ( int i = 0; i < size; i++, r++ ) {
++            tr.setCoords( w - r->x() - 1, h - r->y() - 1,
++                          w - r->right() - 1, h - r->bottom() - 1 );
++            trgn |= tr.normalize();
++          }
++          break;
++      default:
++          break;
++    }
++    return trgn;
++}
++
++QRegion QW100Screen::mapFromDevice( const QRegion &rgn, const QSize &s ) const
++{
++    if ( trans == None )
++        return rgn;
++
++    QRegion trgn;
++    QArray<QRect> a = rgn.rects();
++    const QRect *r = a.data();
++    QRect tr;
++
++    int w = s.width();
++    int h = s.height();
++    int size = a.size();
++
++    switch ( trans ) {
++      case Rot270:
++          for ( int i = 0; i < size; i++, r++ ) {
++            tr.setCoords( r->y(), w - r->x() - 1,
++                          r->bottom(), w - r->right() - 1 );
++            trgn |= tr.normalize();
++          }
++          break;
++      case Rot90:
++          for ( int i = 0; i < size; i++, r++ ) {
++            tr.setCoords( h - r->y() - 1, r->x(),
++                          h - r->bottom() - 1, r->right() );
++            trgn |= tr.normalize();
++          }
++          break;
++      case Rot180:
++          for ( int i = 0; i < size; i++, r++ ) {
++            tr.setCoords( w - r->x() - 1, h - r->y() - 1,
++                          w - r->right() - 1, h - r->bottom() - 1 );
++            trgn |= tr.normalize();
++          }
++          break;
++      default:
++          break;
++    }
++
++    return trgn;
++}
++
++/*!
++  0 = none
++  1..3 = rotates 90..270
++  4..7 = mirrored 0..3
++*/
++int QW100Screen::transformOrientation() const
++{
++    return (int)trans;
++}
++
++
++void qws_w100Transformation( int t )
++{
++    if ( qt_w100_screen ) {
++        qt_w100_screen->setTransformation( static_cast<QW100Screen::Transformation>( t ) );
++    }
 +}
 +
 +extern bool qws_accel;
diff --git a/packages/qte/qte-2.3.10/fix-linuxfb-offscreenoverflow.patch b/packages/qte/qte-2.3.10/fix-linuxfb-offscreenoverflow.patch
new file mode 100644 (file)
index 0000000..a604630
--- /dev/null
@@ -0,0 +1,22 @@
+Fix an overflow when the amount of requested cache memory
+is greater than the *lowest value
+Manuel Teira <manuel.teira@telefonica.net>
+
+#
+# Patch managed by http://www.holgerschurig.de/patcher.html
+#
+
+--- qt-2.3.10/src/kernel/qgfxlinuxfb_qws.cpp~fix-linuxfb-offscreenoverflow
++++ qt-2.3.10/src/kernel/qgfxlinuxfb_qws.cpp
+@@ -610,6 +610,11 @@
+     // No free blocks in already-taken memory; get some more
+     // if we can
++    if ( amount >= (*lowest ) ) {
++      //Avoid this overflow
++      qt_fbdpy->ungrab();
++      return 0;
++    }
+     unsigned int newlowest = (*lowest)-amount;
+     if (newlowest % align) {
+               newlowest -= align;
diff --git a/packages/qte/qte-2.3.10/fix-qscreen-sync.patch b/packages/qte/qte-2.3.10/fix-qscreen-sync.patch
new file mode 100644 (file)
index 0000000..47929ee
--- /dev/null
@@ -0,0 +1,17 @@
+Add a sync member to QScreen class
+Manuel Teira <manuel.teira@telefonica.net>
+
+#
+# Patch managed by http://www.holgerschurig.de/patcher.html
+#
+
+--- qt-2.3.10/src/kernel/qgfx_qws.h~fix-qscreen-sync
++++ qt-2.3.10/src/kernel/qgfx_qws.h
+@@ -191,6 +191,7 @@
+     virtual int pixmapOffsetAlignment() { return 64; }
+     virtual int pixmapLinestepAlignment() { return 64; }
++    virtual void sync() {}
+     virtual bool onCard(unsigned char *) const;
+     virtual bool onCard(unsigned char *, ulong& out_offset) const;
index 2d1025d..3e87b83 100644 (file)
@@ -7,7 +7,7 @@ DEPENDS = "zlib libpng jpeg tslib uicmoc-native"
 DEPENDS_mnci = "zlib libpng jpeg uicmoc-native"
 DEPENDS_append_c7x0 = " sharp-aticore-oss"
 PROVIDES = "virtual/qte virtual/libqte2"
-PR = "r19"
+PR = "r20"
 
 SRC_URI = "ftp://ftp.trolltech.com/pub/qt/source/qt-embedded-${PV}-free.tar.gz;md5=1f7ad30113afc500cab7f5b2f4dec0d7 \
           file://qpe.patch;patch=1 \
@@ -27,10 +27,12 @@ SRC_URI = "ftp://ftp.trolltech.com/pub/qt/source/qt-embedded-${PV}-free.tar.gz;m
           file://increase-qxml-robustness.patch;patch=1 \
           file://qte-fix-iconsize.patch;patch=1 \
           file://fix-linuxfb-setmode.patch;patch=1 \
+       file://fix-linuxfb-offscreenoverflow.patch;patch=1 \
+       file://fix-qscreen-sync.patch;patch=1 \
           file://sharp_char.h \
           file://key.patch;patch=1 \
           file://switches.h \
-           file://bidimetrics.patch;patch=5 "
+       file://bidimetrics.patch;patch=5 "
 
 SRC_URI_append_simpad          = "file://devfs.patch;patch=1 "
 SRC_URI_append_c7x0            = "file://kernel-keymap.patch;patch=1 file://kernel-keymap-corgi.patch;patch=1 file://c7x0-w100-accel.patch;patch=1 "