kdecore Library: kxmessages.cpp Source File (kdecore Library)

| # kdecore Library API Documentation
Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Namespaces | Source Files

# kxmessages.cpp

    00001 /****************************************************************************
    00002
    00003  $Id: kxmessages.cpp 257688 2003-10-10 11:20:55Z lunakl $
    00004
    00005  Copyright (C) 2001-2003 Lubos Lunak        <l.lunak@kde.org>
    00006
    00007 Permission is hereby granted, free of charge, to any person obtaining a
    00008 copy of this software and associated documentation files (the "Software"),
    00009 to deal in the Software without restriction, including without limitation
    00010 the rights to use, copy, modify, merge, publish, distribute, sublicense,
    00011 and/or sell copies of the Software, and to permit persons to whom the
    00012 Software is furnished to do so, subject to the following conditions:
    00013
    00014 The above copyright notice and this permission notice shall be included in
    00015 all copies or substantial portions of the Software.
    00016
    00017 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    00018 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    00019 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
    00020 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    00021 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
    00022 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
    00023 DEALINGS IN THE SOFTWARE.
    00024
    00025 ****************************************************************************/
    00026
    00027 #include "kxmessages.h"
    00028
    00029 #include <kapplication.h>
    00030
    00031 #ifdef Q_WS_X11 // FIXME(E): Figure out what parts we can/should emulate in QT/E
    00032
    00033 #include <X11/Xlib.h>
    00034 #include <kdebug.h>
    00035
    00036 // for broadcasting
    00037 const long BROADCAST_MASK = PropertyChangeMask;
    00038 // CHECKME
    00039
    00040 KXMessages::KXMessages( const char* accept_broadcast_P, QWidget* parent_P )
    00041     : QWidget( parent_P )
    00042     {
    00043     if( accept_broadcast_P != NULL )
    00044         {
    00045         ( void ) kapp->desktop(); //trigger desktop widget creation to select root window events
    00046         kapp->installX11EventFilter( this ); // i.e. PropertyChangeMask
    00047         accept_atom1 = XInternAtom( qt_xdisplay(), accept_broadcast_P, false );
    00048         accept_atom2 = accept_atom1;
    00049         }
    00050     else
    00051         {
    00052         accept_atom1 = accept_atom2 = None;
    00053         }
    00054     handle = new QWidget( this );
    00055     }
    00056
    00057 KXMessages::KXMessages( const char* accept_broadcast_P, QWidget* parent_P, bool obsolete_P )
    00058     : QWidget( parent_P )
    00059     {
    00060     if( accept_broadcast_P != NULL )
    00061         {
    00062         ( void ) kapp->desktop(); //trigger desktop widget creation to select root window events
    00063         kapp->installX11EventFilter( this ); // i.e. PropertyChangeMask
    00064         accept_atom2 = XInternAtom( qt_xdisplay(), accept_broadcast_P, false );
    00065         accept_atom1 = obsolete_P ? accept_atom2
    00066             : XInternAtom( qt_xdisplay(), QCString( accept_broadcast_P ) + "_BEGIN", false );
    00067         }
    00068     else
    00069         {
    00070         accept_atom1 = accept_atom2 = None;
    00071         }
    00072     handle = new QWidget( this );
    00073     }
    00074
    00075 KXMessages::~KXMessages()
    00076     {
    00077 //    delete d; no private data yet
    00078     }
    00079
    00080
    00081 void KXMessages::broadcastMessage( const char* msg_type_P, const QString& message_P )
    00082     {
    00083     broadcastMessage( msg_type_P, message_P, -1, true );
    00084     }
    00085
    00086 void KXMessages::broadcastMessage( const char* msg_type_P, const QString& message_P,
    00087     int screen_P, bool obsolete_P )
    00088     {
    00089     Atom a2 = XInternAtom( qt_xdisplay(), msg_type_P, false );
    00090     Atom a1 = obsolete_P ? a2 : XInternAtom( qt_xdisplay(), QCString( msg_type_P ) + "_BEGIN", false );
    00091     Window root = screen_P == -1 ? qt_xrootwin() : qt_xrootwin( screen_P );
    00092     send_message_internal( root, message_P, BROADCAST_MASK, qt_xdisplay(),
    00093         a1, a2, handle->winId());
    00094     }
    00095
    00096 void KXMessages::sendMessage( WId w_P, const char* msg_type_P, const QString& message_P )
    00097     {
    00098     sendMessage( w_P, msg_type_P, message_P, true );
    00099     }
    00100
    00101 void KXMessages::sendMessage( WId w_P, const char* msg_type_P, const QString& message_P,
    00102     bool obsolete_P )
    00103     {
    00104     Atom a2 = XInternAtom( qt_xdisplay(), msg_type_P, false );
    00105     Atom a1 = obsolete_P ? a2 : XInternAtom( qt_xdisplay(), QCString( msg_type_P ) + "_BEGIN", false );
    00106     send_message_internal( w_P, message_P, 0, qt_xdisplay(), a1, a2, handle->winId());
    00107     }
    00108
    00109 bool KXMessages::broadcastMessageX( Display* disp, const char* msg_type_P,
    00110     const QString& message_P )
    00111     {
    00112     return broadcastMessageX( disp, msg_type_P, message_P, -1, true );
    00113     }
    00114
    00115 bool KXMessages::broadcastMessageX( Display* disp, const char* msg_type_P,
    00116     const QString& message_P, int screen_P, bool obsolete_P )
    00117     {
    00118     if( disp == NULL )
    00119         return false;
    00120     Atom a2 = XInternAtom( disp, msg_type_P, false );
    00121     Atom a1 = obsolete_P ? a2 : XInternAtom( disp, QCString( msg_type_P ) + "_BEGIN", false );
    00122     Window root = screen_P == -1 ? DefaultRootWindow( disp ) : RootWindow( disp, screen_P );
    00123     Window win = XCreateSimpleWindow( disp, root, 0, 0, 1, 1,
    00124         0, BlackPixel( disp, screen_P == -1 ? DefaultScreen( disp ) : screen_P ),
    00125         BlackPixel( disp, screen_P == -1 ? DefaultScreen( disp ) : screen_P ));
    00126     send_message_internal( root, message_P, BROADCAST_MASK, disp,
    00127         a1, a2, win );
    00128     XDestroyWindow( disp, win );
    00129     return true;
    00130     }
    00131
    00132 bool KXMessages::sendMessageX( Display* disp, WId w_P, const char* msg_type_P,
    00133     const QString& message_P )
    00134     {
    00135     return sendMessageX( disp, w_P, msg_type_P, message_P, true );
    00136     }
    00137
    00138 bool KXMessages::sendMessageX( Display* disp, WId w_P, const char* msg_type_P,
    00139     const QString& message_P, bool obsolete_P )
    00140     {
    00141     if( disp == NULL )
    00142         return false;
    00143     Atom a2 = XInternAtom( disp, msg_type_P, false );
    00144     Atom a1 = obsolete_P ? a2 : XInternAtom( disp, QCString( msg_type_P ) + "_BEGIN", false );
    00145     Window win = XCreateSimpleWindow( disp, DefaultRootWindow( disp ), 0, 0, 1, 1,
    00146         0, BlackPixelOfScreen( DefaultScreenOfDisplay( disp )),
    00147         BlackPixelOfScreen( DefaultScreenOfDisplay( disp )));
    00148     send_message_internal( w_P, message_P, 0, disp, a1, a2, win );
    00149     XDestroyWindow( disp, win );
    00150     return true;
    00151     }
    00152
    00153 void KXMessages::send_message_internal( WId w_P, const QString& msg_P, long mask_P,
    00154     Display* disp, Atom atom1_P, Atom atom2_P, Window handle_P )
    00155     {
    00156     unsigned int pos = 0;
    00157     QCString msg = msg_P.utf8();
    00158     unsigned int len = strlen( msg );
    00159     XEvent e;
    00160     e.xclient.type = ClientMessage;
    00161     e.xclient.message_type = atom1_P; // leading message
    00162     e.xclient.display = disp;
    00163     e.xclient.window = handle_P;
    00164     e.xclient.format = 8;
    00165     do
    00166         {
    00167         unsigned int i;
    00168         for( i = 0;
    00169              i < 20 && i + pos <= len;
    00170              ++i )
    00171             e.xclient.data.b[ i ] = msg[ i + pos ];
    00172         XSendEvent( disp, w_P, false, mask_P, &e );
    00173         e.xclient.message_type = atom2_P; // following messages
    00174         pos += i;
    00175         } while( pos <= len );
    00176     XFlush( disp );
    00177     }
    00178
    00179 bool KXMessages::x11Event( XEvent* ev_P )
    00180     {
    00181     if( ev_P->type != ClientMessage || ev_P->xclient.format != 8 )
    00182         return QWidget::x11Event( ev_P );
    00183     if( ev_P->xclient.message_type != accept_atom1 && ev_P->xclient.message_type != accept_atom2 )
    00184         return QWidget::x11Event( ev_P );
    00185     char buf[ 21 ]; // can't be longer
    00186     int i;
    00187     for( i = 0;
    00188          i < 20 && ev_P->xclient.data.b[ i ] != '\0';
    00189          ++i )
    00190         buf[ i ] = ev_P->xclient.data.b[ i ];
    00191     buf[ i ] = '\0';
    00192     if( incoming_messages.contains( ev_P->xclient.window ))
    00193         {
    00194         if( ev_P->xclient.message_type == accept_atom1 && accept_atom1 != accept_atom2 )
    00195             // two different messages on the same window at the same time shouldn't happen anyway
    00196             incoming_messages[ ev_P->xclient.window ] = QCString();
    00197         incoming_messages[ ev_P->xclient.window ] += buf;
    00198         }
    00199     else
    00200         {
    00201         if( ev_P->xclient.message_type == accept_atom2 && accept_atom1 != accept_atom2 )
    00202             return false; // middle of message, but we don't have the beginning
    00203         incoming_messages[ ev_P->xclient.window ] = buf;
    00204         }
    00205     if( i < 20 ) // last message fragment
    00206         {
    00207         emit gotMessage( QString::fromUtf8( incoming_messages[ ev_P->xclient.window ] ));
    00208         incoming_messages.remove( ev_P->xclient.window );
    00209         }
    00210     return false; // lets other KXMessages instances get the event too
    00211     }
    00212
    00213 #include "kxmessages.moc"
    00214 #endif

This file is part of the documentation for kdecore Library Version 3.4.1.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sat Jun 11 20:18:12 2005 by doxygen 1.4.1 written by Dimitri van Heesch, © 1997-2003