[RFC PATCH] xfree86: Lid status hack
Adam Jackson
ajax at redhat.com
Mon Jul 30 12:43:23 PDT 2012
If more than one output is connected, and there's only one ACPI lid
device, proxy the state of the lid into the LVDS / eDP connectivity.
This way we don't suffer from broken lid-status from the firmware in
a way that would result in nothing lighting up.
This is terribly Linux-specific and I don't think we should merge it
as-is, I'm mostly trying to generate some discussion. There's some
weird corner cases that come out of this since we're still doing the
"poke one thing at a time" model, and we don't explicitly turn _off_
outputs during initial setup, so X and kernel's view of the world
gets out of sync.
I think ideally we'd do this in the DRM, but I was unable to come up
with a clean way to do it there. Maybe it just needs to be ugly.
Signed-off-by: Adam Jackson <ajax at redhat.com>
---
hw/xfree86/modes/xf86Crtc.c | 80 ++++++++++++++++++++++++++++++++++++++----
1 files changed, 72 insertions(+), 8 deletions(-)
diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
index 7d80264..0c9bc8d 100644
--- a/hw/xfree86/modes/xf86Crtc.c
+++ b/hw/xfree86/modes/xf86Crtc.c
@@ -32,6 +32,11 @@
#include <stddef.h>
#include <string.h>
#include <stdio.h>
+#include <glob.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
#include "xf86.h"
#include "xf86DDC.h"
@@ -1521,11 +1526,44 @@ handle_detailed_monrec(struct detailed_monitor_section *det_mon, void *data)
}
}
+static int
+lvds_lid_status(void)
+{
+ glob_t g = {0, };
+ int ret = XF86OutputStatusConnected;
+#ifdef linux
+ int fd;
+ char buf[80];
+
+ memset(buf, '\0', sizeof(buf));
+
+ if (glob("/proc/acpi/button/lid/*/state", GLOB_NOSORT, NULL, &g) != 0)
+ goto out;
+
+ if (g.gl_pathc != 1)
+ goto out;
+
+ fd = open(g.gl_pathv[0], O_RDONLY);
+ if (fd == -1)
+ goto out;
+
+ read(fd, buf, sizeof(buf)-1);
+ close(fd);
+ if (strstr(buf, "closed"))
+ ret = XF86OutputStatusDisconnected;
+#endif
+
+out:
+ globfree(&g);
+ return ret;
+}
+
void
xf86ProbeOutputModes(ScrnInfoPtr scrn, int maxX, int maxY)
{
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
int o;
+ int num_connected = 0;
/* When canGrow was TRUE in the initial configuration we have to
* compare against the maximum values so that we don't drop modes.
@@ -1537,6 +1575,40 @@ xf86ProbeOutputModes(ScrnInfoPtr scrn, int maxX, int maxY)
maxY = config->maxHeight;
}
+ /* clean the mode list */
+ for (o = 0; o < config->num_output; o++)
+ {
+ xf86OutputPtr output = config->output[o];
+ while (output->probed_modes != NULL)
+ xf86DeleteMode(&output->probed_modes, output->probed_modes);
+ }
+
+ /* scan for connectivity */
+ for (o = 0; o < config->num_output; o++)
+ {
+ xf86OutputPtr output = config->output[o];
+ output->status = output->funcs->detect(output);
+
+ if (output->status == XF86OutputStatusConnected)
+ num_connected++;
+ }
+
+ /*
+ * Hack for LVDS/eDP. We want to consider these disconnected if the
+ * lid is closed, but only if more than one output is connected (lest
+ * we darken the only available output, since lid status is unreliable)
+ */
+ if (num_connected > 1)
+ {
+ for (o = 0; o < config->num_output; o++)
+ {
+ xf86OutputPtr output = config->output[o];
+ if (strstr(output->name, "LVDS") || strstr(output->name, "eDP"))
+ if (output->status == XF86OutputStatusConnected)
+ output->status = lvds_lid_status();
+ }
+ }
+
/* Probe the list of modes for each output. */
for (o = 0; o < config->num_output; o++) {
xf86OutputPtr output = config->output[o];
@@ -1553,14 +1625,6 @@ xf86ProbeOutputModes(ScrnInfoPtr scrn, int maxX, int maxY)
Bool debug_modes = config->debug_modes || xf86Initialising;
enum det_monrec_source sync_source = sync_default;
- while (output->probed_modes != NULL)
- xf86DeleteMode(&output->probed_modes, output->probed_modes);
-
- /*
- * Check connection status
- */
- output->status = (*output->funcs->detect) (output);
-
if (output->status == XF86OutputStatusDisconnected &&
!xf86ReturnOptValBool(output->options, OPTION_ENABLE, FALSE)) {
xf86OutputSetEDID(output, NULL);
--
1.7.7.6
More information about the xorg-devel
mailing list