mirror of
https://github.com/brl/mutter.git
synced 2024-11-23 00:20:42 -05: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>
|
2008-06-05 Tommi Komulainen <tommi.komulainen@iki.fi>
|
||||||
|
|
||||||
Bug #910 - OSX: missing memory pool
|
Bug #910 - OSX: missing memory pool
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* Clutter - An OpenGL based 'interactive canvas' library.
|
/* Clutter - An OpenGL based 'interactive canvas' library.
|
||||||
* OSX backend - initial entry point
|
* 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.
|
* Copyright (C) 2007 OpenedHand Ltd.
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
@ -36,6 +36,8 @@ static gboolean
|
|||||||
clutter_backend_osx_post_parse (ClutterBackend *backend,
|
clutter_backend_osx_post_parse (ClutterBackend *backend,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
|
ClutterBackendOSX *self = CLUTTER_BACKEND_OSX (backend);
|
||||||
|
|
||||||
CLUTTER_NOTE (BACKEND, "post_parse");
|
CLUTTER_NOTE (BACKEND, "post_parse");
|
||||||
|
|
||||||
CLUTTER_OSX_POOL_ALLOC();
|
CLUTTER_OSX_POOL_ALLOC();
|
||||||
@ -53,40 +55,8 @@ clutter_backend_osx_post_parse (ClutterBackend *backend,
|
|||||||
|
|
||||||
[NSApplication sharedApplication];
|
[NSApplication sharedApplication];
|
||||||
|
|
||||||
/* Initialize(?) OpenGL -- without this glGetString crashes
|
/* Allocate ourselves a GL context. Since we're supposed to have only one per
|
||||||
*
|
* backend we can just as well create it now.
|
||||||
* 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.
|
|
||||||
*/
|
*/
|
||||||
NSOpenGLPixelFormatAttribute attrs[] = {
|
NSOpenGLPixelFormatAttribute attrs[] = {
|
||||||
NSOpenGLPFADoubleBuffer,
|
NSOpenGLPFADoubleBuffer,
|
||||||
@ -96,16 +66,42 @@ clutter_backend_osx_init_stage (ClutterBackend *backend,
|
|||||||
self->context = [[NSOpenGLContext alloc]
|
self->context = [[NSOpenGLContext alloc]
|
||||||
initWithFormat: self->pixel_format
|
initWithFormat: self->pixel_format
|
||||||
shareContext: nil];
|
shareContext: nil];
|
||||||
[self->context makeCurrentContext];
|
|
||||||
|
|
||||||
stage = clutter_stage_osx_new (backend);
|
/* Enable vblank sync - http://developer.apple.com/qa/qa2007/qa1521.html*/
|
||||||
self->stage = g_object_ref_sink (stage);
|
const long sw = 1;
|
||||||
|
[self->context setValues:&sw forParameter: NSOpenGLCPSwapInterval];
|
||||||
|
|
||||||
CLUTTER_OSX_POOL_RELEASE();
|
CLUTTER_OSX_POOL_RELEASE();
|
||||||
|
|
||||||
return TRUE;
|
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
|
static void
|
||||||
clutter_backend_osx_init_events (ClutterBackend *backend)
|
clutter_backend_osx_init_events (ClutterBackend *backend)
|
||||||
{
|
{
|
||||||
@ -114,21 +110,41 @@ clutter_backend_osx_init_events (ClutterBackend *backend)
|
|||||||
_clutter_events_osx_init ();
|
_clutter_events_osx_init ();
|
||||||
}
|
}
|
||||||
|
|
||||||
static ClutterActor *
|
static void
|
||||||
clutter_backend_osx_get_stage (ClutterBackend *backend)
|
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
|
static void
|
||||||
clutter_backend_osx_redraw (ClutterBackend *backend)
|
clutter_backend_osx_redraw (ClutterBackend *backend, ClutterStage *wrapper)
|
||||||
{
|
{
|
||||||
ClutterBackendOSX *self = CLUTTER_BACKEND_OSX (backend);
|
ClutterStageWindow *impl = _clutter_stage_get_window (wrapper);
|
||||||
ClutterStageOSX *stage_osx;
|
ClutterStageOSX *stage_osx = CLUTTER_STAGE_OSX (impl);
|
||||||
|
|
||||||
stage_osx = CLUTTER_STAGE_OSX (self->stage);
|
|
||||||
|
|
||||||
CLUTTER_OSX_POOL_ALLOC();
|
CLUTTER_OSX_POOL_ALLOC();
|
||||||
|
|
||||||
@ -149,12 +165,7 @@ clutter_backend_osx_dispose (GObject *object)
|
|||||||
{
|
{
|
||||||
ClutterBackendOSX *self = CLUTTER_BACKEND_OSX (object);
|
ClutterBackendOSX *self = CLUTTER_BACKEND_OSX (object);
|
||||||
|
|
||||||
if (self->stage)
|
_clutter_shader_release_all ();
|
||||||
{
|
|
||||||
CLUTTER_UNSET_PRIVATE_FLAGS (self->stage, CLUTTER_ACTOR_IS_TOPLEVEL);
|
|
||||||
clutter_actor_destroy (self->stage);
|
|
||||||
self->stage = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
[self->context release];
|
[self->context release];
|
||||||
self->context = NULL;
|
self->context = NULL;
|
||||||
@ -162,7 +173,6 @@ clutter_backend_osx_dispose (GObject *object)
|
|||||||
[self->pixel_format release];
|
[self->pixel_format release];
|
||||||
self->pixel_format = NULL;
|
self->pixel_format = NULL;
|
||||||
|
|
||||||
|
|
||||||
G_OBJECT_CLASS (clutter_backend_osx_parent_class)->dispose (object);
|
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->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->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->init_events = clutter_backend_osx_init_events;
|
||||||
backend_class->get_stage = clutter_backend_osx_get_stage;
|
|
||||||
backend_class->redraw = clutter_backend_osx_redraw;
|
backend_class->redraw = clutter_backend_osx_redraw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,8 +44,6 @@ struct _ClutterBackendOSX
|
|||||||
|
|
||||||
NSOpenGLPixelFormat *pixel_format;
|
NSOpenGLPixelFormat *pixel_format;
|
||||||
NSOpenGLContext *context;
|
NSOpenGLContext *context;
|
||||||
|
|
||||||
ClutterActor *stage;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _ClutterBackendOSXClass
|
struct _ClutterBackendOSXClass
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* Clutter - An OpenGL based 'interactive canvas' library.
|
/* Clutter - An OpenGL based 'interactive canvas' library.
|
||||||
* OSX backend - event loops integration
|
* 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.
|
* Copyright (C) 2007 OpenedHand Ltd.
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
@ -22,6 +22,7 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include "clutter-osx.h"
|
#include "clutter-osx.h"
|
||||||
|
#include "clutter-stage-osx.h"
|
||||||
|
|
||||||
#import <AppKit/AppKit.h>
|
#import <AppKit/AppKit.h>
|
||||||
#include <glib/gmain.h>
|
#include <glib/gmain.h>
|
||||||
@ -37,6 +38,7 @@ static GPollFunc old_poll_func = NULL;
|
|||||||
|
|
||||||
/*************************************************************************/
|
/*************************************************************************/
|
||||||
@interface NSEvent (Clutter)
|
@interface NSEvent (Clutter)
|
||||||
|
- (ClutterStage*)clutterStage;
|
||||||
- (gint)clutterTime;
|
- (gint)clutterTime;
|
||||||
- (gint)clutterButton;
|
- (gint)clutterButton;
|
||||||
- (void)clutterX:(gint*)ptrX y:(gint*)ptrY;
|
- (void)clutterX:(gint*)ptrX y:(gint*)ptrY;
|
||||||
@ -45,6 +47,16 @@ static GPollFunc old_poll_func = NULL;
|
|||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation NSEvent (Clutter)
|
@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
|
- (gint)clutterTime
|
||||||
{
|
{
|
||||||
return [self timestamp] * 1000;
|
return [self timestamp] * 1000;
|
||||||
@ -160,6 +172,7 @@ static GPollFunc old_poll_func = NULL;
|
|||||||
static gboolean
|
static gboolean
|
||||||
clutter_event_osx_translate (NSEvent *nsevent, ClutterEvent *event)
|
clutter_event_osx_translate (NSEvent *nsevent, ClutterEvent *event)
|
||||||
{
|
{
|
||||||
|
event->any.stage = [nsevent clutterStage];
|
||||||
event->any.time = [nsevent clutterTime];
|
event->any.time = [nsevent clutterTime];
|
||||||
|
|
||||||
switch ([nsevent type])
|
switch ([nsevent type])
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* Clutter - An OpenGL based 'interactive canvas' library.
|
/* Clutter - An OpenGL based 'interactive canvas' library.
|
||||||
* OSX backend - integration with NSWindow and NSView
|
* 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.
|
* Copyright (C) 2007 OpenedHand Ltd.
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
@ -29,7 +29,11 @@
|
|||||||
#include <clutter/clutter-debug.h>
|
#include <clutter/clutter-debug.h>
|
||||||
#include <clutter/clutter-private.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 */
|
/* FIXME: this should be in clutter-stage.c */
|
||||||
static void
|
static void
|
||||||
@ -40,12 +44,6 @@ clutter_stage_osx_state_update (ClutterStageOSX *self,
|
|||||||
#define CLUTTER_OSX_FULLSCREEN_WINDOW_LEVEL (NSMainMenuWindowLevel + 1)
|
#define CLUTTER_OSX_FULLSCREEN_WINDOW_LEVEL (NSMainMenuWindowLevel + 1)
|
||||||
|
|
||||||
/*************************************************************************/
|
/*************************************************************************/
|
||||||
@interface ClutterGLWindow : NSWindow
|
|
||||||
{
|
|
||||||
ClutterStageOSX *stage;
|
|
||||||
}
|
|
||||||
@end
|
|
||||||
|
|
||||||
@implementation ClutterGLWindow
|
@implementation ClutterGLWindow
|
||||||
- (id)initWithView:(NSView *)aView UTF8Title:(const char *)aTitle stage:(ClutterStageOSX *)aStage
|
- (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 useOptimizedDrawing: YES];
|
||||||
[self setContentView: aView];
|
[self setContentView: aView];
|
||||||
[self setTitle:[NSString stringWithUTF8String: aTitle ? aTitle : ""]];
|
[self setTitle:[NSString stringWithUTF8String: aTitle ? aTitle : ""]];
|
||||||
stage = aStage;
|
self->stage_osx = aStage;
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL) windowShouldClose: (id) sender
|
- (BOOL) windowShouldClose: (id) sender
|
||||||
{
|
{
|
||||||
CLUTTER_NOTE (BACKEND, "windowShouldClose");
|
CLUTTER_NOTE (BACKEND, "[%p] windowShouldClose", self->stage_osx);
|
||||||
|
|
||||||
ClutterEvent event;
|
ClutterEvent event;
|
||||||
event.type = CLUTTER_DELETE;
|
event.type = CLUTTER_DELETE;
|
||||||
|
event.any.stage = CLUTTER_STAGE (self->stage_osx->wrapper);
|
||||||
clutter_event_put (&event);
|
clutter_event_put (&event);
|
||||||
|
|
||||||
return NO;
|
return NO;
|
||||||
@ -85,55 +84,50 @@ clutter_stage_osx_state_update (ClutterStageOSX *self,
|
|||||||
|
|
||||||
- (void) windowDidBecomeKey:(NSNotification*)aNotification
|
- (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];
|
[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
|
- (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 setLevel: NSNormalWindowLevel];
|
||||||
[self orderBack: nil];
|
[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
|
@end
|
||||||
|
|
||||||
/*************************************************************************/
|
/*************************************************************************/
|
||||||
@interface ClutterGLView : NSOpenGLView
|
@interface ClutterGLView : NSOpenGLView
|
||||||
{
|
{
|
||||||
ClutterActor *stage;
|
ClutterStageOSX *stage_osx;
|
||||||
}
|
}
|
||||||
- (void) drawRect: (NSRect) bounds;
|
- (void) drawRect: (NSRect) bounds;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation ClutterGLView
|
@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)
|
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;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) drawRect: (NSRect) bounds
|
- (void) drawRect: (NSRect) bounds
|
||||||
{
|
{
|
||||||
clutter_actor_paint (self->stage);
|
clutter_actor_paint (CLUTTER_ACTOR (self->stage_osx->wrapper));
|
||||||
[[self openGLContext] flushBuffer];
|
[[self openGLContext] flushBuffer];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -151,14 +145,15 @@ clutter_stage_osx_state_update (ClutterStageOSX *self,
|
|||||||
|
|
||||||
- (void) setFrameSize: (NSSize) aSize
|
- (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);
|
(int)aSize.width, (int)aSize.height);
|
||||||
|
|
||||||
[super setFrameSize: aSize];
|
[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. */
|
/* 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;
|
self->stage_state = event.new_state;
|
||||||
|
|
||||||
event.type = CLUTTER_STAGE_STATE;
|
event.type = CLUTTER_STAGE_STATE;
|
||||||
|
event.stage = CLUTTER_STAGE (self->wrapper);
|
||||||
clutter_event_put ((ClutterEvent*)&event);
|
clutter_event_put ((ClutterEvent*)&event);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -263,11 +259,14 @@ clutter_stage_osx_realize (ClutterActor *actor)
|
|||||||
ClutterBackendOSX *backend_osx;
|
ClutterBackendOSX *backend_osx;
|
||||||
gboolean offscreen;
|
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();
|
CLUTTER_OSX_POOL_ALLOC();
|
||||||
|
|
||||||
g_object_get (actor, "offscreen", &offscreen, NULL);
|
g_object_get (self->wrapper, "offscreen", &offscreen, NULL);
|
||||||
|
|
||||||
if (offscreen)
|
if (offscreen)
|
||||||
{
|
{
|
||||||
@ -276,9 +275,6 @@ clutter_stage_osx_realize (ClutterActor *actor)
|
|||||||
return;
|
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);
|
backend_osx = CLUTTER_BACKEND_OSX (self->backend);
|
||||||
|
|
||||||
NSRect rect = NSMakeRect(0, 0, self->requisition_width, self->requisition_height);
|
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]
|
self->view = [[ClutterGLView alloc]
|
||||||
initWithFrame: rect
|
initWithFrame: rect
|
||||||
pixelFormat: backend_osx->pixel_format
|
pixelFormat: backend_osx->pixel_format
|
||||||
stage: actor];
|
stage: self];
|
||||||
|
[self->view setOpenGLContext:backend_osx->context];
|
||||||
|
|
||||||
self->window = [[ClutterGLWindow alloc]
|
self->window = [[ClutterGLWindow alloc]
|
||||||
initWithView: self->view
|
initWithView: self->view
|
||||||
UTF8Title: clutter_stage_get_title (CLUTTER_STAGE (self))
|
UTF8Title: clutter_stage_get_title (CLUTTER_STAGE (self->wrapper))
|
||||||
stage: self];
|
stage: self];
|
||||||
|
|
||||||
/* looks better than positioning to 0,0 (bottom right) */
|
/* looks better than positioning to 0,0 (bottom right) */
|
||||||
[self->window center];
|
[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();
|
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);
|
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);
|
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();
|
CLUTTER_OSX_POOL_ALLOC();
|
||||||
|
|
||||||
@ -328,8 +322,7 @@ clutter_stage_osx_unrealize (ClutterActor *actor)
|
|||||||
|
|
||||||
CLUTTER_OSX_POOL_RELEASE();
|
CLUTTER_OSX_POOL_RELEASE();
|
||||||
|
|
||||||
if (CLUTTER_ACTOR_CLASS (clutter_stage_osx_parent_class)->unrealize)
|
CLUTTER_ACTOR_UNSET_FLAGS (actor, CLUTTER_ACTOR_REALIZED);
|
||||||
CLUTTER_ACTOR_CLASS (clutter_stage_osx_parent_class)->unrealize (actor);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -337,13 +330,13 @@ clutter_stage_osx_show (ClutterActor *actor)
|
|||||||
{
|
{
|
||||||
ClutterStageOSX *self = CLUTTER_STAGE_OSX (actor);
|
ClutterStageOSX *self = CLUTTER_STAGE_OSX (actor);
|
||||||
|
|
||||||
CLUTTER_NOTE (BACKEND, "show");
|
CLUTTER_NOTE (BACKEND, "[%p] show", self);
|
||||||
|
|
||||||
CLUTTER_ACTOR_SET_FLAGS (actor, CLUTTER_ACTOR_MAPPED);
|
|
||||||
|
|
||||||
if (CLUTTER_ACTOR_CLASS (clutter_stage_osx_parent_class)->show)
|
if (CLUTTER_ACTOR_CLASS (clutter_stage_osx_parent_class)->show)
|
||||||
CLUTTER_ACTOR_CLASS (clutter_stage_osx_parent_class)->show (actor);
|
CLUTTER_ACTOR_CLASS (clutter_stage_osx_parent_class)->show (actor);
|
||||||
|
|
||||||
|
CLUTTER_ACTOR_SET_FLAGS (actor, CLUTTER_ACTOR_MAPPED);
|
||||||
|
|
||||||
CLUTTER_OSX_POOL_ALLOC();
|
CLUTTER_OSX_POOL_ALLOC();
|
||||||
|
|
||||||
clutter_stage_osx_set_frame (self);
|
clutter_stage_osx_set_frame (self);
|
||||||
@ -358,7 +351,7 @@ clutter_stage_osx_hide (ClutterActor *actor)
|
|||||||
{
|
{
|
||||||
ClutterStageOSX *self = CLUTTER_STAGE_OSX (actor);
|
ClutterStageOSX *self = CLUTTER_STAGE_OSX (actor);
|
||||||
|
|
||||||
CLUTTER_NOTE (BACKEND, "hide");
|
CLUTTER_NOTE (BACKEND, "[%p] hide", self);
|
||||||
|
|
||||||
CLUTTER_OSX_POOL_ALLOC();
|
CLUTTER_OSX_POOL_ALLOC();
|
||||||
|
|
||||||
@ -394,7 +387,7 @@ clutter_stage_osx_request_coords (ClutterActor *actor,
|
|||||||
{
|
{
|
||||||
ClutterStageOSX *self = CLUTTER_STAGE_OSX (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->x1),
|
||||||
CLUTTER_UNITS_TO_INT (box->y1),
|
CLUTTER_UNITS_TO_INT (box->y1),
|
||||||
CLUTTER_UNITS_TO_INT (box->x2 - box->x1),
|
CLUTTER_UNITS_TO_INT (box->x2 - box->x1),
|
||||||
@ -416,29 +409,37 @@ clutter_stage_osx_request_coords (ClutterActor *actor,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*************************************************************************/
|
/*************************************************************************/
|
||||||
|
static ClutterActor *
|
||||||
|
clutter_stage_osx_get_wrapper (ClutterStageWindow *stage_window)
|
||||||
|
{
|
||||||
|
ClutterStageOSX *self = CLUTTER_STAGE_OSX (stage_window);
|
||||||
|
|
||||||
|
return CLUTTER_ACTOR (self->wrapper);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
clutter_stage_osx_set_title (ClutterStage *stage,
|
clutter_stage_osx_set_title (ClutterStageWindow *stage_window,
|
||||||
const char *title)
|
const char *title)
|
||||||
{
|
{
|
||||||
ClutterStageOSX *self = CLUTTER_STAGE_OSX (stage);
|
ClutterStageOSX *self = CLUTTER_STAGE_OSX (stage_window);
|
||||||
|
|
||||||
CLUTTER_NOTE (BACKEND, "set_title: %s", title);
|
CLUTTER_NOTE (BACKEND, "[%p] set_title: %s", self, title);
|
||||||
|
|
||||||
CLUTTER_OSX_POOL_ALLOC();
|
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 : ""]];
|
[self->window setTitle:[NSString stringWithUTF8String: title ? title : ""]];
|
||||||
|
|
||||||
CLUTTER_OSX_POOL_RELEASE();
|
CLUTTER_OSX_POOL_RELEASE();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
clutter_stage_osx_set_fullscreen (ClutterStage *stage,
|
clutter_stage_osx_set_fullscreen (ClutterStageWindow *stage_window,
|
||||||
gboolean fullscreen)
|
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();
|
CLUTTER_OSX_POOL_ALLOC();
|
||||||
|
|
||||||
@ -476,14 +477,24 @@ clutter_stage_osx_set_fullscreen (ClutterStage *stage,
|
|||||||
CLUTTER_OSX_POOL_RELEASE();
|
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 *
|
ClutterActor *
|
||||||
clutter_stage_osx_new (ClutterBackend *backend)
|
clutter_stage_osx_new (ClutterBackend *backend,
|
||||||
|
ClutterStage *wrapper)
|
||||||
{
|
{
|
||||||
ClutterStageOSX *self;
|
ClutterStageOSX *self;
|
||||||
|
|
||||||
self = g_object_new (CLUTTER_TYPE_STAGE_OSX, NULL);
|
self = g_object_new (CLUTTER_TYPE_STAGE_OSX, NULL);
|
||||||
self->backend = backend;
|
self->backend = backend;
|
||||||
|
self->wrapper = wrapper;
|
||||||
|
|
||||||
return CLUTTER_ACTOR(self);
|
return CLUTTER_ACTOR(self);
|
||||||
}
|
}
|
||||||
@ -495,14 +506,13 @@ clutter_stage_osx_init (ClutterStageOSX *self)
|
|||||||
self->requisition_width = 640;
|
self->requisition_width = 640;
|
||||||
self->requisition_height = 480;
|
self->requisition_height = 480;
|
||||||
|
|
||||||
CLUTTER_SET_PRIVATE_FLAGS(self, CLUTTER_ACTOR_SYNC_MATRICES);
|
CLUTTER_SET_PRIVATE_FLAGS(self, CLUTTER_ACTOR_IS_TOPLEVEL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
clutter_stage_osx_class_init (ClutterStageOSXClass *klass)
|
clutter_stage_osx_class_init (ClutterStageOSXClass *klass)
|
||||||
{
|
{
|
||||||
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
|
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
|
||||||
ClutterStageClass *stage_class = CLUTTER_STAGE_CLASS (klass);
|
|
||||||
|
|
||||||
actor_class->realize = clutter_stage_osx_realize;
|
actor_class->realize = clutter_stage_osx_realize;
|
||||||
actor_class->unrealize = clutter_stage_osx_unrealize;
|
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->query_coords = clutter_stage_osx_query_coords;
|
||||||
actor_class->request_coords = clutter_stage_osx_request_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>
|
#include <clutter/clutter-backend.h>
|
||||||
|
|
||||||
#import <Foundation/Foundation.h>
|
#import <Foundation/Foundation.h>
|
||||||
@class NSOpenGLView, NSWindow;
|
#import <AppKit/AppKit.h>
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
@ -41,11 +41,19 @@ G_BEGIN_DECLS
|
|||||||
typedef struct _ClutterStageOSX ClutterStageOSX;
|
typedef struct _ClutterStageOSX ClutterStageOSX;
|
||||||
typedef struct _ClutterStageOSXClass ClutterStageOSXClass;
|
typedef struct _ClutterStageOSXClass ClutterStageOSXClass;
|
||||||
|
|
||||||
|
@interface ClutterGLWindow : NSWindow
|
||||||
|
{
|
||||||
|
@public
|
||||||
|
ClutterStageOSX *stage_osx;
|
||||||
|
}
|
||||||
|
@end
|
||||||
|
|
||||||
struct _ClutterStageOSX
|
struct _ClutterStageOSX
|
||||||
{
|
{
|
||||||
ClutterStage parent;
|
ClutterActor parent;
|
||||||
|
|
||||||
ClutterBackend *backend;
|
ClutterBackend *backend;
|
||||||
|
ClutterStage *wrapper;
|
||||||
|
|
||||||
NSWindow *window;
|
NSWindow *window;
|
||||||
NSOpenGLView *view;
|
NSOpenGLView *view;
|
||||||
@ -61,12 +69,13 @@ struct _ClutterStageOSX
|
|||||||
|
|
||||||
struct _ClutterStageOSXClass
|
struct _ClutterStageOSXClass
|
||||||
{
|
{
|
||||||
ClutterStageClass parent_class;
|
ClutterActorClass parent_class;
|
||||||
};
|
};
|
||||||
|
|
||||||
GType clutter_stage_osx_get_type (void) G_GNUC_CONST;
|
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
|
G_END_DECLS
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user