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 Tue Aug 31 00:02:14 2004 by doxygen 1.3.8 written by Dimitri van Heesch, © 1997-2003