diff options
author | Kimmo Hämäläinen <kimmo.hamalainen@nokia.com> | 2010-12-20 17:53:58 +0200 |
---|---|---|
committer | Adam Endrodi <ext-adam.endrodi@nokia.com> | 2011-01-05 16:10:11 +0200 |
commit | 3edfd1ac67abd50891f9430e656a270946e0f930 (patch) | |
tree | 6bd042a746796076bb905c9dacffd5e1694e371d /src | |
parent | d399fc5d09063b1767d67d53ca23a41958dc37f9 (diff) |
Implement support for partial window drawing etc.
- add support for painting MTexturePixmap with modified texture coordinates
for plugins
- add _MEEGOTOUCH_MSTATUSBAR_GEOMETRY to MWindowPropertyCache
- add MCompositeWindowShaderEffect API for the affected MCompositeWindow
Diffstat (limited to 'src')
-rw-r--r-- | src/mcompositemanager.cpp | 13 | ||||
-rw-r--r-- | src/mcompositewindowshadereffect.cpp | 17 | ||||
-rw-r--r-- | src/mcompositewindowshadereffect.h | 4 | ||||
-rw-r--r-- | src/mtexturepixmapitem_p.cpp | 43 | ||||
-rw-r--r-- | src/mtexturepixmapitem_p.h | 6 | ||||
-rw-r--r-- | src/mwindowpropertycache.cpp | 44 | ||||
-rw-r--r-- | src/mwindowpropertycache.h | 8 |
7 files changed, 114 insertions, 21 deletions
diff --git a/src/mcompositemanager.cpp b/src/mcompositemanager.cpp index 5ee91f7..238660d 100644 --- a/src/mcompositemanager.cpp +++ b/src/mcompositemanager.cpp @@ -2943,11 +2943,6 @@ bool MCompositeManagerPrivate::x11EventFilter(XEvent *event) qWarning("%s: no Shape extension!", __func__); } - if (event->type == damage_ev) { - XDamageNotifyEvent *e = reinterpret_cast<XDamageNotifyEvent *>(event); - damageEvent(e); - return true; - } if (event->type == shape_event_base + ShapeNotify) { XShapeEvent *ev = (XShapeEvent*)event; if (ev->kind == ShapeBounding && prop_caches.contains(ev->window)) { @@ -2961,7 +2956,13 @@ bool MCompositeManagerPrivate::x11EventFilter(XEvent *event) if (processX11EventFilters(event, false)) return true; - + + if (event->type == damage_ev) { + XDamageNotifyEvent *e = reinterpret_cast<XDamageNotifyEvent *>(event); + damageEvent(e); + return true; + } + bool ret = true; switch (event->type) { case FocusIn: { diff --git a/src/mcompositewindowshadereffect.cpp b/src/mcompositewindowshadereffect.cpp index dc462eb..c6d76cf 100644 --- a/src/mcompositewindowshadereffect.cpp +++ b/src/mcompositewindowshadereffect.cpp @@ -50,7 +50,10 @@ MCompositeWindowShaderEffectPrivate::MCompositeWindowShaderEffectPrivate(MCompos { } -void MCompositeWindowShaderEffectPrivate::drawTexture(MTexturePixmapPrivate* render, const QTransform &transform, const QRectF &drawRect, qreal opacity) +void MCompositeWindowShaderEffectPrivate::drawTexture(MTexturePixmapPrivate* render, + const QTransform &transform, + const QRectF &drawRect, + qreal opacity) { priv_render = render; effect->drawTexture(transform, drawRect, opacity); @@ -62,6 +65,7 @@ void MCompositeWindowShaderEffectPrivate::drawTexture(MTexturePixmapPrivate* ren */ MCompositeWindowShaderEffect::MCompositeWindowShaderEffect(QObject* parent) :QObject(parent), + comp_window(0), d(new MCompositeWindowShaderEffectPrivate(this)) { // install default pixel shader @@ -167,10 +171,12 @@ GLuint MCompositeWindowShaderEffect::activeShaderFragment() const */ void MCompositeWindowShaderEffect::drawSource(const QTransform &transform, const QRectF &drawRect, - qreal opacity) + qreal opacity, + bool texcoords_from_rect) { if (d->priv_render) - d->priv_render->q_drawTexture(transform, drawRect, opacity); + d->priv_render->q_drawTexture(transform, drawRect, opacity, + texcoords_from_rect); } /*! @@ -184,6 +190,7 @@ void MCompositeWindowShaderEffect::installEffect(MCompositeWindow* window) if (!window->isValid() && (window->type() != MCompositeWindowGroup::Type)) return; + comp_window = window; // only happens with GL. sorry n800 guys :p #ifdef QT_OPENGL_LIB window->renderer()->installEffect(this); @@ -196,9 +203,11 @@ void MCompositeWindowShaderEffect::installEffect(MCompositeWindow* window) */ void MCompositeWindowShaderEffect::removeEffect(MCompositeWindow* window) { - if (!window->isValid() && (window->type() != MCompositeWindowGroup::Type)) + if (window != comp_window || + (!window->isValid() && (window->type() != MCompositeWindowGroup::Type))) return; + comp_window = 0; #ifdef QT_OPENGL_LIB window->renderer()->installEffect(0); #endif diff --git a/src/mcompositewindowshadereffect.h b/src/mcompositewindowshadereffect.h index 902cbe8..b2cf84e 100644 --- a/src/mcompositewindowshadereffect.h +++ b/src/mcompositewindowshadereffect.h @@ -54,8 +54,10 @@ class MCompositeWindowShaderEffect: public QObject void enabledChanged( bool enabled); protected: + MCompositeWindow *comp_window; void drawSource(const QTransform &transform, - const QRectF &drawRect, qreal opacity); + const QRectF &drawRect, qreal opacity, + bool texcoords_from_rect = false); virtual void drawTexture(const QTransform &transform, const QRectF &drawRect, qreal opacity) = 0; virtual void setUniforms(QGLShaderProgram* program); diff --git a/src/mtexturepixmapitem_p.cpp b/src/mtexturepixmapitem_p.cpp index 25d0588..459376a 100644 --- a/src/mtexturepixmapitem_p.cpp +++ b/src/mtexturepixmapitem_p.cpp @@ -210,7 +210,8 @@ public: currentShader = shader[type]; updateVertices(t); - currentShader->bind(); + if (!currentShader->bind()) + qWarning() << __func__ << "failed to bind shader program"; currentShader->setWorldMatrix(worldMatrix); } @@ -224,7 +225,8 @@ public: return; currentShader = frag; updateVertices(t); - currentShader->bind(); + if (!currentShader->bind()) + qWarning() << __func__ << "failed to bind shader program"; currentShader->setWorldMatrix(worldMatrix); } @@ -275,7 +277,9 @@ MShaderProgram *MGLResourceManager::shader[ShaderTotal]; #endif -void MTexturePixmapPrivate::drawTexture(const QTransform &transform, const QRectF &drawRect, qreal opacity) +void MTexturePixmapPrivate::drawTexture(const QTransform &transform, + const QRectF &drawRect, + qreal opacity) { if (current_effect) { current_effect->d->drawTexture(this, transform, drawRect, opacity); @@ -283,7 +287,10 @@ void MTexturePixmapPrivate::drawTexture(const QTransform &transform, const QRect q_drawTexture(transform, drawRect, opacity); } -void MTexturePixmapPrivate::q_drawTexture(const QTransform &transform, const QRectF &drawRect, qreal opacity) +void MTexturePixmapPrivate::q_drawTexture(const QTransform &transform, + const QRectF &drawRect, + qreal opacity, + bool texcoords_from_rect) { if (current_effect) glresource->updateVertices(transform, current_effect->activeShaderFragment()); @@ -300,7 +307,33 @@ void MTexturePixmapPrivate::q_drawTexture(const QTransform &transform, const QRe glEnableVertexAttribArray(D_VERTEX_COORDS); glEnableVertexAttribArray(D_TEXTURE_COORDS); glVertexAttribPointer(D_VERTEX_COORDS, 2, GL_FLOAT, GL_FALSE, 0, vertexCoords); - if (inverted_texture) + if (texcoords_from_rect) { + float w, h, x, y, cx, cy, cw, ch; + w = item->boundingRect().width(); + h = item->boundingRect().height(); + x = item->boundingRect().x(); + y = item->boundingRect().y(); + + cx = (drawRect.x() - x) / w; + cy = (drawRect.y() - y) / h; + cw = drawRect.width() / w; + ch = drawRect.height() / h; + GLfloat texCoords[8]; + if (inverted_texture) { + texCoords[0] = cx; texCoords[1] = cy; + texCoords[2] = cx; texCoords[3] = ch + cy; + texCoords[4] = cx + cw; texCoords[5] = ch + cy; + texCoords[6] = cx + cw; texCoords[7] = cy; + } else { + texCoords[0] = cx; texCoords[1] = ch + cy; + texCoords[2] = cx; texCoords[3] = cy; + texCoords[4] = cx + cw; texCoords[5] = cy; + texCoords[6] = cx + cw; texCoords[7] = ch + cy; + } + glVertexAttribPointer(D_TEXTURE_COORDS, 2, GL_FLOAT, GL_FALSE, 0, + texCoords); + } + else if (inverted_texture) glVertexAttribPointer(D_TEXTURE_COORDS, 2, GL_FLOAT, GL_FALSE, 0, glresource->texCoordsInv); else diff --git a/src/mtexturepixmapitem_p.h b/src/mtexturepixmapitem_p.h index 2dbbf00..92b55d0 100644 --- a/src/mtexturepixmapitem_p.h +++ b/src/mtexturepixmapitem_p.h @@ -60,9 +60,11 @@ public: void clearTexture(); bool isDirectRendered() const; void resize(int w, int h); - void drawTexture(const QTransform& transform, const QRectF& drawRect, qreal opacity); + void drawTexture(const QTransform& transform, const QRectF& drawRect, + qreal opacity); - void q_drawTexture(const QTransform& transform, const QRectF& drawRect, qreal opacity); + void q_drawTexture(const QTransform& transform, const QRectF& drawRect, + qreal opacity, bool texcoords_from_rect = false); void installEffect(MCompositeWindowShaderEffect* effect); static GLuint installPixelShader(const QByteArray& code); diff --git a/src/mwindowpropertycache.cpp b/src/mwindowpropertycache.cpp index 8e9d131..522f131 100644 --- a/src/mwindowpropertycache.cpp +++ b/src/mwindowpropertycache.cpp @@ -83,6 +83,7 @@ void MWindowPropertyCache::init_invalid() memset(&xcb_decor_buttons_cookie, 0, sizeof(xcb_decor_buttons_cookie)); memset(&xcb_orientation_angle_cookie, 0, sizeof(xcb_orientation_angle_cookie)); + memset(&xcb_statusbar_cookie, 0, sizeof(xcb_statusbar_cookie)); memset(&xcb_wm_protocols_cookie, 0, sizeof(xcb_wm_protocols_cookie)); memset(&xcb_wm_state_cookie, 0, sizeof(xcb_wm_state_cookie)); memset(&xcb_wm_hints_cookie, 0, sizeof(xcb_wm_hints_cookie)); @@ -147,7 +148,10 @@ MWindowPropertyCache::MWindowPropertyCache(Window w, XCB_ATOM_CARDINAL, 0, 8); xcb_orientation_angle_cookie = xcb_get_property(xcb_conn, 0, window, ATOM(_MEEGOTOUCH_ORIENTATION_ANGLE), - XCB_ATOM_CARDINAL, 0, 8); + XCB_ATOM_CARDINAL, 0, 1); + xcb_statusbar_cookie = xcb_get_property(xcb_conn, 0, window, + ATOM(_MEEGOTOUCH_MSTATUSBAR_GEOMETRY), + XCB_ATOM_CARDINAL, 0, 4); xcb_wm_protocols_cookie = xcb_get_property(xcb_conn, 0, window, ATOM(WM_PROTOCOLS), XCB_ATOM_ATOM, 0, 100); @@ -267,6 +271,7 @@ MWindowPropertyCache::~MWindowPropertyCache() if (r) free(r); } xcb_discard_reply(xcb_conn, xcb_orientation_angle_cookie.sequence); + xcb_discard_reply(xcb_conn, xcb_statusbar_cookie.sequence); if (custom_region) delete custom_region; if (wm_state_query) windowState(); @@ -661,7 +666,12 @@ bool MWindowPropertyCache::propertyEvent(XPropertyEvent *e) xcb_discard_reply(xcb_conn, xcb_orientation_angle_cookie.sequence); xcb_orientation_angle_cookie = xcb_get_property(xcb_conn, 0, window, ATOM(_MEEGOTOUCH_ORIENTATION_ANGLE), - XCB_ATOM_CARDINAL, 0, 8); + XCB_ATOM_CARDINAL, 0, 1); + } else if (e->atom == ATOM(_MEEGOTOUCH_MSTATUSBAR_GEOMETRY)) { + xcb_discard_reply(xcb_conn, xcb_statusbar_cookie.sequence); + xcb_statusbar_cookie = xcb_get_property(xcb_conn, 0, window, + ATOM(_MEEGOTOUCH_MSTATUSBAR_GEOMETRY), + XCB_ATOM_CARDINAL, 0, 4); } else if (e->atom == ATOM(WM_PROTOCOLS)) { if (!wm_protocols_valid) // collect the old reply @@ -789,6 +799,36 @@ unsigned MWindowPropertyCache::orientationAngle() return orientation_angle; } +const QRect &MWindowPropertyCache::statusbarGeometry() +{ + if (!xcb_statusbar_cookie.sequence) + return statusbar_geom; + + xcb_get_property_reply_t *r; + unsigned long x, y, w, h; + int len; + r = xcb_get_property_reply(xcb_conn, xcb_statusbar_cookie, 0); + if (!r) + goto failure; + len = xcb_get_property_value_length(r); + if (len != 4 * sizeof(CARD32)) { + free(r); + goto failure; + } + x = ((CARD32*)xcb_get_property_value(r))[0]; + y = ((CARD32*)xcb_get_property_value(r))[1]; + w = ((CARD32*)xcb_get_property_value(r))[2]; + h = ((CARD32*)xcb_get_property_value(r))[3]; + statusbar_geom.setRect(x, y, w, h); + free(r); + xcb_statusbar_cookie.sequence = 0; + return statusbar_geom; + +failure: + statusbar_geom.setRect(0, 0, 0, 0); + return statusbar_geom; +} + const QList<Atom>& MWindowPropertyCache::supportedProtocols() { if (!is_valid || wm_protocols_valid) diff --git a/src/mwindowpropertycache.h b/src/mwindowpropertycache.h index 911dd32..c2273d1 100644 --- a/src/mwindowpropertycache.h +++ b/src/mwindowpropertycache.h @@ -237,6 +237,11 @@ public: unsigned orientationAngle(); /*! + * Returns the value of _MEEGOTOUCH_MSTATUSBAR_GEOMETRY. + */ + const QRect &statusbarGeometry(); + + /*! * Called on PropertyNotify for this window. * Returns true if we should re-check stacking order. */ @@ -297,7 +302,7 @@ private: int video_global_alpha; int is_decorator; QList<Atom> net_wm_state; - QRect req_geom, real_geom; + QRect req_geom, real_geom, statusbar_geom; QRect home_button_geom, close_button_geom; XWMHints *wmhints; xcb_get_window_attributes_reply_t *attrs; @@ -329,6 +334,7 @@ private: xcb_get_property_cookie_t xcb_cannot_minimize_cookie; xcb_get_property_cookie_t xcb_custom_region_cookie; xcb_get_property_cookie_t xcb_orientation_angle_cookie; + xcb_get_property_cookie_t xcb_statusbar_cookie; xcb_render_query_pict_formats_cookie_t xcb_pict_formats_cookie; xcb_shape_get_rectangles_cookie_t xcb_shape_rects_cookie; QRegion shape_region; |