Merge branch 'master' into msvc-support-master

This commit is contained in:
Chun-wei Fan 2011-11-14 11:40:49 +08:00
commit 1b7249a247
48 changed files with 2887 additions and 2894 deletions

2
.gitignore vendored
View File

@ -22,7 +22,7 @@ stamp-marshal
/clutter/clutter-version.h /clutter/clutter-version.h
/clutter/gcov-report.txt /clutter/gcov-report.txt
/clutter/clutter-json.h /clutter/clutter-json.h
/clutter/egl/clutter-cex100.h /clutter/cex100/clutter-cex100.h
/build/autotools/*.m4 /build/autotools/*.m4
!/build/autotools/introspection.m4 !/build/autotools/introspection.m4
!/build/autotools/as-linguas.m4 !/build/autotools/as-linguas.m4

View File

@ -16,7 +16,7 @@ Clutter currently requires:
• Cairo ≥ @CAIRO_REQ_VERSION@ • Cairo ≥ @CAIRO_REQ_VERSION@
• PangoCairo ≥ @PANGO_REQ_VERSION@ • PangoCairo ≥ @PANGO_REQ_VERSION@
On X11, Clutter depends on the following extensions When building the X11 backend, Clutter depends on the following extensions:
• XComposite ≥ @XCOMPOSITE_REQ_VERSION@ • XComposite ≥ @XCOMPOSITE_REQ_VERSION@
• XDamage • XDamage
@ -25,6 +25,19 @@ On X11, Clutter depends on the following extensions
• XInput (1.x or 2.x) • XInput (1.x or 2.x)
• XKB • XKB
When building the Wayland backend, Clutter also depends on:
• wayland-client
• xkbcommon
When building the GDK backend, Clutter also depends on:
• gdk-3.0 > @GDK_REQ_VERSION@
When building the CEx100 backend, Clutter also depends on:
• libgdl
If you are building the API reference you will also need: If you are building the API reference you will also need:
• GTK-Doc ≥ @GTK_DOC_REQ_VERSION@ • GTK-Doc ≥ @GTK_DOC_REQ_VERSION@
@ -109,7 +122,7 @@ See also the wiki page:
Clutter has additional command line options for the configure script: Clutter has additional command line options for the configure script:
--enable-debug=[no/minimum/yes/error] --enable-debug=[no/minimum/yes]
Controls Clutter debugging level: Controls Clutter debugging level:
yes: yes:
@ -170,19 +183,19 @@ Clutter has additional command line options for the configure script:
Enable the GDK backend. (default=check) Enable the GDK backend. (default=check)
--enable-wayland-backend=[yes/no] --enable-wayland-backend=[yes/no]
Enable the Wayland client backend. (default=no) Enable the Wayland client backend. (default=no) [EXPERIMENTAL]
--enable-cex100-backend=[yes/no]
Enable the CEx100 platform backend. (default=no) [EXPERIMENTAL]
--enable-egl-backend=[yes/no] --enable-egl-backend=[yes/no]
Enable the EGL framebuffer backend. (default=no) Enable the EGL framebuffer backend. (default=no)
--with-tslib=[yes/no] --enable-tslib-input=[yes/no]
Use TSLib for the input events. (default=yes) Enable the TSLib input backend. (default=no) [EXPERIMENTAL]
--with-evdev=[yes/no] --enable-evdev-input=[yes/no]
Use evdev for the input events. (default=yes) Enable the evdev input backend. (default=no) [EXPERIMENTAL]
--with-gdl=[yes/no]
Use libgdl for CEx100 platforms. (default=no)
See also the INSTALL file generated by autotools for further information. See also the INSTALL file generated by autotools for further information.
@ -273,6 +286,52 @@ Relevant information for developers with existing Clutter applications
wanting to port to newer releases (see NEWS for general information on new wanting to port to newer releases (see NEWS for general information on new
features). features).
Release Notes for Clutter 1.10
-------------------------------------------------------------------------------
• Clutter can support multiple backends in the same shared library. Only one
windowing or input backend can be used at run time. As a result of this
change, the shared library name used by Clutter has changed from:
libclutter-<flavour>-<API version>.so
to:
libclutter-<API version>.so
The pkg-config file has been updated accordingly. Until the next major API
break, Clutter will ship compatibility links for all the previous "flavours"
that were available in versions < 1.10; this allows applications dynamically
linking against Clutter, or using dlopen(), to keep working. For libraries
and applications dynamically linking against Clutter, though, it is still
recommended to recompile to make sure that the most recent version is being
used. Language bindings using GObject Introspection will automatically use
the new shared library without requiring any change.
• The windowing system backend for the CE3100 and CE4100 platforms using the
libgdl library is now implemented as a separate backend instance, instead
of being a sub-flavour of the EGL native framebuffer backend. This change
introduces a new header file, under $includedir/clutter-1.0/clutter/cex100,
which should be included to access the CEx100-specific API. The API and
ABI of the platform API has not been changed, though it should still be
considered experimental.
• As of 1.10 it is not necessary any more to call clutter_threads_init() to
initialize threading support in Clutter; after the changes in GLib 2.32,
threading support in Clutter is always enabled. The rules on how to use
Clutter from multiple threads haven't changed.
• Deprecated API is now marked using the CLUTTER_DEPRECATED and the
CLUTTER_DEPRECATED_FOR annotations; these two annotations will result in
compiler warnings when attempting to use the deprecated API. It is possible
to disable deprecation warnings for Clutter by defining the
CLUTTER_DISABLE_DEPRECATION_WARNINGS symbol when compiling. The previous
deprecation symbol, CLUTTER_DISABLE_DEPRECATED, is only used for macros.
• Deprecated functionality has been moved to separate header files, installed
under the $includedir/clutter-1.0/clutter/deprecated directory. These files
are still included by default by clutter/clutter.h.
Release Notes for Clutter 1.8 Release Notes for Clutter 1.8
------------------------------------------------------------------------------- -------------------------------------------------------------------------------

View File

@ -388,12 +388,10 @@ endif # SUPPORT_X11
cogl_source_h = cogl_source_h =
cogl_source_c = \ cogl_source_c = \
$(srcdir)/cogl/clutter-backend-cogl.c \
$(srcdir)/cogl/clutter-stage-cogl.c \ $(srcdir)/cogl/clutter-stage-cogl.c \
$(NULL) $(NULL)
cogl_source_h_priv = \ cogl_source_h_priv = \
$(srcdir)/cogl/clutter-backend-cogl.h \
$(srcdir)/cogl/clutter-stage-cogl.h \ $(srcdir)/cogl/clutter-stage-cogl.h \
$(NULL) $(NULL)
@ -549,7 +547,9 @@ evdev_h_priv = \
$(srcdir)/evdev/clutter-input-device-evdev.h \ $(srcdir)/evdev/clutter-input-device-evdev.h \
$(NULL) $(NULL)
cex_h = egl/clutter-cex100.h cex_source_h_priv = $(srcdir)/cex100/clutter-backend-cex100.h
cex_source_c = $(srcdir)/cex100/clutter-backend-cex100.c
cex_h = cex100/clutter-cex100.h
BUILT_SOURCES += $(cex_h) BUILT_SOURCES += $(cex_h)
EXTRA_DIST += $(srcdir)/$(cex_h).in EXTRA_DIST += $(srcdir)/$(cex_h).in
@ -564,7 +564,12 @@ egl_source_h_priv += $(evdev_h_priv)
endif # SUPPORT_EVDEV endif # SUPPORT_EVDEV
if SUPPORT_CEX100 if SUPPORT_CEX100
egl_source_h += $(cex_h) backend_source_h += $(cex_h)
backend_source_c += $(cex_source_c)
backend_source_h_priv += $(cex_source_h_priv)
cluttercex100_includedir = $(clutter_includedir)/cex100
cluttercex100_include_HEADERS = $(cex_h)
clutter-cex100-$(CLUTTER_API_VERSION).pc: clutter-$(CLUTTER_API_VERSION).pc clutter-cex100-$(CLUTTER_API_VERSION).pc: clutter-$(CLUTTER_API_VERSION).pc
$(QUIET_GEN)cp -f $< $(@F) $(QUIET_GEN)cp -f $< $(@F)

View File

@ -344,6 +344,9 @@ cally_text_real_initialize(AtkObject *obj,
_check_activate_action (cally_text, clutter_text); _check_activate_action (cally_text, clutter_text);
if (clutter_text_get_password_char (clutter_text) != 0)
obj->role = ATK_ROLE_PASSWORD_TEXT;
else
obj->role = ATK_ROLE_TEXT; obj->role = ATK_ROLE_TEXT;
} }
@ -1091,6 +1094,13 @@ cally_text_notify_clutter (GObject *obj,
{ {
_check_activate_action (cally_text, clutter_text); _check_activate_action (cally_text, clutter_text);
} }
else if (g_strcmp0 (pspec->name, "password-char") == 0)
{
if (clutter_text_get_password_char (clutter_text) != 0)
atk_object_set_role (atk_obj, ATK_ROLE_PASSWORD_TEXT);
else
atk_object_set_role (atk_obj, ATK_ROLE_TEXT);
}
else else
{ {
CALLY_ACTOR_CLASS (cally_text_parent_class)->notify_clutter (obj, pspec); CALLY_ACTOR_CLASS (cally_text_parent_class)->notify_clutter (obj, pspec);

View File

@ -0,0 +1,214 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Copyright (C) 2010,2011 Intel Corporation.
* 2011 Giovanni Campagna <scampa.giovanni@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
* Authors:
* Matthew Allum
* Emmanuele Bassi
* Robert Bragg
* Neil Roberts
*/
#include "config.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include "clutter-backend-eglnative.h"
/* This is a Cogl based backend */
#include "cogl/clutter-stage-cogl.h"
#ifdef HAVE_EVDEV
#include "clutter-device-manager-evdev.h"
#endif
#include "clutter-debug.h"
#include "clutter-private.h"
#include "clutter-main.h"
#include "clutter-stage-private.h"
#ifdef COGL_HAS_EGL_SUPPORT
#include "clutter-egl.h"
#endif
#include "clutter-cex100.h"
static gdl_plane_id_t gdl_plane = GDL_PLANE_ID_UPP_C;
static guint gdl_n_buffers = CLUTTER_CEX100_TRIPLE_BUFFERING;
#define clutter_backend_cex100_get_type _clutter_backend_cex100_get_type
G_DEFINE_TYPE (ClutterBackendCex100, clutter_backend_cex100, CLUTTER_TYPE_BACKEND);
static void
clutter_backend_cex100_dispose (GObject *gobject)
{
ClutterBackendCex100 *backend_cex100 = CLUTTER_BACKEND_CEX100 (gobject);
if (backend_cex100->event_timer != NULL)
{
g_timer_destroy (backend_cex100->event_timer);
backend_cex100->event_timer = NULL;
}
G_OBJECT_CLASS (clutter_backend_cex100_parent_class)->dispose (gobject);
}
static CoglDisplay *
clutter_backend_cex100_get_display (ClutterBackend *backend,
CoglRenderer *renderer,
CoglSwapChain *swap_chain,
GError **error)
{
CoglOnscreenTemplate *onscreen_template = NULL;
CoglDisplay *display;
swap_chain = cogl_swap_chain_new ();
#if defined(COGL_HAS_GDL_SUPPORT)
cogl_swap_chain_set_length (swap_chain, gdl_n_buffers);
#endif
onscreen_template = cogl_onscreen_template_new (swap_chain);
/* XXX: I have some doubts that this is a good design.
* Conceptually should we be able to check an onscreen_template
* without more details about the CoglDisplay configuration?
*/
if (!cogl_renderer_check_onscreen_template (renderer,
onscreen_template,
error))
goto error;
display = cogl_display_new (renderer, onscreen_template);
#if defined(COGL_HAS_GDL_SUPPORT)
cogl_gdl_display_set_plane (cogl_display, gdl_plane);
#endif
return display;
}
static void
clutter_backend_cex100_class_init (ClutterBackendCex100Class *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
ClutterBackendClass *backend_class = CLUTTER_BACKEND_CLASS (klass);
gobject_class->dispose = clutter_backend_cex100_dispose;
backend_class->stage_window_type = CLUTTER_TYPE_STAGE_COGL;
backend_class->get_display = clutter_backend_cex100_get_display;
}
static void
clutter_backend_cex100_init (ClutterBackendCex100 *backend_cex100)
{
backend_cex100->event_timer = g_timer_new ();
}
/**
* clutter_cex100_set_plane:
* @plane: a GDL plane
*
* Intel CE3100 and CE4100 have several planes (frame buffers) and a
* hardware blender to blend the planes togeteher and produce the final
* image.
*
* clutter_cex100_set_plane() let's you configure the GDL plane where
* the stage will be drawn. By default Clutter will pick UPP_C
* (GDL_PLANE_ID_UPP_C).
*
* <note>This function has to be called before clutter_init()</note>
*
* Since: 1.6
*/
void
clutter_cex100_set_plane (gdl_plane_id_t plane)
{
g_return_if_fail (plane >= GDL_PLANE_ID_UPP_A && plane <= GDL_PLANE_ID_UPP_E);
gdl_plane = plane;
}
/**
* clutter_cex100_set_buffering_mode:
* @mode: a #ClutterCex100BufferingMode
*
* Configure the buffering mode of the underlying GDL plane. The GDL
* surface used by Clutter to draw can be backed up by either one or two
* back buffers thus being double or triple buffered, respectively.
*
* Clutter defaults to %CLUTTER_CEX100_TRIPLE_BUFFERING.
*
* <note>This function has to be called before clutter_init()</note>
*
* Since: 1.6
*/
void
clutter_cex100_set_buffering_mode (ClutterCex100BufferingMode mode)
{
g_return_if_fail (mode == CLUTTER_CEX100_DOUBLE_BUFFERING ||
mode == CLUTTER_CEX100_TRIPLE_BUFFERING);
gdl_n_buffers = mode;
}
/**
* clutter_cex100_get_egl_display:
*
* Retrieves the EGL display used by Clutter, if it supports the
* EGL windowing system and if it is running using an EGL backend.
*
* Return value: the EGL display used by Clutter, or 0
*
* Since: 1.10
*/
EGLDisplay
clutter_cex100_get_egl_display (void)
{
ClutterBackend *backend;
if (!_clutter_context_is_initialized ())
{
g_critical ("The Clutter backend has not been initialized yet");
return 0;
}
backend = clutter_get_default_backend ();
if (!CLUTTER_IS_BACKEND_CEX100 (backend))
{
g_critical ("The Clutter backend is not a CEX100 backend");
return 0;
}
#if COGL_HAS_EGL_SUPPORT
return cogl_egl_context_get_egl_display (backend->cogl_context);
#else
return 0;
#endif
}

View File

@ -0,0 +1,71 @@
/* Clutter.
* An OpenGL based 'interactive canvas' library.
*
* Copyright (C) 2006, 2007 OpenedHand
* Copyright (C) 2010 Intel Corp
* 2011 Giovanni Campagna <scampa.giovanni@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Authors:
* Matthew Allum
* Robert Bragg
*/
#ifndef __CLUTTER_BACKEND_CEX100_H__
#define __CLUTTER_BACKEND_CEX100_H__
#include <glib-object.h>
#include <clutter/clutter-event.h>
#include <clutter/clutter-backend.h>
#include <clutter/clutter-device-manager.h>
#include "clutter-backend-private.h"
G_BEGIN_DECLS
#define CLUTTER_TYPE_BACKEND_CEX100 (_clutter_backend_cex100_get_type ())
#define CLUTTER_BACKEND_CEX100(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_BACKEND_CEX100, ClutterBackendCex100))
#define CLUTTER_IS_BACKEND_CEX100(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_BACKEND_CEX100))
#define CLUTTER_BACKEND_CEX100_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_BACKEND_CEX100, ClutterBackendCex100Class))
#define CLUTTER_IS_BACKEND_CEX100_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_BACKEND_CEX100))
#define CLUTTER_BACKEND_CEX100_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_BACKEND_CEX100, ClutterBackendCex100Class))
typedef struct _ClutterBackendCex100 ClutterBackendCex100;
typedef struct _ClutterBackendCex100Class ClutterBackendCex100Class;
struct _ClutterBackendCex100
{
ClutterBackend parent_instance;
/* device manager (ie evdev) */
ClutterDeviceManager *device_manager;
/* event source */
GSource *event_source;
/* event timer */
GTimer *event_timer;
};
struct _ClutterBackendCex100Class
{
ClutterBackendClass parent_class;
};
GType _clutter_backend_cex100_get_type (void) G_GNUC_CONST;
G_END_DECLS
#endif /* __CLUTTER_BACKEND_CEX100_H__ */

View File

@ -30,7 +30,7 @@
* specific API * specific API
* *
* You need to include * You need to include
* <filename class="headerfile">&lt;clutter/egl/clutter-cex100.h&gt;</filename> * <filename class="headerfile">&lt;clutter/cex100/clutter-cex100.h&gt;</filename>
* to have access to the functions documented here. * to have access to the functions documented here.
*/ */
@ -43,28 +43,14 @@
G_BEGIN_DECLS G_BEGIN_DECLS
/**
* clutter_cex100_set_plane:
* @plane: a GDL plane
*
* Intel CE3100 and CE4100 have several planes (frame buffers) and a
* hardware blender to blend the planes togeteher and produce the final
* image.
*
* clutter_cex100_set_plane() let's you configure the GDL plane where
* the stage will be drawn. By default Clutter will pick UPP_C
* (GDL_PLANE_ID_UPP_C).
*
* <note>This function has to be called before clutter_init()</note>
*/
void clutter_cex100_set_plane (gdl_plane_id_t plane);
/** /**
* ClutterCex100BufferingMode: * ClutterCex100BufferingMode:
* @CLUTTER_CEX100_DOUBLE_BUFFERING: The GDL plane will be double buffered * @CLUTTER_CEX100_DOUBLE_BUFFERING: The GDL plane will be double buffered
* @CLUTTER_CEX100_TRIPLE_BUFFERING: The GDL plane will be triple buffered * @CLUTTER_CEX100_TRIPLE_BUFFERING: The GDL plane will be triple buffered
* *
* Enum passed to clutter_cex100_set_buffering_mode(). * Enum passed to clutter_cex100_set_buffering_mode().
*
* Since: 1.6
*/ */
typedef enum /*< prefix=CLUTTER_CEX100 >*/ typedef enum /*< prefix=CLUTTER_CEX100 >*/
{ {
@ -72,20 +58,11 @@ typedef enum /*< prefix=CLUTTER_CEX100 >*/
CLUTTER_CEX100_TRIPLE_BUFFERING = 3 CLUTTER_CEX100_TRIPLE_BUFFERING = 3
} ClutterCex100BufferingMode; } ClutterCex100BufferingMode;
/** void clutter_cex100_set_plane (gdl_plane_id_t plane);
* clutter_cex100_set_buffering_mode:
* @mode: a #ClutterCex100BufferingMode
*
* Configure the buffering mode of the underlying GDL plane. The GDL
* surface used by Clutter to draw can be backed up by either one or two
* back buffers thus being double or triple buffered, respectively.
*
* Clutter defaults to %CLUTTER_CEX100_TRIPLE_BUFFERING.
*
* <note>This function has to be called before clutter_init()</note>
*/
void clutter_cex100_set_buffering_mode (ClutterCex100BufferingMode mode); void clutter_cex100_set_buffering_mode (ClutterCex100BufferingMode mode);
EGLDisplay clutter_cex100_get_egl_display (void);
G_END_DECLS G_END_DECLS
#endif /* __CLUTTER_CEX100_H__ */ #endif /* __CLUTTER_CEX100_H__ */

View File

@ -45,6 +45,8 @@ struct _ClutterBackend
CoglDisplay *cogl_display; CoglDisplay *cogl_display;
CoglContext *cogl_context; CoglContext *cogl_context;
ClutterDeviceManager *device_manager;
ClutterBackendPrivate *priv; ClutterBackendPrivate *priv;
}; };
@ -53,6 +55,8 @@ struct _ClutterBackendClass
/*< private >*/ /*< private >*/
GObjectClass parent_class; GObjectClass parent_class;
GType stage_window_type;
/* vfuncs */ /* vfuncs */
gboolean (* pre_parse) (ClutterBackend *backend, gboolean (* pre_parse) (ClutterBackend *backend,
GError **error); GError **error);
@ -68,6 +72,12 @@ struct _ClutterBackendClass
ClutterFeatureFlags (* get_features) (ClutterBackend *backend); ClutterFeatureFlags (* get_features) (ClutterBackend *backend);
void (* redraw) (ClutterBackend *backend, void (* redraw) (ClutterBackend *backend,
ClutterStage *stage); ClutterStage *stage);
CoglRenderer * (* get_renderer) (ClutterBackend *backend,
GError **error);
CoglDisplay * (* get_display) (ClutterBackend *backend,
CoglRenderer *renderer,
CoglSwapChain *swap_chain,
GError **error);
gboolean (* create_context) (ClutterBackend *backend, gboolean (* create_context) (ClutterBackend *backend,
GError **error); GError **error);
void (* ensure_context) (ClutterBackend *backend, void (* ensure_context) (ClutterBackend *backend,

View File

@ -50,10 +50,31 @@
#include "clutter-profile.h" #include "clutter-profile.h"
#include "clutter-stage-manager-private.h" #include "clutter-stage-manager-private.h"
#include "clutter-stage-private.h" #include "clutter-stage-private.h"
#include "clutter-stage-window.h"
#include "clutter-version.h" #include "clutter-version.h"
#include <cogl/cogl.h> #include <cogl/cogl.h>
#ifdef CLUTTER_INPUT_X11
#include "x11/clutter-backend-x11.h"
#endif
#ifdef CLUTTER_INPUT_WIN32
#include "win32/clutter-backend-win32.h"
#endif
#ifdef CLUTTER_INPUT_OSX
#include "osx/clutter-backend-osx.h"
#endif
#ifdef CLUTTER_INPUT_GDK
#include "gdk/clutter-backend-gdk.h"
#endif
#ifdef CLUTTER_INPUT_EVDEV
#include "evdev/clutter-device-manager-evdev.h"
#endif
#ifdef CLUTTER_INPUT_TSLIB
/* XXX - should probably warn, here */
#include "tslib/clutter-event-tslib.h"
#endif
G_DEFINE_ABSTRACT_TYPE (ClutterBackend, clutter_backend, G_TYPE_OBJECT); G_DEFINE_ABSTRACT_TYPE (ClutterBackend, clutter_backend, G_TYPE_OBJECT);
#define DEFAULT_FONT_NAME "Sans 10" #define DEFAULT_FONT_NAME "Sans 10"
@ -205,6 +226,200 @@ clutter_backend_real_font_changed (ClutterBackend *backend)
CLUTTER_NOTE (BACKEND, "Units per em: %.2f", priv->units_per_em); CLUTTER_NOTE (BACKEND, "Units per em: %.2f", priv->units_per_em);
} }
static gboolean
clutter_backend_real_create_context (ClutterBackend *backend,
GError **error)
{
ClutterBackendClass *klass;
CoglSwapChain *swap_chain;
GError *internal_error;
if (backend->cogl_context != NULL)
return TRUE;
klass = CLUTTER_BACKEND_GET_CLASS (backend);
swap_chain = NULL;
internal_error = NULL;
CLUTTER_NOTE (BACKEND, "Creating Cogl renderer");
if (klass->get_renderer != NULL)
backend->cogl_renderer = klass->get_renderer (backend, &internal_error);
else
backend->cogl_renderer = cogl_renderer_new ();
if (backend->cogl_renderer == NULL)
goto error;
CLUTTER_NOTE (BACKEND, "Connecting the renderer");
if (!cogl_renderer_connect (backend->cogl_renderer, &internal_error))
goto error;
CLUTTER_NOTE (BACKEND, "Creating Cogl swap chain");
swap_chain = cogl_swap_chain_new ();
CLUTTER_NOTE (BACKEND, "Creating Cogl display");
if (klass->get_display != NULL)
{
backend->cogl_display = klass->get_display (backend,
backend->cogl_renderer,
swap_chain,
&internal_error);
}
else
{
CoglOnscreenTemplate *tmpl;
gboolean res;
tmpl = cogl_onscreen_template_new (swap_chain);
/* XXX: I have some doubts that this is a good design.
*
* Conceptually should we be able to check an onscreen_template
* without more details about the CoglDisplay configuration?
*/
res = cogl_renderer_check_onscreen_template (backend->cogl_renderer,
tmpl,
&internal_error);
if (!res)
goto error;
backend->cogl_display = cogl_display_new (backend->cogl_renderer, tmpl);
/* the display owns the template */
cogl_object_unref (tmpl);
}
if (backend->cogl_display == NULL)
goto error;
CLUTTER_NOTE (BACKEND, "Setting up the display");
if (!cogl_display_setup (backend->cogl_display, &internal_error))
goto error;
CLUTTER_NOTE (BACKEND, "Creating the Cogl context");
backend->cogl_context = cogl_context_new (backend->cogl_display, &internal_error);
if (backend->cogl_context == NULL)
goto error;
/* the display owns the renderer and the swap chain */
cogl_object_unref (backend->cogl_renderer);
cogl_object_unref (swap_chain);
return TRUE;
error:
if (backend->cogl_display != NULL)
{
cogl_object_unref (backend->cogl_display);
backend->cogl_display = NULL;
}
if (backend->cogl_renderer != NULL)
{
cogl_object_unref (backend->cogl_renderer);
backend->cogl_renderer = NULL;
}
if (swap_chain != NULL)
cogl_object_unref (swap_chain);
if (internal_error != NULL)
g_propagate_error (error, internal_error);
else
g_set_error_literal (error, CLUTTER_INIT_ERROR,
CLUTTER_INIT_ERROR_BACKEND,
_("Unable to initialize the Clutter backend"));
return FALSE;
}
static void
clutter_backend_real_ensure_context (ClutterBackend *backend,
ClutterStage *stage)
{
ClutterStageWindow *stage_impl;
CoglFramebuffer *framebuffer;
if (stage == NULL)
return;
stage_impl = _clutter_stage_get_window (stage);
if (stage_impl == NULL)
return;
framebuffer = _clutter_stage_window_get_active_framebuffer (stage_impl);
if (framebuffer == NULL)
return;
cogl_set_framebuffer (framebuffer);
}
static ClutterFeatureFlags
clutter_backend_real_get_features (ClutterBackend *backend)
{
ClutterFeatureFlags flags = 0;
if (cogl_clutter_winsys_has_feature (COGL_WINSYS_FEATURE_MULTIPLE_ONSCREEN))
{
CLUTTER_NOTE (BACKEND, "Cogl supports multiple onscreen framebuffers");
flags |= CLUTTER_FEATURE_STAGE_MULTIPLE;
}
else
{
CLUTTER_NOTE (BACKEND, "Cogl only supports one onscreen framebuffer");
flags |= CLUTTER_FEATURE_STAGE_STATIC;
}
if (cogl_clutter_winsys_has_feature (COGL_WINSYS_FEATURE_SWAP_THROTTLE))
{
CLUTTER_NOTE (BACKEND, "Cogl supports swap buffers throttling");
flags |= CLUTTER_FEATURE_SYNC_TO_VBLANK;
}
else
CLUTTER_NOTE (BACKEND, "Cogl doesn't support swap buffers throttling");
if (cogl_clutter_winsys_has_feature (COGL_WINSYS_FEATURE_SWAP_BUFFERS_EVENT))
{
CLUTTER_NOTE (BACKEND, "Cogl supports swap buffers complete events");
flags |= CLUTTER_FEATURE_SWAP_EVENTS;
}
return flags;
}
static ClutterStageWindow *
clutter_backend_real_create_stage (ClutterBackend *backend,
ClutterStage *wrapper,
GError **error)
{
ClutterBackendClass *klass;
if (!clutter_feature_available (CLUTTER_FEATURE_STAGE_MULTIPLE))
{
ClutterStageManager *manager = clutter_stage_manager_get_default ();
if (clutter_stage_manager_get_default_stage (manager) != NULL)
{
g_set_error (error, CLUTTER_INIT_ERROR,
CLUTTER_INIT_ERROR_BACKEND,
_("The backend of type '%s' does not support "
"creating multiple stages"),
G_OBJECT_TYPE_NAME (backend));
return NULL;
}
}
klass = CLUTTER_BACKEND_GET_CLASS (backend);
g_assert (klass->stage_window_type != G_TYPE_INVALID);
return g_object_new (klass->stage_window_type,
"backend", backend,
"wrapper", wrapper,
NULL);
}
static void static void
clutter_backend_real_redraw (ClutterBackend *backend, clutter_backend_real_redraw (ClutterBackend *backend,
ClutterStage *stage) ClutterStage *stage)
@ -221,6 +436,86 @@ clutter_backend_real_redraw (ClutterBackend *backend,
_clutter_stage_window_redraw (impl); _clutter_stage_window_redraw (impl);
} }
static void
clutter_backend_real_init_events (ClutterBackend *backend)
{
const char *input_backend = NULL;
input_backend = g_getenv ("CLUTTER_INPUT_BACKEND");
if (input_backend != NULL)
input_backend = g_intern_string (input_backend);
#ifdef CLUTTER_INPUT_OSX
if (clutter_check_windowing_backend (CLUTTER_WINDOWING_OSX) &&
(input_backend == NULL || input_backend == I_(CLUTTER_INPUT_OSX)))
{
_clutter_backend_osx_events_init (backend);
}
else
#endif
#ifdef CLUTTER_INPUT_WIN32
if (clutter_check_windowing_backend (CLUTTER_WINDOWING_WIN32) &&
(input_backend == NULL || input_backend == I_(CLUTTER_INPUT_WIN32)))
{
_clutter_backend_win32_events_init (backend);
}
else
#endif
#ifdef CLUTTER_INPUT_X11
if (clutter_check_windowing_backend (CLUTTER_WINDOWING_X11) &&
(input_backend == NULL || input_backend == I_(CLUTTER_INPUT_X11)))
{
_clutter_backend_x11_events_init (backend);
}
else
#endif
#ifdef CLUTTER_INPUT_GDK
if (clutter_check_windowing_backend (CLUTTER_WINDOWING_GDK) &&
(input_backend == NULL || input_backend == I_(CLUTTER_INPUT_GDK)))
{
_clutter_backend_gdk_events_init (backend);
}
else
#endif
#ifdef CLUTTER_INPUT_EVDEV
/* Evdev can be used regardless of the windowing system */
if (input_backend != NULL &&
strcmp (input_backend, CLUTTER_INPUT_EVDEV) == 0)
{
_clutter_events_evdev_init (backend);
}
else
#endif
#ifdef CLUTTER_INPUT_TSLIB
/* Tslib can be used regardless of the windowing system */
if (input_backend != NULL &&
strcmp (input_backend, CLUTTER_INPUT_TSLIB) == 0)
{
_clutter_events_tslib_init (backend);
}
else
#endif
if (input_backend != NULL)
{
if (input_backend != I_(CLUTTER_INPUT_NULL))
g_error ("Unrecognized input backend '%s'", input_backend);
}
else
g_error ("Unknown input backend");
}
static ClutterDeviceManager *
clutter_backend_real_get_device_manager (ClutterBackend *backend)
{
if (G_UNLIKELY (backend->device_manager == NULL))
{
g_critical ("No device manager available, expect broken input");
return NULL;
}
return backend->device_manager;
}
static gboolean static gboolean
clutter_backend_real_translate_event (ClutterBackend *backend, clutter_backend_real_translate_event (ClutterBackend *backend,
gpointer native, gpointer native,
@ -260,6 +555,8 @@ clutter_backend_class_init (ClutterBackendClass *klass)
g_type_class_add_private (gobject_class, sizeof (ClutterBackendPrivate)); g_type_class_add_private (gobject_class, sizeof (ClutterBackendPrivate));
klass->stage_window_type = G_TYPE_INVALID;
/** /**
* ClutterBackend::resolution-changed: * ClutterBackend::resolution-changed:
* @backend: the #ClutterBackend that emitted the signal * @backend: the #ClutterBackend that emitted the signal
@ -316,7 +613,14 @@ clutter_backend_class_init (ClutterBackendClass *klass)
klass->resolution_changed = clutter_backend_real_resolution_changed; klass->resolution_changed = clutter_backend_real_resolution_changed;
klass->font_changed = clutter_backend_real_font_changed; klass->font_changed = clutter_backend_real_font_changed;
klass->init_events = clutter_backend_real_init_events;
klass->get_device_manager = clutter_backend_real_get_device_manager;
klass->translate_event = clutter_backend_real_translate_event; klass->translate_event = clutter_backend_real_translate_event;
klass->create_context = clutter_backend_real_create_context;
klass->ensure_context = clutter_backend_real_ensure_context;
klass->get_features = clutter_backend_real_get_features;
klass->create_stage = clutter_backend_real_create_stage;
klass->redraw = clutter_backend_real_redraw; klass->redraw = clutter_backend_real_redraw;
} }
@ -433,10 +737,8 @@ _clutter_backend_create_context (ClutterBackend *backend,
ClutterBackendClass *klass; ClutterBackendClass *klass;
klass = CLUTTER_BACKEND_GET_CLASS (backend); klass = CLUTTER_BACKEND_GET_CLASS (backend);
if (klass->create_context)
return klass->create_context (backend, error);
return TRUE; return klass->create_context (backend, error);
} }
void void
@ -567,7 +869,6 @@ _clutter_backend_init_events (ClutterBackend *backend)
g_assert (CLUTTER_IS_BACKEND (backend)); g_assert (CLUTTER_IS_BACKEND (backend));
klass = CLUTTER_BACKEND_GET_CLASS (backend); klass = CLUTTER_BACKEND_GET_CLASS (backend);
if (klass->init_events)
klass->init_events (backend); klass->init_events (backend);
} }

View File

@ -589,6 +589,7 @@ parse_hsla (ClutterColor *color,
str += 1; str += 1;
l = CLAMP (number / 100.0, 0.0, 1.0); l = CLAMP (number / 100.0, 0.0, 1.0);
skip_whitespace (&str);
/* alpha (optional); since the alpha channel value can only /* alpha (optional); since the alpha channel value can only
* be between 0 and 1 we don't use the parse_rgb_value() * be between 0 and 1 we don't use the parse_rgb_value()
@ -719,17 +720,16 @@ clutter_color_from_string (ClutterColor *color,
* parsing the color ourselves, as we need the alpha channel that * parsing the color ourselves, as we need the alpha channel that
* Pango can't retrieve. * Pango can't retrieve.
*/ */
if (str[0] == '#') if (str[0] == '#' && str[1] != '\0')
{ {
gsize length = strlen (str + 1);
gint32 result; gint32 result;
if (sscanf (str + 1, "%x", &result)) if (sscanf (str + 1, "%x", &result) == 1)
{ {
gsize length = strlen (str);
switch (length) switch (length)
{ {
case 9: /* rrggbbaa */ case 8: /* rrggbbaa */
color->red = (result >> 24) & 0xff; color->red = (result >> 24) & 0xff;
color->green = (result >> 16) & 0xff; color->green = (result >> 16) & 0xff;
color->blue = (result >> 8) & 0xff; color->blue = (result >> 8) & 0xff;
@ -738,7 +738,7 @@ clutter_color_from_string (ClutterColor *color,
return TRUE; return TRUE;
case 7: /* #rrggbb */ case 6: /* #rrggbb */
color->red = (result >> 16) & 0xff; color->red = (result >> 16) & 0xff;
color->green = (result >> 8) & 0xff; color->green = (result >> 8) & 0xff;
color->blue = result & 0xff; color->blue = result & 0xff;
@ -747,7 +747,7 @@ clutter_color_from_string (ClutterColor *color,
return TRUE; return TRUE;
case 5: /* #rgba */ case 4: /* #rgba */
color->red = ((result >> 12) & 0xf); color->red = ((result >> 12) & 0xf);
color->green = ((result >> 8) & 0xf); color->green = ((result >> 8) & 0xf);
color->blue = ((result >> 4) & 0xf); color->blue = ((result >> 4) & 0xf);
@ -760,7 +760,7 @@ clutter_color_from_string (ClutterColor *color,
return TRUE; return TRUE;
case 4: /* #rgb */ case 3: /* #rgb */
color->red = ((result >> 8) & 0xf); color->red = ((result >> 8) & 0xf);
color->green = ((result >> 4) & 0xf); color->green = ((result >> 4) & 0xf);
color->blue = result & 0xf; color->blue = result & 0xf;
@ -774,13 +774,18 @@ clutter_color_from_string (ClutterColor *color,
return TRUE; return TRUE;
default: default:
/* pass through to Pango */ return FALSE;
break;
} }
} }
} }
/* Fall back to pango for named colors */ /* fall back to pango for X11-style named colors; see:
*
* http://en.wikipedia.org/wiki/X11_color_names
*
* for a list. at some point we might even ship with our own list generated
* from X11/rgb.txt, like we generate the key symbols.
*/
if (pango_color_parse (&pango_color, str)) if (pango_color_parse (&pango_color, str))
{ {
color->red = pango_color.red; color->red = pango_color.red;

View File

@ -200,12 +200,9 @@ clutter_device_manager_init (ClutterDeviceManager *self)
ClutterDeviceManager * ClutterDeviceManager *
clutter_device_manager_get_default (void) clutter_device_manager_get_default (void)
{ {
ClutterBackendClass *klass; ClutterBackend *backend = clutter_get_default_backend ();
klass = CLUTTER_BACKEND_GET_CLASS (clutter_get_default_backend ()); return backend->device_manager;
g_assert (klass->get_device_manager != NULL);
return klass->get_device_manager (clutter_get_default_backend ());
} }
/** /**

View File

@ -155,6 +155,7 @@ static gboolean clutter_fatal_warnings = FALSE;
static gboolean clutter_disable_mipmap_text = FALSE; static gboolean clutter_disable_mipmap_text = FALSE;
static gboolean clutter_use_fuzzy_picking = FALSE; static gboolean clutter_use_fuzzy_picking = FALSE;
static gboolean clutter_enable_accessibility = TRUE; static gboolean clutter_enable_accessibility = TRUE;
static gboolean clutter_sync_to_vblank = TRUE;
static guint clutter_default_fps = 60; static guint clutter_default_fps = 60;
@ -302,6 +303,16 @@ clutter_config_read_from_key_file (GKeyFile *keyfile)
else else
clutter_enable_accessibility = bool_value; clutter_enable_accessibility = bool_value;
bool_value =
g_key_file_get_boolean (keyfile, ENVIRONMENT_GROUP,
"SyncToVblank",
&key_error);
if (key_error != NULL)
g_clear_error (&key_error);
else
clutter_sync_to_vblank = bool_value;
int_value = int_value =
g_key_file_get_integer (keyfile, ENVIRONMENT_GROUP, g_key_file_get_integer (keyfile, ENVIRONMENT_GROUP,
"DefaultFps", "DefaultFps",
@ -397,6 +408,8 @@ clutter_config_read_from_file (const gchar *config_path)
g_key_file_load_from_file (key_file, config_path, G_KEY_FILE_NONE, &error); g_key_file_load_from_file (key_file, config_path, G_KEY_FILE_NONE, &error);
if (error == NULL) if (error == NULL)
{ {
CLUTTER_NOTE (MISC, "Reading configuration from '%s'", config_path);
clutter_config_read_from_key_file (key_file); clutter_config_read_from_key_file (key_file);
#ifdef CLUTTER_ENABLE_DEBUG #ifdef CLUTTER_ENABLE_DEBUG
clutter_debug_read_from_key_file (key_file); clutter_debug_read_from_key_file (key_file);
@ -1723,6 +1736,10 @@ pre_parse_hook (GOptionContext *context,
if (env_string) if (env_string)
clutter_use_fuzzy_picking = TRUE; clutter_use_fuzzy_picking = TRUE;
env_string = g_getenv ("CLUTTER_VBLANK");
if (g_strcmp0 (env_string, "none") == 0)
clutter_sync_to_vblank = FALSE;
return _clutter_backend_pre_parse (backend, error); return _clutter_backend_pre_parse (backend, error);
} }
@ -3697,3 +3714,9 @@ clutter_check_windowing_backend (const char *backend_type)
#endif #endif
return FALSE; return FALSE;
} }
gboolean
_clutter_get_sync_to_vblank (void)
{
return clutter_sync_to_vblank;
}

View File

@ -211,6 +211,8 @@ void _clutter_id_to_color (guint id,
ClutterActor * _clutter_get_actor_by_id (ClutterStage *stage, ClutterActor * _clutter_get_actor_by_id (ClutterStage *stage,
guint32 actor_id); guint32 actor_id);
gboolean _clutter_get_sync_to_vblank (void);
/* use this function as the accumulator if you have a signal with /* use this function as the accumulator if you have a signal with
* a G_TYPE_BOOLEAN return value; this will stop the emission as * a G_TYPE_BOOLEAN return value; this will stop the emission as
* soon as one handler returns TRUE * soon as one handler returns TRUE

View File

@ -15,6 +15,25 @@ G_DEFINE_INTERFACE (ClutterStageWindow, clutter_stage_window, G_TYPE_OBJECT);
static void static void
clutter_stage_window_default_init (ClutterStageWindowInterface *iface) clutter_stage_window_default_init (ClutterStageWindowInterface *iface)
{ {
GParamSpec *pspec;
pspec = g_param_spec_object ("backend",
"Backend",
"Back pointer to the Backend instance",
CLUTTER_TYPE_BACKEND,
G_PARAM_WRITABLE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS);
g_object_interface_install_property (iface, pspec);
pspec = g_param_spec_object ("wrapper",
"Wrapper",
"Back pointer to the Stage actor",
CLUTTER_TYPE_STAGE,
G_PARAM_WRITABLE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS);
g_object_interface_install_property (iface, pspec);
} }
ClutterActor * ClutterActor *

View File

@ -1,207 +0,0 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Copyright (C) 2010,2011 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
* Authors:
* Matthew Allum
* Emmanuele Bassi
* Robert Bragg
* Neil Roberts
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include "clutter-backend-cogl.h"
#include "clutter-stage-cogl.h"
#include "clutter-debug.h"
#include "clutter-private.h"
#include "clutter-main.h"
#include "clutter-stage-private.h"
static ClutterBackendCogl *backend_singleton = NULL;
static gchar *clutter_vblank = NULL;
G_DEFINE_TYPE (ClutterBackendCogl, _clutter_backend_cogl, CLUTTER_TYPE_BACKEND);
const gchar*
_clutter_backend_cogl_get_vblank (void)
{
if (clutter_vblank && strcmp (clutter_vblank, "0") == 0)
return "none";
else
return clutter_vblank;
}
static gboolean
clutter_backend_cogl_pre_parse (ClutterBackend *backend,
GError **error)
{
const gchar *env_string;
env_string = g_getenv ("CLUTTER_VBLANK");
if (env_string)
{
clutter_vblank = g_strdup (env_string);
env_string = NULL;
}
return TRUE;
}
static gboolean
clutter_backend_cogl_post_parse (ClutterBackend *backend,
GError **error)
{
return TRUE;
}
static void
clutter_backend_cogl_finalize (GObject *gobject)
{
if (backend_singleton)
backend_singleton = NULL;
G_OBJECT_CLASS (_clutter_backend_cogl_parent_class)->finalize (gobject);
}
static void
clutter_backend_cogl_dispose (GObject *gobject)
{
ClutterBackend *backend = CLUTTER_BACKEND (gobject);
if (backend->cogl_context)
{
cogl_object_unref (backend->cogl_context);
backend->cogl_context = NULL;
}
G_OBJECT_CLASS (_clutter_backend_cogl_parent_class)->dispose (gobject);
}
static GObject *
clutter_backend_cogl_constructor (GType gtype,
guint n_params,
GObjectConstructParam *params)
{
GObjectClass *parent_class;
GObject *retval;
if (backend_singleton == NULL)
{
parent_class = G_OBJECT_CLASS (_clutter_backend_cogl_parent_class);
retval = parent_class->constructor (gtype, n_params, params);
backend_singleton = CLUTTER_BACKEND_COGL (retval);
return retval;
}
g_warning ("Attempting to create a new backend object. This should "
"never happen, so we return the singleton instance.");
return g_object_ref (backend_singleton);
}
static ClutterFeatureFlags
clutter_backend_cogl_get_features (ClutterBackend *backend)
{
ClutterBackendCogl *backend_cogl = CLUTTER_BACKEND_COGL (backend);
ClutterFeatureFlags flags = 0;
if (cogl_clutter_winsys_has_feature (COGL_WINSYS_FEATURE_MULTIPLE_ONSCREEN))
{
CLUTTER_NOTE (BACKEND, "Cogl supports multiple onscreen framebuffers");
flags |= CLUTTER_FEATURE_STAGE_MULTIPLE;
}
else
{
CLUTTER_NOTE (BACKEND, "Cogl only supports one onscreen framebuffer");
flags |= CLUTTER_FEATURE_STAGE_STATIC;
}
if (cogl_clutter_winsys_has_feature (COGL_WINSYS_FEATURE_SWAP_THROTTLE))
{
CLUTTER_NOTE (BACKEND, "Cogl supports swap buffers throttling");
flags |= CLUTTER_FEATURE_SYNC_TO_VBLANK;
}
else
CLUTTER_NOTE (BACKEND, "Cogl doesn't support swap buffers throttling");
if (cogl_clutter_winsys_has_feature (COGL_WINSYS_FEATURE_SWAP_BUFFERS_EVENT))
{
CLUTTER_NOTE (BACKEND, "Cogl supports swap buffers complete events");
flags |= CLUTTER_FEATURE_SWAP_EVENTS;
}
if (cogl_clutter_winsys_has_feature (COGL_WINSYS_FEATURE_SWAP_REGION))
{
CLUTTER_NOTE (BACKEND, "Cogl supports swapping buffer regions");
backend_cogl->can_blit_sub_buffer = TRUE;
}
return flags;
}
static void
clutter_backend_cogl_ensure_context (ClutterBackend *backend,
ClutterStage *stage)
{
ClutterStageCogl *stage_cogl;
/* ignore ensuring the context on an empty stage */
if (stage == NULL)
return;
stage_cogl =
CLUTTER_STAGE_COGL (_clutter_stage_get_window (stage));
cogl_set_framebuffer (COGL_FRAMEBUFFER (stage_cogl->onscreen));
}
static void
_clutter_backend_cogl_class_init (ClutterBackendCoglClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
ClutterBackendClass *backend_class = CLUTTER_BACKEND_CLASS (klass);
gobject_class->constructor = clutter_backend_cogl_constructor;
gobject_class->dispose = clutter_backend_cogl_dispose;
gobject_class->finalize = clutter_backend_cogl_finalize;
backend_class->pre_parse = clutter_backend_cogl_pre_parse;
backend_class->post_parse = clutter_backend_cogl_post_parse;
backend_class->get_features = clutter_backend_cogl_get_features;
backend_class->ensure_context = clutter_backend_cogl_ensure_context;
}
static void
_clutter_backend_cogl_init (ClutterBackendCogl *backend_cogl)
{
}

View File

@ -1,70 +0,0 @@
/* Clutter.
* An OpenGL based 'interactive canvas' library.
*
* Copyright (C) 2006, 2007 OpenedHand
* Copyright (C) 2010 Intel Corp
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Authors:
* Matthew Allum
* Robert Bragg
*/
#ifndef __CLUTTER_BACKEND_COGL_H__
#define __CLUTTER_BACKEND_COGL_H__
#include <glib-object.h>
#include <clutter/clutter-event.h>
#include <clutter/clutter-backend.h>
#include <clutter/clutter-device-manager.h>
#ifdef COGL_HAS_XLIB_SUPPORT
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#endif
#include "clutter-backend-private.h"
G_BEGIN_DECLS
#define CLUTTER_TYPE_BACKEND_COGL (_clutter_backend_cogl_get_type ())
#define CLUTTER_BACKEND_COGL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_BACKEND_COGL, ClutterBackendCogl))
#define CLUTTER_IS_BACKEND_COGL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_BACKEND_COGL))
#define CLUTTER_BACKEND_COGL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_BACKEND_COGL, ClutterBackendCoglClass))
#define CLUTTER_IS_BACKEND_COGL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_BACKEND_COGL))
#define CLUTTER_BACKEND_COGL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_BACKEND_COGL, ClutterBackendCoglClass))
typedef struct _ClutterBackendCogl ClutterBackendCogl;
typedef struct _ClutterBackendCoglClass ClutterBackendCoglClass;
struct _ClutterBackendCogl
{
ClutterBackend parent_instance;
gboolean can_blit_sub_buffer;
};
struct _ClutterBackendCoglClass
{
ClutterBackendClass parent_class;
};
GType _clutter_backend_cogl_get_type (void) G_GNUC_CONST;
const gchar *_clutter_backend_cogl_get_vblank (void);
G_END_DECLS
#endif /* __CLUTTER_BACKEND_COGL_H__ */

View File

@ -33,15 +33,15 @@
#include "clutter-config.h" #include "clutter-config.h"
#include "clutter-stage-cogl.h" #include "clutter-stage-cogl.h"
#include "clutter-backend-cogl.h"
#include "clutter-actor-private.h"
#include "clutter-backend-private.h"
#include "clutter-debug.h" #include "clutter-debug.h"
#include "clutter-event.h" #include "clutter-event.h"
#include "clutter-enum-types.h" #include "clutter-enum-types.h"
#include "clutter-feature.h" #include "clutter-feature.h"
#include "clutter-main.h" #include "clutter-main.h"
#include "clutter-private.h" #include "clutter-private.h"
#include "clutter-actor-private.h"
#include "clutter-stage-private.h" #include "clutter-stage-private.h"
#include "clutter-util.h" #include "clutter-util.h"
@ -102,7 +102,6 @@ clutter_stage_cogl_realize (ClutterStageWindow *stage_window)
GError *error = NULL; GError *error = NULL;
gfloat width = 800; gfloat width = 800;
gfloat height = 600; gfloat height = 600;
const char *clutter_vblank;
CLUTTER_NOTE (BACKEND, "Realizing stage '%s' [%p]", CLUTTER_NOTE (BACKEND, "Realizing stage '%s' [%p]",
G_OBJECT_TYPE_NAME (stage_cogl), G_OBJECT_TYPE_NAME (stage_cogl),
@ -116,9 +115,8 @@ clutter_stage_cogl_realize (ClutterStageWindow *stage_window)
width, height); width, height);
} }
clutter_vblank = _clutter_backend_cogl_get_vblank (); cogl_onscreen_set_swap_throttled (stage_cogl->onscreen,
if (clutter_vblank && strcmp (clutter_vblank, "none") == 0) _clutter_get_sync_to_vblank ());
cogl_onscreen_set_swap_throttled (stage_cogl->onscreen, FALSE);
framebuffer = COGL_FRAMEBUFFER (stage_cogl->onscreen); framebuffer = COGL_FRAMEBUFFER (stage_cogl->onscreen);
if (!cogl_framebuffer_allocate (framebuffer, &error)) if (!cogl_framebuffer_allocate (framebuffer, &error))
@ -316,11 +314,10 @@ static void
clutter_stage_cogl_redraw (ClutterStageWindow *stage_window) clutter_stage_cogl_redraw (ClutterStageWindow *stage_window)
{ {
ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window); ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window);
ClutterActor *wrapper;
ClutterBackend *backend;
ClutterBackendCogl *backend_cogl;
gboolean may_use_clipped_redraw; gboolean may_use_clipped_redraw;
gboolean use_clipped_redraw; gboolean use_clipped_redraw;
gboolean can_blit_sub_buffer;
ClutterActor *wrapper;
CLUTTER_STATIC_TIMER (painting_timer, CLUTTER_STATIC_TIMER (painting_timer,
"Redrawing", /* parent */ "Redrawing", /* parent */
@ -343,19 +340,19 @@ clutter_stage_cogl_redraw (ClutterStageWindow *stage_window)
if (!stage_cogl->onscreen) if (!stage_cogl->onscreen)
return; return;
backend = clutter_get_default_backend ();
backend_cogl = CLUTTER_BACKEND_COGL (backend);
CLUTTER_TIMER_START (_clutter_uprof_context, painting_timer); CLUTTER_TIMER_START (_clutter_uprof_context, painting_timer);
can_blit_sub_buffer =
cogl_clutter_winsys_has_feature (COGL_WINSYS_FEATURE_SWAP_REGION);
may_use_clipped_redraw = FALSE; may_use_clipped_redraw = FALSE;
if (_clutter_stage_window_can_clip_redraws (stage_window) && if (_clutter_stage_window_can_clip_redraws (stage_window) &&
G_LIKELY (backend_cogl->can_blit_sub_buffer) && can_blit_sub_buffer &&
/* NB: a zero width redraw clip == full stage redraw */ /* NB: a zero width redraw clip == full stage redraw */
stage_cogl->bounding_redraw_clip.width != 0 && stage_cogl->bounding_redraw_clip.width != 0 &&
/* some drivers struggle to get going and produce some junk /* some drivers struggle to get going and produce some junk
* frames when starting up... */ * frames when starting up... */
G_LIKELY (stage_cogl->frame_count > 3)) stage_cogl->frame_count > 3)
{ {
may_use_clipped_redraw = TRUE; may_use_clipped_redraw = TRUE;
} }
@ -548,11 +545,11 @@ clutter_stage_cogl_set_property (GObject *gobject,
switch (prop_id) switch (prop_id)
{ {
case PROP_WRAPPER: case PROP_WRAPPER:
self->wrapper = CLUTTER_STAGE (g_value_get_object (value)); self->wrapper = g_value_get_object (value);
break; break;
case PROP_BACKEND: case PROP_BACKEND:
self->backend = CLUTTER_BACKEND_COGL (g_value_get_object (value)); self->backend = g_value_get_object (value);
break; break;
default: default:
@ -568,19 +565,8 @@ _clutter_stage_cogl_class_init (ClutterStageCoglClass *klass)
gobject_class->set_property = clutter_stage_cogl_set_property; gobject_class->set_property = clutter_stage_cogl_set_property;
g_object_class_install_property (gobject_class, PROP_WRAPPER, g_object_class_override_property (gobject_class, PROP_WRAPPER, "wrapper");
g_param_spec_object ("wrapper", g_object_class_override_property (gobject_class, PROP_BACKEND, "backend");
"Wrapper",
"ClutterStage wrapping this native stage",
CLUTTER_TYPE_STAGE,
CLUTTER_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property (gobject_class, PROP_BACKEND,
g_param_spec_object ("backend",
"ClutterBackend",
"The Clutter backend singleton",
CLUTTER_TYPE_BACKEND_COGL,
CLUTTER_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
} }
static void static void

View File

@ -1,8 +1,8 @@
#ifndef __CLUTTER_STAGE_COGL_H__ #ifndef __CLUTTER_STAGE_COGL_H__
#define __CLUTTER_STAGE_COGL_H__ #define __CLUTTER_STAGE_COGL_H__
#include <glib-object.h>
#include <cairo.h> #include <cairo.h>
#include <clutter/clutter-backend.h>
#include <clutter/clutter-stage.h> #include <clutter/clutter-stage.h>
#ifdef COGL_HAS_X11_SUPPORT #ifdef COGL_HAS_X11_SUPPORT
@ -11,8 +11,6 @@
#include <X11/Xutil.h> #include <X11/Xutil.h>
#endif #endif
#include "clutter-backend-cogl.h"
G_BEGIN_DECLS G_BEGIN_DECLS
#define CLUTTER_TYPE_STAGE_COGL (_clutter_stage_cogl_get_type ()) #define CLUTTER_TYPE_STAGE_COGL (_clutter_stage_cogl_get_type ())
@ -33,7 +31,7 @@ struct _ClutterStageCogl
ClutterStage *wrapper; ClutterStage *wrapper;
/* back pointer to the backend */ /* back pointer to the backend */
ClutterBackendCogl *backend; ClutterBackend *backend;
CoglOnscreen *onscreen; CoglOnscreen *onscreen;

View File

@ -44,10 +44,6 @@
#include "clutter-device-manager-evdev.h" #include "clutter-device-manager-evdev.h"
#endif #endif
#ifdef HAVE_TSLIB
#include "clutter-event-tslib.h"
#endif
#include "clutter-debug.h" #include "clutter-debug.h"
#include "clutter-private.h" #include "clutter-private.h"
#include "clutter-main.h" #include "clutter-main.h"
@ -57,61 +53,9 @@
#include "clutter-egl.h" #include "clutter-egl.h"
#endif #endif
#ifdef CLUTTER_EGL_BACKEND_CEX100
#include "clutter-cex100.h"
#endif
#ifdef CLUTTER_EGL_BACKEND_CEX100
static gdl_plane_id_t gdl_plane = GDL_PLANE_ID_UPP_C;
static guint gdl_n_buffers = CLUTTER_CEX100_TRIPLE_BUFFERING;
#endif
#define clutter_backend_egl_native_get_type _clutter_backend_egl_native_get_type #define clutter_backend_egl_native_get_type _clutter_backend_egl_native_get_type
G_DEFINE_TYPE (ClutterBackendEglNative, clutter_backend_egl_native, CLUTTER_TYPE_BACKEND_COGL); G_DEFINE_TYPE (ClutterBackendEglNative, clutter_backend_egl_native, CLUTTER_TYPE_BACKEND);
static ClutterDeviceManager *
clutter_backend_egl_native_get_device_manager (ClutterBackend *backend)
{
ClutterBackendEglNative *backend_egl_native = CLUTTER_BACKEND_EGL_NATIVE (backend);
if (G_UNLIKELY (backend_egl_native->device_manager == NULL))
{
#ifdef HAVE_EVDEV
backend_egl_native->device_manager =
g_object_new (CLUTTER_TYPE_DEVICE_MANAGER_EVDEV,
"backend", backend_egl_native,
NULL);
#endif
}
return backend_egl_native->device_manager;
}
static void
clutter_backend_egl_native_init_events (ClutterBackend *backend)
{
const char *input_backend = NULL;
input_backend = g_getenv ("CLUTTER_INPUT_BACKEND");
#ifdef HAVE_EVDEV
if (input_backend != NULL &&
strcmp (input_backend, CLUTTER_EVDEV_INPUT_BACKEND) == 0)
_clutter_events_evdev_init (CLUTTER_BACKEND (backend));
else
#endif
#ifdef HAVE_TSLIB
if (input_backend != NULL &&
strcmp (input_backend, CLUTTER_TSLIB_INPUT_BACKEND) == 0)
_clutter_events_tslib_init (CLUTTER_BACKEND (backend));
else
#endif
if (input_backend != NULL)
g_error ("Unrecognized input backend '%s'", input_backend);
else
g_error ("Unknown input backend");
}
static void static void
clutter_backend_egl_native_dispose (GObject *gobject) clutter_backend_egl_native_dispose (GObject *gobject)
@ -124,122 +68,9 @@ clutter_backend_egl_native_dispose (GObject *gobject)
backend_egl_native->event_timer = NULL; backend_egl_native->event_timer = NULL;
} }
#ifdef HAVE_TSLIB
_clutter_events_tslib_uninit (CLUTTER_BACKEND (gobject));
#endif
#ifdef HAVE_EVDEV
_clutter_events_evdev_uninit (CLUTTER_BACKEND (gobject));
if (backend_egl_native->device_manager != NULL)
{
g_object_unref (backend_egl_native->device_manager);
backend_egl_native->device_manager = NULL;
}
#endif
G_OBJECT_CLASS (clutter_backend_egl_native_parent_class)->dispose (gobject); G_OBJECT_CLASS (clutter_backend_egl_native_parent_class)->dispose (gobject);
} }
static ClutterStageWindow *
clutter_backend_egl_native_create_stage (ClutterBackend *backend,
ClutterStage *wrapper,
GError **error)
{
ClutterBackendEglNative *backend_egl_native = CLUTTER_BACKEND_EGL_NATIVE (backend);
ClutterStageWindow *stage;
if (G_UNLIKELY (backend_egl_native->stage != NULL))
{
g_set_error (error, CLUTTER_INIT_ERROR,
CLUTTER_INIT_ERROR_BACKEND,
"The EglNative backend does not support multiple "
"onscreen windows");
return backend_egl_native->stage;
}
stage = g_object_new (CLUTTER_TYPE_STAGE_COGL,
"backend", backend,
"wrapper", wrapper,
NULL);
backend_egl_native->stage = stage;
return stage;
}
static gboolean
clutter_backend_egl_native_create_context (ClutterBackend *backend,
GError **error)
{
CoglSwapChain *swap_chain = NULL;
CoglOnscreenTemplate *onscreen_template = NULL;
if (backend->cogl_context != NULL)
return TRUE;
backend->cogl_renderer = cogl_renderer_new ();
if (!cogl_renderer_connect (backend->cogl_renderer, error))
goto error;
swap_chain = cogl_swap_chain_new ();
#if defined(CLUTTER_EGL_BACKEND_CEX100) && defined(COGL_HAS_GDL_SUPPORT)
cogl_swap_chain_set_length (swap_chain, gdl_n_buffers);
#endif
onscreen_template = cogl_onscreen_template_new (swap_chain);
cogl_object_unref (swap_chain);
/* XXX: I have some doubts that this is a good design.
* Conceptually should we be able to check an onscreen_template
* without more details about the CoglDisplay configuration?
*/
if (!cogl_renderer_check_onscreen_template (backend->cogl_renderer,
onscreen_template,
error))
goto error;
backend->cogl_display = cogl_display_new (backend->cogl_renderer,
onscreen_template);
#if defined(CLUTTER_EGL_BACKEND_CEX100) && defined(COGL_HAS_GDL_SUPPORT)
cogl_gdl_display_set_plane (backend->cogl_display, gdl_plane);
#endif /* CLUTTER_EGL_BACKEND_CEX100 */
cogl_object_unref (backend->cogl_renderer);
cogl_object_unref (onscreen_template);
if (!cogl_display_setup (backend->cogl_display, error))
goto error;
backend->cogl_context = cogl_context_new (backend->cogl_display, error);
if (backend->cogl_context == NULL)
goto error;
return TRUE;
error:
if (backend->cogl_display != NULL)
{
cogl_object_unref (backend->cogl_display);
backend->cogl_display = NULL;
}
if (onscreen_template != NULL)
cogl_object_unref (onscreen_template);
if (swap_chain != NULL)
cogl_object_unref (swap_chain);
if (backend->cogl_renderer != NULL)
{
cogl_object_unref (backend->cogl_renderer);
backend->cogl_renderer = NULL;
}
return FALSE;
}
static void static void
clutter_backend_egl_native_class_init (ClutterBackendEglNativeClass *klass) clutter_backend_egl_native_class_init (ClutterBackendEglNativeClass *klass)
{ {
@ -248,10 +79,7 @@ clutter_backend_egl_native_class_init (ClutterBackendEglNativeClass *klass)
gobject_class->dispose = clutter_backend_egl_native_dispose; gobject_class->dispose = clutter_backend_egl_native_dispose;
backend_class->get_device_manager = clutter_backend_egl_native_get_device_manager; backend_class->stage_window_type = CLUTTER_TYPE_STAGE_COGL;
backend_class->init_events = clutter_backend_egl_native_init_events;
backend_class->create_stage = clutter_backend_egl_native_create_stage;
backend_class->create_context = clutter_backend_egl_native_create_context;
} }
static void static void
@ -260,43 +88,6 @@ clutter_backend_egl_native_init (ClutterBackendEglNative *backend_egl_native)
backend_egl_native->event_timer = g_timer_new (); backend_egl_native->event_timer = g_timer_new ();
} }
#ifdef CLUTTER_EGL_BACKEND_CEX100
/**
* clutter_cex100_set_plane:
* @plane: FIXME
*
* FIXME
*
* Since:
*/
void
clutter_cex100_set_plane (gdl_plane_id_t plane)
{
g_return_if_fail (plane >= GDL_PLANE_ID_UPP_A && plane <= GDL_PLANE_ID_UPP_E);
gdl_plane = plane;
}
#endif
#ifdef CLUTTER_EGL_BACKEND_CEX100
/**
* clutter_cex100_set_plane:
* @mode: FIXME
*
* FIXME
*
* Since:
*/
void
clutter_cex100_set_buffering_mode (ClutterCex100BufferingMode mode)
{
g_return_if_fail (mode == CLUTTER_CEX100_DOUBLE_BUFFERING ||
mode == CLUTTER_CEX100_TRIPLE_BUFFERING);
gdl_n_buffers = mode;
}
#endif
/** /**
* clutter_eglx_display: * clutter_eglx_display:
* *

View File

@ -32,7 +32,6 @@
#include <clutter/clutter-device-manager.h> #include <clutter/clutter-device-manager.h>
#include "clutter-backend-private.h" #include "clutter-backend-private.h"
#include "cogl/clutter-backend-cogl.h"
G_BEGIN_DECLS G_BEGIN_DECLS
@ -48,10 +47,7 @@ typedef struct _ClutterBackendEglNativeClass ClutterBackendEglNativeClass;
struct _ClutterBackendEglNative struct _ClutterBackendEglNative
{ {
ClutterBackendCogl parent_instance; ClutterBackend parent_instance;
/* main stage singleton */
ClutterStageWindow *stage;
/* device manager (ie evdev) */ /* device manager (ie evdev) */
ClutterDeviceManager *device_manager; ClutterDeviceManager *device_manager;
@ -65,7 +61,7 @@ struct _ClutterBackendEglNative
struct _ClutterBackendEglNativeClass struct _ClutterBackendEglNativeClass
{ {
ClutterBackendCoglClass parent_class; ClutterBackendClass parent_class;
}; };
GType _clutter_backend_egl_native_get_type (void) G_GNUC_CONST; GType _clutter_backend_egl_native_get_type (void) G_GNUC_CONST;

View File

@ -49,10 +49,6 @@
G_BEGIN_DECLS G_BEGIN_DECLS
#define CLUTTER_TSLIB_INPUT_BACKEND "tslib"
#define CLUTTER_EVDEV_INPUT_BACKEND "evdev"
#ifndef CLUTTER_DISABLE_DEPRECATED
/** /**
* clutter_eglx_display: * clutter_eglx_display:
* *
@ -79,7 +75,6 @@ EGLDisplay clutter_eglx_display (void);
*/ */
CLUTTER_DEPRECATED_FOR(clutter_egl_get_egl_display) CLUTTER_DEPRECATED_FOR(clutter_egl_get_egl_display)
EGLDisplay clutter_egl_display (void); EGLDisplay clutter_egl_display (void);
#endif /* CLUTTER_DISABLE_DEPRECATED */
/** /**
* clutter_egl_get_egl_display: * clutter_egl_get_egl_display:

View File

@ -847,20 +847,14 @@ clutter_device_manager_evdev_init (ClutterDeviceManagerEvdev *self)
self->priv = CLUTTER_DEVICE_MANAGER_EVDEV_GET_PRIVATE (self); self->priv = CLUTTER_DEVICE_MANAGER_EVDEV_GET_PRIVATE (self);
} }
/*
* _clutter_events_evdev_init() and _clutter_events_evdev_uninit() are the two
* symbol to use the evdev event backend from the EGL backend
*/
void void
_clutter_events_evdev_init (ClutterBackend *backend) _clutter_events_evdev_init (ClutterBackend *backend)
{ {
ClutterDeviceManager *dummy G_GNUC_UNUSED;
CLUTTER_NOTE (EVENT, "Initializing evdev backend"); CLUTTER_NOTE (EVENT, "Initializing evdev backend");
/* we need to create the device manager here */ backend->device_manager = g_object_new (CLUTTER_TYPE_DEVICE_MANAGER_EVDEV,
dummy = clutter_device_manager_get_default (); "backend", backend,
NULL);
} }
void void

View File

@ -60,7 +60,7 @@
#include "clutter-private.h" #include "clutter-private.h"
#define clutter_backend_gdk_get_type _clutter_backend_gdk_get_type #define clutter_backend_gdk_get_type _clutter_backend_gdk_get_type
G_DEFINE_TYPE (ClutterBackendGdk, clutter_backend_gdk, CLUTTER_TYPE_BACKEND_COGL); G_DEFINE_TYPE (ClutterBackendGdk, clutter_backend_gdk, CLUTTER_TYPE_BACKEND);
/* global for pre init setup calls */ /* global for pre init setup calls */
static GdkDisplay *_foreign_dpy = NULL; static GdkDisplay *_foreign_dpy = NULL;
@ -178,18 +178,31 @@ _clutter_backend_gdk_post_parse (ClutterBackend *backend,
"Gdk Display '%s' opened", "Gdk Display '%s' opened",
gdk_display_get_name (backend_gdk->display)); gdk_display_get_name (backend_gdk->display));
return CLUTTER_BACKEND_CLASS (clutter_backend_gdk_parent_class)->post_parse (backend, return TRUE;
error);
} }
static void static void
clutter_backend_gdk_init_events (ClutterBackend *backend) gdk_event_handler (GdkEvent *event,
gpointer user_data)
{ {
clutter_gdk_handle_event (event);
}
void
_clutter_backend_gdk_events_init (ClutterBackend *backend)
{
ClutterBackendGdk *backend_gdk = CLUTTER_BACKEND_GDK (backend);
CLUTTER_NOTE (EVENT, "initialising the event loop"); CLUTTER_NOTE (EVENT, "initialising the event loop");
backend->device_manager =
g_object_new (CLUTTER_TYPE_DEVICE_MANAGER_GDK,
"backend", backend,
"gdk-display", backend_gdk->display,
NULL);
if (!disable_event_retrieval) if (!disable_event_retrieval)
_clutter_backend_gdk_events_init (backend); gdk_event_handler_set (gdk_event_handler, NULL, NULL);
} }
static void static void
@ -206,28 +219,19 @@ clutter_backend_gdk_finalize (GObject *gobject)
static void static void
clutter_backend_gdk_dispose (GObject *gobject) clutter_backend_gdk_dispose (GObject *gobject)
{ {
ClutterBackendGdk *backend_gdk = CLUTTER_BACKEND_GDK (gobject);
ClutterStageManager *stage_manager;
CLUTTER_NOTE (BACKEND, "Disposing the of stages");
stage_manager = clutter_stage_manager_get_default ();
g_object_unref (stage_manager);
CLUTTER_NOTE (BACKEND, "Removing the event source");
_clutter_backend_gdk_events_uninit (CLUTTER_BACKEND (backend_gdk));
G_OBJECT_CLASS (clutter_backend_gdk_parent_class)->dispose (gobject); G_OBJECT_CLASS (clutter_backend_gdk_parent_class)->dispose (gobject);
} }
static ClutterFeatureFlags static ClutterFeatureFlags
clutter_backend_gdk_get_features (ClutterBackend *backend) clutter_backend_gdk_get_features (ClutterBackend *backend)
{ {
ClutterFeatureFlags flags = CLUTTER_FEATURE_STAGE_USER_RESIZE | CLUTTER_FEATURE_STAGE_CURSOR; ClutterBackendClass *parent_class;
flags |= CLUTTER_BACKEND_CLASS (clutter_backend_gdk_parent_class)->get_features (backend); parent_class = CLUTTER_BACKEND_CLASS (clutter_backend_gdk_parent_class);
return flags; return parent_class->get_features (backend)
| CLUTTER_FEATURE_STAGE_USER_RESIZE
| CLUTTER_FEATURE_STAGE_CURSOR;
} }
static void static void
@ -253,41 +257,19 @@ clutter_backend_gdk_free_event_data (ClutterBackend *backend,
gdk_event_free (gdk_event); gdk_event_free (gdk_event);
} }
static ClutterDeviceManager * static CoglRenderer *
clutter_backend_gdk_get_device_manager (ClutterBackend *backend) clutter_backend_gdk_get_renderer (ClutterBackend *backend,
{
ClutterBackendGdk *backend_gdk = CLUTTER_BACKEND_GDK (backend);
if (G_UNLIKELY (backend_gdk->device_manager == NULL))
{
backend_gdk->device_manager = g_object_new (CLUTTER_TYPE_DEVICE_MANAGER_GDK,
"backend", backend_gdk,
"gdk-display", backend_gdk->display,
NULL);
}
return backend_gdk->device_manager;
}
static gboolean
clutter_backend_gdk_create_context (ClutterBackend *backend,
GError **error) GError **error)
{ {
ClutterBackendGdk *backend_gdk = CLUTTER_BACKEND_GDK (backend); ClutterBackendGdk *backend_gdk = CLUTTER_BACKEND_GDK (backend);
CoglSwapChain *swap_chain = NULL; CoglRenderer *renderer = cogl_renderer_new ();
CoglOnscreenTemplate *onscreen_template = NULL;
GdkVisual *rgba_visual = NULL;
if (backend->cogl_context != NULL)
return TRUE;
backend->cogl_renderer = cogl_renderer_new ();
#if defined(GDK_WINDOWING_X11) && defined(COGL_HAS_XLIB_SUPPORT) #if defined(GDK_WINDOWING_X11) && defined(COGL_HAS_XLIB_SUPPORT)
if (GDK_IS_X11_DISPLAY (backend_gdk->display)) if (GDK_IS_X11_DISPLAY (backend_gdk->display))
{ {
cogl_xlib_renderer_set_foreign_display (backend->cogl_renderer, Display *xdisplay = gdk_x11_display_get_xdisplay (backend_gdk->display);
gdk_x11_display_get_xdisplay (backend_gdk->display));
cogl_xlib_renderer_set_foreign_display (renderer, xdisplay);
} }
else else
#endif #endif
@ -302,76 +284,79 @@ clutter_backend_gdk_create_context (ClutterBackend *backend,
{ {
g_set_error (error, CLUTTER_INIT_ERROR, g_set_error (error, CLUTTER_INIT_ERROR,
CLUTTER_INIT_ERROR_BACKEND, CLUTTER_INIT_ERROR_BACKEND,
"Could not find a suitable CoglWinsys for" _("Could not find a suitable CoglWinsys for a GdkDisplay of type %s"),
"a GdkDisplay of type %s", G_OBJECT_TYPE_NAME (backend_gdk->display)); G_OBJECT_TYPE_NAME (backend_gdk->display));
goto error; cogl_object_unref (renderer);
return NULL;
} }
return renderer;
if (!cogl_renderer_connect (backend->cogl_renderer, error))
goto error;
swap_chain = cogl_swap_chain_new ();
rgba_visual = gdk_screen_get_rgba_visual (backend_gdk->screen);
cogl_swap_chain_set_has_alpha (swap_chain, rgba_visual != NULL);
onscreen_template = cogl_onscreen_template_new (swap_chain);
cogl_object_unref (swap_chain);
/* XXX: I have some doubts that this is a good design.
* Conceptually should we be able to check an onscreen_template
* without more details about the CoglDisplay configuration?
*/
if (!cogl_renderer_check_onscreen_template (backend->cogl_renderer,
onscreen_template,
error))
goto error;
backend->cogl_display = cogl_display_new (backend->cogl_renderer,
onscreen_template);
cogl_object_unref (backend->cogl_renderer);
cogl_object_unref (onscreen_template);
if (!cogl_display_setup (backend->cogl_display, error))
goto error;
backend->cogl_context = cogl_context_new (backend->cogl_display, error);
if (backend->cogl_context == NULL)
goto error;
return TRUE;
error:
if (backend->cogl_display != NULL)
{
cogl_object_unref (backend->cogl_display);
backend->cogl_display = NULL;
}
if (onscreen_template != NULL)
cogl_object_unref (onscreen_template);
if (swap_chain != NULL)
cogl_object_unref (swap_chain);
if (backend->cogl_renderer != NULL)
{
cogl_object_unref (backend->cogl_renderer);
backend->cogl_renderer = NULL;
}
return FALSE;
} }
static ClutterStageWindow * static CoglDisplay *
clutter_backend_gdk_create_stage (ClutterBackend *backend, clutter_backend_gdk_get_display (ClutterBackend *backend,
ClutterStage *wrapper, CoglRenderer *renderer,
CoglSwapChain *swap_chain,
GError **error) GError **error)
{ {
return g_object_new (CLUTTER_TYPE_STAGE_GDK, ClutterBackendGdk *backend_gdk = CLUTTER_BACKEND_GDK (backend);
"backend", backend, CoglOnscreenTemplate *onscreen_template;
"wrapper", wrapper, GError *internal_error = NULL;
NULL); CoglDisplay *display;
gboolean has_rgba_visual;
gboolean res;
has_rgba_visual = gdk_screen_get_rgba_visual (backend_gdk->screen) == NULL;
CLUTTER_NOTE (BACKEND, "Alpha on Cogl swap chain: %s",
has_rgba_visual ? "enabled" : "disabled");
cogl_swap_chain_set_has_alpha (swap_chain, has_rgba_visual);
onscreen_template = cogl_onscreen_template_new (swap_chain);
res = cogl_renderer_check_onscreen_template (renderer,
onscreen_template,
&internal_error);
if (!res && has_rgba_visual)
{
CLUTTER_NOTE (BACKEND,
"Creation of a context with a ARGB visual failed: %s",
internal_error != NULL ? internal_error->message
: "Unknown reason");
g_clear_error (&internal_error);
/* It's possible that the current renderer doesn't support transparency
* in a swap_chain so lets see if we can fallback to not having any
* transparency...
*
* XXX: It might be nice to have a CoglRenderer feature we could
* explicitly check for ahead of time.
*/
cogl_swap_chain_set_has_alpha (swap_chain, FALSE);
res = cogl_renderer_check_onscreen_template (renderer,
onscreen_template,
&internal_error);
}
if (!res)
{
g_set_error_literal (error, CLUTTER_INIT_ERROR,
CLUTTER_INIT_ERROR_BACKEND,
internal_error->message);
g_error_free (internal_error);
cogl_object_unref (onscreen_template);
return NULL;
}
display = cogl_display_new (renderer, onscreen_template);
cogl_object_unref (onscreen_template);
return display;
} }
static void static void
@ -383,14 +368,16 @@ clutter_backend_gdk_class_init (ClutterBackendGdkClass *klass)
gobject_class->dispose = clutter_backend_gdk_dispose; gobject_class->dispose = clutter_backend_gdk_dispose;
gobject_class->finalize = clutter_backend_gdk_finalize; gobject_class->finalize = clutter_backend_gdk_finalize;
backend_class->stage_window_type = CLUTTER_TYPE_STAGE_GDK;
backend_class->post_parse = _clutter_backend_gdk_post_parse; backend_class->post_parse = _clutter_backend_gdk_post_parse;
backend_class->init_events = clutter_backend_gdk_init_events;
backend_class->get_features = clutter_backend_gdk_get_features; backend_class->get_features = clutter_backend_gdk_get_features;
backend_class->get_device_manager = clutter_backend_gdk_get_device_manager;
backend_class->copy_event_data = clutter_backend_gdk_copy_event_data; backend_class->copy_event_data = clutter_backend_gdk_copy_event_data;
backend_class->free_event_data = clutter_backend_gdk_free_event_data; backend_class->free_event_data = clutter_backend_gdk_free_event_data;
backend_class->create_context = clutter_backend_gdk_create_context;
backend_class->create_stage = clutter_backend_gdk_create_stage; backend_class->get_renderer = clutter_backend_gdk_get_renderer;
backend_class->get_display = clutter_backend_gdk_get_display;
} }
static void static void

View File

@ -30,7 +30,6 @@
#include "clutter-gdk.h" #include "clutter-gdk.h"
#include "clutter-backend-private.h" #include "clutter-backend-private.h"
#include "cogl/clutter-backend-cogl.h"
G_BEGIN_DECLS G_BEGIN_DECLS
@ -46,7 +45,7 @@ typedef struct _ClutterBackendGdkClass ClutterBackendGdkClass;
struct _ClutterBackendGdk struct _ClutterBackendGdk
{ {
ClutterBackendCogl parent_instance; ClutterBackend parent_instance;
GdkDisplay *display; GdkDisplay *display;
GdkScreen *screen; GdkScreen *screen;
@ -56,7 +55,7 @@ struct _ClutterBackendGdk
struct _ClutterBackendGdkClass struct _ClutterBackendGdkClass
{ {
ClutterBackendCoglClass parent_class; ClutterBackendClass parent_class;
/* nothing here, for now */ /* nothing here, for now */
}; };
@ -64,9 +63,9 @@ struct _ClutterBackendGdkClass
GType _clutter_backend_gdk_get_type (void) G_GNUC_CONST; GType _clutter_backend_gdk_get_type (void) G_GNUC_CONST;
void _clutter_backend_gdk_events_init (ClutterBackend *backend); void _clutter_backend_gdk_events_init (ClutterBackend *backend);
void _clutter_backend_gdk_events_uninit (ClutterBackend *backend);
void _clutter_backend_gdk_update_setting (ClutterBackendGdk *backend, const gchar *name); void _clutter_backend_gdk_update_setting (ClutterBackendGdk *backend,
const gchar *name);
G_END_DECLS G_END_DECLS

View File

@ -43,27 +43,6 @@
#include <glib.h> #include <glib.h>
static void
gdk_event_handler (GdkEvent *event,
gpointer user_data)
{
clutter_gdk_handle_event (event);
}
void
_clutter_backend_gdk_events_init (ClutterBackend *backend)
{
gdk_event_handler_set (gdk_event_handler, NULL, NULL);
CLUTTER_NOTE (EVENT, "GDK event handler set");
}
void
_clutter_backend_gdk_events_uninit (ClutterBackend *backend)
{
gdk_event_handler_set (NULL, NULL, NULL);
}
/** /**
* clutter_gdk_handle_event: * clutter_gdk_handle_event:
* @event: a #GdkEvent * @event: a #GdkEvent

View File

@ -28,6 +28,7 @@
#include "clutter-device-manager-osx.h" #include "clutter-device-manager-osx.h"
#include "clutter-shader.h" #include "clutter-shader.h"
#include "clutter-stage-osx.h" #include "clutter-stage-osx.h"
#include "clutter-event-loop-osx.h"
#include "clutter-debug.h" #include "clutter-debug.h"
#include "clutter-private.h" #include "clutter-private.h"
@ -37,6 +38,8 @@
#import <AppKit/AppKit.h> #import <AppKit/AppKit.h>
#define clutter_backend_osx_get_type _clutter_backend_osx_get_type
G_DEFINE_TYPE (ClutterBackendOSX, clutter_backend_osx, CLUTTER_TYPE_BACKEND) G_DEFINE_TYPE (ClutterBackendOSX, clutter_backend_osx, CLUTTER_TYPE_BACKEND)
/*************************************************************************/ /*************************************************************************/
@ -68,52 +71,12 @@ clutter_backend_osx_post_parse (ClutterBackend *backend,
static ClutterFeatureFlags static ClutterFeatureFlags
clutter_backend_osx_get_features (ClutterBackend *backend) clutter_backend_osx_get_features (ClutterBackend *backend)
{ {
return CLUTTER_FEATURE_STAGE_MULTIPLE|CLUTTER_FEATURE_STAGE_USER_RESIZE; return CLUTTER_FEATURE_STAGE_MULTIPLE
| CLUTTER_FEATURE_STAGE_USER_RESIZE;
} }
static ClutterStageWindow* void
clutter_backend_osx_create_stage (ClutterBackend *backend, _clutter_backend_osx_events_init (ClutterBackend *backend)
ClutterStage *wrapper,
GError **error)
{
ClutterStageWindow *impl;
CLUTTER_OSX_POOL_ALLOC();
impl = _clutter_stage_osx_new (backend, wrapper);
CLUTTER_NOTE (BACKEND, "create_stage: wrapper=%p - impl=%p",
wrapper,
impl);
CLUTTER_OSX_POOL_RELEASE();
return impl;
}
static inline void
clutter_backend_osx_create_device_manager (ClutterBackendOSX *backend_osx)
{
if (backend_osx->device_manager != NULL)
return;
backend_osx->device_manager = g_object_new (CLUTTER_TYPE_DEVICE_MANAGER_OSX,
"backend", CLUTTER_BACKEND(backend_osx),
NULL);
}
static ClutterDeviceManager *
clutter_backend_osx_get_device_manager (ClutterBackend *backend)
{
ClutterBackendOSX *backend_osx = CLUTTER_BACKEND_OSX (backend);
clutter_backend_osx_create_device_manager (backend_osx);
return backend_osx->device_manager;
}
static void
clutter_backend_osx_init_events (ClutterBackend *backend)
{ {
ClutterBackendOSX *backend_osx = CLUTTER_BACKEND_OSX (backend); ClutterBackendOSX *backend_osx = CLUTTER_BACKEND_OSX (backend);
@ -122,8 +85,12 @@ clutter_backend_osx_init_events (ClutterBackend *backend)
CLUTTER_NOTE (BACKEND, "init_events"); CLUTTER_NOTE (BACKEND, "init_events");
clutter_backend_osx_create_device_manager (backend_osx); backend->device_manager = backend_osx->device_manager =
_clutter_events_osx_init (); g_object_new (CLUTTER_TYPE_DEVICE_MANAGER_OSX,
"backend", CLUTTER_BACKEND(backend_osx),
NULL);
_clutter_osx_event_loop_init ();
} }
static gboolean static gboolean
@ -141,7 +108,7 @@ clutter_backend_osx_create_context (ClutterBackend *backend,
*/ */
NSOpenGLPixelFormatAttribute attrs[] = { NSOpenGLPixelFormatAttribute attrs[] = {
NSOpenGLPFADoubleBuffer, NSOpenGLPFADoubleBuffer,
NSOpenGLPFADepthSize, 24, NSOpenGLPFADepthSize, 32,
NSOpenGLPFAStencilSize, 8, NSOpenGLPFAStencilSize, 8,
0 0
}; };
@ -188,6 +155,7 @@ clutter_backend_osx_ensure_context (ClutterBackend *backend,
g_assert (CLUTTER_IS_STAGE_OSX (impl)); g_assert (CLUTTER_IS_STAGE_OSX (impl));
stage_osx = CLUTTER_STAGE_OSX (impl); stage_osx = CLUTTER_STAGE_OSX (impl);
[backend_osx->context clearDrawable];
[backend_osx->context setView:stage_osx->view]; [backend_osx->context setView:stage_osx->view];
[backend_osx->context makeCurrentContext]; [backend_osx->context makeCurrentContext];
} }
@ -245,11 +213,10 @@ clutter_backend_osx_class_init (ClutterBackendOSXClass *klass)
object_class->dispose = clutter_backend_osx_dispose; object_class->dispose = clutter_backend_osx_dispose;
backend_class->stage_window_type = CLUTTER_TYPE_STAGE_OSX;
backend_class->post_parse = clutter_backend_osx_post_parse; backend_class->post_parse = clutter_backend_osx_post_parse;
backend_class->get_features = clutter_backend_osx_get_features; backend_class->get_features = clutter_backend_osx_get_features;
backend_class->create_stage = clutter_backend_osx_create_stage;
backend_class->create_context = clutter_backend_osx_create_context; backend_class->create_context = clutter_backend_osx_create_context;
backend_class->ensure_context = clutter_backend_osx_ensure_context; backend_class->ensure_context = clutter_backend_osx_ensure_context;
backend_class->init_events = clutter_backend_osx_init_events;
backend_class->get_device_manager = clutter_backend_osx_get_device_manager;
} }

View File

@ -30,7 +30,7 @@
G_BEGIN_DECLS G_BEGIN_DECLS
#define CLUTTER_TYPE_BACKEND_OSX (clutter_backend_osx_get_type()) #define CLUTTER_TYPE_BACKEND_OSX (_clutter_backend_osx_get_type())
#define CLUTTER_BACKEND_OSX(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),CLUTTER_TYPE_BACKEND_OSX,ClutterBackendOSX)) #define CLUTTER_BACKEND_OSX(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),CLUTTER_TYPE_BACKEND_OSX,ClutterBackendOSX))
#define CLUTTER_BACKEND_OSX_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),CLUTTER_TYPE_BACKEND_OSX,ClutterBackend)) #define CLUTTER_BACKEND_OSX_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),CLUTTER_TYPE_BACKEND_OSX,ClutterBackend))
#define CLUTTER_IS_BACKEND_OSX(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),CLUTTER_TYPE_BACKEND_OSX)) #define CLUTTER_IS_BACKEND_OSX(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),CLUTTER_TYPE_BACKEND_OSX))
@ -54,7 +54,9 @@ struct _ClutterBackendOSXClass
ClutterBackendClass parent_class; ClutterBackendClass parent_class;
}; };
GType clutter_backend_osx_get_type (void) G_GNUC_CONST; GType _clutter_backend_osx_get_type (void) G_GNUC_CONST;
void _clutter_backend_osx_events_init (ClutterBackend *backend);
G_END_DECLS G_END_DECLS

View File

@ -38,8 +38,6 @@
#include "clutter-private.h" #include "clutter-private.h"
#include "clutter-stage-private.h" #include "clutter-stage-private.h"
#include "clutter-event-loop-osx.h"
#define WHEEL_DELTA 1 #define WHEEL_DELTA 1
/*************************************************************************/ /*************************************************************************/
@ -491,15 +489,3 @@ _clutter_event_osx_put (NSEvent *nsevent,
else else
clutter_event_free (event); clutter_event_free (event);
} }
void
_clutter_events_osx_init (void)
{
_clutter_osx_event_loop_init ();
}
void
_clutter_events_osx_uninit (void)
{
g_assert_not_reached ();
}

View File

@ -32,6 +32,14 @@
#import <AppKit/AppKit.h> #import <AppKit/AppKit.h>
enum
{
PROP_0,
PROP_BACKEND,
PROP_WRAPPER
};
static void clutter_stage_window_iface_init (ClutterStageWindowIface *iface); static void clutter_stage_window_iface_init (ClutterStageWindowIface *iface);
#define clutter_stage_osx_get_type _clutter_stage_osx_get_type #define clutter_stage_osx_get_type _clutter_stage_osx_get_type
@ -120,7 +128,7 @@ clutter_stage_osx_get_wrapper (ClutterStageWindow *stage_window);
- (NSSize) windowWillResize:(NSWindow *) sender toSize:(NSSize) frameSize - (NSSize) windowWillResize:(NSWindow *) sender toSize:(NSSize) frameSize
{ {
if ( clutter_stage_get_user_resizable (self->stage_osx->wrapper) ) if (clutter_stage_get_user_resizable (self->stage_osx->wrapper))
{ {
guint min_width, min_height; guint min_width, min_height;
clutter_stage_get_minimum_size (self->stage_osx->wrapper, clutter_stage_get_minimum_size (self->stage_osx->wrapper,
@ -135,7 +143,7 @@ clutter_stage_osx_get_wrapper (ClutterStageWindow *stage_window);
- (void)windowDidChangeScreen:(NSNotification *)notification - (void)windowDidChangeScreen:(NSNotification *)notification
{ {
clutter_stage_ensure_redraw (CLUTTER_STAGE(self->stage_osx->wrapper)); clutter_stage_ensure_redraw (CLUTTER_STAGE (self->stage_osx->wrapper));
} }
@end @end
@ -195,8 +203,8 @@ clutter_stage_osx_get_wrapper (ClutterStageWindow *stage_window);
stage_osx->requisition_width = [self bounds].size.width; stage_osx->requisition_width = [self bounds].size.width;
stage_osx->requisition_height = [self bounds].size.height; stage_osx->requisition_height = [self bounds].size.height;
clutter_actor_set_size (CLUTTER_ACTOR (self->stage_osx->wrapper), clutter_actor_set_size (CLUTTER_ACTOR (self->stage_osx->wrapper),
(int)[self bounds].size.width, stage_osx->requisition_width,
(int)[self bounds].size.height); stage_osx->requisition_height);
[self removeTrackingRect:tracking_rect]; [self removeTrackingRect:tracking_rect];
tracking_rect = [self addTrackingRect:[self bounds] tracking_rect = [self addTrackingRect:[self bounds]
@ -601,24 +609,6 @@ clutter_stage_window_iface_init (ClutterStageWindowIface *iface)
iface->redraw = clutter_stage_osx_redraw; iface->redraw = clutter_stage_osx_redraw;
} }
/*************************************************************************/
ClutterStageWindow *
_clutter_stage_osx_new (ClutterBackend *backend,
ClutterStage *wrapper)
{
ClutterStageOSX *self;
self = g_object_new (CLUTTER_TYPE_STAGE_OSX, NULL);
self->backend = backend;
self->wrapper = wrapper;
self->isHiding = false;
self->haveRealized = false;
self->view = NULL;
self->window = NULL;
return CLUTTER_STAGE_WINDOW(self);
}
/*************************************************************************/ /*************************************************************************/
static void static void
clutter_stage_osx_init (ClutterStageOSX *self) clutter_stage_osx_init (ClutterStageOSX *self)
@ -626,6 +616,35 @@ clutter_stage_osx_init (ClutterStageOSX *self)
self->requisition_width = 640; self->requisition_width = 640;
self->requisition_height = 480; self->requisition_height = 480;
self->acceptFocus = TRUE; self->acceptFocus = TRUE;
self->isHiding = false;
self->haveRealized = false;
self->view = NULL;
self->window = NULL;
}
static void
clutter_stage_osx_set_property (GObject *gobject,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
ClutterStageOSX *self = CLUTTER_STAGE_OSX (gobject);
switch (prop_id)
{
case PROP_BACKEND:
self->backend = g_value_get_object (value);
break;
case PROP_WRAPPER:
self->wrapper = g_value_get_object (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
break;
}
} }
static void static void
@ -645,6 +664,10 @@ clutter_stage_osx_class_init (ClutterStageOSXClass *klass)
{ {
GObjectClass *gobject_class = G_OBJECT_CLASS (klass); GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
gobject_class->set_property = clutter_stage_osx_set_property;
gobject_class->finalize = clutter_stage_osx_finalize; gobject_class->finalize = clutter_stage_osx_finalize;
gobject_class->dispose = clutter_stage_osx_dispose; gobject_class->dispose = clutter_stage_osx_dispose;
g_object_class_override_property (gobject_class, PROP_BACKEND, "backend");
g_object_class_override_property (gobject_class, PROP_WRAPPER, "wrapper");
} }

View File

@ -82,9 +82,6 @@ struct _ClutterStageOSXClass
GType _clutter_stage_osx_get_type (void) G_GNUC_CONST; GType _clutter_stage_osx_get_type (void) G_GNUC_CONST;
ClutterStageWindow * _clutter_stage_osx_new (ClutterBackend *backend,
ClutterStage *wrapper);
G_END_DECLS G_END_DECLS
#endif /* __CLUTTER_STAGE_OSX_H__ */ #endif /* __CLUTTER_STAGE_OSX_H__ */

View File

@ -484,12 +484,6 @@ clutter_backend_wayland_create_context (ClutterBackend *backend,
return status; return status;
} }
static void
clutter_backend_wayland_ensure_context (ClutterBackend *backend,
ClutterStage *stage)
{
}
static void static void
clutter_backend_wayland_redraw (ClutterBackend *backend, clutter_backend_wayland_redraw (ClutterBackend *backend,
ClutterStage *stage) ClutterStage *stage)
@ -505,11 +499,6 @@ clutter_backend_wayland_redraw (ClutterBackend *backend,
_clutter_stage_wayland_redraw (CLUTTER_STAGE_WAYLAND (impl), stage); _clutter_stage_wayland_redraw (CLUTTER_STAGE_WAYLAND (impl), stage);
} }
static void
clutter_backend_wayland_init_events (ClutterBackend *backend)
{
}
static void static void
clutter_backend_wayland_finalize (GObject *gobject) clutter_backend_wayland_finalize (GObject *gobject)
{ {
@ -603,24 +592,6 @@ clutter_backend_wayland_get_features (ClutterBackend *backend)
return flags; return flags;
} }
static ClutterStageWindow *
clutter_backend_wayland_create_stage (ClutterBackend *backend,
ClutterStage *wrapper,
GError **error)
{
ClutterBackendWayland *backend_wayland = CLUTTER_BACKEND_WAYLAND (backend);
ClutterStageWindow *stage;
ClutterStageWayland *stage_wayland;
stage = g_object_new (CLUTTER_TYPE_STAGE_WAYLAND, NULL);
stage_wayland = CLUTTER_STAGE_WAYLAND (stage);
stage_wayland->backend = backend_wayland;
stage_wayland->wrapper = wrapper;
return stage;
}
static void static void
_clutter_backend_wayland_class_init (ClutterBackendWaylandClass *klass) _clutter_backend_wayland_class_init (ClutterBackendWaylandClass *klass)
{ {
@ -631,13 +602,12 @@ _clutter_backend_wayland_class_init (ClutterBackendWaylandClass *klass)
gobject_class->dispose = clutter_backend_wayland_dispose; gobject_class->dispose = clutter_backend_wayland_dispose;
gobject_class->finalize = clutter_backend_wayland_finalize; gobject_class->finalize = clutter_backend_wayland_finalize;
backend_class->stage_window_type = CLUTTER_TYPE_STAGE_WAYLAND;
backend_class->pre_parse = clutter_backend_wayland_pre_parse; backend_class->pre_parse = clutter_backend_wayland_pre_parse;
backend_class->post_parse = clutter_backend_wayland_post_parse; backend_class->post_parse = clutter_backend_wayland_post_parse;
backend_class->get_features = clutter_backend_wayland_get_features; backend_class->get_features = clutter_backend_wayland_get_features;
backend_class->init_events = clutter_backend_wayland_init_events;
backend_class->create_stage = clutter_backend_wayland_create_stage;
backend_class->create_context = clutter_backend_wayland_create_context; backend_class->create_context = clutter_backend_wayland_create_context;
backend_class->ensure_context = clutter_backend_wayland_ensure_context;
backend_class->redraw = clutter_backend_wayland_redraw; backend_class->redraw = clutter_backend_wayland_redraw;
} }

View File

@ -58,6 +58,14 @@ wayland_swap_buffers (ClutterStageWayland *stage_wayland);
static void clutter_stage_window_iface_init (ClutterStageWindowIface *iface); static void clutter_stage_window_iface_init (ClutterStageWindowIface *iface);
enum
{
PROP_0,
PROP_BACKEND,
PROP_WRAPPER
};
G_DEFINE_TYPE_WITH_CODE (ClutterStageWayland, G_DEFINE_TYPE_WITH_CODE (ClutterStageWayland,
_clutter_stage_wayland, _clutter_stage_wayland,
G_TYPE_OBJECT, G_TYPE_OBJECT,
@ -427,9 +435,38 @@ clutter_stage_window_iface_init (ClutterStageWindowIface *iface)
iface->ignoring_redraw_clips = clutter_stage_wayland_ignoring_redraw_clips; iface->ignoring_redraw_clips = clutter_stage_wayland_ignoring_redraw_clips;
} }
static void
clutter_stage_wayland_set_property (GObject *gobject,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
ClutterStageWayland *self = CLUTTER_STAGE_WAYLAND (gobject);
switch (prop_id)
{
case PROP_BACKEND:
self->backend = g_value_get_object (value);
break;
case PROP_WRAPPER:
self->wrapper = g_value_get_object (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
}
}
static void static void
_clutter_stage_wayland_class_init (ClutterStageWaylandClass *klass) _clutter_stage_wayland_class_init (ClutterStageWaylandClass *klass)
{ {
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
gobject_class->set_property = clutter_stage_wayland_set_property;
g_object_class_override_property (gobject_class, PROP_BACKEND, "backend");
g_object_class_override_property (gobject_class, PROP_WRAPPER, "wrapper");
} }
static void static void

View File

@ -49,34 +49,11 @@ typedef int (WINAPI * SwapIntervalProc) (int interval);
/* singleton object */ /* singleton object */
static ClutterBackendWin32 *backend_singleton = NULL; static ClutterBackendWin32 *backend_singleton = NULL;
static gchar *clutter_vblank_name = NULL;
static HINSTANCE clutter_hinst = NULL; static HINSTANCE clutter_hinst = NULL;
/* various flags corresponding to pre init setup calls */ /* various flags corresponding to pre init setup calls */
static gboolean _no_event_retrieval = FALSE; static gboolean _no_event_retrieval = FALSE;
const gchar *
_clutter_backend_win32_get_vblank (void)
{
if (clutter_vblank_name && strcmp (clutter_vblank_name, "0") == 0)
return "none";
else
return clutter_vblank_name;
}
gboolean
clutter_backend_win32_pre_parse (ClutterBackend *backend,
GError **error)
{
const gchar *env_string;
if ((env_string = g_getenv ("CLUTTER_VBLANK")))
clutter_vblank_name = g_strdup (env_string);
return TRUE;
}
static void static void
clutter_backend_win32_init_events (ClutterBackend *backend) clutter_backend_win32_init_events (ClutterBackend *backend)
{ {
@ -84,7 +61,7 @@ clutter_backend_win32_init_events (ClutterBackend *backend)
CLUTTER_NOTE (EVENT, "initialising the event loop"); CLUTTER_NOTE (EVENT, "initialising the event loop");
backend_win32->device_manager = backend->device_manager =
g_object_new (CLUTTER_TYPE_DEVICE_MANAGER_WIN32, g_object_new (CLUTTER_TYPE_DEVICE_MANAGER_WIN32,
"backend", backend_win32, "backend", backend_win32,
NULL); NULL);
@ -185,137 +162,12 @@ ClutterFeatureFlags
clutter_backend_win32_get_features (ClutterBackend *backend) clutter_backend_win32_get_features (ClutterBackend *backend)
{ {
ClutterBackendClass *parent_class; ClutterBackendClass *parent_class;
ClutterFeatureFlags flags;
parent_class = CLUTTER_BACKEND_CLASS (clutter_backend_win32_parent_class); parent_class = CLUTTER_BACKEND_CLASS (clutter_backend_win32_parent_class);
flags = CLUTTER_FEATURE_STAGE_USER_RESIZE | CLUTTER_FEATURE_STAGE_CURSOR; return parent_class->get_features (backend)
| CLUTTER_FEATURE_STAGE_USER_RESIZE
if (cogl_clutter_winsys_has_feature (COGL_WINSYS_FEATURE_MULTIPLE_ONSCREEN)) | CLUTTER_FEATURE_STAGE_CURSOR;
{
CLUTTER_NOTE (BACKEND, "Cogl supports multiple onscreen framebuffers");
flags |= CLUTTER_FEATURE_STAGE_MULTIPLE;
}
else
{
CLUTTER_NOTE (BACKEND, "Cogl only supports one onscreen framebuffer");
flags |= CLUTTER_FEATURE_STAGE_STATIC;
}
if (cogl_clutter_winsys_has_feature (COGL_WINSYS_FEATURE_SWAP_THROTTLE))
{
CLUTTER_NOTE (BACKEND, "Cogl supports swap buffers throttling");
flags |= CLUTTER_FEATURE_SYNC_TO_VBLANK;
}
else
CLUTTER_NOTE (BACKEND, "Cogl doesn't support swap buffers throttling");
CLUTTER_NOTE (BACKEND, "backend features checked");
return flags;
}
static gboolean
clutter_backend_win32_create_context (ClutterBackend *backend,
GError **error)
{
CoglSwapChain *swap_chain;
CoglOnscreenTemplate *onscreen_template;
if (backend->cogl_context)
return TRUE;
backend->cogl_renderer = cogl_renderer_new ();
if (!cogl_renderer_connect (backend->cogl_renderer, error))
goto error;
swap_chain = cogl_swap_chain_new ();
onscreen_template = cogl_onscreen_template_new (swap_chain);
cogl_object_unref (swap_chain);
if (!cogl_renderer_check_onscreen_template (backend->cogl_renderer,
onscreen_template,
error))
goto error;
backend->cogl_display = cogl_display_new (backend->cogl_renderer,
onscreen_template);
cogl_object_unref (backend->cogl_renderer);
cogl_object_unref (onscreen_template);
if (!cogl_display_setup (backend->cogl_display, error))
goto error;
backend->cogl_context = cogl_context_new (backend->cogl_display, error);
if (!backend->cogl_context)
goto error;
return TRUE;
error:
if (backend->cogl_display)
{
cogl_object_unref (backend->cogl_display);
backend->cogl_display = NULL;
}
if (onscreen_template)
cogl_object_unref (onscreen_template);
if (swap_chain)
cogl_object_unref (swap_chain);
if (backend->cogl_renderer)
{
cogl_object_unref (backend->cogl_renderer);
backend->cogl_renderer = NULL;
}
return FALSE;
}
static void
clutter_backend_win32_ensure_context (ClutterBackend *backend,
ClutterStage *stage)
{
ClutterStageWin32 *stage_win32 =
CLUTTER_STAGE_WIN32 (_clutter_stage_get_window (stage));
cogl_set_framebuffer (COGL_FRAMEBUFFER (stage_win32->onscreen));
}
static ClutterStageWindow *
clutter_backend_win32_create_stage (ClutterBackend *backend,
ClutterStage *wrapper,
GError **error)
{
ClutterBackendWin32 *backend_win32 = CLUTTER_BACKEND_WIN32 (backend);
ClutterStageWin32 *stage_win32;
ClutterStageWindow *stage;
stage = g_object_new (CLUTTER_TYPE_STAGE_WIN32, NULL);
/* copy backend data into the stage */
stage_win32 = CLUTTER_STAGE_WIN32 (stage);
stage_win32->backend = backend_win32;
stage_win32->wrapper = wrapper;
return stage;
}
static ClutterDeviceManager *
clutter_backend_win32_get_device_manager (ClutterBackend *backend)
{
ClutterBackendWin32 *backend_win32 = CLUTTER_BACKEND_WIN32 (backend);
if (G_UNLIKELY (backend_win32->device_manager == NULL))
{
backend_win32->device_manager =
g_object_new (CLUTTER_TYPE_DEVICE_MANAGER_WIN32,
"backend", backend_win32,
NULL);
}
return backend_win32->device_manager;
} }
/** /**
@ -351,14 +203,11 @@ clutter_backend_win32_class_init (ClutterBackendWin32Class *klass)
gobject_class->dispose = clutter_backend_win32_dispose; gobject_class->dispose = clutter_backend_win32_dispose;
gobject_class->finalize = clutter_backend_win32_finalize; gobject_class->finalize = clutter_backend_win32_finalize;
backend_class->pre_parse = clutter_backend_win32_pre_parse; backend_class->stage_window_type = CLUTTER_TYPE_STAGE_WIN32;
backend_class->init_events = clutter_backend_win32_init_events; backend_class->init_events = clutter_backend_win32_init_events;
backend_class->create_stage = clutter_backend_win32_create_stage;
backend_class->add_options = clutter_backend_win32_add_options; backend_class->add_options = clutter_backend_win32_add_options;
backend_class->get_features = clutter_backend_win32_get_features; backend_class->get_features = clutter_backend_win32_get_features;
backend_class->create_context = clutter_backend_win32_create_context;
backend_class->ensure_context = clutter_backend_win32_ensure_context;
backend_class->get_device_manager = clutter_backend_win32_get_device_manager;
} }
static void static void

View File

@ -72,8 +72,6 @@ clutter_backend_win32_get_features (ClutterBackend *backend);
HCURSOR _clutter_backend_win32_get_invisible_cursor (ClutterBackend *backend); HCURSOR _clutter_backend_win32_get_invisible_cursor (ClutterBackend *backend);
const gchar *_clutter_backend_win32_get_vblank (void);
G_END_DECLS G_END_DECLS
#endif /* __CLUTTER_BACKEND_WIN32_H__ */ #endif /* __CLUTTER_BACKEND_WIN32_H__ */

View File

@ -42,6 +42,14 @@
static void clutter_stage_window_iface_init (ClutterStageWindowIface *iface); static void clutter_stage_window_iface_init (ClutterStageWindowIface *iface);
enum
{
PROP_0,
PROP_BACKEND,
PROP_WRAPPER
};
G_DEFINE_TYPE_WITH_CODE (ClutterStageWin32, G_DEFINE_TYPE_WITH_CODE (ClutterStageWin32,
clutter_stage_win32, clutter_stage_win32,
G_TYPE_OBJECT, G_TYPE_OBJECT,
@ -398,7 +406,6 @@ clutter_stage_win32_realize (ClutterStageWindow *stage_window)
gfloat width; gfloat width;
gfloat height; gfloat height;
GError *error = NULL; GError *error = NULL;
const char *clutter_vblank;
CLUTTER_NOTE (MISC, "Realizing main stage"); CLUTTER_NOTE (MISC, "Realizing main stage");
@ -470,9 +477,8 @@ clutter_stage_win32_realize (ClutterStageWindow *stage_window)
cogl_win32_onscreen_set_foreign_window (stage_win32->onscreen, cogl_win32_onscreen_set_foreign_window (stage_win32->onscreen,
stage_win32->hwnd); stage_win32->hwnd);
clutter_vblank = _clutter_backend_win32_get_vblank (); cogl_onscreen_set_swap_throttled (stage_win32->onscreen,
if (clutter_vblank && strcmp (clutter_vblank, "none") == 0) _clutter_get_sync_to_vblank ());
cogl_onscreen_set_swap_throttled (stage_win32->onscreen, FALSE);
framebuffer = COGL_FRAMEBUFFER (stage_win32->onscreen); framebuffer = COGL_FRAMEBUFFER (stage_win32->onscreen);
if (!cogl_framebuffer_allocate (framebuffer, &error)) if (!cogl_framebuffer_allocate (framebuffer, &error))
@ -538,6 +544,37 @@ clutter_stage_win32_redraw (ClutterStageWindow *stage_window)
cogl_framebuffer_swap_buffers (COGL_FRAMEBUFFER (stage_win32->onscreen)); cogl_framebuffer_swap_buffers (COGL_FRAMEBUFFER (stage_win32->onscreen));
} }
static CoglFramebuffer *
clutter_stage_win32_get_active_framebuffer (ClutterStageWindow *stage_window)
{
ClutterStageWin32 *stage_win32 = CLUTTER_STAGE_WIN32 (stage_window);
return COGL_FRAMEBUFFER (stage_win32->onscreen);
}
static void
clutter_stage_win32_set_property (GObject *gobject,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
ClutterStageWin32 *self = CLUTTER_STAGE_WIN32 (gobject);
switch (prop_id)
{
case PROP_BACKEND:
self->backend = g_value_get_object (value);
break;
case PROP_WRAPPER:
self->wrapper = g_value_get_object (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
}
}
static void static void
clutter_stage_win32_dispose (GObject *gobject) clutter_stage_win32_dispose (GObject *gobject)
{ {
@ -563,7 +600,11 @@ clutter_stage_win32_class_init (ClutterStageWin32Class *klass)
{ {
GObjectClass *gobject_class = G_OBJECT_CLASS (klass); GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
gobject_class->set_property = clutter_stage_win32_set_property;
gobject_class->dispose = clutter_stage_win32_dispose; gobject_class->dispose = clutter_stage_win32_dispose;
g_object_class_override_property (gobject_class, PROP_BACKEND, "backend");
g_object_class_override_property (gobject_class, PROP_WRAPPER, "wrapper");
} }
static void static void
@ -598,6 +639,7 @@ clutter_stage_window_iface_init (ClutterStageWindowIface *iface)
iface->realize = clutter_stage_win32_realize; iface->realize = clutter_stage_win32_realize;
iface->unrealize = clutter_stage_win32_unrealize; iface->unrealize = clutter_stage_win32_unrealize;
iface->redraw = clutter_stage_win32_redraw; iface->redraw = clutter_stage_win32_redraw;
iface->get_active_framebuffer = clutter_stage_win32_get_active_framebuffer;
} }
/** /**

View File

@ -1,32 +0,0 @@
/* An OpenGL based 'interactive canvas' library.
* Authored By Matthew Allum <mallum@openedhand.com>
* Copyright (C) 2006-2007 OpenedHand
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
#ifndef __CLUTTER_BACKEND_PRIVATE_X11_H__
#define __CLUTTER_BACKEND_PRIVATE_X11_H__
G_BEGIN_DECLS
void _clutter_backend_x11_events_init (ClutterBackend *backend);
void _clutter_backend_x11_events_uninit (ClutterBackend *backend);
G_END_DECLS
#endif

View File

@ -70,7 +70,7 @@
#define clutter_backend_x11_get_type _clutter_backend_x11_get_type #define clutter_backend_x11_get_type _clutter_backend_x11_get_type
G_DEFINE_TYPE (ClutterBackendX11, clutter_backend_x11, CLUTTER_TYPE_BACKEND_COGL); G_DEFINE_TYPE (ClutterBackendX11, clutter_backend_x11, CLUTTER_TYPE_BACKEND);
/* atoms; remember to add the code that assigns the atom value to /* atoms; remember to add the code that assigns the atom value to
* the member of the ClutterBackendX11 structure if you add an * the member of the ClutterBackendX11 structure if you add an
@ -277,6 +277,8 @@ clutter_backend_x11_create_device_manager (ClutterBackendX11 *backend_x11)
} }
backend = CLUTTER_BACKEND (backend_x11); backend = CLUTTER_BACKEND (backend_x11);
backend->device_manager = backend_x11->device_manager;
translator = CLUTTER_EVENT_TRANSLATOR (backend_x11->device_manager); translator = CLUTTER_EVENT_TRANSLATOR (backend_x11->device_manager);
_clutter_backend_add_event_translator (backend, translator); _clutter_backend_add_event_translator (backend, translator);
} }
@ -331,8 +333,7 @@ _clutter_backend_x11_pre_parse (ClutterBackend *backend,
env_string = NULL; env_string = NULL;
} }
return CLUTTER_BACKEND_CLASS (clutter_backend_x11_parent_class)->pre_parse (backend, return TRUE;
error);
} }
gboolean gboolean
@ -411,12 +412,6 @@ _clutter_backend_x11_post_parse (ClutterBackend *backend,
g_object_set (settings, "font-dpi", (int) dpi * 1024, NULL); g_object_set (settings, "font-dpi", (int) dpi * 1024, NULL);
/* create the device manager */
clutter_backend_x11_create_device_manager (backend_x11);
/* register keymap */
clutter_backend_x11_create_keymap (backend_x11);
/* create XSETTINGS client */ /* create XSETTINGS client */
backend_x11->xsettings = backend_x11->xsettings =
_clutter_xsettings_client_new (backend_x11->xdpy, _clutter_xsettings_client_new (backend_x11->xdpy,
@ -457,18 +452,49 @@ _clutter_backend_x11_post_parse (ClutterBackend *backend,
(unsigned int) backend_x11->xwin_root, (unsigned int) backend_x11->xwin_root,
clutter_backend_get_resolution (backend)); clutter_backend_get_resolution (backend));
return CLUTTER_BACKEND_CLASS (clutter_backend_x11_parent_class)->post_parse (backend, return TRUE;
error);
} }
void
static void _clutter_backend_x11_events_init (ClutterBackend *backend)
clutter_backend_x11_init_events (ClutterBackend *backend)
{ {
ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (backend);
CLUTTER_NOTE (EVENT, "initialising the event loop"); CLUTTER_NOTE (EVENT, "initialising the event loop");
/* the event source is optional */
if (!_no_xevent_retrieval) if (!_no_xevent_retrieval)
_clutter_backend_x11_events_init (backend); {
GSource *source;
source = _clutter_x11_event_source_new (backend_x11);
/* default priority for events
*
* XXX - at some point we'll have a common EventSource API that
* is created by the backend, and this code will most likely go
* into the default implementation of ClutterBackend
*/
g_source_set_priority (source, CLUTTER_PRIORITY_EVENTS);
/* attach the source to the default context, and transfer the
* ownership to the GMainContext itself
*/
g_source_attach (source, NULL);
g_source_unref (source);
backend_x11->event_source = source;
}
/* create the device manager; we need this because we can effectively
* choose between core+XI1 and XI2 input events
*/
clutter_backend_x11_create_device_manager (backend_x11);
/* register keymap; unless we create a generic Keymap object, I'm
* afraid this will have to stay
*/
clutter_backend_x11_create_keymap (backend_x11);
} }
static const GOptionEntry entries[] = static const GOptionEntry entries[] =
@ -528,17 +554,6 @@ clutter_backend_x11_finalize (GObject *gobject)
static void static void
clutter_backend_x11_dispose (GObject *gobject) clutter_backend_x11_dispose (GObject *gobject)
{ {
ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (gobject);
ClutterStageManager *stage_manager;
CLUTTER_NOTE (BACKEND, "Disposing the of stages");
stage_manager = clutter_stage_manager_get_default ();
g_object_unref (stage_manager);
CLUTTER_NOTE (BACKEND, "Removing the event source");
_clutter_backend_x11_events_uninit (CLUTTER_BACKEND (backend_x11));
G_OBJECT_CLASS (clutter_backend_x11_parent_class)->dispose (gobject); G_OBJECT_CLASS (clutter_backend_x11_parent_class)->dispose (gobject);
} }
@ -576,16 +591,6 @@ clutter_backend_x11_free_event_data (ClutterBackend *backend,
_clutter_event_x11_free (event_x11); _clutter_event_x11_free (event_x11);
} }
static ClutterDeviceManager *
clutter_backend_x11_get_device_manager (ClutterBackend *backend)
{
ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (backend);
clutter_backend_x11_create_device_manager (backend_x11);
return backend_x11->device_manager;
}
static void static void
update_last_event_time (ClutterBackendX11 *backend_x11, update_last_event_time (ClutterBackendX11 *backend_x11,
XEvent *xevent) XEvent *xevent)
@ -680,40 +685,46 @@ clutter_backend_x11_translate_event (ClutterBackend *backend,
return parent_class->translate_event (backend, native, event); return parent_class->translate_event (backend, native, event);
} }
static gboolean static CoglRenderer *
clutter_backend_x11_create_context (ClutterBackend *backend, clutter_backend_x11_get_renderer (ClutterBackend *backend,
GError **error) GError **error)
{ {
ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (backend); ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (backend);
CoglOnscreenTemplate *onscreen_template = NULL; Display *xdisplay = backend_x11->xdpy;
CoglSwapChain *swap_chain = NULL; CoglRenderer *renderer;
CLUTTER_NOTE (BACKEND, "Creating a new Xlib renderer");
renderer = cogl_renderer_new ();
/* set the display object we're using */
cogl_xlib_renderer_set_foreign_display (renderer, xdisplay);
return renderer;
}
static CoglDisplay *
clutter_backend_x11_get_display (ClutterBackend *backend,
CoglRenderer *renderer,
CoglSwapChain *swap_chain,
GError **error)
{
CoglOnscreenTemplate *onscreen_template;
GError *internal_error = NULL; GError *internal_error = NULL;
gboolean status; CoglDisplay *display;
gboolean res;
if (backend->cogl_context != NULL) CLUTTER_NOTE (BACKEND, "Alpha on Cogl swap chain: %s",
return TRUE; clutter_enable_argb ? "enabled" : "disabled");
backend->cogl_renderer = cogl_renderer_new ();
cogl_xlib_renderer_set_foreign_display (backend->cogl_renderer,
backend_x11->xdpy);
if (!cogl_renderer_connect (backend->cogl_renderer, &internal_error))
goto error;
swap_chain = cogl_swap_chain_new ();
cogl_swap_chain_set_has_alpha (swap_chain, clutter_enable_argb); cogl_swap_chain_set_has_alpha (swap_chain, clutter_enable_argb);
onscreen_template = cogl_onscreen_template_new (swap_chain); onscreen_template = cogl_onscreen_template_new (swap_chain);
cogl_object_unref (swap_chain);
/* XXX: I have some doubts that this is a good design. res = cogl_renderer_check_onscreen_template (renderer,
*
* Conceptually should we be able to check an onscreen_template
* without more details about the CoglDisplay configuration?
*/
status = cogl_renderer_check_onscreen_template (backend->cogl_renderer,
onscreen_template, onscreen_template,
&internal_error); &internal_error);
if (!status && clutter_enable_argb) if (!res && clutter_enable_argb)
{ {
CLUTTER_NOTE (BACKEND, CLUTTER_NOTE (BACKEND,
"Creation of a context with a ARGB visual failed: %s", "Creation of a context with a ARGB visual failed: %s",
@ -731,61 +742,27 @@ clutter_backend_x11_create_context (ClutterBackend *backend,
*/ */
clutter_enable_argb = FALSE; clutter_enable_argb = FALSE;
cogl_swap_chain_set_has_alpha (swap_chain, FALSE); cogl_swap_chain_set_has_alpha (swap_chain, FALSE);
status = cogl_renderer_check_onscreen_template (backend->cogl_renderer, res = cogl_renderer_check_onscreen_template (renderer,
onscreen_template, onscreen_template,
&internal_error); &internal_error);
} }
if (!status) if (!res)
goto error;
backend->cogl_display = cogl_display_new (backend->cogl_renderer,
onscreen_template);
cogl_object_unref (backend->cogl_renderer);
cogl_object_unref (onscreen_template);
if (!cogl_display_setup (backend->cogl_display, &internal_error))
goto error;
backend->cogl_context = cogl_context_new (backend->cogl_display,
&internal_error);
if (backend->cogl_context == NULL)
goto error;
return TRUE;
error:
if (internal_error != NULL)
{ {
CLUTTER_NOTE (BACKEND, "Backend creation failed: %s",
internal_error->message);
g_set_error_literal (error, CLUTTER_INIT_ERROR, g_set_error_literal (error, CLUTTER_INIT_ERROR,
CLUTTER_INIT_ERROR_BACKEND, CLUTTER_INIT_ERROR_BACKEND,
internal_error->message); internal_error->message);
g_error_free (internal_error); g_error_free (internal_error);
}
if (backend->cogl_display != NULL)
{
cogl_object_unref (backend->cogl_display);
backend->cogl_display = NULL;
}
if (onscreen_template != NULL)
cogl_object_unref (onscreen_template); cogl_object_unref (onscreen_template);
if (swap_chain != NULL) return NULL;
cogl_object_unref (swap_chain);
if (backend->cogl_renderer != NULL)
{
cogl_object_unref (backend->cogl_renderer);
backend->cogl_renderer = NULL;
} }
return FALSE; display = cogl_display_new (renderer, onscreen_template);
cogl_object_unref (onscreen_template);
return display;
} }
static ClutterStageWindow * static ClutterStageWindow *
@ -823,16 +800,19 @@ clutter_backend_x11_class_init (ClutterBackendX11Class *klass)
gobject_class->dispose = clutter_backend_x11_dispose; gobject_class->dispose = clutter_backend_x11_dispose;
gobject_class->finalize = clutter_backend_x11_finalize; gobject_class->finalize = clutter_backend_x11_finalize;
backend_class->stage_window_type = CLUTTER_TYPE_STAGE_X11;
backend_class->pre_parse = _clutter_backend_x11_pre_parse; backend_class->pre_parse = _clutter_backend_x11_pre_parse;
backend_class->post_parse = _clutter_backend_x11_post_parse; backend_class->post_parse = _clutter_backend_x11_post_parse;
backend_class->init_events = clutter_backend_x11_init_events;
backend_class->add_options = clutter_backend_x11_add_options; backend_class->add_options = clutter_backend_x11_add_options;
backend_class->get_features = clutter_backend_x11_get_features; backend_class->get_features = clutter_backend_x11_get_features;
backend_class->get_device_manager = clutter_backend_x11_get_device_manager;
backend_class->copy_event_data = clutter_backend_x11_copy_event_data; backend_class->copy_event_data = clutter_backend_x11_copy_event_data;
backend_class->free_event_data = clutter_backend_x11_free_event_data; backend_class->free_event_data = clutter_backend_x11_free_event_data;
backend_class->translate_event = clutter_backend_x11_translate_event; backend_class->translate_event = clutter_backend_x11_translate_event;
backend_class->create_context = clutter_backend_x11_create_context;
backend_class->get_renderer = clutter_backend_x11_get_renderer;
backend_class->get_display = clutter_backend_x11_get_display;
backend_class->create_stage = clutter_backend_x11_create_stage; backend_class->create_stage = clutter_backend_x11_create_stage;
} }

View File

@ -31,7 +31,6 @@
#include "clutter-backend-private.h" #include "clutter-backend-private.h"
#include "clutter-keymap-x11.h" #include "clutter-keymap-x11.h"
#include "cogl/clutter-backend-cogl.h"
#include "xsettings/xsettings-client.h" #include "xsettings/xsettings-client.h"
@ -68,7 +67,7 @@ struct _ClutterEventX11
struct _ClutterBackendX11 struct _ClutterBackendX11
{ {
ClutterBackendCogl parent_instance; ClutterBackend parent_instance;
Display *xdpy; Display *xdpy;
gchar *display_name; gchar *display_name;
@ -113,32 +112,25 @@ struct _ClutterBackendX11
struct _ClutterBackendX11Class struct _ClutterBackendX11Class
{ {
ClutterBackendCoglClass parent_class; ClutterBackendClass parent_class;
}; };
void _clutter_backend_x11_events_init (ClutterBackend *backend);
void _clutter_backend_x11_events_uninit (ClutterBackend *backend);
GType _clutter_backend_x11_get_type (void) G_GNUC_CONST; GType _clutter_backend_x11_get_type (void) G_GNUC_CONST;
void _clutter_backend_x11_events_init (ClutterBackend *backend);
GSource * _clutter_x11_event_source_new (ClutterBackendX11 *backend_x11);
/* Private to glx/eglx backends */ /* Private to glx/eglx backends */
XVisualInfo * XVisualInfo * _clutter_backend_x11_get_visual_info (ClutterBackendX11 *backend_x11);
_clutter_backend_x11_get_visual_info (ClutterBackendX11 *backend_x11);
void void _clutter_x11_select_events (Window xwin);
_clutter_x11_select_events (Window xwin);
ClutterEventX11 * ClutterEventX11 * _clutter_event_x11_new (void);
_clutter_event_x11_new (void); ClutterEventX11 * _clutter_event_x11_copy (ClutterEventX11 *event_x11);
void _clutter_event_x11_free (ClutterEventX11 *event_x11);
ClutterEventX11 * gboolean _clutter_x11_input_device_translate_screen_coord (ClutterInputDevice *device,
_clutter_event_x11_copy (ClutterEventX11 *event_x11);
void
_clutter_event_x11_free (ClutterEventX11 *event_x11);
gboolean
_clutter_x11_input_device_translate_screen_coord (ClutterInputDevice *device,
gint stage_root_x, gint stage_root_x,
gint stage_root_y, gint stage_root_y,
guint index_, guint index_,

View File

@ -67,7 +67,8 @@ struct _ClutterEventSource
{ {
GSource source; GSource source;
ClutterBackend *backend; ClutterBackendX11 *backend;
GPollFD event_poll_fd; GPollFD event_poll_fd;
}; };
@ -100,8 +101,6 @@ static gboolean clutter_event_dispatch (GSource *source,
GSourceFunc callback, GSourceFunc callback,
gpointer user_data); gpointer user_data);
static GList *event_sources = NULL;
static GSourceFuncs event_funcs = { static GSourceFuncs event_funcs = {
clutter_event_prepare, clutter_event_prepare,
clutter_event_check, clutter_event_check,
@ -109,150 +108,33 @@ static GSourceFuncs event_funcs = {
NULL NULL
}; };
static GSource * GSource *
clutter_event_source_new (ClutterBackend *backend) _clutter_x11_event_source_new (ClutterBackendX11 *backend_x11)
{ {
GSource *source = g_source_new (&event_funcs, sizeof (ClutterEventSource));
ClutterEventSource *event_source = (ClutterEventSource *) source;
event_source->backend = backend;
return source;
}
static gboolean
check_xpending (ClutterBackend *backend)
{
return XPending (CLUTTER_BACKEND_X11 (backend)->xdpy);
}
#if 0
static gboolean
xembed_send_message (ClutterBackendX11 *backend_x11,
Window window,
long message,
long detail,
long data1,
long data2)
{
XEvent ev;
memset (&ev, 0, sizeof (ev));
ev.xclient.type = ClientMessage;
ev.xclient.window = window;
ev.xclient.message_type = backend_x11->atom_XEMBED;
ev.xclient.format = 32;
ev.xclient.data.l[0] = CurrentTime;
ev.xclient.data.l[1] = message;
ev.xclient.data.l[2] = detail;
ev.xclient.data.l[3] = data1;
ev.xclient.data.l[4] = data2;
clutter_x11_trap_x_errors ();
XSendEvent (backend_x11->xdpy, window, False, NoEventMask, &ev);
XSync (backend_x11->xdpy, False);
if (clutter_x11_untrap_x_errors ())
return False;
return True;
}
static void
xembed_set_info (ClutterBackendX11 *backend_x11,
Window window,
gint flags)
{
gint32 list[2];
list[0] = MAX_SUPPORTED_XEMBED_VERSION;
list[1] = XEMBED_MAPPED;
XChangeProperty (backend_x11->xdpy, window,
backend_x11->atom_XEMBED_INFO,
backend_x11->atom_XEMBED_INFO, 32,
PropModeReplace, (unsigned char *) list, 2);
}
#endif
void
_clutter_backend_x11_events_init (ClutterBackend *backend)
{
ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (backend);
GSource *source;
ClutterEventSource *event_source; ClutterEventSource *event_source;
int connection_number; int connection_number;
GSource *source;
gchar *name; gchar *name;
connection_number = ConnectionNumber (backend_x11->xdpy); connection_number = ConnectionNumber (backend_x11->xdpy);
CLUTTER_NOTE (EVENT, "Connection number: %d", connection_number); CLUTTER_NOTE (EVENT, "Connection number: %d", connection_number);
source = backend_x11->event_source = clutter_event_source_new (backend); source = g_source_new (&event_funcs, sizeof (ClutterEventSource));
event_source = (ClutterEventSource *) source; event_source = (ClutterEventSource *) source;
g_source_set_priority (source, CLUTTER_PRIORITY_EVENTS);
name = g_strdup_printf ("Clutter X11 Event (connection: %d)", name = g_strdup_printf ("Clutter X11 Event (connection: %d)",
connection_number); connection_number);
g_source_set_name (source, name); g_source_set_name (source, name);
g_free (name); g_free (name);
event_source->backend = backend_x11;
event_source->event_poll_fd.fd = connection_number; event_source->event_poll_fd.fd = connection_number;
event_source->event_poll_fd.events = G_IO_IN; event_source->event_poll_fd.events = G_IO_IN;
event_sources = g_list_prepend (event_sources, event_source);
g_source_add_poll (source, &event_source->event_poll_fd); g_source_add_poll (source, &event_source->event_poll_fd);
g_source_set_can_recurse (source, TRUE); g_source_set_can_recurse (source, TRUE);
g_source_attach (source, NULL);
}
void return source;
_clutter_backend_x11_events_uninit (ClutterBackend *backend)
{
ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (backend);
if (backend_x11->event_source)
{
CLUTTER_NOTE (EVENT, "Destroying the event source");
event_sources = g_list_remove (event_sources,
backend_x11->event_source);
g_source_destroy (backend_x11->event_source);
g_source_unref (backend_x11->event_source);
backend_x11->event_source = NULL;
}
}
static void
events_queue (ClutterBackend *backend)
{
ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (backend);
Display *xdisplay = backend_x11->xdpy;
ClutterEvent *event;
XEvent xevent;
while (!clutter_events_pending () && XPending (xdisplay))
{
XNextEvent (xdisplay, &xevent);
event = clutter_event_new (CLUTTER_NOTHING);
#ifdef HAVE_XGE
XGetEventData (xdisplay, &xevent.xcookie);
#endif
if (_clutter_backend_translate_event (backend, &xevent, event))
_clutter_event_push (event, FALSE);
else
clutter_event_free (event);
#ifdef HAVE_XGE
XFreeEventData (xdisplay, &xevent.xcookie);
#endif
}
} }
/** /**
@ -357,13 +239,13 @@ static gboolean
clutter_event_prepare (GSource *source, clutter_event_prepare (GSource *source,
gint *timeout) gint *timeout)
{ {
ClutterBackend *backend = ((ClutterEventSource *) source)->backend; ClutterBackendX11 *backend = ((ClutterEventSource *) source)->backend;
gboolean retval; gboolean retval;
clutter_threads_enter (); clutter_threads_enter ();
*timeout = -1; *timeout = -1;
retval = (clutter_events_pending () || check_xpending (backend)); retval = (clutter_events_pending () || XPending (backend->xdpy));
clutter_threads_leave (); clutter_threads_leave ();
@ -374,13 +256,13 @@ static gboolean
clutter_event_check (GSource *source) clutter_event_check (GSource *source)
{ {
ClutterEventSource *event_source = (ClutterEventSource *) source; ClutterEventSource *event_source = (ClutterEventSource *) source;
ClutterBackend *backend = event_source->backend; ClutterBackendX11 *backend = event_source->backend;
gboolean retval; gboolean retval;
clutter_threads_enter (); clutter_threads_enter ();
if (event_source->event_poll_fd.revents & G_IO_IN) if (event_source->event_poll_fd.revents & G_IO_IN)
retval = (clutter_events_pending () || check_xpending (backend)); retval = (clutter_events_pending () || XPending (backend->xdpy));
else else
retval = FALSE; retval = FALSE;
@ -389,12 +271,41 @@ clutter_event_check (GSource *source)
return retval; return retval;
} }
static void
events_queue (ClutterBackendX11 *backend_x11)
{
ClutterBackend *backend = CLUTTER_BACKEND (backend_x11);
Display *xdisplay = backend_x11->xdpy;
ClutterEvent *event;
XEvent xevent;
while (!clutter_events_pending () && XPending (xdisplay))
{
XNextEvent (xdisplay, &xevent);
event = clutter_event_new (CLUTTER_NOTHING);
#ifdef HAVE_XGE
XGetEventData (xdisplay, &xevent.xcookie);
#endif
if (_clutter_backend_translate_event (backend, &xevent, event))
_clutter_event_push (event, FALSE);
else
clutter_event_free (event);
#ifdef HAVE_XGE
XFreeEventData (xdisplay, &xevent.xcookie);
#endif
}
}
static gboolean static gboolean
clutter_event_dispatch (GSource *source, clutter_event_dispatch (GSource *source,
GSourceFunc callback, GSourceFunc callback,
gpointer user_data) gpointer user_data)
{ {
ClutterBackend *backend = ((ClutterEventSource *) source)->backend; ClutterBackendX11 *backend = ((ClutterEventSource *) source)->backend;
ClutterEvent *event; ClutterEvent *event;
clutter_threads_enter (); clutter_threads_enter ();

View File

@ -204,6 +204,8 @@ clutter_stage_x11_get_geometry (ClutterStageWindow *stage_window,
ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_x11); ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_x11);
ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (stage_cogl->backend); ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (stage_cogl->backend);
geometry->x = geometry->y = 0;
/* If we're fullscreen, return the size of the display. */ /* If we're fullscreen, return the size of the display. */
if ((stage_x11->state & CLUTTER_STAGE_STATE_FULLSCREEN) && if ((stage_x11->state & CLUTTER_STAGE_STATE_FULLSCREEN) &&
stage_x11->fullscreening) stage_x11->fullscreening)
@ -785,10 +787,9 @@ static void
clutter_stage_x11_dispose (GObject *gobject) clutter_stage_x11_dispose (GObject *gobject)
{ {
ClutterEventTranslator *translator = CLUTTER_EVENT_TRANSLATOR (gobject); ClutterEventTranslator *translator = CLUTTER_EVENT_TRANSLATOR (gobject);
ClutterBackendCogl *backend = CLUTTER_STAGE_COGL (gobject)->backend; ClutterBackend *backend = CLUTTER_STAGE_COGL (gobject)->backend;
_clutter_backend_remove_event_translator (CLUTTER_BACKEND (backend), _clutter_backend_remove_event_translator (backend, translator);
translator);
G_OBJECT_CLASS (clutter_stage_x11_parent_class)->dispose (gobject); G_OBJECT_CLASS (clutter_stage_x11_parent_class)->dispose (gobject);
} }

View File

@ -192,8 +192,10 @@ dnl ========================================================================
FLAVOUR_LIBS="" FLAVOUR_LIBS=""
FLAVOUR_CFLAGS="" FLAVOUR_CFLAGS=""
CLUTTER_BACKENDS="" CLUTTER_BACKENDS=""
CLUTTER_INPUT_BACKENDS=""
experimental_backend=no experimental_backend=no
experimental_input_backend=no
# base dependencies for core # base dependencies for core
CLUTTER_BASE_PC_FILES="cogl-1.0 >= $COGL_REQ_VERSION cairo-gobject >= $CAIRO_REQ_VERSION atk >= $ATK_REQ_VERSION pangocairo >= $PANGO_REQ_VERSION cogl-pango-1.0 json-glib-1.0 >= $JSON_GLIB_REQ_VERSION" CLUTTER_BASE_PC_FILES="cogl-1.0 >= $COGL_REQ_VERSION cairo-gobject >= $CAIRO_REQ_VERSION atk >= $ATK_REQ_VERSION pangocairo >= $PANGO_REQ_VERSION cogl-pango-1.0 json-glib-1.0 >= $JSON_GLIB_REQ_VERSION"
@ -227,6 +229,10 @@ AC_ARG_ENABLE([egl-backend],
[AS_HELP_STRING([--enable-egl-backend=@<:@yes/no@:>@], [Enable the EGL framebuffer backend (default=no)])], [AS_HELP_STRING([--enable-egl-backend=@<:@yes/no@:>@], [Enable the EGL framebuffer backend (default=no)])],
[enable_egl=$enableval], [enable_egl=$enableval],
[enable_egl=no]) [enable_egl=no])
AC_ARG_ENABLE([cex100-backend],
[AS_HELP_STRING([--enable-cex100-backend=@<:@yes/no@:>@], [Enable the CEx100 backend (default=no)])],
[enable_cex100=$enableval],
[enable_cex100=no])
dnl Define default values dnl Define default values
AS_IF([test "x$enable_x11" = "xcheck"], AS_IF([test "x$enable_x11" = "xcheck"],
@ -253,6 +259,7 @@ dnl Per-backend rules
AS_IF([test "x$enable_x11" = "xyes"], AS_IF([test "x$enable_x11" = "xyes"],
[ [
CLUTTER_BACKENDS="$CLUTTER_BACKENDS x11" CLUTTER_BACKENDS="$CLUTTER_BACKENDS x11"
CLUTTER_INPUT_BACKENDS="$CLUTTER_INPUT_BACKENDS x11"
SUPPORT_X11=1 SUPPORT_X11=1
SUPPORT_GLX=1 SUPPORT_GLX=1
@ -287,6 +294,7 @@ AS_IF([test "x$enable_x11" = "xyes"],
AS_IF([test "x$enable_gdk" = "xyes"], AS_IF([test "x$enable_gdk" = "xyes"],
[ [
CLUTTER_BACKENDS="$CLUTTER_BACKENDS gdk" CLUTTER_BACKENDS="$CLUTTER_BACKENDS gdk"
CLUTTER_INPUT_BACKENDS="$CLUTTER_INPUT_BACKENDS gdk"
SUPPORT_GDK=1 SUPPORT_GDK=1
SUPPORT_COGL=1 SUPPORT_COGL=1
@ -313,61 +321,16 @@ AS_IF([test "x$enable_wayland" = "xyes"],
AC_DEFINE([HAVE_CLUTTER_WAYLAND], [1], [Have the Wayland backend]) AC_DEFINE([HAVE_CLUTTER_WAYLAND], [1], [Have the Wayland backend])
]) ])
AS_IF([test "x$enable_egl" = "xyes"], AS_IF([test "x$enable_cex100" = "xyes"],
[ [
CLUTTER_BACKENDS="$CLUTTER_BACKENDS egl" CLUTTER_BACKENDS="$CLUTTER_BACKENDS cex100"
experimental_backend="yes"
SUPPORT_EGL=1
SUPPORT_COGL=1 SUPPORT_COGL=1
SUPPORT_EGL_PLATFORM_GDL=1
# if Mesa has support for egl, we can use it as well
PKG_CHECK_EXISTS([egl],
[
BACKEND_PC_FILES="$BACKEND_PC_FILES egl"
],
[])
AC_ARG_WITH([tslib],
[AS_HELP_STRING([--with-tslib=@<:@yes/no@:>@], [Use TSLib for events (default=no)])],
[],
[with_tslib=no])
AC_ARG_WITH([evdev],
[AS_HELP_STRING([--with-evdev=@<:@yes/no@:>@], [Use evdev for events (default=yes)])],
[],
[with_evdev=yes])
AC_ARG_WITH([gdl],
[AS_HELP_STRING([--with-gdl=@<:@yes/no@:>@], [Use libgdl for CE3100/CE4100 support (default=no)])],
[],
[with_gdl=no])
AS_IF([test "x$with_tslib" = "xyes"],
[
PKG_CHECK_MODULES(TSLIB, [tslib-1.0], [have_tslib=yes], [have_tslib=no])
AS_IF([test "x$have_tslib" = "xyes"],
[
AC_DEFINE([HAVE_TSLIB], [1], [Have tslib for touchscreen handling])
SUPPORT_TSLIB=1
])
],
[have_tslib=no])
AS_IF([test "x$with_evdev" = "xyes"],
[
PKG_CHECK_MODULES(EVDEV, [gudev-1.0 xkbcommon], [have_evdev=yes], [have_evdev=no])
AS_IF([test "x$have_evdev" = "xyes"],
[
AC_DEFINE([HAVE_EVDEV], [1], [Have evdev support for input handling])
SUPPORT_EVDEV=1
])
],
[have_evdev=no])
AS_IF([test "x$with_gdl" = "xyes"],
[
have_gdl=no have_gdl=no
AC_CHECK_HEADERS([libgdl.h], [have_gdl=yes]) AC_CHECK_HEADERS([libgdl.h], [have_gdl=yes])
AS_IF([test "x$have_gdl" = "xno"], AS_IF([test "x$have_gdl" = "xno"],
@ -380,17 +343,33 @@ AS_IF([test "x$enable_egl" = "xyes"],
]) ])
]) ])
AC_SUBST(CLUTTER_CEX100_LIBGDL_PREFIX) AS_IF([test "x$have_gdl" = "xno"],
[AC_MSG_ERROR([libgdl.h not found but the CEx100 backend has been explicitly enabled])])
AS_IF([test "x$have_gdl" = "xno"], [AC_MSG_ERROR([libgdl.h not found])]) AC_SUBST(CLUTTER_CEX100_LIBGDL_PREFIX)
FLAVOUR_LIBS="$FLAVOUR_LIBS -lgdl" FLAVOUR_LIBS="$FLAVOUR_LIBS -lgdl"
SUPPORT_EGL_PLATFORM_GDL=1
AC_DEFINE([CLUTTER_EGL_BACKEND_CEX100], [1], [Use CEX100 EGL backend]) AC_DEFINE([CLUTTER_EGL_BACKEND_CEX100], [1], [Use CEX100 EGL backend])
AC_DEFINE([CLUTTER_EGL_BACKEND_GENERIC], [1], [Use Generic EGL backend])
AC_DEFINE([HAVE_CLUTTER_EGL], [1], [Have the EGL backend])
])
AS_IF([test "x$enable_egl" = "xyes"],
[
CLUTTER_BACKENDS="$CLUTTER_BACKENDS egl"
experimental_backend="yes"
SUPPORT_EGL=1
SUPPORT_COGL=1
# if Mesa has support for egl, we can use it as well
PKG_CHECK_EXISTS([egl],
[
BACKEND_PC_FILES="$BACKEND_PC_FILES egl"
], ],
[have_gdl=no]) [])
FLAVOUR_LIBS="$FLAVOUR_LIBS $TSLIB_LIBS $EVDEV_LIBS" FLAVOUR_LIBS="$FLAVOUR_LIBS $TSLIB_LIBS $EVDEV_LIBS"
FLAVOUR_CFLAGS="$FLAVOUR_CFLAGS $TSLIB_CFLAGS $EVDEV_CFLAGS" FLAVOUR_CFLAGS="$FLAVOUR_CFLAGS $TSLIB_CFLAGS $EVDEV_CFLAGS"
@ -403,6 +382,7 @@ AS_IF([test "x$enable_egl" = "xyes"],
AS_IF([test "x$enable_osx" = "xyes"], AS_IF([test "x$enable_osx" = "xyes"],
[ [
CLUTTER_BACKENDS="$CLUTTER_BACKENDS osx" CLUTTER_BACKENDS="$CLUTTER_BACKENDS osx"
CLUTTER_INPUT_BACKENDS="$CLUTTER_INPUT_BACKENDS osx"
AC_DEFINE([HAVE_CLUTTER_OSX], [1], [Have the OSX backend]) AC_DEFINE([HAVE_CLUTTER_OSX], [1], [Have the OSX backend])
@ -414,6 +394,7 @@ AS_IF([test "x$enable_osx" = "xyes"],
AS_IF([test "x$enable_win32" = "xyes"], AS_IF([test "x$enable_win32" = "xyes"],
[ [
CLUTTER_BACKENDS="$CLUTTER_BACKENDS win32" CLUTTER_BACKENDS="$CLUTTER_BACKENDS win32"
CLUTTER_INPUT_BACKENDS="$CLUTTER_INPUT_BACKENDS win32"
AC_DEFINE([HAVE_CLUTTER_WIN32], [1], [Have the Win32 backend]) AC_DEFINE([HAVE_CLUTTER_WIN32], [1], [Have the Win32 backend])
@ -430,6 +411,41 @@ AS_IF([test "x$CLUTTER_BACKENDS" = "x"],
AC_MSG_ERROR([No backend enabled. You need to enable at least one backend.]) AC_MSG_ERROR([No backend enabled. You need to enable at least one backend.])
]) ])
# additional input backends
AC_ARG_ENABLE([tslib-input],
[AS_HELP_STRING([--enable-tslib-input=@<:@yes/no@:>@], [Enable TSLib for input events (default=no)])],
[enable_tslib=$enableval],
[enable_tslib=no])
AC_ARG_ENABLE([evdev-input],
[AS_HELP_STRING([--with-evdev=@<:@yes/no@:>@], [Enable evdev for input events (default=no)])],
[enable_evdev=$enableval],
[enable_evdev=no])
AS_IF([test "x$enable_tslib" = "xyes"],
[
PKG_CHECK_MODULES(TSLIB, [tslib-1.0], [have_tslib=yes], [have_tslib=no])
AS_IF([test "x$have_tslib" = "xyes"],
[
CLUTTER_INPUT_BACKENDS="$CLUTTER_INPUT_BACKENDS tslib"
experimental_input_backend="yes"
AC_DEFINE([HAVE_TSLIB], [1], [Have tslib for touchscreen handling])
SUPPORT_TSLIB=1
])
])
AS_IF([test "x$enable_evdev" = "xyes"],
[
PKG_CHECK_MODULES(EVDEV, [gudev-1.0 xkbcommon], [have_evdev=yes], [have_evdev=no])
AS_IF([test "x$have_evdev" = "xyes"],
[
CLUTTER_INPUT_BACKENDS="$CLUTTER_INPUT_BACKENDS evdev"
experimental_input_backend="yes"
AC_DEFINE([HAVE_EVDEV], [1], [Have evdev support for input handling])
SUPPORT_EVDEV=1
])
])
# conditionals for use in automake files... # conditionals for use in automake files...
AM_CONDITIONAL(SUPPORT_GLX, [test "x$SUPPORT_GLX" = "x1"]) AM_CONDITIONAL(SUPPORT_GLX, [test "x$SUPPORT_GLX" = "x1"])
AM_CONDITIONAL(SUPPORT_X11, [test "x$SUPPORT_X11" = "x1"]) AM_CONDITIONAL(SUPPORT_X11, [test "x$SUPPORT_X11" = "x1"])
@ -459,6 +475,9 @@ dnl strip leading spaces
CLUTTER_BACKENDS=${CLUTTER_BACKENDS#* } CLUTTER_BACKENDS=${CLUTTER_BACKENDS#* }
AC_SUBST(CLUTTER_BACKENDS) AC_SUBST(CLUTTER_BACKENDS)
CLUTTER_INPUT_BACKENDS=${CLUTTER_INPUT_BACKENDS#* }
AC_SUBST(CLUTTER_INPUT_BACKENDS)
AC_CACHE_SAVE AC_CACHE_SAVE
dnl === Clutter configuration ================================================= dnl === Clutter configuration =================================================
@ -468,10 +487,12 @@ CLUTTER_CONFIG_DEFINES=
# windowing systems # windowing systems
AS_IF([test "x$SUPPORT_X11" = "x1"], AS_IF([test "x$SUPPORT_X11" = "x1"],
[CLUTTER_CONFIG_DEFINES="$CLUTTER_CONFIG_DEFINES [CLUTTER_CONFIG_DEFINES="$CLUTTER_CONFIG_DEFINES
#define CLUTTER_WINDOWING_X11 \"x11\""]) #define CLUTTER_WINDOWING_X11 \"x11\"
#define CLUTTER_INPUT_X11 \"x11\""])
AS_IF([test "x$SUPPORT_GDK" = "x1"], AS_IF([test "x$SUPPORT_GDK" = "x1"],
[CLUTTER_CONFIG_DEFINES="$CLUTTER_CONFIG_DEFINES [CLUTTER_CONFIG_DEFINES="$CLUTTER_CONFIG_DEFINES
#define CLUTTER_WINDOWING_GDK \"gdk\""]) #define CLUTTER_WINDOWING_GDK \"gdk\"
#define CLUTTER_INPUT_GDK \"gdk\""])
AS_IF([test "x$SUPPORT_GLX" = "x1"], AS_IF([test "x$SUPPORT_GLX" = "x1"],
[CLUTTER_CONFIG_DEFINES="$CLUTTER_CONFIG_DEFINES [CLUTTER_CONFIG_DEFINES="$CLUTTER_CONFIG_DEFINES
#define CLUTTER_WINDOWING_GLX \"glx\""]) #define CLUTTER_WINDOWING_GLX \"glx\""])
@ -483,10 +504,12 @@ AS_IF([test "x$SUPPORT_WAYLAND" = "x1"],
#define CLUTTER_WINDOWING_WAYLAND \"wayland\""]) #define CLUTTER_WINDOWING_WAYLAND \"wayland\""])
AS_IF([test "x$SUPPORT_OSX" = "x1"], AS_IF([test "x$SUPPORT_OSX" = "x1"],
[CLUTTER_CONFIG_DEFINES="$CLUTTER_CONFIG_DEFINES [CLUTTER_CONFIG_DEFINES="$CLUTTER_CONFIG_DEFINES
#define CLUTTER_WINDOWING_OSX \"osx\""]) #define CLUTTER_WINDOWING_OSX \"osx\"
#define CLUTTER_INPUT_OSX \"osx\""])
AS_IF([test "x$SUPPORT_WIN32" = "x1"], AS_IF([test "x$SUPPORT_WIN32" = "x1"],
[CLUTTER_CONFIG_DEFINES="$CLUTTER_CONFIG_DEFINES [CLUTTER_CONFIG_DEFINES="$CLUTTER_CONFIG_DEFINES
#define CLUTTER_WINDOWING_WIN32 \"win32\""]) #define CLUTTER_WINDOWING_WIN32 \"win32\"
#define CLUTTER_INPUT_WIN32 \"win32\""])
AS_IF([test "x$SUPPORT_EGL_PLATFORM_GDL" = "x1"], AS_IF([test "x$SUPPORT_EGL_PLATFORM_GDL" = "x1"],
[CLUTTER_CONFIG_DEFINES="$CLUTTER_CONFIG_DEFINES [CLUTTER_CONFIG_DEFINES="$CLUTTER_CONFIG_DEFINES
#define CLUTTER_WINDOWING_CEX100 \"cex100\""]) #define CLUTTER_WINDOWING_CEX100 \"cex100\""])
@ -497,6 +520,10 @@ AS_IF([test "x$SUPPORT_TSLIB" = "x1"],
[CLUTTER_CONFIG_DEFINES="$CLUTTER_CONFIG_DEFINES [CLUTTER_CONFIG_DEFINES="$CLUTTER_CONFIG_DEFINES
#define CLUTTER_INPUT_TSLIB \"tslib\""]) #define CLUTTER_INPUT_TSLIB \"tslib\""])
# the 'null' input backend is special
CLUTTER_CONFIG_DEFINES="$CLUTTER_CONFIG_DEFINES
#define CLUTTER_INPUT_NULL \"null\""
AC_SUBST([CLUTTER_CONFIG_DEFINES]) AC_SUBST([CLUTTER_CONFIG_DEFINES])
dnl === Clutter substitutions kept for backwards compatibility ================ dnl === Clutter substitutions kept for backwards compatibility ================
@ -997,7 +1024,7 @@ AC_CONFIG_FILES([
clutter/cally/cally-$CLUTTER_API_VERSION.pc:clutter/cally/cally.pc.in clutter/cally/cally-$CLUTTER_API_VERSION.pc:clutter/cally/cally.pc.in
clutter/egl/clutter-cex100.h clutter/cex100/clutter-cex100.h
tests/Makefile tests/Makefile
tests/accessibility/Makefile tests/accessibility/Makefile
@ -1069,6 +1096,12 @@ else
echo " Windowing systems: ${CLUTTER_BACKENDS} (WARNING: Experimental backends enabled)" echo " Windowing systems: ${CLUTTER_BACKENDS} (WARNING: Experimental backends enabled)"
fi fi
if test "x$experimental_input_backend" = "xno"; then
echo " Input backends: ${CLUTTER_INPUT_BACKENDS}"
else
echo " Input backends: ${CLUTTER_INPUT_BACKENDS} (WARNING: Experimental backends enabled)"
fi
if test "x$SUPPORT_X11" = "x1"; then if test "x$SUPPORT_X11" = "x1"; then
echo "" echo ""
echo " - X11 backend options:" echo " - X11 backend options:"
@ -1076,12 +1109,10 @@ echo " Enabled extensions: ${X11_EXTS}"
echo " Build X11-specific tests: ${x11_tests}" echo " Build X11-specific tests: ${x11_tests}"
fi fi
if test "x$SUPPORT_EGL" = "x1"; then if test "x$SUPPORT_CEX100" = "x1"; then
echo "" echo ""
echo " - EGL backend options:" echo " - CEx100 backend options:"
echo " Enable TSLib: ${have_tslib}" echo " libGDL include prefix: ${CLUTTER_CEX100_LIBGDL_PREFIX}"
echo " Enable evdev: ${have_evdev}"
echo " Enable GDL: ${have_gdl}"
fi fi
echo "" echo ""

View File

@ -54,7 +54,7 @@ HFILE_GLOB=\
$(top_srcdir)/clutter/x11/clutter-x11-texture-pixmap.h \ $(top_srcdir)/clutter/x11/clutter-x11-texture-pixmap.h \
$(top_srcdir)/clutter/x11/clutter-glx-texture-pixmap.h \ $(top_srcdir)/clutter/x11/clutter-glx-texture-pixmap.h \
$(top_srcdir)/clutter/egl/clutter-egl.h \ $(top_srcdir)/clutter/egl/clutter-egl.h \
$(top_srcdir)/clutter/egl/clutter-cex100.h \ $(top_srcdir)/clutter/cex100/clutter-cex100.h \
$(top_srcdir)/clutter/win32/clutter-win32.h \ $(top_srcdir)/clutter/win32/clutter-win32.h \
$(top_srcdir)/clutter/gdk/clutter-gdk.h $(top_srcdir)/clutter/gdk/clutter-gdk.h
@ -64,6 +64,7 @@ CFILE_GLOB=\
$(top_srcdir)/clutter/x11/*.c \ $(top_srcdir)/clutter/x11/*.c \
$(top_srcdir)/clutter/win32/*.c \ $(top_srcdir)/clutter/win32/*.c \
$(top_srcdir)/clutter/gdk/*.c \ $(top_srcdir)/clutter/gdk/*.c \
$(top_srcdir)/clutter/cex100/*.c \
$(top_srcdir)/clutter/egl/*.c $(top_srcdir)/clutter/egl/*.c
# Header files to ignore when scanning. # Header files to ignore when scanning.
@ -113,7 +114,7 @@ EXTRA_HFILES=\
$(top_srcdir)/clutter/x11/clutter-x11-texture-pixmap.h \ $(top_srcdir)/clutter/x11/clutter-x11-texture-pixmap.h \
$(top_srcdir)/clutter/x11/clutter-glx-texture-pixmap.h \ $(top_srcdir)/clutter/x11/clutter-glx-texture-pixmap.h \
$(top_srcdir)/clutter/egl/clutter-egl.h \ $(top_srcdir)/clutter/egl/clutter-egl.h \
$(top_srcdir)/clutter/egl/clutter-cex100.h \ $(top_srcdir)/clutter/cex100/clutter-cex100.h \
$(top_srcdir)/clutter/wayland/clutter-wayland.h \ $(top_srcdir)/clutter/wayland/clutter-wayland.h \
$(top_srcdir)/clutter/win32/clutter-win32.h \ $(top_srcdir)/clutter/win32/clutter-win32.h \
$(top_srcdir)/clutter/gdk/clutter-gdk.h $(top_srcdir)/clutter/gdk/clutter-gdk.h

View File

@ -6,13 +6,6 @@ clutter/clutter-alpha.c
clutter/clutter-animation.c clutter/clutter-animation.c
clutter/clutter-animator.c clutter/clutter-animator.c
clutter/clutter-backend.c clutter/clutter-backend.c
clutter/deprecated/clutter-behaviour.c
clutter/deprecated/clutter-behaviour-depth.c
clutter/deprecated/clutter-behaviour-ellipse.c
clutter/deprecated/clutter-behaviour-opacity.c
clutter/deprecated/clutter-behaviour-path.c
clutter/deprecated/clutter-behaviour-rotate.c
clutter/deprecated/clutter-behaviour-scale.c
clutter/clutter-bind-constraint.c clutter/clutter-bind-constraint.c
clutter/clutter-binding-pool.c clutter/clutter-binding-pool.c
clutter/clutter-bin-layout.c clutter/clutter-bin-layout.c
@ -31,8 +24,6 @@ clutter/clutter-device-manager.c
clutter/clutter-drag-action.c clutter/clutter-drag-action.c
clutter/clutter-drop-action.c clutter/clutter-drop-action.c
clutter/clutter-event.c clutter/clutter-event.c
clutter/deprecated/clutter-fixed.c
clutter/deprecated/clutter-fixed.h
clutter/clutter-flow-layout.c clutter/clutter-flow-layout.c
clutter/clutter-gesture-action.c clutter/clutter-gesture-action.c
clutter/clutter-input-device.c clutter/clutter-input-device.c
@ -45,7 +36,6 @@ clutter/clutter-path-constraint.c
clutter/clutter-rectangle.c clutter/clutter-rectangle.c
clutter/clutter-script.c clutter/clutter-script.c
clutter/clutter-settings.c clutter/clutter-settings.c
clutter/deprecated/clutter-shader.c
clutter/clutter-shader-effect.c clutter/clutter-shader-effect.c
clutter/clutter-shader-types.c clutter/clutter-shader-types.c
clutter/clutter-snap-constraint.c clutter/clutter-snap-constraint.c
@ -58,7 +48,6 @@ clutter/clutter-text.c
clutter/clutter-texture.c clutter/clutter-texture.c
clutter/clutter-timeline.c clutter/clutter-timeline.c
clutter/clutter-units.c clutter/clutter-units.c
clutter/cogl/clutter-backend-cogl.c
clutter/deprecated/clutter-behaviour.c clutter/deprecated/clutter-behaviour.c
clutter/deprecated/clutter-behaviour-depth.c clutter/deprecated/clutter-behaviour-depth.c
clutter/deprecated/clutter-behaviour-ellipse.c clutter/deprecated/clutter-behaviour-ellipse.c
@ -70,6 +59,7 @@ clutter/deprecated/clutter-fixed.c
clutter/deprecated/clutter-fixed.h clutter/deprecated/clutter-fixed.h
clutter/deprecated/clutter-shader.c clutter/deprecated/clutter-shader.c
clutter/evdev/clutter-input-device-evdev.c clutter/evdev/clutter-input-device-evdev.c
clutter/gdk/clutter-backend-gdk.c
clutter/x11/clutter-backend-x11.c clutter/x11/clutter-backend-x11.c
clutter/x11/clutter-keymap-x11.c clutter/x11/clutter-keymap-x11.c
clutter/x11/clutter-x11-texture-pixmap.c clutter/x11/clutter-x11-texture-pixmap.c

File diff suppressed because it is too large Load Diff

770
po/es.po

File diff suppressed because it is too large Load Diff

765
po/gl.po

File diff suppressed because it is too large Load Diff

View File

@ -73,7 +73,23 @@ test_color_hls_roundtrip (TestConformSimpleFixture *fixture,
} }
void void
test_color_from_string (TestConformSimpleFixture *fixture, test_color_from_string_invalid (TestConformSimpleFixture *fixture,
gconstpointer data)
{
ClutterColor color;
g_assert (!clutter_color_from_string (&color, "ff0000ff"));
g_assert (!clutter_color_from_string (&color, "#decaffbad"));
g_assert (!clutter_color_from_string (&color, "ponies"));
g_assert (!clutter_color_from_string (&color, "rgb(255, 0, 0, 0)"));
g_assert (!clutter_color_from_string (&color, "rgba(1.0, 0, 0)"));
g_assert (!clutter_color_from_string (&color, "hsl(100, 0, 0)"));
g_assert (!clutter_color_from_string (&color, "hsla(10%, 0%, 50%)"));
g_assert (!clutter_color_from_string (&color, "hsla(100%, 0%, 50%, 20%)"));
}
void
test_color_from_string_valid (TestConformSimpleFixture *fixture,
gconstpointer data) gconstpointer data)
{ {
ClutterColor color; ClutterColor color;
@ -205,6 +221,20 @@ test_color_from_string (TestConformSimpleFixture *fixture,
g_assert_cmpint (color.green, ==, 0); g_assert_cmpint (color.green, ==, 0);
g_assert_cmpint (color.blue, ==, 0); g_assert_cmpint (color.blue, ==, 0);
g_assert_cmpint (color.alpha, ==, 255); g_assert_cmpint (color.alpha, ==, 255);
g_assert (clutter_color_from_string (&color, "hsla( 0, 100%, 50%, 0.5 )"));
if (g_test_verbose ())
{
g_print ("color = { %x, %x, %x, %x }, expected = { 255, 0, 0, 127 }\n",
color.red,
color.green,
color.blue,
color.alpha);
}
g_assert_cmpint (color.red, ==, 255);
g_assert_cmpint (color.green, ==, 0);
g_assert_cmpint (color.blue, ==, 0);
g_assert_cmpint (color.alpha, ==, 127);
} }
void void

View File

@ -182,7 +182,8 @@ main (int argc, char **argv)
TEST_CONFORM_SIMPLE ("/model", test_list_model_from_script); TEST_CONFORM_SIMPLE ("/model", test_list_model_from_script);
TEST_CONFORM_SIMPLE ("/model", test_list_model_row_changed); TEST_CONFORM_SIMPLE ("/model", test_list_model_row_changed);
TEST_CONFORM_SIMPLE ("/color", test_color_from_string); TEST_CONFORM_SIMPLE ("/color", test_color_from_string_valid);
TEST_CONFORM_SIMPLE ("/color", test_color_from_string_invalid);
TEST_CONFORM_SIMPLE ("/color", test_color_to_string); TEST_CONFORM_SIMPLE ("/color", test_color_to_string);
TEST_CONFORM_SIMPLE ("/color", test_color_hls_roundtrip); TEST_CONFORM_SIMPLE ("/color", test_color_hls_roundtrip);
TEST_CONFORM_SIMPLE ("/color", test_color_operators); TEST_CONFORM_SIMPLE ("/color", test_color_operators);