1 #include "qwindowcompositor.h"
6 QWindowCompositor::QWindowCompositor(QOpenGLWindow *window)
7 : WaylandCompositor(window)
10 m_backgroundImage = QImage(QLatin1String(":/background.jpg"));
11 m_renderer = new SurfaceRenderer(m_window->context(), m_window);
12 m_backgroundTexture = m_renderer->textureFromImage(m_backgroundImage);
14 window->installEventFilter(this);
19 void QWindowCompositor::surfaceDestroyed(QObject *object)
21 WaylandSurface *surface = static_cast<WaylandSurface *>(object);
22 m_surfaces.removeOne(surface);
23 if (inputFocus() == surface || !inputFocus()) // typically reset to 0 already in Compositor::surfaceDestroyed()
24 setInputFocus(m_surfaces.isEmpty() ? 0 : m_surfaces.last());
28 void QWindowCompositor::surfaceMapped(const QSize &size)
30 WaylandSurface *surface = qobject_cast<WaylandSurface *>(sender());
32 if (!m_surfaces.contains(surface)) {
33 uint px = 1 + (qrand() % (m_window->width() - size.width() - 2));
34 uint py = 1 + (qrand() % (m_window->height() - size.height() - 2));
36 surface->setGeometry(QRect(pos, size));
38 surface->setGeometry(QRect(window()->geometry().topLeft(),size));
39 m_surfaces.removeOne(surface);
41 m_surfaces.append(surface);
42 setInputFocus(surface);
46 void QWindowCompositor::surfaceDamaged(const QRect &rect)
48 WaylandSurface *surface = qobject_cast<WaylandSurface *>(sender());
49 surfaceDamaged(surface, rect);
52 void QWindowCompositor::surfaceDamaged(WaylandSurface *surface, const QRect &rect)
59 void QWindowCompositor::surfaceCreated(WaylandSurface *surface)
61 connect(surface, SIGNAL(destroyed(QObject *)), this, SLOT(surfaceDestroyed(QObject *)));
62 connect(surface, SIGNAL(mapped(const QSize &)), this, SLOT(surfaceMapped(const QSize &)));
63 connect(surface, SIGNAL(damaged(const QRect &)), this, SLOT(surfaceDamaged(const QRect &)));
67 QPointF QWindowCompositor::toSurface(WaylandSurface *surface, const QPointF &pos) const
69 return pos - surface->geometry().topLeft();
72 WaylandSurface *QWindowCompositor::surfaceAt(const QPoint &point, QPoint *local)
74 for (int i = m_surfaces.size() - 1; i >= 0; --i) {
75 if (m_surfaces.at(i)->geometry().contains(point)) {
77 *local = toSurface(m_surfaces.at(i), point).toPoint();
78 return m_surfaces.at(i);
84 void QWindowCompositor::render()
86 m_window->makeCurrent();
88 //Draw the background Image texture
89 int w = m_window->width();
90 int h = m_window->height();
91 int iw = m_backgroundImage.width();
92 int ih = m_backgroundImage.height();
93 for (int y = 0; y < h; y += ih) {
94 for (int x = 0; x < w; x += iw) {
95 m_renderer->drawTexture(m_backgroundTexture, QRect(QPoint(x, y), QSize(iw, ih)), 0);
99 //Iterate all surfaces in m_surfaces
100 //If type == WaylandSurface::Texture draw textureId at geometry
101 foreach (WaylandSurface *surface, m_surfaces) {
102 if (surface->type() == WaylandSurface::Texture)
103 m_renderer->drawTexture(surface->texture(QOpenGLContext::currentContext()), surface->geometry(), 1); //depth argument should be dynamic (focused should be top).
104 else if (surface->type() == WaylandSurface::Shm)
105 m_renderer->drawImage(surface->image(), surface->geometry());
109 m_window->swapBuffers();
110 m_window->context()->doneCurrent();
113 bool QWindowCompositor::eventFilter(QObject *obj, QEvent *event)
118 switch (event->type()) {
119 case QEvent::MouseButtonPress: {
121 QMouseEvent *me = static_cast<QMouseEvent *>(event);
122 WaylandSurface *targetSurface = surfaceAt(me->pos(), &local);
124 if (inputFocus() != targetSurface) {
125 setInputFocus(targetSurface);
126 m_surfaces.removeOne(targetSurface);
127 m_surfaces.append(targetSurface);
130 targetSurface->sendMousePressEvent(local, me->button());
134 case QEvent::MouseButtonRelease: {
135 WaylandSurface *targetSurface = inputFocus();
137 QMouseEvent *me = static_cast<QMouseEvent *>(event);
138 targetSurface->sendMouseReleaseEvent(toSurface(targetSurface, me->pos()).toPoint(), me->button());
142 case QEvent::KeyPress: {
143 QKeyEvent *ke = static_cast<QKeyEvent *>(event);
144 WaylandSurface *targetSurface = inputFocus();
146 targetSurface->sendKeyPressEvent(ke->nativeScanCode());
149 case QEvent::KeyRelease: {
150 QKeyEvent *ke = static_cast<QKeyEvent *>(event);
151 WaylandSurface *targetSurface = inputFocus();
153 targetSurface->sendKeyReleaseEvent(ke->nativeScanCode());
156 case QEvent::TouchBegin:
157 case QEvent::TouchUpdate:
158 case QEvent::TouchEnd:
160 QSet<WaylandSurface *> targets;
161 QTouchEvent *te = static_cast<QTouchEvent *>(event);
162 QList<QTouchEvent::TouchPoint> points = te->touchPoints();
163 for (int i = 0; i < points.count(); ++i) {
164 const QTouchEvent::TouchPoint &tp(points.at(i));
166 WaylandSurface *targetSurface = surfaceAt(tp.pos().toPoint(), &local);
168 targetSurface->sendTouchPointEvent(tp.id(), local.x(), local.y(), tp.state());
169 targets.insert(targetSurface);
172 foreach (WaylandSurface *surface, targets)
173 surface->sendTouchFrameEvent();