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