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