• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdelibs API Reference
  • KDE Home
  • Contact Us
 

KDEUI

  • sources
  • kde-4.14
  • kdelibs
  • kdeui
  • util
kxmessages.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 
3  Copyright (C) 2001-2003 Lubos Lunak <l.lunak@kde.org>
4 
5 Permission is hereby granted, free of charge, to any person obtaining a
6 copy of this software and associated documentation files (the "Software"),
7 to deal in the Software without restriction, including without limitation
8 the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 and/or sell copies of the Software, and to permit persons to whom the
10 Software is furnished to do so, subject to the following conditions:
11 
12 The above copyright notice and this permission notice shall be included in
13 all copies or substantial portions of the Software.
14 
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 DEALINGS IN THE SOFTWARE.
22 
23 ****************************************************************************/
24 
25 #include "kxmessages.h"
26 
27 #ifdef Q_WS_X11 // FIXME(E): Figure out what parts we can/should emulate in QT/E
28 
29 #include <qx11info_x11.h>
30 #include <X11/Xlib.h>
31 #include <fixx11h.h>
32 #include <kapplication.h>
33 
34 class KXMessagesPrivate
35 {
36 public:
37  QWidget* handle;
38  Atom accept_atom2;
39  Atom accept_atom1;
40  QMap< WId, QByteArray > incoming_messages;
41 };
42 
43 
44 // for broadcasting
45 const long BROADCAST_MASK = PropertyChangeMask;
46 // CHECKME
47 
48 KXMessages::KXMessages( const char* accept_broadcast_P, QWidget* parent_P )
49  : QWidget( parent_P )
50  , d( new KXMessagesPrivate )
51  {
52  if( accept_broadcast_P != NULL )
53  {
54  ( void ) qApp->desktop(); //trigger desktop widget creation to select root window events
55  kapp->installX11EventFilter( this ); // i.e. PropertyChangeMask
56  d->accept_atom1 = XInternAtom( QX11Info::display(), accept_broadcast_P, false );
57  d->accept_atom2 = d->accept_atom1;
58  }
59  else
60  {
61  d->accept_atom1 = d->accept_atom2 = None;
62  }
63  d->handle = new QWidget( this );
64  }
65 
66 KXMessages::KXMessages( const char* accept_broadcast_P, QWidget* parent_P, bool obsolete_P )
67  : QWidget( parent_P )
68  , d( new KXMessagesPrivate )
69  {
70  if( accept_broadcast_P != NULL )
71  {
72  ( void ) qApp->desktop(); //trigger desktop widget creation to select root window events
73  kapp->installX11EventFilter( this ); // i.e. PropertyChangeMask
74  d->accept_atom2 = XInternAtom( QX11Info::display(), accept_broadcast_P, false );
75  d->accept_atom1 = obsolete_P ? d->accept_atom2
76  : XInternAtom( QX11Info::display(), QByteArray(QByteArray( accept_broadcast_P ) + "_BEGIN").constData(), false );
77  }
78  else
79  {
80  d->accept_atom1 = d->accept_atom2 = None;
81  }
82  d->handle = new QWidget( this );
83  }
84 
85 KXMessages::~KXMessages()
86  {
87  delete d;
88  }
89 
90 
91 void KXMessages::broadcastMessage( const char* msg_type_P, const QString& message_P )
92  {
93  broadcastMessage( msg_type_P, message_P, -1, true );
94  }
95 
96 void KXMessages::broadcastMessage( const char* msg_type_P, const QString& message_P,
97  int screen_P, bool obsolete_P )
98  {
99  Atom a2 = XInternAtom( QX11Info::display(), msg_type_P, false );
100  Atom a1 = obsolete_P ? a2 : XInternAtom( QX11Info::display(), QByteArray(QByteArray( msg_type_P ) + "_BEGIN").constData(), false );
101  Window root = screen_P == -1 ? QX11Info::appRootWindow() : QX11Info::appRootWindow( screen_P );
102  send_message_internal( root, message_P, BROADCAST_MASK, QX11Info::display(),
103  a1, a2, d->handle->winId());
104  }
105 
106 void KXMessages::sendMessage( WId w_P, const char* msg_type_P, const QString& message_P )
107  {
108  sendMessage( w_P, msg_type_P, message_P, true );
109  }
110 
111 void KXMessages::sendMessage( WId w_P, const char* msg_type_P, const QString& message_P,
112  bool obsolete_P )
113  {
114  Atom a2 = XInternAtom( QX11Info::display(), msg_type_P, false );
115  Atom a1 = obsolete_P ? a2 : XInternAtom( QX11Info::display(), QByteArray(QByteArray( msg_type_P ) + "_BEGIN").constData(), false );
116  send_message_internal( w_P, message_P, 0, QX11Info::display(), a1, a2, d->handle->winId());
117  }
118 
119 bool KXMessages::broadcastMessageX( Display* disp, const char* msg_type_P,
120  const QString& message_P )
121  {
122  return broadcastMessageX( disp, msg_type_P, message_P, -1, true );
123  }
124 
125 bool KXMessages::broadcastMessageX( Display* disp, const char* msg_type_P,
126  const QString& message_P, int screen_P, bool obsolete_P )
127  {
128  if( disp == NULL )
129  return false;
130  Atom a2 = XInternAtom( disp, msg_type_P, false );
131  Atom a1 = obsolete_P ? a2 : XInternAtom( disp, QByteArray(QByteArray( msg_type_P ) + "_BEGIN").constData(), false );
132  Window root = screen_P == -1 ? DefaultRootWindow( disp ) : RootWindow( disp, screen_P );
133  Window win = XCreateSimpleWindow( disp, root, 0, 0, 1, 1,
134  0, BlackPixel( disp, screen_P == -1 ? DefaultScreen( disp ) : screen_P ),
135  BlackPixel( disp, screen_P == -1 ? DefaultScreen( disp ) : screen_P ));
136  send_message_internal( root, message_P, BROADCAST_MASK, disp,
137  a1, a2, win );
138  XDestroyWindow( disp, win );
139  return true;
140  }
141 
142 bool KXMessages::sendMessageX( Display* disp, WId w_P, const char* msg_type_P,
143  const QString& message_P )
144  {
145  return sendMessageX( disp, w_P, msg_type_P, message_P, true );
146  }
147 
148 bool KXMessages::sendMessageX( Display* disp, WId w_P, const char* msg_type_P,
149  const QString& message_P, bool obsolete_P )
150  {
151  if( disp == NULL )
152  return false;
153  Atom a2 = XInternAtom( disp, msg_type_P, false );
154  Atom a1 = obsolete_P ? a2 : XInternAtom( disp, QByteArray(QByteArray( msg_type_P ) + "_BEGIN").constData(), false );
155  Window win = XCreateSimpleWindow( disp, DefaultRootWindow( disp ), 0, 0, 1, 1,
156  0, BlackPixelOfScreen( DefaultScreenOfDisplay( disp )),
157  BlackPixelOfScreen( DefaultScreenOfDisplay( disp )));
158  send_message_internal( w_P, message_P, 0, disp, a1, a2, win );
159  XDestroyWindow( disp, win );
160  return true;
161  }
162 
163 void KXMessages::send_message_internal( WId w_P, const QString& msg_P, long mask_P,
164  Display* disp, Atom atom1_P, Atom atom2_P, Window handle_P )
165  {
166  unsigned int pos = 0;
167  QByteArray msg = msg_P.toUtf8();
168  unsigned int len = strlen( msg );
169  XEvent e;
170  e.xclient.type = ClientMessage;
171  e.xclient.message_type = atom1_P; // leading message
172  e.xclient.display = disp;
173  e.xclient.window = handle_P;
174  e.xclient.format = 8;
175  do
176  {
177  unsigned int i;
178  for( i = 0;
179  i < 20 && i + pos <= len;
180  ++i )
181  e.xclient.data.b[ i ] = msg[ i + pos ];
182  XSendEvent( disp, w_P, false, mask_P, &e );
183  e.xclient.message_type = atom2_P; // following messages
184  pos += i;
185  } while( pos <= len );
186  XFlush( disp );
187  }
188 
189 bool KXMessages::x11Event( XEvent* ev_P )
190  {
191  if( ev_P->type != ClientMessage || ev_P->xclient.format != 8 )
192  return QWidget::x11Event( ev_P );
193  if( ev_P->xclient.message_type != d->accept_atom1 && ev_P->xclient.message_type != d->accept_atom2 )
194  return QWidget::x11Event( ev_P );
195  char buf[ 21 ]; // can't be longer
196  int i;
197  for( i = 0;
198  i < 20 && ev_P->xclient.data.b[ i ] != '\0';
199  ++i )
200  buf[ i ] = ev_P->xclient.data.b[ i ];
201  buf[ i ] = '\0';
202  if( d->incoming_messages.contains( ev_P->xclient.window ))
203  {
204  if( ev_P->xclient.message_type == d->accept_atom1 && d->accept_atom1 != d->accept_atom2 )
205  // two different messages on the same window at the same time shouldn't happen anyway
206  d->incoming_messages[ ev_P->xclient.window ] = QByteArray();
207  d->incoming_messages[ ev_P->xclient.window ] += buf;
208  }
209  else
210  {
211  if( ev_P->xclient.message_type == d->accept_atom2 && d->accept_atom1 != d->accept_atom2 )
212  return false; // middle of message, but we don't have the beginning
213  d->incoming_messages[ ev_P->xclient.window ] = buf;
214  }
215  if( i < 20 ) // last message fragment
216  {
217  emit gotMessage( QString::fromUtf8( d->incoming_messages[ ev_P->xclient.window ] ));
218  d->incoming_messages.remove( ev_P->xclient.window );
219  }
220  return false; // lets other KXMessages instances get the event too
221  }
222 
223 #include "kxmessages.moc"
224 #endif
Atom
unsigned long Atom
Definition: kapplication.h:29
KXMessages::sendMessageX
static bool sendMessageX(Display *disp, WId w, const char *msg_type, const QString &message, bool obsolete)
Sends the given message with the given message type only to given window.
Definition: kxmessages.cpp:148
kapp
#define kapp
Definition: kapplication.h:56
QWidget
kapplication.h
KXMessages::broadcastMessage
void broadcastMessage(const char *msg_type, const QString &message, int screen, bool obsolete)
Broadcasts the given message with the given message type.
Definition: kxmessages.cpp:96
QByteArray
QX11Info::appRootWindow
Qt::HANDLE appRootWindow(int screen)
QX11Info::display
Display * display()
QMap< WId, QByteArray >
KXMessages::KXMessages
KXMessages(const char *accept_broadcast, QWidget *parent, bool obsolete)
Creates an instance which will receive X messages.
Definition: kxmessages.cpp:66
KXMessages::x11Event
virtual bool x11Event(XEvent *ev)
Definition: kxmessages.cpp:189
QWidget::x11Event
virtual bool x11Event(XEvent *event)
kxmessages.h
None
QString::fromUtf8
QString fromUtf8(const char *str, int size)
QWidget::pos
QPoint pos() const
QString
BROADCAST_MASK
const long BROADCAST_MASK
Definition: kxmessages.cpp:45
fixx11h.h
KXMessages::~KXMessages
virtual ~KXMessages()
Definition: kxmessages.cpp:85
Window
KXMessages::gotMessage
void gotMessage(const QString &message)
Emitted when a message was received.
QWidget::QWidget
QWidget(QWidget *parent, QFlags< Qt::WindowType > f)
KXMessages::sendMessage
void sendMessage(WId w, const char *msg_type, const QString &message, bool obsolete)
Sends the given message with the given message type only to given window.
Definition: kxmessages.cpp:111
KXMessages::broadcastMessageX
static bool broadcastMessageX(Display *disp, const char *msg_type, const QString &message, int screen, bool obsolete)
Broadcasts the given message with the given message type.
Definition: kxmessages.cpp:125
QString::toUtf8
QByteArray toUtf8() const
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:24:00 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KDEUI

Skip menu "KDEUI"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Modules
  • Related Pages

kdelibs API Reference

Skip menu "kdelibs API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal