1 /****************************************************************************
2 **
3 ** Copyright (C) 2015 The Qt Company Ltd.
4 ** Contact: http://www.qt.io/licensing/
5 **
6 ** This file is part of the QtGui module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see http://www.qt.io/terms-conditions. For further
15 ** information use the contact form at http://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 or version 3 as published by the Free
20 ** Software Foundation and appearing in the file LICENSE.LGPLv21 and
21 ** LICENSE.LGPLv3 included in the packaging of this file. Please review the
22 ** following information to ensure the GNU Lesser General Public License
23 ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
24 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 **
26 ** As a special exception, The Qt Company gives you certain additional
27 ** rights. These rights are described in The Qt Company LGPL Exception
28 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 **
30 ** GNU General Public License Usage
31 ** Alternatively, this file may be used under the terms of the GNU
32 ** General Public License version 3.0 as published by the Free Software
33 ** Foundation and appearing in the file LICENSE.GPL included in the
34 ** packaging of this file.  Please review the following information to
35 ** ensure the GNU General Public License version 3.0 requirements will be
36 ** met: http://www.gnu.org/copyleft/gpl.html.
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #ifndef QWSCOMMAND_QWS_P_H
43 #define QWSCOMMAND_QWS_P_H
44 
45 //
46 //  W A R N I N G
47 //  -------------
48 //
49 // This file is not part of the Qt API.  It exists purely as an
50 // implementation detail.  This header file may change from version to
51 // version without notice, or even be removed.
52 //
53 // We mean it.
54 //
55 
56 // When reading commands "off the wire" in the server, the rawLen is read
57 // and then that many bytes are allocated.  If the rawLen is corrupted (or
58 // the protocol is being attacked) too many bytes can be allocated.  Set
59 // a hard limit here for security.
60 #define MAX_COMMAND_SIZE (16 * 1024)
61 
62 #include <QtCore/qbytearray.h>
63 #include <QtGui/qwsutils_qws.h>
64 #include <QtGui/qfont.h>
65 #include <QtCore/qdatastream.h>
66 #include <QtCore/qvariant.h>
67 #include <QtCore/qrect.h>
68 #include <QtGui/qregion.h>
69 #include <QtCore/qvector.h>
70 #include <QtCore/qvarlengtharray.h>
71 #include <QtGui/qwsevent_qws.h>
72 #include "qwsprotocolitem_qws.h"
73 
74 QT_BEGIN_NAMESPACE
75 
76 QT_MODULE(Gui)
77 
78 class QRect;
79 
80 /*********************************************************************
81  *
82  * Functions to read/write commands on/from a socket
83  *
84  *********************************************************************/
85 #ifndef QT_NO_QWS_MULTIPROCESS
86 void qws_write_command(QIODevice *socket, int type, char *simpleData, int simpleLen, char *rawData, int rawLen);
87 bool qws_read_command(QIODevice *socket, char *&simpleData, int &simpleLen, char *&rawData, int &rawLen, int &bytesRead);
88 #endif
89 
90 struct QWSCommand : QWSProtocolItem
91 {
QWSCommandQWSCommand92     QWSCommand(int t, int len, char *ptr) : QWSProtocolItem(t,len,ptr) {}
93 
94     enum Type {
95         Unknown = 0,
96         Create,
97         Shutdown,
98         Region,
99         RegionMove,
100         RegionDestroy,
101         SetProperty,
102         AddProperty,
103         RemoveProperty,
104         GetProperty,
105         SetSelectionOwner,
106         ConvertSelection,
107         RequestFocus,
108         ChangeAltitude,
109         SetOpacity,
110         DefineCursor,
111         SelectCursor,
112         PositionCursor,
113         GrabMouse,
114         PlaySound,
115         QCopRegisterChannel,
116         QCopSend,
117         RegionName,
118         Identify,
119         GrabKeyboard,
120         RepaintRegion,
121         IMMouse,
122         IMUpdate,
123         IMResponse,
124         Embed,
125         Font,
126         ScreenTransform
127     };
128     static QWSCommand *factory(int type);
129 };
130 
131 const char *qws_getCommandTypeString( QWSCommand::Type tp );
132 
133 #ifndef QT_NO_DEBUG
134 class QDebug;
135 QDebug &operator<<(QDebug &dbg, QWSCommand::Type tp);
136 #endif // QT_NO_DEBUG
137 
138 /*********************************************************************
139  *
140  * Commands
141  *
142  *********************************************************************/
143 
144 struct QWSIdentifyCommand : public QWSCommand
145 {
QWSIdentifyCommandQWSIdentifyCommand146     QWSIdentifyCommand() :
147         QWSCommand(QWSCommand::Identify,
148                    sizeof(simpleData), reinterpret_cast<char *>(&simpleData))
149     {
150         simpleData.idLen = 0;
151         simpleData.idLock = -1;
152     }
153 
setDataQWSIdentifyCommand154     void setData(const char *d, int len, bool allocateMem) {
155         QWSCommand::setData(d, len, allocateMem);
156         if ( simpleData.idLen > MAX_COMMAND_SIZE )
157         {
158             qWarning( "Identify command - name length %d - too big!", simpleData.idLen );
159             simpleData.idLen = MAX_COMMAND_SIZE;
160         }
161         if ( simpleData.idLen * int(sizeof(QChar)) > len )
162         {
163             qWarning( "Identify command - name length %d - buffer size %d - buffer overrun!", simpleData.idLen, len );
164         }
165         else
166         {
167             id = QString(reinterpret_cast<const QChar*>(d), simpleData.idLen);
168         }
169     }
170 
setIdQWSIdentifyCommand171     void setId(const QString& i, int lock)
172     {
173         id = i;
174         simpleData.idLen = id.length();
175         simpleData.idLock = lock;
176         setData(reinterpret_cast<const char*>(id.unicode()), simpleData.idLen*2, true);
177     }
178 
179     struct SimpleData {
180         int idLen;
181         int idLock;
182     } simpleData;
183     QString id;
184 };
185 
186 struct QWSCreateCommand : public QWSCommand
187 {
188     QWSCreateCommand(int n = 1) :
QWSCommandQWSCreateCommand189         QWSCommand(QWSCommand::Create, sizeof(count),
190                    reinterpret_cast<char *>(&count)), count(n) {}
191     int count;
192 };
193 
194 struct QWSRegionNameCommand : public QWSCommand
195 {
QWSRegionNameCommandQWSRegionNameCommand196     QWSRegionNameCommand() :
197         QWSCommand(QWSCommand::RegionName,
198                     sizeof(simpleData), reinterpret_cast<char *>(&simpleData)) {}
199 
setDataQWSRegionNameCommand200     void setData(const char *d, int len, bool allocateMem) {
201         QWSCommand::setData(d, len, allocateMem);
202         if ( simpleData.nameLen > MAX_COMMAND_SIZE )
203         {
204             qWarning( "region name command - name length too big!" );
205             simpleData.nameLen = MAX_COMMAND_SIZE;
206         }
207         if ( simpleData.captionLen > MAX_COMMAND_SIZE )
208         {
209             qWarning( "region name command - caption length too big!" );
210             simpleData.captionLen = MAX_COMMAND_SIZE;
211         }
212         if ( simpleData.nameLen + simpleData.captionLen > len )
213         {
214             qWarning( "region name command - name length %d - caption length %d - buffer size %d - buffer overrun!",
215                       simpleData.nameLen, simpleData.captionLen, len );
216 
217         }
218         else
219         {
220             name = QString(reinterpret_cast<const QChar*>(d), simpleData.nameLen/2);
221             d += simpleData.nameLen;
222             caption = QString(reinterpret_cast<const QChar*>(d), simpleData.captionLen/2);
223         }
224     }
225 
setNameQWSRegionNameCommand226     void setName(const QString& n, const QString &c)
227     {
228         name = n;
229         caption = c;
230         int l = simpleData.nameLen = name.length()*2;
231         l += simpleData.captionLen = caption.length()*2;
232         char *d = new char[l];
233         memcpy(d, name.unicode(), simpleData.nameLen);
234         memcpy(d+simpleData.nameLen, caption.unicode(), simpleData.captionLen);
235         setData(d, l, true);
236         delete[] d;
237     }
238 
239     struct SimpleData {
240         int windowid;
241         int nameLen;
242         int captionLen;
243     } simpleData;
244     QString name;
245     QString caption;
246 };
247 
248 struct QWSRegionCommand : public QWSCommand
249 {
QWSRegionCommandQWSRegionCommand250     QWSRegionCommand() :
251         QWSCommand(QWSCommand::Region, sizeof(simpleData),
252                     reinterpret_cast<char*>(&simpleData)) {}
253 
254     void setData(const char *d, int len, bool allocateMem = true) {
255         QWSCommand::setData(d, len, allocateMem);
256 
257         if( simpleData.nrectangles * int(sizeof(QRect)) + simpleData.surfacekeylength * int(sizeof(QChar)) + simpleData.surfacedatalength * int(sizeof(char)) > len )
258         {
259             qWarning( "region command - rectangle count %d - surface key length %d - region data size %d - buffer size %d - buffer overrun!",
260                       simpleData.nrectangles, simpleData.surfacekeylength, simpleData.surfacedatalength, len );
261         }
262         else
263         {
264             char *ptr = rawDataPtr;
265 
266             region.setRects(reinterpret_cast<QRect*>(ptr), simpleData.nrectangles);
267             ptr += simpleData.nrectangles * sizeof(QRect);
268 
269             surfaceKey = QString(reinterpret_cast<QChar*>(ptr),
270                              simpleData.surfacekeylength);
271             ptr += simpleData.surfacekeylength * sizeof(QChar);
272 
273             surfaceData = QByteArray(ptr, simpleData.surfacedatalength);
274         }
275     }
276 
setDataQWSRegionCommand277     void setData(int id, const QString &key, const QByteArray &data,
278                  const QRegion &reg)
279     {
280         surfaceKey = key;
281         surfaceData = data;
282         region = reg;
283 
284         const QVector<QRect> rects = reg.rects();
285 
286         simpleData.windowid = id;
287         simpleData.surfacekeylength = key.size();
288         simpleData.surfacedatalength = data.size();
289         simpleData.nrectangles = rects.count();
290 
291         QVarLengthArray<char, 256> buffer;
292         buffer.append(reinterpret_cast<const char*>(rects.constData()),
293                       rects.count() * sizeof(QRect));
294         buffer.append(reinterpret_cast<const char*>(key.constData()),
295                       key.size() * sizeof(QChar));
296         buffer.append(data, data.size());
297 
298         QWSCommand::setData(buffer.constData(), buffer.size(), true);
299     }
300 
301     /* XXX this will pad out in a compiler dependent way,
302        should move nrectangles to before windowtype, and
303        add reserved bytes.
304        Symptom will be valgrind reported uninitialized memory usage
305        */
306     struct SimpleData {
307         int windowid;
308         int surfacekeylength;
309         int surfacedatalength;
310         int nrectangles;
311     } simpleData;
312 
313     QString surfaceKey;
314     QByteArray surfaceData;
315     QRegion region;
316 };
317 
318 struct QWSSetOpacityCommand : public QWSCommand
319 {
QWSSetOpacityCommandQWSSetOpacityCommand320     QWSSetOpacityCommand() :
321         QWSCommand(QWSCommand::SetOpacity, sizeof(simpleData),
322                     reinterpret_cast<char*>(&simpleData)) {}
323 
324     struct SimpleData {
325         int windowid;
326         uchar opacity;
327     } simpleData;
328 };
329 
330 struct QWSRegionMoveCommand : public QWSCommand
331 {
QWSRegionMoveCommandQWSRegionMoveCommand332     QWSRegionMoveCommand() :
333         QWSCommand(QWSCommand::RegionMove, sizeof(simpleData),
334                     reinterpret_cast<char*>(&simpleData)) {}
335 
336     struct SimpleData {
337         int windowid;
338         int dx;
339         int dy;
340     } simpleData;
341 
342 };
343 
344 struct QWSRegionDestroyCommand : public QWSCommand
345 {
QWSRegionDestroyCommandQWSRegionDestroyCommand346     QWSRegionDestroyCommand() :
347         QWSCommand(QWSCommand::RegionDestroy, sizeof(simpleData),
348                     reinterpret_cast<char*>(&simpleData)) {}
349 
350     struct SimpleData {
351         int windowid;
352     } simpleData;
353 
354 };
355 
356 struct QWSRequestFocusCommand : public QWSCommand
357 {
QWSRequestFocusCommandQWSRequestFocusCommand358     QWSRequestFocusCommand() :
359         QWSCommand(QWSCommand::RequestFocus, sizeof(simpleData), reinterpret_cast<char*>(&simpleData)) {}
360 
361     struct SimpleData {
362         int windowid;
363         int flag;
364     } simpleData;
365 };
366 
367 struct QWSChangeAltitudeCommand : public QWSCommand
368 {
QWSChangeAltitudeCommandQWSChangeAltitudeCommand369     QWSChangeAltitudeCommand() :
370         QWSCommand(QWSCommand::ChangeAltitude, sizeof(simpleData), reinterpret_cast<char*>(&simpleData)) {}
371 
372     enum Altitude {
373         Lower = -1,
374         Raise = 0,
375         StaysOnTop = 1
376     };
377 
378     struct SimpleData {
379         int windowid;
380         Altitude altitude;
381         bool fixed;
382     } simpleData;
383 
384 };
385 
386 
387 struct QWSAddPropertyCommand : public QWSCommand
388 {
QWSAddPropertyCommandQWSAddPropertyCommand389     QWSAddPropertyCommand() :
390         QWSCommand(QWSCommand::AddProperty, sizeof(simpleData), reinterpret_cast<char*>(&simpleData)) {}
391 
392     struct SimpleData {
393         int windowid, property;
394     } simpleData;
395 
396 };
397 
398 struct QWSSetPropertyCommand : public QWSCommand
399 {
QWSSetPropertyCommandQWSSetPropertyCommand400     QWSSetPropertyCommand() :
401         QWSCommand(QWSCommand::SetProperty, sizeof(simpleData),
402                     reinterpret_cast<char*>(&simpleData)) { data = 0; }
403 
404     void setData(const char *d, int len, bool allocateMem = true) {
405         QWSCommand::setData(d, len, allocateMem);
406         data = rawDataPtr;
407     }
408 
409     struct SimpleData {
410         int windowid, property, mode;
411     } simpleData;
412 
413     char *data;
414 };
415 
416 struct QWSRepaintRegionCommand : public QWSCommand
417 {
QWSRepaintRegionCommandQWSRepaintRegionCommand418     QWSRepaintRegionCommand() :
419         QWSCommand(QWSCommand::RepaintRegion, sizeof(simpleData),
420                     reinterpret_cast<char*>(&simpleData)) {}
421 
422     void setData(const char *d, int len, bool allocateMem = true) {
423         QWSCommand::setData(d, len, allocateMem);
424 
425         if( simpleData.nrectangles * int(sizeof(QRect)) > len )
426         {
427             qWarning( "repaint region command - region rectangle count %d - buffer size %d - buffer overrun",
428                       simpleData.nrectangles, len );
429 
430             simpleData.nrectangles = len / sizeof(QRect);
431         }
432         rectangles = reinterpret_cast<QRect *>(rawDataPtr);
433     }
434 
435     struct SimpleData {
436         int windowid;
437         int windowFlags;
438         bool opaque;
439         int nrectangles;
440     } simpleData;
441 
442     QRect * rectangles;
443 
444 };
445 
446 struct QWSRemovePropertyCommand : public QWSCommand
447 {
QWSRemovePropertyCommandQWSRemovePropertyCommand448     QWSRemovePropertyCommand() :
449         QWSCommand(QWSCommand::RemoveProperty, sizeof(simpleData), reinterpret_cast<char*>(&simpleData)) {}
450 
451     struct SimpleData {
452         int windowid, property;
453     } simpleData;
454 
455 };
456 
457 struct QWSGetPropertyCommand : public QWSCommand
458 {
QWSGetPropertyCommandQWSGetPropertyCommand459     QWSGetPropertyCommand() :
460         QWSCommand(QWSCommand::GetProperty, sizeof(simpleData), reinterpret_cast<char*>(&simpleData)) {}
461 
462     struct SimpleData {
463         int windowid, property;
464     } simpleData;
465 
466 };
467 
468 struct QWSSetSelectionOwnerCommand : public QWSCommand
469 {
QWSSetSelectionOwnerCommandQWSSetSelectionOwnerCommand470     QWSSetSelectionOwnerCommand() :
471         QWSCommand(QWSCommand::SetSelectionOwner,
472                     sizeof(simpleData), reinterpret_cast<char*>(&simpleData)) {}
473 
474     struct SimpleData {
475         int windowid;
476         int hour, minute, sec, ms; // time
477     } simpleData;
478 
479 };
480 
481 struct QWSConvertSelectionCommand : public QWSCommand
482 {
QWSConvertSelectionCommandQWSConvertSelectionCommand483     QWSConvertSelectionCommand() :
484         QWSCommand(QWSCommand::ConvertSelection,
485                     sizeof(simpleData), reinterpret_cast<char*>(&simpleData)) {}
486 
487     struct SimpleData {
488         int requestor; // requestor window of the selection
489         int selection; // property on requestor into which the selection should be stored
490         int mimeTypes; // property ion requestor in which the mimetypes, in which the selection may be, are stored
491     } simpleData;
492 
493 };
494 
495 struct QWSDefineCursorCommand : public QWSCommand
496 {
QWSDefineCursorCommandQWSDefineCursorCommand497     QWSDefineCursorCommand() :
498         QWSCommand(QWSCommand::DefineCursor,
499                     sizeof(simpleData), reinterpret_cast<char *>(&simpleData)) {}
500 
501     void setData(const char *d, int len, bool allocateMem = true) {
502         QWSCommand::setData(d, len, allocateMem);
503         data = reinterpret_cast<unsigned char *>(rawDataPtr);
504         if (simpleData.height * ((simpleData.width+7) / 8) > len) {
505             qWarning("define cursor command - width %d height %d- buffer size %d - buffer overrun",
506                      simpleData.width, simpleData.height, len );
507             simpleData.width = simpleData.height = 0;
508         }
509     }
510 
511     struct SimpleData {
512         int width;
513         int height;
514         int hotX;
515         int hotY;
516         int id;
517     } simpleData;
518 
519     unsigned char *data;
520 };
521 
522 struct QWSSelectCursorCommand : public QWSCommand
523 {
QWSSelectCursorCommandQWSSelectCursorCommand524     QWSSelectCursorCommand() :
525         QWSCommand(QWSCommand::SelectCursor,
526                     sizeof(simpleData), reinterpret_cast<char *>(&simpleData)) {}
527 
528     struct SimpleData {
529         int windowid;
530         int id;
531     } simpleData;
532 };
533 
534 struct QWSPositionCursorCommand : public QWSCommand
535 {
QWSPositionCursorCommandQWSPositionCursorCommand536     QWSPositionCursorCommand() :
537         QWSCommand(QWSCommand::PositionCursor,
538                     sizeof(simpleData), reinterpret_cast<char *>(&simpleData)) {}
539 
540     struct SimpleData {
541         int newX;
542         int newY;
543     } simpleData;
544 };
545 
546 struct QWSGrabMouseCommand : public QWSCommand
547 {
QWSGrabMouseCommandQWSGrabMouseCommand548     QWSGrabMouseCommand() :
549         QWSCommand(QWSCommand::GrabMouse,
550                     sizeof(simpleData), reinterpret_cast<char *>(&simpleData)) {}
551 
552     struct SimpleData {
553         int windowid;
554         bool grab;  // grab or ungrab?
555     } simpleData;
556 };
557 
558 struct QWSGrabKeyboardCommand : public QWSCommand
559 {
QWSGrabKeyboardCommandQWSGrabKeyboardCommand560     QWSGrabKeyboardCommand() :
561         QWSCommand(QWSCommand::GrabKeyboard,
562                     sizeof(simpleData), reinterpret_cast<char *>(&simpleData)) {}
563 
564     struct SimpleData {
565         int windowid;
566         bool grab;  // grab or ungrab?
567     } simpleData;
568 };
569 
570 #ifndef QT_NO_SOUND
571 struct QWSPlaySoundCommand : public QWSCommand
572 {
QWSPlaySoundCommandQWSPlaySoundCommand573     QWSPlaySoundCommand() :
574         QWSCommand(QWSCommand::PlaySound,
575                     sizeof(simpleData), reinterpret_cast<char *>(&simpleData)) {}
576 
setDataQWSPlaySoundCommand577     void setData(const char *d, int len, bool allocateMem) {
578         QWSCommand::setData(d, len, allocateMem);
579         filename = QString(reinterpret_cast<QChar*>(rawDataPtr),len/2);
580     }
setFileNameQWSPlaySoundCommand581     void setFileName(const QString& n)
582     {
583         setData(reinterpret_cast<const char*>(n.unicode()), n.length()*2, true);
584     }
585 
586     struct SimpleData {
587         int windowid;
588     } simpleData;
589     QString filename;
590 };
591 #endif
592 
593 
594 #ifndef QT_NO_COP
595 struct QWSQCopRegisterChannelCommand : public QWSCommand
596 {
QWSQCopRegisterChannelCommandQWSQCopRegisterChannelCommand597     QWSQCopRegisterChannelCommand() :
598         QWSCommand(QWSCommand::QCopRegisterChannel,
599                     sizeof(simpleData), reinterpret_cast<char *>(&simpleData)) {}
600 
setDataQWSQCopRegisterChannelCommand601     void setData(const char *d, int len, bool allocateMem) {
602         QWSCommand::setData(d, len, allocateMem);
603         if ( simpleData.chLen > MAX_COMMAND_SIZE )
604         {
605             qWarning( "Command channel name too large!" );
606             simpleData.chLen = MAX_COMMAND_SIZE;
607         }
608         if( simpleData.chLen * int(sizeof(QChar)) > len )
609         {
610             qWarning( "register qcop channel command - channel name length %d - buffer size %d - buffer overrun!", simpleData.chLen, len );
611         }
612         else
613         {
614             channel = QString(reinterpret_cast<const QChar*>(d), simpleData.chLen);
615         }
616     }
617 
setChannelQWSQCopRegisterChannelCommand618     void setChannel(const QString& n)
619     {
620         channel = n;
621         simpleData.chLen = channel.length();
622         setData(reinterpret_cast<const char*>(channel.unicode()), simpleData.chLen*2, true);
623     }
624 
625     struct SimpleData {
626         int chLen;
627     } simpleData;
628     QString channel;
629 };
630 
631 struct QWSQCopSendCommand : public QWSCommand
632 {
QWSQCopSendCommandQWSQCopSendCommand633     QWSQCopSendCommand() :
634         QWSCommand(QWSCommand::QCopSend,
635                     sizeof(simpleData), reinterpret_cast<char *>(&simpleData)) {}
636 
setDataQWSQCopSendCommand637     void setData(const char *d, int len, bool allocateMem) {
638         QWSCommand::setData(d, len, allocateMem);
639 
640         if( simpleData.clen * int(sizeof(QChar)) + simpleData.mlen * int(sizeof(QChar)) + simpleData.dlen * int(sizeof(char)) > len )
641         {
642             qWarning( "qcop send command - channel name length %d - message name length %d - data size %d - buffer size %d - buffer overrun!",
643                       simpleData.clen, simpleData.mlen, simpleData.dlen, len );
644         }
645         else
646         {
647             const QChar *cd = reinterpret_cast<const QChar*>(d);
648             channel = QString(cd,simpleData.clen); cd += simpleData.clen;
649             message = QString(cd,simpleData.mlen);
650             d += simpleData.clen*sizeof(QChar) + simpleData.mlen*sizeof(QChar);
651             data = QByteArray(d, simpleData.dlen);
652         }
653     }
654 
setMessageQWSQCopSendCommand655     void setMessage(const QString &c, const QString &m,
656                      const QByteArray &data)
657     {
658         this->channel = c;
659         this->message = m;
660         this->data = data;
661         simpleData.clen = c.length();
662         simpleData.mlen = m.length();
663         simpleData.dlen = data.size();
664         int l = simpleData.clen*sizeof(QChar);
665         l += simpleData.mlen*sizeof(QChar);
666         l += simpleData.dlen;
667         char *tmp = new char[l];
668         char *d = tmp;
669         memcpy(d, c.unicode(), simpleData.clen*sizeof(QChar));
670         d += simpleData.clen*sizeof(QChar);
671         memcpy(d, m.unicode(), simpleData.mlen*sizeof(QChar));
672         d += simpleData.mlen*sizeof(QChar);
673         memcpy(d, data.data(), simpleData.dlen);
674         QWSCommand::setData(tmp, l, false);
675         deleteRaw = true;
676     }
677 
678     struct SimpleData {
679         int clen;
680         int mlen;
681         int dlen;
682     } simpleData;
683     QString channel;
684     QString message;
685     QByteArray data;
686 };
687 
688 #endif
689 
690 
691 #ifndef QT_NO_QWS_INPUTMETHODS
692 
693 struct QWSIMMouseCommand : public QWSCommand
694 {
QWSIMMouseCommandQWSIMMouseCommand695     QWSIMMouseCommand() :
696         QWSCommand(QWSCommand::IMMouse,
697                     sizeof(simpleData), reinterpret_cast<char *>(&simpleData)) {}
698 
699     struct SimpleData {
700         int windowid;
701         int state;
702         int index;
703     } simpleData;
704 };
705 
706 
707 struct QWSIMResponseCommand : public QWSCommand
708 {
QWSIMResponseCommandQWSIMResponseCommand709     QWSIMResponseCommand() :
710         QWSCommand(QWSCommand::IMResponse,
711                     sizeof(simpleData), reinterpret_cast<char *>(&simpleData)) {}
712 
setDataQWSIMResponseCommand713     void setData(const char *d, int len, bool allocateMem) {
714         QWSCommand::setData(d, len, allocateMem);
715 
716         QByteArray tmp = QByteArray::fromRawData(d, len);
717         QDataStream s(tmp);
718         s >> result;
719     }
720 
setResultQWSIMResponseCommand721     void setResult(const QVariant & v)
722     {
723         QByteArray tmp;
724         QDataStream s(&tmp, QIODevice::WriteOnly);
725         s << v;
726         setData(tmp.data(), tmp.size(), true);
727     }
728 
729     struct SimpleData {
730         int windowid;
731         int property;
732     } simpleData;
733 
734     QVariant result;
735 };
736 
737 struct QWSIMUpdateCommand: public QWSCommand
738 {
QWSIMUpdateCommandQWSIMUpdateCommand739     QWSIMUpdateCommand() :
740         QWSCommand(QWSCommand::IMUpdate,
741                     sizeof(simpleData), reinterpret_cast<char *>(&simpleData)) {}
742 
743     struct SimpleData {
744         int windowid;
745         int type;
746         int widgetid;
747     } simpleData;
748 };
749 
750 #endif
751 
752 #ifndef QT_NO_QWSEMBEDWIDGET
753 struct QWSEmbedCommand : public QWSCommand
754 {
QWSEmbedCommandQWSEmbedCommand755     QWSEmbedCommand() : QWSCommand(QWSCommand::Embed,
756                                    sizeof(simpleData),
757                                    reinterpret_cast<char*>(&simpleData))
758     {}
759 
760     void setData(const char *d, int len, bool allocateMem = true)
761     {
762         QWSCommand::setData(d, len, allocateMem);
763 
764         if( simpleData.rects * int(sizeof(QRect)) > len )
765         {
766             qWarning( "embed command - region rectangle count %d - buffer size %d - buffer overrun!",
767                       simpleData.rects, len );
768         }
769         else
770         {
771             region.setRects(reinterpret_cast<QRect*>(rawDataPtr),
772                             simpleData.rects);
773         }
774     }
775 
776     void setData(WId embedder, WId embedded, QWSEmbedEvent::Type type,
777                  const QRegion reg = QRegion())
778     {
779         simpleData.embedder = embedder;
780         simpleData.embedded = embedded;
781         simpleData.type = type;
782 
783         region = reg;
784         const QVector<QRect> rects = reg.rects();
785         simpleData.rects = rects.count();
786 
787         QWSCommand::setData(reinterpret_cast<const char*>(rects.constData()),
788                             rects.count() * sizeof(QRect));
789     }
790 
791     struct {
792         WId embedder;
793         WId embedded;
794         QWSEmbedEvent::Type type;
795         int rects;
796     } simpleData;
797 
798     QRegion region;
799 };
800 #endif // QT_NO_QWSEMBEDWIDGET
801 
802 struct QWSFontCommand : public QWSCommand
803 {
804     enum CommandType {
805         StartedUsingFont,
806         StoppedUsingFont
807     };
808 
QWSFontCommandQWSFontCommand809     QWSFontCommand() :
810         QWSCommand(QWSCommand::Font,
811                     sizeof(simpleData), reinterpret_cast<char *>(&simpleData)) {}
812 
setDataQWSFontCommand813     void setData(const char *d, int len, bool allocateMem) {
814         QWSCommand::setData(d, len, allocateMem);
815 
816         fontName = QByteArray(d, len);
817     }
818 
setFontNameQWSFontCommand819     void setFontName(const QByteArray &name)
820     {
821         setData(name.constData(), name.size(), true);
822     }
823 
824     struct SimpleData {
825         int type;
826     } simpleData;
827 
828     QByteArray fontName;
829 };
830 
831 struct QWSScreenTransformCommand : public QWSCommand
832 {
QWSScreenTransformCommandQWSScreenTransformCommand833     QWSScreenTransformCommand() :
834         QWSCommand(QWSCommand::ScreenTransform,
835                    sizeof(simpleData), reinterpret_cast<char *>(&simpleData)) {}
836 
setTransformationQWSScreenTransformCommand837     void setTransformation(int screen, int transformation)
838     {
839         simpleData.screen = screen;
840         simpleData.transformation = transformation;
841     }
842 
843     struct SimpleData {
844         int screen;
845         int transformation;
846     } simpleData;
847 };
848 
849 QT_END_NAMESPACE
850 
851 #endif // QWSCOMMAND_QWS_P_H
852