summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backends/meta-monitor-manager-private.h7
-rw-r--r--src/backends/meta-monitor-manager.c27
-rw-r--r--src/backends/x11/meta-monitor-manager-xrandr.c87
3 files changed, 120 insertions, 1 deletions
diff --git a/src/backends/meta-monitor-manager-private.h b/src/backends/meta-monitor-manager-private.h
index c5444d62..d21888ed 100644
--- a/src/backends/meta-monitor-manager-private.h
+++ b/src/backends/meta-monitor-manager-private.h
@@ -349,6 +349,13 @@ struct _MetaMonitorManagerClass
unsigned short *,
unsigned short *,
unsigned short *);
+
+ void (*add_monitor) (MetaMonitorManager *,
+ MetaMonitorInfo *);
+
+ void (*delete_monitor) (MetaMonitorManager *,
+ int monitor_winsys_xid);
+
};
void meta_monitor_manager_rebuild_derived (MetaMonitorManager *manager);
diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c
index 2588d22a..66f38a56 100644
--- a/src/backends/meta-monitor-manager.c
+++ b/src/backends/meta-monitor-manager.c
@@ -173,6 +173,7 @@ construct_tile_monitor (MetaMonitorManager *manager,
static void
make_logical_config (MetaMonitorManager *manager)
{
+ MetaMonitorManagerClass *manager_class = META_MONITOR_MANAGER_GET_CLASS (manager);
GArray *monitor_infos;
unsigned int i, j;
@@ -277,6 +278,10 @@ make_logical_config (MetaMonitorManager *manager)
manager->n_monitor_infos = monitor_infos->len;
manager->monitor_infos = (void*)g_array_free (monitor_infos, FALSE);
+
+ if (manager_class->add_monitor)
+ for (i = 0; i < manager->n_monitor_infos; i++)
+ manager_class->add_monitor (manager, &manager->monitor_infos[i]);
}
static void
@@ -1364,15 +1369,35 @@ meta_monitor_manager_read_current_config (MetaMonitorManager *manager)
void
meta_monitor_manager_rebuild_derived (MetaMonitorManager *manager)
{
+ MetaMonitorManagerClass *manager_class = META_MONITOR_MANAGER_GET_CLASS (manager);
MetaMonitorInfo *old_monitor_infos;
-
+ unsigned old_n_monitor_infos;
+ unsigned i, j;
old_monitor_infos = manager->monitor_infos;
+ old_n_monitor_infos = manager->n_monitor_infos;
if (manager->in_init)
return;
make_logical_config (manager);
+ if (manager_class->delete_monitor)
+ {
+ for (i = 0; i < old_n_monitor_infos; i++)
+ {
+ gboolean delete_mon = TRUE;
+ for (j = 0; j < manager->n_monitor_infos; j++)
+ {
+ if (manager->monitor_infos[j].monitor_winsys_xid == old_monitor_infos[i].monitor_winsys_xid)
+ {
+ delete_mon = FALSE;
+ break;
+ }
+ }
+ if (delete_mon)
+ manager_class->delete_monitor (manager, old_monitor_infos[i].monitor_winsys_xid);
+ }
+ }
g_signal_emit_by_name (manager, "monitors-changed");
g_free (old_monitor_infos);
diff --git a/src/backends/x11/meta-monitor-manager-xrandr.c b/src/backends/x11/meta-monitor-manager-xrandr.c
index 1aa6bdf4..55f339cc 100644
--- a/src/backends/x11/meta-monitor-manager-xrandr.c
+++ b/src/backends/x11/meta-monitor-manager-xrandr.c
@@ -1277,6 +1277,88 @@ meta_monitor_manager_xrandr_set_crtc_gamma (MetaMonitorManager *manager,
XRRFreeGamma (gamma);
}
+#ifdef HAVE_XRANDR15
+static void
+meta_monitor_manager_xrandr_add_monitor(MetaMonitorManager *manager,
+ MetaMonitorInfo *monitor)
+{
+ MetaMonitorManagerXrandr *manager_xrandr = META_MONITOR_MANAGER_XRANDR (manager);
+ XRRMonitorInfo *m;
+ int o;
+ Atom name;
+ char name_buf[40];
+
+ if (manager_xrandr->has_randr15 == FALSE)
+ return;
+
+ if (monitor->n_outputs <= 1)
+ return;
+
+ if (monitor->outputs[0]->product)
+ snprintf (name_buf, 40, "%s-%d", monitor->outputs[0]->product, monitor->outputs[0]->tile_info.group_id);
+ else
+ snprintf (name_buf, 40, "Tiled-%d", monitor->outputs[0]->tile_info.group_id);
+
+ name = XInternAtom (manager_xrandr->xdisplay, name_buf, False);
+ monitor->monitor_winsys_xid = name;
+ m = XRRAllocateMonitor (manager_xrandr->xdisplay, monitor->n_outputs);
+ if (!m)
+ return;
+ m->name = name;
+ m->primary = monitor->is_primary;
+ m->automatic = True;
+
+ for (o = 0; o < monitor->n_outputs; o++) {
+ MetaOutput *output = monitor->outputs[o];
+ m->outputs[o] = output->winsys_id;
+ }
+ XRRSetMonitor (manager_xrandr->xdisplay,
+ DefaultRootWindow (manager_xrandr->xdisplay),
+ m);
+ XRRFreeMonitors (m);
+}
+
+static void
+meta_monitor_manager_xrandr_delete_monitor(MetaMonitorManager *manager,
+ int monitor_winsys_xid)
+{
+ MetaMonitorManagerXrandr *manager_xrandr = META_MONITOR_MANAGER_XRANDR (manager);
+
+ if (manager_xrandr->has_randr15 == FALSE)
+ return;
+ XRRDeleteMonitor (manager_xrandr->xdisplay,
+ DefaultRootWindow (manager_xrandr->xdisplay),
+ monitor_winsys_xid);
+}
+
+static void
+meta_monitor_manager_xrandr_init_monitors(MetaMonitorManagerXrandr *manager_xrandr)
+{
+ XRRMonitorInfo *m;
+ int n, i;
+
+ if (manager_xrandr->has_randr15 == FALSE)
+ return;
+
+ /* delete any tiled monitors setup, as mutter will want to recreate
+ things in its image */
+ m = XRRGetMonitors (manager_xrandr->xdisplay,
+ DefaultRootWindow (manager_xrandr->xdisplay),
+ FALSE, &n);
+ if (n == -1)
+ return;
+
+ for (i = 0; i < n; i++)
+ {
+ if (m[i].noutput > 1)
+ XRRDeleteMonitor (manager_xrandr->xdisplay,
+ DefaultRootWindow (manager_xrandr->xdisplay),
+ m[i].name);
+ }
+ XRRFreeMonitors (m);
+}
+#endif
+
static void
meta_monitor_manager_xrandr_init (MetaMonitorManagerXrandr *manager_xrandr)
{
@@ -1309,6 +1391,7 @@ meta_monitor_manager_xrandr_init (MetaMonitorManagerXrandr *manager_xrandr)
(major_version == 1 &&
minor_version >= 5))
manager_xrandr->has_randr15 = TRUE;
+ meta_monitor_manager_xrandr_init_monitors (manager_xrandr);
#endif
}
}
@@ -1340,6 +1423,10 @@ meta_monitor_manager_xrandr_class_init (MetaMonitorManagerXrandrClass *klass)
manager_class->change_backlight = meta_monitor_manager_xrandr_change_backlight;
manager_class->get_crtc_gamma = meta_monitor_manager_xrandr_get_crtc_gamma;
manager_class->set_crtc_gamma = meta_monitor_manager_xrandr_set_crtc_gamma;
+#ifdef HAVE_XRANDR15
+ manager_class->add_monitor = meta_monitor_manager_xrandr_add_monitor;
+ manager_class->delete_monitor = meta_monitor_manager_xrandr_delete_monitor;
+#endif
}
gboolean