File mutter-bnc879109-no-monitors-crash.patch of Package mutter

commit a8e4253b56d8f1310087c8f80ba6e54935d2fa30
Author: Federico Mena Quintero <federico@gnome.org>
Date:   Sat May 31 12:32:26 2014 -0500

    MonitorManager: generate a null configuration if no real outputs are usable

diff --git a/src/core/monitor-private.h b/src/core/monitor-private.h
index bbe73f5..1710dd6 100644
--- a/src/core/monitor-private.h
+++ b/src/core/monitor-private.h
@@ -256,6 +256,12 @@ struct _MetaMonitorManager
   MetaMonitorConfig *config;
 
   GnomePnpIds *pnp_ids;
+
+  /* When there are no usable outputs/modes/crtcs, we use the following */
+  gboolean using_null_configuration;
+  MetaOutput null_output;
+  MetaMonitorMode null_mode;
+  MetaCRTC null_crtc;
 };
 
 struct _MetaMonitorManagerClass
diff --git a/src/core/monitor.c b/src/core/monitor.c
index a07571d..349cc9d 100644
--- a/src/core/monitor.c
+++ b/src/core/monitor.c
@@ -41,6 +41,12 @@
 
 #define ALL_WL_TRANSFORMS ((1 << (WL_OUTPUT_TRANSFORM_FLIPPED_270 + 1)) - 1)
 
+#define NULL_CONFIGURATION_WIDTH  1024
+#define NULL_CONFIGURATION_HEIGHT 768
+#define NULL_OUTPUT_ID            0
+#define NULL_MODE_ID              0
+#define NULL_CRTC_ID              0
+
 enum {
   CONFIRM_DISPLAY_CHANGE,
   SIGNALS_LAST
@@ -364,8 +370,76 @@ get_edid_file_dummy (MetaMonitorManager *manager,
 }
 
 static void
+init_null_output (MetaMonitorManager *manager)
+{
+  MetaOutput *o = &manager->null_output;
+
+  o->crtc              = &manager->null_crtc;
+  o->output_id         = NULL_OUTPUT_ID;
+  o->name              = g_strdup ("META-NULL");
+  o->vendor            = g_strdup ("MetaProducts Inc.");
+  o->product           = g_strdup ("unknown");
+  o->serial            = g_strdup ("0xC0FFEE");
+  o->width_mm          = 222;
+  o->height_mm         = 125;
+  o->subpixel_order    = COGL_SUBPIXEL_ORDER_UNKNOWN;
+  o->preferred_mode    = &manager->null_mode;
+  o->n_modes           = 1;
+  o->modes             = g_new0 (MetaMonitorMode *, 1);
+  o->modes[0]          = &manager->null_mode;
+  o->n_possible_crtcs  = 1;
+  o->possible_crtcs    = g_new0 (MetaCRTC *, 1);
+  o->possible_crtcs[0] = &manager->null_crtc;
+  o->n_possible_clones = 0;
+  o->possible_clones   = NULL;
+  o->backlight         = -1;
+  o->backlight_min     = 0;
+  o->backlight_max     = 0;
+}
+
+static void
+free_null_output (MetaMonitorManager *manager)
+{
+  g_free (manager->null_output.name);
+  g_free (manager->null_output.vendor);
+  g_free (manager->null_output.product);
+  g_free (manager->null_output.serial);
+  g_free (manager->null_output.modes);
+  g_free (manager->null_output.possible_crtcs);
+}
+
+static void
+init_null_mode (MetaMonitorManager *manager)
+{
+  MetaMonitorMode *m = &manager->null_mode;
+
+  m->mode_id      = NULL_MODE_ID;
+  m->width        = NULL_CONFIGURATION_WIDTH;
+  m->height       = NULL_CONFIGURATION_HEIGHT;
+  m->refresh_rate = 60.0;
+}
+
+static void
+init_null_crtc (MetaMonitorManager *manager)
+{
+  MetaCRTC *c = &manager->null_crtc;
+
+  c->crtc_id        = NULL_CRTC_ID;
+  c->rect.x         = 0;
+  c->rect.y         = 0;
+  c->rect.width     = NULL_CONFIGURATION_WIDTH;
+  c->rect.height    = NULL_CONFIGURATION_HEIGHT;
+  c->current_mode   = &manager->null_mode;
+  c->transform      = WL_OUTPUT_TRANSFORM_NORMAL;
+  c->all_transforms = ALL_WL_TRANSFORMS;
+}
+
+static void
 meta_monitor_manager_init (MetaMonitorManager *manager)
 {
+  init_null_output (manager);
+  init_null_mode (manager);
+  init_null_crtc (manager);
 }
 
 static void
@@ -376,6 +450,55 @@ read_current_config (MetaMonitorManager *manager)
   META_MONITOR_MANAGER_GET_CLASS (manager)->read_current (manager);
 }
 
+static gboolean
+monitor_infos_are_valid (GArray *monitor_infos)
+{
+  return monitor_infos->len > 0;
+}
+
+static MetaMonitorInfo *
+make_null_monitor_info (void)
+{
+  MetaMonitorInfo *null_monitor_info;
+
+  null_monitor_info = g_new0 (MetaMonitorInfo, 1);
+
+  null_monitor_info->number          = 0;
+  null_monitor_info->xinerama_index  = 0; /* set in meta_screen_ensure_xinerama_indices() */
+  null_monitor_info->rect.x          = 0;
+  null_monitor_info->rect.y          = 0;
+  null_monitor_info->rect.width      = NULL_CONFIGURATION_WIDTH;
+  null_monitor_info->rect.height     = NULL_CONFIGURATION_HEIGHT;
+  null_monitor_info->is_primary      = TRUE;
+  null_monitor_info->is_presentation = TRUE;
+  null_monitor_info->in_fullscreen   = -1; /* as from make_logical_config() */
+  null_monitor_info->output_id       = NULL_OUTPUT_ID;
+
+  return null_monitor_info;
+}
+
+/* This function generates a "null" configuration that has one dummy but usable
+ * output, which in turn has a dummy but usable CRTC.  All of this is used, for
+ * example, when all the real outputs are off, or when they have no usable
+ * modes.  A laptop may be turned on in a docking station, with the lid closed,
+ * and the external monitor may not have been plugged in yet.  Or the only
+ * monitor on a machine may be unplugged, and replugged later - while there are
+ * no usable outputs, we just use a dummy output.
+ *
+ * (This is not called make_dummy_configuration() to avoid confusion with
+ * read_current_dummy() and related functions above.)
+ */
+static void
+make_null_configuration (MetaMonitorManager *manager)
+{
+  manager->monitor_infos   = make_null_monitor_info ();
+  manager->n_monitor_infos = 1;
+
+  manager->primary_monitor_index = 0;
+
+  manager->using_null_configuration = TRUE;
+}
+
 /*
  * make_logical_config:
  *
@@ -467,8 +590,17 @@ make_logical_config (MetaMonitorManager *manager)
         manager->primary_monitor_index = info->number;
     }
 
-  manager->n_monitor_infos = monitor_infos->len;
-  manager->monitor_infos = (void*)g_array_free (monitor_infos, FALSE);
+  if (monitor_infos_are_valid (monitor_infos))
+    {
+      manager->n_monitor_infos = monitor_infos->len;
+      manager->monitor_infos = (void*)g_array_free (monitor_infos, FALSE);
+      manager->using_null_configuration = FALSE;
+    }
+  else
+    {
+      g_array_free (monitor_infos, TRUE);
+      make_null_configuration (manager);
+    }
 }
 
 static MetaMonitorManager *
@@ -582,6 +714,8 @@ meta_monitor_manager_finalize (GObject *object)
   g_free (manager->modes);
   g_free (manager->crtcs);
 
+  free_null_output (manager);
+
   G_OBJECT_CLASS (meta_monitor_manager_parent_class)->finalize (object);
 }
 
@@ -1425,8 +1559,16 @@ MetaOutput *
 meta_monitor_manager_get_outputs (MetaMonitorManager *manager,
                                   unsigned int       *n_outputs)
 {
-  *n_outputs = manager->n_outputs;
-  return manager->outputs;
+  if (manager->using_null_configuration)
+    {
+      *n_outputs = 1;
+      return &manager->null_output;
+    }
+  else
+    {
+      *n_outputs = manager->n_outputs;
+      return manager->outputs;
+    }
 }
 
 void
openSUSE Build Service is sponsored by