qxcbclipboard.cpp

Absolute File Name:/home/qt/qt5_coco/qt5/qtbase/src/plugins/platforms/xcb/qxcbclipboard.cpp
Switch to Source codePreprocessed file
LineSourceCount
1-
2-
3-
4-
5-
6-
7-
8-
9-
10-
11-
12class QXcbClipboardMime : public QXcbMime-
13{-
14 public: template <typename ThisObject> inline void qt_check_for_QOBJECT_macro(const ThisObject &_q_argument) const { int i = qYouForgotTheQ_OBJECT_Macro(this, &_q_argument); i = i + 1; }-
15#pragma GCC diagnostic push-
16 static const QMetaObject staticMetaObject; virtual const QMetaObject *metaObject() const; virtual void *qt_metacast(const char *); virtual int qt_metacall(QMetaObject::Call, int, void **); static inline QString tr(const char *s, const char *c = nullptr, int n = -1) { return staticMetaObject.tr(s, c, n); } __attribute__ ((__deprecated__)) static inline QString trUtf8(const char *s, const char *c = nullptr, int n = -1) { return staticMetaObject.tr(s, c, n); } private: __attribute__((visibility("hidden"))) static void qt_static_metacall(QObject *, QMetaObject::Call, int, void **);-
17#pragma GCC diagnostic pop-
18 struct QPrivateSignal {};-
19public:-
20 QXcbClipboardMime(QClipboard::Mode mode, QXcbClipboard *clipboard)-
21 : QXcbMime()-
22 , m_clipboard(clipboard)-
23 {-
24 switch (mode) {-
25 case QClipboard::Selection:-
26 modeAtom = XCB_ATOM_PRIMARY;-
27 break;-
28-
29 case QClipboard::Clipboard:-
30 modeAtom = m_clipboard->atom(QXcbAtom::CLIPBOARD);-
31 break;-
32-
33 default:-
34 QMessageLogger(__FILE__, 7177, __PRETTY_FUNCTION__).warning("QXcbClipboardMime: Internal error: Unsupported clipboard mode");-
35 break;-
36 }-
37 }-
38-
39 void reset()-
40 {-
41 formatList.clear();-
42 }-
43-
44 bool isEmpty() const-
45 {-
46 return m_clipboard->getSelectionOwner(modeAtom) == 0L;-
47 }-
48-
49protected:-
50 QStringList formats_sys() const override-
51 {-
52 if (isEmpty())-
53 return QStringList();-
54-
55 if (!formatList.count()) {-
56 QXcbClipboardMime *that = const_cast<QXcbClipboardMime *>(this);-
57-
58-
59-
60 that->format_atoms = m_clipboard->getDataInFormat(modeAtom, m_clipboard->atom(QXcbAtom::TARGETS));-
61-
62 if (format_atoms.size() > 0) {-
63 const xcb_atom_t *targets = (const xcb_atom_t *) format_atoms.data();-
64 int size = format_atoms.size() / sizeof(xcb_atom_t);-
65-
66 for (int i = 0; i < size; ++i) {-
67 if (targets[i] == 0)-
68 continue;-
69-
70 QString format = mimeAtomToString(m_clipboard->connection(), targets[i]);-
71 if (!formatList.contains(format))-
72 that->formatList.append(format);-
73 }-
74 }-
75 }-
76-
77 return formatList;-
78 }-
79-
80 bool hasFormat_sys(const QString &format) const override-
81 {-
82 QStringList list = formats();-
83 return list.contains(format);-
84 }-
85-
86 QVariant retrieveData_sys(const QString &fmt, QVariant::Type requestedType) const override-
87 {-
88 if (fmt.isEmpty() || isEmpty())-
89 return QByteArray();-
90-
91 (void)formats();-
92-
93 QVector<xcb_atom_t> atoms;-
94 const xcb_atom_t *targets = (const xcb_atom_t *) format_atoms.data();-
95 int size = format_atoms.size() / sizeof(xcb_atom_t);-
96 atoms.reserve(size);-
97 for (int i = 0; i < size; ++i)-
98 atoms.append(targets[i]);-
99-
100 QByteArray encoding;-
101 xcb_atom_t fmtatom = mimeAtomForFormat(m_clipboard->connection(), fmt, requestedType, atoms, &encoding);-
102-
103 if (fmtatom == 0)-
104 return QVariant();-
105-
106 return mimeConvertToFormat(m_clipboard->connection(), fmtatom, m_clipboard->getDataInFormat(modeAtom, fmtatom), fmt, requestedType, encoding);-
107 }-
108private:-
109-
110 xcb_atom_t modeAtom;-
111 QXcbClipboard *m_clipboard;-
112 QStringList formatList;-
113 QByteArray format_atoms;-
114};-
115-
116class INCRTransaction;-
117typedef QMap<xcb_window_t,INCRTransaction*> TransactionMap;-
118static TransactionMap *transactions = 0;-
119-
120-
121-
122class INCRTransaction : public QObject-
123{-
124 public: template <typename ThisObject> inline void qt_check_for_QOBJECT_macro(const ThisObject &_q_argument) const { int i = qYouForgotTheQ_OBJECT_Macro(this, &_q_argument); i = i + 1; }-
125#pragma GCC diagnostic push-
126 static const QMetaObject staticMetaObject; virtual const QMetaObject *metaObject() const; virtual void *qt_metacast(const char *); virtual int qt_metacall(QMetaObject::Call, int, void **); static inline QString tr(const char *s, const char *c = nullptr, int n = -1) { return staticMetaObject.tr(s, c, n); } __attribute__ ((__deprecated__)) static inline QString trUtf8(const char *s, const char *c = nullptr, int n = -1) { return staticMetaObject.tr(s, c, n); } private: __attribute__((visibility("hidden"))) static void qt_static_metacall(QObject *, QMetaObject::Call, int, void **);-
127#pragma GCC diagnostic pop-
128 struct QPrivateSignal {};-
129public:-
130 INCRTransaction(QXcbConnection *c, xcb_window_t w, xcb_atom_t p,-
131 QByteArray d, uint i, xcb_atom_t t, int f, int to) :-
132 conn(c), win(w), property(p), data(d), increment(i),-
133 target(t), format(f), timeout(to), offset(0)-
134 {-
135 const quint32 values[] = { XCB_EVENT_MASK_PROPERTY_CHANGE };-
136 xcb_change_window_attributes(conn->xcb_connection(), win,-
137 XCB_CW_EVENT_MASK, values);-
138 if (!transactions) {-
139-
140-
141-
142 transactions = new TransactionMap;-
143 conn->clipboard()->setProcessIncr(true);-
144 }-
145 transactions->insert(win, this);-
146 abort_timer = startTimer(timeout);-
147 }-
148-
149 ~INCRTransaction()-
150 {-
151 if (abort_timer)-
152 killTimer(abort_timer);-
153 abort_timer = 0;-
154 transactions->remove(win);-
155 if (transactions->isEmpty()) {-
156-
157-
158-
159 delete transactions;-
160 transactions = 0;-
161 conn->clipboard()->setProcessIncr(false);-
162 }-
163 }-
164-
165 void updateIncrProperty(xcb_property_notify_event_t *event, bool &accepted)-
166 {-
167 xcb_connection_t *c = conn->xcb_connection();-
168 if (event->atom == property && event->state == XCB_PROPERTY_DELETE) {-
169 accepted = true;-
170-
171 if (abort_timer)-
172 killTimer(abort_timer);-
173 abort_timer = startTimer(timeout);-
174-
175 unsigned int bytes_left = data.size() - offset;-
176 if (bytes_left > 0) {-
177 unsigned int bytes_to_send = qMin(increment, bytes_left);-
178-
179-
180-
181-
182 int dataSize = bytes_to_send / (format / 8);-
183 xcb_change_property(c, XCB_PROP_MODE_REPLACE, win, property,-
184 target, format, dataSize, data.constData() + offset);-
185 offset += bytes_to_send;-
186 } else {-
187-
188-
189-
190 xcb_change_property(c, XCB_PROP_MODE_REPLACE, win, property,-
191 target, format, 0, (const void *)0);-
192 const quint32 values[] = { XCB_EVENT_MASK_NO_EVENT };-
193 xcb_change_window_attributes(conn->xcb_connection(), win,-
194 XCB_CW_EVENT_MASK, values);-
195-
196 delete this;-
197 }-
198 }-
199 }-
200-
201protected:-
202 void timerEvent(QTimerEvent *ev) override-
203 {-
204 if (ev->timerId() == abort_timer) {-
205-
206-
207-
208-
209-
210 delete this;-
211 }-
212 }-
213-
214private:-
215 QXcbConnection *conn;-
216 xcb_window_t win;-
217 xcb_atom_t property;-
218 QByteArray data;-
219 uint increment;-
220 xcb_atom_t target;-
221 int format;-
222 int timeout;-
223 uint offset;-
224 int abort_timer;-
225};-
226-
227const int QXcbClipboard::clipboard_timeout = 5000;-
228-
229QXcbClipboard::QXcbClipboard(QXcbConnection *c)-
230 : QXcbObject(c), QPlatformClipboard()-
231 , m_requestor(0L)-
232 , m_owner(0L)-
233 , m_incr_active(false)-
234 , m_clipboard_closing(false)-
235 , m_incr_receive_time(0)-
236{-
237 ((!(QClipboard::Clipboard == 0)) ? qt_assert("QClipboard::Clipboard == 0",__FILE__,270276) : qt_noop());-
238 ((!(QClipboard::Selection == 1)) ? qt_assert("QClipboard::Selection == 1",__FILE__,271277) : qt_noop());-
239 m_clientClipboard[QClipboard::Clipboard] = 0;-
240 m_clientClipboard[QClipboard::Selection] = 0;-
241 m_timestamp[QClipboard::Clipboard] = 0L;-
242 m_timestamp[QClipboard::Selection] = 0L;-
243 m_owner = connection()->getQtSelectionOwner();-
244-
245-
246 QByteArray ba("Qt clipboard window");-
247 xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, m_owner, atom(QXcbAtom::_NET_WM_NAME), atom(QXcbAtom::UTF8_STRING), 8, ba.length(), ba.constData())-
248-
249-
250-
251-
252-
253-
254 ;-
255-
256-
257 if (connection()->hasXFixes()) {-
258 const uint32_t mask = XCB_XFIXES_SELECTION_EVENT_MASK_SET_SELECTION_OWNER |-
259 XCB_XFIXES_SELECTION_EVENT_MASK_SELECTION_WINDOW_DESTROY |-
260 XCB_XFIXES_SELECTION_EVENT_MASK_SELECTION_CLIENT_CLOSE;-
261 xcb_xfixes_select_selection_input_checked(xcb_connection(), m_owner, XCB_ATOM_PRIMARY, mask);-
262 xcb_xfixes_select_selection_input_checked(xcb_connection(), m_owner, atom(QXcbAtom::CLIPBOARD), mask);-
263 }-
264}-
265-
266QXcbClipboard::~QXcbClipboard()-
267{-
268 m_clipboard_closing = true;-
269-
270 if (m_timestamp[QClipboard::Clipboard] != 0L ||-
271 m_timestamp[QClipboard::Selection] != 0L) {-
272-
273-
274 xcb_get_selection_owner_cookie_t cookie = xcb_get_selection_owner(xcb_connection(), atom(QXcbAtom::CLIPBOARD_MANAGER));-
275 xcb_get_selection_owner_reply_t *reply = xcb_get_selection_owner_reply(xcb_connection(), cookie, 0);-
276 if (reply && reply->owner != 0L) {-
277-
278 xcb_delete_property(xcb_connection(), m_owner, atom(QXcbAtom::_QT_SELECTION));-
279 xcb_convert_selection(xcb_connection(), m_owner, atom(QXcbAtom::CLIPBOARD_MANAGER), atom(QXcbAtom::SAVE_TARGETS),-
280 atom(QXcbAtom::_QT_SELECTION), connection()->time());-
281 connection()->sync();-
282-
283-
284 if (!waitForClipboardEvent(m_owner, 31, clipboard_timeout, true)) {-
285 QMessageLogger(__FILE__, 318324, __PRETTY_FUNCTION__).warning("QXcbClipboard: Unable to receive an event from the "-
286 "clipboard manager in a reasonable time");-
287 }-
288 }-
289 free(reply);-
290 }-
291-
292 if (m_clientClipboard[QClipboard::Clipboard] != m_clientClipboard[QClipboard::Selection])-
293 delete m_clientClipboard[QClipboard::Clipboard];-
294 delete m_clientClipboard[QClipboard::Selection];-
295}-
296-
297void QXcbClipboard::incrTransactionPeeker(xcb_generic_event_t *ge, bool &accepted)-
298{-
299 uint response_type = ge->response_type & ~0x80;-
300 if (response_type == 28) {-
301 xcb_property_notify_event_t *event = (xcb_property_notify_event_t *)ge;-
302 TransactionMap::Iterator it = transactions->find(event->window);-
303 if (it != transactions->end()) {-
304 (*it)->updateIncrProperty(event, accepted);-
305 }-
306 }-
307}-
308-
309xcb_window_t QXcbClipboard::getSelectionOwner(xcb_atom_t atom) const-
310{-
311 return connection()->getSelectionOwner(atom);-
312}-
313-
314xcb_atom_t QXcbClipboard::atomForMode(QClipboard::Mode mode) const-
315{-
316 if (mode == QClipboard::Clipboard)-
317 return atom(QXcbAtom::CLIPBOARD);-
318 if (mode == QClipboard::Selection)-
319 return XCB_ATOM_PRIMARY;-
320 return 0L;-
321}-
322-
323QClipboard::Mode QXcbClipboard::modeForAtom(xcb_atom_t a) const-
324{-
325 if (a == XCB_ATOM_PRIMARY)-
326 return QClipboard::Selection;-
327 if (a == atom(QXcbAtom::CLIPBOARD))-
328 return QClipboard::Clipboard;-
329-
330 return QClipboard::FindBuffer;-
331}-
332-
333-
334QMimeData * QXcbClipboard::mimeData(QClipboard::Mode mode)-
335{-
336 if (mode > QClipboard::Selection)-
337 return 0;-
338-
339 xcb_window_t clipboardOwner = getSelectionOwner(atomForMode(mode));-
340 if (clipboardOwner == owner()) {-
341 return m_clientClipboard[mode];-
342 } else {-
343 if (!m_xClipboard[mode])-
344 m_xClipboard[mode].reset(new QXcbClipboardMime(mode, this));-
345-
346 return m_xClipboard[mode].data();-
347 }-
348}-
349-
350void QXcbClipboard::setMimeData(QMimeData *data, QClipboard::Mode mode)-
351{-
352 if (mode > QClipboard::Selection)-
353 return;-
354-
355 QXcbClipboardMime *xClipboard = 0;-
356-
357 if (!data) {-
358 xClipboard = qobject_cast<QXcbClipboardMime *>(mimeData(mode));-
359 if (xClipboard) {-
360 if (xClipboard->isEmpty())-
361 return;-
362 }-
363 }-
364-
365 if (!xClipboard && (m_clientClipboard[mode] == data))-
366 return;-
367-
368 xcb_atom_t modeAtom = atomForMode(mode);-
369 xcb_window_t newOwner = 0L;-
370-
371 if (m_clientClipboard[mode]) {-
372 if (m_clientClipboard[QClipboard::Clipboard] != m_clientClipboard[QClipboard::Selection])-
373 delete m_clientClipboard[mode];-
374 m_clientClipboard[mode] = 0;-
375 m_timestamp[mode] = 0L;-
376 }-
377-
378 if (connection()->time() == 0L)-
379 connection()->setTime(connection()->getTimestamp());-
380-
381 if (data) {-
382 newOwner = owner();-
383-
384 m_clientClipboard[mode] = data;-
385 m_timestamp[mode] = connection()->time();-
386 }-
387-
388 xcb_set_selection_owner(xcb_connection(), newOwner, modeAtom, connection()->time());-
389-
390 if (getSelectionOwner(modeAtom) != newOwner) {-
391 QMessageLogger(__FILE__, 424430, __PRETTY_FUNCTION__).warning("QXcbClipboard::setMimeData: Cannot set X11 selection owner");-
392 }-
393-
394 emitChanged(mode);-
395}-
396-
397bool QXcbClipboard::supportsMode(QClipboard::Mode mode) const-
398{-
399 if (mode <= QClipboard::Selection)-
400 return true;-
401 return false;-
402}-
403-
404bool QXcbClipboard::ownsMode(QClipboard::Mode mode) const-
405{-
406 if (m_owner == 0L || mode > QClipboard::Selection)-
407 return false;-
408-
409 ((!(m_timestamp[mode] == 0L || getSelectionOwner(atomForMode(mode)) == m_owner)) ? qt_assert("m_timestamp[mode] == XCB_CURRENT_TIME || getSelectionOwner(atomForMode(mode)) == m_owner",__FILE__,442448) : qt_noop());-
410-
411 return m_timestamp[mode] != 0L;-
412}-
413-
414QXcbScreen *QXcbClipboard::screen() const-
415{-
416 return connection()->primaryScreen();-
417}-
418-
419xcb_window_t QXcbClipboard::requestor() const-
420{-
421 QXcbScreen *platformScreen = screen();-
422-
423 if (!m_requestor && platformScreen) {-
424 const int x = 0, y = 0, w = 3, h = 3;-
425 QXcbClipboard *that = const_cast<QXcbClipboard *>(this);-
426-
427 xcb_window_t window = xcb_generate_id(xcb_connection());-
428 xcb_create_window(xcb_connection(), 0L, window, platformScreen->screen()->root, x, y, w, h, 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, platformScreen->screen()->root_visual, 0, 0)-
429 ;-
430-
431 QByteArray ba("Qt clipboard requestor window");-
432 xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, window, atom(QXcbAtom::_NET_WM_NAME), atom(QXcbAtom::UTF8_STRING), 8, ba.length(), ba.constData())-
433-
434-
435-
436-
437-
438-
439 ;-
440-
441-
442 uint32_t mask = XCB_EVENT_MASK_PROPERTY_CHANGE;-
443 xcb_change_window_attributes(xcb_connection(), window, XCB_CW_EVENT_MASK, &mask);-
444-
445 that->setRequestor(window);-
446 }-
447 return m_requestor;-
448}-
449-
450void QXcbClipboard::setRequestor(xcb_window_t window)-
451{-
452 if (m_requestor != 0L) {-
453 xcb_destroy_window(xcb_connection(), m_requestor);-
454 }-
455 m_requestor = window;-
456}-
457-
458xcb_window_t QXcbClipboard::owner() const-
459{-
460 return m_owner;-
461}-
462-
463xcb_atom_t QXcbClipboard::sendTargetsSelection(QMimeData *d, xcb_window_t window, xcb_atom_t property)-
464{-
465 QVector<xcb_atom_t> types;-
466 QStringList formats = QInternalMimeData::formatsHelper(d);-
467 for (int i = 0; i < formats.size(); ++i) {-
468 QVector<xcb_atom_t> atoms = QXcbMime::mimeAtomsForFormat(connection(), formats.at(i));-
469 for (int j = 0; j < atoms.size(); ++j) {-
470 if (!types.contains(atoms.at(j)))-
471 types.append(atoms.at(j));-
472 }-
473 }-
474 types.append(atom(QXcbAtom::TARGETS));-
475 types.append(atom(QXcbAtom::MULTIPLE));-
476 types.append(atom(QXcbAtom::TIMESTAMP));-
477 types.append(atom(QXcbAtom::SAVE_TARGETS));-
478-
479 xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, window, property, XCB_ATOM_ATOM,-
480 32, types.size(), (const void *)types.constData());-
481 return property;-
482}-
483-
484xcb_atom_t QXcbClipboard::sendSelection(QMimeData *d, xcb_atom_t target, xcb_window_t window, xcb_atom_t property)-
485{-
486 xcb_atom_t atomFormat = target;-
487 int dataFormat = 0;-
488 QByteArray data;-
489-
490 QString fmt = QXcbMime::mimeAtomToString(connection(), target);-
491 if (fmt.isEmpty()) {-
492-
493 return 0L;-
494 }-
495-
496-
497 if (QXcbMime::mimeDataForAtom(connection(), target, d, &data, &atomFormat, &dataFormat)) {-
498-
499-
500-
501 static xcb_atom_t motif_clip_temporary = atom(QXcbAtom::CLIP_TEMPORARY);-
502 bool allow_incr = property != motif_clip_temporary;-
503-
504 if (m_clipboard_closing)-
505 allow_incr = false;-
506-
507 const int increment = (xcb_get_maximum_request_length(xcb_connection()) * 4) - 24;-
508 if (data.size() > increment && allow_incr) {-
509 long bytes = data.size();-
510 xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, window, property,-
511 atom(QXcbAtom::INCR), 32, 1, (const void *)&bytes);-
512 new INCRTransaction(connection(), window, property, data, increment,-
513 atomFormat, dataFormat, clipboard_timeout);-
514 return property;-
515 }-
516-
517-
518 if (data.size() > increment)-
519 return 0L;-
520 int dataSize = data.size() / (dataFormat / 8);-
521-
522 xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, window, property, atomFormat,-
523 dataFormat, dataSize, (const void *)data.constData());-
524 }-
525 return property;-
526}-
527-
528void QXcbClipboard::handleSelectionClearRequest(xcb_selection_clear_event_t *event)-
529{-
530 QClipboard::Mode mode = modeForAtom(event->selection);-
531 if (mode > QClipboard::Selection)-
532 return;-
533-
534-
535 if (m_timestamp[mode] != 0L && event->time <= m_timestamp[mode])-
536 return;-
537-
538-
539-
540-
541-
542 xcb_window_t newOwner = getSelectionOwner(event->selection);-
543-
544-
545-
546-
547-
548 if (newOwner != 0L) {-
549 if (m_clientClipboard[QClipboard::Clipboard] != m_clientClipboard[QClipboard::Selection])-
550 delete m_clientClipboard[mode];-
551 m_clientClipboard[mode] = 0;-
552 m_timestamp[mode] = 0L;-
553 }-
554}-
555-
556void QXcbClipboard::handleSelectionRequest(xcb_selection_request_event_t *req)-
557{-
558 if (requestor()
requestor()Description
TRUEevaluated 10 times by 5 tests
Evaluated by:
  • tst_QApplication
  • tst_qclipboard - unknown status
  • tst_qlineedit - unknown status
  • tst_qplaintextedit - unknown status
  • tst_qtextedit - unknown status
FALSEnever evaluated
&& req->requestor == requestor()
req->requestor == requestor()Description
TRUEnever evaluated
FALSEevaluated 10 times by 5 tests
Evaluated by:
  • tst_QApplication
  • tst_qclipboard - unknown status
  • tst_qlineedit - unknown status
  • tst_qplaintextedit - unknown status
  • tst_qtextedit - unknown status
) {
0-10
559 QMessageLogger(__FILE__, 600606, __PRETTY_FUNCTION__).warning("QXcbClipboard: Selection request should be caught before");-
560 return;
never executed: return;
0
561 }-
562-
563 q_padded_xcb_event<xcb_selection_notify_event_t> store = q_padded_xcb_event<xcb_selection_notify_event_t >(); auto &event = store.event;;;-
564 event.response_type = 31;-
565 event.requestor = req->requestor;-
566 event.selection = req->selection;-
567 event.target = req->target;-
568 event.property = 0L;-
569 event.time = req->time;-
570-
571 QMimeData *d;-
572 QClipboard::Mode mode = modeForAtom(req->selection);-
573 if (mode > QClipboard::Selection
mode > QClipboard::SelectionDescription
TRUEnever evaluated
FALSEevaluated 10 times by 5 tests
Evaluated by:
  • tst_QApplication
  • tst_qclipboard - unknown status
  • tst_qlineedit - unknown status
  • tst_qplaintextedit - unknown status
  • tst_qtextedit - unknown status
) {
0-10
574 QMessageLogger(__FILE__, 615621, __PRETTY_FUNCTION__).warning() << "QXcbClipboard: Unknown selection" << connection()->atomName(req->selection);-
575 xcb_send_event(xcb_connection(), false, req->requestor, XCB_EVENT_MASK_NO_EVENT, (const char *)&event);-
576 return;
never executed: return;
0
577 }-
578-
579 d = m_clientClipboard[mode];-
580-
581 if (!d
!dDescription
TRUEnever evaluated
FALSEevaluated 10 times by 5 tests
Evaluated by:
  • tst_QApplication
  • tst_qclipboard - unknown status
  • tst_qlineedit - unknown status
  • tst_qplaintextedit - unknown status
  • tst_qtextedit - unknown status
) {
0-10
582 QMessageLogger(__FILE__, 623629, __PRETTY_FUNCTION__).warning("QXcbClipboard: Cannot transfer data, no data available");-
583 xcb_send_event(xcb_connection(), false, req->requestor, XCB_EVENT_MASK_NO_EVENT, (const char *)&event);-
584 return;
never executed: return;
0
585 }-
586-
587 if (m_timestamp[mode] == 0L
m_timestamp[mode] == 0LDescription
TRUEnever evaluated
FALSEevaluated 10 times by 5 tests
Evaluated by:
  • tst_QApplication
  • tst_qclipboard - unknown status
  • tst_qlineedit - unknown status
  • tst_qplaintextedit - unknown status
  • tst_qtextedit - unknown status
0-10
588 || (req->time != 0L
req->time != 0LDescription
TRUEevaluated 10 times by 5 tests
Evaluated by:
  • tst_QApplication
  • tst_qclipboard - unknown status
  • tst_qlineedit - unknown status
  • tst_qplaintextedit - unknown status
  • tst_qtextedit - unknown status
FALSEnever evaluated
&& req->time < m_timestamp[mode]
req->time < m_timestamp[mode]Description
TRUEnever evaluated
FALSEevaluated 10 times by 5 tests
Evaluated by:
  • tst_QApplication
  • tst_qclipboard - unknown status
  • tst_qlineedit - unknown status
  • tst_qplaintextedit - unknown status
  • tst_qtextedit - unknown status
)) {
0-10
589 QMessageLogger(__FILE__, 630636, __PRETTY_FUNCTION__).warning("QXcbClipboard: SelectionRequest too old");-
590 xcb_send_event(xcb_connection(), false, req->requestor, XCB_EVENT_MASK_NO_EVENT, (const char *)&event);-
591 return;
never executed: return;
0
592 }-
593-
594 xcb_atom_t targetsAtom = atom(QXcbAtom::TARGETS);-
595 xcb_atom_t multipleAtom = atom(QXcbAtom::MULTIPLE);-
596 xcb_atom_t timestampAtom = atom(QXcbAtom::TIMESTAMP);-
597-
598 struct AtomPair { xcb_atom_t target; xcb_atom_t property; } *multi = 0;-
599 xcb_atom_t multi_type = 0L;-
600 int multi_format = 0;-
601 int nmulti = 0;-
602 int imulti = -1;-
603 bool multi_writeback = false;-
604-
605 if (req->target == multipleAtom
req->target == multipleAtomDescription
TRUEevaluated 5 times by 5 tests
Evaluated by:
  • tst_QApplication
  • tst_qclipboard - unknown status
  • tst_qlineedit - unknown status
  • tst_qplaintextedit - unknown status
  • tst_qtextedit - unknown status
FALSEevaluated 5 times by 5 tests
Evaluated by:
  • tst_QApplication
  • tst_qclipboard - unknown status
  • tst_qlineedit - unknown status
  • tst_qplaintextedit - unknown status
  • tst_qtextedit - unknown status
) {
5
606 QByteArray multi_data;-
607 if (req->property == 0L
req->property == 0LDescription
TRUEnever evaluated
FALSEevaluated 5 times by 5 tests
Evaluated by:
  • tst_QApplication
  • tst_qclipboard - unknown status
  • tst_qlineedit - unknown status
  • tst_qplaintextedit - unknown status
  • tst_qtextedit - unknown status
0-5
608 || !clipboardReadProperty(req->requestor, req->property, false, &multi_data,
!clipboardRead...&multi_format)Description
TRUEnever evaluated
FALSEevaluated 5 times by 5 tests
Evaluated by:
  • tst_QApplication
  • tst_qclipboard - unknown status
  • tst_qlineedit - unknown status
  • tst_qplaintextedit - unknown status
  • tst_qtextedit - unknown status
0-5
609 0, &multi_type, &multi_format)
!clipboardRead...&multi_format)Description
TRUEnever evaluated
FALSEevaluated 5 times by 5 tests
Evaluated by:
  • tst_QApplication
  • tst_qclipboard - unknown status
  • tst_qlineedit - unknown status
  • tst_qplaintextedit - unknown status
  • tst_qtextedit - unknown status
0-5
610 || multi_format != 32
multi_format != 32Description
TRUEnever evaluated
FALSEevaluated 5 times by 5 tests
Evaluated by:
  • tst_QApplication
  • tst_qclipboard - unknown status
  • tst_qlineedit - unknown status
  • tst_qplaintextedit - unknown status
  • tst_qtextedit - unknown status
) {
0-5
611-
612 xcb_send_event(xcb_connection(), false, req->requestor, XCB_EVENT_MASK_NO_EVENT, (const char *)&event);-
613 return;
never executed: return;
0
614 }-
615 nmulti = multi_data.size()/sizeof(*multi);-
616 multi = new AtomPair[nmulti];-
617 memcpy(multi,multi_data.data(),multi_data.size());-
618 imulti = 0;-
619 }
executed 5 times by 5 tests: end of block
Executed by:
  • tst_QApplication
  • tst_qclipboard - unknown status
  • tst_qlineedit - unknown status
  • tst_qplaintextedit - unknown status
  • tst_qtextedit - unknown status
5
620-
621 for (; imulti < nmulti
imulti < nmultiDescription
TRUEevaluated 39 times by 5 tests
Evaluated by:
  • tst_QApplication
  • tst_qclipboard - unknown status
  • tst_qlineedit - unknown status
  • tst_qplaintextedit - unknown status
  • tst_qtextedit - unknown status
FALSEevaluated 5 times by 5 tests
Evaluated by:
  • tst_QApplication
  • tst_qclipboard - unknown status
  • tst_qlineedit - unknown status
  • tst_qplaintextedit - unknown status
  • tst_qtextedit - unknown status
; ++imulti) {
5-39
622 xcb_atom_t target;-
623 xcb_atom_t property;-
624-
625 if (multi
multiDescription
TRUEevaluated 34 times by 5 tests
Evaluated by:
  • tst_QApplication
  • tst_qclipboard - unknown status
  • tst_qlineedit - unknown status
  • tst_qplaintextedit - unknown status
  • tst_qtextedit - unknown status
FALSEevaluated 5 times by 5 tests
Evaluated by:
  • tst_QApplication
  • tst_qclipboard - unknown status
  • tst_qlineedit - unknown status
  • tst_qplaintextedit - unknown status
  • tst_qtextedit - unknown status
) {
5-34
626 target = multi[imulti].target;-
627 property = multi[imulti].property;-
628 }
executed 34 times by 5 tests: end of block
Executed by:
  • tst_QApplication
  • tst_qclipboard - unknown status
  • tst_qlineedit - unknown status
  • tst_qplaintextedit - unknown status
  • tst_qtextedit - unknown status
else {
34
629 target = req->target;-
630 property = req->property;-
631 if (property == 0L
property == 0LDescription
TRUEnever evaluated
FALSEevaluated 5 times by 5 tests
Evaluated by:
  • tst_QApplication
  • tst_qclipboard - unknown status
  • tst_qlineedit - unknown status
  • tst_qplaintextedit - unknown status
  • tst_qtextedit - unknown status
)
0-5
632 property = target;
never executed: property = target;
0
633 }
executed 5 times by 5 tests: end of block
Executed by:
  • tst_QApplication
  • tst_qclipboard - unknown status
  • tst_qlineedit - unknown status
  • tst_qplaintextedit - unknown status
  • tst_qtextedit - unknown status
5
634-
635 xcb_atom_t ret = 0L;-
636 if (target == 0L
target == 0LDescription
TRUEnever evaluated
FALSEevaluated 39 times by 5 tests
Evaluated by:
  • tst_QApplication
  • tst_qclipboard - unknown status
  • tst_qlineedit - unknown status
  • tst_qplaintextedit - unknown status
  • tst_qtextedit - unknown status
|| property == 0L
property == 0LDescription
TRUEnever evaluated
FALSEevaluated 39 times by 5 tests
Evaluated by:
  • tst_QApplication
  • tst_qclipboard - unknown status
  • tst_qlineedit - unknown status
  • tst_qplaintextedit - unknown status
  • tst_qtextedit - unknown status
) {
0-39
637 ;-
638 }
never executed: end of block
else if (target == timestampAtom
target == timestampAtomDescription
TRUEevaluated 5 times by 5 tests
Evaluated by:
  • tst_QApplication
  • tst_qclipboard - unknown status
  • tst_qlineedit - unknown status
  • tst_qplaintextedit - unknown status
  • tst_qtextedit - unknown status
FALSEevaluated 34 times by 5 tests
Evaluated by:
  • tst_QApplication
  • tst_qclipboard - unknown status
  • tst_qlineedit - unknown status
  • tst_qplaintextedit - unknown status
  • tst_qtextedit - unknown status
) {
0-34
639 if (m_timestamp[mode] != 0L
m_timestamp[mode] != 0LDescription
TRUEevaluated 5 times by 5 tests
Evaluated by:
  • tst_QApplication
  • tst_qclipboard - unknown status
  • tst_qlineedit - unknown status
  • tst_qplaintextedit - unknown status
  • tst_qtextedit - unknown status
FALSEnever evaluated
) {
0-5
640 xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, req->requestor,-
641 property, XCB_ATOM_INTEGER, 32, 1, &m_timestamp[mode]);-
642 ret = property;-
643 }
executed 5 times by 5 tests: end of block
Executed by:
  • tst_QApplication
  • tst_qclipboard - unknown status
  • tst_qlineedit - unknown status
  • tst_qplaintextedit - unknown status
  • tst_qtextedit - unknown status
else {
5
644 QMessageLogger(__FILE__, 685691, __PRETTY_FUNCTION__).warning("QXcbClipboard: Invalid data timestamp");-
645 }
never executed: end of block
0
646 } else if (target == targetsAtom
target == targetsAtomDescription
TRUEevaluated 5 times by 5 tests
Evaluated by:
  • tst_QApplication
  • tst_qclipboard - unknown status
  • tst_qlineedit - unknown status
  • tst_qplaintextedit - unknown status
  • tst_qtextedit - unknown status
FALSEevaluated 29 times by 5 tests
Evaluated by:
  • tst_QApplication
  • tst_qclipboard - unknown status
  • tst_qlineedit - unknown status
  • tst_qplaintextedit - unknown status
  • tst_qtextedit - unknown status
) {
5-29
647 ret = sendTargetsSelection(d, req->requestor, property);-
648 }
executed 5 times by 5 tests: end of block
Executed by:
  • tst_QApplication
  • tst_qclipboard - unknown status
  • tst_qlineedit - unknown status
  • tst_qplaintextedit - unknown status
  • tst_qtextedit - unknown status
else {
5
649 ret = sendSelection(d, target, req->requestor, property);-
650 }
executed 29 times by 5 tests: end of block
Executed by:
  • tst_QApplication
  • tst_qclipboard - unknown status
  • tst_qlineedit - unknown status
  • tst_qplaintextedit - unknown status
  • tst_qtextedit - unknown status
29
651-
652 if (nmulti > 0
nmulti > 0Description
TRUEevaluated 34 times by 5 tests
Evaluated by:
  • tst_QApplication
  • tst_qclipboard - unknown status
  • tst_qlineedit - unknown status
  • tst_qplaintextedit - unknown status
  • tst_qtextedit - unknown status
FALSEevaluated 5 times by 5 tests
Evaluated by:
  • tst_QApplication
  • tst_qclipboard - unknown status
  • tst_qlineedit - unknown status
  • tst_qplaintextedit - unknown status
  • tst_qtextedit - unknown status
) {
5-34
653 if (ret == 0L
ret == 0LDescription
TRUEnever evaluated
FALSEevaluated 34 times by 5 tests
Evaluated by:
  • tst_QApplication
  • tst_qclipboard - unknown status
  • tst_qlineedit - unknown status
  • tst_qplaintextedit - unknown status
  • tst_qtextedit - unknown status
) {
0-34
654 multi[imulti].property = 0L;-
655 multi_writeback = true;-
656 }
never executed: end of block
0
657 }
executed 34 times by 5 tests: end of block
Executed by:
  • tst_QApplication
  • tst_qclipboard - unknown status
  • tst_qlineedit - unknown status
  • tst_qplaintextedit - unknown status
  • tst_qtextedit - unknown status
else {
34
658 event.property = ret;-
659 break;
executed 5 times by 5 tests: break;
Executed by:
  • tst_QApplication
  • tst_qclipboard - unknown status
  • tst_qlineedit - unknown status
  • tst_qplaintextedit - unknown status
  • tst_qtextedit - unknown status
5
660 }-
661 }-
662-
663 if (nmulti > 0
nmulti > 0Description
TRUEevaluated 5 times by 5 tests
Evaluated by:
  • tst_QApplication
  • tst_qclipboard - unknown status
  • tst_qlineedit - unknown status
  • tst_qplaintextedit - unknown status
  • tst_qtextedit - unknown status
FALSEevaluated 5 times by 5 tests
Evaluated by:
  • tst_QApplication
  • tst_qclipboard - unknown status
  • tst_qlineedit - unknown status
  • tst_qplaintextedit - unknown status
  • tst_qtextedit - unknown status
) {
5
664 if (multi_writeback
multi_writebackDescription
TRUEnever evaluated
FALSEevaluated 5 times by 5 tests
Evaluated by:
  • tst_QApplication
  • tst_qclipboard - unknown status
  • tst_qlineedit - unknown status
  • tst_qplaintextedit - unknown status
  • tst_qtextedit - unknown status
) {
0-5
665-
666-
667 xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, req->requestor, req->property,-
668 multi_type, 32, nmulti*2, (const void *)multi);-
669 }
never executed: end of block
0
670-
671 delete [] multi;-
672 event.property = req->property;-
673 }
executed 5 times by 5 tests: end of block
Executed by:
  • tst_QApplication
  • tst_qclipboard - unknown status
  • tst_qlineedit - unknown status
  • tst_qplaintextedit - unknown status
  • tst_qtextedit - unknown status
5
674-
675-
676 xcb_send_event(xcb_connection(), false, req->requestor, XCB_EVENT_MASK_NO_EVENT, (const char *)&event);-
677}
executed 10 times by 5 tests: end of block
Executed by:
  • tst_QApplication
  • tst_qclipboard - unknown status
  • tst_qlineedit - unknown status
  • tst_qplaintextedit - unknown status
  • tst_qtextedit - unknown status
10
678-
679void QXcbClipboard::handleXFixesSelectionRequest(xcb_xfixes_selection_notify_event_t *event)-
680{-
681 QClipboard::Mode mode = modeForAtom(event->selection);-
682 if (mode > QClipboard::Selection)-
683 return;-
684-
685-
686-
687-
688 if (event->owner != owner() && event->selection_timestamp > m_timestamp[mode]) {-
689 if (!m_xClipboard[mode]) {-
690 m_xClipboard[mode].reset(new QXcbClipboardMime(mode, this));-
691 } else {-
692 m_xClipboard[mode]->reset();-
693 }-
694 emitChanged(mode);-
695 } else if (event->subtype == XCB_XFIXES_SELECTION_EVENT_SELECTION_CLIENT_CLOSE ||-
696 event->subtype == XCB_XFIXES_SELECTION_EVENT_SELECTION_WINDOW_DESTROY)-
697 emitChanged(mode);-
698}-
699-
700-
701static inline int maxSelectionIncr(xcb_connection_t *c)-
702{-
703 int l = xcb_get_maximum_request_length(c);-
704 return (l > 65536 ? 65536*4 : l*4) - 100;-
705}-
706-
707bool QXcbClipboard::clipboardReadProperty(xcb_window_t win, xcb_atom_t property, bool deleteProperty, QByteArray *buffer, int *size, xcb_atom_t *type, int *format)-
708{-
709 int maxsize = maxSelectionIncr(xcb_connection());-
710 ulong bytes_left;-
711 xcb_atom_t dummy_type;-
712 int dummy_format;-
713-
714 if (!type)-
715 type = &dummy_type;-
716 if (!format)-
717 format = &dummy_format;-
718-
719-
720 xcb_get_property_cookie_t cookie = xcb_get_property(xcb_connection(), false, win, property, XCB_GET_PROPERTY_TYPE_ANY, 0, 0);-
721 xcb_get_property_reply_t *reply = xcb_get_property_reply(xcb_connection(), cookie, 0);-
722 if (!reply || reply->type == 0L) {-
723 free(reply);-
724 buffer->resize(0);-
725 return false;-
726 }-
727 *type = reply->type;-
728 *format = reply->format;-
729 bytes_left = reply->bytes_after;-
730 free(reply);-
731-
732 int offset = 0, buffer_offset = 0;-
733-
734 int newSize = bytes_left;-
735 buffer->resize(newSize);-
736-
737 bool ok = (buffer->size() == newSize);-
738-
739 if (ok && newSize) {-
740-
741-
742 while (bytes_left) {-
743-
744-
745 xcb_get_property_cookie_t cookie = xcb_get_property(xcb_connection(), false, win, property, XCB_GET_PROPERTY_TYPE_ANY, offset, maxsize/4);-
746 reply = xcb_get_property_reply(xcb_connection(), cookie, 0);-
747 if (!reply || reply->type == 0L) {-
748 free(reply);-
749 break;-
750 }-
751 *type = reply->type;-
752 *format = reply->format;-
753 bytes_left = reply->bytes_after;-
754 char *data = (char *)xcb_get_property_value(reply);-
755 int length = xcb_get_property_value_length(reply);-
756-
757-
758-
759-
760 if ((int)(buffer_offset + length) > buffer->size()) {-
761 QMessageLogger(__FILE__, 802808, __PRETTY_FUNCTION__).warning("QXcbClipboard: buffer overflow");-
762 length = buffer->size() - buffer_offset;-
763-
764-
765 bytes_left = 0;-
766 }-
767-
768 memcpy(buffer->data() + buffer_offset, data, length);-
769 buffer_offset += length;-
770-
771 if (bytes_left) {-
772-
773 offset += length / 4;-
774 }-
775 free(reply);-
776 }-
777 }-
778-
779-
780-
781 if (size)-
782 *size = buffer_offset;-
783 if (*type == atom(QXcbAtom::INCR))-
784 m_incr_receive_time = connection()->getTimestamp();-
785 if (deleteProperty)-
786 xcb_delete_property(xcb_connection(), win, property);-
787-
788 connection()->flush();-
789-
790 return ok;-
791}-
792-
793-
794namespace-
795{-
796 class Notify {-
797 public:-
798 Notify(xcb_window_t win, int t)-
799 : window(win), type(t) {}-
800 xcb_window_t window;-
801 int type;-
802 bool checkEvent(xcb_generic_event_t *event) const {-
803 if (!event)-
804 return false;-
805 int t = event->response_type & 0x7f;-
806 if (t != type)-
807 return false;-
808 if (t == 28) {-
809 xcb_property_notify_event_t *pn = (xcb_property_notify_event_t *)event;-
810 if (pn->window == window)-
811 return true;-
812 } else if (t == 31) {-
813 xcb_selection_notify_event_t *sn = (xcb_selection_notify_event_t *)event;-
814 if (sn->requestor == window)-
815 return true;-
816 }-
817 return false;-
818 }-
819 };-
820 class ClipboardEvent {-
821 public:-
822 ClipboardEvent(QXcbConnection *c)-
823 { clipboard = c->internAtom("CLIPBOARD"); }-
824 xcb_atom_t clipboard;-
825 bool checkEvent(xcb_generic_event_t *e) const {-
826 if (!e)-
827 return false;-
828 int type = e->response_type & 0x7f;-
829 if (type == 30) {-
830 xcb_selection_request_event_t *sr = (xcb_selection_request_event_t *)e;-
831 return sr->selection == XCB_ATOM_PRIMARY || sr->selection == clipboard;-
832 } else if (type == 29) {-
833 xcb_selection_clear_event_t *sc = (xcb_selection_clear_event_t *)e;-
834 return sc->selection == XCB_ATOM_PRIMARY || sc->selection == clipboard;-
835 }-
836 return false;-
837 }-
838 };-
839}-
840-
841xcb_generic_event_t *QXcbClipboard::waitForClipboardEvent(xcb_window_t win, int type, int timeout, bool checkManager)-
842{-
843 QElapsedTimer timer;-
844 timer.start();-
845 do {-
846 Notify notify(win, type);-
847 xcb_generic_event_t *e = connection()->checkEvent(notify);-
848 if (e)-
849 return e;-
850-
851 if (checkManager) {-
852 xcb_get_selection_owner_cookie_t cookie = xcb_get_selection_owner(xcb_connection(), atom(QXcbAtom::CLIPBOARD_MANAGER));-
853 xcb_get_selection_owner_reply_t *reply = xcb_get_selection_owner_reply(xcb_connection(), cookie, 0);-
854 if (!reply || reply->owner == 0L) {-
855 free(reply);-
856 return 0;-
857 }-
858 free(reply);-
859 }-
860-
861-
862 ClipboardEvent clipboard(connection());-
863 e = connection()->checkEvent(clipboard);-
864 if (e) {-
865 connection()->handleXcbEvent(e);-
866 free(e);-
867 }-
868-
869 connection()->flush();-
870-
871-
872 struct timeval usleep_tv;-
873 usleep_tv.tv_sec = 0;-
874 usleep_tv.tv_usec = 50000;-
875 select(0, 0, 0, 0, &usleep_tv);-
876 } while (timer.elapsed() < timeout);-
877-
878 return 0;-
879}-
880-
881QByteArray QXcbClipboard::clipboardReadIncrementalProperty(xcb_window_t win, xcb_atom_t property, int nbytes, bool nullterm)-
882{-
883 QByteArray buf;-
884 QByteArray tmp_buf;-
885 bool alloc_error = false;-
886 int length;-
887 int offset = 0;-
888 xcb_timestamp_t prev_time = m_incr_receive_time;-
889-
890 if (nbytes > 0) {-
891-
892-
893-
894 buf.resize(nbytes+1);-
895 alloc_error = buf.size() != nbytes+1;-
896 }-
897-
898 for (;;) {-
899 connection()->flush();-
900 xcb_generic_event_t *ge = waitForClipboardEvent(win, 28, clipboard_timeout);-
901 if (!ge)-
902 break;-
903 xcb_property_notify_event_t *event = (xcb_property_notify_event_t *)ge;-
904-
905 if (event->atom != property-
906 || event->state != XCB_PROPERTY_NEW_VALUE-
907 || event->time < prev_time)-
908 continue;-
909 prev_time = event->time;-
910-
911 if (clipboardReadProperty(win, property, true, &tmp_buf, &length, 0, 0)) {-
912 if (length == 0) {-
913 if (nullterm) {-
914 buf.resize(offset+1);-
915 buf[offset] = '\0';-
916 } else {-
917 buf.resize(offset);-
918 }-
919 return buf;-
920 } else if (!alloc_error) {-
921 if (offset+length > (int)buf.size()) {-
922 buf.resize(offset+length+65535);-
923 if (buf.size() != offset+length+65535) {-
924 alloc_error = true;-
925 length = buf.size() - offset;-
926 }-
927 }-
928 memcpy(buf.data()+offset, tmp_buf.constData(), length);-
929 tmp_buf.resize(0);-
930 offset += length;-
931 }-
932 } else {-
933 break;-
934 }-
935-
936 free(ge);-
937 }-
938-
939-
940-
941 setRequestor(0);-
942-
943 return QByteArray();-
944}-
945-
946QByteArray QXcbClipboard::getDataInFormat(xcb_atom_t modeAtom, xcb_atom_t fmtAtom)-
947{-
948 return getSelection(modeAtom, fmtAtom, atom(QXcbAtom::_QT_SELECTION));-
949}-
950-
951QByteArray QXcbClipboard::getSelection(xcb_atom_t selection, xcb_atom_t target, xcb_atom_t property, xcb_timestamp_t time)-
952{-
953 QByteArray buf;-
954 xcb_window_t win = requestor();-
955-
956 if (time == 0) time = connection()->time();-
957-
958 xcb_delete_property(xcb_connection(), win, property);-
959 xcb_convert_selection(xcb_connection(), win, selection, target, property, time);-
960-
961 connection()->sync();-
962-
963 xcb_generic_event_t *ge = waitForClipboardEvent(win, 31, clipboard_timeout);-
964 bool no_selection = !ge || ((xcb_selection_notify_event_t *)ge)->property == 0L;-
965 free(ge);-
966-
967 if (no_selection)-
968 return buf;-
969-
970 xcb_atom_t type;-
971 if (clipboardReadProperty(win, property, true, &buf, 0, &type, 0)) {-
972 if (type == atom(QXcbAtom::INCR)) {-
973 int nbytes = buf.size() >= 4 ? *((int*)buf.data()) : 0;-
974 buf = clipboardReadIncrementalProperty(win, property, nbytes, false);-
975 }-
976 }-
977-
978 return buf;-
979}-
980-
981-
982-
983-
984-
Switch to Source codePreprocessed file

Generated by Squish Coco Non-Commercial 4.3.0-BETA-master-30-08-2018-4cb69e9