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