summaryrefslogtreecommitdiff
diff options
authorMikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com>2012-01-26 09:25:52 +0100
committerMikkel Kamstrup Erlandsen <mikkel.kamstrup@gmail.com>2012-01-26 09:25:52 +0100
commit9f9eda847941450218b2e24557cb447d62985982 (patch)
tree0704cfe13de47a78c488f652bb017d9170e5cf59
parentff4dd90f82c1ddf95c918e21f0d73ef78cba0fc8 (diff)
parent278dde9cfa9c75b92ad8c353cf4bdf0c164f9a94 (diff)
Sync with trunk
(bzr r1825.2.61)
-rw-r--r--CMakeLists.txt4
-rw-r--r--plugins/unity-mt-grab-handles/src/unity-mt-grab-handles.cpp31
-rw-r--r--plugins/unity-mt-grab-handles/src/unity-mt-grab-handles.h4
-rw-r--r--plugins/unitydialog/src/unitydialog.cpp98
-rw-r--r--plugins/unitydialog/src/unitydialog.h24
-rw-r--r--plugins/unityshell/src/BamfLauncherIcon.cpp4
-rw-r--r--plugins/unityshell/src/IconLoader.cpp168
-rw-r--r--plugins/unityshell/src/IconRenderer.cpp33
-rw-r--r--plugins/unityshell/src/LauncherModel.cpp52
-rw-r--r--plugins/unityshell/src/ScreenEffectFramebufferObject.cpp4
-rw-r--r--plugins/unityshell/src/ScreenEffectFramebufferObject.h2
-rw-r--r--plugins/unityshell/src/unityshell.cpp187
-rw-r--r--plugins/unityshell/src/unityshell.h21
-rw-r--r--services/panel-service.c3
-rw-r--r--standalone-clients/TestShortcut.cpp2
-rw-r--r--tests/CMakeLists.txt5
-rw-r--r--tests/test_icon_loader.cpp191
-rwxr-xr-xtools/unity-introspection-visualiser.py87
18 files changed, 786 insertions, 134 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 359efd68e..66c47f12e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -17,6 +17,9 @@ set (CMAKE_CXX_FLAGS "-DGNOME_DESKTOP_USE_UNSTABLE_API -std=c++0x -fno-permissiv
set (CMAKE_CXX_FLAGS_DEBUG "-g3")
set (CMAKE_CXX_FLAGS_RELEASE "")
+if (BUILD_GLES)
+ SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DNUX_OPENGLES_20 -DUSE_GLES")
+endif (BUILD_GLES)
#
# Niceties
@@ -136,6 +139,7 @@ add_subdirectory(UnityCore)
add_subdirectory(guides)
add_subdirectory(standalone-clients EXCLUDE_FROM_ALL)
+
#
# GSettings Schema
#
diff --git a/plugins/unity-mt-grab-handles/src/unity-mt-grab-handles.cpp b/plugins/unity-mt-grab-handles/src/unity-mt-grab-handles.cpp
index ce5792da1..c17ad2d0f 100644
--- a/plugins/unity-mt-grab-handles/src/unity-mt-grab-handles.cpp
+++ b/plugins/unity-mt-grab-handles/src/unity-mt-grab-handles.cpp
@@ -438,13 +438,21 @@ UnityMTGrabHandlesWindow::getOutputExtents(CompWindowExtents& output)
bool
UnityMTGrabHandlesWindow::glDraw(const GLMatrix& transform,
+#ifdef USE_GLES
+ const GLWindowPaintAttrib& attrib,
+#else
GLFragment::Attrib& fragment,
+#endif
const CompRegion& region,
unsigned int mask)
{
/* Draw the window on the bottom, we will be drawing the
* handles on top */
+#ifdef USE_GLES
+ bool status = gWindow->glDraw(transform, attrib, region, mask);
+#else
bool status = gWindow->glDraw(transform, fragment, region, mask);
+#endif
if (mHandles && mHandles->visible())
{
@@ -464,10 +472,17 @@ UnityMTGrabHandlesWindow::glDraw(const GLMatrix& transform,
GLTexture::MatrixList matl;
GLTexture::Matrix mat = tex->matrix();
CompRegion paintRegion(region);
+#ifdef USE_GLES
+ GLWindowPaintAttrib wAttrib(attrib);
+#endif
/* We can reset the window geometry since it will be
* re-added later */
+#ifdef USE_GLES
+ gWindow->vertexBuffer()->begin();
+#else
gWindow->geometry().reset();
+#endif
/* Not sure what this does, but it is necessary
* (adjusts for scale?) */
@@ -483,23 +498,35 @@ UnityMTGrabHandlesWindow::glDraw(const GLMatrix& transform,
* dim (so we get a nice render for things like
* wobbly etc etc */
gWindow->glAddGeometry(matl, reg, paintRegion);
-
+#ifdef USE_GLES
+ gWindow->vertexBuffer()->end();
+ wAttrib.opacity = mHandles->opacity();
+#else
/* Did it succeed? */
if (gWindow->geometry().vertices)
{
fragment.setOpacity(mHandles->opacity());
/* Texture rendering set-up */
us->gScreen->setTexEnvMode(GL_MODULATE);
+#endif
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
/* Draw the dim texture with all of it's modified
* geometry glory */
- gWindow->glDrawTexture(tex, fragment, mask | PAINT_WINDOW_BLEND_MASK
+ gWindow->glDrawTexture(tex,
+#ifdef USE_GLES
+ transform, wAttrib,
+#else
+ fragment,
+#endif
+ mask | PAINT_WINDOW_BLEND_MASK
| PAINT_WINDOW_TRANSLUCENT_MASK |
PAINT_WINDOW_TRANSFORMED_MASK);
/* Texture rendering tear-down */
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+#ifndef USE_GLES
us->gScreen->setTexEnvMode(GL_REPLACE);
}
+#endif
}
handle++;
diff --git a/plugins/unity-mt-grab-handles/src/unity-mt-grab-handles.h b/plugins/unity-mt-grab-handles/src/unity-mt-grab-handles.h
index e10568ce0..a5a4e362e 100644
--- a/plugins/unity-mt-grab-handles/src/unity-mt-grab-handles.h
+++ b/plugins/unity-mt-grab-handles/src/unity-mt-grab-handles.h
@@ -229,7 +229,11 @@ public:
void moveNotify(int dx, int dy, bool immediate);
bool glDraw(const GLMatrix&,
+#ifdef USE_GLES
+ const GLWindowPaintAttrib&,
+#else
GLFragment::Attrib&,
+#endif
const CompRegion&,
unsigned int);
diff --git a/plugins/unitydialog/src/unitydialog.cpp b/plugins/unitydialog/src/unitydialog.cpp
index f2423fe90..300b8e19f 100644
--- a/plugins/unitydialog/src/unitydialog.cpp
+++ b/plugins/unitydialog/src/unitydialog.cpp
@@ -420,7 +420,12 @@ UnityDialogWindow::glAddGeometry(const GLTexture::MatrixList& matrices,
/* Collect textures */
void
UnityDialogWindow::glDrawTexture(GLTexture* texture,
+#ifdef USE_GLES
+ const GLMatrix &transform,
+ const GLWindowPaintAttrib &attrib,
+#else
GLFragment::Attrib& fa,
+#endif
unsigned int mask)
{
unity::PaintInfoCollector::Active ()->processTexture (texture);
@@ -448,7 +453,11 @@ unity::GeometryCollection::addGeometryForWindow (CompWindow *w, const CompRegion
{
/* We can reset the window geometry since it will be
* re-added later */
+#ifdef USE_GLES
+ GLWindow::get (w)->vertexBuffer()->begin();
+#else
GLWindow::get (w)->geometry().reset();
+#endif
for (unsigned int i = 0; i < collectedMatrixLists.size (); i++)
{
@@ -462,6 +471,10 @@ unity::GeometryCollection::addGeometryForWindow (CompWindow *w, const CompRegion
* wobbly etc etc */
GLWindow::get (w)->glAddGeometry(matl, reg, paintRegion, min, max);
}
+
+#ifdef USE_GLES
+ GLWindow::get (w)->vertexBuffer()->end();
+#endif
}
void
@@ -497,7 +510,11 @@ unity::TexGeometryCollection::setTexture (GLTexture *tex)
}
void
-unity::TexGeometryCollection::addGeometriesAndDrawTextureForWindow(CompWindow *w, unsigned int mask)
+unity::TexGeometryCollection::addGeometriesAndDrawTextureForWindow(CompWindow *w,
+#ifdef USE_GLES
+ const GLMatrix &transform,
+#endif
+ unsigned int mask)
{
if (mTexture && mGeometries.status ())
{
@@ -509,6 +526,25 @@ unity::TexGeometryCollection::addGeometriesAndDrawTextureForWindow(CompWindow *w
mGeometries.addGeometryForWindow (w, paintRegion);
+#ifdef USE_GLES
+ UnityDialogScreen *uds = UnityDialogScreen::get (screen);
+ GLWindowPaintAttrib attrib (gWindow->lastPaintAttrib());
+ unsigned int glDrawTextureIndex = gWindow->glDrawTextureGetCurrentIndex();
+ /* Texture rendering set-up */
+// uds->gScreen->setTexEnvMode(GL_MODULATE);
+ glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+ /* Draw the dim texture with all of it's modified
+ * geometry glory */
+ gWindow->glDrawTextureSetCurrentIndex(MAXSHORT);
+ gWindow->glDrawTexture(mTexture, transform, attrib, mask
+ | PAINT_WINDOW_BLEND_MASK
+ | PAINT_WINDOW_TRANSLUCENT_MASK
+ | PAINT_WINDOW_TRANSFORMED_MASK);
+ gWindow->glDrawTextureSetCurrentIndex(glDrawTextureIndex);
+ /* Texture rendering tear-down */
+ glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+ uds->gScreen->setTexEnvMode(GL_REPLACE);
+#else
if (gWindow->geometry().vertices)
{
UnityDialogScreen *uds = UnityDialogScreen::get (screen);
@@ -528,6 +564,7 @@ unity::TexGeometryCollection::addGeometriesAndDrawTextureForWindow(CompWindow *w
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
uds->gScreen->setTexEnvMode(GL_REPLACE);
}
+#endif
}
}
@@ -581,10 +618,18 @@ unity::PaintInfoCollector::processTexture (GLTexture *tex)
}
void
-unity::PaintInfoCollector::drawGeometriesForWindow(CompWindow *w, unsigned int pm)
+unity::PaintInfoCollector::drawGeometriesForWindow(CompWindow *w,
+#ifdef USE_GLES
+ const GLMatrix &transform,
+#endif
+ unsigned int pm)
{
for (unity::TexGeometryCollection &tcg : mCollection)
+#if USE_GLES
+ tcg.addGeometriesAndDrawTextureForWindow (w, transform, pm);
+#else
tcg.addGeometriesAndDrawTextureForWindow (w, pm);
+#endif
}
unity::PaintInfoCollector * unity::PaintInfoCollector::active_collector = NULL;
@@ -599,7 +644,11 @@ unity::PaintInfoCollector::Active ()
bool
UnityDialogWindow::glDraw(const GLMatrix& transform,
+#ifdef USE_GLES
+ const GLWindowPaintAttrib& attrib,
+#else
GLFragment::Attrib& fragment,
+#endif
const CompRegion& region,
unsigned int mask)
{
@@ -610,7 +659,13 @@ UnityDialogWindow::glDraw(const GLMatrix& transform,
/* Draw the window on the bottom, we will be drawing the
* dim render on top */
- bool status = gWindow->glDraw(transform, fragment, region, mask);
+ bool status = gWindow->glDraw(transform,
+#ifdef USE_GLES
+ attrib,
+#else
+ fragment,
+#endif
+ region, mask);
UNITY_DIALOG_SCREEN(screen);
@@ -618,10 +673,17 @@ UnityDialogWindow::glDraw(const GLMatrix& transform,
{
GLTexture::MatrixList matl;
GLTexture::Matrix mat = tex->matrix();
+#ifdef USE_GLES
+ GLWindowPaintAttrib wAttrib(attrib);
+#endif
/* We can reset the window geometry since it will be
* re-added later */
+#ifdef USE_GLES
+ gWindow->vertexBuffer()->begin();
+#else
gWindow->geometry().reset();
+#endif
/* Scale the dim render by the ratio of dim size
* to window size */
@@ -642,7 +704,28 @@ UnityDialogWindow::glDraw(const GLMatrix& transform,
* dim (so we get a nice render for things like
* wobbly etc etc */
gWindow->glAddGeometry(matl, reg, paintRegion);
-
+#ifdef USE_GLES
+ gWindow->vertexBuffer()->end();
+#endif
+
+#ifdef USE_GLES
+ unsigned int glDrawTextureIndex = gWindow->glDrawTextureGetCurrentIndex();
+ wAttrib.opacity = mShadeProgress;
+ /* Texture rendering set-up */
+// uds->gScreen->setTexEnvMode(GL_MODULATE);
+ glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+ /* Draw the dim texture with all of it's modified
+ * geometry glory */
+ gWindow->glDrawTextureSetCurrentIndex(MAXSHORT);
+ gWindow->glDrawTexture(tex, transform, attrib, mask
+ | PAINT_WINDOW_BLEND_MASK
+ | PAINT_WINDOW_TRANSLUCENT_MASK
+ | PAINT_WINDOW_TRANSFORMED_MASK);
+ gWindow->glDrawTextureSetCurrentIndex(glDrawTextureIndex);
+ /* Texture rendering tear-down */
+ glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+ uds->gScreen->setTexEnvMode(GL_REPLACE);
+#else
/* Did it succeed? */
if (gWindow->geometry().vertices)
{
@@ -662,6 +745,7 @@ UnityDialogWindow::glDraw(const GLMatrix& transform,
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
uds->gScreen->setTexEnvMode(GL_REPLACE);
}
+#endif
}
for (CompWindow* w : mTransients)
@@ -674,7 +758,11 @@ UnityDialogWindow::glDraw(const GLMatrix& transform,
unity::PaintInfoCollector pc (w);
pc.collect();
- pc.drawGeometriesForWindow (window, mask);
+ pc.drawGeometriesForWindow (window,
+#ifdef USE_GLES
+ transform,
+#endif
+ mask);
}
}
diff --git a/plugins/unitydialog/src/unitydialog.h b/plugins/unitydialog/src/unitydialog.h
index c57a99b5c..be3d785ac 100644
--- a/plugins/unitydialog/src/unitydialog.h
+++ b/plugins/unitydialog/src/unitydialog.h
@@ -64,7 +64,13 @@ namespace unity
int max);
void setTexture (GLTexture *);
+#ifdef USE_GLES
+ void addGeometriesAndDrawTextureForWindow (CompWindow *w,
+ const GLMatrix &transform,
+ unsigned int mask);
+#else
void addGeometriesAndDrawTextureForWindow (CompWindow *, unsigned int pm);
+#endif
private:
GLTexture* mTexture;
@@ -78,7 +84,13 @@ namespace unity
PaintInfoCollector (CompWindow *w);
void collect ();
+#ifdef USE_GLES
+ void drawGeometriesForWindow (CompWindow *w,
+ const GLMatrix &transform,
+ unsigned int pm);
+#else
void drawGeometriesForWindow (CompWindow *w, unsigned int pm);
+#endif
void processGeometry (const GLTexture::MatrixList &ml,
const CompRegion &r,
@@ -242,7 +254,12 @@ public:
public:
bool
- glDraw(const GLMatrix&, GLFragment::Attrib&,
+ glDraw(const GLMatrix&,
+#ifdef USE_GLES
+ const GLWindowPaintAttrib&,
+#else
+ GLFragment::Attrib&,
+#endif
const CompRegion&, unsigned int);
bool
@@ -258,7 +275,12 @@ public:
void
glDrawTexture(GLTexture* texture,
+#ifdef USE_GLES
+ const GLMatrix& transform,
+ const GLWindowPaintAttrib& attrib,
+#else
GLFragment::Attrib& attrib,
+#endif
unsigned int mask);
diff --git a/plugins/unityshell/src/BamfLauncherIcon.cpp b/plugins/unityshell/src/BamfLauncherIcon.cpp
index 7a3d76aea..a136d2114 100644
--- a/plugins/unityshell/src/BamfLauncherIcon.cpp
+++ b/plugins/unityshell/src/BamfLauncherIcon.cpp
@@ -323,9 +323,7 @@ std::string BamfLauncherIcon::NameForWindow (Window window)
view = static_cast <BamfView*> (l->data);
if (BAMF_IS_WINDOW(view) && (Window) bamf_window_get_xid(BAMF_WINDOW(view)) == window)
{
- gchar *name = bamf_view_get_name (view);
- result = name;
- g_free (name);
+ result = glib::String(bamf_view_get_name(view)).Str();
break;
}
}
diff --git a/plugins/unityshell/src/IconLoader.cpp b/plugins/unityshell/src/IconLoader.cpp
index 52a4f9956..f385517d9 100644
--- a/plugins/unityshell/src/IconLoader.cpp
+++ b/plugins/unityshell/src/IconLoader.cpp
@@ -85,6 +85,9 @@ private:
IconLoaderCallback slot;
Handle handle;
Impl* self;
+ GtkIconInfo* icon_info;
+ GdkPixbuf* result;
+ glib::Error error;
IconLoaderTask(IconLoaderRequestType type_,
std::string const& data_,
@@ -95,6 +98,7 @@ private:
Impl* self_)
: type(type_), data(data_), size(size_), key(key_)
, slot(slot_), handle(handle_), self(self_)
+ , icon_info(NULL), result(NULL)
{}
};
@@ -116,17 +120,19 @@ private:
unsigned size,
IconLoaderCallback slot);
+ // these methods might run asynchronously
bool ProcessTask(IconLoaderTask* task);
bool ProcessIconNameTask(IconLoaderTask* task);
bool ProcessGIconTask(IconLoaderTask* task);
-
- // URI processing is async.
bool ProcessURITask(IconLoaderTask* task);
- void ProcessURITaskReady(IconLoaderTask* task, char* contents, gsize length);
- static void LoadContentsReady(GObject* object, GAsyncResult* res, IconLoaderTask* task);
+
+ // Loading/rendering of pixbufs is done in a separate thread
+ static gboolean LoaderJobFunc(GIOSchedulerJob* job, GCancellable *canc,
+ IconLoaderTask *task);
+ static gboolean LoadIconComplete(IconLoaderTask* task);
// Loop calls the iteration function.
- static bool Loop(Impl* self);
+ static gboolean Loop(Impl* self);
bool Iteration();
private:
@@ -312,26 +318,17 @@ bool IconLoader::Impl::ProcessTask(IconLoaderTask* task)
bool IconLoader::Impl::ProcessIconNameTask(IconLoaderTask* task)
{
- GdkPixbuf* pixbuf = nullptr;
GtkIconInfo* info = gtk_icon_theme_lookup_icon(theme_,
task->data.c_str(),
task->size,
(GtkIconLookupFlags)0);
if (info)
{
- glib::Error error;
+ task->icon_info = info;
+ g_io_scheduler_push_job ((GIOSchedulerJobFunc) LoaderJobFunc,
+ task, NULL, G_PRIORITY_HIGH_IDLE, NULL);
- pixbuf = gtk_icon_info_load_icon(info, &error);
- if (GDK_IS_PIXBUF(pixbuf))
- {
- cache_[task->key] = pixbuf;
- }
- else
- {
- LOG_WARNING(logger) << "Unable to load icon " << task->data
- << " at size " << task->size << ": " << error;
- }
- gtk_icon_info_free(info);
+ return false;
}
else
{
@@ -339,14 +336,12 @@ bool IconLoader::Impl::ProcessIconNameTask(IconLoaderTask* task)
<< " at size " << task->size;
}
- task->slot(task->data, task->size, pixbuf);
+ task->slot(task->data, task->size, nullptr);
return true;
}
bool IconLoader::Impl::ProcessGIconTask(IconLoaderTask* task)
{
- GdkPixbuf* pixbuf = NULL;
-
glib::Error error;
glib::Object<GIcon> icon(::g_icon_new_for_string(task->data.c_str(), &error));
@@ -368,18 +363,11 @@ bool IconLoader::Impl::ProcessGIconTask(IconLoaderTask* task)
(GtkIconLookupFlags)0);
if (info)
{
- pixbuf = gtk_icon_info_load_icon(info, &error);
+ task->icon_info = info;
+ g_io_scheduler_push_job ((GIOSchedulerJobFunc) LoaderJobFunc,
+ task, NULL, G_PRIORITY_HIGH_IDLE, NULL);
- if (GDK_IS_PIXBUF(pixbuf))
- {
- cache_[task->key] = pixbuf;
- }
- else
- {
- LOG_WARNING(logger) << "Unable to load icon " << task->data
- << " at size " << task->size << ": " << error;
- }
- gtk_icon_info_free(info);
+ return false;
}
else
{
@@ -409,58 +397,91 @@ bool IconLoader::Impl::ProcessGIconTask(IconLoaderTask* task)
<< " at size " << task->size << ": " << error;
}
- task->slot(task->data, task->size, pixbuf);
+ task->slot(task->data, task->size, nullptr);
return true;
}
bool IconLoader::Impl::ProcessURITask(IconLoaderTask* task)
{
- glib::Object<GFile> file(g_file_new_for_uri(task->data.c_str()));
-
- g_file_load_contents_async(file,
- NULL,
- (GAsyncReadyCallback)LoadContentsReady,
- task);
+ g_io_scheduler_push_job ((GIOSchedulerJobFunc) LoaderJobFunc,
+ task, NULL, G_PRIORITY_HIGH_IDLE, NULL);
return false;
}
-void IconLoader::Impl::ProcessURITaskReady(IconLoaderTask* task,
- char* contents,
- gsize length)
+gboolean IconLoader::Impl::LoaderJobFunc(GIOSchedulerJob* job,
+ GCancellable *canc,
+ IconLoaderTask *task)
{
- GInputStream* stream = g_memory_input_stream_new_from_data(contents, length, NULL);
+ // careful here this is running in non-main thread
+ if (task->icon_info)
+ {
+ task->result = gtk_icon_info_load_icon(task->icon_info, &task->error);
- glib::Error error;
- glib::Object<GdkPixbuf> pixbuf(gdk_pixbuf_new_from_stream_at_scale(stream,
- -1,
- task->size,
- true,
- NULL,
- &error));
- if (error)
+ gtk_icon_info_free (task->icon_info);
+ task->icon_info = NULL;
+ }
+ else if (task->type == REQUEST_TYPE_URI)
{
- LOG_WARNING(logger) << "Unable to create pixbuf from input stream for "
- << task->data << " at size " << task->size << ": " << error;
+ glib::Object<GFile> file(g_file_new_for_uri(task->data.c_str()));
+ glib::String contents;
+ gsize length = 0;
+
+ if (g_file_load_contents(file, canc, &contents, &length,
+ NULL, &task->error))
+ {
+ glib::Object<GInputStream> stream(
+ g_memory_input_stream_new_from_data(contents.Value(), length, NULL));
+
+ task->result = gdk_pixbuf_new_from_stream_at_scale(stream,
+ -1,
+ task->size,
+ TRUE,
+ canc,
+ &task->error);
+ g_input_stream_close(stream, canc, NULL);
+ }
+ }
+
+ g_io_scheduler_job_send_to_mainloop_async (job,
+ (GSourceFunc) LoadIconComplete,
+ task,
+ NULL);
+
+ return FALSE;
+}
+
+// this will be invoked back in the thread from which push_job was called
+gboolean IconLoader::Impl::LoadIconComplete(IconLoaderTask* task)
+{
+ if (GDK_IS_PIXBUF(task->result))
+ {
+ task->self->cache_[task->key] = task->result;
}
else
{
- cache_[task->key] = pixbuf;
+ LOG_WARNING(logger) << "Unable to load icon " << task->data
+ << " at size " << task->size << ": " << task->error;
}
- task->slot(task->data, task->size, pixbuf);
- g_input_stream_close(stream, NULL, NULL);
+ task->slot(task->data, task->size, task->result);
+
+ // this was all async, we need to erase ourselves from the task_map
+ task->self->task_map_.erase(task->handle);
+ delete task;
+
+ return FALSE;
}
bool IconLoader::Impl::Iteration()
{
- static const int MAX_MICRO_SECS = 10000;
+ static const int MAX_MICRO_SECS = 1000;
util::Timer timer;
bool queue_empty = tasks_.empty();
- while (!queue_empty &&
- (timer.ElapsedMicroSeconds() < MAX_MICRO_SECS))
+ // always do at least one iteration if the queue isn't empty
+ while (!queue_empty)
{
IconLoaderTask* task = tasks_.front();
@@ -472,6 +493,8 @@ bool IconLoader::Impl::Iteration()
tasks_.pop();
queue_empty = tasks_.empty();
+
+ if (timer.ElapsedMicroSeconds() >= MAX_MICRO_SECS) break;
}
LOG_DEBUG(logger) << "Iteration done, queue size now at " << tasks_.size();
@@ -487,34 +510,11 @@ bool IconLoader::Impl::Iteration()
}
-bool IconLoader::Impl::Loop(IconLoader::Impl* self)
+gboolean IconLoader::Impl::Loop(IconLoader::Impl* self)
{
- return self->Iteration();
+ return self->Iteration() ? TRUE : FALSE;
}
-void IconLoader::Impl::LoadContentsReady(GObject* obj,
- GAsyncResult* res,
- IconLoaderTask* task)
-{
- glib::String contents;
- glib::Error error;
- gsize length = 0;
-
- if (g_file_load_contents_finish(G_FILE(obj), res, &contents, &length, NULL, &error))
- {
- task->self->ProcessURITaskReady(task, contents.Value(), length);
- }
- else
- {
- LOG_WARNING(logger) << "Unable to load contents of "
- << task->data << ": " << error;
- task->slot(task->data, task->size, nullptr);
- }
- task->self->task_map_.erase(task->handle);
- delete task;
-}
-
-
IconLoader::IconLoader()
: pimpl(new Impl())
{
diff --git a/plugins/unityshell/src/IconRenderer.cpp b/plugins/unityshell/src/IconRenderer.cpp
index f461b4045..2c6cb41e4 100644
--- a/plugins/unityshell/src/IconRenderer.cpp
+++ b/plugins/unityshell/src/IconRenderer.cpp
@@ -39,6 +39,14 @@ namespace unity
namespace ui
{
+#ifdef USE_GLES
+ #define VertexShaderHeader "#version 100\n"
+ #define FragmentShaderHeader "#version 100\n precision mediump float;\n"
+#else
+ #define VertexShaderHeader "#version 120\n"
+ #define FragmentShaderHeader "#version 110\n"
+#endif
+
/*
Use this shader to pass vertices in screen coordinates in the C++ code and compute use
the fragment shader to perform the texture perspective correct division.
@@ -60,9 +68,9 @@ namespace ui
#define LUMIN_BLUE "0.055"
nux::NString gPerspectiveCorrectShader = TEXT(
-"[Vertex Shader] \n\
-#version 120 \n\
-uniform mat4 ViewProjectionMatrix; \n\
+"[Vertex Shader] \n"
+VertexShaderHeader
+"uniform mat4 ViewProjectionMatrix; \n\
\n\
attribute vec4 iTexCoord0; \n\
attribute vec4 iVertex; \n\
@@ -75,9 +83,9 @@ void main() \n\
gl_Position = ViewProjectionMatrix * iVertex; \n\
} \n\
\n\
-[Fragment Shader] \n\
-#version 110 \n\
- \n\
+[Fragment Shader] \n"
+FragmentShaderHeader
+" \n\
varying vec4 varyTexCoord0; \n\
\n\
uniform sampler2D TextureObject0; \n\
@@ -649,8 +657,13 @@ void IconRenderer::RenderElement(nux::GraphicsEngine& GfxContext,
// Perspective correct
v0.x, v0.y, 0.0f, 1.0f, s0 / v0.w, t0 / v0.w, 0.0f, 1.0f / v0.w,
v1.x, v1.y, 0.0f, 1.0f, s1 / v1.w, t1 / v1.w, 0.0f, 1.0f / v1.w,
+#ifdef USE_GLES
+ v3.x, v3.y, 0.0f, 1.0f, s3 / v3.w, t3 / v3.w, 0.0f, 1.0f / v3.w,
+ v2.x, v2.y, 0.0f, 1.0f, s2 / v2.w, t2 / v2.w, 0.0f, 1.0f / v2.w,
+#else
v2.x, v2.y, 0.0f, 1.0f, s2 / v2.w, t2 / v2.w, 0.0f, 1.0f / v2.w,
v3.x, v3.y, 0.0f, 1.0f, s3 / v3.w, t3 / v3.w, 0.0f, 1.0f / v3.w,
+#endif
};
CHECKGL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0));
@@ -681,6 +694,7 @@ void IconRenderer::RenderElement(nux::GraphicsEngine& GfxContext,
local::shader_program_uv_persp_correction->SetUniformLocMatrix4fv((GLint)VPMatrixLocation, 1, false, (GLfloat*) & (_stored_projection_matrix.m));
}
}
+#ifndef USE_GLES
else
{
local::asm_shader->Begin();
@@ -698,6 +712,7 @@ void IconRenderer::RenderElement(nux::GraphicsEngine& GfxContext,
CHECKGL(glMatrixMode(GL_PROJECTION));
CHECKGL(glLoadMatrixf((float*) GfxContext.GetOpenGLProjectionMatrix().m));
}
+#endif
CHECKGL(glEnableVertexAttribArrayARB(VertexLocation));
CHECKGL(glVertexAttribPointerARB((GLuint)VertexLocation, 4, GL_FLOAT, GL_FALSE, 32, VtxBuffer));
@@ -716,8 +731,13 @@ void IconRenderer::RenderElement(nux::GraphicsEngine& GfxContext,
CHECKGL(glUniform4fARB(DesatFactor, arg.saturation, arg.saturation, arg.saturation, arg.saturation));
nux::GetWindowThread()->GetGraphicsEngine().SetTexture(GL_TEXTURE0, icon);
+#ifdef USE_GLES
+ CHECKGL(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
+#else
CHECKGL(glDrawArrays(GL_QUADS, 0, 4));
+#endif
}
+#ifndef USE_GLES
else
{
CHECKGL(glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 0, bg_color.red, bg_color.green, bg_color.blue, bg_color.alpha));
@@ -726,6 +746,7 @@ void IconRenderer::RenderElement(nux::GraphicsEngine& GfxContext,
nux::GetWindowThread()->GetGraphicsEngine().SetTexture(GL_TEXTURE0, icon);
CHECKGL(glDrawArrays(GL_QUADS, 0, 4));
}
+#endif
if (VertexLocation != -1)
CHECKGL(glDisableVertexAttribArrayARB(VertexLocation));
diff --git a/plugins/unityshell/src/LauncherModel.cpp b/plugins/unityshell/src/LauncherModel.cpp
index dc862b76a..45cc4196a 100644
--- a/plugins/unityshell/src/LauncherModel.cpp
+++ b/plugins/unityshell/src/LauncherModel.cpp
@@ -66,19 +66,17 @@ LauncherModel::Populate()
_inner.clear();
- iterator it, it2;
-
int i = 0;
- for (it = main_begin(); it != main_end(); it++)
+ for (auto icon : _inner_main)
{
- _inner.push_back(*it);
- (*it)->SetSortPriority(i++);
+ _inner.push_back(icon);
+ icon->SetSortPriority(i++);
}
- for (it = shelf_begin(); it != shelf_end(); it++)
+ for (auto icon : _inner_shelf)
{
- _inner.push_back(*it);
- (*it)->SetSortPriority(i++);
+ _inner.push_back(icon);
+ icon->SetSortPriority(i++);
}
return !std::equal(begin(), end(), copy.begin());
@@ -195,35 +193,33 @@ LauncherModel::ReorderBefore(LauncherIcon* icon, LauncherIcon* other, bool save)
if (icon == other)
return;
- LauncherModel::iterator it;
-
int i = 0;
int j = 0;
- for (it = begin(); it != end(); it++)
+ for (auto icon_it : _inner)
{
- if ((*it) == icon)
+ if (icon_it == icon)
{
j++;
continue;
}
- if ((*it) == other)
+ if (icon_it == other)
{
icon->SetSortPriority(i);
if (i != j && save)
- (*it)->SaveCenter();
+ icon_it->SaveCenter();
i++;
- (*it)->SetSortPriority(i);
+ icon_it->SetSortPriority(i);
if (i != j && save)
- (*it)->SaveCenter();
+ icon_it->SaveCenter();
i++;
}
else
{
- (*it)->SetSortPriority(i);
+ icon_it->SetSortPriority(i);
if (i != j && save)
- (*it)->SaveCenter();
+ icon_it->SaveCenter();
i++;
}
j++;
@@ -238,48 +234,46 @@ LauncherModel::ReorderSmart(LauncherIcon* icon, LauncherIcon* other, bool save)
if (icon == other)
return;
- LauncherModel::iterator it;
-
int i = 0;
int j = 0;
bool skipped = false;
- for (it = begin(); it != end(); it++)
+ for (auto icon_it : _inner)
{
- if ((*it) == icon)
+ if (icon_it == icon)
{
skipped = true;
j++;
continue;
}
- if ((*it) == other)
+ if (icon_it == other)
{
if (!skipped)
{
icon->SetSortPriority(i);
if (i != j && save)
- (*it)->SaveCenter();
+ icon_it->SaveCenter();
i++;
}
- (*it)->SetSortPriority(i);
+ icon_it->SetSortPriority(i);
if (i != j && save)
- (*it)->SaveCenter();
+ icon_it->SaveCenter();
i++;
if (skipped)
{
icon->SetSortPriority(i);
if (i != j && save)
- (*it)->SaveCenter();
+ icon_it->SaveCenter();
i++;
}
}
else
{
- (*it)->SetSortPriority(i);
+ icon_it->SetSortPriority(i);
if (i != j && save)
- (*it)->SaveCenter();
+ icon_it->SaveCenter();
i++;
}
j++;
diff --git a/plugins/unityshell/src/ScreenEffectFramebufferObject.cpp b/plugins/unityshell/src/ScreenEffectFramebufferObject.cpp
index 6b0011f38..2f2010396 100644
--- a/plugins/unityshell/src/ScreenEffectFramebufferObject.cpp
+++ b/plugins/unityshell/src/ScreenEffectFramebufferObject.cpp
@@ -17,6 +17,7 @@
* Authored By: Sam Spilsbury <sam.spilsbury@canonical.com>
*/
+#ifndef USE_GLES
#include "ScreenEffectFramebufferObject.h"
#include "BackgroundEffectHelper.h"
#include <NuxCore/Logger.h>
@@ -232,3 +233,6 @@ unity::ScreenEffectFramebufferObject::~ScreenEffectFramebufferObject ()
if (mFBTexture)
glDeleteTextures (1, &mFBTexture);
}
+
+#endif // USE_GLES
+
diff --git a/plugins/unityshell/src/ScreenEffectFramebufferObject.h b/plugins/unityshell/src/ScreenEffectFramebufferObject.h
index 1dbecca0e..2481136f1 100644
--- a/plugins/unityshell/src/ScreenEffectFramebufferObject.h
+++ b/plugins/unityshell/src/ScreenEffectFramebufferObject.h
@@ -20,6 +20,7 @@
#ifndef UNITY_SCREENEFFECT_FRAMEBUFFER_H
#define UNITY_SCREENEFFECT_FRAMEBUFFER_H
+#ifndef USE_GLES
#include <Nux/Nux.h>
namespace unity
@@ -84,4 +85,5 @@ private:
};
} // namespace unity
+#endif // USE_GLES
#endif
diff --git a/plugins/unityshell/src/unityshell.cpp b/plugins/unityshell/src/unityshell.cpp
index 168049cbb..cab4bbc25 100644
--- a/plugins/unityshell/src/unityshell.cpp
+++ b/plugins/unityshell/src/unityshell.cpp
@@ -114,7 +114,9 @@ UnityScreen::UnityScreen(CompScreen* screen)
, damaged(false)
, _key_nav_mode_requested(false)
, _last_output(nullptr)
+#ifndef USE_GLES
, _active_fbo (0)
+#endif
, dash_is_open_ (false)
, grab_index_ (0)
, painting_tray_ (false)
@@ -128,6 +130,7 @@ UnityScreen::UnityScreen(CompScreen* screen)
int (*old_handler)(Display*, XErrorEvent*);
old_handler = XSetErrorHandler(NULL);
+#ifndef USE_GLES
/* Ensure OpenGL version is 1.4+. */
version = get_opengl_version_f32((const gchar*) glGetString(GL_VERSION));
if (version < 1.4f)
@@ -183,6 +186,7 @@ UnityScreen::UnityScreen(CompScreen* screen)
failed = true;
}
}
+#endif
if (!failed)
{
@@ -199,16 +203,27 @@ UnityScreen::UnityScreen(CompScreen* screen)
CompositeScreenInterface::setHandler(cScreen);
GLScreenInterface::setHandler(gScreen);
+#ifdef USE_GLES
+ gScreen->glPaintCompositedOutputSetEnabled (this, true);
+#endif
+
PluginAdapter::Initialize(screen);
WindowManager::SetDefault(PluginAdapter::Default());
StartupNotifyService::Default()->SetSnDisplay(screen->snDisplay(), screen->screenNum());
nux::NuxInitialize(0);
+#ifndef USE_GLES
wt = nux::CreateFromForeignWindow(cScreen->output(),
glXGetCurrentContext(),
&UnityScreen::initUnity,
this);
+#else
+ wt = nux::CreateFromForeignWindow(cScreen->output(),
+ eglGetCurrentContext(),
+ &UnityScreen::initUnity,
+ this);
+#endif
wt->RedrawRequested.connect(sigc::mem_fun(this, &UnityScreen::onRedrawRequested));
@@ -226,6 +241,7 @@ UnityScreen::UnityScreen(CompScreen* screen)
_edge_timeout = optionGetLauncherRevealEdgeTimeout ();
_in_paint = false;
+#ifndef USE_GLES
void *dlhand = dlopen ("libunityshell.so", RTLD_LAZY);
if (dlhand)
@@ -242,6 +258,7 @@ UnityScreen::UnityScreen(CompScreen* screen)
uScreen->_fbo = ScreenEffectFramebufferObject::Ptr (new ScreenEffectFramebufferObject (glXGetProcAddressP, geometry));
uScreen->_fbo->onScreenSizeChanged (geometry);
}
+#endif
optionSetBackgroundColorNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2));
optionSetLauncherHideModeNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2));
@@ -363,7 +380,7 @@ void UnityScreen::initAltTabNextWindow()
{
KeyboardUtil key_util (screen->dpy());
guint above_tab_keycode = key_util.GetKeycodeAboveKeySymbol (XStringToKeysym("Tab"));
- KeySym above_tab_keysym = XKeycodeToKeysym (screen->dpy(), above_tab_keycode, 0);
+ KeySym above_tab_keysym = XkbKeycodeToKeysym (screen->dpy(), above_tab_keycode, 0, 0);
if (above_tab_keysym != NoSymbol)
{
@@ -443,6 +460,7 @@ void UnityScreen::CreateSuperNewAction(char shortcut, bool use_shift, bool use_n
void UnityScreen::nuxPrologue()
{
+#ifndef USE_GLES
/* Vertex lighting isn't used in Unity, we disable that state as it could have
* been leaked by another plugin. That should theoretically be switched off
* right after PushAttrib since ENABLE_BIT is meant to restore the LIGHTING
@@ -459,12 +477,14 @@ void UnityScreen::nuxPrologue()
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
+#endif
glGetError();
}
void UnityScreen::nuxEpilogue()
{
+#ifndef USE_GLES
(*GL::bindFramebuffer)(GL_FRAMEBUFFER_EXT, _active_fbo);
glMatrixMode(GL_PROJECTION);
@@ -486,6 +506,11 @@ void UnityScreen::nuxEpilogue()
glReadBuffer(GL_BACK);
glPopAttrib();
+#else
+ glDepthRangef(0, 1);
+ //glViewport(-1, -1, 2, 2);
+ gScreen->resetRasterPos();
+#endif
glDisable(GL_SCISSOR_TEST);
}
@@ -500,6 +525,7 @@ void UnityScreen::OnLauncherHiddenChanged()
void UnityScreen::paintPanelShadow(const GLMatrix& matrix)
{
+#ifndef USE_GLES
if (relayoutSourceId > 0)
return;
@@ -559,6 +585,86 @@ void UnityScreen::paintPanelShadow(const GLMatrix& matrix)
glDisable(GL_BLEND);
}
}
+#else
+#warning Panel shadow not properly implemented for GLES2
+ return;
+
+ if (relayoutSourceId > 0)
+ return;
+
+ if (PluginAdapter::Default()->IsExpoActive())
+ return;
+
+ nuxPrologue();
+
+ CompOutput* output = _last_output;
+ float vc[4];
+ float h = 20.0f;
+ float w = 1.0f;
+ float panel_h = 24.0f;
+
+ float x1 = output->x();
+ float y1 = output->y() + panel_h;
+ float x2 = x1 + output->width();
+ float y2 = y1 + h;
+
+ vc[0] = x1;
+ vc[1] = x2;
+ vc[2] = y1;
+ vc[3] = y2;
+
+ if (!dash_is_open_ && panel_controller_->opacity() > 0.0f)
+ {
+ foreach(GLTexture * tex, _shadow_texture)
+ {
+ std::vector<GLfloat> vertexData;
+ std::vector<GLfloat> textureData;
+ std::vector<GLushort> colorData;
+ GLVertexBuffer *streamingBuffer = GLVertexBuffer::streamingBuffer();
+ bool wasBlend = glIsEnabled(GL_BLEND);
+
+ if (!wasBlend)
+ glEnable(GL_BLEND);
+
+ GL::activeTexture(GL_TEXTURE0);
+ tex->enable(GLTexture::Fast);
+
+ glTexParameteri(tex->target(), GL_TEXTURE_WRAP_S, GL_REPEAT);
+
+ colorData = { 0xFFFF, 0xFFFF, 0xFFFF,
+ (GLushort)(panel_controller_->opacity() * 0xFFFF)
+ };
+
+ vertexData = {
+ vc[0], vc[2], 0,
+ vc[0], vc[3], 0,
+ vc[1], vc[2], 0,
+ vc[1], vc[3], 0,
+ };
+
+ textureData = {
+ COMP_TEX_COORD_X(tex->matrix(), 0), COMP_TEX_COORD_Y(tex->matrix(), 0),
+ COMP_TEX_COORD_X(tex->matrix(), 0), COMP_TEX_COORD_Y(tex->matrix(), h),
+ COMP_TEX_COORD_X(tex->matrix(), w), COMP_TEX_COORD_Y(tex->matrix(), 0),
+ COMP_TEX_COORD_X(tex->matrix(), w), COMP_TEX_COORD_Y(tex->matrix(), h),
+ };
+
+ streamingBuffer->begin(GL_TRIANGLE_STRIP);
+
+ streamingBuffer->addColors(1, &colorData[0]);
+ streamingBuffer->addVertices(4, &vertexData[0]);
+ streamingBuffer->addTexCoords(0, 4, &textureData[0]);
+
+ streamingBuffer->end();
+ streamingBuffer->render(matrix);
+
+ tex->disable();
+ if (!wasBlend)
+ glDisable(GL_BLEND);
+ }
+ }
+ nuxEpilogue();
+#endif
}
void
@@ -573,11 +679,16 @@ UnityWindow::updateIconPos (int &wx,
wy = y + (last_bound.height - height) / 2;
}
+#ifdef USE_GLES
+void UnityScreen::paintDisplay()
+#else
void UnityScreen::paintDisplay(const CompRegion& region, const GLMatrix& transform, unsigned int mask)
+#endif
{
CompOutput *output = _last_output;
Window tray_xid = panel_controller_->GetTrayXid ();
+#ifndef USE_GLES
bool was_bound = _fbo->bound ();
_fbo->unbind ();
@@ -596,6 +707,11 @@ void UnityScreen::paintDisplay(const CompRegion& region, const GLMatrix& transfo
nux::ObjectPtr<nux::IOpenGLTexture2D> device_texture =
nux::GetGraphicsDisplay()->GetGpuDevice()->CreateTexture2DFromID(_fbo->texture(),
screen->width (), screen->height(), 1, nux::BITFMT_R8G8B8A8);
+#else
+ nux::ObjectPtr<nux::IOpenGLTexture2D> device_texture =
+ nux::GetGraphicsDisplay()->GetGpuDevice()->CreateTexture2DFromID(gScreen->fbo ()->tex ()->name (),
+ output->width(), output->height(), 1, nux::BITFMT_R8G8B8A8);
+#endif
nux::GetGraphicsDisplay()->GetGpuDevice()->backup_texture0_ = device_texture;
@@ -603,6 +719,13 @@ void UnityScreen::paintDisplay(const CompRegion& region, const GLMatrix& transfo
nux::Geometry oGeo = nux::Geometry (output->x (), output->y (), output->width (), output->height ());
BackgroundEffectHelper::monitor_rect_ = geo;
+#ifdef USE_GLES
+ GLint fboID;
+ // Nux renders to the referenceFramebuffer when it's embedded.
+ glGetIntegerv(GL_FRAMEBUFFER_BINDING, &fboID);
+ wt->GetWindowCompositor().SetReferenceFramebuffer(fboID, geo);
+#endif
+
nuxPrologue();
_in_paint = true;
wt->RenderInterfaceFromForeignCmd (&oGeo);
@@ -617,36 +740,56 @@ void UnityScreen::paintDisplay(const CompRegion& region, const GLMatrix& transfo
{
GLMatrix oTransform;
UnityWindow *uTrayWindow = UnityWindow::get (tray);
+#ifndef USE_GLES
GLFragment::Attrib attrib (uTrayWindow->gWindow->lastPaintAttrib());
+#else
+ GLWindowPaintAttrib attrib (uTrayWindow->gWindow->lastPaintAttrib());
+#endif
unsigned int oldGlAddGeometryIndex = uTrayWindow->gWindow->glAddGeometryGetCurrentIndex ();
unsigned int oldGlDrawIndex = uTrayWindow->gWindow->glDrawGetCurrentIndex ();
+#ifndef USE_GLES
unsigned int oldGlDrawGeometryIndex = uTrayWindow->gWindow->glDrawGeometryGetCurrentIndex ();
+#endif
+#ifndef USE_GLES
attrib.setOpacity (OPAQUE);
attrib.setBrightness (BRIGHT);
attrib.setSaturation (COLOR);
+#else
+ attrib.opacity = OPAQUE;
+ attrib.brightness = BRIGHT;
+ attrib.saturation = COLOR;
+#endif
oTransform.toScreenSpace (output, -DEFAULT_Z_CAMERA);
+#ifndef USE_GLES
glPushMatrix ();
glLoadMatrixf (oTransform.getMatrix ());
+#endif
painting_tray_ = true;
/* force the use of the core functions */
uTrayWindow->gWindow->glDrawSetCurrentIndex (MAXSHORT);
uTrayWindow->gWindow->glAddGeometrySetCurrentIndex ( MAXSHORT);
+#ifndef USE_GLES
uTrayWindow->gWindow->glDrawGeometrySetCurrentIndex (MAXSHORT);
+#endif
uTrayWindow->gWindow->glDraw (oTransform, attrib, infiniteRegion,
PAINT_WINDOW_TRANSFORMED_MASK |
PAINT_WINDOW_BLEND_MASK |
PAINT_WINDOW_ON_TRANSFORMED_SCREEN_MASK);
+#ifndef USE_GLES
uTrayWindow->gWindow->glDrawGeometrySetCurrentIndex (oldGlDrawGeometryIndex);
+#endif
uTrayWindow->gWindow->glAddGeometrySetCurrentIndex (oldGlAddGeometryIndex);
uTrayWindow->gWindow->glDrawSetCurrentIndex (oldGlDrawIndex);
painting_tray_ = false;
+#ifndef USE_GLES
glPopMatrix ();
+#endif
}
}
@@ -1009,6 +1152,7 @@ bool UnityScreen::glPaintOutput(const GLScreenPaintAttrib& attrib,
allowWindowPaint = true;
_last_output = output;
+#ifndef USE_GLES
/* bind the framebuffer here
* - it will be unbound and flushed
* to the backbuffer when some
@@ -1020,16 +1164,43 @@ bool UnityScreen::glPaintOutput(const GLScreenPaintAttrib& attrib,
* its bind reference so make sure that
* you always unbind as much as you bind */
_fbo->bind (nux::Geometry (output->x (), output->y (), output->width (), output->height ()));
+#endif
/* glPaintOutput is part of the opengl plugin, so we need the GLScreen base class. */
ret = gScreen->glPaintOutput(attrib, transform, region, output, mask);
+#ifndef USE_GLES
if (doShellRepaint)
paintDisplay(region, transform, mask);
+#endif
return ret;
}
+#ifdef USE_GLES
+void UnityScreen::glPaintCompositedOutput (const CompRegion &region,
+ GLFramebufferObject *fbo,
+ unsigned int mask)
+{
+ bool useFbo = false;
+
+ if (doShellRepaint)
+ {
+ oldFbo = fbo->bind ();
+ useFbo = fbo->checkStatus () && fbo->tex ();
+ if (!useFbo) {
+ printf ("bailing from UnityScreen::glPaintCompositedOutput");
+ GLFramebufferObject::rebind (oldFbo);
+ return;
+ }
+ paintDisplay();
+ GLFramebufferObject::rebind (oldFbo);
+ }
+
+ gScreen->glPaintCompositedOutput(region, fbo, mask);
+}
+#endif
+
/* called whenever a plugin needs to paint the entire scene
* transformed */
@@ -1111,7 +1282,9 @@ void UnityScreen::handleEvent(XEvent* event)
PluginAdapter::Default()->OnScreenGrabbed();
else if (event->xfocus.mode == NotifyUngrab)
PluginAdapter::Default()->OnScreenUngrabbed();
+#ifndef USE_GLES
cScreen->damageScreen(); // evil hack
+#endif
if (_key_nav_mode_requested)
launcher.startKeyNavMode();
_key_nav_mode_requested = false;
@@ -1770,7 +1943,11 @@ bool UnityWindow::glPaint(const GLWindowPaintAttrib& attrib,
* and if so paint nux and stop us from painting
* other windows or on top of the whole screen */
bool UnityWindow::glDraw(const GLMatrix& matrix,
+#ifndef USE_GLES
GLFragment::Attrib& attrib,
+#else
+ const GLWindowPaintAttrib& attrib,
+#endif
const CompRegion& region,
unsigned int mask)
{
@@ -1786,7 +1963,11 @@ bool UnityWindow::glDraw(const GLMatrix& matrix,
{
if (xwns[i] == id)
{
+#ifdef USE_GLES
+ uScreen->paintDisplay();
+#else
uScreen->paintDisplay(region, matrix, mask);
+#endif
break;
}
}
@@ -2258,11 +2439,13 @@ void UnityScreen::Relayout()
if (!needsRelayout)
return;
+#ifndef USE_GLES
if (GL::fbo)
{
uScreen->_fbo = ScreenEffectFramebufferObject::Ptr (new ScreenEffectFramebufferObject (glXGetProcAddressP, geometry));
uScreen->_fbo->onScreenSizeChanged (geometry);
}
+#endif
UScreen *uscreen = UScreen::GetDefault();
int primary_monitor = uscreen->GetPrimaryMonitor();
@@ -2388,7 +2571,7 @@ void UnityScreen::InitHints()
hints_.push_back(new shortcut::Hint(launcher, "", "", _("Switch applications via Launcher."), shortcut::HARDCODED_OPTION, "Super + Tab"));
hints_.push_back(new shortcut::Hint(launcher, "", _(" + 1 to 9"), _("Same as clicking on a Launcher icon."), shortcut::COMPIZ_KEY_OPTION, "unityshell", "show_launcher"));
hints_.push_back(new shortcut::Hint(launcher, "", _(" + Shift + 1 to 9"), _("Open new window of the app."), shortcut::COMPIZ_KEY_OPTION, "unityshell", "show_launcher"));
- hints_.push_back(new shortcut::Hint(launcher, "", " + T", _("Open the Rubbish Bin."), shortcut::COMPIZ_KEY_OPTION, "unityshell", "show_launcher"));
+ hints_.push_back(new shortcut::Hint(launcher, "", " + T", _("Open the Trash."), shortcut::COMPIZ_KEY_OPTION, "unityshell", "show_launcher"));
// Dash...
std::string const dash = _("Dash");
diff --git a/plugins/unityshell/src/unityshell.h b/plugins/unityshell/src/unityshell.h
index d81b1de29..adb8d800a 100644
--- a/plugins/unityshell/src/unityshell.h
+++ b/plugins/unityshell/src/unityshell.h
@@ -49,7 +49,9 @@
#include "DebugDBusInterface.h"
#include "SwitcherController.h"
#include "UBusWrapper.h"
+#ifndef USE_GLES
#include "ScreenEffectFramebufferObject.h"
+#endif
#include "compizminimizedwindowhandler.h"
#include "BGHash.h"
@@ -130,7 +132,11 @@ public:
void nuxEpilogue();
/* nux draw wrapper */
+#ifdef USE_GLES
+ void paintDisplay();
+#else
void paintDisplay(const CompRegion& region, const GLMatrix& transform, unsigned int mask);
+#endif
void paintPanelShadow(const GLMatrix& matrix);
void preparePaint (int ms);
@@ -151,6 +157,11 @@ public:
const CompRegion&,
CompOutput*,
unsigned int);
+#ifdef USE_GLES
+ void glPaintCompositedOutput (const CompRegion &region,
+ GLFramebufferObject *fbo,
+ unsigned int mask);
+#endif
/* paint in the special case that the output is transformed */
void glPaintTransformedOutput(const GLScreenPaintAttrib&,
@@ -302,8 +313,12 @@ private:
unity::BGHash _bghash;
+#ifdef USE_GLES
+ GLFramebufferObject *oldFbo;
+#else
ScreenEffectFramebufferObject::Ptr _fbo;
GLuint _active_fbo;
+#endif
bool queryForShader ();
@@ -314,7 +329,9 @@ private:
bool painting_tray_;
unsigned int tray_paint_mask_;
+#ifndef USE_GLES
ScreenEffectFramebufferObject::GLXGetProcAddressProc glXGetProcAddressP;
+#endif
friend class UnityWindow;
};
@@ -351,7 +368,11 @@ public:
/* basic window draw function */
bool glDraw(const GLMatrix& matrix,
+#ifndef USE_GLES
GLFragment::Attrib& attrib,
+#else
+ const GLWindowPaintAttrib& attrib,
+#endif
const CompRegion& region,
unsigned intmask);
diff --git a/services/panel-service.c b/services/panel-service.c
index faab66bf9..da0927954 100644
--- a/services/panel-service.c
+++ b/services/panel-service.c
@@ -31,6 +31,7 @@
#include <gdk/gdkx.h>
#include <X11/extensions/XInput2.h>
+#include <X11/XKBlib.h>
#include "panel-marshal.h"
@@ -249,7 +250,7 @@ event_filter (GdkXEvent *ev, GdkEvent *gev, PanelService *self)
if (event->evtype == XI_KeyRelease)
{
- if (XKeycodeToKeysym(event->display, event->detail, 0) == GDK_KEY_F10)
+ if (XkbKeycodeToKeysym(event->display, event->detail, 0, 0) == GDK_KEY_F10)
{
if (GTK_MENU (priv->last_menu))
gtk_menu_popdown (GTK_MENU (priv->last_menu));
diff --git a/standalone-clients/TestShortcut.cpp b/standalone-clients/TestShortcut.cpp
index db8722494..8a658c115 100644
--- a/standalone-clients/TestShortcut.cpp
+++ b/standalone-clients/TestShortcut.cpp
@@ -42,7 +42,7 @@ void ThreadWidgetInit(nux::NThread* thread, void* InitData)
hints.push_back(new shortcut::MockHint(_("Launcher"), "", "", _("Switch application via Launcher."), shortcut::HARDCODED_OPTION, "Super + Tab"));
hints.push_back(new shortcut::MockHint(_("Launcher"), "", _(" + 1 to 9"), _("Same as clicking on a Launcher icon."), shortcut::COMPIZ_KEY_OPTION, "unityshell", "show_launcher"));
hints.push_back(new shortcut::MockHint(_("Launcher"), "", _(" + Shift + 1 to 9"), _("Open a new window of the app."), shortcut::COMPIZ_KEY_OPTION, "unityshell", "show_launcher"));
- hints.push_back(new shortcut::MockHint(_("Launcher"), "", " + T", _("Open the Rubbish Bin."), shortcut::COMPIZ_KEY_OPTION, "unityshell", "show_launcher"));
+ hints.push_back(new shortcut::MockHint(_("Launcher"), "", " + T", _("Open the Trash."), shortcut::COMPIZ_KEY_OPTION, "unityshell", "show_launcher"));
// Dash...
hints.push_back(new shortcut::MockHint(_("Dash"), "", _(" (Tap)"), _("Open the Dash Home."), shortcut::COMPIZ_KEY_OPTION, "unityshell", "show_launcher"));
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index e7620f209..94b4ac7b2 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -185,10 +185,15 @@ if (GTEST_FOUND AND
test_dashview_impl.cpp
test_texture_cache.cpp
test_main.cpp
+ test_icon_loader.cpp
${UNITY_SRC}/DashViewPrivate.cpp
${UNITY_SRC}/DashViewPrivate.h
${UNITY_SRC}/TextureCache.cpp
${UNITY_SRC}/TextureCache.h
+ ${UNITY_SRC}/IconLoader.cpp
+ ${UNITY_SRC}/IconLoader.h
+ ${UNITY_SRC}/Timer.cpp
+ ${UNITY_SRC}/Timer.h
)
target_link_libraries(test-gtest ${GTEST_BOTH_LIBRARIES})
add_test(UnityGTest test-gtest)
diff --git a/tests/test_icon_loader.cpp b/tests/test_icon_loader.cpp
new file mode 100644
index 000000000..0c9a42a1b
--- /dev/null
+++ b/tests/test_icon_loader.cpp
@@ -0,0 +1,191 @@
+/*
+ * Copyright 2012 Canonical Ltd.
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 3, as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranties of
+ * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 3 along with this program. If not, see
+ * <http://www.gnu.org/licenses/>
+ *
+ * Authored by: Michal Hruby <michal.hruby@canonical.com>
+ */
+
+#include <gmock/gmock.h>
+
+#include "IconLoader.h"
+
+using namespace testing;
+using namespace unity;
+
+namespace
+{
+bool IsValidPixbuf(GdkPixbuf *pixbuf)
+{
+ return GDK_IS_PIXBUF (pixbuf);
+}
+
+gboolean TimeoutReached (gpointer data)
+{
+ bool *b = static_cast<bool*>(data);
+
+ *b = true;
+
+ return FALSE;
+}
+
+struct LoadResult
+{
+ GdkPixbuf *pixbuf;
+ bool got_callback;
+
+ LoadResult() : pixbuf(NULL), got_callback(false) {}
+ void IconLoaded(std::string const& icon_name, unsigned size,
+ GdkPixbuf *buf)
+ {
+ pixbuf = buf;
+
+ got_callback = true;
+ }
+};
+
+TEST(TestIconLoader, TestGetDefault)
+{
+ // we need to initialize gtk
+ int args_cnt = 0;
+ gtk_init (&args_cnt, NULL);
+
+ IconLoader::GetDefault();
+}
+
+TEST(TestIconLoader, TestGetOneIcon)
+{
+ LoadResult load_result;
+ IconLoader& icon_loader = IconLoader::GetDefault();
+ volatile bool timeout_reached = false;
+
+ icon_loader.LoadFromIconName("gedit-icon", 48, sigc::mem_fun(load_result,
+ &LoadResult::IconLoaded));
+
+ guint tid = g_timeout_add (10000, TimeoutReached, (gpointer)(&timeout_reached));
+ while (!timeout_reached && !load_result.got_callback)
+ {
+ g_main_context_iteration (NULL, TRUE);
+ }
+
+ EXPECT_TRUE(load_result.got_callback);
+ EXPECT_TRUE(IsValidPixbuf(load_result.pixbuf));
+
+ g_source_remove (tid);
+}
+
+TEST(TestIconLoader, TestGetManyIcons)
+{
+ std::vector<LoadResult> results;
+ IconLoader& icon_loader = IconLoader::GetDefault();
+ volatile bool timeout_reached = false;
+ int i = 0;
+ int icon_count;
+
+ GList *icons = gtk_icon_theme_list_icons (gtk_icon_theme_get_default (),
+ "Applications");
+ // loading 100 icons should suffice
+ icon_count = MIN (100, g_list_length (icons));
+ results.resize (icon_count);
+ for (GList *it = icons; it != NULL; it = it->next)
+ {
+ const char *icon_name = static_cast<char*>(it->data);
+ icon_loader.LoadFromIconName(icon_name, 48, sigc::mem_fun(results[i++],
+ &LoadResult::IconLoaded));
+ if (i >= icon_count) break;
+ }
+
+ guint tid = g_timeout_add (30000, TimeoutReached, (gpointer)(&timeout_reached));
+ while (!timeout_reached)
+ {
+ g_main_context_iteration (NULL, TRUE);
+ bool all_loaded = true;
+ for (auto loader: results)
+ {
+ all_loaded &= loader.got_callback;
+ if (!all_loaded) break;
+ }
+ if (all_loaded) break;
+ }
+
+ for (auto load_result: results)
+ {
+ EXPECT_TRUE(load_result.got_callback);
+ EXPECT_TRUE(IsValidPixbuf(load_result.pixbuf));
+ }
+
+ g_source_remove (tid);
+}
+
+TEST(TestIconLoader, TestCancelSome)
+{
+ std::vector<LoadResult> results;
+ std::vector<int> handles;
+ IconLoader& icon_loader = IconLoader::GetDefault();
+ volatile bool timeout_reached = false;
+ int i = 0;
+ int icon_count;
+
+ GList *icons = gtk_icon_theme_list_icons (gtk_icon_theme_get_default (),
+ "Emblems");
+ // loading 100 icons should suffice
+ icon_count = MIN (100, g_list_length (icons));
+ results.resize (icon_count);
+ handles.resize (icon_count);
+ for (GList *it = icons; it != NULL; it = it->next)
+ {
+ const char *icon_name = static_cast<char*>(it->data);
+ int handle = icon_loader.LoadFromIconName(icon_name, 48, sigc::mem_fun(
+ results[i], &LoadResult::IconLoaded));
+ handles[i++] = handle;
+ if (i >= icon_count) break;
+ }
+
+ // disconnect every other handler
+ for (i = 0; i < icon_count; i += 2)
+ {
+ icon_loader.DisconnectHandle(handles[i]);
+ }
+
+ guint tid = g_timeout_add (30000, TimeoutReached, (gpointer)(&timeout_reached));
+ while (!timeout_reached)
+ {
+ g_main_context_iteration (NULL, TRUE);
+ bool all_loaded = true;
+ for (int i = 1; i < icon_count; i += 2)
+ {
+ all_loaded &= results[i].got_callback;
+ if (!all_loaded) break;
+ }
+ if (all_loaded) break;
+ }
+
+ for (i = 0; i < icon_count; i++)
+ {
+ if (i % 2)
+ {
+ EXPECT_TRUE(results[i].got_callback);
+ EXPECT_TRUE(IsValidPixbuf(results[i].pixbuf));
+ }
+ else
+ {
+ EXPECT_FALSE(results[i].got_callback);
+ }
+ }
+
+ g_source_remove (tid);
+}
+
+
+}
diff --git a/tools/unity-introspection-visualiser.py b/tools/unity-introspection-visualiser.py
new file mode 100755
index 000000000..fae236e2c
--- /dev/null
+++ b/tools/unity-introspection-visualiser.py
@@ -0,0 +1,87 @@
+#!/usr/bin/env python
+
+#
+# Script to generate a nice PNG file of the currently running unity introspection tree.
+from sys import argv
+import dbus
+
+try:
+ from autopilot.emulators.unity import Unity
+except ImportError:
+ print "Error: could not import the autopilot python module."
+ print "Make sure the autopilot module is in your $PYTHONPATH."
+ exit(1)
+
+try:
+ import pydot
+except ImportError:
+ print "Error: the 'pydot' module is required to run this script."
+ print "Try installing the 'python-pydot' package."
+ exit(1)
+
+NEXT_NODE_ID=1
+
+def string_rep(dbus_type):
+ """Get a string representation of various dbus types."""
+ if type(dbus_type) == dbus.Boolean:
+ return repr(bool(dbus_type))
+ if type(dbus_type) == dbus.String:
+ return str(dbus_type)
+ if type(dbus_type) in (dbus.Int16, dbus.UInt16, dbus.Int32, dbus.UInt32, dbus.Int64, dbus.UInt64):
+ return repr(int(dbus_type))
+ if type(dbus_type) == dbus.Double:
+ return repr(float(dbus_type))
+ if type(dbus_type) == dbus.Array:
+ return ', '.join([string_rep(i) for i in dbus_type])
+ else:
+ return repr(dbus_type)
+
+
+def escape(s):
+ """Escape a string so it can be use in a dot label."""
+ return pydot.quote_if_necessary(s).replace('<','\\<').replace('>', '\\>')
+
+
+def traverse_tree(state, parent, graph):
+ """Recursively traverse state tree, building dot graph as we go."""
+ global NEXT_NODE_ID
+ lbl = parent.get_comment() + "|"
+ # first, set labels for this node:
+ bits = ["%s=%s" % (k, string_rep(state[k])) for k in state.keys() if k != 'Children']
+ lbl += "\l".join(bits)
+ parent.set_label(escape('"{' + lbl + '}"'))
+ if state.has_key('Children'):
+ # Add all array nodes as children of this node.
+ for child_name, child_state in state['Children']:
+ child = pydot.Node(str(NEXT_NODE_ID))
+ NEXT_NODE_ID+=1
+ child.set_comment(child_name)
+ graph.add_node(child)
+ graph.add_edge(pydot.Edge(parent, child))
+
+ traverse_tree(child_state, child, graph)
+
+
+if __name__ == '__main__':
+ if len(argv) != 2:
+ print """Usage: %s output_file.png.
+
+This script queries the currently running Unity process and dumps the entire
+introspection tree into a graph, and renders this to a PNG file.
+""" % (argv[0])
+ exit(1)
+
+ u = Unity()
+ introspection_tree = u.get_state()
+ graph = pydot.Dot()
+ graph.set_simplify(False)
+ graph.set_node_defaults(shape='Mrecord')
+ graph.set_fontname('Ubuntu')
+ graph.set_fontsize('10')
+
+ gnode_unity = pydot.Node("Unity")
+ gnode_unity.set_comment("Unity")
+ traverse_tree(introspection_tree[0], gnode_unity, graph)
+
+ graph.write(argv[1], format='png')
+