• Skip to content
  • Skip to link menu
KDE 4.2 API Reference
  • KDE API Reference
  • kdelibs
  • Sitemap
  • Contact Us
 

KDEUI

kxmessages.cpp

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

KDEUI

Skip menu "KDEUI"
  • Main Page
  • Modules
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • Kross
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.5.7
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal