mirror of
https://github.com/brl/mutter.git
synced 2024-12-23 11:32:04 +00:00
OSX: add multistage support
Bug #911 - OSX: add multistage support * clutter/osx/clutter-backend-osx.{c,h} (clutter_backend_osx_init_stage, clutter_backend_osx_get_stage, clutter_backend_osx_redraw, clutter_backend_osx_create_stage, clutter_backend_osx_ensure_context, clutter_backend_osx_class_init, clutter_backend_osx_dispose, ClutterGLView:drawRect:): * clutter/osx/clutter-stage-osx.{c,h} (clutter_stage_osx_realize, ClutterGLWindow:setFrameSize:): Adapt to new multistage backend API. Don't keep a pointer to default stage. Derive from ClutterActor instead of ClutterStage. Implement ClutterStageWindow interface. Paint, resize and otherwise manipulate the wrapper rather than self when necessary. (clutter_backend_post_parse): Create our singleton GL context here. We could probably create the context when the default stage is created, but I think this is more clean. * clutter/osx/clutter-event-osx.c (clutter_event_osx_translate) * clutter/osx/clutter-stage-osx.c (clutter_stage_osx_state_update, ClutterGLWindow:windowShouldClose:): * clutter/osx/clutter-stage-osx.h: Export ClutterGLWindow interface for clutter-event-osx.c to easily get the stage for NSWindow. Fill in ClutterEventAny::stage on our events. Consistently use 'stage_osx' and 'wrapper' as variable names when referring to ClutterStageOSX and ClutterStage objects respectively.
This commit is contained in:
parent
cba23c0b26
commit
b8e8a80a40
27
ChangeLog
27
ChangeLog
@ -1,3 +1,30 @@
|
||||
2008-06-05 Tommi Komulainen <tommi.komulainen@iki.fi>
|
||||
|
||||
Bug #911 - OSX: add multistage support
|
||||
|
||||
* clutter/osx/clutter-backend-osx.{c,h}
|
||||
(clutter_backend_osx_init_stage, clutter_backend_osx_get_stage,
|
||||
clutter_backend_osx_redraw, clutter_backend_osx_create_stage,
|
||||
clutter_backend_osx_ensure_context, clutter_backend_osx_class_init,
|
||||
clutter_backend_osx_dispose, ClutterGLView:drawRect:):
|
||||
* clutter/osx/clutter-stage-osx.{c,h} (clutter_stage_osx_realize,
|
||||
ClutterGLWindow:setFrameSize:):
|
||||
Adapt to new multistage backend API. Don't keep a pointer to
|
||||
default stage. Derive from ClutterActor instead of ClutterStage.
|
||||
Implement ClutterStageWindow interface. Paint, resize and
|
||||
otherwise manipulate the wrapper rather than self when necessary.
|
||||
|
||||
(clutter_backend_post_parse): Create our singleton GL context
|
||||
here. We could probably create the context when the default
|
||||
stage is created, but I think this is more clean.
|
||||
|
||||
* clutter/osx/clutter-event-osx.c (clutter_event_osx_translate)
|
||||
* clutter/osx/clutter-stage-osx.c (clutter_stage_osx_state_update,
|
||||
ClutterGLWindow:windowShouldClose:):
|
||||
* clutter/osx/clutter-stage-osx.h: Export ClutterGLWindow interface
|
||||
for clutter-event-osx.c to easily get the stage for NSWindow.
|
||||
Fill in ClutterEventAny::stage on our events.
|
||||
|
||||
2008-06-05 Tommi Komulainen <tommi.komulainen@iki.fi>
|
||||
|
||||
Bug #910 - OSX: missing memory pool
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* Clutter - An OpenGL based 'interactive canvas' library.
|
||||
* OSX backend - initial entry point
|
||||
*
|
||||
* Copyright (C) 2007 Tommi Komulainen <tommi.komulainen@iki.fi>
|
||||
* Copyright (C) 2007-2008 Tommi Komulainen <tommi.komulainen@iki.fi>
|
||||
* Copyright (C) 2007 OpenedHand Ltd.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
@ -36,6 +36,8 @@ static gboolean
|
||||
clutter_backend_osx_post_parse (ClutterBackend *backend,
|
||||
GError **error)
|
||||
{
|
||||
ClutterBackendOSX *self = CLUTTER_BACKEND_OSX (backend);
|
||||
|
||||
CLUTTER_NOTE (BACKEND, "post_parse");
|
||||
|
||||
CLUTTER_OSX_POOL_ALLOC();
|
||||
@ -53,40 +55,8 @@ clutter_backend_osx_post_parse (ClutterBackend *backend,
|
||||
|
||||
[NSApplication sharedApplication];
|
||||
|
||||
/* Initialize(?) OpenGL -- without this glGetString crashes
|
||||
*
|
||||
* Program received signal EXC_BAD_ACCESS, Could not access memory.
|
||||
* Reason: KERN_PROTECTION_FAILURE at address: 0x00000ac0
|
||||
* 0x92b22b2f in glGetString ()
|
||||
*/
|
||||
[NSOpenGLView defaultPixelFormat];
|
||||
|
||||
CLUTTER_OSX_POOL_RELEASE();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static ClutterFeatureFlags
|
||||
clutter_backend_osx_get_features (ClutterBackend *backend)
|
||||
{
|
||||
return CLUTTER_FEATURE_STAGE_USER_RESIZE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
clutter_backend_osx_init_stage (ClutterBackend *backend,
|
||||
GError **error)
|
||||
{
|
||||
ClutterBackendOSX *self = CLUTTER_BACKEND_OSX (backend);
|
||||
ClutterActor *stage;
|
||||
|
||||
CLUTTER_NOTE (BACKEND, "init_stage");
|
||||
|
||||
CLUTTER_OSX_POOL_ALLOC();
|
||||
|
||||
g_assert (self->stage == NULL);
|
||||
|
||||
/* Allocate ourselves a GL context. We need one this early for clutter to
|
||||
* manage textures.
|
||||
/* Allocate ourselves a GL context. Since we're supposed to have only one per
|
||||
* backend we can just as well create it now.
|
||||
*/
|
||||
NSOpenGLPixelFormatAttribute attrs[] = {
|
||||
NSOpenGLPFADoubleBuffer,
|
||||
@ -96,16 +66,42 @@ clutter_backend_osx_init_stage (ClutterBackend *backend,
|
||||
self->context = [[NSOpenGLContext alloc]
|
||||
initWithFormat: self->pixel_format
|
||||
shareContext: nil];
|
||||
[self->context makeCurrentContext];
|
||||
|
||||
stage = clutter_stage_osx_new (backend);
|
||||
self->stage = g_object_ref_sink (stage);
|
||||
/* Enable vblank sync - http://developer.apple.com/qa/qa2007/qa1521.html*/
|
||||
const long sw = 1;
|
||||
[self->context setValues:&sw forParameter: NSOpenGLCPSwapInterval];
|
||||
|
||||
CLUTTER_OSX_POOL_RELEASE();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static ClutterFeatureFlags
|
||||
clutter_backend_osx_get_features (ClutterBackend *backend)
|
||||
{
|
||||
return CLUTTER_FEATURE_STAGE_MULTIPLE|CLUTTER_FEATURE_STAGE_USER_RESIZE;
|
||||
}
|
||||
|
||||
static ClutterActor*
|
||||
clutter_backend_osx_create_stage (ClutterBackend *backend,
|
||||
ClutterStage *wrapper,
|
||||
GError **error)
|
||||
{
|
||||
ClutterActor *impl;
|
||||
|
||||
CLUTTER_NOTE (BACKEND, "create_stage: wrapper=%p", wrapper);
|
||||
|
||||
CLUTTER_OSX_POOL_ALLOC();
|
||||
|
||||
impl = clutter_stage_osx_new (backend, wrapper);
|
||||
|
||||
CLUTTER_NOTE (BACKEND, "create_stage: impl=%p", impl);
|
||||
|
||||
CLUTTER_OSX_POOL_RELEASE();
|
||||
|
||||
return impl;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_backend_osx_init_events (ClutterBackend *backend)
|
||||
{
|
||||
@ -114,21 +110,41 @@ clutter_backend_osx_init_events (ClutterBackend *backend)
|
||||
_clutter_events_osx_init ();
|
||||
}
|
||||
|
||||
static ClutterActor *
|
||||
clutter_backend_osx_get_stage (ClutterBackend *backend)
|
||||
static void
|
||||
clutter_backend_osx_ensure_context (ClutterBackend *backend,
|
||||
ClutterStage *wrapper)
|
||||
{
|
||||
ClutterBackendOSX *self = CLUTTER_BACKEND_OSX (backend);
|
||||
ClutterBackendOSX *backend_osx = CLUTTER_BACKEND_OSX (backend);
|
||||
|
||||
return self->stage;
|
||||
CLUTTER_NOTE (BACKEND, "ensure_context: wrapper=%p", wrapper);
|
||||
|
||||
CLUTTER_OSX_POOL_ALLOC();
|
||||
|
||||
if (wrapper)
|
||||
{
|
||||
ClutterStageWindow *impl = _clutter_stage_get_window (wrapper);
|
||||
ClutterStageOSX *stage_osx;
|
||||
|
||||
g_assert (CLUTTER_IS_STAGE_OSX (impl));
|
||||
stage_osx = CLUTTER_STAGE_OSX (impl);
|
||||
|
||||
[backend_osx->context setView:stage_osx->view];
|
||||
[backend_osx->context makeCurrentContext];
|
||||
}
|
||||
else
|
||||
{
|
||||
[backend_osx->context clearDrawable];
|
||||
[NSOpenGLContext clearCurrentContext];
|
||||
}
|
||||
|
||||
CLUTTER_OSX_POOL_RELEASE();
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_backend_osx_redraw (ClutterBackend *backend)
|
||||
clutter_backend_osx_redraw (ClutterBackend *backend, ClutterStage *wrapper)
|
||||
{
|
||||
ClutterBackendOSX *self = CLUTTER_BACKEND_OSX (backend);
|
||||
ClutterStageOSX *stage_osx;
|
||||
|
||||
stage_osx = CLUTTER_STAGE_OSX (self->stage);
|
||||
ClutterStageWindow *impl = _clutter_stage_get_window (wrapper);
|
||||
ClutterStageOSX *stage_osx = CLUTTER_STAGE_OSX (impl);
|
||||
|
||||
CLUTTER_OSX_POOL_ALLOC();
|
||||
|
||||
@ -149,12 +165,7 @@ clutter_backend_osx_dispose (GObject *object)
|
||||
{
|
||||
ClutterBackendOSX *self = CLUTTER_BACKEND_OSX (object);
|
||||
|
||||
if (self->stage)
|
||||
{
|
||||
CLUTTER_UNSET_PRIVATE_FLAGS (self->stage, CLUTTER_ACTOR_IS_TOPLEVEL);
|
||||
clutter_actor_destroy (self->stage);
|
||||
self->stage = NULL;
|
||||
}
|
||||
_clutter_shader_release_all ();
|
||||
|
||||
[self->context release];
|
||||
self->context = NULL;
|
||||
@ -162,7 +173,6 @@ clutter_backend_osx_dispose (GObject *object)
|
||||
[self->pixel_format release];
|
||||
self->pixel_format = NULL;
|
||||
|
||||
|
||||
G_OBJECT_CLASS (clutter_backend_osx_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
@ -176,9 +186,9 @@ clutter_backend_osx_class_init (ClutterBackendOSXClass *klass)
|
||||
|
||||
backend_class->post_parse = clutter_backend_osx_post_parse;
|
||||
backend_class->get_features = clutter_backend_osx_get_features;
|
||||
backend_class->init_stage = clutter_backend_osx_init_stage;
|
||||
backend_class->create_stage = clutter_backend_osx_create_stage;
|
||||
backend_class->ensure_context = clutter_backend_osx_ensure_context;
|
||||
backend_class->init_events = clutter_backend_osx_init_events;
|
||||
backend_class->get_stage = clutter_backend_osx_get_stage;
|
||||
backend_class->redraw = clutter_backend_osx_redraw;
|
||||
}
|
||||
|
||||
|
@ -44,8 +44,6 @@ struct _ClutterBackendOSX
|
||||
|
||||
NSOpenGLPixelFormat *pixel_format;
|
||||
NSOpenGLContext *context;
|
||||
|
||||
ClutterActor *stage;
|
||||
};
|
||||
|
||||
struct _ClutterBackendOSXClass
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* Clutter - An OpenGL based 'interactive canvas' library.
|
||||
* OSX backend - event loops integration
|
||||
*
|
||||
* Copyright (C) 2007 Tommi Komulainen <tommi.komulainen@iki.fi>
|
||||
* Copyright (C) 2007-2008 Tommi Komulainen <tommi.komulainen@iki.fi>
|
||||
* Copyright (C) 2007 OpenedHand Ltd.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
@ -22,6 +22,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#include "clutter-osx.h"
|
||||
#include "clutter-stage-osx.h"
|
||||
|
||||
#import <AppKit/AppKit.h>
|
||||
#include <glib/gmain.h>
|
||||
@ -37,6 +38,7 @@ static GPollFunc old_poll_func = NULL;
|
||||
|
||||
/*************************************************************************/
|
||||
@interface NSEvent (Clutter)
|
||||
- (ClutterStage*)clutterStage;
|
||||
- (gint)clutterTime;
|
||||
- (gint)clutterButton;
|
||||
- (void)clutterX:(gint*)ptrX y:(gint*)ptrY;
|
||||
@ -45,6 +47,16 @@ static GPollFunc old_poll_func = NULL;
|
||||
@end
|
||||
|
||||
@implementation NSEvent (Clutter)
|
||||
- (ClutterStage*)clutterStage
|
||||
{
|
||||
ClutterGLWindow *w = (ClutterGLWindow*)[self window];
|
||||
if (![w isKindOfClass:[ClutterGLWindow class]])
|
||||
return NULL;
|
||||
|
||||
ClutterStageOSX *stage_osx = w->stage_osx;
|
||||
return stage_osx->wrapper;
|
||||
}
|
||||
|
||||
- (gint)clutterTime
|
||||
{
|
||||
return [self timestamp] * 1000;
|
||||
@ -160,6 +172,7 @@ static GPollFunc old_poll_func = NULL;
|
||||
static gboolean
|
||||
clutter_event_osx_translate (NSEvent *nsevent, ClutterEvent *event)
|
||||
{
|
||||
event->any.stage = [nsevent clutterStage];
|
||||
event->any.time = [nsevent clutterTime];
|
||||
|
||||
switch ([nsevent type])
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* Clutter - An OpenGL based 'interactive canvas' library.
|
||||
* OSX backend - integration with NSWindow and NSView
|
||||
*
|
||||
* Copyright (C) 2007 Tommi Komulainen <tommi.komulainen@iki.fi>
|
||||
* Copyright (C) 2007-2008 Tommi Komulainen <tommi.komulainen@iki.fi>
|
||||
* Copyright (C) 2007 OpenedHand Ltd.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
@ -29,7 +29,11 @@
|
||||
#include <clutter/clutter-debug.h>
|
||||
#include <clutter/clutter-private.h>
|
||||
|
||||
G_DEFINE_TYPE (ClutterStageOSX, clutter_stage_osx, CLUTTER_TYPE_STAGE)
|
||||
static void clutter_stage_window_iface_init (ClutterStageWindowIface *iface);
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (ClutterStageOSX, clutter_stage_osx, CLUTTER_TYPE_ACTOR,
|
||||
G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_STAGE_WINDOW,
|
||||
clutter_stage_window_iface_init))
|
||||
|
||||
/* FIXME: this should be in clutter-stage.c */
|
||||
static void
|
||||
@ -40,12 +44,6 @@ clutter_stage_osx_state_update (ClutterStageOSX *self,
|
||||
#define CLUTTER_OSX_FULLSCREEN_WINDOW_LEVEL (NSMainMenuWindowLevel + 1)
|
||||
|
||||
/*************************************************************************/
|
||||
@interface ClutterGLWindow : NSWindow
|
||||
{
|
||||
ClutterStageOSX *stage;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation ClutterGLWindow
|
||||
- (id)initWithView:(NSView *)aView UTF8Title:(const char *)aTitle stage:(ClutterStageOSX *)aStage
|
||||
{
|
||||
@ -58,17 +56,18 @@ clutter_stage_osx_state_update (ClutterStageOSX *self,
|
||||
[self useOptimizedDrawing: YES];
|
||||
[self setContentView: aView];
|
||||
[self setTitle:[NSString stringWithUTF8String: aTitle ? aTitle : ""]];
|
||||
stage = aStage;
|
||||
self->stage_osx = aStage;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (BOOL) windowShouldClose: (id) sender
|
||||
{
|
||||
CLUTTER_NOTE (BACKEND, "windowShouldClose");
|
||||
CLUTTER_NOTE (BACKEND, "[%p] windowShouldClose", self->stage_osx);
|
||||
|
||||
ClutterEvent event;
|
||||
event.type = CLUTTER_DELETE;
|
||||
event.any.stage = CLUTTER_STAGE (self->stage_osx->wrapper);
|
||||
clutter_event_put (&event);
|
||||
|
||||
return NO;
|
||||
@ -85,55 +84,50 @@ clutter_stage_osx_state_update (ClutterStageOSX *self,
|
||||
|
||||
- (void) windowDidBecomeKey:(NSNotification*)aNotification
|
||||
{
|
||||
CLUTTER_NOTE (BACKEND, "windowDidBecomeKey");
|
||||
CLUTTER_NOTE (BACKEND, "[%p] windowDidBecomeKey", self->stage_osx);
|
||||
|
||||
if (stage->stage_state & CLUTTER_STAGE_STATE_FULLSCREEN)
|
||||
if (self->stage_osx->stage_state & CLUTTER_STAGE_STATE_FULLSCREEN)
|
||||
[self setLevel: CLUTTER_OSX_FULLSCREEN_WINDOW_LEVEL];
|
||||
|
||||
clutter_stage_osx_state_update (stage, 0, CLUTTER_STAGE_STATE_ACTIVATED);
|
||||
clutter_stage_osx_state_update (self->stage_osx, 0, CLUTTER_STAGE_STATE_ACTIVATED);
|
||||
}
|
||||
|
||||
- (void) windowDidResignKey:(NSNotification*)aNotification
|
||||
{
|
||||
CLUTTER_NOTE (BACKEND, "windowDidResignKey");
|
||||
CLUTTER_NOTE (BACKEND, "[%p] windowDidResignKey", self->stage_osx);
|
||||
|
||||
if (stage->stage_state & CLUTTER_STAGE_STATE_FULLSCREEN)
|
||||
if (self->stage_osx->stage_state & CLUTTER_STAGE_STATE_FULLSCREEN)
|
||||
{
|
||||
[self setLevel: NSNormalWindowLevel];
|
||||
[self orderBack: nil];
|
||||
}
|
||||
|
||||
clutter_stage_osx_state_update (stage, CLUTTER_STAGE_STATE_ACTIVATED, 0);
|
||||
clutter_stage_osx_state_update (self->stage_osx, CLUTTER_STAGE_STATE_ACTIVATED, 0);
|
||||
}
|
||||
@end
|
||||
|
||||
/*************************************************************************/
|
||||
@interface ClutterGLView : NSOpenGLView
|
||||
{
|
||||
ClutterActor *stage;
|
||||
ClutterStageOSX *stage_osx;
|
||||
}
|
||||
- (void) drawRect: (NSRect) bounds;
|
||||
@end
|
||||
|
||||
@implementation ClutterGLView
|
||||
- (id) initWithFrame: (NSRect)aFrame pixelFormat:(NSOpenGLPixelFormat*)aFormat stage:(ClutterActor*)aStage
|
||||
- (id) initWithFrame: (NSRect)aFrame pixelFormat:(NSOpenGLPixelFormat*)aFormat stage:(ClutterStageOSX*)aStage
|
||||
{
|
||||
long sw = 1;
|
||||
|
||||
if ((self = [super initWithFrame:aFrame pixelFormat:aFormat]) != nil)
|
||||
{
|
||||
self->stage = aStage;
|
||||
self->stage_osx = aStage;
|
||||
}
|
||||
|
||||
/* Enable vblank sync - http://developer.apple.com/qa/qa2007/qa1521.html*/
|
||||
[[self openGLContext] setValues:&sw forParameter: NSOpenGLCPSwapInterval];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) drawRect: (NSRect) bounds
|
||||
{
|
||||
clutter_actor_paint (self->stage);
|
||||
clutter_actor_paint (CLUTTER_ACTOR (self->stage_osx->wrapper));
|
||||
[[self openGLContext] flushBuffer];
|
||||
}
|
||||
|
||||
@ -151,14 +145,15 @@ clutter_stage_osx_state_update (ClutterStageOSX *self,
|
||||
|
||||
- (void) setFrameSize: (NSSize) aSize
|
||||
{
|
||||
CLUTTER_NOTE (BACKEND, "setFrameSize: %dx%d",
|
||||
CLUTTER_NOTE (BACKEND, "[%p] setFrameSize: %dx%d", self->stage_osx,
|
||||
(int)aSize.width, (int)aSize.height);
|
||||
|
||||
[super setFrameSize: aSize];
|
||||
|
||||
clutter_actor_set_size (self->stage, (int)aSize.width, (int)aSize.height);
|
||||
clutter_actor_set_size (CLUTTER_ACTOR (self->stage_osx->wrapper),
|
||||
(int)aSize.width, (int)aSize.height);
|
||||
|
||||
CLUTTER_SET_PRIVATE_FLAGS(self->stage, CLUTTER_ACTOR_SYNC_MATRICES);
|
||||
CLUTTER_SET_PRIVATE_FLAGS(self->stage_osx->wrapper, CLUTTER_ACTOR_SYNC_MATRICES);
|
||||
}
|
||||
|
||||
/* Simply forward all events that reach our view to clutter. */
|
||||
@ -209,6 +204,7 @@ clutter_stage_osx_state_update (ClutterStageOSX *self,
|
||||
self->stage_state = event.new_state;
|
||||
|
||||
event.type = CLUTTER_STAGE_STATE;
|
||||
event.stage = CLUTTER_STAGE (self->wrapper);
|
||||
clutter_event_put ((ClutterEvent*)&event);
|
||||
}
|
||||
|
||||
@ -263,11 +259,14 @@ clutter_stage_osx_realize (ClutterActor *actor)
|
||||
ClutterBackendOSX *backend_osx;
|
||||
gboolean offscreen;
|
||||
|
||||
CLUTTER_NOTE (BACKEND, "realize");
|
||||
CLUTTER_NOTE (BACKEND, "[%p] realize", self);
|
||||
|
||||
/* ensure we get realize+unrealize properly paired */
|
||||
g_return_if_fail (self->view == NULL && self->window == NULL);
|
||||
|
||||
CLUTTER_OSX_POOL_ALLOC();
|
||||
|
||||
g_object_get (actor, "offscreen", &offscreen, NULL);
|
||||
g_object_get (self->wrapper, "offscreen", &offscreen, NULL);
|
||||
|
||||
if (offscreen)
|
||||
{
|
||||
@ -276,9 +275,6 @@ clutter_stage_osx_realize (ClutterActor *actor)
|
||||
return;
|
||||
}
|
||||
|
||||
if (CLUTTER_ACTOR_CLASS (clutter_stage_osx_parent_class)->realize)
|
||||
CLUTTER_ACTOR_CLASS (clutter_stage_osx_parent_class)->realize (actor);
|
||||
|
||||
backend_osx = CLUTTER_BACKEND_OSX (self->backend);
|
||||
|
||||
NSRect rect = NSMakeRect(0, 0, self->requisition_width, self->requisition_height);
|
||||
@ -286,28 +282,23 @@ clutter_stage_osx_realize (ClutterActor *actor)
|
||||
self->view = [[ClutterGLView alloc]
|
||||
initWithFrame: rect
|
||||
pixelFormat: backend_osx->pixel_format
|
||||
stage: actor];
|
||||
stage: self];
|
||||
[self->view setOpenGLContext:backend_osx->context];
|
||||
|
||||
self->window = [[ClutterGLWindow alloc]
|
||||
initWithView: self->view
|
||||
UTF8Title: clutter_stage_get_title (CLUTTER_STAGE (self))
|
||||
UTF8Title: clutter_stage_get_title (CLUTTER_STAGE (self->wrapper))
|
||||
stage: self];
|
||||
|
||||
/* looks better than positioning to 0,0 (bottom right) */
|
||||
[self->window center];
|
||||
|
||||
/* To not miss all textures created with the context created in the backend
|
||||
* make sure we share the context. (By default NSOpenGLView creates its own
|
||||
* context.)
|
||||
*/
|
||||
NSOpenGLContext *context = backend_osx->context;
|
||||
|
||||
[self->view setOpenGLContext: context];
|
||||
[context setView: self->view];
|
||||
|
||||
|
||||
CLUTTER_OSX_POOL_RELEASE();
|
||||
|
||||
/* FIXME: ClutterStage:realize is using the class pointer directly rather
|
||||
* than clutter_actor_realize which would set the REALIZED flag for us.
|
||||
*/
|
||||
CLUTTER_ACTOR_SET_FLAGS(self, CLUTTER_ACTOR_REALIZED);
|
||||
CLUTTER_SET_PRIVATE_FLAGS(self, CLUTTER_ACTOR_SYNC_MATRICES);
|
||||
}
|
||||
|
||||
@ -316,7 +307,10 @@ clutter_stage_osx_unrealize (ClutterActor *actor)
|
||||
{
|
||||
ClutterStageOSX *self = CLUTTER_STAGE_OSX (actor);
|
||||
|
||||
CLUTTER_NOTE (BACKEND, "unrealize");
|
||||
CLUTTER_NOTE (BACKEND, "[%p] unrealize", self);
|
||||
|
||||
/* ensure we get realize+unrealize properly paired */
|
||||
g_return_if_fail (self->view != NULL && self->window != NULL);
|
||||
|
||||
CLUTTER_OSX_POOL_ALLOC();
|
||||
|
||||
@ -328,8 +322,7 @@ clutter_stage_osx_unrealize (ClutterActor *actor)
|
||||
|
||||
CLUTTER_OSX_POOL_RELEASE();
|
||||
|
||||
if (CLUTTER_ACTOR_CLASS (clutter_stage_osx_parent_class)->unrealize)
|
||||
CLUTTER_ACTOR_CLASS (clutter_stage_osx_parent_class)->unrealize (actor);
|
||||
CLUTTER_ACTOR_UNSET_FLAGS (actor, CLUTTER_ACTOR_REALIZED);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -337,13 +330,13 @@ clutter_stage_osx_show (ClutterActor *actor)
|
||||
{
|
||||
ClutterStageOSX *self = CLUTTER_STAGE_OSX (actor);
|
||||
|
||||
CLUTTER_NOTE (BACKEND, "show");
|
||||
|
||||
CLUTTER_ACTOR_SET_FLAGS (actor, CLUTTER_ACTOR_MAPPED);
|
||||
CLUTTER_NOTE (BACKEND, "[%p] show", self);
|
||||
|
||||
if (CLUTTER_ACTOR_CLASS (clutter_stage_osx_parent_class)->show)
|
||||
CLUTTER_ACTOR_CLASS (clutter_stage_osx_parent_class)->show (actor);
|
||||
|
||||
CLUTTER_ACTOR_SET_FLAGS (actor, CLUTTER_ACTOR_MAPPED);
|
||||
|
||||
CLUTTER_OSX_POOL_ALLOC();
|
||||
|
||||
clutter_stage_osx_set_frame (self);
|
||||
@ -358,7 +351,7 @@ clutter_stage_osx_hide (ClutterActor *actor)
|
||||
{
|
||||
ClutterStageOSX *self = CLUTTER_STAGE_OSX (actor);
|
||||
|
||||
CLUTTER_NOTE (BACKEND, "hide");
|
||||
CLUTTER_NOTE (BACKEND, "[%p] hide", self);
|
||||
|
||||
CLUTTER_OSX_POOL_ALLOC();
|
||||
|
||||
@ -394,7 +387,7 @@ clutter_stage_osx_request_coords (ClutterActor *actor,
|
||||
{
|
||||
ClutterStageOSX *self = CLUTTER_STAGE_OSX (actor);
|
||||
|
||||
CLUTTER_NOTE (BACKEND, "request_coords: %d,%d %dx%d",
|
||||
CLUTTER_NOTE (BACKEND, "[%p], request_coords: %d,%d %dx%d", self,
|
||||
CLUTTER_UNITS_TO_INT (box->x1),
|
||||
CLUTTER_UNITS_TO_INT (box->y1),
|
||||
CLUTTER_UNITS_TO_INT (box->x2 - box->x1),
|
||||
@ -416,29 +409,37 @@ clutter_stage_osx_request_coords (ClutterActor *actor,
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
static void
|
||||
clutter_stage_osx_set_title (ClutterStage *stage,
|
||||
const char *title)
|
||||
static ClutterActor *
|
||||
clutter_stage_osx_get_wrapper (ClutterStageWindow *stage_window)
|
||||
{
|
||||
ClutterStageOSX *self = CLUTTER_STAGE_OSX (stage);
|
||||
ClutterStageOSX *self = CLUTTER_STAGE_OSX (stage_window);
|
||||
|
||||
CLUTTER_NOTE (BACKEND, "set_title: %s", title);
|
||||
return CLUTTER_ACTOR (self->wrapper);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_stage_osx_set_title (ClutterStageWindow *stage_window,
|
||||
const char *title)
|
||||
{
|
||||
ClutterStageOSX *self = CLUTTER_STAGE_OSX (stage_window);
|
||||
|
||||
CLUTTER_NOTE (BACKEND, "[%p] set_title: %s", self, title);
|
||||
|
||||
CLUTTER_OSX_POOL_ALLOC();
|
||||
|
||||
if (CLUTTER_ACTOR_IS_REALIZED (CLUTTER_ACTOR (stage)))
|
||||
if (CLUTTER_ACTOR_IS_REALIZED (CLUTTER_ACTOR (self)))
|
||||
[self->window setTitle:[NSString stringWithUTF8String: title ? title : ""]];
|
||||
|
||||
CLUTTER_OSX_POOL_RELEASE();
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_stage_osx_set_fullscreen (ClutterStage *stage,
|
||||
gboolean fullscreen)
|
||||
clutter_stage_osx_set_fullscreen (ClutterStageWindow *stage_window,
|
||||
gboolean fullscreen)
|
||||
{
|
||||
ClutterStageOSX *self = CLUTTER_STAGE_OSX (stage);
|
||||
ClutterStageOSX *self = CLUTTER_STAGE_OSX (stage_window);
|
||||
|
||||
CLUTTER_NOTE (BACKEND, "set_fullscreen: %u", fullscreen);
|
||||
CLUTTER_NOTE (BACKEND, "[%p] set_fullscreen: %u", self, fullscreen);
|
||||
|
||||
CLUTTER_OSX_POOL_ALLOC();
|
||||
|
||||
@ -476,14 +477,24 @@ clutter_stage_osx_set_fullscreen (ClutterStage *stage,
|
||||
CLUTTER_OSX_POOL_RELEASE();
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_stage_window_iface_init (ClutterStageWindowIface *iface)
|
||||
{
|
||||
iface->get_wrapper = clutter_stage_osx_get_wrapper;
|
||||
iface->set_title = clutter_stage_osx_set_title;
|
||||
iface->set_fullscreen = clutter_stage_osx_set_fullscreen;
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
ClutterActor *
|
||||
clutter_stage_osx_new (ClutterBackend *backend)
|
||||
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;
|
||||
|
||||
return CLUTTER_ACTOR(self);
|
||||
}
|
||||
@ -495,14 +506,13 @@ clutter_stage_osx_init (ClutterStageOSX *self)
|
||||
self->requisition_width = 640;
|
||||
self->requisition_height = 480;
|
||||
|
||||
CLUTTER_SET_PRIVATE_FLAGS(self, CLUTTER_ACTOR_SYNC_MATRICES);
|
||||
CLUTTER_SET_PRIVATE_FLAGS(self, CLUTTER_ACTOR_IS_TOPLEVEL);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_stage_osx_class_init (ClutterStageOSXClass *klass)
|
||||
{
|
||||
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
|
||||
ClutterStageClass *stage_class = CLUTTER_STAGE_CLASS (klass);
|
||||
|
||||
actor_class->realize = clutter_stage_osx_realize;
|
||||
actor_class->unrealize = clutter_stage_osx_unrealize;
|
||||
@ -511,7 +521,4 @@ clutter_stage_osx_class_init (ClutterStageOSXClass *klass)
|
||||
|
||||
actor_class->query_coords = clutter_stage_osx_query_coords;
|
||||
actor_class->request_coords = clutter_stage_osx_request_coords;
|
||||
|
||||
stage_class->set_title = clutter_stage_osx_set_title;
|
||||
stage_class->set_fullscreen = clutter_stage_osx_set_fullscreen;
|
||||
}
|
||||
|
@ -26,7 +26,7 @@
|
||||
#include <clutter/clutter-backend.h>
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
@class NSOpenGLView, NSWindow;
|
||||
#import <AppKit/AppKit.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@ -41,11 +41,19 @@ G_BEGIN_DECLS
|
||||
typedef struct _ClutterStageOSX ClutterStageOSX;
|
||||
typedef struct _ClutterStageOSXClass ClutterStageOSXClass;
|
||||
|
||||
@interface ClutterGLWindow : NSWindow
|
||||
{
|
||||
@public
|
||||
ClutterStageOSX *stage_osx;
|
||||
}
|
||||
@end
|
||||
|
||||
struct _ClutterStageOSX
|
||||
{
|
||||
ClutterStage parent;
|
||||
ClutterActor parent;
|
||||
|
||||
ClutterBackend *backend;
|
||||
ClutterStage *wrapper;
|
||||
|
||||
NSWindow *window;
|
||||
NSOpenGLView *view;
|
||||
@ -61,12 +69,13 @@ struct _ClutterStageOSX
|
||||
|
||||
struct _ClutterStageOSXClass
|
||||
{
|
||||
ClutterStageClass parent_class;
|
||||
ClutterActorClass parent_class;
|
||||
};
|
||||
|
||||
GType clutter_stage_osx_get_type (void) G_GNUC_CONST;
|
||||
|
||||
ClutterActor* clutter_stage_osx_new (ClutterBackend *backend);
|
||||
ClutterActor* clutter_stage_osx_new (ClutterBackend *backend,
|
||||
ClutterStage *wrapper);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user