mutter/clutter/sdl/clutter-stage-sdl.c
Emmanuele Bassi 7c89a0ccfa [stage] Rename :fullscreen to :fullscreen-set
The :fullscreen property is very much confusing as it is implemented.
It can be written to a value, but the whole process might fail. If we
set:

  g_object_set (stage, "fullscreen", TRUE, NULL);

and the fullscreen process fails or it is not implemented, the value
will be reset to FALSE (if we're lucky) or left TRUE (most of the
times).

The writability is just a shorthand for invoking clutter_stage_fullscreen()
or clutter_stage_unfullscreen() depending on a boolean value without
using an if.

The :fullscreen property also greatly confuses high level languages,
since the same symbol is used:

  - for a method name (Clutter.Stage.fullscreen())
  - for a property name (Clutter.Stage.fullscreen)
  - for a signal (Clutter.Stage::fullscreen)

For these reasons, the :fullscreen should be renamed to :fullscreen-set
and be read-only. Implementations of the Stage should only emit the
StageState event to change from normal to fullscreen, and the Stage
will automatically update the value of the property and emit a notify
signal for it.
2009-06-09 14:07:35 +01:00

235 lines
6.6 KiB
C

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "clutter-stage-sdl.h"
#include "clutter-sdl.h"
#include "../clutter-main.h"
#include "../clutter-feature.h"
#include "../clutter-color.h"
#include "../clutter-util.h"
#include "../clutter-event.h"
#include "../clutter-enum-types.h"
#include "../clutter-private.h"
#include "../clutter-debug.h"
#include "../clutter-units.h"
#include "../clutter-stage-window.h"
#include "cogl/cogl.h"
static void clutter_stage_window_iface_init (ClutterStageWindowIface *iface);
G_DEFINE_TYPE_WITH_CODE (ClutterStageSDL,
clutter_stage_sdl,
CLUTTER_TYPE_ACTOR,
G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_STAGE_WINDOW,
clutter_stage_window_iface_init));
static void
clutter_stage_sdl_show (ClutterActor *actor)
{
CLUTTER_ACTOR_SET_FLAGS (actor, CLUTTER_ACTOR_MAPPED);
CLUTTER_ACTOR_SET_FLAGS (CLUTTER_STAGE_SDL (actor)->wrapper,
CLUTTER_ACTOR_MAPPED);
CLUTTER_ACTOR_CLASS (clutter_stage_sdl_parent_class)->show (actor);
}
static void
clutter_stage_sdl_hide (ClutterActor *actor)
{
/* No way to easily unmap SDL window ? */
CLUTTER_ACTOR_UNSET_FLAGS (actor, CLUTTER_ACTOR_MAPPED);
CLUTTER_ACTOR_UNSET_FLAGS (CLUTTER_STAGE_SDL (actor)->wrapper,
CLUTTER_ACTOR_MAPPED);
CLUTTER_ACTOR_CLASS (clutter_stage_sdl_parent_class)->hide (actor);
}
static void
clutter_stage_sdl_unrealize (ClutterActor *actor)
{
;
}
static void
clutter_stage_sdl_realize (ClutterActor *actor)
{
ClutterStageSDL *stage_sdl = CLUTTER_STAGE_SDL (actor);
gboolean is_offscreen, is_fullscreen;
CLUTTER_NOTE (BACKEND, "Realizing main stage");
is_offscreen = is_fullscreen = FALSE;
g_object_get (stage_sdl->wrapper,
"offscreen", &is_offscreen,
"fullscreen-set", &is_fullscreen,
NULL);
if (G_LIKELY (!is_offscreen))
{
gint flags = SDL_OPENGL;
if (is_fullscreen)
flags |= SDL_FULLSCREEN;
SDL_GL_SetAttribute (SDL_GL_ACCUM_RED_SIZE, 0);
SDL_GL_SetAttribute (SDL_GL_ACCUM_GREEN_SIZE, 0);
SDL_GL_SetAttribute (SDL_GL_ACCUM_BLUE_SIZE, 0);
SDL_GL_SetAttribute (SDL_GL_ACCUM_ALPHA_SIZE, 0);
if (SDL_SetVideoMode (stage_sdl->win_width,
stage_sdl->win_height,
0, flags) == NULL)
{
CLUTTER_NOTE (BACKEND, "SDL appears not to handle this mode - %s",
SDL_GetError ());
CLUTTER_ACTOR_UNSET_FLAGS (actor, CLUTTER_ACTOR_REALIZED);
return;
}
}
else
{
/* FIXME */
g_critical ("SDL Backend does not yet support offscreen rendering");
CLUTTER_ACTOR_UNSET_FLAGS (actor, CLUTTER_ACTOR_REALIZED);
}
}
static void
clutter_stage_sdl_get_preferred_width (ClutterActor *self,
gfloat for_height,
gfloat *min_width_p,
gfloat *natural_width_p)
{
ClutterStageSDL *stage_sdl = CLUTTER_STAGE_SDL (self);
if (min_width_p)
*min_width_p = CLUTTER_UNITS_FROM_DEVICE (stage_sdl->win_width);
if (natural_width_p)
*natural_width_p = CLUTTER_UNITS_FROM_DEVICE (stage_sdl->win_width);
}
static void
clutter_stage_sdl_get_preferred_height (ClutterActor *self,
gfloat for_width,
gfloat *min_height_p,
gfloat *natural_height_p)
{
ClutterStageSDL *stage_sdl = CLUTTER_STAGE_SDL (self);
if (min_height_p)
*min_height_p = CLUTTER_UNITS_FROM_DEVICE (stage_sdl->win_height);
if (natural_height_p)
*natural_height_p = CLUTTER_UNITS_FROM_DEVICE (stage_sdl->win_height);
}
static void
clutter_stage_sdl_allocate (ClutterActor *self,
const ClutterActorBox *box,
ClutterAllocationFlags flags)
{
ClutterStageSDL *stage_sdl = CLUTTER_STAGE_SDL (self);
gint new_width, new_height;
ClutterActorClass *parent_class;
/* FIXME: some how have X configure_notfiy call this ? */
new_width = ABS (CLUTTER_UNITS_TO_INT (box->x2 - box->x1));
new_height = ABS (CLUTTER_UNITS_TO_INT (box->y2 - box->y1));
if (new_width != stage_sdl->win_width ||
new_height != stage_sdl->win_height)
{
if (SDL_SetVideoMode(new_width,
new_height,
0, SDL_OPENGL) == NULL)
{
/* Failed */
return;
}
stage_sdl->win_width = new_width;
stage_sdl->win_height = new_height;
CLUTTER_SET_PRIVATE_FLAGS (self, CLUTTER_ACTOR_SYNC_MATRICES);
}
parent_class = CLUTTER_ACTOR_CLASS (clutter_stage_sdl_parent_class);
parent_class->allocate (self, box, flags);
}
static void
clutter_stage_sdl_set_fullscreen (ClutterStageWindow *stage_window,
gboolean fullscreen)
{
ClutterStageSDL *stage_sdl = CLUTTER_STAGE_SDL (stage_window);
int flags = SDL_OPENGL;
if (fullscreen)
flags |= SDL_FULLSCREEN;
SDL_SetVideoMode (stage_sdl->win_width,
stage_sdl->win_height,
0, flags);
}
static void
clutter_stage_sdl_set_cursor_visible (ClutterStageWindow *stage_window,
gboolean show_cursor)
{
SDL_ShowCursor (show_cursor);
}
static void
clutter_stage_sdl_set_title (ClutterStageWindow *stage_window,
const gchar *title)
{
SDL_WM_SetCaption (title, NULL);
}
static void
clutter_stage_sdl_dispose (GObject *gobject)
{
ClutterStageSDL *stage_sdl = CLUTTER_STAGE_SDL (gobject);
G_OBJECT_CLASS (clutter_stage_sdl_parent_class)->dispose (gobject);
}
static void
clutter_stage_sdl_class_init (ClutterStageSDLClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
gobject_class->dispose = clutter_stage_sdl_dispose;
actor_class->show = clutter_stage_sdl_show;
actor_class->hide = clutter_stage_sdl_hide;
actor_class->realize = clutter_stage_sdl_realize;
actor_class->unrealize = clutter_stage_sdl_unrealize;
actor_class->get_preferred_width = clutter_stage_sdl_get_preferred_width;
actor_class->get_preferred_height = clutter_stage_sdl_get_preferred_height;
actor_class->allocate = clutter_stage_sdl_allocate;
}
static void
clutter_stage_window_iface_init (ClutterStageWindowIface *iface)
{
iface->set_fullscreen = clutter_stage_sdl_set_fullscreen;
iface->set_cursor_visible = clutter_stage_sdl_set_cursor_visible;
iface->set_title = clutter_stage_sdl_set_title;
}
static void
clutter_stage_sdl_init (ClutterStageSDL *stage)
{
stage->win_width = 640;
stage->win_height = 480;
}