kdecore Library API Documentation

kxmessages.cpp

00001 /**************************************************************************** 00002 00003 $Id: kxmessages.cpp,v 1.9 2003/10/10 11:20:54 lunakl Exp $ 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
KDE Logo
This file is part of the documentation for kdecore Library Version 3.2.3.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sun Oct 10 18:54:57 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003