7#include <QtGui/qtguiglobal.h>
8#include <QtGui/qvector3d.h>
9#include <QtGui/qvector4d.h>
10#include <QtGui/qquaternion.h>
11#include <QtGui/qgenericmatrix.h>
12#include <QtCore/qrect.h>
19#ifndef QT_NO_MATRIX4X4
30 inline QMatrix4x4(
float m11,
float m12,
float m13,
float m14,
31 float m21,
float m22,
float m23,
float m24,
32 float m31,
float m32,
float m33,
float m34,
33 float m41,
float m42,
float m43,
float m44);
35 template <
int N,
int M>
41 inline const float& operator()(
int row,
int column)
const;
42 inline float& operator()(
int row,
int column);
52 inline bool isAffine()
const;
54 inline bool isIdentity()
const;
55 inline void setToIdentity();
59 double determinant()
const;
60 QMatrix4x4 inverted(
bool *invertible =
nullptr)
const;
76#if QT_DEPRECATED_SINCE(6, 1)
88#if QT_DEPRECATED_SINCE(6, 1)
104 void scale(
float x,
float y,
float z);
105 void scale(
float factor);
108 void rotate(
float angle,
float x,
float y,
float z = 0.0f);
109#ifndef QT_NO_QUATERNION
115 void ortho(
float left,
float right,
float bottom,
float top,
float nearPlane,
float farPlane);
116 void frustum(
float left,
float right,
float bottom,
float top,
float nearPlane,
float farPlane);
117 void perspective(
float verticalAngle,
float aspectRatio,
float nearPlane,
float farPlane);
118#ifndef QT_NO_VECTOR3D
123 void flipCoordinates();
125 void copyDataTo(
float *
values)
const;
128 QTransform toTransform(
float distanceToPlane)
const;
132#ifndef QT_NO_VECTOR3D
136#ifndef QT_NO_VECTOR4D
142 template <
int N,
int M>
145 inline float *
data();
146 inline const float *
data()
const {
return *
m; }
153#ifndef QT_NO_DEBUG_STREAM
157#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
158 void projectedRotate(
float angle,
float x,
float y,
float z,
float distanceToPlane);
160 void projectedRotate(
float angle,
float x,
float y,
float z);
162 void projectedRotate(
float angle,
float x,
float y,
float z,
float distanceToPlane = 1024.0);
169 Translation = 0x0001,
173 Perspective = 0x0010,
186 friend class ::tst_QMatrixNxN;
197 (
float m11,
float m12,
float m13,
float m14,
198 float m21,
float m22,
float m23,
float m24,
199 float m31,
float m32,
float m33,
float m34,
200 float m41,
float m42,
float m43,
float m44)
202 m[0][0] = m11;
m[0][1] = m21;
m[0][2] = m31;
m[0][3] = m41;
203 m[1][0] = m12;
m[1][1] = m22;
m[1][2] = m32;
m[1][3] = m42;
204 m[2][0] = m13;
m[2][1] = m23;
m[2][2] = m33;
m[2][3] = m43;
205 m[3][0] = m14;
m[3][1] = m24;
m[3][2] = m34;
m[3][3] = m44;
209template <
int N,
int M>
214 for (
int matrixCol = 0; matrixCol < 4; ++matrixCol) {
215 for (
int matrixRow = 0; matrixRow < 4; ++matrixRow) {
216 if (matrixCol < N && matrixRow <
M)
217 m[matrixCol][matrixRow] =
values[matrixCol *
M + matrixRow];
218 else if (matrixCol == matrixRow)
219 m[matrixCol][matrixRow] = 1.0f;
221 m[matrixCol][matrixRow] = 0.0f;
227template <
int N,
int M>
232 for (
int matrixCol = 0; matrixCol < N; ++matrixCol) {
233 for (
int matrixRow = 0; matrixRow <
M; ++matrixRow) {
234 if (matrixCol < 4 && matrixRow < 4)
235 values[matrixCol *
M + matrixRow] =
m[matrixCol][matrixRow];
236 else if (matrixCol == matrixRow)
237 values[matrixCol *
M + matrixRow] = 1.0f;
239 values[matrixCol *
M + matrixRow] = 0.0f;
247 Q_ASSERT(aRow >= 0 && aRow < 4 && aColumn >= 0 && aColumn < 4);
248 return m[aColumn][aRow];
253 Q_ASSERT(aRow >= 0 && aRow < 4 && aColumn >= 0 && aColumn < 4);
255 return m[aColumn][aRow];
258#ifndef QT_NO_VECTOR4D
296 return m[0][3] == 0.0f &&
m[1][3] == 0.0f &&
m[2][3] == 0.0f &&
m[3][3] == 1.0f;
303 if (
m[0][0] != 1.0f ||
m[0][1] != 0.0f ||
m[0][2] != 0.0f)
305 if (
m[0][3] != 0.0f ||
m[1][0] != 0.0f ||
m[1][1] != 1.0f)
307 if (
m[1][2] != 0.0f ||
m[1][3] != 0.0f ||
m[2][0] != 0.0f)
309 if (
m[2][1] != 0.0f ||
m[2][2] != 1.0f ||
m[2][3] != 0.0f)
311 if (
m[3][0] != 0.0f ||
m[3][1] != 0.0f ||
m[3][2] != 0.0f)
313 return (
m[3][3] == 1.0f);
405 flagBits |=
other.flagBits;
408 m[3][0] +=
m[0][0] *
other.m[3][0];
409 m[3][1] +=
m[1][1] *
other.m[3][1];
410 m[3][2] +=
m[2][2] *
other.m[3][2];
419 m0 =
m[0][0] *
other.m[0][0]
422 +
m[3][0] *
other.m[0][3];
423 m1 =
m[0][0] *
other.m[1][0]
426 +
m[3][0] *
other.m[1][3];
427 m2 =
m[0][0] *
other.m[2][0]
430 +
m[3][0] *
other.m[2][3];
431 m[3][0] =
m[0][0] *
other.m[3][0]
434 +
m[3][0] *
other.m[3][3];
439 m0 =
m[0][1] *
other.m[0][0]
442 +
m[3][1] *
other.m[0][3];
443 m1 =
m[0][1] *
other.m[1][0]
446 +
m[3][1] *
other.m[1][3];
447 m2 =
m[0][1] *
other.m[2][0]
450 +
m[3][1] *
other.m[2][3];
451 m[3][1] =
m[0][1] *
other.m[3][0]
454 +
m[3][1] *
other.m[3][3];
459 m0 =
m[0][2] *
other.m[0][0]
462 +
m[3][2] *
other.m[0][3];
463 m1 =
m[0][2] *
other.m[1][0]
466 +
m[3][2] *
other.m[1][3];
467 m2 =
m[0][2] *
other.m[2][0]
470 +
m[3][2] *
other.m[2][3];
471 m[3][2] =
m[0][2] *
other.m[3][0]
474 +
m[3][2] *
other.m[3][3];
479 m0 =
m[0][3] *
other.m[0][0]
482 +
m[3][3] *
other.m[0][3];
483 m1 =
m[0][3] *
other.m[1][0]
486 +
m[3][3] *
other.m[1][3];
487 m2 =
m[0][3] *
other.m[2][0]
490 +
m[3][3] *
other.m[2][3];
491 m[3][3] =
m[0][3] *
other.m[3][0]
494 +
m[3][3] *
other.m[3][3];
525 return m[0][0] ==
other.m[0][0] &&
526 m[0][1] ==
other.m[0][1] &&
527 m[0][2] ==
other.m[0][2] &&
528 m[0][3] ==
other.m[0][3] &&
529 m[1][0] ==
other.m[1][0] &&
530 m[1][1] ==
other.m[1][1] &&
531 m[1][2] ==
other.m[1][2] &&
532 m[1][3] ==
other.m[1][3] &&
533 m[2][0] ==
other.m[2][0] &&
534 m[2][1] ==
other.m[2][1] &&
535 m[2][2] ==
other.m[2][2] &&
536 m[2][3] ==
other.m[2][3] &&
537 m[3][0] ==
other.m[3][0] &&
538 m[3][1] ==
other.m[3][1] &&
539 m[3][2] ==
other.m[3][2] &&
545 return m[0][0] !=
other.m[0][0] ||
546 m[0][1] !=
other.m[0][1] ||
547 m[0][2] !=
other.m[0][2] ||
548 m[0][3] !=
other.m[0][3] ||
549 m[1][0] !=
other.m[1][0] ||
550 m[1][1] !=
other.m[1][1] ||
551 m[1][2] !=
other.m[1][2] ||
552 m[1][3] !=
other.m[1][3] ||
553 m[2][0] !=
other.m[2][0] ||
554 m[2][1] !=
other.m[2][1] ||
555 m[2][2] !=
other.m[2][2] ||
556 m[2][3] !=
other.m[2][3] ||
557 m[3][0] !=
other.m[3][0] ||
558 m[3][1] !=
other.m[3][1] ||
559 m[3][2] !=
other.m[3][2] ||
566 m.m[0][0] = m1.m[0][0] + m2.m[0][0];
567 m.m[0][1] = m1.m[0][1] + m2.m[0][1];
568 m.m[0][2] = m1.m[0][2] + m2.m[0][2];
569 m.m[0][3] = m1.m[0][3] + m2.m[0][3];
570 m.m[1][0] = m1.m[1][0] + m2.m[1][0];
571 m.m[1][1] = m1.m[1][1] + m2.m[1][1];
572 m.m[1][2] = m1.m[1][2] + m2.m[1][2];
573 m.m[1][3] = m1.m[1][3] + m2.m[1][3];
574 m.m[2][0] = m1.m[2][0] + m2.m[2][0];
575 m.m[2][1] = m1.m[2][1] + m2.m[2][1];
576 m.m[2][2] = m1.m[2][2] + m2.m[2][2];
577 m.m[2][3] = m1.m[2][3] + m2.m[2][3];
578 m.m[3][0] = m1.m[3][0] + m2.m[3][0];
579 m.m[3][1] = m1.m[3][1] + m2.m[3][1];
580 m.m[3][2] = m1.m[3][2] + m2.m[3][2];
581 m.m[3][3] = m1.m[3][3] + m2.m[3][3];
588 m.m[0][0] = m1.m[0][0] - m2.m[0][0];
589 m.m[0][1] = m1.m[0][1] - m2.m[0][1];
590 m.m[0][2] = m1.m[0][2] - m2.m[0][2];
591 m.m[0][3] = m1.m[0][3] - m2.m[0][3];
592 m.m[1][0] = m1.m[1][0] - m2.m[1][0];
593 m.m[1][1] = m1.m[1][1] - m2.m[1][1];
594 m.m[1][2] = m1.m[1][2] - m2.m[1][2];
595 m.m[1][3] = m1.m[1][3] - m2.m[1][3];
596 m.m[2][0] = m1.m[2][0] - m2.m[2][0];
597 m.m[2][1] = m1.m[2][1] - m2.m[2][1];
598 m.m[2][2] = m1.m[2][2] - m2.m[2][2];
599 m.m[2][3] = m1.m[2][3] - m2.m[2][3];
600 m.m[3][0] = m1.m[3][0] - m2.m[3][0];
601 m.m[3][1] = m1.m[3][1] - m2.m[3][1];
602 m.m[3][2] = m1.m[3][2] - m2.m[3][2];
603 m.m[3][3] = m1.m[3][3] - m2.m[3][3];
609 QMatrix4x4::Flags flagBits = m1.flagBits | m2.flagBits;
612 m.m[3][0] +=
m.m[0][0] * m2.m[3][0];
613 m.m[3][1] +=
m.m[1][1] * m2.m[3][1];
614 m.m[3][2] +=
m.m[2][2] * m2.m[3][2];
616 m.m[0][0] *= m2.m[0][0];
617 m.m[1][1] *= m2.m[1][1];
618 m.m[2][2] *= m2.m[2][2];
619 m.flagBits = flagBits;
624 m.m[0][0] = m1.m[0][0] * m2.m[0][0]
625 + m1.m[1][0] * m2.m[0][1]
626 + m1.m[2][0] * m2.m[0][2]
627 + m1.m[3][0] * m2.m[0][3];
628 m.m[0][1] = m1.m[0][1] * m2.m[0][0]
629 + m1.m[1][1] * m2.m[0][1]
630 + m1.m[2][1] * m2.m[0][2]
631 + m1.m[3][1] * m2.m[0][3];
632 m.m[0][2] = m1.m[0][2] * m2.m[0][0]
633 + m1.m[1][2] * m2.m[0][1]
634 + m1.m[2][2] * m2.m[0][2]
635 + m1.m[3][2] * m2.m[0][3];
636 m.m[0][3] = m1.m[0][3] * m2.m[0][0]
637 + m1.m[1][3] * m2.m[0][1]
638 + m1.m[2][3] * m2.m[0][2]
639 + m1.m[3][3] * m2.m[0][3];
641 m.m[1][0] = m1.m[0][0] * m2.m[1][0]
642 + m1.m[1][0] * m2.m[1][1]
643 + m1.m[2][0] * m2.m[1][2]
644 + m1.m[3][0] * m2.m[1][3];
645 m.m[1][1] = m1.m[0][1] * m2.m[1][0]
646 + m1.m[1][1] * m2.m[1][1]
647 + m1.m[2][1] * m2.m[1][2]
648 + m1.m[3][1] * m2.m[1][3];
649 m.m[1][2] = m1.m[0][2] * m2.m[1][0]
650 + m1.m[1][2] * m2.m[1][1]
651 + m1.m[2][2] * m2.m[1][2]
652 + m1.m[3][2] * m2.m[1][3];
653 m.m[1][3] = m1.m[0][3] * m2.m[1][0]
654 + m1.m[1][3] * m2.m[1][1]
655 + m1.m[2][3] * m2.m[1][2]
656 + m1.m[3][3] * m2.m[1][3];
658 m.m[2][0] = m1.m[0][0] * m2.m[2][0]
659 + m1.m[1][0] * m2.m[2][1]
660 + m1.m[2][0] * m2.m[2][2]
661 + m1.m[3][0] * m2.m[2][3];
662 m.m[2][1] = m1.m[0][1] * m2.m[2][0]
663 + m1.m[1][1] * m2.m[2][1]
664 + m1.m[2][1] * m2.m[2][2]
665 + m1.m[3][1] * m2.m[2][3];
666 m.m[2][2] = m1.m[0][2] * m2.m[2][0]
667 + m1.m[1][2] * m2.m[2][1]
668 + m1.m[2][2] * m2.m[2][2]
669 + m1.m[3][2] * m2.m[2][3];
670 m.m[2][3] = m1.m[0][3] * m2.m[2][0]
671 + m1.m[1][3] * m2.m[2][1]
672 + m1.m[2][3] * m2.m[2][2]
673 + m1.m[3][3] * m2.m[2][3];
675 m.m[3][0] = m1.m[0][0] * m2.m[3][0]
676 + m1.m[1][0] * m2.m[3][1]
677 + m1.m[2][0] * m2.m[3][2]
678 + m1.m[3][0] * m2.m[3][3];
679 m.m[3][1] = m1.m[0][1] * m2.m[3][0]
680 + m1.m[1][1] * m2.m[3][1]
681 + m1.m[2][1] * m2.m[3][2]
682 + m1.m[3][1] * m2.m[3][3];
683 m.m[3][2] = m1.m[0][2] * m2.m[3][0]
684 + m1.m[1][2] * m2.m[3][1]
685 + m1.m[2][2] * m2.m[3][2]
686 + m1.m[3][2] * m2.m[3][3];
687 m.m[3][3] = m1.m[0][3] * m2.m[3][0]
688 + m1.m[1][3] * m2.m[3][1]
689 + m1.m[2][3] * m2.m[3][2]
690 + m1.m[3][3] * m2.m[3][3];
691 m.flagBits = flagBits;
695#ifndef QT_NO_VECTOR3D
697#if QT_DEPRECATED_SINCE(6, 1)
735#ifndef QT_NO_VECTOR4D
808 xin = float(point.
x());
809 yin = float(point.
y());
826#if QT_DEPRECATED_SINCE(6, 1)
867 m.m[0][0] =
matrix.m[0][0] * factor;
868 m.m[0][1] =
matrix.m[0][1] * factor;
869 m.m[0][2] =
matrix.m[0][2] * factor;
870 m.m[0][3] =
matrix.m[0][3] * factor;
871 m.m[1][0] =
matrix.m[1][0] * factor;
872 m.m[1][1] =
matrix.m[1][1] * factor;
873 m.m[1][2] =
matrix.m[1][2] * factor;
874 m.m[1][3] =
matrix.m[1][3] * factor;
875 m.m[2][0] =
matrix.m[2][0] * factor;
876 m.m[2][1] =
matrix.m[2][1] * factor;
877 m.m[2][2] =
matrix.m[2][2] * factor;
878 m.m[2][3] =
matrix.m[2][3] * factor;
879 m.m[3][0] =
matrix.m[3][0] * factor;
880 m.m[3][1] =
matrix.m[3][1] * factor;
881 m.m[3][2] =
matrix.m[3][2] * factor;
882 m.m[3][3] =
matrix.m[3][3] * factor;
889 m.m[0][0] =
matrix.m[0][0] * factor;
890 m.m[0][1] =
matrix.m[0][1] * factor;
891 m.m[0][2] =
matrix.m[0][2] * factor;
892 m.m[0][3] =
matrix.m[0][3] * factor;
893 m.m[1][0] =
matrix.m[1][0] * factor;
894 m.m[1][1] =
matrix.m[1][1] * factor;
895 m.m[1][2] =
matrix.m[1][2] * factor;
896 m.m[1][3] =
matrix.m[1][3] * factor;
897 m.m[2][0] =
matrix.m[2][0] * factor;
898 m.m[2][1] =
matrix.m[2][1] * factor;
899 m.m[2][2] =
matrix.m[2][2] * factor;
900 m.m[2][3] =
matrix.m[2][3] * factor;
901 m.m[3][0] =
matrix.m[3][0] * factor;
902 m.m[3][1] =
matrix.m[3][1] * factor;
903 m.m[3][2] =
matrix.m[3][2] * factor;
904 m.m[3][3] =
matrix.m[3][3] * factor;
922 qRound(xin *
m[0][1] + yin *
m[1][1] +
m[3][1]));
975#ifndef QT_NO_VECTOR3D
985 point.
y() *
m[1][1] +
m[3][1],
986 point.
z() *
m[2][2] +
m[3][2]);
989 return QVector3D(point.
x() *
m[0][0] + point.
y() *
m[1][0] +
m[3][0],
990 point.
x() *
m[0][1] + point.
y() *
m[1][1] +
m[3][1],
991 point.
z() *
m[2][2] +
m[3][2]);
993 x = point.
x() *
m[0][0] +
994 point.
y() *
m[1][0] +
995 point.
z() *
m[2][0] +
997 y = point.
x() *
m[0][1] +
998 point.
y() *
m[1][1] +
999 point.
z() *
m[2][1] +
1001 z = point.
x() *
m[0][2] +
1002 point.
y() *
m[1][2] +
1003 point.
z() *
m[2][2] +
1005 w = point.
x() *
m[0][3] +
1006 point.
y() *
m[1][3] +
1007 point.
z() *
m[2][3] +
1018 if (flagBits.toInt() <
Scale) {
1041#ifndef QT_NO_VECTOR4D
1045 return *
this * point;
1065#ifndef QT_NO_DEBUG_STREAM
1069#ifndef QT_NO_DATASTREAM
\inmodule QtCore\reentrant
The QGenericMatrix class is a template class that represents a NxM transformation matrix with N colum...
The QMatrix4x4 class represents a 4x4 transformation matrix in 3D space.
QMatrix4x4 & operator*=(const QMatrix4x4 &other)
Multiplies the contents of other by this matrix.
void fill(float value)
Fills all elements of this matrx with value.
bool operator==(const QMatrix4x4 &other) const
Returns true if this matrix is identical to other; false otherwise.
QVector4D column(int index) const
Returns the elements of column index as a 4D vector.
QMatrix4x4()
Constructs an identity matrix.
QMatrix4x4 & operator+=(const QMatrix4x4 &other)
Adds the contents of other to this matrix.
const float & operator()(int row, int column) const
Returns a constant reference to the element at position (row, column) in this matrix.
float * data()
Returns a pointer to the raw data of this matrix.
void setColumn(int index, const QVector4D &value)
Sets the elements of column index to the components of value.
QGenericMatrix< N, M, float > toGenericMatrix() const
Constructs a NxM generic matrix from the left-most N columns and top-most M rows of this 4x4 matrix.
QMatrix4x4 & operator-=(const QMatrix4x4 &other)
Subtracts the contents of other from this matrix.
QVector4D row(int index) const
Returns the elements of row index as a 4D vector.
QVector3D mapVector(const QVector3D &vector) const
Maps vector by multiplying the top 3x3 portion of this matrix by vector.
void setRow(int index, const QVector4D &value)
Sets the elements of row index to the components of value.
QMatrix4x4(const QGenericMatrix< N, M, float > &matrix)
Constructs a 4x4 matrix from the left-most 4 columns and top-most 4 rows of matrix.
QPoint map(const QPoint &point) const
Maps point by multiplying this matrix by point.
void setToIdentity()
Sets this matrix to the identity.
bool isIdentity() const
Returns true if this matrix is the identity; false otherwise.
QMatrix4x4(Qt::Initialization)
void viewport(const QRectF &rect)
This is an overloaded member function, provided for convenience. It differs from the above function o...
const float * constData() const
Returns a constant pointer to the raw data of this matrix.
const float * data() const
Returns a constant pointer to the raw data of this matrix.
bool operator!=(const QMatrix4x4 &other) const
Returns true if this matrix is not identical to other; false otherwise.
\inmodule QtCore\reentrant
constexpr qreal x() const noexcept
Returns the x coordinate of this point.
constexpr qreal y() const noexcept
Returns the y coordinate of this point.
\inmodule QtCore\reentrant
constexpr int x() const noexcept
Returns the x coordinate of this point.
constexpr int y() const noexcept
Returns the y coordinate of this point.
The QQuaternion class represents a quaternion consisting of a vector and scalar.
\inmodule QtCore\reentrant
\inmodule QtCore\reentrant
The QVector3D class represents a vector or vertex in 3D space.
constexpr float y() const noexcept
Returns the y coordinate of this point.
constexpr float x() const noexcept
Returns the x coordinate of this point.
constexpr float z() const noexcept
Returns the z coordinate of this point.
The QVector4D class represents a vector or vertex in 4D space.
QMap< QString, QString > map
[6]
Combined button and popup list for selecting options.
constexpr Initialization Uninitialized
#define QT_WARNING_DISABLE_FLOAT_COMPARE
constexpr bool operator!=(const timespec &t1, const timespec &t2)
constexpr timespec operator+(const timespec &t1, const timespec &t2)
constexpr timespec operator*(const timespec &t1, int mul)
constexpr timespec & operator+=(timespec &t1, const timespec &t2)
constexpr timespec operator-(const timespec &t1, const timespec &t2)
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
#define Q_DECLARE_FLAGS(Flags, Enum)
#define Q_DECLARE_OPERATORS_FOR_FLAGS(Flags)
bool qFuzzyCompare(qfloat16 p1, qfloat16 p2) noexcept
int qRound(qfloat16 d) noexcept
constexpr QMargins operator/(const QMargins &margins, int divisor)
QMatrix4x4 operator*(const QMatrix4x4 &m1, const QMatrix4x4 &m2)
Q_GUI_EXPORT QDataStream & operator>>(QDataStream &, QMatrix4x4 &)
QMatrix4x4 operator-(const QMatrix4x4 &m1, const QMatrix4x4 &m2)
QT_WARNING_POP Q_GUI_EXPORT QDebug operator<<(QDebug dbg, const QMatrix4x4 &m)
Q_GUI_EXPORT QMatrix4x4 operator/(const QMatrix4x4 &matrix, float divisor)
QMatrix4x4 operator+(const QMatrix4x4 &m1, const QMatrix4x4 &m2)
GLenum GLsizei GLsizei GLint * values
[15]
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat z
GLint GLint GLint GLint GLint x
[0]
GLfloat GLfloat GLfloat w
[0]
GLint GLsizei GLsizei height
GLdouble GLdouble GLdouble GLdouble top
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLenum GLenum GLsizei void GLsizei void * column
GLuint GLenum GLenum transform
GLenum GLenum GLsizei void * row
GLenum GLenum GLenum GLenum GLenum scale
bool operator==(const QRandomGenerator &rng1, const QRandomGenerator &rng2)
#define QT_DEPRECATED_VERSION_X_6_1(text)
#define Q_DECLARE_TYPEINFO(TYPE, FLAGS)
static bool translate(xcb_connection_t *connection, xcb_window_t child, xcb_window_t parent, int *x, int *y)
view viewport() -> scroll(dx, dy, deviceRect)