[Kwintv] [PATCH] Removes screen lint

John Ryland kwintv@mail.kde.org
Wed, 04 Dec 2002 04:55:34 +1000


This is a multi-part message in MIME format.

------=_NextPart_000_5623_3453_1427
Content-Type: text/plain; format=flowed


Hi,

This patch fixes problems I get with moving and resizing the window and it 
leaving corrupted areas on my desktop. I tested and fixed for the 
wintvscreen_v4l.cpp case as I currently don't have Xv working but will set 
that up shortly so I can try that out too.

What the patch does is to immediately provoke X11 to repaint just the areas 
that need erasing. It also gets Qt to repaint the areas of the top level 
widget which need repainting also. I think it does this fairly smartly now 
so it is repainting exactly what needs repainting.

I now nolonger can ever get the program to leave behind any pixels on my 
desktop and other programs when I vigourously move or resize it's window. It 
still isn't quite there yet as when you move other windows across in front 
of it, the screen easily corrupts. Do other people get that problem too?

Regards
John


_________________________________________________________________
The new MSN 8: smart spam protection and 2 months FREE*  
http://join.msn.com/?page=features/junkmail

------=_NextPart_000_5623_3453_1427
Content-Type: text/plain; name="screenlint.patch"; format=flowed
Content-Transfer-Encoding: 8bit
Content-Disposition: attachment; filename="screenlint.patch"

Index: rcfile.cpp
===================================================================
RCS file: /home/kde/kdenonbeta/kwintv/kwintv/rcfile.cpp,v
retrieving revision 1.6
diff -u -3 -p -r1.6 rcfile.cpp
--- rcfile.cpp	6 May 2002 21:12:20 -0000	1.6
+++ rcfile.cpp	3 Dec 2002 18:22:38 -0000
@@ -167,7 +167,7 @@ int rcfile::load()
	// Better not open up a dialog box here... Inform the user only
	// on the console about what's happening. Otherwise we risk a crash!
	// KMessageBox::information(NULL, i18n("Old channel files found.\nCopying 
them to share/apps/kwintv.\nYou can remove them from %1 
after.").arg(tmpdataDir), i18n("KWinTV"));
-	fprintf( stderr, "%s", i18n("Old channel files found.\nCopying them to 
share/apps/kwintv.\nYou can remove them from %1 
after.\n").arg(tmpdataDir).local8Bit() );
+	fprintf( stderr, "%s", (const char *)i18n("Old channel files 
found.\nCopying them to share/apps/kwintv.\nYou can remove them from %1 
after.\n").arg(tmpdataDir).local8Bit() );
	KShellProcess ksp;
	ksp << "cp" << QString(tmpdataDir+"/*") << dataDir;
	ksp.start(KProcess::Block);
Index: v4lxif.h
===================================================================
RCS file: /home/kde/kdenonbeta/kwintv/kwintv/v4lxif.h,v
retrieving revision 1.4
diff -u -3 -p -r1.4 v4lxif.h
--- v4lxif.h	1 Mar 2002 08:18:30 -0000	1.4
+++ v4lxif.h	3 Dec 2002 18:22:38 -0000
@@ -33,9 +33,6 @@

#define MAXCLIPRECS 100

-const bool on  = true;
-const bool off = false;
-
struct STRTAB {
     int  nr;
     const char *str;
Index: wintvscreen_v4l.cpp
===================================================================
RCS file: /home/kde/kdenonbeta/kwintv/kwintv/wintvscreen_v4l.cpp,v
retrieving revision 1.11
diff -u -3 -p -r1.11 wintvscreen_v4l.cpp
--- wintvscreen_v4l.cpp	14 May 2002 22:10:02 -0000	1.11
+++ wintvscreen_v4l.cpp	3 Dec 2002 18:22:39 -0000
@@ -103,7 +102,7 @@ WinTVScreen_v4l::WinTVScreen_v4l( QWidge
     if (!v4lx)
       v4lx = new v4l1if( devname, _bpp, _palette );

-    v4lx->setCapture( off );
+    v4lx->setCapture( false );

     // use my XErrorHandler
     oldXErrorHandler = XSetErrorHandler((XErrorHandler) xerror);
@@ -360,12 +359,10 @@ void WinTVScreen_v4l::switch_capture(int
{
//kdDebug() << "screen: switch_capture from " << captureIsOn << " to " << on 
<< endl;
   if (on && captureIsOn) {
-    if ( isVisible() ) {
-      v4lx->setCapture( on );
-      captureIsOn = true;
-    }
+    if ( isVisible() )
+      v4lx->setCapture( true );
   } else {
-    v4lx->setCapture( off );
+    v4lx->setCapture( false );
   }
}

@@ -375,13 +372,10 @@ void WinTVScreen_v4l::capture(int on)
{
//kdDebug() << "screen: capture from " << captureIsOn << " to " << on << 
endl;
   if (isVisible()) {
-    if (on) {
-      captureIsOn = true;
+    if (on)
       newTVGeometry( false );
-    } else {
-      captureIsOn = false;
-    }
-    v4lx->setCapture( captureIsOn );
+    v4lx->setCapture( on );
+    captureIsOn = on;
   }
}

@@ -485,92 +479,94 @@ void WinTVScreen_v4l::destroyTV()

//==============================================================================

+static void provokeX11Repaint( const QRect& r )
+{
+  int scr;
+  XSetWindowAttributes xswa;
+  unsigned long mask;
+  Window rwin,rootW;
+  Display *disp;
+  disp = qt_xdisplay();
+  scr = DefaultScreen(disp);
+  rootW = RootWindow(disp, scr);
+  xswa.override_redirect = true;
+  xswa.backing_store = NotUseful;
+  xswa.save_under = false;
+  mask = ( CWSaveUnder | CWBackingStore | CWOverrideRedirect );
+  rwin = XCreateWindow( disp, rootW, r.x(), r.y(), r.width() + 1, 
r.height() + 1, 0,
+	      CopyFromParent, InputOutput, CopyFromParent, mask, &xswa);
+  XMapWindow(disp, rwin);
+  XUnmapWindow(disp, rwin);
+  XDestroyWindow(disp, rwin);
+}
+
void WinTVScreen_v4l::newTVGeometry( bool doViewRefresh )
{
-  bool checkClipping;
   unsigned int view_width, view_height;
-  int xp, yp, oldx, oldy, dx = 0, dy = 0;
+  int newx, newy, oldx, oldy;
   unsigned int neww, newh, oldw, oldh;

   if (!isVisible()) return;

   v4lx->getCapAClip( &oldx, &oldy, &oldw, &oldh );
-#ifdef CLIPDEBUG
-  debug("CLIP: newTVGeometry values getCapAClip %d %d %d 
%d",oldx,oldy,oldw,oldh);
-#endif
-
-  checkClipping = false;
-  didViewMove = false;

   // get new geometry values, need the global position
   QPoint p = mapToGlobal(QPoint(0,0));
-  view_height = geometry().height();
   view_width = geometry().width();
+  view_height = geometry().height();

-  xp = p.x() & ~3;
-  yp = p.y() & ~3;
-
-/*
-  kdDebug() << "Height: " << view_height
-            << " Width: " << view_width
-            << " x(): " << p.x()
-            << " y(): " << p.y()
-            << endl;
-*/
+  newx = p.x() & ~3;
+  newy = p.y() & ~3;

-  // checkClipping if size changed
   // set a new width
   if (view_width > max_width) {
-    dx = (view_width - max_width)/2;
+    newx += (view_width - max_width)/2;
     neww = max_width & ~3;
   } else {
     neww = view_width & ~3;
   }

-  if (oldw != neww) checkClipping = true;
-
-  if (oldw > neww) didViewMove = true;
-
   // set a new height
   if (view_height > max_height) {
-    dy = (view_height - max_height)/2;
+    newy += (view_height - max_height)/2;
     newh = max_height & ~3;
   } else {
     newh = view_height & ~3;
   }

-  if (oldh != newh) checkClipping = true;
-
-  if (oldh > newh) didViewMove = true;
-
-  if ( (p.x() & ~3) < p.x() ) {
-    xp += 4;
+  if ( newx % 4 ) {
+    newx += 4;
     neww -= 4;
-#ifdef CLIPDEBUG
-    debug("CLIP: xp, neww");
-#endif
   }

-  if ( (p.y() & ~3) < p.y() ) {
-    yp += 4;
+  if ( newy % 4 ) {
+    newy += 4;
     newh -= 4;
-#ifdef CLIPDEBUG
-    debug("CLIP: yp, newh");
-#endif
   }

-  // checkClipping if position changed
-  if (oldx != xp+dx) {
-    didViewMove = true;
-    checkClipping = true;
-  } else if (oldy != yp+dy) {
-    didViewMove = true;
-    checkClipping = true;
-  }
+  if ( captureIsOn && ( oldx != newx || oldy != newy || oldw != neww || 
oldh != newh ) ) {
+    setTVClipTab( getTVClipTab( true, newx, newy, neww, newh ) );
+
+    configOverlay();
+    didViewRefresh = true;

-  if (checkClipping && captureIsOn) {
-    setTVClipTab(getTVClipTab(true,xp+dx,yp+dy,neww,newh)); 
//,(xp+dx)-oldx,(yp+dy)-oldy)
-    if ( allowViewRefresh && doViewRefresh ) refreshTV();
+    // refresh the part of the old region which is not a part of the new 
region
+    QRegion oldRegion( QRect( oldx, oldy, oldw + 5, oldh + 5 ) );
+    oldRegion -= QRect( newx, newy, neww, newh );
+
+    QRegion x11InvalidRegions = oldRegion;//.subtract( 
topLevelWidget()->geometry() );
+    // iterate over the sub-rectangles which make up the regions to 
invalidate with X11
+    for ( int i = 0; i < x11InvalidRegions.rects().count(); i++ )
+      provokeX11Repaint( x11InvalidRegions.rects()[i] );
+
+    // refresh the part of the old region which is not a part of the new 
region
+    // and which intersects with the top level widget to this widget
+    QRegion qtInvalidRegions = oldRegion.intersect( 
topLevelWidget()->geometry() );
+    // iterate over the sub-rectangles which make up the regions to 
invalidate with Qt with itself
+    for ( int i = 0; i < qtInvalidRegions.rects().count(); i++ ) {
+      QRect r = qtInvalidRegions.rects()[i];
+      topLevelWidget()->repaint( QRect( topLevelWidget()->mapFromGlobal( 
r.topLeft() ), r.size() ) );
+    }
   }

}


------=_NextPart_000_5623_3453_1427--