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