Merge branch 'master' into msvc-support-master

Conflicts:
	tests/interactive/Makefile.am
This commit is contained in:
Chun-wei Fan 2011-09-29 16:33:02 +08:00
commit f0dfd8ab07
17 changed files with 485 additions and 261 deletions

View File

@ -27,7 +27,8 @@ typedef enum {
CLUTTER_DEBUG_PICK = 1 << 16,
CLUTTER_DEBUG_EVENTLOOP = 1 << 17,
CLUTTER_DEBUG_CLIPPING = 1 << 18,
CLUTTER_DEBUG_OOB_TRANSFORMS = 1 << 19
CLUTTER_DEBUG_OOB_TRANSFORMS = 1 << 19,
CLUTTER_DEBUG_PAINT_DEFORM_TILES = 1 << 20,
} ClutterDebugFlag;
typedef enum {

View File

@ -290,6 +290,26 @@ clutter_deform_effect_paint_target (ClutterOffscreenEffect *effect)
cogl_set_backface_culling_enabled (FALSE);
else if (priv->back_material == COGL_INVALID_HANDLE && is_cull_enabled)
cogl_set_backface_culling_enabled (TRUE);
if (G_UNLIKELY (clutter_debug_flags & CLUTTER_DEBUG_PAINT_DEFORM_TILES))
{
cogl_set_source_color4f (1.0, 0, 0, 1.0);
cogl_vertex_buffer_draw_elements (priv->vbo,
COGL_VERTICES_MODE_LINE_STRIP,
priv->indices,
0,
n_tiles,
0,
priv->n_indices);
cogl_vertex_buffer_draw_elements (priv->vbo,
COGL_VERTICES_MODE_LINE_STRIP,
priv->back_indices,
0,
n_tiles,
0,
priv->n_indices);
}
}
static inline void

View File

@ -168,7 +168,8 @@ static const GDebugKey clutter_debug_keys[] = {
{ "animation", CLUTTER_DEBUG_ANIMATION },
{ "layout", CLUTTER_DEBUG_LAYOUT },
{ "clipping", CLUTTER_DEBUG_CLIPPING },
{ "oob-transforms", CLUTTER_DEBUG_OOB_TRANSFORMS }
{ "oob-transforms", CLUTTER_DEBUG_OOB_TRANSFORMS },
{ "paint-deform-tiles", CLUTTER_DEBUG_PAINT_DEFORM_TILES },
};
#endif /* CLUTTER_ENABLE_DEBUG */

View File

@ -99,36 +99,37 @@ struct _ClutterTexturePrivate
guint seen_create_pick_material_warning : 1;
};
#define ASYNC_STATE_LOCKED 1
#define ASYNC_STATE_CANCELLED 2
#define ASYNC_STATE_QUEUED 3
struct _ClutterTextureAsyncData
{
/* Mutex used to synchronize setting the abort flag */
GMutex *mutex;
/* If set to true, the loaded data will be discarded */
gboolean abort;
/* The texture for which the data is being loaded */
ClutterTexture *texture;
/* Source ID of the idle handler for loading. If this is zero then
the data is being loaded in a thread from the thread pool. Once
the thread is finished it will be converted to idle load handler
and load_idle will be nonzero. If load_idle is nonzero, and
upload_queued is FALSE then the rest of the load can safely be
aborted by just removing the source, otherwise the abort flag
needs to be set and the data should be disowned */
guint load_idle;
gchar *load_filename;
CoglHandle load_bitmap;
/* Set when the texture is queued for GPU upload, used to determine
* what to do with the texture data when load_idle is zero.
*/
gboolean upload_queued;
guint load_idle;
gchar *load_filename;
CoglHandle load_bitmap;
GError *load_error;
GError *load_error;
gint state;
};
static inline void
clutter_texture_async_data_lock (ClutterTextureAsyncData *data)
{
g_bit_lock (&data->state, 0);
}
static inline void
clutter_texture_async_data_unlock (ClutterTextureAsyncData *data)
{
g_bit_unlock (&data->state, 0);
}
enum
{
PROP_0,
@ -166,7 +167,7 @@ static int texture_signals[LAST_SIGNAL] = { 0 };
static GThreadPool *async_thread_pool = NULL;
static guint repaint_upload_func = 0;
static GList *upload_list = NULL;
static GStaticMutex upload_list_mutex = G_STATIC_MUTEX_INIT;
static GMutex upload_list_mutex = G_MUTEX_INIT;
static CoglMaterial *texture_template_material = NULL;
@ -711,19 +712,14 @@ clutter_texture_async_data_free (ClutterTextureAsyncData *data)
once it is known that the load thread has completed or from the
load thread/upload function itself if the abort flag is true (in
which case the main thread has disowned the data) */
g_free (data->load_filename);
if (data->load_filename)
g_free (data->load_filename);
if (data->load_bitmap)
if (data->load_bitmap != NULL)
cogl_handle_unref (data->load_bitmap);
if (data->load_error)
if (data->load_error != NULL)
g_error_free (data->load_error);
if (data->mutex)
g_mutex_free (data->mutex);
g_slice_free (ClutterTextureAsyncData, data);
}
@ -739,40 +735,30 @@ clutter_texture_async_load_cancel (ClutterTexture *texture)
{
ClutterTexturePrivate *priv = texture->priv;
if (priv->async_data)
if (priv->async_data != NULL)
{
GMutex *mutex = priv->async_data->mutex;
ClutterTextureAsyncData *async_data = priv->async_data;
/* The mutex will only be NULL if the no thread was used for
this load, in which case there's no need for any
synchronization */
if (mutex)
g_mutex_lock (mutex);
priv->async_data = NULL;
/* If there is no thread behind this load then we can just abort
the idle handler and destroy the load data immediately */
if (priv->async_data->load_idle)
if (async_data->load_idle != 0)
{
g_source_remove (priv->async_data->load_idle);
priv->async_data->load_idle = 0;
g_source_remove (async_data->load_idle);
async_data->load_idle = 0;
if (mutex)
g_mutex_unlock (mutex);
clutter_texture_async_data_free (priv->async_data);
clutter_texture_async_data_free (async_data);
}
else
{
/* Otherwise we need to tell the thread to abort and disown
the data, if the data has been loaded and decoded the data
is now waiting for a master clock iteration to be repainted */
priv->async_data->abort = TRUE;
clutter_texture_async_data_lock (async_data);
if (mutex)
g_mutex_unlock (mutex);
CLUTTER_NOTE (TEXTURE, "[async] cancelling operation for '%s'",
async_data->load_filename);
async_data->state |= ASYNC_STATE_CANCELLED;
clutter_texture_async_data_unlock (async_data);
}
priv->async_data = NULL;
}
}
@ -1736,8 +1722,8 @@ clutter_texture_async_load_complete (ClutterTexture *self,
const GError *error)
{
ClutterTexturePrivate *priv = self->priv;
CoglHandle handle;
CoglTextureFlags flags = COGL_TEXTURE_NONE;
CoglHandle handle;
priv->async_data = NULL;
@ -1766,38 +1752,14 @@ clutter_texture_async_load_complete (ClutterTexture *self,
clutter_actor_queue_relayout (CLUTTER_ACTOR (self));
}
static gboolean
clutter_texture_thread_idle_func (gpointer user_data)
{
ClutterTextureAsyncData *data = user_data;
/* Grab the mutex so we can be sure the thread has unlocked it
before we destroy it */
g_mutex_lock (data->mutex);
if (data->abort)
{
g_mutex_unlock (data->mutex);
clutter_texture_async_data_free (data);
return FALSE;
}
g_mutex_unlock (data->mutex);
clutter_texture_async_load_complete (data->texture, data->load_bitmap,
data->load_error);
clutter_texture_async_data_free (data);
return FALSE;
}
static gboolean
texture_repaint_upload_func (gpointer user_data)
{
gulong start_time;
g_static_mutex_lock (&upload_list_mutex);
g_mutex_lock (&upload_list_mutex);
if (upload_list)
if (upload_list != NULL)
{
start_time = clutter_get_timestamp ();
@ -1806,16 +1768,32 @@ texture_repaint_upload_func (gpointer user_data)
*/
do
{
ClutterTextureAsyncData *data = upload_list->data;
ClutterTextureAsyncData *async_data = upload_list->data;
clutter_texture_thread_idle_func (data);
clutter_texture_async_data_lock (async_data);
upload_list = g_list_remove (upload_list, data);
if (async_data->state & ASYNC_STATE_QUEUED)
{
CLUTTER_NOTE (TEXTURE, "[async] operation complete for '%s'",
async_data->load_filename);
clutter_texture_async_load_complete (async_data->texture,
async_data->load_bitmap,
async_data->load_error);
}
else
CLUTTER_NOTE (TEXTURE, "[async] operation cancelled for '%s'",
async_data->load_filename);
clutter_texture_async_data_unlock (async_data);
upload_list = g_list_remove (upload_list, async_data);
clutter_texture_async_data_free (async_data);
}
while (upload_list && clutter_get_timestamp () < start_time + 5 * 1000);
}
if (upload_list)
if (upload_list != NULL)
{
ClutterMasterClock *master_clock;
@ -1823,54 +1801,30 @@ texture_repaint_upload_func (gpointer user_data)
_clutter_master_clock_ensure_next_iteration (master_clock);
}
g_static_mutex_unlock (&upload_list_mutex);
g_mutex_unlock (&upload_list_mutex);
return TRUE;
}
static void
clutter_texture_thread_func (gpointer user_data, gpointer pool_data)
clutter_texture_thread_load (gpointer user_data,
gpointer pool_data)
{
ClutterTextureAsyncData *data = user_data;
gboolean should_abort;
ClutterTextureAsyncData *async_data = user_data;
ClutterMasterClock *master_clock = _clutter_master_clock_get_default ();
/* Make sure we haven't been told to abort before the thread had a
chance to run */
g_mutex_lock (data->mutex);
should_abort = data->abort;
g_mutex_unlock (data->mutex);
clutter_texture_async_data_lock (async_data);
if (should_abort)
if (~async_data->state & ASYNC_STATE_CANCELLED)
{
/* If we've been told to abort then main thread has disowned the
async data and we need to free it */
clutter_texture_async_data_free (data);
return;
}
CLUTTER_NOTE (TEXTURE, "[async] loading bitmap from file '%s'",
async_data->load_filename);
data->load_bitmap = cogl_bitmap_new_from_file (data->load_filename,
&data->load_error);
async_data->load_bitmap =
cogl_bitmap_new_from_file (async_data->load_filename,
&async_data->load_error);
/* Check again if we've been told to abort */
g_mutex_lock (data->mutex);
if (data->abort)
{
g_mutex_unlock (data->mutex);
clutter_texture_async_data_free (data);
}
else
{
ClutterMasterClock *master_clock = _clutter_master_clock_get_default ();
/* Make sure we give the image to GL in the main thread, where we
* hold the main Clutter lock. Once load_idle is non-NULL then the
* main thread is guaranteed not to set the abort flag. It can't
* set it while we're holding the mutex so we can safely start the
* idle handler now without the possibility of calling the
* callback after it is aborted */
g_static_mutex_lock (&upload_list_mutex);
g_mutex_lock (&upload_list_mutex);
if (repaint_upload_func == 0)
{
@ -1879,33 +1833,40 @@ clutter_texture_thread_func (gpointer user_data, gpointer pool_data)
NULL, NULL);
}
upload_list = g_list_append (upload_list, data);
data->upload_queued = TRUE;
upload_list = g_list_append (upload_list, async_data);
async_data->state |= ASYNC_STATE_QUEUED;
g_static_mutex_unlock (&upload_list_mutex);
CLUTTER_NOTE (TEXTURE, "[async] operation queued");
g_mutex_unlock (data->mutex);
_clutter_master_clock_ensure_next_iteration (master_clock);
g_mutex_unlock (&upload_list_mutex);
}
else
{
clutter_texture_async_data_unlock (async_data);
clutter_texture_async_data_free (async_data);
return;
}
clutter_texture_async_data_unlock (async_data);
_clutter_master_clock_ensure_next_iteration (master_clock);
}
static gboolean
clutter_texture_idle_func (gpointer user_data)
clutter_texture_idle_load (gpointer data)
{
ClutterTextureAsyncData *data = user_data;
GError *internal_error = NULL;
ClutterTextureAsyncData *async_data = data;
data->load_bitmap = cogl_bitmap_new_from_file (data->load_filename,
&internal_error);
async_data->load_bitmap =
cogl_bitmap_new_from_file (async_data->load_filename,
&async_data->load_error);
clutter_texture_async_load_complete (data->texture, data->load_bitmap,
internal_error);
clutter_texture_async_load_complete (async_data->texture,
async_data->load_bitmap,
async_data->load_error);
if (internal_error)
g_error_free (internal_error);
clutter_texture_async_data_free (data);
clutter_texture_async_data_free (async_data);
return FALSE;
}
@ -1956,9 +1917,7 @@ clutter_texture_async_load (ClutterTexture *self,
height = 0;
}
else
{
res = cogl_bitmap_get_size_from_file (filename, &width, &height);
}
res = cogl_bitmap_get_size_from_file (filename, &width, &height);
if (!res)
{
@ -1975,35 +1934,34 @@ clutter_texture_async_load (ClutterTexture *self,
clutter_texture_async_load_cancel (self);
data = g_slice_new (ClutterTextureAsyncData);
data = g_slice_new0 (ClutterTextureAsyncData);
data->abort = FALSE;
data->texture = self;
data->load_idle = 0;
data->load_filename = g_strdup (filename);
data->load_bitmap = NULL;
data->load_error = NULL;
priv->async_data = data;
if (g_thread_supported ())
{
data->mutex = g_mutex_new ();
if (async_thread_pool == NULL)
/* This apparently can't fail if exclusive == FALSE */
async_thread_pool
= g_thread_pool_new (clutter_texture_thread_func,
NULL, 1, FALSE, NULL);
if (G_UNLIKELY (async_thread_pool == NULL))
{
/* This apparently can't fail if exclusive == FALSE */
async_thread_pool =
g_thread_pool_new (clutter_texture_thread_load, NULL,
1,
FALSE,
NULL);
}
g_thread_pool_push (async_thread_pool, data, NULL);
}
else
{
data->mutex = NULL;
data->load_idle
= clutter_threads_add_idle (clutter_texture_idle_func, data);
data->load_idle =
clutter_threads_add_idle_full (G_PRIORITY_DEFAULT_IDLE,
clutter_texture_idle_load,
data,
NULL);
}
return TRUE;
@ -2921,6 +2879,8 @@ clutter_texture_set_load_async (ClutterTexture *texture,
priv = texture->priv;
load_async = !!load_async;
if (priv->load_async_set != load_async)
{
priv->load_data_async = load_async;

View File

@ -113,7 +113,7 @@ LT_INIT([disable-static])
AC_HEADER_STDC
# required versions for dependencies
m4_define([glib_req_version], [2.28.0])
m4_define([glib_req_version], [2.31.0])
m4_define([cogl_req_version], [1.8.0])
m4_define([json_glib_req_version], [0.12.0])
m4_define([atk_req_version], [2.1.5])

View File

@ -8,7 +8,7 @@ msgstr ""
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug."
"cgi?product=clutter&keywords=I18N+L10N&component=general\n"
"POT-Creation-Date: 2011-09-23 07:16+0000\n"
"PO-Revision-Date: 2011-09-23 14:38+0530\n"
"PO-Revision-Date: 2011-09-26 21:28+0530\n"
"Last-Translator: Krishnababu Krothapalli <kkrothap@redhat.com>\n"
"Language-Team: Telugu <te@li.org>\n"
"MIME-Version: 1.0\n"
@ -24,15 +24,15 @@ msgstr "X అక్షము"
#: ../clutter/clutter-actor.c:3876
msgid "X coordinate of the actor"
msgstr ""
msgstr "ఏక్టర్ యొక్క X అక్షము"
#: ../clutter/clutter-actor.c:3891
msgid "Y coordinate"
msgstr ""
msgstr "Y అక్షము"
#: ../clutter/clutter-actor.c:3892
msgid "Y coordinate of the actor"
msgstr ""
msgstr "ఏక్టర్ యొక్క Y అక్షము"
#: ../clutter/clutter-actor.c:3907 ../clutter/clutter-behaviour-ellipse.c:477
msgid "Width"
@ -40,7 +40,7 @@ msgstr "వెడల్పు"
#: ../clutter/clutter-actor.c:3908
msgid "Width of the actor"
msgstr ""
msgstr "ఏక్టర్ యొక్క వెడల్పు"
#: ../clutter/clutter-actor.c:3922 ../clutter/clutter-behaviour-ellipse.c:493
msgid "Height"
@ -48,31 +48,31 @@ msgstr "ఎత్తు"
#: ../clutter/clutter-actor.c:3923
msgid "Height of the actor"
msgstr ""
msgstr "ఏక్టర్ యొక్క యెత్తు"
#: ../clutter/clutter-actor.c:3941
msgid "Fixed X"
msgstr ""
msgstr "నిర్దిష్ట X"
#: ../clutter/clutter-actor.c:3942
msgid "Forced X position of the actor"
msgstr ""
msgstr "ఏక్టర్ యొక్క నిర్దిష్ట X స్థానం"
#: ../clutter/clutter-actor.c:3960
msgid "Fixed Y"
msgstr ""
msgstr "నిర్దిష్ట Y"
#: ../clutter/clutter-actor.c:3961
msgid "Forced Y position of the actor"
msgstr ""
msgstr "ఏక్టర్ యొక్క బలవంతపు Y స్థానం"
#: ../clutter/clutter-actor.c:3977
msgid "Fixed position set"
msgstr ""
msgstr "నిర్దిష్ట స్థాన అమర్పు"
#: ../clutter/clutter-actor.c:3978
msgid "Whether to use fixed positioning for the actor"
msgstr ""
msgstr "ఏక్టర్ కొరకు నిర్దిష్టంగా స్థానపరచుటను వుపయోగించాలా"
#: ../clutter/clutter-actor.c:4000
msgid "Min Width"
@ -80,7 +80,7 @@ msgstr "కనిష్ఠ వెడల్పు"
#: ../clutter/clutter-actor.c:4001
msgid "Forced minimum width request for the actor"
msgstr ""
msgstr "ఏక్టర్ కొరకు అభ్యర్దించిన బలవంతపు కనిష్ట వెడల్పు"
#: ../clutter/clutter-actor.c:4020
msgid "Min Height"
@ -88,119 +88,120 @@ msgstr "కనిష్ఠ ఎత్తు"
#: ../clutter/clutter-actor.c:4021
msgid "Forced minimum height request for the actor"
msgstr ""
msgstr "ఏక్టర్ కొరకు అభ్యర్దించిన బలవంతపు కనిష్ట యెత్తు"
#: ../clutter/clutter-actor.c:4040
msgid "Natural Width"
msgstr ""
msgstr "సహజ వెడల్పు"
#: ../clutter/clutter-actor.c:4041
msgid "Forced natural width request for the actor"
msgstr ""
msgstr "ఏక్టర్ కొరకు అభ్యర్దించిన బలవంతపు సహజ వెడల్పు"
#: ../clutter/clutter-actor.c:4060
msgid "Natural Height"
msgstr ""
msgstr "సహజ యెత్తు"
#: ../clutter/clutter-actor.c:4061
msgid "Forced natural height request for the actor"
msgstr ""
msgstr "ఏక్టర్ కొరకు అభ్యర్దించిన బలవంతపు సహజ యెత్తు"
#: ../clutter/clutter-actor.c:4077
msgid "Minimum width set"
msgstr ""
msgstr "కనిష్ట వెడల్పు అమర్పు"
#: ../clutter/clutter-actor.c:4078
msgid "Whether to use the min-width property"
msgstr ""
msgstr "కనిష్ట-వెడల్పు లక్షణం వుపయోగించాలా"
#: ../clutter/clutter-actor.c:4093
msgid "Minimum height set"
msgstr ""
msgstr "కనిష్ట యెత్తు అమర్పు"
#: ../clutter/clutter-actor.c:4094
msgid "Whether to use the min-height property"
msgstr ""
msgstr "కనిష్ట-యెత్తు లక్షణం వుపయోగించాలా"
#: ../clutter/clutter-actor.c:4109
msgid "Natural width set"
msgstr ""
msgstr "సహజ వెడల్పు అమర్పు"
#: ../clutter/clutter-actor.c:4110
msgid "Whether to use the natural-width property"
msgstr ""
msgstr "సహజ-వెడల్పు లక్షణం వుపయోగించాలా"
#: ../clutter/clutter-actor.c:4127
msgid "Natural height set"
msgstr ""
msgstr "సహజ యెత్తు అమర్పు"
#: ../clutter/clutter-actor.c:4128
msgid "Whether to use the natural-height property"
msgstr ""
msgstr "సహజ-యెత్తు లక్షణం వుపయోగించాలా"
#: ../clutter/clutter-actor.c:4147
msgid "Allocation"
msgstr ""
msgstr "కేటాయింపు"
#: ../clutter/clutter-actor.c:4148
msgid "The actor's allocation"
msgstr ""
msgstr "ఏక్టర్ యొక్క కేటాయింపు"
#: ../clutter/clutter-actor.c:4204
msgid "Request Mode"
msgstr ""
msgstr "అభ్యర్దన రీతి"
#: ../clutter/clutter-actor.c:4205
msgid "The actor's request mode"
msgstr ""
msgstr "ఏక్టర్ యొక్క అభ్యర్దన రీతి"
#: ../clutter/clutter-actor.c:4220
msgid "Depth"
msgstr ""
msgstr "లోతు"
#: ../clutter/clutter-actor.c:4221
msgid "Position on the Z axis"
msgstr ""
msgstr "Z అక్షంపై స్థానం"
#: ../clutter/clutter-actor.c:4235
msgid "Opacity"
msgstr ""
msgstr "మసక"
#: ../clutter/clutter-actor.c:4236
msgid "Opacity of an actor"
msgstr ""
msgstr "ఏక్టర్ యొక్క మసక"
#: ../clutter/clutter-actor.c:4255
msgid "Offscreen redirect"
msgstr ""
msgstr "ఆఫ్‌స్క్రీన్ రీడైరెక్ట్"
#: ../clutter/clutter-actor.c:4256
msgid "Flags controlling when to flatten the actor into a single image"
msgstr ""
"ఏక్టర్‌ను వొంటరి ప్రతిరూపమునకు యెప్పుడు ఫ్లాటెన్ చేయాలో నియంత్రించే ఫ్లాగులు"
#: ../clutter/clutter-actor.c:4274
msgid "Visible"
msgstr ""
msgstr "దృశ్యనీయం"
#: ../clutter/clutter-actor.c:4275
msgid "Whether the actor is visible or not"
msgstr ""
msgstr "ఏక్టర్ దృశ్యనీయం కావలెనా లేదా"
#: ../clutter/clutter-actor.c:4290
msgid "Mapped"
msgstr ""
msgstr "మాప్‌డ్"
#: ../clutter/clutter-actor.c:4291
msgid "Whether the actor will be painted"
msgstr ""
msgstr "ఏక్టర్ రంగు వేయబడుదురా"
#: ../clutter/clutter-actor.c:4305
msgid "Realized"
msgstr ""
msgstr "తెలుసుకొనెను"
#: ../clutter/clutter-actor.c:4306
msgid "Whether the actor has been realized"
msgstr ""
msgstr "ఏక్టర్‌కు తెలియవలెనా"
#: ../clutter/clutter-actor.c:4322
msgid "Reactive"

View File

@ -1,7 +1,7 @@
include $(top_srcdir)/build/autotools/Makefile.am.silent
UNIT_TESTS = \
test-textures.c \
test-texture-slicing.c \
test-texture-async.c \
test-texture-material.c \
test-events.c \
@ -74,11 +74,13 @@ endif
# For convenience, this provides a way to easily run individual unit tests:
wrappers: stamp-test-interactive ../../build/win32/test-interactive.bat
@true
stamp-test-interactive: Makefile test-interactive$(EXEEXT)
stamp-test-interactive: Makefile
@wrapper=$(abs_builddir)/wrapper.sh ; \
chmod +x $$wrapper && \
( echo "/stamp-test-interactive" ; \
echo "/stamp-test-unit-names" ; \
echo "/test-interactive" ; \
echo "/test-unit-names.h" ; \
echo "*.o" ; \
echo ".gitignore" ) > .gitignore ; \
for i in $(UNIT_TESTS); \
@ -107,6 +109,21 @@ stamp-test-interactive: Makefile test-interactive$(EXEEXT)
done \
&& cp *.bat $(top_srcdir)/build/win32/
test-unit-names.h: stamp-test-unit-names
@true
stamp-test-unit-names: Makefile
@( echo "/* ** This file is autogenerated. Do not edit. ** */" ; \
echo "" ; \
echo "const char *test_unit_names[] = {" ) > test-unit-names.h ; \
for i in $(UNIT_TESTS); \
do \
test_bin=$${i%*.c} ; \
echo " \"$$test_bin\"," >> test-unit-names.h ; \
done \
&& echo "};" >> test-unit-names.h \
&& echo timestamp > $(@F)
clean-wrappers:
@for i in $(UNIT_TESTS); \
do \
@ -131,7 +148,7 @@ common_ldadd = $(top_builddir)/clutter/libclutter-@CLUTTER_SONAME_INFIX@-@CLUTTE
noinst_PROGRAMS = test-interactive
test_interactive_SOURCES = test-main.c $(UNIT_TESTS)
test_interactive_SOURCES = test-main.c test-unit-names.h $(UNIT_TESTS)
test_interactive_CFLAGS = $(CLUTTER_CFLAGS) $(MAINTAINER_CFLAGS)
test_interactive_CPPFLAGS = \
-DTESTS_DATADIR=\""$(abs_top_srcdir)/tests/data"\" \
@ -142,9 +159,9 @@ test_interactive_LDFLAGS = -export-dynamic
test_interactive_LDADD = $(CLUTTER_LIBS) $(common_ldadd) -lm
EXTRA_DIST = wrapper.sh.in
DISTCLEANFILES = wrapper.sh .gitignore
DISTCLEANFILES = wrapper.sh .gitignore test-unit-names.h
BUILT_SOURCES = wrappers
BUILT_SOURCES = wrappers test-unit-names.h
dist-hook: ../../build/win32/vs9/test-interactive.vcproj ../../build/win32/vs10/test-interactive.vcxproj ../../build/win32/vs10/test-interactive.vcxproj.filters

View File

@ -114,3 +114,9 @@ test_animation_main (int argc, char *argv[])
return EXIT_SUCCESS;
}
G_MODULE_EXPORT const char *
test_animation_describe (void)
{
return "Simple clutter_actor_animate() demo";
}

View File

@ -111,3 +111,9 @@ test_cairo_clock_main (int argc, char *argv[])
return EXIT_SUCCESS;
}
G_MODULE_EXPORT const char *
test_cairo_clock_describe (void)
{
return "Simple 2D canvas using a Cairo texture actor";
}

View File

@ -247,3 +247,9 @@ test_constraints_main (int argc, char *argv[])
return EXIT_SUCCESS;
}
G_MODULE_EXPORT const char *
test_constraints_describe (void)
{
return "Visualize usage of Bind and Align constraints";
}

View File

@ -243,3 +243,9 @@ test_drop_main (int argc, char *argv[])
return EXIT_SUCCESS;
}
G_MODULE_EXPORT const char *
test_drop_describe (void)
{
return "Drop action support";
}

View File

@ -262,3 +262,9 @@ test_easing_main (int argc, char *argv[])
return EXIT_SUCCESS;
}
G_MODULE_EXPORT const char *
test_easing_describe (void)
{
return "Visualize all easing modes provided by Clutter";
}

View File

@ -1,37 +1,207 @@
#include <stdlib.h>
#include <string.h>
#include <glib.h>
#include <gmodule.h>
#include "test-unit-names.h"
#define MAX_DESC_SIZE 72
static GModule *module = NULL;
static gpointer
get_symbol_with_suffix (const char *unit_name,
const char *suffix)
{
char *main_symbol_name;
gpointer func;
main_symbol_name = g_strconcat (unit_name, "_", suffix, NULL);
main_symbol_name = g_strdelimit (main_symbol_name, "-", '_');
g_module_symbol (module, main_symbol_name, &func);
g_free (main_symbol_name);
return func;
}
static gpointer
get_unit_name_main (const char *unit_name)
{
return get_symbol_with_suffix (unit_name, "main");
}
static char *
get_unit_name_description (const char *unit_name,
gssize max_len)
{
const char *description;
gpointer func;
char *retval;
func = get_symbol_with_suffix (unit_name, "describe");
if (func == NULL)
description = "No description found";
else
{
const char *(* unit_test_describe) (void);
unit_test_describe = func;
description = unit_test_describe ();
}
if (max_len > 0 && strlen (description) >= max_len)
{
GString *buf = g_string_sized_new (max_len);
char *newline;
newline = strchr (description, '\n');
if (newline != NULL)
{
g_string_append_len (buf, description,
MIN (newline - description - 1, max_len - 3));
}
else
g_string_append_len (buf, description, max_len - 3);
g_string_append (buf, "...");
retval = g_string_free (buf, FALSE);
}
else
retval = g_strdup (description);
return retval;
}
static gboolean list_all = FALSE;
static gboolean describe = FALSE;
static char **unit_names = NULL;
static GOptionEntry entries[] = {
{
"describe", 'd',
0,
G_OPTION_ARG_NONE, &describe,
"Describe the interactive unit test", NULL,
},
{
"list-all", 'l',
0,
G_OPTION_ARG_NONE, &list_all,
"List all available units", NULL,
},
{
G_OPTION_REMAINING, 0,
0,
G_OPTION_ARG_STRING_ARRAY, &unit_names,
"The interactive unit test", "UNIT_NAME"
},
{ NULL }
};
int
main (int argc, char **argv)
{
GModule *module;
char *unit_test;
char *main_symbol_name;
gpointer func;
int (*unit_test_main) (int argc, char **argv);
int ret;
int ret, i, n_unit_names;
GOptionContext *context;
context = g_option_context_new (" - Interactive test suite");
g_option_context_add_main_entries (context, entries, NULL);
g_option_context_set_help_enabled (context, TRUE);
g_option_context_set_ignore_unknown_options (context, TRUE);
if (!g_option_context_parse (context, &argc, &argv, NULL))
{
g_print ("Usage: test-interactive <unit_test>\n");
return EXIT_FAILURE;
}
g_option_context_free (context);
if (argc < 2)
g_error ("Usage: %s unit_test", argv[0]);
module = g_module_open (NULL, 0);
if (!module)
g_error ("Failed to open self for symbol lookup");
g_error ("*** Failed to open self for symbol lookup");
unit_test = g_path_get_basename (argv[1]);
ret = EXIT_SUCCESS;
main_symbol_name = g_strdup_printf ("%s_main", unit_test);
main_symbol_name = g_strdelimit (main_symbol_name, "-", '_');
if (list_all)
{
g_print ("* Available unit tests:\n");
if (!g_module_symbol (module, main_symbol_name, &func))
g_error ("Failed to look up main symbol for the test: %s", unit_test);
for (i = 0; i < G_N_ELEMENTS (test_unit_names); i++)
{
char *str;
gsize len;
unit_test_main = func;
ret = unit_test_main (argc - 1, argv + 1);
g_free (unit_test);
g_free (main_symbol_name);
len = MAX_DESC_SIZE - strlen (test_unit_names[i]);
str = get_unit_name_description (test_unit_names[i], len - 2);
g_print (" - %s:%*s%s\n",
test_unit_names[i],
(int) len - strlen (str), " ",
str);
g_free (str);
}
ret = EXIT_SUCCESS;
goto out;
}
n_unit_names = g_strv_length (unit_names);
for (i = 0; i < n_unit_names; i++)
{
const char *unit_name = unit_names[i];
char *unit_test = NULL;
gboolean found;
int j;
unit_test = g_path_get_basename (unit_name);
found = FALSE;
for (j = 0; j < G_N_ELEMENTS (test_unit_names); j++)
{
if (strcmp (test_unit_names[j], unit_test) == 0)
{
found = TRUE;
break;
}
}
if (!found)
g_error ("*** Unit '%s' does not exist", unit_test);
if (describe)
{
char *str;
str = get_unit_name_description (unit_test, -1);
g_print ("* %s:\n%s\n\n", unit_test, str);
g_free (str);
ret = EXIT_SUCCESS;
}
else
{
int (* unit_test_main) (int argc, char **argv);
gpointer func;
func = get_unit_name_main (unit_test);
if (func == NULL)
g_error ("*** Unable to find the main entry point for '%s'", unit_test);
unit_test_main = func;
ret = unit_test_main (argc, argv);
}
g_free (unit_test);
}
out:
g_module_close (module);
return ret;

View File

@ -274,3 +274,9 @@ test_table_layout_main (int argc, char *argv[])
return EXIT_SUCCESS;
}
G_MODULE_EXPORT const char *
test_table_layout_describe (void)
{
return "Table layout manager";
}

View File

@ -334,3 +334,14 @@ test_text_field_main (gint argc,
return EXIT_SUCCESS;
}
G_MODULE_EXPORT const char *
test_text_field_describe (void)
{
return
"Text actor single-line and password mode support\n"
"\n"
"This test checks the :single-line-mode and :password-char properties of\n"
"the ClutterText actor, plus the password hint feature and the :max-length\n"
"property.";
}

View File

@ -1,7 +1,5 @@
#include <stdlib.h>
#include <gmodule.h>
#undef CLUTTER_DISABLE_DEPRECATED
#include <clutter/clutter.h>
enum
@ -11,6 +9,8 @@ enum
LOAD_ASYNC
};
static ClutterActor *stage = NULL;
static void
on_load_finished (ClutterTexture *texture,
const GError *error,
@ -52,17 +52,11 @@ size_change_cb (ClutterTexture *texture,
static
gboolean task (gpointer user_data)
{
ClutterTimeline *timeline;
ClutterAlpha *alpha;
ClutterBehaviour *depth_behavior;
ClutterActor *image[4];
ClutterActor *clone[4];
ClutterActor *stage;
gchar *path = user_data;
const gchar *path = user_data;
ClutterActor *image[3];
ClutterActor *clone[3];
gint i;
stage = clutter_stage_get_default ();
image[0] = g_object_new (CLUTTER_TYPE_TEXTURE, NULL);
g_signal_connect (image[0], "load-finished",
G_CALLBACK (on_load_finished),
@ -93,62 +87,69 @@ gboolean task (gpointer user_data)
}
for (i = 0; i < 3; i++)
clutter_container_add (CLUTTER_CONTAINER (stage), image[i], NULL);
clutter_container_add_actor (CLUTTER_CONTAINER (stage), image[i]);
for (i = 0; i < 3; i++)
{
clutter_actor_set_position (image[i], 50+i*100, 0+i*50);
clone[i]=clutter_clone_new (image[i]);
clutter_actor_set_position (image[i], 50 + i * 100, 0 + i * 50);
clone[i] = clutter_clone_new (image[i]);
g_signal_connect (image[i], "size-change",
G_CALLBACK (size_change_cb), clone[i]);
clutter_container_add (CLUTTER_CONTAINER (stage), clone[i], NULL);
clutter_actor_set_position (clone[i], 50+i*100, 150+i*50+100);
clutter_container_add_actor (CLUTTER_CONTAINER (stage), clone[i]);
clutter_actor_set_position (clone[i], 50 + i * 100, 150 + i * 50 + 100);
}
for (i = 0; i < 3; i++)
{
timeline = clutter_timeline_new (5000);
alpha = clutter_alpha_new_full (timeline, CLUTTER_LINEAR);
depth_behavior = clutter_behaviour_depth_new (alpha, -2500, 0);
clutter_behaviour_apply (depth_behavior, image[i]);
clutter_timeline_start (timeline);
clutter_actor_set_depth (image[i], -2500);
clutter_actor_animate (image[i], CLUTTER_LINEAR, 5000,
"depth", 0.0,
NULL);
}
return FALSE;
}
static void
cleanup_task (gpointer data)
{
}
G_MODULE_EXPORT gint
test_texture_async_main (int argc, char *argv[])
{
ClutterActor *stage;
ClutterColor stage_color = { 0x12, 0x34, 0x56, 0xff };
gchar *path;
gchar *path;
g_thread_init (NULL);
clutter_threads_init ();
if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS)
return 1;
g_thread_init (NULL);
stage = clutter_stage_get_default ();
clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color);
stage = clutter_stage_new ();
clutter_stage_set_title (CLUTTER_STAGE (stage), "Asynchronous Texture Loading");
clutter_stage_set_color (CLUTTER_STAGE (stage), CLUTTER_COLOR_LightSkyBlue);
g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL);
clutter_actor_show (stage);
g_signal_connect (stage,
"button-press-event", G_CALLBACK (clutter_main_quit),
NULL);
path = (argc > 1)
? g_strdup (argv[1])
: g_build_filename (TESTS_DATADIR, "redhand.png", NULL);
clutter_threads_add_timeout (500, task, path);
clutter_threads_add_timeout_full (G_PRIORITY_DEFAULT, 500,
task, path,
cleanup_task);
clutter_main ();
g_free (path);
/*g_object_unref (depth_behavior);
g_object_unref (timeline);*/
return EXIT_SUCCESS;
}
G_MODULE_EXPORT const char *
test_texture_async_describe (void)
{
return "Texture asynchronous loading using threads";
}

View File

@ -110,3 +110,9 @@ test_textures_main (int argc, char *argv[])
return EXIT_SUCCESS;
}
G_MODULE_EXPORT const char *
test_texture_slicing_describe (void)
{
return "Check texture slicing support in CoglTexture";
}