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 #ifndef None // CHECKME
00037 #define None 0
00038 #endif
00039
00040
00041 const long BROADCAST_MASK = PropertyChangeMask;
00042
00043
00044 KXMessages::KXMessages( const char* accept_broadcast_P, QWidget* parent_P )
00045 : QWidget( parent_P )
00046 {
00047 if( accept_broadcast_P != NULL )
00048 {
00049 ( void ) kapp->desktop();
00050 kapp->installX11EventFilter( this );
00051 accept_atom = XInternAtom( qt_xdisplay(), accept_broadcast_P, false );
00052 cached_atom_name = accept_broadcast_P;
00053 cached_atom = accept_atom;
00054 }
00055 else
00056 {
00057 accept_atom = None;
00058 cached_atom_name = "";
00059 }
00060 handle = new QWidget( this );
00061 }
00062
00063 KXMessages::~KXMessages()
00064 {
00065
00066 }
00067
00068 void KXMessages::broadcastMessage( const char* msg_type_P, const QString& message_P )
00069 {
00070 if( cached_atom_name != msg_type_P )
00071 {
00072 cached_atom = XInternAtom( qt_xdisplay(), msg_type_P, false );
00073 cached_atom_name = msg_type_P;
00074 }
00075 send_message_internal( qt_xrootwin(), message_P, BROADCAST_MASK, qt_xdisplay(),
00076 cached_atom, handle->winId());
00077 }
00078
00079 void KXMessages::sendMessage( WId w_P, const char* msg_type_P, const QString& message_P )
00080 {
00081 if( cached_atom_name != msg_type_P )
00082 {
00083 cached_atom = XInternAtom( qt_xdisplay(), msg_type_P, false );
00084 cached_atom_name = msg_type_P;
00085 }
00086 send_message_internal( w_P, message_P, 0, qt_xdisplay(), cached_atom, handle->winId());
00087 }
00088
00089 bool KXMessages::broadcastMessageX( Display* disp, const char* msg_type_P,
00090 const QString& message_P )
00091 {
00092 if( disp == NULL )
00093 return false;
00094 Atom atom = XInternAtom( disp, msg_type_P, false );
00095 Window win = XCreateSimpleWindow( disp, DefaultRootWindow( disp ), 0, 0, 1, 1,
00096 0, BlackPixelOfScreen( DefaultScreenOfDisplay( disp )),
00097 BlackPixelOfScreen( DefaultScreenOfDisplay( disp )));
00098 send_message_internal( DefaultRootWindow( disp ), message_P, BROADCAST_MASK, disp,
00099 atom, win );
00100 XDestroyWindow( disp, win );
00101 return true;
00102 }
00103
00104 bool KXMessages::sendMessageX( Display* disp, WId w_P, const char* msg_type_P,
00105 const QString& message_P )
00106 {
00107 if( disp == NULL )
00108 return false;
00109 Atom atom = XInternAtom( disp, msg_type_P, false );
00110 Window win = XCreateSimpleWindow( disp, DefaultRootWindow( disp ), 0, 0, 1, 1,
00111 0, BlackPixelOfScreen( DefaultScreenOfDisplay( disp )),
00112 BlackPixelOfScreen( DefaultScreenOfDisplay( disp )));
00113 send_message_internal( w_P, message_P, 0, disp, atom, win );
00114 XDestroyWindow( disp, win );
00115 return true;
00116 }
00117
00118 void KXMessages::send_message_internal( WId w_P, const QString& msg_P, long mask_P,
00119 Display* disp, Atom atom_P, Window handle_P )
00120 {
00121 unsigned int pos = 0;
00122 QCString msg = msg_P.utf8();
00123 unsigned int len = strlen( msg );
00124 XEvent e;
00125 e.xclient.type = ClientMessage;
00126 e.xclient.message_type = atom_P;
00127 e.xclient.display = disp;
00128 e.xclient.window = handle_P;
00129 e.xclient.format = 8;
00130 do
00131 {
00132 unsigned int i;
00133 for( i = 0;
00134 i < 20 && i + pos <= len;
00135 ++i )
00136 e.xclient.data.b[ i ] = msg[ i + pos ];
00137 XSendEvent( disp, w_P, false, mask_P, &e );
00138 pos += i;
00139 } while( pos <= len );
00140 XFlush( disp );
00141 }
00142
00143 bool KXMessages::x11Event( XEvent* ev_P )
00144 {
00145 if( ev_P->type != ClientMessage || ev_P->xclient.message_type != accept_atom
00146 || ev_P->xclient.format != 8 )
00147 return QWidget::x11Event( ev_P );
00148 char buf[ 21 ];
00149 int i;
00150 for( i = 0;
00151 i < 20 && ev_P->xclient.data.b[ i ] != '\0';
00152 ++i )
00153 buf[ i ] = ev_P->xclient.data.b[ i ];
00154 buf[ i ] = '\0';
00155 if( incoming_messages.contains( ev_P->xclient.window ))
00156 incoming_messages[ ev_P->xclient.window ] += buf;
00157 else
00158 incoming_messages[ ev_P->xclient.window ] = buf;
00159 if( i < 20 )
00160 {
00161 emit gotMessage( QString::fromUtf8( incoming_messages[ ev_P->xclient.window ] ));
00162 incoming_messages.remove( ev_P->xclient.window );
00163 }
00164 return false;
00165 }
00166
00167 #undef None
00168
00169 #include "kxmessages.moc"
00170 #endif