00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
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
00037 const long BROADCAST_MASK = PropertyChangeMask;
00038
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();
00046 kapp->installX11EventFilter( this );
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();
00063 kapp->installX11EventFilter( this );
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
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;
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;
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 ];
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
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;
00203 incoming_messages[ ev_P->xclient.window ] = buf;
00204 }
00205 if( i < 20 )
00206 {
00207 emit gotMessage( QString::fromUtf8( incoming_messages[ ev_P->xclient.window ] ));
00208 incoming_messages.remove( ev_P->xclient.window );
00209 }
00210 return false;
00211 }
00212
00213 #include "kxmessages.moc"
00214 #endif