• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • twin
 

twin

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 #include <string.h>
00022 #include <netdb.h>
00023 
00024 #include <sys/socket.h>
00025 
00026 #ifndef KCMRULES
00027 
00028 #include <tqapplication.h>
00029 #include <kxerrorhandler.h>
00030 #include <assert.h>
00031 #include <kdebug.h>
00032 
00033 #include <X11/Xlib.h>
00034 #include <X11/extensions/shape.h>
00035 #include <X11/Xatom.h>
00036 
00037 #include "atoms.h"
00038 #include "notifications.h"
00039 
00040 #ifdef USE_QT4
00041 #include <Qt/qx11info_x11.h>
00042 #endif // USE_QT4
00043 
00044 #endif
00045 
00046 namespace KWinInternal
00047 {
00048 
00049 #ifndef KCMRULES
00050 
00051 // used to store the return values of
00052 // XShapeQueryExtension.
00053 // Necessary since shaped window are an extension to X
00054 int Shape::twin_shape_version = 0;
00055 int Shape::twin_shape_event = 0;
00056 
00057 // does the window w  need a shape combine mask around it?
00058 bool Shape::hasShape( WId w)
00059     {
00060     int xws, yws, xbs, ybs;
00061     unsigned int wws, hws, wbs, hbs;
00062     int boundingShaped = 0, clipShaped = 0;
00063     if (!available())
00064         return FALSE;
00065     XShapeQueryExtents(tqt_xdisplay(), w,
00066                        &boundingShaped, &xws, &yws, &wws, &hws,
00067                        &clipShaped, &xbs, &ybs, &wbs, &hbs);
00068     return boundingShaped != 0;
00069     }
00070 
00071 int Shape::shapeEvent()
00072     {
00073     return twin_shape_event;
00074     }
00075 
00076 void Shape::init()
00077     {
00078     twin_shape_version = 0;
00079     int dummy;
00080     if( !XShapeQueryExtension(tqt_xdisplay(), &twin_shape_event, &dummy))
00081         return;
00082     int major, minor;
00083     if( !XShapeQueryVersion( tqt_xdisplay(), &major, &minor ))
00084         return;
00085     twin_shape_version = major * 0x10 + minor;
00086     }
00087 
00088 void Motif::readFlags( WId w, bool& noborder, bool& resize, bool& move,
00089     bool& minimize, bool& maximize, bool& close )
00090     {
00091     Atom type;
00092     int format;
00093     unsigned long length, after;
00094     unsigned char* data;
00095     MwmHints* hints = 0;
00096     if ( XGetWindowProperty( tqt_xdisplay(), w, atoms->motif_wm_hints, 0, 5,
00097                              FALSE, atoms->motif_wm_hints, &type, &format,
00098                              &length, &after, &data ) == Success ) 
00099         {
00100         if ( data )
00101             hints = (MwmHints*) data;
00102         }
00103     noborder = false;
00104     resize = true;
00105     move = true;
00106     minimize = true;
00107     maximize = true;
00108     close = true;
00109     if ( hints ) 
00110         {
00111     // To quote from Metacity 'We support those MWM hints deemed non-stupid'
00112         if ( hints->flags & MWM_HINTS_FUNCTIONS ) 
00113             {
00114             // if MWM_FUNC_ALL is set, other flags say what to turn _off_
00115             bool set_value = (( hints->functions & MWM_FUNC_ALL ) == 0 );
00116             resize = move = minimize = maximize = close = !set_value;
00117             if( hints->functions & MWM_FUNC_RESIZE )
00118                 resize = set_value;
00119             if( hints->functions & MWM_FUNC_MOVE )
00120                 move = set_value;
00121             if( hints->functions & MWM_FUNC_MINIMIZE )
00122                 minimize = set_value;
00123             if( hints->functions & MWM_FUNC_MAXIMIZE )
00124                 maximize = set_value;
00125             if( hints->functions & MWM_FUNC_CLOSE )
00126                 close = set_value;
00127             }
00128         if ( hints->flags & MWM_HINTS_DECORATIONS ) 
00129             {
00130             if ( hints->decorations == 0 )
00131                 noborder = true;
00132             }
00133         XFree( data );
00134         }
00135     }
00136 
00137 //************************************
00138 // KWinSelectionOwner
00139 //************************************
00140 
00141 KWinSelectionOwner::KWinSelectionOwner( int screen_P )
00142     : TDESelectionOwner( make_selection_atom( screen_P ), screen_P )
00143     {
00144     }
00145 
00146 Atom KWinSelectionOwner::make_selection_atom( int screen_P )
00147     {
00148     if( screen_P < 0 )
00149         screen_P = DefaultScreen( tqt_xdisplay());
00150     char tmp[ 30 ];
00151     sprintf( tmp, "WM_S%d", screen_P );
00152     return XInternAtom( tqt_xdisplay(), tmp, False );
00153     }
00154 
00155 void KWinSelectionOwner::getAtoms()
00156     {
00157     TDESelectionOwner::getAtoms();
00158     if( xa_version == None )
00159         {
00160         Atom atoms[ 1 ];
00161         const char* const names[] =
00162             { "VERSION" };
00163         XInternAtoms( tqt_xdisplay(), const_cast< char** >( names ), 1, False, atoms );
00164         xa_version = atoms[ 0 ];
00165         }
00166     }
00167 
00168 void KWinSelectionOwner::replyTargets( Atom property_P, Window requestor_P )
00169     {
00170     TDESelectionOwner::replyTargets( property_P, requestor_P );
00171     Atom atoms[ 1 ] = { xa_version };
00172     // PropModeAppend !
00173     XChangeProperty( tqt_xdisplay(), requestor_P, property_P, XA_ATOM, 32, PropModeAppend,
00174         reinterpret_cast< unsigned char* >( atoms ), 1 );
00175     }
00176 
00177 bool KWinSelectionOwner::genericReply( Atom target_P, Atom property_P, Window requestor_P )
00178     {
00179     if( target_P == xa_version )
00180         {
00181         long version[] = { 2, 0 };
00182         XChangeProperty( tqt_xdisplay(), requestor_P, property_P, XA_INTEGER, 32,
00183             PropModeReplace, reinterpret_cast< unsigned char* >( &version ), 2 );
00184         }
00185     else
00186         return TDESelectionOwner::genericReply( target_P, property_P, requestor_P );
00187     return true;    
00188     }
00189 
00190 Atom KWinSelectionOwner::xa_version = None;
00191 
00192 
00193 TQCString getStringProperty(WId w, Atom prop, char separator)
00194     {
00195     Atom type;
00196     int format, status;
00197     unsigned long nitems = 0;
00198     unsigned long extra = 0;
00199     unsigned char *data = 0;
00200     TQCString result = "";
00201     KXErrorHandler handler; // ignore errors
00202     status = XGetWindowProperty( tqt_xdisplay(), w, prop, 0, 10000,
00203                                  FALSE, XA_STRING, &type, &format,
00204                                  &nitems, &extra, &data );
00205     if ( status == Success) 
00206         {
00207         if (data && separator) 
00208             {
00209             for (int i=0; i<(int)nitems; i++)
00210                 if (!data[i] && i+1<(int)nitems)
00211                     data[i] = separator;
00212             }
00213         if (data)
00214             result = (const char*) data;
00215         XFree(data);
00216         }
00217     return result;
00218     }
00219 
00220 static Time next_x_time;
00221 static Bool update_x_time_predicate( Display*, XEvent* event, XPointer )
00222 {
00223     if( next_x_time != CurrentTime )
00224         return False;
00225     // from qapplication_x11.cpp
00226     switch ( event->type ) {
00227     case ButtonPress:
00228     // fallthrough intended
00229     case ButtonRelease:
00230     next_x_time = event->xbutton.time;
00231     break;
00232     case MotionNotify:
00233     next_x_time = event->xmotion.time;
00234     break;
00235     case KeyPress:
00236     // fallthrough intended
00237     case KeyRelease:
00238     next_x_time = event->xkey.time;
00239     break;
00240     case PropertyNotify:
00241     next_x_time = event->xproperty.time;
00242     break;
00243     case EnterNotify:
00244     case LeaveNotify:
00245     next_x_time = event->xcrossing.time;
00246     break;
00247     case SelectionClear:
00248     next_x_time = event->xselectionclear.time;
00249     break;
00250     default:
00251     break;
00252     }
00253     return False;
00254 }
00255 
00256 /*
00257  Updates tqt_x_time. This used to simply fetch current timestamp from the server,
00258  but that can cause tqt_x_time to be newer than timestamp of events that are
00259  still in our events queue, thus e.g. making XSetInputFocus() caused by such
00260  event to be ignored. Therefore events queue is searched for first
00261  event with timestamp, and extra PropertyNotify is generated in order to make
00262  sure such event is found.
00263 */
00264 void updateXTime()
00265     {
00266     static TQWidget* w = 0;
00267     if ( !w )
00268         w = new TQWidget;
00269     long data = 1;
00270     XChangeProperty(tqt_xdisplay(), w->winId(), atoms->twin_running, atoms->twin_running, 32,
00271                     PropModeAppend, (unsigned char*) &data, 1);
00272     next_x_time = CurrentTime;
00273     XEvent dummy;
00274     XCheckIfEvent( tqt_xdisplay(), &dummy, update_x_time_predicate, NULL );
00275     if( next_x_time == CurrentTime )
00276         {
00277         XSync( tqt_xdisplay(), False );
00278         XCheckIfEvent( tqt_xdisplay(), &dummy, update_x_time_predicate, NULL );
00279         }
00280     assert( next_x_time != CurrentTime );
00281     SET_QT_X_TIME(next_x_time);
00282     XEvent ev; // remove the PropertyNotify event from the events queue
00283     XWindowEvent( tqt_xdisplay(), w->winId(), PropertyChangeMask, &ev );
00284     }
00285 
00286 static int server_grab_count = 0;
00287 
00288 void grabXServer()
00289     {
00290     if( ++server_grab_count == 1 )
00291         XGrabServer( tqt_xdisplay());
00292     }
00293 
00294 void ungrabXServer()
00295     {
00296     assert( server_grab_count > 0 );
00297     if( --server_grab_count == 0 )
00298         {
00299         XUngrabServer( tqt_xdisplay());
00300         XFlush( tqt_xdisplay());
00301         Notify::sendPendingEvents();
00302         }
00303     }
00304     
00305 bool grabbedXServer()
00306     {
00307     return server_grab_count > 0;
00308     }
00309 
00310 #endif
00311 
00312 bool isLocalMachine( const TQCString& host )
00313     {
00314 #ifdef HOST_NAME_MAX
00315     char hostnamebuf[HOST_NAME_MAX];
00316 #else
00317     char hostnamebuf[256];
00318 #endif
00319     if (gethostname (hostnamebuf, sizeof hostnamebuf) >= 0) 
00320         {
00321         hostnamebuf[sizeof(hostnamebuf)-1] = 0;
00322         if (host == hostnamebuf)
00323             return true;
00324         if( char *dot = strchr(hostnamebuf, '.'))
00325             {
00326             *dot = '\0';
00327             if( host == hostnamebuf )
00328                 return true;
00329             }
00330         else
00331             { // e.g. LibreOffice likes to give FQDN, even if gethostname() doesn't include domain
00332             struct addrinfo hints, *res, *addr;
00333             bool is_local = false;
00334 
00335             memset (&hints, 0, sizeof (hints));
00336             hints.ai_family = PF_UNSPEC;
00337             hints.ai_socktype = SOCK_STREAM;
00338             hints.ai_flags |= AI_CANONNAME;
00339 
00340             if( getaddrinfo( host, NULL, &hints, &res ) != 0)
00341                 return false;
00342             for(addr = res; !is_local && addr; addr = addr->ai_next)
00343                 {
00344                 if( addr->ai_canonname &&
00345                     host == TQCString( addr->ai_canonname ))
00346                     is_local = true;
00347                 }
00348             freeaddrinfo(res);
00349             return is_local;
00350             }
00351         }
00352     return false;
00353     }
00354 
00355 #ifndef KCMRULES
00356 ShortcutDialog::ShortcutDialog( const TDEShortcut& cut )
00357     : TDEShortcutDialog( cut, false /*TODO???*/ )
00358     {
00359     // make it a popup, so that it has the grab
00360     XSetWindowAttributes attrs;
00361     attrs.override_redirect = True;
00362     XChangeWindowAttributes( tqt_xdisplay(), winId(), CWOverrideRedirect, &attrs );
00363     setWFlags( WType_Popup );
00364     }
00365 
00366 void ShortcutDialog::accept()
00367     {
00368     for( int i = 0;
00369          ;
00370          ++i )
00371         {
00372         KKeySequence seq = shortcut().seq( i );
00373         if( seq.isNull())
00374             break;
00375         if( seq.key( 0 ) == Key_Escape )
00376             {
00377             reject();
00378             return;
00379             }
00380         if( seq.key( 0 ) == Key_Space )
00381             { // clear
00382             setShortcut( TDEShortcut());
00383             TDEShortcutDialog::accept();
00384             return;
00385             }
00386         if( seq.key( 0 ).modFlags() == 0 )
00387             { // no shortcuts without modifiers
00388             TDEShortcut cut = shortcut();
00389             cut.setSeq( i, KKeySequence());
00390             setShortcut( cut );
00391             return;
00392             }
00393         }
00394     TDEShortcutDialog::accept();
00395     }
00396 
00397 // Workaround for Qt bug causing #119142 - wheel event causes only calling
00398 // of hide() but not close(), so dialog closing is not performed.
00399 // Possible recursive calling close->hide->close should be fine, as close()
00400 // has checks against that.
00401 void ShortcutDialog::hide()
00402     {
00403     close();
00404     return TDEShortcutDialog::hide();
00405     }
00406 
00407 #endif
00408 
00409 
00410 } // namespace
00411 
00412 #ifndef KCMRULES
00413 #include "utils.moc"
00414 #endif

twin

Skip menu "twin"
  • Main Page
  • Alphabetical List
  • Class List
  • File List
  • Class Members

twin

Skip menu "twin"
  • kate
  • libkonq
  • twin
  •   lib
Generated for twin by doxygen 1.6.3
This website is maintained by Timothy Pearson.