diff --git a/src/backends/meta-backend-types.h b/src/backends/meta-backend-types.h index 146a8c3d7..eae62c02f 100644 --- a/src/backends/meta-backend-types.h +++ b/src/backends/meta-backend-types.h @@ -59,6 +59,9 @@ typedef struct _MetaScreenCastStream MetaScreenCastStream; typedef struct _MetaWaylandCompositor MetaWaylandCompositor; +typedef struct _MetaVirtualMonitor MetaVirtualMonitor; +typedef struct _MetaVirtualMonitorInfo MetaVirtualMonitorInfo; + #ifdef HAVE_REMOTE_DESKTOP typedef struct _MetaRemoteDesktop MetaRemoteDesktop; #endif diff --git a/src/backends/meta-monitor-manager-private.h b/src/backends/meta-monitor-manager-private.h index 70d61f823..fd30ebb58 100644 --- a/src/backends/meta-monitor-manager-private.h +++ b/src/backends/meta-monitor-manager-private.h @@ -261,6 +261,10 @@ struct _MetaMonitorManagerClass void (* set_output_ctm) (MetaOutput *output, const MetaOutputCtm *ctm); + + MetaVirtualMonitor * (* create_virtual_monitor) (MetaMonitorManager *manager, + const MetaVirtualMonitorInfo *info, + GError **error); }; META_EXPORT_TEST @@ -388,6 +392,10 @@ gboolean meta_monitor_manager_get_max_screen_size (MetaMonitorManager MetaLogicalMonitorLayoutMode meta_monitor_manager_get_default_layout_mode (MetaMonitorManager *manager); +MetaVirtualMonitor * meta_monitor_manager_create_virtual_monitor (MetaMonitorManager *manager, + const MetaVirtualMonitorInfo *info, + GError **error); + MetaMonitorConfigManager * meta_monitor_manager_get_config_manager (MetaMonitorManager *manager); @@ -424,4 +432,6 @@ void meta_monitor_manager_post_init (MetaMonitorManager *manager); MetaViewportInfo * meta_monitor_manager_get_viewports (MetaMonitorManager *manager); +GList * meta_monitor_manager_get_virtual_monitors (MetaMonitorManager *manager); + #endif /* META_MONITOR_MANAGER_PRIVATE_H */ diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c index 8744d729e..005fa6791 100644 --- a/src/backends/meta-monitor-manager.c +++ b/src/backends/meta-monitor-manager.c @@ -53,6 +53,7 @@ #include "backends/meta-monitor-config-manager.h" #include "backends/meta-orientation-manager.h" #include "backends/meta-output.h" +#include "backends/meta-virtual-monitor.h" #include "backends/x11/meta-monitor-manager-xrandr.h" #include "clutter/clutter.h" #include "core/main-private.h" @@ -101,6 +102,10 @@ typedef struct _MetaMonitorManagerPrivate { MetaPowerSave power_save_mode; gboolean initial_orient_change_done; + + GList *virtual_monitors; + + gboolean shutting_down; } MetaMonitorManagerPrivate; G_DEFINE_TYPE_WITH_PRIVATE (MetaMonitorManager, meta_monitor_manager, @@ -400,6 +405,16 @@ lid_is_closed_changed (MetaBackend *backend, meta_monitor_manager_lid_is_closed_changed (manager); } +static void +prepare_shutdown (MetaBackend *backend, + MetaMonitorManager *manager) +{ + MetaMonitorManagerPrivate *priv = + meta_monitor_manager_get_instance_private (manager); + + priv->shutting_down = TRUE; +} + /** * meta_monitor_manager_is_headless: * @manager: A #MetaMonitorManager object @@ -483,6 +498,60 @@ meta_monitor_manager_get_default_layout_mode (MetaMonitorManager *manager) return manager_class->get_default_layout_mode (manager); } +static void +on_virtual_monitor_destroyed (MetaVirtualMonitor *virtual_monitor, + MetaMonitorManager *manager) +{ + MetaMonitorManagerPrivate *priv = + meta_monitor_manager_get_instance_private (manager); + MetaOutput *output; + + output = meta_virtual_monitor_get_output (virtual_monitor); + g_message ("Removed virtual monitor %s", meta_output_get_name (output)); + priv->virtual_monitors = g_list_remove (priv->virtual_monitors, + virtual_monitor); + + if (!priv->shutting_down) + meta_monitor_manager_reload (manager); +} + +MetaVirtualMonitor * +meta_monitor_manager_create_virtual_monitor (MetaMonitorManager *manager, + const MetaVirtualMonitorInfo *info, + GError **error) +{ + MetaMonitorManagerPrivate *priv = + meta_monitor_manager_get_instance_private (manager); + MetaMonitorManagerClass *manager_class = + META_MONITOR_MANAGER_GET_CLASS (manager); + MetaVirtualMonitor *virtual_monitor; + MetaOutput *output; + + if (!manager_class->create_virtual_monitor) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + "Backend doesn't support creating virtual monitors"); + return NULL; + } + + virtual_monitor = manager_class->create_virtual_monitor (manager, info, + error); + if (!virtual_monitor) + return NULL; + + g_signal_connect (virtual_monitor, "destroy", + G_CALLBACK (on_virtual_monitor_destroyed), + manager); + + priv->virtual_monitors = g_list_append (priv->virtual_monitors, + virtual_monitor); + + output = meta_virtual_monitor_get_output (virtual_monitor); + g_message ("Added virtual monitor %s", meta_output_get_name (output)); + + return virtual_monitor; +} + static void meta_monitor_manager_ensure_initial_config (MetaMonitorManager *manager) { @@ -896,6 +965,10 @@ meta_monitor_manager_constructed (GObject *object) G_CALLBACK (lid_is_closed_changed), manager, 0); + g_signal_connect (backend, "prepare-shutdown", + G_CALLBACK (prepare_shutdown), + manager); + manager->current_switch_config = META_MONITOR_SWITCH_CONFIG_UNKNOWN; initialize_dbus_interface (manager); @@ -905,9 +978,13 @@ static void meta_monitor_manager_finalize (GObject *object) { MetaMonitorManager *manager = META_MONITOR_MANAGER (object); + MetaMonitorManagerPrivate *priv = + meta_monitor_manager_get_instance_private (manager); g_list_free_full (manager->logical_monitors, g_object_unref); + g_warn_if_fail (!priv->virtual_monitors); + g_clear_signal_handler (&manager->experimental_features_changed_handler_id, manager->backend); @@ -2894,6 +2971,18 @@ rebuild_monitors (MetaMonitorManager *manager) } } } + + for (l = meta_monitor_manager_get_virtual_monitors (manager); l; l = l->next) + { + MetaVirtualMonitor *virtual_monitor = l->data; + MetaOutput *output = meta_virtual_monitor_get_output (virtual_monitor); + MetaMonitorNormal *monitor_normal; + + monitor_normal = meta_monitor_normal_new (manager, output); + manager->monitors = g_list_append (manager->monitors, + monitor_normal); + + } } void @@ -3365,3 +3454,12 @@ meta_monitor_manager_get_viewports (MetaMonitorManager *manager) return info; } + +GList * +meta_monitor_manager_get_virtual_monitors (MetaMonitorManager *manager) +{ + MetaMonitorManagerPrivate *priv = + meta_monitor_manager_get_instance_private (manager); + + return priv->virtual_monitors; +} diff --git a/src/backends/meta-output.h b/src/backends/meta-output.h index 3c4431c4d..b96c118d8 100644 --- a/src/backends/meta-output.h +++ b/src/backends/meta-output.h @@ -39,7 +39,8 @@ struct _MetaTileInfo uint32_t tile_h; }; -/* This matches the values in drm_mode.h */ +/* The first 17 matches the values in drm_mode.h, the ones starting with + * 1000 do not. */ typedef enum { META_CONNECTOR_TYPE_Unknown = 0, @@ -59,6 +60,8 @@ typedef enum META_CONNECTOR_TYPE_eDP = 14, META_CONNECTOR_TYPE_VIRTUAL = 15, META_CONNECTOR_TYPE_DSI = 16, + + META_CONNECTOR_TYPE_META = 1000, } MetaConnectorType; typedef struct _MetaOutputInfo diff --git a/src/backends/meta-virtual-monitor.c b/src/backends/meta-virtual-monitor.c new file mode 100644 index 000000000..2bd95ffd7 --- /dev/null +++ b/src/backends/meta-virtual-monitor.c @@ -0,0 +1,238 @@ +/* + * Copyright (C) 2021 Red Hat Inc. + * + * 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. + * + */ + +#include "config.h" + +#include "backends/meta-virtual-monitor.h" + +#include "backends/meta-crtc.h" +#include "backends/meta-crtc-mode.h" +#include "backends/meta-output.h" + +enum +{ + DESTROY, + + N_SIGNALS +}; + +static guint signals[N_SIGNALS] = { 0 }; + +enum +{ + PROP_0, + + PROP_CRTC, + PROP_CRTC_MODE, + PROP_OUTPUT, + + N_PROPS +}; + +static GParamSpec *obj_props[N_PROPS]; + +typedef struct _MetaVirtualMonitorPrivate +{ + MetaCrtc *crtc; + MetaCrtcMode *crtc_mode; + MetaOutput *output; + + gboolean is_destroyed; +} MetaVirtualMonitorPrivate; + +G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (MetaVirtualMonitor, meta_virtual_monitor, + G_TYPE_OBJECT) + +MetaVirtualMonitorInfo * +meta_virtual_monitor_info_new (int width, + int height, + float refresh_rate, + const char *vendor, + const char *product, + const char *serial) +{ + MetaVirtualMonitorInfo *info; + + info = g_new0 (MetaVirtualMonitorInfo, 1); + info->width = width; + info->height = height; + info->refresh_rate = refresh_rate; + info->vendor = g_strdup (vendor); + info->product = g_strdup (product); + info->serial = g_strdup (serial); + + return info; +} + +void +meta_virtual_monitor_info_free (MetaVirtualMonitorInfo *info) +{ + g_free (info->vendor); + g_free (info->product); + g_free (info->serial); + g_free (info); +} + +MetaCrtc * +meta_virtual_monitor_get_crtc (MetaVirtualMonitor *virtual_monitor) +{ + MetaVirtualMonitorPrivate *priv = + meta_virtual_monitor_get_instance_private (virtual_monitor); + + return priv->crtc; +} + +MetaCrtcMode * +meta_virtual_monitor_get_crtc_mode (MetaVirtualMonitor *virtual_monitor) +{ + MetaVirtualMonitorPrivate *priv = + meta_virtual_monitor_get_instance_private (virtual_monitor); + + return priv->crtc_mode; +} + +MetaOutput * +meta_virtual_monitor_get_output (MetaVirtualMonitor *virtual_monitor) +{ + MetaVirtualMonitorPrivate *priv = + meta_virtual_monitor_get_instance_private (virtual_monitor); + + return priv->output; +} + +static void +meta_virtual_monitor_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + MetaVirtualMonitor *virtual_monitor = META_VIRTUAL_MONITOR (object); + MetaVirtualMonitorPrivate *priv = + meta_virtual_monitor_get_instance_private (virtual_monitor); + + switch (prop_id) + { + case PROP_CRTC: + priv->crtc = g_value_get_object (value); + break; + case PROP_CRTC_MODE: + priv->crtc_mode = g_value_get_object (value); + break; + case PROP_OUTPUT: + priv->output = g_value_get_object (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +meta_virtual_monitor_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + MetaVirtualMonitor *virtual_monitor = META_VIRTUAL_MONITOR (object); + MetaVirtualMonitorPrivate *priv = + meta_virtual_monitor_get_instance_private (virtual_monitor); + + switch (prop_id) + { + case PROP_CRTC: + g_value_set_object (value, priv->crtc); + break; + case PROP_CRTC_MODE: + g_value_set_object (value, priv->crtc_mode); + break; + case PROP_OUTPUT: + g_value_set_object (value, priv->output); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +meta_virtual_monitor_dispose (GObject *object) +{ + MetaVirtualMonitor *virtual_monitor = META_VIRTUAL_MONITOR (object); + MetaVirtualMonitorPrivate *priv = + meta_virtual_monitor_get_instance_private (virtual_monitor); + + if (!priv->is_destroyed) + { + g_signal_emit (virtual_monitor, signals[DESTROY], 0); + priv->is_destroyed = TRUE; + } + + g_clear_object (&priv->crtc); + g_clear_object (&priv->crtc_mode); + g_clear_object (&priv->output); + + G_OBJECT_CLASS (meta_virtual_monitor_parent_class)->dispose (object); +} + +static void +meta_virtual_monitor_init (MetaVirtualMonitor *virtual_monitor) +{ +} + +static void +meta_virtual_monitor_class_init (MetaVirtualMonitorClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->set_property = meta_virtual_monitor_set_property; + object_class->get_property = meta_virtual_monitor_get_property; + object_class->dispose = meta_virtual_monitor_dispose; + + obj_props[PROP_CRTC] = + g_param_spec_object ("crtc", + "crtc", + "The virtual CRTC", + META_TYPE_CRTC, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + obj_props[PROP_CRTC_MODE] = + g_param_spec_object ("crtc-mode", + "crtc-mode", + "The virtual CRTC mode", + META_TYPE_CRTC_MODE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + obj_props[PROP_OUTPUT] = + g_param_spec_object ("output", + "output", + "The virtual output", + META_TYPE_OUTPUT, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + g_object_class_install_properties (object_class, N_PROPS, obj_props); + + signals[DESTROY] = + g_signal_new ("destroy", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, 0, + NULL, NULL, NULL, + G_TYPE_NONE, 0); +} diff --git a/src/backends/meta-virtual-monitor.h b/src/backends/meta-virtual-monitor.h new file mode 100644 index 000000000..f2d102f00 --- /dev/null +++ b/src/backends/meta-virtual-monitor.h @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2021 Red Hat Inc. + * + * 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. + * + */ + +#ifndef META_VIRTUAL_MONITOR_H +#define META_VIRTUAL_MONITOR_H + +#include + +#include "backends/meta-backend-types.h" +#include "core/util-private.h" + +typedef struct _MetaVirtualMonitorInfo +{ + int width; + int height; + float refresh_rate; + + char *vendor; + char *product; + char *serial; +} MetaVirtualMonitorInfo; + +#define META_TYPE_VIRTUAL_MONITOR (meta_virtual_monitor_get_type ()) +G_DECLARE_DERIVABLE_TYPE (MetaVirtualMonitor, meta_virtual_monitor, + META, VIRTUAL_MONITOR, + GObject) + +struct _MetaVirtualMonitorClass +{ + GObjectClass parent_class; +}; + +MetaVirtualMonitorInfo * meta_virtual_monitor_info_new (int width, + int height, + float refresh_rate, + const char *vendor, + const char *product, + const char *serial); + +void meta_virtual_monitor_info_free (MetaVirtualMonitorInfo *info); + +MetaCrtc * meta_virtual_monitor_get_crtc (MetaVirtualMonitor *virtual_monitor); + +MetaCrtcMode * meta_virtual_monitor_get_crtc_mode (MetaVirtualMonitor *virtual_monitor); + +MetaOutput * meta_virtual_monitor_get_output (MetaVirtualMonitor *virtual_monitor); + +G_DEFINE_AUTOPTR_CLEANUP_FUNC (MetaVirtualMonitorInfo, + meta_virtual_monitor_info_free) + +#endif /* META_VIRTUAL_MONITOR_H */ diff --git a/src/backends/native/meta-backend-native-types.h b/src/backends/native/meta-backend-native-types.h index 3efbca9ca..f16f6b1d0 100644 --- a/src/backends/native/meta-backend-native-types.h +++ b/src/backends/native/meta-backend-native-types.h @@ -27,6 +27,8 @@ typedef struct _MetaSeatImpl MetaSeatImpl; typedef struct _MetaKeymapNative MetaKeymapNative; typedef struct _MetaRendererNative MetaRendererNative; typedef struct _MetaGpuKms MetaGpuKms; +typedef struct _MetaCrtcVirtual MetaCrtcVirtual; +typedef struct _MetaCrtcModeVirtual MetaCrtcModeVirtual; typedef enum _MetaSeatNativeFlag { diff --git a/src/backends/native/meta-crtc-mode-virtual.c b/src/backends/native/meta-crtc-mode-virtual.c new file mode 100644 index 000000000..3bb883049 --- /dev/null +++ b/src/backends/native/meta-crtc-mode-virtual.c @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2021 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. + */ + +#include "config.h" + +#include "backends/native/meta-crtc-mode-virtual.h" + +#include "backends/meta-virtual-monitor.h" + +struct _MetaCrtcModeVirtual +{ + MetaCrtcMode parent; +}; + +#define META_CRTC_MODE_VIRTUAL_ID_BIT (((uint64_t) 1) << 63) + +G_DEFINE_TYPE (MetaCrtcModeVirtual, meta_crtc_mode_virtual, + META_TYPE_CRTC_MODE) + +MetaCrtcModeVirtual * +meta_crtc_mode_virtual_new (uint64_t id, + const MetaVirtualMonitorInfo *info) +{ + g_autoptr (MetaCrtcModeInfo) crtc_mode_info = NULL; + g_autofree char *crtc_mode_name = NULL; + MetaCrtcModeVirtual *mode_virtual; + + crtc_mode_info = meta_crtc_mode_info_new (); + crtc_mode_info->width = info->width; + crtc_mode_info->height = info->height; + crtc_mode_info->refresh_rate = info->refresh_rate; + + crtc_mode_name = g_strdup_printf ("%dx%d@%f", + info->width, + info->height, + info->refresh_rate); + mode_virtual = g_object_new (META_TYPE_CRTC_MODE_VIRTUAL, + "id", META_CRTC_MODE_VIRTUAL_ID_BIT | id, + "name", crtc_mode_name, + "info", crtc_mode_info, + NULL); + + return mode_virtual; +} + +static void +meta_crtc_mode_virtual_init (MetaCrtcModeVirtual *mode_virtual) +{ +} + +static void +meta_crtc_mode_virtual_class_init (MetaCrtcModeVirtualClass *klass) +{ +} diff --git a/src/backends/native/meta-crtc-mode-virtual.h b/src/backends/native/meta-crtc-mode-virtual.h new file mode 100644 index 000000000..e3ddb289c --- /dev/null +++ b/src/backends/native/meta-crtc-mode-virtual.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2021 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. + */ + +#ifndef META_CRTC_MODE_VIRTUAL_H +#define META_CRTC_MODE_VIRTUAL_H + +#include "backends/meta-backend-types.h" +#include "backends/meta-crtc-mode.h" + +#define META_TYPE_CRTC_MODE_VIRTUAL (meta_crtc_mode_virtual_get_type ()) +G_DECLARE_FINAL_TYPE (MetaCrtcModeVirtual, meta_crtc_mode_virtual, + META, CRTC_MODE_VIRTUAL, + MetaCrtcMode) + +MetaCrtcModeVirtual * meta_crtc_mode_virtual_new (uint64_t id, + const MetaVirtualMonitorInfo *info); + +#endif /* META_CRTC_MODE_VIRTUAL_H */ diff --git a/src/backends/native/meta-crtc-virtual.c b/src/backends/native/meta-crtc-virtual.c new file mode 100644 index 000000000..eee346a23 --- /dev/null +++ b/src/backends/native/meta-crtc-virtual.c @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2021 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. + */ + +#include "config.h" + +#include "backends/native/meta-crtc-virtual.h" + +struct _MetaCrtcVirtual +{ + MetaCrtcNative parent; +}; + +#define META_CRTC_VIRTUAL_ID_BIT (((uint64_t) 1) << 63) + +G_DEFINE_TYPE (MetaCrtcVirtual, meta_crtc_virtual, META_TYPE_CRTC_NATIVE) + +MetaCrtcVirtual * +meta_crtc_virtual_new (uint64_t id) +{ + return g_object_new (META_TYPE_CRTC_VIRTUAL, + "id", META_CRTC_VIRTUAL_ID_BIT | id, + NULL); +} + +static gboolean +meta_crtc_virtual_is_transform_handled (MetaCrtcNative *crtc_native, + MetaMonitorTransform transform) +{ + return transform == META_MONITOR_TRANSFORM_NORMAL; +} + +static void +meta_crtc_virtual_init (MetaCrtcVirtual *crtc_virtual) +{ +} + +static void +meta_crtc_virtual_class_init (MetaCrtcVirtualClass *klass) +{ + MetaCrtcNativeClass *crtc_native_class = META_CRTC_NATIVE_CLASS (klass); + + crtc_native_class->is_transform_handled = + meta_crtc_virtual_is_transform_handled; +} diff --git a/src/backends/native/meta-crtc-virtual.h b/src/backends/native/meta-crtc-virtual.h new file mode 100644 index 000000000..89b1bcc7a --- /dev/null +++ b/src/backends/native/meta-crtc-virtual.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2021 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. + */ + +#ifndef META_CRTC_VIRTUAL_H +#define META_CRTC_VIRTUAL_H + +#include "backends/native/meta-crtc-native.h" + +#define META_TYPE_CRTC_VIRTUAL (meta_crtc_virtual_get_type ()) +G_DECLARE_FINAL_TYPE (MetaCrtcVirtual, meta_crtc_virtual, + META, CRTC_VIRTUAL, + MetaCrtcNative) + +MetaCrtcVirtual * meta_crtc_virtual_new (uint64_t id); + +#endif /* META_CRTC_VIRTUAL_H */ diff --git a/src/backends/native/meta-cursor-renderer-native.c b/src/backends/native/meta-cursor-renderer-native.c index 3d83e6e47..098ef24bd 100644 --- a/src/backends/native/meta-cursor-renderer-native.c +++ b/src/backends/native/meta-cursor-renderer-native.c @@ -542,6 +542,9 @@ meta_cursor_renderer_native_prepare_frame (MetaCursorRendererNative *cursor_rend META_POWER_SAVE_ON) return; + if (!meta_crtc_get_gpu (crtc)) + return; + crtc_cursor_data = ensure_crtc_cursor_data (META_CRTC_KMS (crtc)); if (!crtc_cursor_data->hw_state_invalidated && !crtc_cursor_data->needs_sync_position) @@ -849,6 +852,9 @@ should_have_hw_cursor (MetaCursorRenderer *renderer, float scale; GList *l; + if (!gpus) + return FALSE; + if (!cursor_sprite) return FALSE; @@ -989,7 +995,7 @@ calculate_cursor_sprite_gpus (MetaCursorRenderer *renderer, MetaGpu *gpu; gpu = meta_output_get_gpu (output); - if (!g_list_find (gpus, gpu)) + if (gpu && !g_list_find (gpus, gpu)) gpus = g_list_prepend (gpus, gpu); } } diff --git a/src/backends/native/meta-monitor-manager-native.c b/src/backends/native/meta-monitor-manager-native.c index 0b9471c25..82cf0373e 100644 --- a/src/backends/native/meta-monitor-manager-native.c +++ b/src/backends/native/meta-monitor-manager-native.c @@ -59,6 +59,7 @@ #include "backends/native/meta-launcher.h" #include "backends/native/meta-output-kms.h" #include "backends/native/meta-renderer-native.h" +#include "backends/native/meta-virtual-monitor-native.h" #include "clutter/clutter.h" #include "meta/main.h" #include "meta/meta-x11-errors.h" @@ -90,6 +91,8 @@ struct _MetaMonitorManagerNativeClass MetaMonitorManagerClass parent_class; }; +#define VIRTUAL_OUTPUT_ID_BIT (((uint64_t) 1) << 63) + static void initable_iface_init (GInitableIface *initable_iface); @@ -224,6 +227,16 @@ apply_crtc_assignments (MetaMonitorManager *manager, to_configure_crtcs = g_list_concat (to_configure_crtcs, crtcs); } + for (l = meta_monitor_manager_get_virtual_monitors (manager); l; l = l->next) + { + MetaVirtualMonitor *virtual_monitor = l->data; + MetaOutput *output = meta_virtual_monitor_get_output (virtual_monitor); + MetaCrtc *crtc = meta_virtual_monitor_get_crtc (virtual_monitor); + + to_configure_outputs = g_list_append (to_configure_outputs, output); + to_configure_crtcs = g_list_append (to_configure_crtcs, crtc); + } + for (i = 0; i < n_crtcs; i++) { MetaCrtcAssignment *crtc_assignment = crtcs[i]; @@ -362,6 +375,8 @@ meta_monitor_manager_native_get_crtc_gamma (MetaMonitorManager *manager, MetaKmsCrtc *kms_crtc; const MetaKmsCrtcState *crtc_state; + g_return_if_fail (META_IS_CRTC_KMS (crtc)); + kms_crtc = meta_crtc_kms_get_kms_crtc (META_CRTC_KMS (crtc)); crtc_state = meta_kms_crtc_get_current_state (kms_crtc); @@ -455,12 +470,17 @@ meta_monitor_manager_native_set_crtc_gamma (MetaMonitorManager *manager, { MetaMonitorManagerNative *manager_native = META_MONITOR_MANAGER_NATIVE (manager); - MetaCrtcKms *crtc_kms = META_CRTC_KMS (crtc); - MetaKmsCrtc *kms_crtc = meta_crtc_kms_get_kms_crtc (META_CRTC_KMS (crtc)); + MetaCrtcKms *crtc_kms; + MetaKmsCrtc *kms_crtc; g_autofree char *gamma_ramp_string = NULL; MetaBackend *backend = meta_monitor_manager_get_backend (manager); ClutterStage *stage = CLUTTER_STAGE (meta_backend_get_stage (backend)); + g_return_if_fail (META_IS_CRTC_KMS (crtc)); + + crtc_kms = META_CRTC_KMS (crtc); + kms_crtc = meta_crtc_kms_get_kms_crtc (META_CRTC_KMS (crtc)); + g_hash_table_replace (manager_native->crtc_gamma_cache, GUINT_TO_POINTER (meta_crtc_get_id (crtc)), meta_kms_crtc_gamma_new (kms_crtc, size, @@ -602,6 +622,55 @@ meta_monitor_manager_native_get_default_layout_mode (MetaMonitorManager *manager return META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL; } +static MetaVirtualMonitorNative * +find_virtual_monitor (MetaMonitorManagerNative *manager_native, + uint64_t id) +{ + MetaMonitorManager *manager = META_MONITOR_MANAGER (manager_native); + GList *l; + + for (l = meta_monitor_manager_get_virtual_monitors (manager); l; l = l->next) + { + MetaVirtualMonitorNative *virtual_monitor_native = l->data; + + if (meta_virtual_monitor_native_get_id (virtual_monitor_native) == id) + return virtual_monitor_native; + } + + return NULL; +} + +static uint64_t +allocate_virtual_monitor_id (MetaMonitorManagerNative *manager_native) +{ + uint64_t id; + + id = 0; + + while (TRUE) + { + if (!find_virtual_monitor (manager_native, id)) + return id; + + id++; + } +} + +static MetaVirtualMonitor * +meta_monitor_manager_native_create_virtual_monitor (MetaMonitorManager *manager, + const MetaVirtualMonitorInfo *info, + GError **error) +{ + MetaMonitorManagerNative *manager_native = + META_MONITOR_MANAGER_NATIVE (manager); + MetaVirtualMonitorNative *virtual_monitor_native; + uint64_t id; + + id = allocate_virtual_monitor_id (manager_native); + virtual_monitor_native = meta_virtual_monitor_native_new (id, info); + return META_VIRTUAL_MONITOR (virtual_monitor_native); +} + static void meta_monitor_manager_native_set_property (GObject *object, guint prop_id, @@ -722,6 +791,8 @@ meta_monitor_manager_native_class_init (MetaMonitorManagerNativeClass *klass) meta_monitor_manager_native_get_max_screen_size; manager_class->get_default_layout_mode = meta_monitor_manager_native_get_default_layout_mode; + manager_class->create_virtual_monitor = + meta_monitor_manager_native_create_virtual_monitor; obj_props[PROP_NEED_OUTPUTS] = g_param_spec_boolean ("needs-outputs", diff --git a/src/backends/native/meta-output-kms.c b/src/backends/native/meta-output-kms.c index 8fcf91ab8..024344a3c 100644 --- a/src/backends/native/meta-output-kms.c +++ b/src/backends/native/meta-output-kms.c @@ -270,6 +270,8 @@ init_output_modes (MetaOutputInfo *output_info, static MetaConnectorType meta_kms_connector_type_from_drm (uint32_t drm_connector_type) { + g_warn_if_fail (drm_connector_type < META_CONNECTOR_TYPE_META); + return (MetaConnectorType) drm_connector_type; } diff --git a/src/backends/native/meta-output-virtual.c b/src/backends/native/meta-output-virtual.c new file mode 100644 index 000000000..12efb3338 --- /dev/null +++ b/src/backends/native/meta-output-virtual.c @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2021 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. + */ + +#include "config.h" + +#include "backends/native/meta-output-virtual.h" + +#include "backends/native/meta-crtc-mode-virtual.h" +#include "backends/native/meta-crtc-virtual.h" +#include "backends/meta-virtual-monitor.h" + +struct _MetaOutputVirtual +{ + MetaOutputNative parent; +}; + +#define META_OUTPUT_VIRTUAL_ID_BIT (((uint64_t) 1) << 63) + +G_DEFINE_TYPE (MetaOutputVirtual, meta_output_virtual, META_TYPE_OUTPUT_NATIVE) + +MetaOutputVirtual * +meta_output_virtual_new (uint64_t id, + const MetaVirtualMonitorInfo *info, + MetaCrtcVirtual *crtc_virtual, + MetaCrtcModeVirtual *crtc_mode_virtual) +{ + g_autoptr (MetaOutputInfo) output_info = NULL; + + output_info = meta_output_info_new (); + output_info->name = g_strdup_printf ("Meta-%" G_GUINT64_FORMAT, id); + + output_info->n_possible_crtcs = 1; + output_info->possible_crtcs = g_new0 (MetaCrtc *, 1); + output_info->possible_crtcs[0] = META_CRTC (crtc_virtual); + + output_info->hotplug_mode_update = FALSE; + output_info->suggested_x = -1; + output_info->suggested_y = -1; + + output_info->connector_type = META_CONNECTOR_TYPE_META; + output_info->vendor = g_strdup (info->vendor); + output_info->product = g_strdup (info->product); + output_info->serial = g_strdup (info->serial); + + output_info->n_modes = 1; + output_info->modes = g_new0 (MetaCrtcMode *, 1); + output_info->modes[0] = META_CRTC_MODE (crtc_mode_virtual); + output_info->preferred_mode = output_info->modes[0]; + + return g_object_new (META_TYPE_OUTPUT_VIRTUAL, + "id", META_OUTPUT_VIRTUAL_ID_BIT | id, + "info", output_info, + NULL); +} + +static void +meta_output_virtual_init (MetaOutputVirtual *output_virtual) +{ +} + +static void +meta_output_virtual_class_init (MetaOutputVirtualClass *klass) +{ +} diff --git a/src/backends/native/meta-output-virtual.h b/src/backends/native/meta-output-virtual.h new file mode 100644 index 000000000..b04579f0d --- /dev/null +++ b/src/backends/native/meta-output-virtual.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2021 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. + */ + +#ifndef META_OUTPUT_VIRTUAL_H +#define META_OUTPUT_VIRTUAL_H + +#include "backends/native/meta-backend-native-types.h" +#include "backends/native/meta-output-native.h" + +#define META_TYPE_OUTPUT_VIRTUAL (meta_output_virtual_get_type ()) +G_DECLARE_FINAL_TYPE (MetaOutputVirtual, meta_output_virtual, + META, OUTPUT_VIRTUAL, + MetaOutputNative) + +MetaOutputVirtual * meta_output_virtual_new (uint64_t id, + const MetaVirtualMonitorInfo *info, + MetaCrtcVirtual *crtc_virtual, + MetaCrtcModeVirtual *crtc_mode_virtual); + +#endif /* META_OUTPUT_VIRTUAL_H */ diff --git a/src/backends/native/meta-renderer-native.c b/src/backends/native/meta-renderer-native.c index bacf0f96e..95d2ffd77 100644 --- a/src/backends/native/meta-renderer-native.c +++ b/src/backends/native/meta-renderer-native.c @@ -50,6 +50,7 @@ #include "backends/meta-logical-monitor.h" #include "backends/native/meta-cogl-utils.h" #include "backends/native/meta-crtc-kms.h" +#include "backends/native/meta-crtc-virtual.h" #include "backends/native/meta-kms-device.h" #include "backends/native/meta-kms.h" #include "backends/native/meta-onscreen-native.h" @@ -1021,13 +1022,11 @@ meta_renderer_native_create_view (MetaRenderer *renderer, CoglContext *cogl_context = cogl_context_from_renderer_native (renderer_native); CoglDisplay *cogl_display = cogl_context_get_display (cogl_context); - CoglDisplayEGL *cogl_display_egl; - CoglOnscreenEgl *onscreen_egl; const MetaCrtcConfig *crtc_config; const MetaCrtcModeInfo *crtc_mode_info; MetaMonitorTransform view_transform; - MetaOnscreenNative *onscreen_native; - CoglOffscreen *offscreen = NULL; + g_autoptr (CoglFramebuffer) framebuffer = NULL; + g_autoptr (CoglOffscreen) offscreen = NULL; gboolean use_shadowfb; float scale; int onscreen_width; @@ -1042,16 +1041,41 @@ meta_renderer_native_create_view (MetaRenderer *renderer, onscreen_width = crtc_mode_info->width; onscreen_height = crtc_mode_info->height; - onscreen_native = meta_onscreen_native_new (renderer_native, - renderer_native->primary_gpu_kms, - output, - crtc, - cogl_context, - onscreen_width, - onscreen_height); + if (META_IS_CRTC_KMS (crtc)) + { + MetaOnscreenNative *onscreen_native; - if (!cogl_framebuffer_allocate (COGL_FRAMEBUFFER (onscreen_native), &error)) - g_error ("Failed to allocate onscreen framebuffer: %s", error->message); + onscreen_native = meta_onscreen_native_new (renderer_native, + renderer_native->primary_gpu_kms, + output, + crtc, + cogl_context, + onscreen_width, + onscreen_height); + + if (!cogl_framebuffer_allocate (COGL_FRAMEBUFFER (onscreen_native), &error)) + g_error ("Failed to allocate onscreen framebuffer: %s", error->message); + + use_shadowfb = should_force_shadow_fb (renderer_native, + renderer_native->primary_gpu_kms); + framebuffer = COGL_FRAMEBUFFER (onscreen_native); + } + else + { + CoglOffscreen *virtual_onscreen; + + g_assert (META_IS_CRTC_VIRTUAL (crtc)); + + virtual_onscreen = meta_renderer_native_create_offscreen (renderer_native, + cogl_context, + onscreen_width, + onscreen_height, + &error); + if (!virtual_onscreen) + g_error ("Failed to allocate back buffer texture: %s", error->message); + use_shadowfb = FALSE; + framebuffer = COGL_FRAMEBUFFER (virtual_onscreen); + } view_transform = calculate_view_transform (monitor_manager, logical_monitor, @@ -1082,9 +1106,6 @@ meta_renderer_native_create_view (MetaRenderer *renderer, g_error ("Failed to allocate back buffer texture: %s", error->message); } - use_shadowfb = should_force_shadow_fb (renderer_native, - renderer_native->primary_gpu_kms); - if (meta_is_stage_views_scaled ()) scale = meta_logical_monitor_get_scale (logical_monitor); else @@ -1099,25 +1120,29 @@ meta_renderer_native_create_view (MetaRenderer *renderer, "layout", &view_layout, "crtc", crtc, "scale", scale, - "framebuffer", onscreen_native, + "framebuffer", framebuffer, "offscreen", offscreen, "use-shadowfb", use_shadowfb, "transform", view_transform, "refresh-rate", crtc_mode_info->refresh_rate, NULL); - g_clear_object (&offscreen); - g_object_unref (onscreen_native); - meta_onscreen_native_set_view (COGL_ONSCREEN (onscreen_native), view); + if (META_IS_ONSCREEN_NATIVE (framebuffer)) + { + CoglDisplayEGL *cogl_display_egl; + CoglOnscreenEgl *onscreen_egl; - /* Ensure we don't point to stale surfaces when creating the offscreen */ - cogl_display_egl = cogl_display->winsys; - onscreen_egl = COGL_ONSCREEN_EGL (onscreen_native); - egl_surface = cogl_onscreen_egl_get_egl_surface (onscreen_egl); - _cogl_winsys_egl_make_current (cogl_display, - egl_surface, - egl_surface, - cogl_display_egl->egl_context); + meta_onscreen_native_set_view (COGL_ONSCREEN (framebuffer), view); + + /* Ensure we don't point to stale surfaces when creating the offscreen */ + cogl_display_egl = cogl_display->winsys; + onscreen_egl = COGL_ONSCREEN_EGL (framebuffer); + egl_surface = cogl_onscreen_egl_get_egl_surface (onscreen_egl); + _cogl_winsys_egl_make_current (cogl_display, + egl_surface, + egl_surface, + cogl_display_egl->egl_context); + } return view; } @@ -1165,9 +1190,16 @@ meta_renderer_native_prepare_frame (MetaRendererNative *renderer_native, ClutterFrame *frame) { MetaCrtc *crtc = meta_renderer_view_get_crtc (view); - MetaCrtcKms *crtc_kms = META_CRTC_KMS (crtc); - MetaKmsCrtc *kms_crtc = meta_crtc_kms_get_kms_crtc (META_CRTC_KMS (crtc)); - MetaKmsDevice *kms_device = meta_kms_crtc_get_device (kms_crtc);; + MetaCrtcKms *crtc_kms; + MetaKmsCrtc *kms_crtc; + MetaKmsDevice *kms_device; + + if (!META_IS_CRTC_KMS (crtc)) + return; + + crtc_kms = META_CRTC_KMS (crtc); + kms_crtc = meta_crtc_kms_get_kms_crtc (META_CRTC_KMS (crtc)); + kms_device = meta_kms_crtc_get_device (kms_crtc); meta_crtc_kms_maybe_set_gamma (crtc_kms, kms_device); } @@ -1181,9 +1213,13 @@ meta_renderer_native_finish_frame (MetaRendererNative *renderer_native, { CoglFramebuffer *framebuffer = clutter_stage_view_get_onscreen (CLUTTER_STAGE_VIEW (view)); - CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer); - meta_onscreen_native_finish_frame (onscreen, frame); + if (COGL_IS_ONSCREEN (framebuffer)) + { + CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer); + + meta_onscreen_native_finish_frame (onscreen, frame); + } } } diff --git a/src/backends/native/meta-stage-native.c b/src/backends/native/meta-stage-native.c index efc45c3ee..b56acd9d4 100644 --- a/src/backends/native/meta-stage-native.c +++ b/src/backends/native/meta-stage-native.c @@ -27,6 +27,7 @@ #include "backends/native/meta-stage-native.h" #include "backends/meta-backend-private.h" +#include "backends/native/meta-crtc-virtual.h" #include "backends/native/meta-cursor-renderer-native.h" #include "backends/native/meta-renderer-native.h" #include "meta/meta-backend.h" @@ -45,6 +46,8 @@ struct _MetaStageNative int64_t presented_frame_counter_complete; }; +static ClutterStageWindowInterface *clutter_stage_window_parent_iface = NULL; + static void clutter_stage_window_iface_init (ClutterStageWindowInterface *iface); @@ -126,6 +129,24 @@ meta_stage_native_prepare_frame (ClutterStageWindow *stage_window, META_RENDERER_VIEW (stage_view)); } +static void +meta_stage_native_redraw_view (ClutterStageWindow *stage_window, + ClutterStageView *view, + ClutterFrame *frame) +{ + MetaCrtc *crtc; + + clutter_stage_window_parent_iface->redraw_view (stage_window, view, frame); + + crtc = meta_renderer_view_get_crtc (META_RENDERER_VIEW (view)); + if (META_IS_CRTC_VIRTUAL (crtc)) + { + g_warn_if_fail (!clutter_frame_has_result (frame)); + + clutter_frame_set_result (frame, CLUTTER_FRAME_RESULT_PENDING_PRESENTED); + } +} + static void meta_stage_native_finish_frame (ClutterStageWindow *stage_window, ClutterStageView *stage_view, @@ -137,6 +158,9 @@ meta_stage_native_finish_frame (ClutterStageWindow *stage_window, meta_renderer_native_finish_frame (META_RENDERER_NATIVE (renderer), META_RENDERER_VIEW (stage_view), frame); + + if (!clutter_frame_has_result (frame)) + clutter_frame_set_result (frame, CLUTTER_FRAME_RESULT_IDLE); } static void @@ -156,9 +180,12 @@ meta_stage_native_class_init (MetaStageNativeClass *klass) static void clutter_stage_window_iface_init (ClutterStageWindowInterface *iface) { + clutter_stage_window_parent_iface = g_type_interface_peek_parent (iface); + iface->can_clip_redraws = meta_stage_native_can_clip_redraws; iface->get_geometry = meta_stage_native_get_geometry; iface->get_views = meta_stage_native_get_views; iface->prepare_frame = meta_stage_native_prepare_frame; + iface->redraw_view = meta_stage_native_redraw_view; iface->finish_frame = meta_stage_native_finish_frame; } diff --git a/src/backends/native/meta-virtual-monitor-native.c b/src/backends/native/meta-virtual-monitor-native.c new file mode 100644 index 000000000..3f81f4180 --- /dev/null +++ b/src/backends/native/meta-virtual-monitor-native.c @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2021 Red Hat Inc. + * + * 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. + * + */ + +#include "config.h" + +#include "backends/native/meta-virtual-monitor-native.h" + +#include "backends/native/meta-crtc-mode-virtual.h" +#include "backends/native/meta-crtc-virtual.h" +#include "backends/native/meta-output-virtual.h" + +struct _MetaVirtualMonitorNative +{ + MetaVirtualMonitor parent; + + uint64_t id; +}; + +#define VIRTUAL_OUTPUT_ID_BIT (((uint64_t) 1) << 63) + +G_DEFINE_TYPE (MetaVirtualMonitorNative, meta_virtual_monitor_native, + META_TYPE_VIRTUAL_MONITOR) + +uint64_t +meta_virtual_monitor_native_get_id (MetaVirtualMonitorNative *virtual_monitor_native) +{ + return virtual_monitor_native->id; +} + +MetaVirtualMonitorNative * +meta_virtual_monitor_native_new (uint64_t id, + const MetaVirtualMonitorInfo *info) +{ + MetaVirtualMonitorNative *virtual_monitor_native; + MetaCrtcVirtual *crtc_virtual; + MetaCrtcModeVirtual *crtc_mode_virtual; + MetaOutputVirtual *output_virtual; + + crtc_virtual = meta_crtc_virtual_new (id); + crtc_mode_virtual = meta_crtc_mode_virtual_new (id, info); + output_virtual = meta_output_virtual_new (id, info, + crtc_virtual, + crtc_mode_virtual); + + virtual_monitor_native = g_object_new (META_TYPE_VIRTUAL_MONITOR_NATIVE, + "crtc", crtc_virtual, + "crtc-mode", crtc_mode_virtual, + "output", output_virtual, + NULL); + virtual_monitor_native->id = id; + + return virtual_monitor_native; +} + +static void +meta_virtual_monitor_native_init (MetaVirtualMonitorNative *virtual_monitor_native) +{ +} + +static void +meta_virtual_monitor_native_class_init (MetaVirtualMonitorNativeClass *klass) +{ +} diff --git a/src/backends/native/meta-virtual-monitor-native.h b/src/backends/native/meta-virtual-monitor-native.h new file mode 100644 index 000000000..d1a0ced64 --- /dev/null +++ b/src/backends/native/meta-virtual-monitor-native.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2021 Red Hat Inc. + * + * 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. + * + */ + +#ifndef META_VIRTUAL_MONITOR_NATIVE_H +#define META_VIRTUAL_MONITOR_NATIVE_H + +#include + +#include "backends/meta-virtual-monitor.h" +#include "backends/meta-backend-types.h" + +#define META_TYPE_VIRTUAL_MONITOR_NATIVE (meta_virtual_monitor_native_get_type ()) +G_DECLARE_FINAL_TYPE (MetaVirtualMonitorNative, meta_virtual_monitor_native, + META, VIRTUAL_MONITOR_NATIVE, + MetaVirtualMonitor) + +uint64_t meta_virtual_monitor_native_get_id (MetaVirtualMonitorNative *virtual_monitor_native); + +MetaCrtcMode * meta_virtual_monitor_native_get_crtc_mode (MetaVirtualMonitorNative *virtual_monitor_native); + +MetaCrtc * meta_virtual_monitor_native_get_crtc (MetaVirtualMonitorNative *virtual_monitor_native); + +MetaOutput * meta_virtual_monitor_native_get_output (MetaVirtualMonitorNative *virtual_monitor_native); + +MetaVirtualMonitorNative * meta_virtual_monitor_native_new (uint64_t id, + const MetaVirtualMonitorInfo *info); + +#endif /* META_VIRTUAL_MONITOR_NATIVE_H */ diff --git a/src/meson.build b/src/meson.build index 6f52ab714..fe3d1ccaf 100644 --- a/src/meson.build +++ b/src/meson.build @@ -236,6 +236,8 @@ mutter_sources = [ 'backends/meta-stage-private.h', 'backends/meta-viewport-info.c', 'backends/meta-viewport-info.h', + 'backends/meta-virtual-monitor.c', + 'backends/meta-virtual-monitor.h', 'backends/x11/cm/meta-backend-x11-cm.c', 'backends/x11/cm/meta-backend-x11-cm.h', 'backends/x11/cm/meta-cursor-sprite-xfixes.c', @@ -649,6 +651,10 @@ if have_native_backend 'backends/native/meta-crtc-native.h', 'backends/native/meta-crtc-mode-kms.c', 'backends/native/meta-crtc-mode-kms.h', + 'backends/native/meta-crtc-mode-virtual.c', + 'backends/native/meta-crtc-mode-virtual.h', + 'backends/native/meta-crtc-virtual.c', + 'backends/native/meta-crtc-virtual.h', 'backends/native/meta-cursor-renderer-native.c', 'backends/native/meta-cursor-renderer-native.h', 'backends/native/meta-drm-buffer-dumb.c', @@ -678,6 +684,8 @@ if have_native_backend 'backends/native/meta-output-kms.h', 'backends/native/meta-output-native.c', 'backends/native/meta-output-native.h', + 'backends/native/meta-output-virtual.c', + 'backends/native/meta-output-virtual.h', 'backends/native/meta-kms-connector-private.h', 'backends/native/meta-kms-connector.c', 'backends/native/meta-kms-connector.h', @@ -732,6 +740,8 @@ if have_native_backend 'backends/native/meta-udev.h', 'backends/native/meta-virtual-input-device-native.c', 'backends/native/meta-virtual-input-device-native.h', + 'backends/native/meta-virtual-monitor-native.c', + 'backends/native/meta-virtual-monitor-native.h', 'backends/native/meta-xkb-utils.c', 'backends/native/meta-xkb-utils.h', 'compositor/meta-compositor-native.c',