summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKimmo Hämäläinen <kimmo.hamalainen@nokia.com>2010-12-20 17:53:58 +0200
committerAdam Endrodi <ext-adam.endrodi@nokia.com>2011-01-05 16:10:11 +0200
commit3edfd1ac67abd50891f9430e656a270946e0f930 (patch)
tree6bd042a746796076bb905c9dacffd5e1694e371d /src
parentd399fc5d09063b1767d67d53ca23a41958dc37f9 (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.cpp13
-rw-r--r--src/mcompositewindowshadereffect.cpp17
-rw-r--r--src/mcompositewindowshadereffect.h4
-rw-r--r--src/mtexturepixmapitem_p.cpp43
-rw-r--r--src/mtexturepixmapitem_p.h6
-rw-r--r--src/mwindowpropertycache.cpp44
-rw-r--r--src/mwindowpropertycache.h8
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;