#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", &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 CLUTTER_ACTOR_SET_FLAGS (actor, CLUTTER_ACTOR_REALIZED); } 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; }