kwin Library API Documentation

utils.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 is for (very) small utility functions/classes.
00015 
00016 */
00017 
00018 #include "utils.h"
00019 
00020 #include <unistd.h>
00021 
00022 #ifndef KCMRULES
00023 
00024 #include <kxerrorhandler.h>
00025 #include <assert.h>
00026 #include <kdebug.h>
00027 
00028 #include <X11/Xlib.h>
00029 #include <X11/extensions/shape.h>
00030 #include <X11/Xatom.h>
00031 
00032 #include "atoms.h"
00033 
00034 extern Time qt_x_time;
00035 
00036 #endif
00037 
00038 namespace KWinInternal
00039 {
00040 
00041 #ifndef KCMRULES
00042 
00043 // used to store the return values of
00044 // XShapeQueryExtension.
00045 // Necessary since shaped window are an extension to X
00046 int Shape::kwin_has_shape = 0;
00047 int Shape::kwin_shape_event = 0;
00048 
00049 // does the window w  need a shape combine mask around it?
00050 bool Shape::hasShape( WId w)
00051     {
00052     int xws, yws, xbs, ybs;
00053     unsigned int wws, hws, wbs, hbs;
00054     int boundingShaped = 0, clipShaped = 0;
00055     if (!kwin_has_shape)
00056         return FALSE;
00057     XShapeQueryExtents(qt_xdisplay(), w,
00058                        &boundingShaped, &xws, &yws, &wws, &hws,
00059                        &clipShaped, &xbs, &ybs, &wbs, &hbs);
00060     return boundingShaped != 0;
00061     }
00062 
00063 int Shape::shapeEvent()
00064     {
00065     return kwin_shape_event;
00066     }
00067 
00068 void Shape::init()
00069     {
00070     int dummy;
00071     kwin_has_shape =
00072       XShapeQueryExtension(qt_xdisplay(), &kwin_shape_event, &dummy);
00073     }
00074 
00075 void Motif::readFlags( WId w, bool& noborder, bool& resize, bool& move,
00076     bool& minimize, bool& maximize, bool& close )
00077     {
00078     Atom type;
00079     int format;
00080     unsigned long length, after;
00081     unsigned char* data;
00082     MwmHints* hints = 0;
00083     if ( XGetWindowProperty( qt_xdisplay(), w, atoms->motif_wm_hints, 0, 5,
00084                              FALSE, atoms->motif_wm_hints, &type, &format,
00085                              &length, &after, &data ) == Success ) 
00086         {
00087         if ( data )
00088             hints = (MwmHints*) data;
00089         }
00090     noborder = false;
00091     resize = true;
00092     move = true;
00093     minimize = true;
00094     maximize = true;
00095     close = true;
00096     if ( hints ) 
00097         {
00098     // To quote from Metacity 'We support those MWM hints deemed non-stupid'
00099         if ( hints->flags & MWM_HINTS_FUNCTIONS ) 
00100             {
00101             // if MWM_FUNC_ALL is set, other flags say what to turn _off_
00102             bool set_value = (( hints->functions & MWM_FUNC_ALL ) == 0 );
00103             resize = move = minimize = maximize = close = !set_value;
00104             if( hints->functions & MWM_FUNC_RESIZE )
00105                 resize = set_value;
00106             if( hints->functions & MWM_FUNC_MOVE )
00107                 move = set_value;
00108             if( hints->functions & MWM_FUNC_MINIMIZE )
00109                 minimize = set_value;
00110             if( hints->functions & MWM_FUNC_MAXIMIZE )
00111                 maximize = set_value;
00112             if( hints->functions & MWM_FUNC_CLOSE )
00113                 close = set_value;
00114             }
00115         if ( hints->flags & MWM_HINTS_DECORATIONS ) 
00116             {
00117             if ( hints->decorations == 0 )
00118                 noborder = true;
00119             }
00120         XFree( data );
00121         }
00122     }
00123 
00124 //************************************
00125 // KWinSelectionOwner
00126 //************************************
00127 
00128 KWinSelectionOwner::KWinSelectionOwner( int screen_P )
00129     : KSelectionOwner( make_selection_atom( screen_P ), screen_P )
00130     {
00131     }
00132 
00133 Atom KWinSelectionOwner::make_selection_atom( int screen_P )
00134     {
00135     if( screen_P < 0 )
00136         screen_P = DefaultScreen( qt_xdisplay());
00137     char tmp[ 30 ];
00138     sprintf( tmp, "WM_S%d", screen_P );
00139     return XInternAtom( qt_xdisplay(), tmp, False );
00140     }
00141 
00142 void KWinSelectionOwner::getAtoms()
00143     {
00144     KSelectionOwner::getAtoms();
00145     if( xa_version == None )
00146         {
00147         Atom atoms[ 1 ];
00148         const char* const names[] =
00149             { "VERSION" };
00150         XInternAtoms( qt_xdisplay(), const_cast< char** >( names ), 1, False, atoms );
00151         xa_version = atoms[ 0 ];
00152         }
00153     }
00154 
00155 void KWinSelectionOwner::replyTargets( Atom property_P, Window requestor_P )
00156     {
00157     KSelectionOwner::replyTargets( property_P, requestor_P );
00158     Atom atoms[ 1 ] = { xa_version };
00159     // PropModeAppend !
00160     XChangeProperty( qt_xdisplay(), requestor_P, property_P, XA_ATOM, 32, PropModeAppend,
00161         reinterpret_cast< unsigned char* >( atoms ), 1 );
00162     }
00163 
00164 bool KWinSelectionOwner::genericReply( Atom target_P, Atom property_P, Window requestor_P )
00165     {
00166     if( target_P == xa_version )
00167         {
00168         long version[] = { 2, 0 };
00169         XChangeProperty( qt_xdisplay(), requestor_P, property_P, XA_INTEGER, 32,
00170             PropModeReplace, reinterpret_cast< unsigned char* >( &version ), 2 );
00171         }
00172     else
00173         return KSelectionOwner::genericReply( target_P, property_P, requestor_P );
00174     return true;    
00175     }
00176 
00177 Atom KWinSelectionOwner::xa_version = None;
00178 
00179 
00180 QCString getStringProperty(WId w, Atom prop, char separator)
00181     {
00182     Atom type;
00183     int format, status;
00184     unsigned long nitems = 0;
00185     unsigned long extra = 0;
00186     unsigned char *data = 0;
00187     QCString result = "";
00188     KXErrorHandler handler; // ignore errors
00189     status = XGetWindowProperty( qt_xdisplay(), w, prop, 0, 10000,
00190                                  FALSE, XA_STRING, &type, &format,
00191                                  &nitems, &extra, &data );
00192     if ( status == Success) 
00193         {
00194         if (data && separator) 
00195             {
00196             for (int i=0; i<(int)nitems; i++)
00197                 if (!data[i] && i+1<(int)nitems)
00198                     data[i] = separator;
00199             }
00200         if (data)
00201             result = (const char*) data;
00202         XFree(data);
00203         }
00204     return result;
00205     }
00206 
00207 static Time next_x_time;
00208 static Bool update_x_time_predicate( Display*, XEvent* event, XPointer )
00209 {
00210     if( next_x_time != CurrentTime )
00211         return False;
00212     // from qapplication_x11.cpp
00213     switch ( event->type ) {
00214     case ButtonPress:
00215     // fallthrough intended
00216     case ButtonRelease:
00217     next_x_time = event->xbutton.time;
00218     break;
00219     case MotionNotify:
00220     next_x_time = event->xmotion.time;
00221     break;
00222     case KeyPress:
00223     // fallthrough intended
00224     case KeyRelease:
00225     next_x_time = event->xkey.time;
00226     break;
00227     case PropertyNotify:
00228     next_x_time = event->xproperty.time;
00229     break;
00230     case EnterNotify:
00231     case LeaveNotify:
00232     next_x_time = event->xcrossing.time;
00233     break;
00234     case SelectionClear:
00235     next_x_time = event->xselectionclear.time;
00236     break;
00237     default:
00238     break;
00239     }
00240     return False;
00241 }
00242 
00243 /*
00244  Updates qt_x_time. This used to simply fetch current timestamp from the server,
00245  but that can cause qt_x_time to be newer than timestamp of events that are
00246  still in our events queue, thus e.g. making XSetInputFocus() caused by such
00247  event to be ignored. Therefore events queue is searched for first
00248  event with timestamp, and extra PropertyNotify is generated in order to make
00249  sure such event is found.
00250 */
00251 void updateXTime()
00252     {
00253     static QWidget* w = 0;
00254     if ( !w )
00255         w = new QWidget;
00256     long data = 1;
00257     XChangeProperty(qt_xdisplay(), w->winId(), atoms->kwin_running, atoms->kwin_running, 32,
00258                     PropModeAppend, (unsigned char*) &data, 1);
00259     next_x_time = CurrentTime;
00260     XEvent dummy;
00261     XCheckIfEvent( qt_xdisplay(), &dummy, update_x_time_predicate, NULL );
00262     if( next_x_time == CurrentTime )
00263         {
00264         XSync( qt_xdisplay(), False );
00265         XCheckIfEvent( qt_xdisplay(), &dummy, update_x_time_predicate, NULL );
00266         }
00267     assert( next_x_time != CurrentTime );
00268     qt_x_time = next_x_time;
00269     XEvent ev; // remove the PropertyNotify event from the events queue
00270     XWindowEvent( qt_xdisplay(), w->winId(), PropertyChangeMask, &ev );
00271     }
00272 
00273 static int server_grab_count = 0;
00274 
00275 void grabXServer()
00276     {
00277     if( ++server_grab_count == 1 )
00278         XGrabServer( qt_xdisplay());
00279     }
00280 
00281 void ungrabXServer()
00282     {
00283     assert( server_grab_count > 0 );
00284     if( --server_grab_count == 0 )
00285         XUngrabServer( qt_xdisplay());
00286     }
00287 #endif
00288 
00289 bool isLocalMachine( const QCString& host )
00290     {
00291 #ifdef HOST_NAME_MAX
00292     char hostnamebuf[HOST_NAME_MAX];
00293 #else
00294     char hostnamebuf[256];
00295 #endif
00296     if (gethostname (hostnamebuf, sizeof hostnamebuf) >= 0) 
00297         {
00298         hostnamebuf[sizeof(hostnamebuf)-1] = 0;
00299         if (host == hostnamebuf)
00300             return true;
00301         char *dot = strchr(hostnamebuf, '.');
00302         if (dot && !(*dot = 0) && host == hostnamebuf)
00303             return true;
00304         }
00305     return false;
00306     }
00307 
00308 #ifndef KCMRULES
00309 ShortcutDialog::ShortcutDialog( const KShortcut& cut )
00310     : KShortcutDialog( cut, false /*TODO???*/ )
00311     {
00312     // make it a popup, so that it has the grab
00313     XSetWindowAttributes attrs;
00314     attrs.override_redirect = True;
00315     XChangeWindowAttributes( qt_xdisplay(), winId(), CWOverrideRedirect, &attrs );
00316     setWFlags( WType_Popup );
00317     }
00318 
00319 void ShortcutDialog::accept()
00320     {
00321     for( int i = 0;
00322          ;
00323          ++i )
00324         {
00325         KKeySequence seq = shortcut().seq( i );
00326         if( seq.isNull())
00327             break;
00328         if( seq.key( 0 ) == Key_Escape )
00329             {
00330             reject();
00331             return;
00332             }
00333         if( seq.key( 0 ) == Key_Space )
00334             { // clear
00335             setShortcut( KShortcut());
00336             KShortcutDialog::accept();
00337             return;
00338             }
00339         if( seq.key( 0 ).modFlags() == 0 )
00340             { // no shortcuts without modifiers
00341             KShortcut cut = shortcut();
00342             cut.setSeq( i, KKeySequence());
00343             setShortcut( cut );
00344             return;
00345             }
00346         }
00347     KShortcutDialog::accept();
00348     }
00349 #endif
00350 
00351 
00352 } // namespace
00353 
00354 #ifndef KCMRULES
00355 #include "utils.moc"
00356 #endif
KDE Logo
This file is part of the documentation for kwin Library Version 3.4.3.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Fri Nov 4 00:48:57 2005 by doxygen 1.4.4 written by Dimitri van Heesch, © 1997-2003