diff --git a/src/Makefile.am b/src/Makefile.am index 09721c08d..816eef6a6 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -49,6 +49,7 @@ wayland_protocols = \ libmutter_la_SOURCES = \ backends/meta-backend.c \ backends/meta-backend.h \ + backends/meta-backend-private.h \ backends/meta-cursor.c \ backends/meta-cursor.h \ backends/meta-cursor-private.h \ diff --git a/src/backends/meta-backend-private.h b/src/backends/meta-backend-private.h new file mode 100644 index 000000000..1f54b8611 --- /dev/null +++ b/src/backends/meta-backend-private.h @@ -0,0 +1,53 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2014 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Jasper St. Pierre + */ + + +#ifndef META_BACKEND_PRIVATE_H +#define META_BACKEND_PRIVATE_H + +#include + +#include "meta-backend.h" + +#define META_TYPE_BACKEND (meta_backend_get_type ()) +#define META_BACKEND(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_BACKEND, MetaBackend)) +#define META_BACKEND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_BACKEND, MetaBackendClass)) +#define META_IS_BACKEND(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_BACKEND)) +#define META_IS_BACKEND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_BACKEND)) +#define META_BACKEND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_BACKEND, MetaBackendClass)) + +struct _MetaBackend +{ + GObject parent; + + MetaIdleMonitor *device_monitors[256]; + int device_id_max; +}; + +struct _MetaBackendClass +{ + GObjectClass parent_class; +}; + +#endif /* META_BACKEND_PRIVATE_H */ diff --git a/src/backends/meta-backend.c b/src/backends/meta-backend.c index b8a6dc1cf..967d98306 100644 --- a/src/backends/meta-backend.c +++ b/src/backends/meta-backend.c @@ -25,6 +25,7 @@ #include "config.h" #include "meta-backend.h" +#include "meta-backend-private.h" #include #include @@ -34,6 +35,118 @@ #include "backends/native/meta-weston-launch.h" #include +#include "backends/x11/meta-idle-monitor-xsync.h" +#include "backends/native/meta-idle-monitor-native.h" + +static MetaBackend *_backend; + +MetaBackend * +meta_get_backend (void) +{ + return _backend; +} + +G_DEFINE_TYPE (MetaBackend, meta_backend, G_TYPE_OBJECT); + +static void +meta_backend_finalize (GObject *object) +{ + MetaBackend *backend = META_BACKEND (object); + int i; + + for (i = 0; i <= backend->device_id_max; i++) + { + if (backend->device_monitors[i]) + g_object_unref (backend->device_monitors[i]); + } + + G_OBJECT_CLASS (meta_backend_parent_class)->finalize (object); +} + +static void +meta_backend_class_init (MetaBackendClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = meta_backend_finalize; +} + +static void +meta_backend_init (MetaBackend *backend) +{ + _backend = backend; +} + +static GType +get_idle_monitor_type (void) +{ +#if defined(CLUTTER_WINDOWING_X11) + if (clutter_check_windowing_backend (CLUTTER_WINDOWING_X11)) + return META_TYPE_IDLE_MONITOR_XSYNC; +#endif + + return META_TYPE_IDLE_MONITOR_NATIVE; +} + +/* FIXME -- destroy device monitors at some point */ +G_GNUC_UNUSED static void +destroy_device_monitor (MetaBackend *backend, + int device_id) +{ + g_clear_object (&backend->device_monitors[device_id]); + if (device_id == backend->device_id_max) + backend->device_id_max--; +} + +MetaIdleMonitor * +meta_backend_get_idle_monitor (MetaBackend *backend, + int device_id) +{ + g_return_val_if_fail (device_id >= 0 && device_id < 256, NULL); + + if (!backend->device_monitors[device_id]) + { + backend->device_monitors[device_id] = g_object_new (get_idle_monitor_type (), + "device-id", device_id, + NULL); + backend->device_id_max = MAX (backend->device_id_max, device_id); + } + + return backend->device_monitors[device_id]; +} + +void +meta_backend_x11_handle_alarm_notify (MetaBackend *backend, + XEvent *xevent) +{ + int i; + + for (i = 0; i <= backend->device_id_max; i++) + { + if (backend->device_monitors[i]) + { + if (!META_IS_IDLE_MONITOR_XSYNC (backend->device_monitors[i])) + return; + + meta_idle_monitor_xsync_handle_xevent (backend->device_monitors[i], (XSyncAlarmNotifyEvent*)xevent); + } + } +} + +static GType +get_backend_type (void) +{ + return META_TYPE_BACKEND; +} + +static void +meta_create_backend (void) +{ + /* The initializer above installs it in _backend so meta_get_backend + * is valid during initialization. */ + g_object_new (get_backend_type (), NULL); +} + /* Mutter is responsible for pulling events off the X queue, so Clutter * doesn't need (and shouldn't) run its normal event source which polls * the X fd, but we do have to deal with dispatching events that accumulate @@ -89,6 +202,8 @@ meta_clutter_init (void) { GSource *source; + meta_create_backend (); + /* When running as an X11 compositor, we install our own event filter and * pass events to Clutter explicitly, so we need to prevent Clutter from * handling our events. diff --git a/src/backends/meta-backend.h b/src/backends/meta-backend.h index 03d8a5633..0e718a3d9 100644 --- a/src/backends/meta-backend.h +++ b/src/backends/meta-backend.h @@ -27,6 +27,22 @@ #include +#include +#include + +typedef struct _MetaBackend MetaBackend; +typedef struct _MetaBackendClass MetaBackendClass; + +GType meta_backend_get_type (void); + +MetaBackend * meta_get_backend (void); + +MetaIdleMonitor * meta_backend_get_idle_monitor (MetaBackend *backend, + int device_id); + +void meta_backend_x11_handle_alarm_notify (MetaBackend *backend, + XEvent *event); + void meta_clutter_init (void); gboolean meta_activate_vt (int vt, GError **error); diff --git a/src/backends/meta-idle-monitor.c b/src/backends/meta-idle-monitor.c index 5e18f1b1d..adc96ab3d 100644 --- a/src/backends/meta-idle-monitor.c +++ b/src/backends/meta-idle-monitor.c @@ -38,8 +38,7 @@ #include #include "meta-idle-monitor-private.h" #include "meta-idle-monitor-dbus.h" -#include "backends/x11/meta-idle-monitor-xsync.h" -#include "backends/native/meta-idle-monitor-native.h" +#include "meta-backend.h" G_STATIC_ASSERT(sizeof(unsigned long) == sizeof(gpointer)); @@ -54,9 +53,6 @@ static GParamSpec *obj_props[PROP_LAST]; G_DEFINE_TYPE (MetaIdleMonitor, meta_idle_monitor, G_TYPE_OBJECT) -static MetaIdleMonitor *device_monitors[256]; -static int device_id_max; - void _meta_idle_monitor_watch_fire (MetaIdleMonitorWatch *watch) { @@ -160,38 +156,6 @@ meta_idle_monitor_init (MetaIdleMonitor *monitor) { } -static GType -get_idle_monitor_type (void) -{ -#if defined(CLUTTER_WINDOWING_X11) - if (clutter_check_windowing_backend (CLUTTER_WINDOWING_X11)) - return META_TYPE_IDLE_MONITOR_XSYNC; -#endif - - return META_TYPE_IDLE_MONITOR_NATIVE; -} - -static void -ensure_device_monitor (int device_id) -{ - if (device_monitors[device_id]) - return; - - device_monitors[device_id] = g_object_new (get_idle_monitor_type (), - "device-id", device_id, - NULL); - device_id_max = MAX (device_id_max, device_id); -} - -/* FIXME -- destroy device monitors at some point */ -G_GNUC_UNUSED static void -destroy_device_monitor (int device_id) -{ - g_clear_object (&device_monitors[device_id]); - if (device_id == device_id_max) - device_id_max--; -} - /** * meta_idle_monitor_get_core: * @@ -202,8 +166,8 @@ destroy_device_monitor (int device_id) MetaIdleMonitor * meta_idle_monitor_get_core (void) { - ensure_device_monitor (0); - return device_monitors[0]; + MetaBackend *backend = meta_get_backend (); + return meta_backend_get_idle_monitor (backend, 0); } /** @@ -217,10 +181,8 @@ meta_idle_monitor_get_core (void) MetaIdleMonitor * meta_idle_monitor_get_for_device (int device_id) { - g_return_val_if_fail (device_id > 0 && device_id < 256, NULL); - - ensure_device_monitor (device_id); - return device_monitors[device_id]; + MetaBackend *backend = meta_get_backend (); + return meta_backend_get_idle_monitor (backend, device_id); } static MetaIdleMonitorWatch * @@ -354,20 +316,3 @@ meta_idle_monitor_get_idletime (MetaIdleMonitor *monitor) { return META_IDLE_MONITOR_GET_CLASS (monitor)->get_idletime (monitor); } - -void -meta_idle_monitor_xsync_handle_xevent_all (XEvent *xevent) -{ - int i; - - for (i = 0; i <= device_id_max; i++) - { - if (device_monitors[i]) - { - if (!META_IS_IDLE_MONITOR_XSYNC (device_monitors[i])) - return; - - meta_idle_monitor_xsync_handle_xevent (device_monitors[i], (XSyncAlarmNotifyEvent*)xevent); - } - } -} diff --git a/src/backends/x11/meta-idle-monitor-xsync.h b/src/backends/x11/meta-idle-monitor-xsync.h index f8e88f09e..e349cfa9c 100644 --- a/src/backends/x11/meta-idle-monitor-xsync.h +++ b/src/backends/x11/meta-idle-monitor-xsync.h @@ -44,6 +44,4 @@ GType meta_idle_monitor_xsync_get_type (void); void meta_idle_monitor_xsync_handle_xevent (MetaIdleMonitor *monitor, XSyncAlarmNotifyEvent *xevent); -void meta_idle_monitor_xsync_handle_xevent_all (XEvent *xevent); - #endif /* META_IDLE_MONITOR_XSYNC_H */ diff --git a/src/core/events.c b/src/core/events.c index 90d346a73..34c84a039 100644 --- a/src/core/events.c +++ b/src/core/events.c @@ -34,6 +34,7 @@ #include "window-private.h" #include "bell.h" #include "workspace-private.h" +#include "backends/meta-backend.h" #include "backends/x11/meta-idle-monitor-xsync.h" #include "backends/native/meta-idle-monitor-native.h" @@ -1264,7 +1265,10 @@ handle_other_xevent (MetaDisplay *display, bypass_gtk = TRUE; /* GTK doesn't want to see this really */ } else - meta_idle_monitor_xsync_handle_xevent_all (event); + { + MetaBackend *backend = meta_get_backend (); + meta_backend_x11_handle_alarm_notify (backend, event); + } goto out; }