[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-core-devel
Subject:    Re: Kicker Xinerama support
From:       Kevin Puetz <puetzk () iastate ! edu>
Date:       2002-06-07 1:19:08
[Download RAW message or body]

Kevin Puetz wrote:

> Kevin Puetz wrote:
> 

> Ok, second cut, all the above bugs are corrected except the lack of
> kcontrol configuration. If nobody has any great suggestions, I'm just
> going to add a combobox to pick the screen number a panel is on, because I
> think trying to represent all the possible locations for Xinerama
> placement is just too messy. Better to just drag&drop if you want to see
> what you're getting.
> 
> I need to check this on non-Xinerama, and then I'm going to commit if I
> don't hear any objections.

Oops, I apparently made the diff before, rather than after, fixing a missing 
semicolon ;-) sorry folks, last time around
["kicker-xinerama.diff" (text/x-diff)]

? .snprj
? kicker.proj
? core/.container_panel.h.swp
Index: core/container_panel.cpp
===================================================================
RCS file: /home/kde/kdebase/kicker/core/container_panel.cpp,v
retrieving revision 1.57
diff -u -p -r1.57 container_panel.cpp
--- core/container_panel.cpp	2002/06/02 23:55:10	1.57
+++ core/container_panel.cpp	2002/06/07 01:17:36
@@ -78,11 +78,11 @@ PanelSettings::PanelSettings()
     _size              = Normal;
     _customSize        = 58;
 
-    // For now, we barely support xinerama.  Let's just stick to the U-L head and \
that's it. +    // Basic Xinerama support - position itself on the U-L head, along \
the bottom  if (QApplication::desktop()->isVirtualDesktop()) {
-        int screen = QApplication::desktop()->screenNumber(QPoint(0,0));
-        _sizePercentage = \
                100*QApplication::desktop()->screenGeometry(screen).width() / 
-                   QApplication::desktop()->width();
+        _xineramaScreen = QApplication::desktop()->screenNumber(QPoint(0,0));
+    } else {
+        _xineramaScreen = -1;
     }
 }
 
@@ -92,6 +92,7 @@ void PanelSettings::readConfig( KConfig 
                          c->readNumEntry(  "Position",               _position));
     _alignment         = static_cast<Alignment>(
                          c->readNumEntry(  "Alignment",              _alignment));
+    _xineramaScreen    = c->readNumEntry(  "XineramaScreen",         \
                _xineramaScreen);
     _HBwidth           = c->readNumEntry(  "HideButtonSize",         _HBwidth);
     _showLeftHB        = c->readBoolEntry( "ShowLeftHideButton",     _showLeftHB);
     _showRightHB       = c->readBoolEntry( "ShowRightHideButton",    _showRightHB);
@@ -130,6 +131,7 @@ void PanelSettings::readConfig( KConfig 
 void PanelSettings::writeConfig( KConfig *c ) {
     c->writeEntry( "Position", static_cast<int>(_position));
     c->writeEntry( "Alignment", static_cast<int>(_alignment));
+    c->writeEntry( "XineramaScreen",         _xineramaScreen);
     c->writeEntry( "HideButtonSize",         _HBwidth);
     c->writeEntry( "ShowLeftHideButton",     _showLeftHB);
     c->writeEntry( "ShowRightHideButton",    _showRightHB);
@@ -171,8 +173,8 @@ PanelContainer::PanelContainer(QWidget *
     setLineWidth( 0 );
     setMargin(0);
 
-    connect( UnhideTrigger::the(), SIGNAL(triggerUnhide(UnhideTrigger::Trigger)),
-             SLOT(unhideTriggered(UnhideTrigger::Trigger)) );
+    connect( UnhideTrigger::the(), \
SIGNAL(triggerUnhide(UnhideTrigger::Trigger,int)), +             \
SLOT(unhideTriggered(UnhideTrigger::Trigger,int)) );  
     _popupWidgetFilter = new PopupWidgetFilter( this );
     connect( _popupWidgetFilter, SIGNAL(popupWidgetHiding()), \
SLOT(maybeStartAutoHideTimer()) ); @@ -252,9 +254,9 @@ void \
PanelContainer::writeConfig( KConfi  _settings.writeConfig( config );
 }
 
-void PanelContainer::arrange( Position p, Alignment a )
+void PanelContainer::arrange( Position p, Alignment a, int XineramaScreen )
 {
-    if ( p == _settings._position && a == _settings._alignment )
+    if ( p == _settings._position && a == _settings._alignment && XineramaScreen == \
_settings._xineramaScreen)  return;
 
     if ( p != _settings._position ) {
@@ -267,6 +269,11 @@ void PanelContainer::arrange( Position p
 	emit alignmentChange( a );
     }
 
+   if( XineramaScreen != _settings._xineramaScreen ) {
+	_settings._xineramaScreen = XineramaScreen;
+	emit xineramaScreenChange( XineramaScreen );
+    }
+
     updateLayout();
     writeConfig();
 }
@@ -334,7 +341,7 @@ void PanelContainer::hideRight()
 
 void PanelContainer::resetLayout()
 {
-    QRect g = initialGeometry( position(), alignment(), autoHidden(), userHidden() \
); +    QRect g = initialGeometry( position(), alignment(), xineramaScreen(), \
autoHidden(), userHidden() );  
     setGeometry( g );
 
@@ -448,7 +455,7 @@ void PanelContainer::blockUserInput( boo
 // are printed! WTF?! This happens if you drag an applet handle outside
 // the panel and wait for the timeout. I am completely mystified
 // by this.
-void PanelContainer::unhideTriggered( UnhideTrigger::Trigger tr )
+void PanelContainer::unhideTriggered( UnhideTrigger::Trigger tr, int XineramaScreen \
)  {
     if( _settings._hideMode == PanelSettings::Manual )
 	return;
@@ -468,6 +475,9 @@ void PanelContainer::unhideTriggered( Un
     if( !_autoHidden )
 	return;
 
+    if(XineramaScreen != _settings._xineramaScreen)
+	return;
+    
     int x = QCursor::pos().x();
     int y = QCursor::pos().y();
     int t = geometry().top();
@@ -648,9 +658,9 @@ bool PanelContainer::eventFilter( QObjec
     return false;
 }
 
-QSize PanelContainer::initialSize( Position p )
+QSize PanelContainer::initialSize( Position p, int XineramaScreen )
 {
-    QRect a = workArea();
+    QRect a = workArea(XineramaScreen);
 
 //    kdDebug(1210) << "     Work Area: (" << a.topLeft().x() << ", " << \
a.topLeft().y() << ") to ("  //                                 << \
a.bottomRight().x() << ", " << a.bottomRight().y() << ")" << endl; @@ -678,9 +688,9 \
@@ QSize PanelContainer::initialSize( Posit  return QSize( width, height );
 }
 
-QPoint PanelContainer::initialLocation( Position p, Alignment a, QSize s, bool \
autohidden, UserHidden userHidden ) +QPoint PanelContainer::initialLocation( Position \
p, Alignment a, int XineramaScreen, QSize s, bool autohidden, UserHidden userHidden ) \
                {
-    QRect area = workArea();
+    QRect area = workArea(XineramaScreen);
 
     int left;
     int top;
@@ -784,16 +794,15 @@ QPoint PanelContainer::initialLocation( 
 	    break;
 	}
     }
-
     return QPoint( left, top );
 }
 
-QRect PanelContainer::initialGeometry( Position p, Alignment a, bool autoHidden, \
UserHidden userHidden ) +QRect PanelContainer::initialGeometry( Position p, Alignment \
a, int XineramaScreen, bool autoHidden, UserHidden userHidden )  {
 //    kdDebug(1210) << "   Computing geometry for " << name() << endl;
 
-    QSize size = initialSize( p );
-    QPoint point = initialLocation( p, a, size, autoHidden, userHidden );
+    QSize size = initialSize( p, XineramaScreen );
+    QPoint point = initialLocation( p, a, XineramaScreen, size, autoHidden, \
userHidden );  
 //    kdDebug(1210) << "     Size: " << size.width() << " x " << size.height() << \
endl;  //    kdDebug(1210) << "     Pos: (" << point.x() << ", " << point.y() << ")" \
<< endl; @@ -811,7 +820,7 @@ void PanelContainer::updateLayout()
 void PanelContainer::strutChanged()
 {
 //    kdDebug(1210) << "PanelContainer::strutChanged()" << endl;
-    if ( initialGeometry( position(), alignment(), autoHidden(), userHidden() ) != \
geometry() ) { +    if ( initialGeometry( position(), alignment(), xineramaScreen(), \
autoHidden(), userHidden() ) != geometry() ) {  updateLayout();
     }
 }
@@ -825,18 +834,30 @@ void PanelContainer::updateWindowManager
 
     QRect r(QApplication::desktop()->geometry());
 
-    QRect geom = initialGeometry( position(), alignment() );
+    QRect geom = initialGeometry( position(), alignment(), xineramaScreen() );
 
     if( userHidden() || _settings._hideMode != PanelSettings::Manual )
 	w = h = 0;
 
     // only call KWin::setStrut when the strut is really changed
+
+    //FIXME do not set the strut if we are not actually along the edge of the \
virtual screen, since +    //NETWM has no way to represent the resulting \
non-rectangular client areas that result in +    //an Xinerama environment. Remove \
these checks once NetWM is smarter  NETStrut strut;
     switch (position()) {
-    case ::Top:     strut.top = geom.y() + h; break;
-    case ::Bottom:  strut.bottom = (r.bottom() - geom.y() - height()) + h + 1; \
                break;
-    case ::Right:   strut.right = (r.right() - geom.x() - width()) + w + 1; break;
-    case ::Left:    strut.left = geom.x() + w; break;
+      case ::Top:     if(geom.top() == r.top()) 
+			strut.top = geom.y() + h;
+		      break;
+      case ::Bottom:  if(geom.bottom() == r.bottom())
+			strut.bottom = (r.bottom() - geom.bottom()) + h + 1;
+		      break;
+      case ::Right:   if(geom.right() == r.right())
+			strut.right = (r.right() - geom.right()) + w + 1;
+		      break;
+      case ::Left:    if(geom.left() == r.left())
+			strut.left = geom.x() + w;
+		      break;
     }
 
     if ( strut.left   != _strut.left  ||
@@ -847,12 +868,7 @@ void PanelContainer::updateWindowManager
 	_strut = strut;
 //	kdDebug(1210) << "Panel sets new strut: " << position() << endl;
 //	kdDebug(1210) << strut.top << " " << strut.bottom << " " << strut.right << " " << \
                strut.left << endl;
-	switch (position()) {
-	case ::Top:     KWin::setStrut( winId(), 0, 0,  strut.top, 0 ); break;
-	case ::Bottom:  KWin::setStrut( winId(), 0, 0, 0, strut.bottom); break;
-	case ::Right:   KWin::setStrut( winId(), 0, strut.right, 0, 0 ); break;
-	case ::Left:    KWin::setStrut( winId(), strut.left, 0, 0, 0 ); break;
-	}
+	KWin::setStrut( winId(), strut.left, strut.right,  strut.top, strut.bottom );
     }
 }
 
@@ -893,14 +909,28 @@ void PanelContainer::animatedHide(bool l
     if( _userHidden != Unhidden )
         newState = Unhidden;
     else if( left )
-        newState = LeftTop;
+	newState = LeftTop;
     else
         newState = RightBottom;
 
     QPoint oldpos = pos();
-    QPoint newpos = initialGeometry( position(), alignment(), false, newState \
).topLeft(); +    QRect newextent = initialGeometry( position(), alignment(), \
xineramaScreen(), false, newState ); +    QPoint newpos(newextent.topLeft());
 
     if( newState != Unhidden ) {
+	/* bail out if we are unable to hide */
+	for(int s=0; s <  QApplication::desktop()->numScreens(); s++) {
+	    /* don't let it intersect with any screen in the hidden position 
+	     * that it doesn't intesect in the shown position. Should prevent 
+	     * panels from hiding by sliding onto other screens, while still 
+	     * letting them show reveal buttons onscreen */
+	    if(QApplication::desktop()->screenGeometry(s).intersects(newextent) 
+	    && !QApplication::desktop()->screenGeometry(s).intersects(geometry())) {
+		blockUserInput( false );
+		return;
+	    }
+	}
+
 	_userHidden = newState;
 
 	// So we don't cover the mac-style menubar
@@ -970,6 +1000,28 @@ void PanelContainer::autoHide(bool hide)
 
 //    kdDebug(1210) << "entering autohide for real" << endl;
 
+    blockUserInput(true);
+
+    QPoint oldpos = pos();
+    QRect newextent = initialGeometry( position(), alignment(), xineramaScreen(), \
hide, Unhidden ); +    QPoint newpos = newextent.topLeft();
+
+    if ( hide ) {
+	/* bail out if we are unable to hide */
+	
+	for(int s=0; s <  QApplication::desktop()->numScreens(); s++) {
+ 	    /* don't let it intersect with any screen in the hidden position 
+	     * that it doesn't intesect in the shown position. Should prevent 
+	     * panels from hiding by sliding onto other screens, while still 
+	     * letting them show reveal buttons onscreen */
+	    if(QApplication::desktop()->screenGeometry(s).intersects(newextent) 
+	    && !QApplication::desktop()->screenGeometry(s).intersects(geometry())) {
+		blockUserInput( false );
+		return;
+	    }
+	}
+
+    }
     _in_autohide = true;
 
     PanelButtonBase::setZoomEnabled(false);
@@ -977,11 +1029,6 @@ void PanelContainer::autoHide(bool hide)
     _autoHidden = hide;
     UnhideTrigger::the()->setEnabled( _autoHidden );
 
-    blockUserInput(true);
-
-    QPoint oldpos = pos();
-    QPoint newpos = initialGeometry( position(), alignment(), hide, Unhidden \
                ).topLeft();
-
     if( hide ) {
 	// So we don't cover other panels
 	lower();
@@ -1048,18 +1095,19 @@ void PanelContainer::moveMe()
 
     Position  positions[]  = { ::Left, ::Right, ::Top, ::Bottom };
     Alignment alignments[] = { ::LeftTop, ::Center, ::RightBottom };
-    for( int i = 0; i < 4; i++ ) {
-        for( int j = 0; j < 3; j++ ) {
-            rects.append( initialGeometry( positions[i], alignments[j] ) );
+    for(int s = 0; s < QApplication::desktop()->numScreens(); s++) {
+        for( int i = 0; i < 4; i++ ) {
+            for( int j = 0; j < 3; j++ ) {
+                rects.append( initialGeometry( positions[i], alignments[j], s ) );
+            }
         }
     }
 
     int rect = UserRectSel::select(rects, position());
-    Position p = (Position)(rect / 3);
+    int XineramaScreen = rect / 12;
+    Position p = (Position)((rect / 3) % 4);
     Alignment a = (Alignment)(rect % 3);
-    setPosition( p );
-    setAlignment( a );
-    updateLayout();
+    arrange(p, a, XineramaScreen);
 
     _is_lmb_down = false;
 
@@ -1070,7 +1118,7 @@ void PanelContainer::moveMe()
     maybeStartAutoHideTimer();
 }
 
-QRect PanelContainer::workArea()
+QRect PanelContainer::workArea(int XineramaScreen)
 {
     QValueList<WId> list;
 
@@ -1087,7 +1135,10 @@ QRect PanelContainer::workArea()
 	list.append((*it)->winId());
     }
 
-    return kWinModule->workArea(list);
+    if(XineramaScreen < 0 || XineramaScreen >= \
QApplication::desktop()->numScreens()) +      /* force invalid screen locations onto \
the primary screen */ +      XineramaScreen = \
QApplication::desktop()->primaryScreen(); +    return \
kWinModule->workArea(list).intersect(QApplication::desktop()->screenGeometry(XineramaScreen));
  }
 
 PopupWidgetFilter::PopupWidgetFilter( QObject *parent )
Index: core/container_panel.h
===================================================================
RCS file: /home/kde/kdebase/kicker/core/container_panel.h,v
retrieving revision 1.26
diff -u -p -r1.26 container_panel.h
--- core/container_panel.h	2002/06/02 23:55:10	1.26
+++ core/container_panel.h	2002/06/07 01:17:36
@@ -51,6 +51,7 @@ public:
     // Configuration settings
     Position  _position;
     Alignment _alignment;
+		int       _xineramaScreen;
     int       _HBwidth;
     bool      _showLeftHB;
     bool      _showRightHB;
@@ -76,17 +77,20 @@ public:
     virtual ~PanelContainer();
 
     Position position() const { return _settings._position; }
-    void setPosition(Position p) { arrange( p, alignment() ); }
+    void setPosition(Position p) { arrange( p, alignment(), xineramaScreen() ); }
 
+    int xineramaScreen() const { return _settings._xineramaScreen; }
+    void setXineramaScreen(int screen) { arrange(position(),alignment(), screen); }
+
     virtual void setSize(Size size, int customSize = 0);
     Size size() const;
     int customSize() const;
 
     Alignment alignment() const { return _settings._alignment; }
-    void setAlignment(Alignment a) { arrange( position(), a ); }
+    void setAlignment(Alignment a) { arrange( position(), a, xineramaScreen() ); }
 
     enum UserHidden{ Unhidden, LeftTop, RightBottom };
-    QRect initialGeometry( Position p, Alignment a, bool autoHidden = false, \
UserHidden userHidden = Unhidden ); +    QRect initialGeometry( Position p, Alignment \
a, int XineramaScreen, bool autoHidden = false, UserHidden userHidden = Unhidden );  
     virtual QSize sizeHint( Position p, QSize maxSize );
     bool eventFilter( QObject *, QEvent * );
@@ -101,10 +105,11 @@ public:
 signals:
     void positionChange( Position pos );
     void alignmentChange( Alignment a );
+    void xineramaScreenChange ( int XineramaScreen );
     void sizeChange( int size, int customSize );
 
 protected:
-    void arrange( Position p, Alignment a );
+    void arrange( Position p, Alignment a, int XineramaScreen );
     void setMainWidget( QWidget* widget );
     virtual PanelSettings defaultSettings();
     bool autoHidden() const { return _autoHidden; };
@@ -112,7 +117,7 @@ protected:
     Orientation orientation() const;
     virtual void resetLayout();
     virtual bool vetoAutoHide() { return false; }
-    QRect workArea();
+    QRect workArea(int XineramaScreen);
 
     static KWinModule* kWinModule;
 
@@ -123,7 +128,7 @@ protected slots:
     void enableZoomedIcons();
 
 private slots:
-    void unhideTriggered( UnhideTrigger::Trigger t );
+    void unhideTriggered( UnhideTrigger::Trigger t, int XineramaScreen );
     void autoHideTimeout();
     void hideLeft();
     void hideRight();
@@ -137,8 +142,8 @@ private slots:
     void stopAutoHideTimer();
 
 private:
-    QSize initialSize( Position p );
-    QPoint initialLocation( Position p, Alignment a, QSize s,
+    QSize initialSize( Position p, int XineramaScreen );
+    QPoint initialLocation( Position p, Alignment a, int XineramaScreen, QSize s,
          bool autohidden = false, UserHidden userHidden = Unhidden );
 
     PanelSettings    _settings;
Index: core/containerarea.cpp
===================================================================
RCS file: /home/kde/kdebase/kicker/core/containerarea.cpp,v
retrieving revision 1.122
diff -u -p -r1.122 containerarea.cpp
--- core/containerarea.cpp	2002/05/26 22:47:06	1.122
+++ core/containerarea.cpp	2002/06/07 01:17:37
@@ -114,7 +114,7 @@ void ContainerArea::defaultContainerConf
     containers.append( new KMenuButtonContainer( viewport() ) );
     containers.append( new DesktopButtonContainer( viewport() ) );
 
-    QRect r = panel->initialGeometry( panel->position(), panel->alignment() );
+    QRect r = panel->initialGeometry( panel->position(), panel->alignment(), \
panel->xineramaScreen() );  
     int dsize;
     if (orientation() == Horizontal)
Index: core/unhidetrigger.cpp
===================================================================
RCS file: /home/kde/kdebase/kicker/core/unhidetrigger.cpp,v
retrieving revision 1.1
diff -u -p -r1.1 unhidetrigger.cpp
--- core/unhidetrigger.cpp	2002/02/27 13:31:49	1.1
+++ core/unhidetrigger.cpp	2002/06/07 01:17:37
@@ -36,6 +36,7 @@ UnhideTrigger* UnhideTrigger::the()
 
 UnhideTrigger::UnhideTrigger()
 	: _lastTrigger( None )
+	, _lastXineramaScreen( -1 )
 	, enabledCount( 0 )
 {
 	_timer = new QTimer( this );
@@ -64,37 +65,42 @@ bool UnhideTrigger::isEnabled() const
 void UnhideTrigger::pollMouse()
 {
 	QPoint pos = QCursor::pos();
-	QRect r = QApplication::desktop()->geometry();
-	if( pos.x() == 0 ) {
-		if( pos.y() == 0 ) {
-			emitTrigger( TopLeft );
+	for(int s = 0; s < QApplication::desktop()->numScreens(); s++)
+	{
+		QRect r = QApplication::desktop()->screenGeometry(s);
+		if( pos.x() == r.left() ) {
+			if( pos.y() == r.top() ) {
+				emitTrigger( TopLeft, s );
+			} else if( pos.y() == r.bottom() ) {
+				emitTrigger( BottomLeft, s );
+			} else {
+				emitTrigger( Left, s );
+			}
+		} else if( pos.x() == r.right() ) {
+			if( pos.y() == r.top() ) {
+				emitTrigger( TopRight, s );
+			} else if( pos.y() == r.bottom() ) {
+				emitTrigger( BottomRight ,s );
+			} else {
+				emitTrigger( Right, s );
+			}
+		} else if( pos.y() == r.top() ) {
+			emitTrigger( Top, s );
 		} else if( pos.y() == r.bottom() ) {
-			emitTrigger( BottomLeft );
+			emitTrigger( Bottom, s );
 		} else {
-			emitTrigger( Left );
+			_lastTrigger = None;
+			_lastXineramaScreen = -1;
 		}
-	} else if( pos.x() == r.right() ) {
-		if( pos.y() == 0 ) {
-			emitTrigger( TopRight );
-		} else if( pos.y() == r.bottom() ) {
-			emitTrigger( BottomRight );
-		} else {
-			emitTrigger( Right );
-		}
-	} else if( pos.y() == 0 ) {
-		emitTrigger( Top );
-	} else if( pos.y() == r.bottom() ) {
-		emitTrigger( Bottom );
-	} else {
-		_lastTrigger = None;
 	}
 }
 
-void UnhideTrigger::emitTrigger( Trigger t )
+void UnhideTrigger::emitTrigger( Trigger t, int XineramaScreen )
 {
-	if( _lastTrigger == t )
+	if( _lastTrigger == t  && _lastXineramaScreen == XineramaScreen)
 		return;
 
 	_lastTrigger = t;
-	emit triggerUnhide( t );
+	_lastXineramaScreen = XineramaScreen;
+	emit triggerUnhide( t, XineramaScreen );
 }
Index: core/unhidetrigger.h
===================================================================
RCS file: /home/kde/kdebase/kicker/core/unhidetrigger.h,v
retrieving revision 1.1
diff -u -p -r1.1 unhidetrigger.h
--- core/unhidetrigger.h	2002/02/27 13:31:49	1.1
+++ core/unhidetrigger.h	2002/06/07 01:17:37
@@ -42,13 +42,14 @@ public:
 	bool isEnabled() const;
 
 signals:
-	void triggerUnhide( UnhideTrigger::Trigger t );
+	void triggerUnhide( UnhideTrigger::Trigger t, int XineramaScreen );
 private slots:
 	void pollMouse();
 private:
 	UnhideTrigger();
-	void emitTrigger( Trigger t );
+	void emitTrigger( Trigger t , int XineramaScreen);
 	Trigger _lastTrigger;
+	int _lastXineramaScreen;
 	QTimer *_timer;
 	int enabledCount;
 };
Index: core/userrectsel.cpp
===================================================================
RCS file: /home/kde/kdebase/kicker/core/userrectsel.cpp,v
retrieving revision 1.2
diff -u -p -r1.2 userrectsel.cpp
--- core/userrectsel.cpp	2002/03/16 06:11:32	1.2
+++ core/userrectsel.cpp	2002/06/07 01:17:37
@@ -66,8 +66,6 @@ void UserRectSel::mouseMoveEvent( QMouse
 	QRect r( rectangles[i] );
 	int ndiff = (r.center().x() - e->globalPos().x() ) *  (r.center().x() - \
                e->globalPos().x() )
       +  (r.center().y() - e->globalPos().y() ) *  (r.center().y() - \
                e->globalPos().y() );
-	if ( r.contains( e->globalPos() ) )
-      ndiff = 0;
 	if ( diff < 0 || ndiff < diff ) {
       diff = ndiff;
       nearest = i;



[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic