kwin Library API Documentation

geometry.cpp

00001 /*****************************************************************
00002  KWin - the KDE window manager
00003  This file is part of the KDE project.
00004 
00005 Copyright (C) 1999, 2000 Matthias Ettrich <ettrich@kde.org>
00006 Copyright (C) 2003 Lubos Lunak <l.lunak@kde.org>
00007 
00008 You can Freely distribute this program under the GNU General Public
00009 License. See the file "COPYING" for the exact licensing terms.
00010 ******************************************************************/
00011 
00012 /*
00013 
00014  This file contains things relevant to geometry, i.e. workspace size,
00015  window positions and window sizes.
00016 
00017 */
00018 
00019 #include "client.h"
00020 #include "workspace.h"
00021 
00022 #include <kapplication.h>
00023 #include <kglobal.h>
00024 #include <qpainter.h>
00025 #include <kwin.h>
00026 
00027 #include "placement.h"
00028 #include "notifications.h"
00029 #include "geometrytip.h"
00030 #include "rules.h"
00031 
00032 extern Time qt_x_time;
00033 
00034 namespace KWinInternal
00035 {
00036 
00037 //********************************************
00038 // Workspace
00039 //********************************************
00040 
00044 void Workspace::desktopResized()
00045     {
00046     updateClientArea();
00047     checkElectricBorders( true );
00048     }
00049 
00062 void Workspace::updateClientArea( bool force )
00063     {
00064     QDesktopWidget *desktopwidget = KApplication::desktop();
00065     int nscreens = desktopwidget -> numScreens ();
00066 //    kdDebug () << "screens: " << nscreens << endl;
00067     QRect* new_wareas = new QRect[ numberOfDesktops() + 1 ];
00068     QRect** new_sareas = new QRect*[ numberOfDesktops() + 1];
00069     QRect* screens = new QRect [ nscreens ];
00070     QRect desktopArea = desktopwidget -> geometry ();
00071     for( int iS = 0;
00072             iS < nscreens;
00073             iS ++ )
00074         {
00075             screens [iS] = desktopwidget -> screenGeometry (iS);
00076         }
00077     for( int i = 1;
00078             i <= numberOfDesktops();
00079             ++i )
00080         {
00081             new_wareas[ i ] = desktopArea;
00082             new_sareas[ i ] = new QRect [ nscreens ];
00083             for( int iS = 0;
00084                     iS < nscreens;
00085                     iS ++ )
00086                 new_sareas[ i ][ iS ] = screens[ iS ];
00087         }
00088     for ( ClientList::ConstIterator it = clients.begin(); it != clients.end(); ++it)
00089         {
00090             QRect r = (*it)->adjustedClientArea( desktopArea, desktopArea );
00091             if( r == desktopArea ) // should be sufficient
00092                 continue;
00093             if( (*it)->isOnAllDesktops())
00094                 for( int i = 1;
00095                         i <= numberOfDesktops();
00096                         ++i )
00097                     {
00098                         new_wareas[ i ] = new_wareas[ i ].intersect( r );
00099                         for( int iS = 0;
00100                                 iS < nscreens;
00101                                 iS ++ )
00102                             new_sareas[ i ][ iS ] =
00103                                 new_sareas[ i ][ iS ].intersect(
00104                                         (*it)->adjustedClientArea( desktopArea, screens[ iS ] )
00105                                     );
00106                     }
00107             else
00108                 {
00109                     new_wareas[ (*it)->desktop() ] = new_wareas[ (*it)->desktop() ].intersect( r );
00110                     for( int iS = 0;
00111                             iS < nscreens;
00112                             iS ++ )
00113                         {
00114 //                            kdDebug () << "adjusting new_sarea: " << screens[ iS ] << endl;
00115                             new_sareas[ (*it)->desktop() ][ iS ] =
00116                                 new_sareas[ (*it)->desktop() ][ iS ].intersect(
00117                                         (*it)->adjustedClientArea( desktopArea, screens[ iS ] )
00118                                         );
00119                         }
00120                 }
00121         }
00122 #if 0
00123     for( int i = 1;
00124             i <= numberOfDesktops();
00125             ++i )
00126         {
00127             for( int iS = 0;
00128                     iS < nscreens;
00129                     iS ++ )
00130                 kdDebug () << "new_sarea: " << new_sareas[ i ][ iS ] << endl;
00131         }
00132 #endif
00133     // TODO topmenu update for screenarea changes?
00134     if( topmenu_space != NULL )
00135         {
00136         QRect topmenu_area = desktopArea;
00137         topmenu_area.setTop( topMenuHeight());
00138         for( int i = 1;
00139              i <= numberOfDesktops();
00140              ++i )
00141             new_wareas[ i ] = new_wareas[ i ].intersect( topmenu_area );
00142         }
00143 
00144     bool changed = force;
00145 
00146     if (! screenarea)
00147         changed = true;
00148 
00149     for( int i = 1;
00150          !changed && i <= numberOfDesktops();
00151          ++i )
00152         {
00153             if( workarea[ i ] != new_wareas[ i ] )
00154                 changed = true;
00155             for( int iS = 0;
00156                     iS < nscreens;
00157                     iS ++ )
00158                 if (new_sareas[ i ][ iS ] != screenarea [ i ][ iS ])
00159                     changed = true;
00160         }
00161 
00162     if ( changed )
00163         {
00164         delete[] workarea;
00165         workarea = new_wareas;
00166         new_wareas = NULL;
00167         delete[] screenarea;
00168         screenarea = new_sareas;
00169         new_sareas = NULL;
00170         NETRect r;
00171         for( int i = 1; i <= numberOfDesktops(); i++)
00172             {
00173             r.pos.x = workarea[ i ].x();
00174             r.pos.y = workarea[ i ].y();
00175             r.size.width = workarea[ i ].width();
00176             r.size.height = workarea[ i ].height();
00177             rootInfo->setWorkArea( i, r );
00178             }
00179 
00180         updateTopMenuGeometry();
00181         for( ClientList::ConstIterator it = clients.begin();
00182              it != clients.end();
00183              ++it)
00184             (*it)->checkWorkspacePosition();
00185         }
00186     delete[] screens;
00187     delete[] new_sareas;
00188     delete[] new_wareas;
00189     }
00190 
00191 void Workspace::updateClientArea()
00192     {
00193     updateClientArea( false );
00194     }
00195 
00196 
00204 QRect Workspace::clientArea( clientAreaOption opt, const QPoint& p, int desktop ) const
00205     {
00206     if( desktop == NETWinInfo::OnAllDesktops || desktop == 0 )
00207         desktop = currentDesktop();
00208     QDesktopWidget *desktopwidget = KApplication::desktop();
00209     int screen = desktopwidget->screenNumber( p );
00210     if( screen < 0 )
00211         screen = desktopwidget->primaryScreen();
00212     QRect sarea = screenarea // may be NULL during KWin initialization
00213         ? screenarea[ desktop ][ screen ]
00214         : desktopwidget->screenGeometry( screen );
00215     QRect warea = workarea[ desktop ].isNull()
00216         ? QApplication::desktop()->geometry()
00217         : workarea[ desktop ];
00218     switch (opt)
00219         {
00220         case MaximizeArea:
00221             if (options->xineramaMaximizeEnabled)
00222                 return sarea;
00223             else
00224                 return warea;
00225         case MaximizeFullArea:
00226             if (options->xineramaMaximizeEnabled)
00227                 return desktopwidget->screenGeometry( screen );
00228             else
00229                 return desktopwidget->geometry();
00230         case FullScreenArea:
00231             if (options->xineramaFullscreenEnabled)
00232                 return desktopwidget->screenGeometry( screen );
00233             else
00234                 return desktopwidget->geometry();
00235         case PlacementArea:
00236             if (options->xineramaPlacementEnabled)
00237                 return sarea;
00238             else
00239                 return warea;
00240         case MovementArea:
00241             if (options->xineramaMovementEnabled)
00242                 return desktopwidget->screenGeometry( screen );
00243             else
00244                 return desktopwidget->geometry();
00245         case WorkArea:
00246             return warea;
00247         case FullArea:
00248             return desktopwidget->geometry();
00249         case ScreenArea:
00250             return sarea;
00251         }
00252     assert( false );
00253     return QRect();
00254     }
00255 
00256 QRect Workspace::clientArea( clientAreaOption opt, const Client* c ) const
00257     {
00258     return clientArea( opt, c->geometry().center(), c->desktop());
00259     }
00260 
00266 QPoint Workspace::adjustClientPosition( Client* c, QPoint pos )
00267     {
00268    //CT 16mar98, 27May98 - magics: BorderSnapZone, WindowSnapZone
00269    //CT adapted for kwin on 25Nov1999
00270    //aleXXX 02Nov2000 added second snapping mode
00271     if (options->windowSnapZone || options->borderSnapZone )
00272         {
00273         const bool sOWO=options->snapOnlyWhenOverlapping;
00274         const QRect maxRect = clientArea(MovementArea, pos+c->rect().center(), c->desktop());
00275         const int xmin = maxRect.left();
00276         const int xmax = maxRect.right()+1;               //desk size
00277         const int ymin = maxRect.top();
00278         const int ymax = maxRect.bottom()+1;
00279 
00280         const int cx(pos.x());
00281         const int cy(pos.y());
00282         const int cw(c->width());
00283         const int ch(c->height());
00284         const int rx(cx+cw);
00285         const int ry(cy+ch);                 //these don't change
00286 
00287         int nx(cx), ny(cy);                         //buffers
00288         int deltaX(xmax);
00289         int deltaY(ymax);   //minimum distance to other clients
00290 
00291         int lx, ly, lrx, lry; //coords and size for the comparison client, l
00292 
00293       // border snap
00294         int snap = options->borderSnapZone; //snap trigger
00295         if (snap)
00296             {
00297             if ((sOWO?(cx<xmin):true) && (QABS(xmin-cx)<snap))
00298                 {
00299                 deltaX = xmin-cx;
00300                 nx = xmin;
00301                 }
00302             if ((sOWO?(rx>xmax):true) && (QABS(rx-xmax)<snap) && (QABS(xmax-rx) < deltaX))
00303                 {
00304                 deltaX = rx-xmax;
00305                 nx = xmax - cw;
00306                 }
00307 
00308             if ((sOWO?(cy<ymin):true) && (QABS(ymin-cy)<snap))
00309                 {
00310                 deltaY = ymin-cy;
00311                 ny = ymin;
00312                 }
00313             if ((sOWO?(ry>ymax):true) && (QABS(ry-ymax)<snap) && (QABS(ymax-ry) < deltaY))
00314                 {
00315                 deltaY =ry-ymax;
00316                 ny = ymax - ch;
00317                 }
00318             }
00319 
00320       // windows snap
00321         snap = options->windowSnapZone;
00322         if (snap)
00323             {
00324             QValueList<Client *>::ConstIterator l;
00325             for (l = clients.begin();l != clients.end();++l )
00326                 {
00327                 if ((*l)->isOnDesktop(currentDesktop()) &&
00328                    !(*l)->isMinimized()
00329                     && (*l) != c )
00330                     {
00331                     lx = (*l)->x();
00332                     ly = (*l)->y();
00333                     lrx = lx + (*l)->width();
00334                     lry = ly + (*l)->height();
00335 
00336                     if ( (( cy <= lry ) && ( cy  >= ly  ))  ||
00337                          (( ry >= ly  ) && ( ry  <= lry ))  ||
00338                          (( cy <= ly  ) && ( ry >= lry  )) )
00339                         {
00340                         if ((sOWO?(cx<lrx):true) && (QABS(lrx-cx)<snap) && ( QABS(lrx -cx) < deltaX) )
00341                             {
00342                             deltaX = QABS( lrx - cx );
00343                             nx = lrx;
00344                             }
00345                         if ((sOWO?(rx>lx):true) && (QABS(rx-lx)<snap) && ( QABS( rx - lx )<deltaX) )
00346                             {
00347                             deltaX = QABS(rx - lx);
00348                             nx = lx - cw;
00349                             }
00350                         }
00351 
00352                     if ( (( cx <= lrx ) && ( cx  >= lx  ))  ||
00353                          (( rx >= lx  ) && ( rx  <= lrx ))  ||
00354                          (( cx <= lx  ) && ( rx >= lrx  )) )
00355                         {
00356                         if ((sOWO?(cy<lry):true) && (QABS(lry-cy)<snap) && (QABS( lry -cy ) < deltaY))
00357                             {
00358                             deltaY = QABS( lry - cy );
00359                             ny = lry;
00360                             }
00361                   //if ( (QABS( ry-ly ) < snap) && (QABS( ry - ly ) < deltaY ))
00362                         if ((sOWO?(ry>ly):true) && (QABS(ry-ly)<snap) && (QABS( ry - ly ) < deltaY ))
00363                             {
00364                             deltaY = QABS( ry - ly );
00365                             ny = ly - ch;
00366                             }
00367                         }
00368                     }
00369                 }
00370             }
00371         pos = QPoint(nx, ny);
00372         }
00373     return pos;
00374     }
00375 
00376 QRect Workspace::adjustClientSize( Client* c, QRect moveResizeGeom, int mode )
00377     {
00378    //adapted from adjustClientPosition on 29May2004
00379    //this function is called when resizing a window and will modify
00380    //the new dimensions to snap to other windows/borders if appropriate
00381     if ( options->windowSnapZone || options->borderSnapZone  )
00382         {
00383         const bool sOWO=options->snapOnlyWhenOverlapping;
00384 
00385         const QRect maxRect = clientArea(MovementArea, c->rect().center(), c->desktop());
00386         const int xmin = maxRect.left();
00387         const int xmax = maxRect.right();               //desk size
00388         const int ymin = maxRect.top();
00389         const int ymax = maxRect.bottom();
00390 
00391         const int cx(moveResizeGeom.left());
00392         const int cy(moveResizeGeom.top());
00393         const int rx(moveResizeGeom.right());
00394         const int ry(moveResizeGeom.bottom());
00395 
00396         int newcx(cx), newcy(cy);                         //buffers
00397         int newrx(rx), newry(ry);
00398         int deltaX(xmax);
00399         int deltaY(ymax);   //minimum distance to other clients
00400 
00401         int lx, ly, lrx, lry; //coords and size for the comparison client, l
00402 
00403       // border snap
00404         int snap = options->borderSnapZone; //snap trigger
00405         if (snap)
00406             {
00407             deltaX = int(snap);
00408             deltaY = int(snap);
00409 
00410 #define SNAP_BORDER_TOP \
00411             if ((sOWO?(newcy<ymin):true) && (QABS(ymin-newcy)<deltaY)) \
00412               { \
00413                 deltaY = QABS(ymin-newcy); \
00414                 newcy = ymin; \
00415                }
00416 
00417 #define SNAP_BORDER_BOTTOM \
00418             if ((sOWO?(newry>ymax):true) && (QABS(ymax-newry)<deltaY)) \
00419               { \
00420                 deltaY = QABS(ymax-newcy); \
00421                 newry = ymax; \
00422                }
00423 
00424 #define SNAP_BORDER_LEFT \
00425             if ((sOWO?(newcx<xmin):true) && (QABS(xmin-newcx)<deltaX)) \
00426               { \
00427                 deltaX = QABS(xmin-newcx); \
00428                 newcx = xmin; \
00429                }
00430 
00431 #define SNAP_BORDER_RIGHT \
00432             if ((sOWO?(newrx>xmax):true) && (QABS(xmax-newrx)<deltaX)) \
00433               { \
00434                 deltaX = QABS(xmax-newrx); \
00435                 newrx = xmax; \
00436                }
00437                      switch ( mode )
00438                       {
00439                       case PositionBottomRight:
00440                         SNAP_BORDER_BOTTOM
00441                         SNAP_BORDER_RIGHT
00442                         break;
00443                       case PositionRight:
00444                         SNAP_BORDER_RIGHT
00445                         break;
00446                       case PositionBottom:
00447                         SNAP_BORDER_BOTTOM
00448                         break;
00449                       case PositionTopLeft:
00450                         SNAP_BORDER_TOP
00451                         SNAP_BORDER_LEFT
00452                         break;
00453                       case PositionLeft:
00454                         SNAP_BORDER_LEFT
00455                         break;
00456                       case PositionTop:
00457                         SNAP_BORDER_TOP
00458                         break;
00459                       case PositionTopRight:
00460                         SNAP_BORDER_TOP
00461                         SNAP_BORDER_RIGHT
00462                         break;
00463                       case PositionBottomLeft:
00464                         SNAP_BORDER_BOTTOM
00465                         SNAP_BORDER_LEFT
00466                         break;
00467                       default:
00468                         assert( false );
00469                         break;
00470                       }
00471 
00472 
00473             }
00474 
00475       // windows snap
00476         snap = options->windowSnapZone;
00477         if (snap)
00478             {
00479             deltaX = int(snap);
00480             deltaY = int(snap);
00481             QValueList<Client *>::ConstIterator l;
00482             for (l = clients.begin();l != clients.end();++l )
00483                 {
00484                 if ((*l)->isOnDesktop(currentDesktop()) &&
00485                    !(*l)->isMinimized()
00486                     && (*l) != c )
00487                     {
00488                     lx = (*l)->x()-1;
00489                     ly = (*l)->y()-1;
00490                     lrx =(*l)->x() + (*l)->width();
00491                     lry =(*l)->y() + (*l)->height();
00492 
00493 #define WITHIN_HEIGHT ((( newcy <= lry ) && ( newcy  >= ly  ))  || \
00494                          (( newry >= ly  ) && ( newry  <= lry ))  || \
00495                          (( newcy <= ly  ) && ( newry >= lry  )) )
00496 
00497 #define WITHIN_WIDTH  ( (( cx <= lrx ) && ( cx  >= lx  ))  || \
00498                          (( rx >= lx  ) && ( rx  <= lrx ))  || \
00499                          (( cx <= lx  ) && ( rx >= lrx  )) )
00500 
00501 #define SNAP_WINDOW_TOP  if ( (sOWO?(newcy<lry):true) \
00502                   && WITHIN_WIDTH  \
00503                   && (QABS( lry - newcy ) < deltaY) ) {  \
00504                   deltaY = QABS( lry - newcy ); \
00505                   newcy=lry; \
00506                   }
00507 
00508 #define SNAP_WINDOW_BOTTOM  if ( (sOWO?(newry>ly):true)  \
00509                      && WITHIN_WIDTH  \
00510                      && (QABS( ly - newry ) < deltaY) ) {  \
00511                      deltaY = QABS( ly - newry );  \
00512                      newry=ly;  \
00513                      }
00514 
00515 #define SNAP_WINDOW_LEFT  if ( (sOWO?(newcx<lrx):true)  \
00516                    && WITHIN_HEIGHT  \
00517                    && (QABS( lrx - newcx ) < deltaX)) {  \
00518                    deltaX = QABS( lrx - newcx );  \
00519                    newcx=lrx;  \
00520                    }
00521 
00522 #define SNAP_WINDOW_RIGHT  if ( (sOWO?(newrx>lx):true)  \
00523                     && WITHIN_HEIGHT  \
00524                     && (QABS( lx - newrx ) < deltaX))  \
00525                     {  \
00526                     deltaX = QABS( lx - newrx );  \
00527                     newrx=lx;  \
00528                     }
00529 
00530                     switch ( mode )
00531                       {
00532                       case PositionBottomRight:
00533                         SNAP_WINDOW_BOTTOM
00534                         SNAP_WINDOW_RIGHT
00535                         break;
00536                       case PositionRight:
00537                         SNAP_WINDOW_RIGHT
00538                         break;
00539                       case PositionBottom:
00540                         SNAP_WINDOW_BOTTOM
00541                         break;
00542                       case PositionTopLeft:
00543                         SNAP_WINDOW_TOP
00544                         SNAP_WINDOW_LEFT
00545                         break;
00546                       case PositionLeft:
00547                         SNAP_WINDOW_LEFT
00548                         break;
00549                       case PositionTop:
00550                         SNAP_WINDOW_TOP
00551                         break;
00552                       case PositionTopRight:
00553                         SNAP_WINDOW_TOP
00554                         SNAP_WINDOW_RIGHT
00555                         break;
00556                       case PositionBottomLeft:
00557                         SNAP_WINDOW_BOTTOM
00558                         SNAP_WINDOW_LEFT
00559                         break;
00560                       default:
00561                         assert( false );
00562                         break;
00563                       }
00564                     }
00565                 }
00566             }
00567        moveResizeGeom = QRect(QPoint(newcx, newcy), QPoint(newrx, newry));
00568        }
00569     return moveResizeGeom;
00570     }
00571 
00575 void Workspace::setClientIsMoving( Client *c )
00576     {
00577     Q_ASSERT(!c || !movingClient); // Catch attempts to move a second
00578     // window while still moving the first one.
00579     movingClient = c;
00580     if (movingClient)
00581         ++block_focus;
00582     else
00583         --block_focus;
00584     }
00585 
00589 void Workspace::cascadeDesktop()
00590     {
00591 // TODO XINERAMA this probably is not right for xinerama
00592     Q_ASSERT( block_stacking_updates == 0 );
00593     ClientList::ConstIterator it(stackingOrder().begin());
00594     bool re_init_cascade_at_first_client = true;
00595     for (; it != stackingOrder().end(); ++it)
00596         {
00597         if((!(*it)->isOnDesktop(currentDesktop())) ||
00598            ((*it)->isMinimized())                  ||
00599            ((*it)->isOnAllDesktops())              ||
00600            (!(*it)->isMovable()) )
00601             continue;
00602         initPositioning->placeCascaded(*it, QRect(), re_init_cascade_at_first_client);
00603         //CT is an if faster than an attribution?
00604         if (re_init_cascade_at_first_client)
00605           re_init_cascade_at_first_client = false;
00606         }
00607     }
00608 
00613 void Workspace::unclutterDesktop()
00614     {
00615     ClientList::Iterator it(clients.fromLast());
00616     for (; it != clients.end(); --it)
00617         {
00618         if((!(*it)->isOnDesktop(currentDesktop())) ||
00619            ((*it)->isMinimized())                  ||
00620            ((*it)->isOnAllDesktops())              ||
00621            (!(*it)->isMovable()) )
00622             continue;
00623         initPositioning->placeSmart(*it, QRect());
00624         }
00625     }
00626 
00627 
00628 void Workspace::updateTopMenuGeometry( Client* c )
00629     {
00630     if( !managingTopMenus())
00631         return;
00632     if( c != NULL )
00633         {
00634         XEvent ev;
00635         ev.xclient.display = qt_xdisplay();
00636         ev.xclient.type = ClientMessage;
00637         ev.xclient.window = c->window();
00638         static Atom msg_type_atom = XInternAtom( qt_xdisplay(), "_KDE_TOPMENU_MINSIZE", False );
00639         ev.xclient.message_type = msg_type_atom;
00640         ev.xclient.format = 32;
00641         ev.xclient.data.l[0] = qt_x_time;
00642         ev.xclient.data.l[1] = topmenu_space->width();
00643         ev.xclient.data.l[2] = topmenu_space->height();
00644         ev.xclient.data.l[3] = 0;
00645         ev.xclient.data.l[4] = 0;
00646         XSendEvent( qt_xdisplay(), c->window(), False, NoEventMask, &ev );
00647         KWin::setStrut( c->window(), 0, 0, topmenu_height, 0 ); // so that kicker etc. know
00648         c->checkWorkspacePosition();
00649         return;
00650         }
00651     // c == NULL - update all, including topmenu_space
00652     QRect area;
00653     area = clientArea( MaximizeFullArea, QPoint( 0, 0 ), 1 ); // HACK desktop ?
00654     area.setHeight( topMenuHeight());
00655     topmenu_space->setGeometry( area );
00656     for( ClientList::ConstIterator it = topmenus.begin();
00657          it != topmenus.end();
00658          ++it )
00659         updateTopMenuGeometry( *it );
00660     }
00661 
00662 //********************************************
00663 // Client
00664 //********************************************
00665 
00666 
00667 void Client::keepInArea( const QRect& area )
00668     {
00669     if ( geometry().right() > area.right() && width() < area.width() )
00670         move( area.right() - width(), y() );
00671     if ( geometry().bottom() > area.bottom() && height() < area.height() )
00672         move( x(), area.bottom() - height() );
00673     if( !area.contains( geometry().topLeft() ))
00674         {
00675         int tx = x();
00676         int ty = y();
00677         if ( tx < area.x() )
00678             tx = area.x();
00679         if ( ty < area.y() )
00680             ty = area.y();
00681         move( tx, ty );
00682         }
00683     }
00684 
00690 // TODO move to Workspace?
00691 
00692 QRect Client::adjustedClientArea( const QRect &desktopArea, const QRect& area ) const
00693     {
00694     QRect r = area;
00695     // topmenu area is reserved in updateClientArea()
00696     if( isTopMenu())
00697         return r;
00698     NETExtendedStrut str = strut();
00699     QRect stareaL = QRect(
00700             0,
00701             str . left_start,
00702             str . left_width,
00703             str . left_end - str . left_start + 1 );
00704     QRect stareaR = QRect (
00705             desktopArea . right () - str . right_width + 1,
00706             str . right_start,
00707             str . right_width,
00708             str . right_end - str . right_start + 1 );
00709     QRect stareaT = QRect (
00710             str . top_start,
00711             0,
00712             str . top_end - str . top_start + 1,
00713             str . top_width);
00714     QRect stareaB = QRect (
00715             str . bottom_start,
00716             desktopArea . bottom () - str . bottom_width + 1,
00717             str . bottom_end - str . bottom_start + 1,
00718             str . bottom_width);
00719 
00720     NETExtendedStrut ext = info->extendedStrut();
00721     if( ext.left_width == 0 && ext.right_width == 0 && ext.top_width == 0 && ext.bottom_width == 0
00722         && ( str.left_width != 0 || str.right_width != 0 || str.top_width != 0 || str.bottom_width != 0 )) {
00723 
00724         // hack, might cause problems... this tries to guess the start/end of a
00725         // non-extended strut; only works on windows that have exact same
00726         // geometry as their strut (ie, if the geometry fits the width
00727         // exactly, we will adjust length of strut to match the geometry as well;
00728         // otherwise we use the full-edge strut)
00729 
00730         if (stareaT.top() == geometry().top() && stareaT.bottom() == geometry().bottom()) {
00731             stareaT.setLeft(geometry().left());
00732             stareaT.setRight(geometry().right());
00733 //            kdDebug () << "Trimming top-strut to geometry() to: " << stareaT << endl;
00734         }
00735         if (stareaB.top() == geometry().top() && stareaB.bottom() == geometry().bottom()) {
00736             stareaB.setLeft(geometry().left());
00737             stareaB.setRight(geometry().right());
00738 //            kdDebug () << "Trimming bottom-strut to geometry(): " << stareaB << endl;
00739         }
00740         if (stareaL.left() == geometry().left() && stareaL.right() == geometry().right()) {
00741             stareaL.setTop(geometry().top());
00742             stareaL.setBottom(geometry().bottom());
00743 //            kdDebug () << "Trimming left-strut to geometry(): " << stareaL << endl;
00744         }
00745         if (stareaR.left() == geometry().left() && stareaR.right() == geometry().right()) {
00746             stareaR.setTop(geometry().top());
00747             stareaR.setBottom(geometry().bottom());
00748 //            kdDebug () << "Trimming right-strut to geometry(): " << stareaR << endl;
00749         }
00750     }
00751     if (stareaL . intersects (area)) {
00752 //        kdDebug () << "Moving left of: " << r << " to " << stareaL.right() + 1 << endl;
00753         r . setLeft( stareaL . right() + 1 );
00754     }
00755     if (stareaR . intersects (area)) {
00756 //        kdDebug () << "Moving right of: " << r << " to " << stareaR.left() - 1 << endl;
00757         r . setRight( stareaR . left() - 1 );
00758     }
00759     if (stareaT . intersects (area)) {
00760 //        kdDebug () << "Moving top of: " << r << " to " << stareaT.bottom() + 1 << endl;
00761         r . setTop( stareaT . bottom() + 1 );
00762     }
00763     if (stareaB . intersects (area)) {
00764 //        kdDebug () << "Moving bottom of: " << r << " to " << stareaB.top() - 1 << endl;
00765         r . setBottom( stareaB . top() - 1 );
00766     }
00767     return r;
00768     }
00769 
00770 NETExtendedStrut Client::strut() const
00771     {
00772     NETExtendedStrut ext = info->extendedStrut();
00773     NETStrut str = info->strut();
00774     if( ext.left_width == 0 && ext.right_width == 0 && ext.top_width == 0 && ext.bottom_width == 0
00775         && ( str.left != 0 || str.right != 0 || str.top != 0 || str.bottom != 0 ))
00776         {
00777         // build extended from simple
00778         if( str.left != 0 )
00779             {
00780             ext.left_width = str.left;
00781             ext.left_start = 0;
00782             ext.left_end = XDisplayHeight( qt_xdisplay(), DefaultScreen( qt_xdisplay()));
00783             }
00784         if( str.right != 0 )
00785             {
00786             ext.right_width = str.right;
00787             ext.right_start = 0;
00788             ext.right_end = XDisplayHeight( qt_xdisplay(), DefaultScreen( qt_xdisplay()));
00789             }
00790         if( str.top != 0 )
00791             {
00792             ext.top_width = str.top;
00793             ext.top_start = 0;
00794             ext.top_end = XDisplayWidth( qt_xdisplay(), DefaultScreen( qt_xdisplay()));
00795             }
00796         if( str.bottom != 0 )
00797             {
00798             ext.bottom_width = str.bottom;
00799             ext.bottom_start = 0;
00800             ext.bottom_end = XDisplayWidth( qt_xdisplay(), DefaultScreen( qt_xdisplay()));
00801             }
00802         }
00803     return ext;
00804     }
00805 bool Client::hasStrut() const
00806     {
00807     NETExtendedStrut ext = strut();
00808     if( ext.left_width == 0 && ext.right_width == 0 && ext.top_width == 0 && ext.bottom_width == 0 )
00809         {
00810             return false;
00811         }
00812     return true;
00813     }
00814 
00815 
00816 // updates differences to workarea edges for all directions
00817 void Client::updateWorkareaDiffs()
00818     {
00819     QRect area = workspace()->clientArea( WorkArea, this );
00820     QRect geom = geometry();
00821     workarea_diff_x = computeWorkareaDiff( geom.left(), geom.right(), area.left(), area.right());
00822     workarea_diff_y = computeWorkareaDiff( geom.top(), geom.bottom(), area.top(), area.bottom());
00823     }
00824 
00825 // If the client was inside workarea in the x direction, and if it was close to the left/right
00826 // edge, return the distance from the left/right edge (negative for left, positive for right)
00827 // INT_MIN means 'not inside workarea', INT_MAX means 'not near edge'.
00828 // In order to recognize 'at the left workarea edge' from 'at the right workarea edge'
00829 // (i.e. negative vs positive zero), the distances are one larger in absolute value than they
00830 // really are (i.e. 5 pixels from the left edge is -6, not -5). A bit hacky, but I'm lazy
00831 // to rewrite it just to make it nicer. If this will ever get touched again, perhaps then.
00832 // the y direction is done the same, just the values will be rotated: top->left, bottom->right
00833 int Client::computeWorkareaDiff( int left, int right, int a_left, int a_right )
00834     {
00835     int left_diff = left - a_left;
00836     int right_diff = a_right - right;
00837     if( left_diff < 0 || right_diff < 0 )
00838         return INT_MIN;
00839     else // fully inside workarea in this direction direction
00840         {
00841         // max distance from edge where it's still considered to be close and is kept at that distance
00842         int max_diff = ( a_right - a_left ) / 10;
00843         if( left_diff < right_diff )
00844             return left_diff < max_diff ? -left_diff - 1 : INT_MAX;
00845         else if( left_diff > right_diff )
00846             return right_diff < max_diff ? right_diff + 1 : INT_MAX;
00847         return INT_MAX; // not close to workarea edge
00848         }
00849     }
00850 
00851 void Client::checkWorkspacePosition()
00852     {
00853     if( maximizeMode() != MaximizeRestore )
00854     // TODO update geom_restore?
00855         changeMaximize( false, false, true ); // adjust size
00856 
00857     if( isFullScreen())
00858         {
00859         QRect area = workspace()->clientArea( FullScreenArea, this );
00860         if( geometry() != area )
00861             setGeometry( area );
00862         return;
00863         }
00864     if( isDock())
00865         return;
00866     if( isOverride())
00867         return; // I wish I knew what to do here :(
00868     if( isTopMenu())
00869         {
00870         if( workspace()->managingTopMenus())
00871             {
00872             QRect area;
00873             ClientList mainclients = mainClients();
00874             if( mainclients.count() == 1 )
00875                 area = workspace()->clientArea( MaximizeFullArea, mainclients.first());
00876             else
00877                 area = workspace()->clientArea( MaximizeFullArea, QPoint( 0, 0 ), desktop());
00878             area.setHeight( workspace()->topMenuHeight());
00879 //            kdDebug() << "TOPMENU size adjust: " << area << ":" << this << endl;
00880             setGeometry( area );
00881             }
00882         return;
00883         }
00884 
00885     if( !isShade()) // TODO
00886         {
00887         int old_diff_x = workarea_diff_x;
00888         int old_diff_y = workarea_diff_y;
00889         updateWorkareaDiffs();
00890 
00891         // this can be true only if this window was mapped before KWin
00892         // was started - in such case, don't adjust position to workarea,
00893         // because the window already had its position, and if a window
00894         // with a strut altering the workarea would be managed in initialization
00895         // after this one, this window would be moved
00896         if( workspace()->initializing())
00897             return;
00898 
00899         QRect area = workspace()->clientArea( WorkArea, this );
00900         QRect new_geom = geometry();
00901         QRect tmp_rect_x( new_geom.left(), 0, new_geom.width(), 0 );
00902         QRect tmp_area_x( area.left(), 0, area.width(), 0 );
00903         checkDirection( workarea_diff_x, old_diff_x, tmp_rect_x, tmp_area_x );
00904         // the x<->y swapping
00905         QRect tmp_rect_y( new_geom.top(), 0, new_geom.height(), 0 );
00906         QRect tmp_area_y( area.top(), 0, area.height(), 0 );
00907         checkDirection( workarea_diff_y, old_diff_y, tmp_rect_y, tmp_area_y );
00908         new_geom = QRect( tmp_rect_x.left(), tmp_rect_y.left(), tmp_rect_x.width(), tmp_rect_y.width());
00909         QRect final_geom( new_geom.topLeft(), adjustedSize( new_geom.size()));
00910         if( final_geom != new_geom ) // size increments, or size restrictions
00911             { // adjusted size differing matters only for right and bottom edge
00912             if( old_diff_x != INT_MAX && old_diff_x > 0 )
00913                 final_geom.moveRight( area.right() - ( old_diff_x - 1 ));
00914             if( old_diff_y != INT_MAX && old_diff_y > 0 )
00915                 final_geom.moveBottom( area.bottom() - ( old_diff_y - 1 ));
00916             }
00917         if( final_geom != geometry() )
00918             setGeometry( final_geom );
00919         //    updateWorkareaDiffs(); done already by setGeometry()
00920         }
00921     }
00922 
00923 // Try to be smart about keeping the clients visible.
00924 // If the client was fully inside the workspace before, try to keep
00925 // it still inside the workarea, possibly moving it or making it smaller if possible,
00926 // and try to keep the distance from the nearest workarea edge.
00927 // On the other hand, it it was partially moved outside of the workspace in some direction,
00928 // don't do anything with that direction if it's still at least partially visible. If it's
00929 // not visible anymore at all, make sure it's visible at least partially
00930 // again (not fully, as that could(?) be potentionally annoying) by
00931 // moving it slightly inside the workarea (those '+ 5').
00932 // Again, this is done for the x direction, y direction will be done by x<->y swapping
00933 void Client::checkDirection( int new_diff, int old_diff, QRect& rect, const QRect& area )
00934     {
00935     if( old_diff != INT_MIN ) // was inside workarea
00936         {
00937         if( old_diff == INT_MAX ) // was in workarea, but far from edge
00938             {
00939             if( new_diff == INT_MIN )  // is not anymore fully in workarea
00940                 {
00941                 rect.setLeft( area.left());
00942                 rect.setRight( area.right());
00943                 }
00944             return;
00945             }
00946         if( isResizable())
00947             {
00948             if( rect.width() > area.width())
00949                 rect.setWidth( area.width());
00950             if( rect.width() >= area.width() / 2 )
00951                 {
00952                 if( old_diff < 0 )
00953                     rect.setLeft( area.left() + ( -old_diff - 1 ) );
00954                 else // old_diff > 0
00955                     rect.setRight( area.right() - ( old_diff - 1 ));
00956                 }
00957             }
00958         if( isMovable())
00959             {
00960             if( old_diff < 0 ) // was in left third, keep distance from left edge
00961                 rect.moveLeft( area.left() + ( -old_diff - 1 ));
00962             else // old_diff > 0 // was in right third, keep distance from right edge
00963                 rect.moveRight( area.right() - ( old_diff - 1 ));
00964             }
00965         // this isResizable() block is copied from above, the difference is
00966         // the condition with 'area.width() / 2' - for windows that are not wide,
00967         // moving is preffered to resizing
00968         if( isResizable())
00969             {
00970             if( old_diff < 0 )
00971                 rect.setLeft( area.left() + ( -old_diff - 1 ) );
00972             else // old_diff > 0
00973                 rect.setRight( area.right() - ( old_diff - 1 ));
00974             }
00975         }
00976     if( rect.right() < area.left() + 5 || rect.left() > area.right() - 5 )
00977         { // not visible (almost) at all - try to make it at least partially visible
00978         if( isMovable())
00979             {
00980             if( rect.left() < area.left() + 5 )
00981                 rect.moveRight( area.left() + 5 );
00982             if( rect.right() > area.right() - 5 )
00983                 rect.moveLeft( area.right() - 5 );
00984             }
00985         }
00986     }
00987 
00991 QSize Client::adjustedSize( const QSize& frame, Sizemode mode ) const
00992     {
00993     // first, get the window size for the given frame size s
00994 
00995     QSize wsize( frame.width() - ( border_left + border_right ),
00996              frame.height() - ( border_top + border_bottom ));
00997 
00998     return sizeForClientSize( wsize, mode );
00999     }
01000 
01009 QSize Client::sizeForClientSize( const QSize& wsize, Sizemode mode ) const
01010     {
01011     int w = wsize.width();
01012     int h = wsize.height();
01013     if (w<1) w = 1;
01014     if (h<1) h = 1;
01015 
01016     // basesize, minsize, maxsize, paspect and resizeinc have all values defined,
01017     // even if they're not set in flags - see getWmNormalHints()
01018     QSize min_size = minSize();
01019     QSize max_size = maxSize();
01020     if( decoration != NULL )
01021         {
01022         QSize decominsize = decoration->minimumSize();
01023         QSize border_size( border_left + border_right, border_top + border_bottom );
01024         if( border_size.width() > decominsize.width()) // just in case
01025             decominsize.setWidth( border_size.width());
01026         if( border_size.height() > decominsize.height())
01027             decominsize.setHeight( border_size.height());
01028         if( decominsize.width() > min_size.width())
01029                 min_size.setWidth( decominsize.width());
01030         if( decominsize.height() > min_size.height())
01031                 min_size.setHeight( decominsize.height());
01032         }
01033     w = QMIN( max_size.width(), w );
01034     h = QMIN( max_size.height(), h );
01035     w = QMAX( min_size.width(), w );
01036     h = QMAX( min_size.height(), h );
01037 
01038     int w1 = w;
01039     int h1 = h;
01040     int width_inc = xSizeHint.width_inc;
01041     int height_inc = xSizeHint.height_inc;
01042     int basew_inc = xSizeHint.min_width; // see getWmNormalHints()
01043     int baseh_inc = xSizeHint.min_height;
01044     w = int(( w - basew_inc ) / width_inc ) * width_inc + basew_inc;
01045     h = int(( h - baseh_inc ) / height_inc ) * height_inc + baseh_inc;
01046 // code for aspect ratios based on code from FVWM
01047     /*
01048      * The math looks like this:
01049      *
01050      * minAspectX    dwidth     maxAspectX
01051      * ---------- <= ------- <= ----------
01052      * minAspectY    dheight    maxAspectY
01053      *
01054      * If that is multiplied out, then the width and height are
01055      * invalid in the following situations:
01056      *
01057      * minAspectX * dheight > minAspectY * dwidth
01058      * maxAspectX * dheight < maxAspectY * dwidth
01059      *
01060      */
01061     if( xSizeHint.flags & PAspect )
01062         {
01063         double min_aspect_w = xSizeHint.min_aspect.x; // use doubles, because the values can be MAX_INT
01064         double min_aspect_h = xSizeHint.min_aspect.y; // and multiplying would go wrong otherwise
01065         double max_aspect_w = xSizeHint.max_aspect.x;
01066         double max_aspect_h = xSizeHint.max_aspect.y;
01067         w -= xSizeHint.base_width;
01068         h -= xSizeHint.base_height;
01069         int max_width = max_size.width() - xSizeHint.base_width;
01070         int min_width = min_size.width() - xSizeHint.base_width;
01071         int max_height = max_size.height() - xSizeHint.base_height;
01072         int min_height = min_size.height() - xSizeHint.base_height;
01073 #define ASPECT_CHECK_GROW_W \
01074         if( min_aspect_w * h > min_aspect_h * w ) \
01075             { \
01076             int delta = int( min_aspect_w * h / min_aspect_h - w ) / width_inc * width_inc; \
01077             if( w + delta <= max_width ) \
01078                 w += delta; \
01079             }
01080 #define ASPECT_CHECK_SHRINK_H_GROW_W \
01081         if( min_aspect_w * h > min_aspect_h * w ) \
01082             { \
01083             int delta = int( h - w * min_aspect_h / min_aspect_w ) / height_inc * height_inc; \
01084             if( h - delta >= min_height ) \
01085                 h -= delta; \
01086             else \
01087                 { \
01088                 int delta = int( min_aspect_w * h / min_aspect_h - w ) / width_inc * width_inc; \
01089                 if( w + delta <= max_width ) \
01090                     w += delta; \
01091                 } \
01092             }
01093 #define ASPECT_CHECK_GROW_H \
01094         if( max_aspect_w * h < max_aspect_h * w ) \
01095             { \
01096             int delta = int( w * max_aspect_h / max_aspect_w - h ) / height_inc * height_inc; \
01097             if( h + delta <= max_height ) \
01098                 h += delta; \
01099             }
01100 #define ASPECT_CHECK_SHRINK_W_GROW_H \
01101         if( max_aspect_w * h < max_aspect_h * w ) \
01102             { \
01103             int delta = int( w - max_aspect_w * h / max_aspect_h ) / width_inc * width_inc; \
01104             if( w - delta >= min_width ) \
01105                 w -= delta; \
01106             else \
01107                 { \
01108                 int delta = int( w * max_aspect_h / max_aspect_w - h ) / height_inc * height_inc; \
01109                 if( h + delta <= max_height ) \
01110                     h += delta; \
01111                 } \
01112             }
01113         switch( mode )
01114             {
01115             case SizemodeAny:
01116                 {
01117                 ASPECT_CHECK_SHRINK_H_GROW_W
01118                 ASPECT_CHECK_SHRINK_W_GROW_H
01119                 ASPECT_CHECK_GROW_H
01120                 ASPECT_CHECK_GROW_W
01121                 break;
01122                 }
01123             case SizemodeFixedW:
01124                 {
01125                 // the checks are order so that attempts to modify height are first
01126                 ASPECT_CHECK_GROW_H
01127                 ASPECT_CHECK_SHRINK_H_GROW_W
01128                 ASPECT_CHECK_SHRINK_W_GROW_H
01129                 ASPECT_CHECK_GROW_W
01130                 break;
01131                 }
01132             case SizemodeFixedH:
01133                 {
01134                 ASPECT_CHECK_GROW_W
01135                 ASPECT_CHECK_SHRINK_W_GROW_H
01136                 ASPECT_CHECK_SHRINK_H_GROW_W
01137                 ASPECT_CHECK_GROW_H
01138                 break;
01139                 }
01140             case SizemodeMax:
01141                 {
01142                 // first checks that try to shrink
01143                 ASPECT_CHECK_SHRINK_H_GROW_W
01144                 ASPECT_CHECK_SHRINK_W_GROW_H
01145                 ASPECT_CHECK_GROW_W
01146                 ASPECT_CHECK_GROW_H
01147                 break;
01148                 }
01149             case SizemodeShaded:
01150                 break;
01151             }
01152 #undef ASPECT_CHECK_SHRINK_H_GROW_W
01153 #undef ASPECT_CHECK_SHRINK_W_GROW_H
01154 #undef ASPECT_CHECK_GROW_W
01155 #undef ASPECT_CHECK_GROW_H
01156         w += xSizeHint.base_width;
01157         h += xSizeHint.base_height;
01158         }
01159     // disobey increments and aspect when maximized
01160     if( maximizeMode() & MaximizeHorizontal )
01161         w = w1;
01162     if( maximizeMode() & MaximizeVertical )
01163         h = h1;
01164 
01165     w += border_left + border_right;
01166     h += border_top + border_bottom;
01167     QSize ret = rules()->checkSize( QSize( w, h ));
01168     if ( mode == SizemodeShaded && wsize.height() == 0 )
01169         ret.setHeight( border_top + border_bottom );
01170     return ret;
01171     }
01172 
01176 void Client::getWmNormalHints()
01177     {
01178     long msize;
01179     if (XGetWMNormalHints(qt_xdisplay(), window(), &xSizeHint, &msize) == 0 )
01180         xSizeHint.flags = 0;
01181     // set defined values for the fields, even if they're not in flags
01182 
01183     // basesize is just like minsize, except for minsize is not used for aspect ratios
01184     // keep basesize only for aspect ratios, for size increments, keep the base
01185     // value in minsize - see ICCCM 4.1.2.3
01186     if( xSizeHint.flags & PBaseSize )
01187         {
01188         if( ! ( xSizeHint.flags & PMinSize )) // PBaseSize and PMinSize are equivalent
01189             {
01190             xSizeHint.flags |= PMinSize;
01191             xSizeHint.min_width = xSizeHint.base_width;
01192             xSizeHint.min_height = xSizeHint.base_height;
01193             }
01194         }
01195     else
01196         xSizeHint.base_width = xSizeHint.base_height = 0;
01197     if( ! ( xSizeHint.flags & PMinSize ))
01198         xSizeHint.min_width = xSizeHint.min_height = 0;
01199     if( ! ( xSizeHint.flags & PMaxSize ))
01200         xSizeHint.max_width = xSizeHint.max_height = INT_MAX;
01201     else
01202         {
01203         xSizeHint.max_width = QMAX( xSizeHint.max_width, 1 );
01204         xSizeHint.max_height = QMAX( xSizeHint.max_height, 1 );
01205         }
01206     if( xSizeHint.flags & PResizeInc )
01207         {
01208         xSizeHint.width_inc = kMax( xSizeHint.width_inc, 1 );
01209         xSizeHint.height_inc = kMax( xSizeHint.height_inc, 1 );
01210         }
01211     else
01212         {
01213         xSizeHint.width_inc = 1;
01214         xSizeHint.height_inc = 1;
01215         }
01216     if( xSizeHint.flags & PAspect )
01217         { // no dividing by zero
01218         xSizeHint.min_aspect.y = kMax( xSizeHint.min_aspect.y, 1 );
01219         xSizeHint.max_aspect.y = kMax( xSizeHint.max_aspect.y, 1 );
01220         }
01221     else
01222         {
01223         xSizeHint.min_aspect.x = 1;
01224         xSizeHint.min_aspect.y = INT_MAX;
01225         xSizeHint.max_aspect.x = INT_MAX;
01226         xSizeHint.max_aspect.y = 1;
01227         }
01228     if( ! ( xSizeHint.flags & PWinGravity ))
01229         xSizeHint.win_gravity = NorthWestGravity;
01230     if( isManaged())
01231         { // update to match restrictions
01232         QSize new_size = adjustedSize( size());
01233         if( new_size != size() && !isShade() && !isFullScreen()) // SHADE
01234             resizeWithChecks( new_size );
01235         }
01236     updateAllowedActions(); // affects isResizeable()
01237     }
01238 
01239 QSize Client::minSize() const
01240     {
01241     return rules()->checkMinSize( QSize( xSizeHint.min_width, xSizeHint.min_height ));
01242     }
01243 
01244 QSize Client::maxSize() const
01245     {
01246     return rules()->checkMaxSize( QSize( xSizeHint.max_width, xSizeHint.max_height ));
01247     }
01248 
01254 void Client::sendSyntheticConfigureNotify()
01255     {
01256     XConfigureEvent c;
01257     c.type = ConfigureNotify;
01258     c.send_event = True;
01259     c.event = window();
01260     c.window = window();
01261     c.x = x() + clientPos().x();
01262     c.y = y() + clientPos().y();
01263     c.width = clientSize().width();
01264     c.height = clientSize().height();
01265     c.border_width = 0;
01266     c.above = None;
01267     c.override_redirect = 0;
01268     XSendEvent( qt_xdisplay(), c.event, TRUE, StructureNotifyMask, (XEvent*)&c );
01269     }
01270 
01271 const QPoint Client::calculateGravitation( bool invert, int gravity ) const
01272     {
01273     int dx, dy;
01274     dx = dy = 0;
01275 
01276     if( gravity == 0 ) // default (nonsense) value for the argument
01277         gravity = xSizeHint.win_gravity;
01278 
01279 // dx, dy specify how the client window moves to make space for the frame
01280     switch (gravity)
01281         {
01282         case NorthWestGravity: // move down right
01283         default:
01284             dx = border_left;
01285             dy = border_top;
01286             break;
01287         case NorthGravity: // move right
01288             dx = 0;
01289             dy = border_top;
01290             break;
01291         case NorthEastGravity: // move down left
01292             dx = -border_right;
01293             dy = border_top;
01294             break;
01295         case WestGravity: // move right
01296             dx = border_left;
01297             dy = 0;
01298             break;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299         case Centerspan>;
01299