diff --git a/clutter/Makefile.am b/clutter/Makefile.am index 4f61beeae..fb52faabb 100644 --- a/clutter/Makefile.am +++ b/clutter/Makefile.am @@ -630,46 +630,6 @@ clutter-egl-$(CLUTTER_API_VERSION).pc: clutter-$(CLUTTER_API_VERSION).pc pc_files += clutter-egl-$(CLUTTER_API_VERSION).pc endif # SUPPORT_EGL -# OSX backend rules -osx_source_c = \ - osx/clutter-backend-osx.c \ - osx/clutter-stage-osx.c \ - $(NULL) - -osx_source_h = osx/clutter-osx.h - -osx_source_h_priv = \ - osx/clutter-backend-osx.h \ - osx/clutter-event-loop-osx.h \ - osx/clutter-stage-osx.h \ - osx/clutter-device-manager-osx.h \ - $(NULL) - -osx_source_c_priv = \ - osx/clutter-event-loop-osx.c \ - osx/clutter-event-osx.c \ - osx/clutter-device-manager-osx.c \ - $(NULL) - -if SUPPORT_OSX -# we need to tell the compiler that part of our code base is -# in Objective C -AM_CFLAGS += -xobjective-c - -backend_source_h += $(osx_source_h) -backend_source_c += $(osx_source_c) -backend_source_h_priv += $(osx_source_h_priv) -backend_source_c_priv += $(osx_source_c_priv) - -clutterosx_includedir = $(clutter_includedir)/osx -clutterosx_include_HEADERS = $(osx_source_h) - -clutter-osx-$(CLUTTER_API_VERSION).pc: clutter-$(CLUTTER_API_VERSION).pc - $(QUIET_GEN)cp -f $< $(@F) - -pc_files += clutter-osx-$(CLUTTER_API_VERSION).pc -endif # SUPPORT_OSX - # cally cally_sources_h = \ cally/cally-actor.h \ diff --git a/clutter/clutter-backend.c b/clutter/clutter-backend.c index b8778df44..5f85b1d89 100644 --- a/clutter/clutter-backend.c +++ b/clutter/clutter-backend.c @@ -67,9 +67,6 @@ #ifdef CLUTTER_INPUT_X11 #include "x11/clutter-backend-x11.h" #endif -#ifdef CLUTTER_INPUT_OSX -#include "osx/clutter-backend-osx.h" -#endif #ifdef CLUTTER_INPUT_GDK #include "gdk/clutter-backend-gdk.h" #endif @@ -527,9 +524,6 @@ static const struct { const char *name; ClutterBackend * (* create_backend) (void); } available_backends[] = { -#ifdef CLUTTER_WINDOWING_OSX - { CLUTTER_WINDOWING_OSX, clutter_backend_osx_new }, -#endif #ifdef CLUTTER_WINDOWING_GDK { CLUTTER_WINDOWING_GDK, clutter_backend_gdk_new }, #endif @@ -603,14 +597,6 @@ clutter_backend_real_init_events (ClutterBackend *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_X11 if (clutter_check_windowing_backend (CLUTTER_WINDOWING_X11) && (input_backend == NULL || input_backend == I_(CLUTTER_INPUT_X11))) diff --git a/clutter/clutter-main.c b/clutter/clutter-main.c index 3c64d86d7..ccac23175 100644 --- a/clutter/clutter-main.c +++ b/clutter/clutter-main.c @@ -70,9 +70,6 @@ #include "clutter-stage-private.h" #include "clutter-version.h" /* For flavour define */ -#ifdef CLUTTER_WINDOWING_OSX -#include "osx/clutter-backend-osx.h" -#endif #ifdef CLUTTER_WINDOWING_GDK #include "gdk/clutter-backend-gdk.h" #endif @@ -3634,12 +3631,6 @@ clutter_check_windowing_backend (const char *backend_type) backend_type = g_intern_string (backend_type); -#ifdef CLUTTER_WINDOWING_OSX - if (backend_type == I_(CLUTTER_WINDOWING_OSX) && - CLUTTER_IS_BACKEND_OSX (context->backend)) - return TRUE; - else -#endif #ifdef CLUTTER_WINDOWING_WAYLAND if (backend_type == I_(CLUTTER_WINDOWING_WAYLAND) && CLUTTER_IS_BACKEND_WAYLAND (context->backend)) diff --git a/clutter/osx/clutter-backend-osx.c b/clutter/osx/clutter-backend-osx.c deleted file mode 100644 index 6b6aaec11..000000000 --- a/clutter/osx/clutter-backend-osx.c +++ /dev/null @@ -1,253 +0,0 @@ -/* Clutter - An OpenGL based 'interactive canvas' library. - * OSX backend - initial entry point - * - * Copyright (C) 2007-2008 Tommi Komulainen - * Copyright (C) 2007 OpenedHand Ltd. - * Copyright (C) 2011 Crystalnix - * - * 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 . - * - * - */ -#include "config.h" - -#import "clutter-osx.h" -#import "clutter-backend-osx.h" -#import "clutter-device-manager-osx.h" -#import "clutter-stage-osx.h" -#import "clutter-event-loop-osx.h" - -#include "clutter-debug.h" -#include "clutter-private.h" -#include "clutter-stage-private.h" - -#include "cogl/cogl.h" - -#import - -#define DEFAULT_FONT_NAME "Lucida Grande 13" - -#define clutter_backend_osx_get_type _clutter_backend_osx_get_type - -G_DEFINE_TYPE (ClutterBackendOSX, clutter_backend_osx, CLUTTER_TYPE_BACKEND) - -/* various flags corresponding to pre init setup calls */ -static gboolean _no_event_retrieval = FALSE; - -/*************************************************************************/ -static gboolean -clutter_backend_osx_post_parse (ClutterBackend *backend, - GError **error) -{ - ClutterSettings *settings = clutter_settings_get_default (); - - CLUTTER_OSX_POOL_ALLOC(); - /* getting standart dpi for main screen */ - NSDictionary* prop = [[NSScreen mainScreen] deviceDescription]; - NSSize size; - [[prop valueForKey:@"NSDeviceResolution"] getValue:&size]; - CLUTTER_OSX_POOL_RELEASE(); - - /* setting dpi for backend, it needs by font rendering library */ - if (size.height > 0) - { - int font_dpi = size.height * 1024; - - g_object_set (settings, "font-dpi", font_dpi, NULL); - } - - /* set the default font name */ - g_object_set (settings, "font-name", DEFAULT_FONT_NAME, NULL); - - /* finish launching the application */ - [NSApp finishLaunching]; - - return TRUE; -} - -void -clutter_osx_disable_event_retrieval (void) -{ - if (_clutter_context_is_initialized ()) - { - g_warning ("clutter_osx_disable_event_retrieval() can only be " - "called before clutter_init()"); - return; - } - - _no_event_retrieval = TRUE; -} - -static ClutterFeatureFlags -clutter_backend_osx_get_features (ClutterBackend *backend) -{ - return CLUTTER_FEATURE_STAGE_MULTIPLE - | CLUTTER_FEATURE_STAGE_USER_RESIZE; -} - -void -_clutter_backend_osx_events_init (ClutterBackend *backend) -{ - ClutterBackendOSX *backend_osx = CLUTTER_BACKEND_OSX (backend); - - if (backend_osx->device_manager != NULL) - return; - - CLUTTER_NOTE (BACKEND, "init_events"); - - backend->device_manager = backend_osx->device_manager = - g_object_new (CLUTTER_TYPE_DEVICE_MANAGER_OSX, - "backend", CLUTTER_BACKEND(backend_osx), - NULL); - - if (!_no_event_retrieval) - _clutter_osx_event_loop_init (); -} - -static gboolean -clutter_backend_osx_create_context (ClutterBackend *backend, - GError **error) -{ - ClutterBackendOSX *backend_osx = CLUTTER_BACKEND_OSX (backend); - - CLUTTER_OSX_POOL_ALLOC(); - - if (backend_osx->context == nil) - { - /* 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, - NSOpenGLPFADepthSize, 32, - NSOpenGLPFAStencilSize, 8, - 0 - }; - -#ifdef MAC_OS_X_VERSION_10_5 - const int sw = 1; -#else - const long sw = 1; -#endif - - backend_osx->pixel_format = [[NSOpenGLPixelFormat alloc] initWithAttributes:attrs]; - - backend_osx->context = [[NSOpenGLContext alloc] initWithFormat: backend_osx->pixel_format - shareContext: nil]; - - /* Enable vblank sync - http://developer.apple.com/qa/qa2007/qa1521.html */ - [backend_osx->context setValues:&sw forParameter: NSOpenGLCPSwapInterval]; - - CLUTTER_NOTE (BACKEND, "Context was created"); - } - - [backend_osx->context makeCurrentContext]; - - CLUTTER_BACKEND_CLASS (clutter_backend_osx_parent_class)->create_context (backend, - error); - - CLUTTER_OSX_POOL_RELEASE(); - - return TRUE; -} - -static void -clutter_backend_osx_ensure_context (ClutterBackend *backend, - ClutterStage *wrapper) -{ - ClutterBackendOSX *backend_osx = CLUTTER_BACKEND_OSX (backend); - - CLUTTER_OSX_POOL_ALLOC(); - - CLUTTER_NOTE (BACKEND, "ensure_context: wrapper=%p", wrapper); - - 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 clearDrawable]; - [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_init (ClutterBackendOSX *backend_osx) -{ - const ProcessSerialNumber psn = { 0, kCurrentProcess }; - - backend_osx->context = nil; - backend_osx->pixel_format = nil; - - /* Bring our app to foreground, background apps don't appear in dock or - * accept keyboard focus. - */ - TransformProcessType (&psn, kProcessTransformToForegroundApplication); - - /* Also raise our app to front, otherwise our window will remain under the - * terminal. - */ - SetFrontProcess (&psn); - - [NSApplication sharedApplication]; -} - -static void -clutter_backend_osx_dispose (GObject *object) -{ - ClutterBackendOSX *self = CLUTTER_BACKEND_OSX (object); - - [self->context release]; - self->context = NULL; - - [self->pixel_format release]; - self->pixel_format = NULL; - - G_OBJECT_CLASS (clutter_backend_osx_parent_class)->dispose (object); -} - -static void -clutter_backend_osx_class_init (ClutterBackendOSXClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - ClutterBackendClass *backend_class = CLUTTER_BACKEND_CLASS (klass); - - 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->get_features = clutter_backend_osx_get_features; - backend_class->create_context = clutter_backend_osx_create_context; - backend_class->ensure_context = clutter_backend_osx_ensure_context; -} - -ClutterBackend * -clutter_backend_osx_new (void) -{ - return g_object_new (CLUTTER_TYPE_BACKEND_OSX, NULL); -} diff --git a/clutter/osx/clutter-backend-osx.h b/clutter/osx/clutter-backend-osx.h deleted file mode 100644 index b3e13d8e4..000000000 --- a/clutter/osx/clutter-backend-osx.h +++ /dev/null @@ -1,76 +0,0 @@ -/* Clutter - An OpenGL based 'interactive canvas' library. - * OSX backend - initial entry point - * - * Copyright (C) 2007 Tommi Komulainen - * Copyright (C) 2007 OpenedHand Ltd. - * Copyright (C) 2011 Crystalnix - * - * 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 . - * - * - */ -#ifndef __CLUTTER_BACKEND_OSX_H__ -#define __CLUTTER_BACKEND_OSX_H__ - -#import -#import -#import - -#include - -#include "clutter-backend-private.h" - -@class NSOpenGLPixelFormat, NSOpenGLContext; - -G_BEGIN_DECLS - -#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_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_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),CLUTTER_TYPE_BACKEND_OSX)) -#define CLUTTER_BACKEND_OSX_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj),CLUTTER_TYPE_BACKEND_OSX,ClutterBackendOSXClass)) - -typedef struct _ClutterBackendOSX ClutterBackendOSX; -typedef struct _ClutterBackendOSXClass ClutterBackendOSXClass; - -struct _ClutterBackendOSX -{ - ClutterBackend parent; - - NSOpenGLPixelFormat *pixel_format; - NSOpenGLContext *context; - ClutterDeviceManager *device_manager; -}; - -struct _ClutterBackendOSXClass -{ - ClutterBackendClass parent_class; -}; - -GType _clutter_backend_osx_get_type (void) G_GNUC_CONST; - -void _clutter_backend_osx_events_init (ClutterBackend *backend); - -#define CLUTTER_OSX_POOL_ALLOC() NSAutoreleasePool *autorelease_pool = [[NSAutoreleasePool alloc] init] -#define CLUTTER_OSX_POOL_RELEASE() [autorelease_pool release]; - -void _clutter_event_osx_put (NSEvent *nsevent, - ClutterStage *wrapper); - -ClutterBackend *clutter_backend_osx_new (void); - -G_END_DECLS - -#endif /* __CLUTTER_BACKEND_OSX_H__ */ diff --git a/clutter/osx/clutter-device-manager-osx.c b/clutter/osx/clutter-device-manager-osx.c deleted file mode 100644 index 8480da634..000000000 --- a/clutter/osx/clutter-device-manager-osx.c +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2009 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 . - * - * Author: Emmanuele Bassi - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "clutter-backend-osx.h" -#include "clutter-device-manager-osx.h" -#include "clutter-device-manager-osx.h" -#include "clutter-stage-osx.h" - -#include "clutter-backend.h" -#include "clutter-debug.h" -#include "clutter-device-manager-private.h" -#include "clutter-private.h" - -enum -{ - PROP_0 -}; - -G_DEFINE_TYPE (ClutterDeviceManagerOSX, - clutter_device_manager_osx, - CLUTTER_TYPE_DEVICE_MANAGER); - -static void -clutter_device_manager_osx_constructed (GObject *gobject) -{ - ClutterDeviceManager *manager = CLUTTER_DEVICE_MANAGER (gobject); - ClutterDeviceManagerOSX *manager_osx; - ClutterInputDevice *device; - - device = g_object_new (CLUTTER_TYPE_INPUT_DEVICE, - "id", 0, - "name", "Core Pointer", - "device-type", CLUTTER_POINTER_DEVICE, - "device-mode", CLUTTER_INPUT_MODE_MASTER, - "has-cursor", TRUE, - "enabled", TRUE, - NULL); - CLUTTER_NOTE (BACKEND, "Added core pointer device"); - _clutter_device_manager_add_device (manager, device); - - device = g_object_new (CLUTTER_TYPE_INPUT_DEVICE, - "id", 1, - "name", "Core Keyboard", - "device-type", CLUTTER_KEYBOARD_DEVICE, - "device-mode", CLUTTER_INPUT_MODE_MASTER, - "enabled", TRUE, - NULL); - CLUTTER_NOTE (BACKEND, "Added core keyboard device"); - _clutter_device_manager_add_device (manager, device); - - manager_osx = CLUTTER_DEVICE_MANAGER_OSX (manager); - - _clutter_input_device_set_associated_device (manager_osx->core_pointer, - manager_osx->core_keyboard); - _clutter_input_device_set_associated_device (manager_osx->core_keyboard, - manager_osx->core_pointer); -} - -static void -clutter_device_manager_osx_add_device (ClutterDeviceManager *manager, - ClutterInputDevice *device) -{ - ClutterDeviceManagerOSX *manager_osx = CLUTTER_DEVICE_MANAGER_OSX (manager); - ClutterInputDeviceType device_type; - gboolean is_pointer, is_keyboard; - - device_type = clutter_input_device_get_device_type (device); - is_pointer = (device_type == CLUTTER_POINTER_DEVICE) ? TRUE : FALSE; - is_keyboard = (device_type == CLUTTER_KEYBOARD_DEVICE) ? TRUE : FALSE; - - manager_osx->devices = g_slist_prepend (manager_osx->devices, device); - - if (is_pointer && manager_osx->core_pointer == NULL) - manager_osx->core_pointer = device; - - if (is_keyboard && manager_osx->core_keyboard == NULL) - manager_osx->core_keyboard = device; -} - -static void -clutter_device_manager_osx_remove_device (ClutterDeviceManager *manager, - ClutterInputDevice *device) -{ - ClutterDeviceManagerOSX *manager_osx = CLUTTER_DEVICE_MANAGER_OSX (manager); - - manager_osx->devices = g_slist_remove (manager_osx->devices, device); -} - -static const GSList * -clutter_device_manager_osx_get_devices (ClutterDeviceManager *manager) -{ - return CLUTTER_DEVICE_MANAGER_OSX (manager)->devices; -} - -static ClutterInputDevice * -clutter_device_manager_osx_get_core_device (ClutterDeviceManager *manager, - ClutterInputDeviceType type) -{ - ClutterDeviceManagerOSX *manager_osx; - - manager_osx = CLUTTER_DEVICE_MANAGER_OSX (manager); - - switch (type) - { - case CLUTTER_POINTER_DEVICE: - return manager_osx->core_pointer; - - case CLUTTER_KEYBOARD_DEVICE: - return manager_osx->core_keyboard; - - case CLUTTER_EXTENSION_DEVICE: - default: - return NULL; - } - - return NULL; -} - -static ClutterInputDevice * -clutter_device_manager_osx_get_device (ClutterDeviceManager *manager, - gint id_) -{ - ClutterDeviceManagerOSX *manager_osx = CLUTTER_DEVICE_MANAGER_OSX (manager); - GSList *l; - - for (l = manager_osx->devices; l != NULL; l = l->next) - { - ClutterInputDevice *device = l->data; - - if (clutter_input_device_get_device_id (device) == id_) - return device; - } - - return NULL; -} - -static void -clutter_device_manager_osx_class_init (ClutterDeviceManagerOSXClass *klass) -{ - ClutterDeviceManagerClass *manager_class; - GObjectClass *gobject_class = (GObjectClass *) klass; - - gobject_class->constructed = clutter_device_manager_osx_constructed; - - manager_class = CLUTTER_DEVICE_MANAGER_CLASS (klass); - manager_class->add_device = clutter_device_manager_osx_add_device; - manager_class->remove_device = clutter_device_manager_osx_remove_device; - manager_class->get_devices = clutter_device_manager_osx_get_devices; - manager_class->get_core_device = clutter_device_manager_osx_get_core_device; - manager_class->get_device = clutter_device_manager_osx_get_device; -} - -static void -clutter_device_manager_osx_init (ClutterDeviceManagerOSX *self) -{ -} diff --git a/clutter/osx/clutter-device-manager-osx.h b/clutter/osx/clutter-device-manager-osx.h deleted file mode 100644 index 300513fc7..000000000 --- a/clutter/osx/clutter-device-manager-osx.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * 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 . - * - * Author: Emmanuele Bassi - */ - -#ifndef __CLUTTER_DEVICE_MANAGER_OSX_H__ -#define __CLUTTER_DEVICE_MANAGER_OSX_H__ - -#include - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_DEVICE_MANAGER_OSX (clutter_device_manager_osx_get_type ()) -#define CLUTTER_DEVICE_MANAGER_OSX(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_DEVICE_MANAGER_OSX, ClutterDeviceManagerOSX)) -#define CLUTTER_IS_DEVICE_MANAGER_OSX(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_DEVICE_MANAGER_OSX)) -#define CLUTTER_DEVICE_MANAGER_OSX_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_DEVICE_MANAGER_OSX, ClutterDeviceManagerOSXClass)) -#define CLUTTER_IS_DEVICE_MANAGER_OSX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_DEVICE_MANAGER_OSX)) -#define CLUTTER_DEVICE_MANAGER_OSX_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_DEVICE_MANAGER_OSX, ClutterDeviceManagerOSXClass)) - -typedef struct _ClutterDeviceManagerOSX ClutterDeviceManagerOSX; -typedef struct _ClutterDeviceManagerOSXClass ClutterDeviceManagerOSXClass; - -struct _ClutterDeviceManagerOSX -{ - ClutterDeviceManager parent_instance; - - GSList *devices; - - ClutterInputDevice *core_pointer; - ClutterInputDevice *core_keyboard; -}; - -struct _ClutterDeviceManagerOSXClass -{ - ClutterDeviceManagerClass parent_class; -}; - -GType clutter_device_manager_osx_get_type (void) G_GNUC_CONST; - -G_END_DECLS - -#endif /* __CLUTTER_DEVICE_MANAGER_OSX_H__ */ diff --git a/clutter/osx/clutter-event-loop-osx.c b/clutter/osx/clutter-event-loop-osx.c deleted file mode 100644 index 77a4330ab..000000000 --- a/clutter/osx/clutter-event-loop-osx.c +++ /dev/null @@ -1,1056 +0,0 @@ -/* source code taken from gtk+-2.22.1/gdk/quartz/gdkeventloop-quartz.c */ -/* Clutter - An OpenGL based 'interactive canvas' library. - * OSX backend - event loop - * - * Copyright (C) 2005-2007 Imendio AB - * Copyright (C) 2011 Crystalnix - * - * 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 . - * - * - */ - -#include "config.h" - -#include "clutter-osx.h" -#include "clutter-stage-osx.h" - -#import -#include -#include -#include -#include -#include - -#include "clutter-debug.h" -#include "clutter-private.h" - -/* - * This file implementations integration between the GLib main loop and - * the native system of the Core Foundation run loop and Cocoa event - * handling. There are basically two different cases that we need to - * handle: either the GLib main loop is in control (the application - * has called gtk_main(), or is otherwise iterating the main loop), or - * CFRunLoop is in control (we are in a modal operation such as window - * resizing or drag-and-drop.) - * - * When the GLib main loop is in control we integrate in native event - * handling in two ways: first we add a GSource that handles checking - * whether there are native events available, translating native events - * to clutter events, and dispatching GDK events. Second we replace the - * "poll function" of the GLib main loop with our own version that knows - * how to wait for both the file descriptors and timeouts that GLib is - * interested in and also for incoming native events. - * - * When CFRunLoop is in control, we integrate in GLib main loop handling - * by adding a "run loop observer" that gives us notification at various - * points in the run loop cycle. We map these points onto the corresponding - * stages of the GLib main loop (prepare, check, dispatch), and make the - * appropriate calls into GLib. - * - * Both cases share a single problem: the OS X API's don't allow us to - * wait simultaneously for file descriptors and for events. So when we - * need to do a blocking wait that includes file descriptor activity, we - * push the actual work of calling select() to a helper thread (the - * "select thread") and wait for native events in the main thread. - * - * The main known limitation of this code is that if a callback is triggered - * via the OS X run loop while we are "polling" (in either case described - * above), iteration of the GLib main loop is not possible from within - * that callback. If the programmer tries to do so explicitly, then they - * will get a warning from GLib "main loop already active in another thread". - */ - -/******* State for run loop iteration *******/ - -/* Count of number of times we've gotten an "Entry" notification for - * our run loop observer. - */ -static int current_loop_level = 0; - -/* Run loop level at which we acquired ownership of the GLib main - * loop. See note in run_loop_entry(). -1 means that we don't have - * ownership - */ -static int acquired_loop_level = -1; - -/* Between run_loop_before_waiting() and run_loop_after_waiting(); - * whether we we need to call select_thread_collect_poll() - */ -static gboolean run_loop_polling_async = FALSE; - -/* Between run_loop_before_waiting() and run_loop_after_waiting(); - * max_prioritiy to pass to g_main_loop_check() - */ -static gint run_loop_max_priority; - -/* Timer that we've added to wake up the run loop when a GLib timeout - */ -static CFRunLoopTimerRef run_loop_timer = NULL; - -/* These are the file descriptors that are we are polling out of - * the run loop. (We keep the array around and reuse it to avoid - * constant allocations.) - */ -#define RUN_LOOP_POLLFDS_INITIAL_SIZE 16 -static GPollFD *run_loop_pollfds; -static guint run_loop_pollfds_size; /* Allocated size of the array */ -static guint run_loop_n_pollfds; /* Number of file descriptors in the array */ - -/******* Other global variables *******/ - -/* Since we count on replacing the GLib main loop poll function as our - * method of integrating Cocoa event handling into the GLib main loop - * we need to make sure that the poll function is always called even - * when there are no file descriptors that need to be polled. To do - * this, we add a dummy GPollFD to our event source with a file - * descriptor of '-1'. Then any time that GLib is polling the event - * source, it will call our poll function. - */ -static GPollFD event_poll_fd; - -/* Current NSEvents that we've gotten from Cocoa but haven't yet converted - * to GdkEvents. We wait until our dispatch() function to do the conversion - * since the conversion can conceivably cause signals to be emmitted - * or other things that shouldn't happen inside a poll function. - */ -static GQueue *current_events; - -/* The default poll function for GLib; we replace this with our own - * Cocoa-aware version and then call the old version to do actual - * file descriptor polling. There's no actual need to chain to the - * old one; we could reimplement the same functionality from scratch, - * but since the default implementation does the right thing, why - * bother. - */ -static GPollFunc old_poll_func = NULL; - -/* Reference to the run loop of the main thread. (There is a unique - * CFRunLoop per thread.) - */ -static CFRunLoopRef main_thread_run_loop; - -/* Normally the Cocoa main loop maintains an NSAutoReleasePool and frees - * it on every iteration. Since we are replacing the main loop we have - * to provide this functionality ourself. We free and replace the - * auto-release pool in our sources prepare() function. - */ -static NSAutoreleasePool *autorelease_pool; - -/* Flag when we've called nextEventMatchingMask ourself; this triggers - * a run loop iteration, so we need to detect that and avoid triggering - * our "run the GLib main looop while the run loop is active machinery. - */ -static gboolean getting_events; - -/************************************************************ - ********* Select Thread ********* - ************************************************************/ - -/* The states in our state machine, see comments in select_thread_func() - * for descriptiions of each state - */ -typedef enum { - BEFORE_START, - WAITING, - POLLING_QUEUED, - POLLING_RESTART, - POLLING_DESCRIPTORS, -} SelectThreadState; - -static const char *const state_names[] = { - "BEFORE_START", - "WAITING", - "POLLING_QUEUED", - "POLLING_RESTART", - "POLLING_DESCRIPTORS" -}; - -static SelectThreadState select_thread_state = BEFORE_START; - -static pthread_t select_thread; -static pthread_mutex_t select_thread_mutex = PTHREAD_MUTEX_INITIALIZER; -static pthread_cond_t select_thread_cond = PTHREAD_COND_INITIALIZER; - -#define SELECT_THREAD_LOCK() pthread_mutex_lock (&select_thread_mutex) -#define SELECT_THREAD_UNLOCK() pthread_mutex_unlock (&select_thread_mutex) -#define SELECT_THREAD_SIGNAL() pthread_cond_signal (&select_thread_cond) -#define SELECT_THREAD_WAIT() pthread_cond_wait (&select_thread_cond, &select_thread_mutex) - -/* These are the file descriptors that the select thread is currently - * polling. - */ -static GPollFD *current_pollfds; -static guint current_n_pollfds; - -/* These are the file descriptors that the select thread should pick - * up and start polling when it has a chance. - */ -static GPollFD *next_pollfds; -static guint next_n_pollfds; - -/* Pipe used to wake up the select thread */ -static gint select_thread_wakeup_pipe[2]; - -/* Run loop source used to wake up the main thread */ -static CFRunLoopSourceRef select_main_thread_source; - -/* Events */ -typedef enum { - CLUTTER_OSX_EVENT_SUBTYPE_EVENTLOOP -} ClutterOSXEventSubType; - -static void -select_thread_set_state (SelectThreadState new_state) -{ - gboolean old_state; - - if (select_thread_state == new_state) - return; - - CLUTTER_NOTE (EVENTLOOP, "EventLoop: Select thread state: %s => %s\n", state_names[select_thread_state], state_names[new_state]); - - old_state = select_thread_state; - select_thread_state = new_state; - if (old_state == WAITING && new_state != WAITING) - SELECT_THREAD_SIGNAL (); -} - -static void -signal_main_thread (void) -{ - CLUTTER_NOTE (EVENTLOOP, "EventLoop: Waking up main thread\n"); - - /* If we are in nextEventMatchingMask, then we need to make sure an - * event gets queued, otherwise it's enough to simply wake up the - * main thread run loop - */ - if (!run_loop_polling_async) - CFRunLoopSourceSignal (select_main_thread_source); - - if (CFRunLoopIsWaiting (main_thread_run_loop)) - CFRunLoopWakeUp (main_thread_run_loop); -} - -static void * -select_thread_func (void *arg) -{ - char c; - - SELECT_THREAD_LOCK (); - - while (TRUE) - { - switch (select_thread_state) - { - case BEFORE_START: - /* The select thread has not been started yet - */ - g_assert_not_reached (); - - case WAITING: - /* Waiting for a set of file descriptors to be submitted by the main thread - * - * => POLLING_QUEUED: main thread thread submits a set of file descriptors - */ - SELECT_THREAD_WAIT (); - break; - - case POLLING_QUEUED: - /* Waiting for a set of file descriptors to be submitted by the main thread - * - * => POLLING_DESCRIPTORS: select thread picks up the file descriptors to begin polling - */ - if (current_pollfds) - g_free (current_pollfds); - - current_pollfds = next_pollfds; - current_n_pollfds = next_n_pollfds; - - next_pollfds = NULL; - next_n_pollfds = 0; - - select_thread_set_state (POLLING_DESCRIPTORS); - break; - - case POLLING_RESTART: - /* Select thread is currently polling a set of file descriptors, main thread has - * began a new iteration with the same set of file descriptors. We don't want to - * wake the select thread up and wait for it to restart immediately, but to avoid - * a race (described below in select_thread_start_polling()) we need to recheck after - * polling completes. - * - * => POLLING_DESCRIPTORS: select completes, main thread rechecks by polling again - * => POLLING_QUEUED: main thread submits a new set of file descriptors to be polled - */ - select_thread_set_state (POLLING_DESCRIPTORS); - break; - - case POLLING_DESCRIPTORS: - /* In the process of polling the file descriptors - * - * => WAITING: polling completes when a file descriptor becomes active - * => POLLING_QUEUED: main thread submits a new set of file descriptors to be polled - * => POLLING_RESTART: main thread begins a new iteration with the same set file descriptors - */ - SELECT_THREAD_UNLOCK (); - old_poll_func (current_pollfds, current_n_pollfds, -1); - SELECT_THREAD_LOCK (); - - read (select_thread_wakeup_pipe[0], &c, 1); - - if (select_thread_state == POLLING_DESCRIPTORS) - { - signal_main_thread (); - select_thread_set_state (WAITING); - } - break; - } - } -} - -static void -got_fd_activity (void *info) -{ - NSEvent *event; - - /* Post a message so we'll break out of the message loop */ - event = [NSEvent otherEventWithType: NSApplicationDefined - location: NSZeroPoint - modifierFlags: 0 - timestamp: 0 - windowNumber: 0 - context: nil - subtype: CLUTTER_OSX_EVENT_SUBTYPE_EVENTLOOP - data1: 0 - data2: 0]; - - [NSApp postEvent:event atStart:YES]; -} - -static void -select_thread_start (void) -{ - CFRunLoopSourceContext source_context = {0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, got_fd_activity }; - - g_return_if_fail (select_thread_state == BEFORE_START); - - pipe (select_thread_wakeup_pipe); - fcntl (select_thread_wakeup_pipe[0], F_SETFL, O_NONBLOCK); - - select_main_thread_source = CFRunLoopSourceCreate (NULL, 0, &source_context); - - CFRunLoopAddSource (main_thread_run_loop, select_main_thread_source, kCFRunLoopCommonModes); - - select_thread_state = WAITING; - - while (TRUE) - { - if (pthread_create (&select_thread, NULL, select_thread_func, NULL) == 0) - break; - - g_warning ("Failed to create select thread, sleeping and trying again"); - sleep (1); - } -} - -#ifdef G_ENABLE_DEBUG -static void -dump_poll_result (GPollFD *ufds, - guint nfds) -{ - gint i; - - for (i = 0; i < nfds; i++) - { - if (ufds[i].fd >= 0 && ufds[i].revents) - { - g_print (" %d:", ufds[i].fd); - if (ufds[i].revents & G_IO_IN) - g_print (" in"); - if (ufds[i].revents & G_IO_OUT) - g_print (" out"); - if (ufds[i].revents & G_IO_PRI) - g_print (" pri"); - g_print ("\n"); - } - } -} -#endif - -gboolean -pollfds_equal (GPollFD *old_pollfds, - guint old_n_pollfds, - GPollFD *new_pollfds, - guint new_n_pollfds) -{ - gint i; - - if (old_n_pollfds != new_n_pollfds) - return FALSE; - - for (i = 0; i < old_n_pollfds; i++) - { - if (old_pollfds[i].fd != new_pollfds[i].fd || - old_pollfds[i].events != new_pollfds[i].events) - return FALSE; - } - - return TRUE; -} - -/* Begins a polling operation with the specified GPollFD array; the - * timeout is used only to tell if the polling operation is blocking - * or non-blocking. - * - * Return value: - * -1: No file descriptors ready, began asynchronous poll - * 0: No file descriptors ready, asynchronous poll not needed - * > 0: Number of file descriptors ready - */ -static gint -select_thread_start_poll (GPollFD *ufds, - guint nfds, gint timeout) -{ - gint n_ready; - gboolean have_new_pollfds = FALSE; - gint poll_fd_index = -1; - gint i; - - for (i = 0; i < nfds; i++) - if (ufds[i].fd == -1) - { - poll_fd_index = i; - break; - } - - if (nfds == 0 || - (nfds == 1 && poll_fd_index >= 0)) - { - CLUTTER_NOTE (EVENTLOOP, "EventLoop: Nothing to poll\n"); - return 0; - } - - /* If we went immediately to an async poll, then we might decide to - * dispatch idle functions when higher priority file descriptor sources - * are ready to be dispatched. So we always need to first check - * check synchronously with a timeout of zero, and only when no - * sources are immediately ready, go to the asynchronous poll. - * - * Of course, if the timeout passed in is 0, then the synchronous - * check is sufficient and we never need to do the asynchronous poll. - */ - n_ready = old_poll_func (ufds, nfds, 0); - if (n_ready > 0 || timeout == 0) - { -#ifdef G_ENABLE_DEBUG - if (CLUTTER_HAS_DEBUG(EVENTLOOP) && n_ready > 0) - { - g_print ("EventLoop: Found ready file descriptors before waiting\n"); - dump_poll_result (ufds, nfds); - } -#endif - - return n_ready; - } - - SELECT_THREAD_LOCK (); - - if (select_thread_state == BEFORE_START) - { - select_thread_start (); - } - - if (select_thread_state == POLLING_QUEUED) - { - /* If the select thread hasn't picked up the set of file descriptors yet - * then we can simply replace an old stale set with a new set. - */ - if (!pollfds_equal (ufds, nfds, next_pollfds, next_n_pollfds - 1)) - { - g_free (next_pollfds); - next_pollfds = NULL; - next_n_pollfds = 0; - - have_new_pollfds = TRUE; - } - } - else if (select_thread_state == POLLING_RESTART || select_thread_state == POLLING_DESCRIPTORS) - { - /* If we are already in the process of polling the right set of file descriptors, - * there's no need for us to immediately force the select thread to stop polling - * and then restart again. And avoiding doing so increases the efficiency considerably - * in the common case where we have a set of basically inactive file descriptors that - * stay unchanged present as we process many events. - * - * However, we have to be careful that we don't hit the following race condition - * Select Thread Main Thread - * ----------------- --------------- - * Polling Completes - * Reads data or otherwise changes file descriptor state - * Checks if polling is current - * Does nothing (*) - * Releases lock - * Acquires lock - * Marks polling as complete - * Wakes main thread - * Receives old stale file descriptor state - * - * To avoid this, when the new set of poll descriptors is the same as the current - * one, we transition to the POLLING_RESTART stage at the point marked (*). When - * the select thread wakes up from the poll because a file descriptor is active, if - * the state is POLLING_RESTART it immediately begins polling same the file descriptor - * set again. This normally will just return the same set of active file descriptors - * as the first time, but in sequence described above will properly update the - * file descriptor state. - * - * Special case: this RESTART logic is not needed if the only FD is the internal GLib - * "wakeup pipe" that is presented when threads are initialized. - * - * P.S.: The harm in the above sequence is mostly that sources can be signalled - * as ready when they are no longer ready. This may prompt a blocking read - * from a file descriptor that hangs. - */ - if (!pollfds_equal (ufds, nfds, current_pollfds, current_n_pollfds - 1)) - have_new_pollfds = TRUE; - else - { - if (!((nfds == 1 && poll_fd_index < 0) || - (nfds == 2 && poll_fd_index >= 0))) - select_thread_set_state (POLLING_RESTART); - } - } - else - have_new_pollfds = TRUE; - - if (have_new_pollfds) - { - CLUTTER_NOTE (EVENTLOOP, "EventLoop: Submitting a new set of file descriptor to the select thread\n"); - - g_assert (next_pollfds == NULL); - - next_n_pollfds = nfds + 1; - next_pollfds = g_new (GPollFD, nfds + 1); - memcpy (next_pollfds, ufds, nfds * sizeof (GPollFD)); - - next_pollfds[nfds].fd = select_thread_wakeup_pipe[0]; - next_pollfds[nfds].events = G_IO_IN; - - if (select_thread_state != POLLING_QUEUED && select_thread_state != WAITING) - { - if (select_thread_wakeup_pipe[1]) - { - char c = 'A'; - write (select_thread_wakeup_pipe[1], &c, 1); - } - } - - select_thread_set_state (POLLING_QUEUED); - } - - SELECT_THREAD_UNLOCK (); - - return -1; -} - -/* End an asynchronous polling operation started with - * select_thread_collect_poll(). This must be called if and only if - * select_thread_start_poll() return -1. The GPollFD array passed - * in must be identical to the one passed to select_thread_start_poll(). - * - * The results of the poll are written into the GPollFD array passed in. - * - * Return Value: number of file descriptors ready - */ -static int -select_thread_collect_poll (GPollFD *ufds, guint nfds) -{ - gint i; - gint n_ready = 0; - - SELECT_THREAD_LOCK (); - - if (select_thread_state == WAITING) /* The poll completed */ - { - for (i = 0; i < nfds; i++) - { - if (ufds[i].fd == -1) - continue; - - g_assert (ufds[i].fd == current_pollfds[i].fd); - g_assert (ufds[i].events == current_pollfds[i].events); - - if (current_pollfds[i].revents) - { - ufds[i].revents = current_pollfds[i].revents; - n_ready++; - } - } - -#ifdef G_ENABLE_DEBUG - if (_gdk_debug_flags & GDK_DEBUG_EVENTLOOP) - { - g_print ("EventLoop: Found ready file descriptors after waiting\n"); - dump_poll_result (ufds, nfds); - } -#endif - } - - SELECT_THREAD_UNLOCK (); - - return n_ready; -} - -/************************************************************ - ********* Main Loop Source ********* - ************************************************************/ - -gboolean -_clutter_osx_event_loop_check_pending (void) -{ - return current_events && current_events->head; -} - -NSEvent* -_clutter_osx_event_loop_get_pending (void) -{ - NSEvent *event = NULL; - - if (current_events) - event = g_queue_pop_tail (current_events); - - return event; -} - -void -_clutter_osx_event_loop_release_event (NSEvent *event) -{ - [event release]; -} - -static gboolean -clutter_event_prepare (GSource *source, - gint *timeout) -{ - gboolean retval; - - _clutter_threads_acquire_lock (); - - *timeout = -1; - - retval = (clutter_events_pending () || _clutter_osx_event_loop_check_pending ()); - - _clutter_threads_release_lock (); - - return retval; -} - -static gboolean -clutter_event_check (GSource *source) -{ - gboolean retval; - - _clutter_threads_acquire_lock (); - - /* XXX: This check isn't right it won't handle a recursive GLib main - * loop run within an outer CFRunLoop run. Such loops will pile up - * memory. Fixing this requires setting a flag *only* when we call - * g_main_context_check() from within the run loop iteraton code, - * and also maintaining our own stack of run loops... allocating and - * releasing NSAutoReleasePools not properly nested with CFRunLoop - * runs seems to cause problems. - */ - if (current_loop_level == 0) - { - if (autorelease_pool) - [autorelease_pool release]; - autorelease_pool = [[NSAutoreleasePool alloc] init]; - } - - retval = (clutter_events_pending () || _clutter_osx_event_loop_check_pending ()); - - _clutter_threads_release_lock (); - - return retval; -} - -static gboolean -clutter_event_dispatch (GSource *source, - GSourceFunc callback, - gpointer user_data) -{ - NSEvent *nsevent; - ClutterEvent *event; - - _clutter_threads_acquire_lock (); - - nsevent = _clutter_osx_event_loop_get_pending (); - if (nsevent) - { - _clutter_threads_release_lock (); - - [NSApp sendEvent:nsevent]; - - _clutter_threads_acquire_lock (); - - _clutter_osx_event_loop_release_event (nsevent); - } - - event = clutter_event_get (); - - if (event) - { - /* forward the event into clutter for emission etc. */ - _clutter_stage_queue_event (event->any.stage, event, FALSE); - } - - _clutter_threads_release_lock (); - - return TRUE; -} - -static GSourceFuncs event_funcs = { - clutter_event_prepare, - clutter_event_check, - clutter_event_dispatch, - NULL -}; - -/************************************************************ - ********* Our Poll Function ********* - ************************************************************/ - -static gint -poll_func (GPollFD *ufds, - guint nfds, - gint timeout_) -{ - NSEvent *event; - NSDate *limit_date; - gint n_ready; - - n_ready = select_thread_start_poll (ufds, nfds, timeout_); - if (n_ready > 0) - timeout_ = 0; - - if (timeout_ == -1) - limit_date = [NSDate distantFuture]; - else if (timeout_ == 0) - limit_date = [NSDate distantPast]; - else - limit_date = [NSDate dateWithTimeIntervalSinceNow:timeout_/1000.0]; - - getting_events = TRUE; - event = [NSApp nextEventMatchingMask: NSAnyEventMask - untilDate: limit_date - inMode: NSDefaultRunLoopMode - dequeue: YES]; - getting_events = FALSE; - - if (n_ready < 0) - n_ready = select_thread_collect_poll (ufds, nfds); - - if (event && - [event type] == NSApplicationDefined && - [event subtype] == CLUTTER_OSX_EVENT_SUBTYPE_EVENTLOOP) - { - /* Just used to wake us up; if an event and a FD arrived at the same - * time; could have come from a previous iteration in some cases, - * but the spurious wake up is harmless if a little inefficient. - */ - event = NULL; - } - - if (event) - { - if (!current_events) - current_events = g_queue_new (); - g_queue_push_head (current_events, [event retain]); - } - - return n_ready; -} - -/************************************************************ - ********* Running the main loop out of CFRunLoop ********* - ************************************************************/ - -/* Wrapper around g_main_context_query() that handles reallocating - * run_loop_pollfds up to the proper size - */ -static gint -query_main_context (GMainContext *context, - int max_priority, - int *timeout) -{ - gint nfds; - - if (!run_loop_pollfds) - { - run_loop_pollfds_size = RUN_LOOP_POLLFDS_INITIAL_SIZE; - run_loop_pollfds = g_new (GPollFD, run_loop_pollfds_size); - } - - while ((nfds = g_main_context_query (context, max_priority, timeout, - run_loop_pollfds, - run_loop_pollfds_size)) > run_loop_pollfds_size) - { - g_free (run_loop_pollfds); - run_loop_pollfds_size = nfds; - run_loop_pollfds = g_new (GPollFD, nfds); - } - - return nfds; -} - -static void -run_loop_entry (void) -{ - current_loop_level++; - - if (acquired_loop_level == -1) - { - if (g_main_context_acquire (NULL)) - { - CLUTTER_NOTE (EVENTLOOP, "EventLoop: Beginning tracking run loop activity\n"); - acquired_loop_level = current_loop_level; - } - else - { - /* If we fail to acquire the main context, that means someone is iterating - * the main context in a different thread; we simply wait until this loop - * exits and then try again at next entry. In general, iterating the loop - * from a different thread is rare: it is only possible when GDK threading - * is initialized and is not frequently used even then. So, we hope that - * having GLib main loop iteration blocked in the combination of that and - * a native modal operation is a minimal problem. We could imagine using a - * thread that does g_main_context_wait() and then wakes us back up, but - * the gain doesn't seem worth the complexity. - */ - CLUTTER_NOTE (EVENTLOOP, "EventLoop: Can't acquire main loop; skipping tracking run loop activity\n"); - } - } -} - -static void -run_loop_before_timers (void) -{ -} - -static void -run_loop_before_sources (void) -{ - GMainContext *context = g_main_context_default (); - gint max_priority; - gint nfds; - - /* Before we let the CFRunLoop process sources, we want to check if there - * are any pending GLib main loop sources more urgent than - * G_PRIORITY_DEFAULT that need to be dispatched. (We consider all activity - * from the CFRunLoop to have a priority of G_PRIORITY_DEFAULT.) If no - * sources are processed by the CFRunLoop, then processing will continue - * on to the BeforeWaiting stage where we check for lower priority sources. - */ - - g_main_context_prepare (context, &max_priority); - max_priority = MIN (max_priority, G_PRIORITY_DEFAULT); - - /* We ignore the timeout that query_main_context () returns since we'll - * always query again before waiting. - */ - nfds = query_main_context (context, max_priority, NULL); - - if (nfds) - old_poll_func (run_loop_pollfds, nfds, 0); - - if (g_main_context_check (context, max_priority, run_loop_pollfds, nfds)) - { - CLUTTER_NOTE (EVENTLOOP, "EventLoop: Dispatching high priority sources\n"); - g_main_context_dispatch (context); - } -} - -static void -dummy_timer_callback (CFRunLoopTimerRef timer, - void *info) -{ - /* Nothing; won't normally even be called */ -} - -static void -run_loop_before_waiting (void) -{ - GMainContext *context = g_main_context_default (); - gint timeout; - gint n_ready; - - /* At this point, the CFRunLoop is ready to wait. We start a GMain loop - * iteration by calling the check() and query() stages. We start a - * poll, and if it doesn't complete immediately we let the run loop - * go ahead and sleep. Before doing that, if there was a timeout from - * GLib, we set up a CFRunLoopTimer to wake us up. - */ - - g_main_context_prepare (context, &run_loop_max_priority); - - run_loop_n_pollfds = query_main_context (context, run_loop_max_priority, &timeout); - - n_ready = select_thread_start_poll (run_loop_pollfds, run_loop_n_pollfds, timeout); - - if (n_ready > 0 || timeout == 0) - { - /* We have stuff to do, no sleeping allowed! */ - CFRunLoopWakeUp (main_thread_run_loop); - } - else if (timeout > 0) - { - /* We need to get the run loop to break out of it's wait when our timeout - * expires. We do this by adding a dummy timer that we'll remove immediately - * after the wait wakes up. - */ - CLUTTER_NOTE (EVENTLOOP, "EventLoop: Adding timer to wake us up in %d milliseconds\n", timeout); - - run_loop_timer = CFRunLoopTimerCreate (NULL, /* allocator */ - CFAbsoluteTimeGetCurrent () + timeout / 1000., - 0, /* interval (0=does not repeat) */ - 0, /* flags */ - 0, /* order (priority) */ - dummy_timer_callback, - NULL); - - CFRunLoopAddTimer (main_thread_run_loop, run_loop_timer, kCFRunLoopCommonModes); - } - - run_loop_polling_async = n_ready < 0; -} - -static void -run_loop_after_waiting (void) -{ - GMainContext *context = g_main_context_default (); - - /* After sleeping, we finish of the GMain loop iteratin started in before_waiting() - * by doing the check() and dispatch() stages. - */ - - if (run_loop_timer) - { - CFRunLoopRemoveTimer (main_thread_run_loop, run_loop_timer, kCFRunLoopCommonModes); - CFRelease (run_loop_timer); - run_loop_timer = NULL; - } - - if (run_loop_polling_async) - { - select_thread_collect_poll (run_loop_pollfds, run_loop_n_pollfds); - run_loop_polling_async = FALSE; - } - - if (g_main_context_check (context, run_loop_max_priority, run_loop_pollfds, run_loop_n_pollfds)) - { - CLUTTER_NOTE (EVENTLOOP, "EventLoop: Dispatching after waiting\n"); - g_main_context_dispatch (context); - } -} - -static void -run_loop_exit (void) -{ - g_return_if_fail (current_loop_level > 0); - - if (current_loop_level == acquired_loop_level) - { - g_main_context_release (NULL); - acquired_loop_level = -1; - CLUTTER_NOTE (EVENTLOOP, "EventLoop: Ended tracking run loop activity\n"); - } - - current_loop_level--; -} - -static void -run_loop_observer_callback (CFRunLoopObserverRef observer, - CFRunLoopActivity activity, - void *info) -{ - if (getting_events) /* Activity we triggered */ - return; - - switch (activity) - { - case kCFRunLoopEntry: - run_loop_entry (); - break; - case kCFRunLoopBeforeTimers: - run_loop_before_timers (); - break; - case kCFRunLoopBeforeSources: - run_loop_before_sources (); - break; - case kCFRunLoopBeforeWaiting: - run_loop_before_waiting (); - break; - case kCFRunLoopAfterWaiting: - run_loop_after_waiting (); - break; - case kCFRunLoopExit: - run_loop_exit (); - break; - default: - break; - } -} - -/************************************************************/ - -void -_clutter_osx_event_loop_init (void) -{ - GSource *source; - CFRunLoopObserverRef observer; - - g_assert (old_poll_func == NULL); - - /* Hook into the GLib main loop */ - - event_poll_fd.events = G_IO_IN; - event_poll_fd.fd = -1; - - source = g_source_new (&event_funcs, sizeof (GSource)); - g_source_set_name (source, "Clutter OS X event source"); - g_source_add_poll (source, &event_poll_fd); - g_source_set_priority (source, CLUTTER_PRIORITY_EVENTS); - g_source_set_can_recurse (source, TRUE); - g_source_attach (source, NULL); - - old_poll_func = g_main_context_get_poll_func (NULL); - g_main_context_set_poll_func (NULL, poll_func); - - /* Hook into the the CFRunLoop for the main thread */ - - main_thread_run_loop = CFRunLoopGetCurrent (); - - observer = CFRunLoopObserverCreate (NULL, /* default allocator */ - kCFRunLoopAllActivities, - true, /* repeats: not one-shot */ - 0, /* order (priority) */ - run_loop_observer_callback, - NULL); - - CFRunLoopAddObserver (main_thread_run_loop, observer, kCFRunLoopCommonModes); - - /* Initialize our autorelease pool */ - - autorelease_pool = [[NSAutoreleasePool alloc] init]; -} diff --git a/clutter/osx/clutter-event-loop-osx.h b/clutter/osx/clutter-event-loop-osx.h deleted file mode 100644 index 1f7dd5698..000000000 --- a/clutter/osx/clutter-event-loop-osx.h +++ /dev/null @@ -1,32 +0,0 @@ -/* Clutter - An OpenGL based 'interactive canvas' library. - * OSX backend - event loop - * - * Copyright (C) 2005-2007 Imendio AB - * Copyright (C) 2011 Crystalnix - * - * 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 . - * - * - */ -#ifndef __CLUTTER_EVENT_LOOP_OSX_H__ -#define __CLUTTER_EVENT_LOOP_OSX_H__ - -G_BEGIN_DECLS - -/* Initialization */ -void _clutter_osx_event_loop_init (void); - -G_END_DECLS - -#endif diff --git a/clutter/osx/clutter-event-osx.c b/clutter/osx/clutter-event-osx.c deleted file mode 100644 index 4b53fefad..000000000 --- a/clutter/osx/clutter-event-osx.c +++ /dev/null @@ -1,497 +0,0 @@ -/* Clutter - An OpenGL based 'interactive canvas' library. - * OSX backend - event loops integration - * - * Copyright (C) 2007-2008 Tommi Komulainen - * Copyright (C) 2007 OpenedHand Ltd. - * Copyright (C) 2011 Crystalnix - * - * 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 . - * - * - */ -#include "config.h" - -#include "clutter-osx.h" - -#include "clutter-backend-osx.h" -#include "clutter-device-manager-osx.h" -#include "clutter-stage-osx.h" - -#import - -#include - -#include "clutter-debug.h" -#include "clutter-device-manager.h" -#include "clutter-event-private.h" -#include "clutter-keysyms.h" -#include "clutter-private.h" -#include "clutter-stage-private.h" - -#define WHEEL_DELTA 1 - -/*************************************************************************/ -@interface NSEvent (Clutter) -- (gint)clutterTime; -- (gint)clutterButton; -- (void)clutterX:(gfloat*)ptrX y:(gfloat*)ptrY; -- (gint)clutterModifierState; -- (guint)clutterKeyVal; -@end - -@implementation NSEvent (Clutter) -- (gint)clutterTime -{ - return [self timestamp] * 1000; -} - -- (gint)clutterButton -{ - switch ([self buttonNumber]) - { - case 0: return 1; /* left */ - case 1: return 3; /* right */ - case 2: return 2; /* middle */ - default: return 1 + [self buttonNumber]; - } -} - -- (void)clutterX:(gfloat*)ptrX y:(gfloat*)ptrY -{ - NSView *view = [[self window] contentView]; - NSPoint pt = [view convertPoint:[self locationInWindow] fromView:nil]; - - *ptrX = pt.x; - *ptrY = pt.y; -} - -- (gint)clutterModifierState -{ - guint mods = [self modifierFlags]; - guint type = [self type]; - gint rv = 0; - - /* add key masks */ - if (mods & NSAlphaShiftKeyMask) - rv |= CLUTTER_LOCK_MASK; - if (mods & NSShiftKeyMask) - rv |= CLUTTER_SHIFT_MASK; - if (mods & NSControlKeyMask) - rv |= CLUTTER_CONTROL_MASK; - if (mods & NSAlternateKeyMask) - rv |= CLUTTER_MOD1_MASK; - if (mods & NSCommandKeyMask) - rv |= CLUTTER_MOD2_MASK; - - /* add button mask */ - if ((type == NSLeftMouseDragged) || - (type == NSRightMouseDragged) || - (type == NSOtherMouseDragged)) - rv |= CLUTTER_BUTTON1_MASK << [self buttonNumber]; - - return rv; -} - -- (guint)clutterKeyVal -{ - unichar c; - - /* FIXME: doing this right is a lot of work, see gdkkeys-quartz.c in gtk+ - * For now handle some common/simple keys only. Might not work with other - * hardware than mine (MacBook Pro, finnish layout). Sorry. - * - * charactersIgnoringModifiers ignores most modifiers, not Shift though. - * So, for all Shift-modified keys we'll end up reporting 'keyval' identical - * to 'unicode_value' Instead of a or 3 you'd get A - * and # - */ - - if ([self type] == NSFlagsChanged) - { - switch ([self keyCode]) - { - case 54: // Right Command - return CLUTTER_KEY_Meta_R; - case 55: // Left Command - return CLUTTER_KEY_Meta_L; - case 57: // Capslock - return CLUTTER_KEY_Caps_Lock; - case 56: // Left Shift - return CLUTTER_KEY_Shift_L; - case 60: // Right Shift - return CLUTTER_KEY_Shift_R; - case 58: // Left Alt - return CLUTTER_KEY_Alt_L; - case 61: // Right Alt - return CLUTTER_KEY_Alt_R; - case 59: // Left Ctrl - return CLUTTER_KEY_Control_L; - case 62: // Right Ctrl - return CLUTTER_KEY_Control_R; - case 63: // Function - return CLUTTER_KEY_function; - default: // No such key??!?? - CLUTTER_NOTE (EVENT, "Got NSFlagsChanged event with keyCode not a known modifier key: %d", - [self keyCode]); - return CLUTTER_KEY_VoidSymbol; - } - } - - c = [[self charactersIgnoringModifiers] characterAtIndex:0]; - - /* Latin-1 characters, 1:1 mapping - this ought to be reliable */ - if ((c >= 0x0020 && c <= 0x007e) || - (c >= 0x00a0 && c <= 0x00ff)) - return c; - - switch (c) - { - /* these should be fairly standard */ - /* (maybe add 0x0008 (Ctrl+H) for backspace too) */ - case 0x000d: - return CLUTTER_KEY_Return; - case 0x001b: - return CLUTTER_KEY_Escape; - case 0x007f: - return CLUTTER_KEY_BackSpace; - /* Defined in NSEvent.h */ - case NSUpArrowFunctionKey: - return CLUTTER_KEY_Up; - case NSDownArrowFunctionKey: - return CLUTTER_KEY_Down; - case NSLeftArrowFunctionKey: - return CLUTTER_KEY_Left; - case NSRightArrowFunctionKey: - return CLUTTER_KEY_Right; - case NSF1FunctionKey: - return CLUTTER_KEY_F1; - case NSF2FunctionKey: - return CLUTTER_KEY_F2; - case NSF3FunctionKey: - return CLUTTER_KEY_F3; - case NSF4FunctionKey: - return CLUTTER_KEY_F4; - case NSF5FunctionKey: - return CLUTTER_KEY_F5; - case NSF6FunctionKey: - return CLUTTER_KEY_F6; - case NSF7FunctionKey: - return CLUTTER_KEY_F7; - case NSF8FunctionKey: - return CLUTTER_KEY_F8; - case NSF9FunctionKey: - return CLUTTER_KEY_F9; - case NSF10FunctionKey: - return CLUTTER_KEY_F10; - case NSF11FunctionKey: - return CLUTTER_KEY_F11; - case NSF12FunctionKey: - return CLUTTER_KEY_F12; - case NSInsertFunctionKey: - return CLUTTER_KEY_Insert; - case NSDeleteFunctionKey: - return CLUTTER_KEY_Delete; - case NSHomeFunctionKey: - return CLUTTER_KEY_Home; - case NSEndFunctionKey: - return CLUTTER_KEY_End; - case NSPageUpFunctionKey: - return CLUTTER_KEY_Page_Up; - case NSPageDownFunctionKey: - return CLUTTER_KEY_Page_Down; - } - - CLUTTER_NOTE (BACKEND, "unhandled unicode key 0x%x (%d)", c, c); - - /* hardware dependent, worksforme(tm) Redundant due to above, left around as - * example. - */ - switch ([self keyCode]) - { - case 115: - return CLUTTER_KEY_Home; - case 116: - return CLUTTER_KEY_Page_Up; - case 117: - return CLUTTER_KEY_Delete; - case 119: - return CLUTTER_KEY_End; - case 121: - return CLUTTER_KEY_Page_Down; - case 123: - return CLUTTER_KEY_Left; - case 124: - return CLUTTER_KEY_Right; - case 125: - return CLUTTER_KEY_Down; - case 126: - return CLUTTER_KEY_Up; - } - - return 0; -} -@end - -/*************************************************************************/ - -static void -take_and_queue_event (ClutterEvent *event) -{ - _clutter_event_push (event, FALSE); -} - -static void -process_scroll_event (ClutterEvent *event, - gboolean isVertical) -{ - ClutterStageWindow *impl; - ClutterStageOSX *stage_osx; - gfloat *scroll_pos; - - impl = _clutter_stage_get_window (event->any.stage); - stage_osx = CLUTTER_STAGE_OSX (impl); - - scroll_pos = isVertical - ? &(stage_osx->scroll_pos_y) - : &(stage_osx->scroll_pos_x); - - while (abs (*scroll_pos) >= WHEEL_DELTA) - { - ClutterEvent *event_gen = clutter_event_new (CLUTTER_SCROLL); - - event_gen->scroll.time = event->any.time; - event_gen->scroll.modifier_state = event->scroll.modifier_state; - event_gen->any.stage = event->any.stage; - - event_gen->scroll.x = event->scroll.x; - event_gen->scroll.y = event->scroll.y; - - if (*scroll_pos > 0) - { - event_gen->scroll.direction = isVertical ? CLUTTER_SCROLL_UP : CLUTTER_SCROLL_RIGHT; - *scroll_pos -= WHEEL_DELTA; - } - else - { - event_gen->scroll.direction = isVertical ? CLUTTER_SCROLL_DOWN : CLUTTER_SCROLL_LEFT; - *scroll_pos += WHEEL_DELTA; - } - - clutter_event_set_device (event_gen, clutter_event_get_device (event)); - - take_and_queue_event (event_gen); - - CLUTTER_NOTE (EVENT, "scroll %s at %f,%f", - (event_gen->scroll.direction == CLUTTER_SCROLL_UP) ? "UP" : - ( - (event_gen->scroll.direction == CLUTTER_SCROLL_DOWN) ? "DOWN" : - ( - (event_gen->scroll.direction == CLUTTER_SCROLL_RIGHT) ? "RIGHT" : "LEFT")), - event->scroll.x, event->scroll.y); - } -} - -static gboolean -clutter_event_osx_translate (NSEvent *nsevent, - ClutterEvent *event) -{ - ClutterDeviceManagerOSX *manager_osx; - ClutterDeviceManager *manager; - ClutterStageOSX *stage_osx; - ClutterStageWindow *impl; - ClutterStage *stage; - - manager = clutter_device_manager_get_default (); - if (manager == NULL) - return FALSE; - - stage = event->any.stage; - impl = _clutter_stage_get_window (event->any.stage); - stage_osx = CLUTTER_STAGE_OSX (impl); - manager_osx = CLUTTER_DEVICE_MANAGER_OSX (manager); - - event->any.time = [nsevent clutterTime]; - - switch ([nsevent type]) - { - case NSLeftMouseDown: - case NSRightMouseDown: - case NSOtherMouseDown: - event->type = CLUTTER_BUTTON_PRESS; - /* fall through */ - case NSLeftMouseUp: - case NSRightMouseUp: - case NSOtherMouseUp: - if (event->type != CLUTTER_BUTTON_PRESS) - event->type = CLUTTER_BUTTON_RELEASE; - - event->button.button = [nsevent clutterButton]; - event->button.click_count = [nsevent clickCount]; - event->motion.modifier_state = [nsevent clutterModifierState]; - [nsevent clutterX:&(event->button.x) y:&(event->button.y)]; - clutter_event_set_device (event, manager_osx->core_pointer); - - CLUTTER_NOTE (EVENT, "button %d %s at %f,%f clicks=%d", - (int)[nsevent buttonNumber], - event->type == CLUTTER_BUTTON_PRESS ? "press" : "release", - event->button.x, event->button.y, - event->button.click_count); - return TRUE; - - case NSMouseMoved: - case NSLeftMouseDragged: - case NSRightMouseDragged: - case NSOtherMouseDragged: - event->type = CLUTTER_MOTION; - - [nsevent clutterX:&(event->motion.x) y:&(event->motion.y)]; - event->motion.modifier_state = [nsevent clutterModifierState]; - clutter_event_set_device (event, manager_osx->core_pointer); - - CLUTTER_NOTE (EVENT, "motion %d at %f,%f", - (int)[nsevent buttonNumber], - event->button.x, event->button.y); - return TRUE; - - case NSMouseEntered: - event->type = CLUTTER_ENTER; - - [nsevent clutterX:&(event->crossing.x) y:&(event->crossing.y)]; - event->crossing.related = NULL; - event->crossing.source = CLUTTER_ACTOR (stage); - clutter_event_set_device (event, manager_osx->core_pointer); - - _clutter_input_device_set_stage (manager_osx->core_pointer, stage); - - CLUTTER_NOTE (EVENT, "enter at %f,%f", - event->crossing.x, event->crossing.y); - return TRUE; - - case NSMouseExited: - event->type = CLUTTER_LEAVE; - - [nsevent clutterX:&(event->crossing.x) y:&(event->crossing.y)]; - event->crossing.related = NULL; - event->crossing.source = CLUTTER_ACTOR (stage); - clutter_event_set_device (event, manager_osx->core_pointer); - - _clutter_input_device_set_stage (manager_osx->core_pointer, NULL); - - CLUTTER_NOTE (EVENT, "exit at %f,%f", - event->crossing.x, event->crossing.y); - return TRUE; - - case NSScrollWheel: - stage_osx->scroll_pos_x += [nsevent deltaX]; - stage_osx->scroll_pos_y += [nsevent deltaY]; - - [nsevent clutterX:&(event->scroll.x) y:&(event->scroll.y)]; - event->scroll.modifier_state = [nsevent clutterModifierState]; - clutter_event_set_device (event, manager_osx->core_pointer); - - process_scroll_event (event, TRUE); - process_scroll_event (event, FALSE); - break; - - case NSFlagsChanged: - // FIXME: This logic fails if the user presses both Shift keys at once, for example: - // we treat releasing one of them as keyDown. - switch ([nsevent keyCode]) - { - case 54: // Right Command - case 55: // Left Command - if ([nsevent modifierFlags] & NSCommandKeyMask) - event->type = CLUTTER_KEY_PRESS; - break; - - case 57: // Capslock - if ([nsevent modifierFlags] & NSAlphaShiftKeyMask) - event->type = CLUTTER_KEY_PRESS; - break; - - case 56: // Left Shift - case 60: // Right Shift - if ([nsevent modifierFlags] & NSShiftKeyMask) - event->type = CLUTTER_KEY_PRESS; - break; - - case 58: // Left Alt - case 61: // Right Alt - if ([nsevent modifierFlags] & NSAlternateKeyMask) - event->type = CLUTTER_KEY_PRESS; - break; - - case 59: // Left Ctrl - case 62: // Right Ctrl - if ([nsevent modifierFlags] & NSControlKeyMask) - event->type = CLUTTER_KEY_PRESS; - break; - - case 63: // Function - if ([nsevent modifierFlags] & NSFunctionKeyMask) - event->type = CLUTTER_KEY_PRESS; - break; - } - /* fall through */ - case NSKeyDown: - if ([nsevent type] == NSKeyDown) - event->type = CLUTTER_KEY_PRESS; - /* fall through */ - case NSKeyUp: - if (event->type != CLUTTER_KEY_PRESS) - event->type = CLUTTER_KEY_RELEASE; - - event->key.hardware_keycode = [nsevent keyCode]; - event->key.modifier_state = [nsevent clutterModifierState]; - event->key.keyval = [nsevent clutterKeyVal]; - event->key.unicode_value = ([nsevent type] == NSFlagsChanged) - ? (gunichar)'\0' - : [[nsevent characters] characterAtIndex:0]; - clutter_event_set_device (event, manager_osx->core_keyboard); - - CLUTTER_NOTE (EVENT, "key %d (%s) (%s) %s, keyval %d", - [nsevent keyCode], - ([nsevent type] == NSFlagsChanged) ? "NULL" : [[nsevent characters] UTF8String], - ([nsevent type] == NSFlagsChanged) ? "NULL" : [[nsevent charactersIgnoringModifiers] UTF8String], - (event->type == CLUTTER_KEY_PRESS) ? "press" : "release", - event->key.keyval); - return TRUE; - - default: - CLUTTER_NOTE (EVENT, "unhandled event %d", (int)[nsevent type]); - break; - } - - return FALSE; -} - -void -_clutter_event_osx_put (NSEvent *nsevent, - ClutterStage *wrapper) -{ - ClutterEvent *event = clutter_event_new (CLUTTER_NOTHING); - - /* common fields */ - event->any.stage = wrapper; - event->any.time = [nsevent clutterTime]; - - if (clutter_event_osx_translate (nsevent, event)) - { - g_assert (event->type != CLUTTER_NOTHING); - - _clutter_event_push (event, FALSE); - } - else - clutter_event_free (event); -} diff --git a/clutter/osx/clutter-osx.h b/clutter/osx/clutter-osx.h deleted file mode 100644 index 8930b0ad1..000000000 --- a/clutter/osx/clutter-osx.h +++ /dev/null @@ -1,38 +0,0 @@ -/* Clutter - An OpenGL based 'interactive canvas' library. - * OSX backend - * - * Copyright (C) 2007 Tommi Komulainen - * Copyright (C) 2007 OpenedHand Ltd. - * - * 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 . - * - * - */ -#ifndef __CLUTTER_OSX_H__ -#define __CLUTTER_OSX_H__ - -#import - -#include - -@class NSEvent; - -G_BEGIN_DECLS - -CLUTTER_AVAILABLE_IN_1_22 -void clutter_osx_disable_event_retrieval (void); - -G_END_DECLS - -#endif /* __CLUTTER_OSX_H__ */ diff --git a/clutter/osx/clutter-stage-osx.c b/clutter/osx/clutter-stage-osx.c deleted file mode 100644 index 9536e9588..000000000 --- a/clutter/osx/clutter-stage-osx.c +++ /dev/null @@ -1,715 +0,0 @@ -/* Clutter - An OpenGL based 'interactive canvas' library. - * OSX backend - integration with NSWindow and NSView - * - * Copyright (C) 2007-2008 Tommi Komulainen - * Copyright (C) 2007 OpenedHand Ltd. - * Copyright (C) 2011 Crystalnix - * - * 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 . - * - * - */ -#include "config.h" - -#import "clutter-osx.h" -#import "clutter-stage-osx.h" -#import "clutter-backend-osx.h" - -#include "clutter-debug.h" -#include "clutter-private.h" -#include "clutter-stage-private.h" - -enum -{ - PROP_0, - - PROP_BACKEND, - PROP_WRAPPER -}; - -static void clutter_stage_window_iface_init (ClutterStageWindowIface *iface); - -#define clutter_stage_osx_get_type _clutter_stage_osx_get_type - -G_DEFINE_TYPE_WITH_CODE (ClutterStageOSX, - clutter_stage_osx, - G_TYPE_OBJECT, - G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_STAGE_WINDOW, - clutter_stage_window_iface_init)) - -static ClutterActor * -clutter_stage_osx_get_wrapper (ClutterStageWindow *stage_window); - -#define CLUTTER_OSX_FULLSCREEN_WINDOW_LEVEL (NSMainMenuWindowLevel + 1) - -/*************************************************************************/ -@implementation ClutterGLWindow -- (id)initWithView:(NSView *)aView UTF8Title:(const char *)aTitle stage:(ClutterStageOSX *)aStage -{ - if ((self = [super initWithContentRect: [aView frame] - styleMask: NSTitledWindowMask | NSClosableWindowMask | NSResizableWindowMask - backing: NSBackingStoreBuffered - defer: NO]) != nil) - { - [self setDelegate: self]; - [self useOptimizedDrawing: YES]; - [self setAcceptsMouseMovedEvents:YES]; - [self setContentView: aView]; - [self setTitle:[NSString stringWithUTF8String: aTitle ? aTitle : ""]]; - self->stage_osx = aStage; - } - return self; -} - -- (BOOL) windowShouldClose: (id) sender -{ - ClutterEvent event; - - CLUTTER_NOTE (BACKEND, "[%p] windowShouldClose", self->stage_osx); - - event.type = CLUTTER_DELETE; - event.any.stage = self->stage_osx->wrapper; - clutter_event_put (&event); - - return NO; -} - -- (NSRect) constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen*)aScreen -{ - /* in fullscreen mode we don't want to be constrained by menubar or dock - * FIXME: calculate proper constraints depending on fullscreen mode - */ - - return frameRect; -} - -- (void) windowDidBecomeKey:(NSNotification*)aNotification -{ - ClutterStage *stage; - - CLUTTER_NOTE (BACKEND, "[%p] windowDidBecomeKey", self->stage_osx); - - stage = self->stage_osx->wrapper; - - if (_clutter_stage_is_fullscreen (stage)) - [self setLevel: CLUTTER_OSX_FULLSCREEN_WINDOW_LEVEL]; - - _clutter_stage_update_state (stage, 0, CLUTTER_STAGE_STATE_ACTIVATED); -} - -- (void) windowDidResignKey:(NSNotification*)aNotification -{ - ClutterStage *stage; - - CLUTTER_NOTE (BACKEND, "[%p] windowDidResignKey", self->stage_osx); - - stage = self->stage_osx->wrapper; - - if (_clutter_stage_is_fullscreen (stage)) - { - [self setLevel: NSNormalWindowLevel]; - if (!self->stage_osx->isHiding) - [self orderBack: nil]; - } - - _clutter_stage_update_state (stage, CLUTTER_STAGE_STATE_ACTIVATED, 0); -} - -- (NSSize) windowWillResize:(NSWindow *) sender toSize:(NSSize) frameSize -{ - if (clutter_stage_get_user_resizable (self->stage_osx->wrapper)) - { - guint min_width, min_height; - clutter_stage_get_minimum_size (self->stage_osx->wrapper, - &min_width, - &min_height); - [self setContentMinSize:NSMakeSize(min_width, min_height)]; - return frameSize; - } - else - return [self frame].size; -} - -- (void)windowDidChangeScreen:(NSNotification *)notification -{ - clutter_stage_ensure_redraw (self->stage_osx->wrapper); -} -@end - -/*************************************************************************/ -@interface ClutterGLView : NSOpenGLView -{ - ClutterStageOSX *stage_osx; - - NSTrackingRectTag trackingRect; -} -- (void) drawRect: (NSRect) bounds; -@end - -@implementation ClutterGLView -- (id) initWithFrame: (NSRect)aFrame pixelFormat:(NSOpenGLPixelFormat*)aFormat stage:(ClutterStageOSX*)aStage -{ - if ((self = [super initWithFrame:aFrame pixelFormat:aFormat]) != nil) - { - self->stage_osx = aStage; - trackingRect = [self addTrackingRect:[self bounds] - owner:self - userData:NULL - assumeInside:NO]; - } - - return self; -} - -- (void) dealloc -{ - if (trackingRect) - { - [self removeTrackingRect:trackingRect]; - trackingRect = 0; - } - - [super dealloc]; -} - -- (NSTrackingRectTag) trackingRect -{ - return trackingRect; -} - -- (ClutterActor *) clutterStage -{ - return (ClutterActor *) stage_osx->wrapper; -} - -- (void) drawRect: (NSRect) bounds -{ - ClutterActor *stage = [self clutterStage]; - - _clutter_stage_do_paint (CLUTTER_STAGE (stage), NULL); - - cogl_flush (); - - [[self openGLContext] flushBuffer]; -} - -/* In order to receive key events */ -- (BOOL) acceptsFirstResponder -{ - return YES; -} - -/* We want 0,0 top left */ -- (BOOL) isFlipped -{ - return YES; -} - -- (BOOL) isOpaque -{ - ClutterActor *stage = [self clutterStage]; - - if (CLUTTER_ACTOR_IN_DESTRUCTION (stage)) - return YES; - - if (clutter_stage_get_use_alpha (CLUTTER_STAGE (stage))) - return NO; - - return YES; -} - -- (void) reshape -{ - ClutterActor *stage; - - stage_osx->requisition_width = [self bounds].size.width; - stage_osx->requisition_height = [self bounds].size.height; - - stage = [self clutterStage]; - clutter_actor_set_size (stage, - stage_osx->requisition_width, - stage_osx->requisition_height); - - [self removeTrackingRect:trackingRect]; - trackingRect = [self addTrackingRect:[self bounds] - owner:self - userData:NULL - assumeInside:NO]; -} - -/* Simply forward all events that reach our view to clutter. */ - -#define EVENT_HANDLER(event) \ --(void)event:(NSEvent *) theEvent { \ - _clutter_event_osx_put (theEvent, stage_osx->wrapper); \ -} - -EVENT_HANDLER(mouseDown) -EVENT_HANDLER(mouseDragged) -EVENT_HANDLER(mouseUp) -EVENT_HANDLER(mouseMoved) -EVENT_HANDLER(mouseEntered) -EVENT_HANDLER(mouseExited) -EVENT_HANDLER(rightMouseDown) -EVENT_HANDLER(rightMouseDragged) -EVENT_HANDLER(rightMouseUp) -EVENT_HANDLER(otherMouseDown) -EVENT_HANDLER(otherMouseDragged) -EVENT_HANDLER(otherMouseUp) -EVENT_HANDLER(scrollWheel) -EVENT_HANDLER(keyDown) -EVENT_HANDLER(keyUp) -EVENT_HANDLER(flagsChanged) -EVENT_HANDLER(helpRequested) -EVENT_HANDLER(tabletPoint) -EVENT_HANDLER(tabletProximity) - -#undef EVENT_HANDLER -@end - -/*************************************************************************/ - -static void -clutter_stage_osx_save_frame (ClutterStageOSX *self) -{ - g_assert (self->window != NULL); - - self->normalFrame = [self->window frame]; - self->haveNormalFrame = TRUE; -} - -static void -clutter_stage_osx_set_frame (ClutterStageOSX *self) -{ - g_assert (self->window != NULL); - - if (_clutter_stage_is_fullscreen (self->wrapper)) - { - /* Raise above the menubar (and dock) covering the whole screen. - * - * NOTE: This effectively breaks Option-Tabbing as our window covers - * all other applications completely. However we deal with the situation - * by lowering the window to the bottom of the normal level stack on - * windowDidResignKey notification. - */ - [self->window setLevel: CLUTTER_OSX_FULLSCREEN_WINDOW_LEVEL]; - - [self->window setFrame: [self->window frameRectForContentRect: [[self->window screen] frame]] - display: NO]; - } - else - { - [self->window setLevel: NSNormalWindowLevel]; - - if (self->haveNormalFrame) - [self->window setFrame: self->normalFrame display: NO]; - else - { - /* looks better than positioning to 0,0 (bottom right) */ - [self->window center]; - } - } -} - -/*************************************************************************/ -static gboolean -clutter_stage_osx_realize (ClutterStageWindow *stage_window) -{ - ClutterStageOSX *self = CLUTTER_STAGE_OSX (stage_window); - gfloat width, height; - NSRect rect; - - CLUTTER_OSX_POOL_ALLOC(); - - CLUTTER_NOTE (BACKEND, "[%p] realize", self); - - if (!self->haveRealized) - { - ClutterBackendOSX *backend_osx; - - backend_osx = CLUTTER_BACKEND_OSX (self->backend); - - /* Call get_size - this will either get the geometry size (which - * before we create the window is set to 640x480), or if a size - * is set, it will get that. This lets you set a size on the - * stage before it's realized. - */ - clutter_actor_get_size (CLUTTER_ACTOR (self->wrapper), &width, &height); - self->requisition_width = width; - self->requisition_height= height; - - rect = NSMakeRect (0, 0, self->requisition_width, self->requisition_height); - - self->view = [[ClutterGLView alloc] - initWithFrame: rect - pixelFormat: backend_osx->pixel_format - stage: self]; - [self->view setOpenGLContext:backend_osx->context]; - - self->window = [[ClutterGLWindow alloc] - initWithView: self->view - UTF8Title: clutter_stage_get_title (CLUTTER_STAGE (self->wrapper)) - stage: self]; - /* looks better than positioning to 0,0 (bottom right) */ - [self->window center]; - self->haveRealized = true; - - CLUTTER_NOTE (BACKEND, "Stage successfully realized"); - } - - CLUTTER_OSX_POOL_RELEASE(); - - return TRUE; -} - -static void -clutter_stage_osx_unrealize (ClutterStageWindow *stage_window) -{ - ClutterStageOSX *self = CLUTTER_STAGE_OSX (stage_window); - - CLUTTER_OSX_POOL_ALLOC(); - - CLUTTER_NOTE (BACKEND, "[%p] unrealize", self); - - /* ensure we get realize+unrealize properly paired */ - g_return_if_fail (self->view != NULL && self->window != NULL); - - [self->view release]; - [self->window close]; - - self->view = NULL; - self->window = NULL; - self->haveRealized = false; - - CLUTTER_OSX_POOL_RELEASE(); -} - -static void -clutter_stage_osx_show (ClutterStageWindow *stage_window, - gboolean do_raise) -{ - ClutterStageOSX *self = CLUTTER_STAGE_OSX (stage_window); - BOOL isViewHidden; - NSPoint nspoint; - - CLUTTER_OSX_POOL_ALLOC(); - - CLUTTER_NOTE (BACKEND, "[%p] show", self); - - clutter_stage_osx_realize (stage_window); - clutter_actor_map (CLUTTER_ACTOR (self->wrapper)); - - clutter_stage_osx_set_frame (self); - - /* Draw view should be avoided and it is the reason why - * we should hide OpenGL view while we showing the stage. - */ - isViewHidden = [self->view isHidden]; - if (isViewHidden == NO) - [self->view setHidden:YES]; - - if (self->acceptFocus) - [self->window makeKeyAndOrderFront: nil]; - else - [self->window orderFront: nil]; - - /* If the window is placed directly under the mouse pointer, Quartz will - * not send a NSMouseEntered event; we can easily synthesize one ourselves - * though. - */ - nspoint = [self->window mouseLocationOutsideOfEventStream]; - if ([self->view mouse:nspoint inRect:[self->view frame]]) - { - NSEvent *event; - - event = [NSEvent enterExitEventWithType: NSMouseEntered - location: NSMakePoint(0, 0) - modifierFlags: 0 - timestamp: 0 - windowNumber: [self->window windowNumber] - context: NULL - eventNumber: 0 - trackingNumber: [self->view trackingRect] - userData: nil]; - - [NSApp postEvent:event atStart:NO]; - } - - [self->view setHidden:isViewHidden]; - [self->window setExcludedFromWindowsMenu:NO]; - - /* - * After hiding we cease to be first responder. - */ - [self->window makeFirstResponder: self->view]; - - CLUTTER_OSX_POOL_RELEASE(); -} - -static void -clutter_stage_osx_hide (ClutterStageWindow *stage_window) -{ - ClutterStageOSX *self = CLUTTER_STAGE_OSX (stage_window); - - CLUTTER_OSX_POOL_ALLOC(); - - CLUTTER_NOTE (BACKEND, "[%p] hide", self); - - self->isHiding = true; - [self->window orderOut: nil]; - [self->window setExcludedFromWindowsMenu:YES]; - - clutter_actor_unmap (CLUTTER_ACTOR (self->wrapper)); - - self->isHiding = false; - - CLUTTER_OSX_POOL_RELEASE(); -} - -static void -clutter_stage_osx_get_geometry (ClutterStageWindow *stage_window, - cairo_rectangle_int_t *geometry) -{ - ClutterBackend *backend = clutter_get_default_backend (); - ClutterStageOSX *self = CLUTTER_STAGE_OSX (stage_window); - - g_return_if_fail (CLUTTER_IS_BACKEND_OSX (backend)); - - geometry->width = self->requisition_width; - geometry->height = self->requisition_height; -} - -static void -clutter_stage_osx_resize (ClutterStageWindow *stage_window, - gint width, - gint height) -{ - ClutterStageOSX *self = CLUTTER_STAGE_OSX (stage_window); - ClutterActor *actor = clutter_stage_osx_get_wrapper (stage_window); - guint min_width, min_height; - NSSize size; - - CLUTTER_OSX_POOL_ALLOC (); - - clutter_stage_get_minimum_size (CLUTTER_STAGE (actor), - &min_width, - &min_height); - - [self->window setContentMinSize: NSMakeSize (min_width, min_height)]; - - width = width < min_width ? min_width : width; - height = height < min_height ? min_height : height; - - self->requisition_width = width; - self->requisition_height = height; - - size = NSMakeSize (self->requisition_width, self->requisition_height); - [self->window setContentSize: size]; - - CLUTTER_OSX_POOL_RELEASE (); -} - -/*************************************************************************/ -static ClutterActor * -clutter_stage_osx_get_wrapper (ClutterStageWindow *stage_window) -{ - ClutterStageOSX *self = CLUTTER_STAGE_OSX (stage_window); - - 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_OSX_POOL_ALLOC(); - - CLUTTER_NOTE (BACKEND, "[%p] set_title: %s", self, title); - - [self->window setTitle:[NSString stringWithUTF8String: title ? title : ""]]; - - CLUTTER_OSX_POOL_RELEASE(); -} - -static void -clutter_stage_osx_set_fullscreen (ClutterStageWindow *stage_window, - gboolean fullscreen) -{ - ClutterStageOSX *self = CLUTTER_STAGE_OSX (stage_window); - - CLUTTER_OSX_POOL_ALLOC(); - - CLUTTER_NOTE (BACKEND, "[%p] set_fullscreen: %u", self, fullscreen); - - /* Make sure to update the state before clutter_stage_osx_set_frame. - * - * Toggling fullscreen isn't atomic, there's two "events" involved: - * - stage state change (via state_update) - * - stage size change (via set_frame -> setFrameSize / set_size) - * - * We do state change first. Not sure there's any difference. - */ - if (fullscreen) - { - _clutter_stage_update_state (CLUTTER_STAGE (self->wrapper), - 0, - CLUTTER_STAGE_STATE_FULLSCREEN); - clutter_stage_osx_save_frame (self); - } - else - { - _clutter_stage_update_state (CLUTTER_STAGE (self->wrapper), - CLUTTER_STAGE_STATE_FULLSCREEN, - 0); - } - - clutter_stage_osx_set_frame (self); - - CLUTTER_OSX_POOL_RELEASE(); -} -static void -clutter_stage_osx_set_cursor_visible (ClutterStageWindow *stage_window, - gboolean cursor_visible) -{ - CLUTTER_OSX_POOL_ALLOC(); - - if (cursor_visible) - [NSCursor unhide]; - else - [NSCursor hide]; - - CLUTTER_OSX_POOL_RELEASE(); -} - -static void -clutter_stage_osx_set_user_resizable (ClutterStageWindow *stage_window, - gboolean is_resizable) -{ - ClutterStageOSX *self = CLUTTER_STAGE_OSX (stage_window); - - CLUTTER_OSX_POOL_ALLOC(); - - [self->window setShowsResizeIndicator:is_resizable]; - - CLUTTER_OSX_POOL_RELEASE(); -} - -static void -clutter_stage_osx_set_accept_focus (ClutterStageWindow *stage_window, - gboolean accept_focus) -{ - ClutterStageOSX *self = CLUTTER_STAGE_OSX (stage_window); - - CLUTTER_OSX_POOL_ALLOC(); - - self->acceptFocus = !!accept_focus; - - CLUTTER_OSX_POOL_RELEASE(); -} - -static void -clutter_stage_osx_redraw (ClutterStageWindow *stage_window) -{ - ClutterStageOSX *stage_osx = CLUTTER_STAGE_OSX (stage_window); - - CLUTTER_OSX_POOL_ALLOC(); - - if (stage_osx->view != NULL) - [stage_osx->view setNeedsDisplay: YES]; - - 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; - iface->show = clutter_stage_osx_show; - iface->hide = clutter_stage_osx_hide; - iface->realize = clutter_stage_osx_realize; - iface->unrealize = clutter_stage_osx_unrealize; - iface->get_geometry = clutter_stage_osx_get_geometry; - iface->resize = clutter_stage_osx_resize; - iface->set_cursor_visible = clutter_stage_osx_set_cursor_visible; - iface->set_user_resizable = clutter_stage_osx_set_user_resizable; - iface->set_accept_focus = clutter_stage_osx_set_accept_focus; - iface->redraw = clutter_stage_osx_redraw; -} - -/*************************************************************************/ -static void -clutter_stage_osx_init (ClutterStageOSX *self) -{ - self->requisition_width = 640; - self->requisition_height = 480; - 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 -clutter_stage_osx_finalize (GObject *gobject) -{ - G_OBJECT_CLASS (clutter_stage_osx_parent_class)->finalize (gobject); -} - -static void -clutter_stage_osx_dispose (GObject *gobject) -{ - G_OBJECT_CLASS (clutter_stage_osx_parent_class)->dispose (gobject); -} - -static void -clutter_stage_osx_class_init (ClutterStageOSXClass *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->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"); -} diff --git a/clutter/osx/clutter-stage-osx.h b/clutter/osx/clutter-stage-osx.h deleted file mode 100644 index cb2c1267e..000000000 --- a/clutter/osx/clutter-stage-osx.h +++ /dev/null @@ -1,85 +0,0 @@ -/* Clutter - An OpenGL based 'interactive canvas' library. - * OSX backend - integration with NSWindow and NSView - * - * Copyright (C) 2007 Tommi Komulainen - * Copyright (C) 2007 OpenedHand Ltd. - * - * 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 . - * - * - */ -#ifndef __CLUTTER_STAGE_OSX_H__ -#define __CLUTTER_STAGE_OSX_H__ - -#include -#include -#include - -#import -#import - -G_BEGIN_DECLS - -/* convenience macros */ -#define CLUTTER_TYPE_STAGE_OSX (_clutter_stage_osx_get_type()) -#define CLUTTER_STAGE_OSX(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),CLUTTER_TYPE_STAGE_OSX,ClutterStageOSX)) -#define CLUTTER_STAGE_OSX_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),CLUTTER_TYPE_STAGE_OSX,ClutterStage)) -#define CLUTTER_IS_STAGE_OSX(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),CLUTTER_TYPE_STAGE_OSX)) -#define CLUTTER_IS_STAGE_OSX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),CLUTTER_TYPE_STAGE_OSX)) -#define CLUTTER_STAGE_OSX_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj),CLUTTER_TYPE_STAGE_OSX,ClutterStageOSXClass)) - -typedef struct _ClutterStageOSX ClutterStageOSX; -typedef struct _ClutterStageOSXClass ClutterStageOSXClass; - -@interface ClutterGLWindow : NSWindow -{ -@public - ClutterStageOSX *stage_osx; -} -@end - -struct _ClutterStageOSX -{ - GObject parent; - - ClutterBackend *backend; - ClutterStage *wrapper; - - NSWindow *window; - NSOpenGLView *view; - - gboolean haveNormalFrame; - NSRect normalFrame; - - gint requisition_width; - gint requisition_height; - - gboolean acceptFocus; - gboolean isHiding; - gboolean haveRealized; - - gfloat scroll_pos_x; - gfloat scroll_pos_y; -}; - -struct _ClutterStageOSXClass -{ - GObjectClass parent_class; -}; - -GType _clutter_stage_osx_get_type (void) G_GNUC_CONST; - -G_END_DECLS - -#endif /* __CLUTTER_STAGE_OSX_H__ */ diff --git a/configure.ac b/configure.ac index 381a942f7..c45a80e27 100644 --- a/configure.ac +++ b/configure.ac @@ -87,13 +87,7 @@ dnl = Preliminary platform checks ============================================= AC_CANONICAL_HOST -platform_quartz=no -platform_linux=no - -AC_CHECK_HEADER([OpenGL/gl.h], [platform_quartz=yes], [platform_quartz=no]) -AM_CONDITIONAL(OS_QUARTZ, [test "$platform_quartz" = "yes"]) - -AM_CONDITIONAL(OS_LINUX, [test "$platform_linux" = "yes"]) +AC_DEFINE([OS_LINUX], [1], [Define to 1 if building for Linux]) AC_SUBST(CLUTTER_LT_LDFLAGS) @@ -220,10 +214,6 @@ AC_ARG_ENABLE([x11-backend], [AS_HELP_STRING([--enable-x11-backend=@<:@yes/no@:>@], [Enable the X11 backend (default=check)])], [enable_x11=$enableval], [enable_x11=check]) -AC_ARG_ENABLE([quartz-backend], - [AS_HELP_STRING([--enable-quartz-backend=@<:@yes/no@:>@], [Enable the OS X backend (default=check)])], - [enable_osx=$enableval], - [enable_osx=check]) AC_ARG_ENABLE([gdk-backend], [AS_HELP_STRING([--enable-gdk-backend=@<:@yes/no@:>@], [Enable the GDK backend (default=check)])], [enable_gdk=$enableval], @@ -252,10 +242,6 @@ AS_IF([test "x$enable_x11" = xcheck], [ PKG_CHECK_EXISTS([x11], [enable_x11=yes], [enable_x11=no]) ]) -AS_IF([test "x$enable_osx" = xcheck], [ - AS_IF([test "x$platform_quartz" = "xyes"], [enable_osx=yes], [enable_osx=no]) -]) - AS_IF([test "x$enable_gdk" = xcheck], [ PKG_CHECK_EXISTS([gdk-3.0 >= gdk_req_version], [enable_gdk=yes], [enable_gdk=no]) ]) @@ -387,26 +373,11 @@ AS_IF([test "x$enable_egl" = "xyes"], AC_DEFINE([CLUTTER_EGL_BACKEND_GENERIC], [1], [Use Generic EGL backend]) ]) -AS_IF([test "x$enable_osx" = "xyes"], - [ - CLUTTER_BACKENDS="$CLUTTER_BACKENDS osx" - CLUTTER_INPUT_BACKENDS="$CLUTTER_INPUT_BACKENDS osx" - - FLAVOUR_LIBS="$FLAVOUR_LIBS -framework Cocoa -framework OpenGL" - - SUPPORT_OSX=1 - ]) - AS_IF([test "x$CLUTTER_BACKENDS" = "x"], [ AC_MSG_ERROR([No backend enabled. You need to enable at least one backend.]) ]) -AS_IF([test "x$platform_linux" = "xyes"], - [ - AC_DEFINE([OS_LINUX], [1], [Define to 1 if building for Linux]) - ]) - AS_IF([test "x$enable_tslib" = xyes], [ PKG_CHECK_EXISTS([tslib-1.0], [have_tslib=yes], [have_tslib=no]) AS_IF([test "x$have_tslib" = xyes], [ @@ -432,7 +403,6 @@ AM_CONDITIONAL(SUPPORT_GLX, [test "x$SUPPORT_GLX" = "x1"]) AM_CONDITIONAL(SUPPORT_X11, [test "x$SUPPORT_X11" = "x1"]) AM_CONDITIONAL(SUPPORT_GDK, [test "x$SUPPORT_GDK" = "x1"]) AM_CONDITIONAL(SUPPORT_EGL, [test "x$SUPPORT_EGL" = "x1"]) -AM_CONDITIONAL(SUPPORT_OSX, [test "x$SUPPORT_OSX" = "x1"]) AM_CONDITIONAL(SUPPORT_WAYLAND, [test "x$SUPPORT_WAYLAND" = "x1"]) AM_CONDITIONAL(USE_COGL, [test "x$SUPPORT_COGL" = "x1"]) @@ -484,10 +454,6 @@ AS_IF([test "x$SUPPORT_EGL" = "x1"], AS_IF([test "x$SUPPORT_WAYLAND" = "x1"], [CLUTTER_CONFIG_DEFINES="$CLUTTER_CONFIG_DEFINES #define CLUTTER_WINDOWING_WAYLAND \"wayland\""]) -AS_IF([test "x$SUPPORT_OSX" = "x1"], - [CLUTTER_CONFIG_DEFINES="$CLUTTER_CONFIG_DEFINES -#define CLUTTER_WINDOWING_OSX \"osx\" -#define CLUTTER_INPUT_OSX \"osx\""]) AS_IF([test "x$SUPPORT_EVDEV" = "x1"], [CLUTTER_CONFIG_DEFINES="$CLUTTER_CONFIG_DEFINES #define CLUTTER_INPUT_EVDEV \"evdev\""])