summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/sna/sna.h2
-rw-r--r--src/sna/sna_driver.c56
2 files changed, 52 insertions, 6 deletions
diff --git a/src/sna/sna.h b/src/sna/sna.h
index e0356343..4cd85d19 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -312,6 +312,8 @@ struct sna {
struct udev_monitor *backlight_monitor;
pointer backlight_handler;
#endif
+
+ Bool (*rrGetInfo)(ScreenPtr, Rotation *);
} mode;
struct {
diff --git a/src/sna/sna_driver.c b/src/sna/sna_driver.c
index f28ca872..a09aa986 100644
--- a/src/sna/sna_driver.c
+++ b/src/sna/sna_driver.c
@@ -59,6 +59,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <sys/ioctl.h>
#include <sys/fcntl.h>
+#include <sys/poll.h>
#include "i915_drm.h"
#ifdef HAVE_VALGRIND
@@ -866,6 +867,22 @@ err_dev:
goto out;
}
+static bool sna_uevent_poll(struct sna *sna)
+{
+ struct pollfd pfd;
+
+ if (sna->uevent_monitor == NULL)
+ return false;
+
+ pfd.fd = udev_monitor_get_fd(sna->uevent_monitor);
+ pfd.events = POLLIN;
+
+ if (poll(&pfd, 1, 0) > 0)
+ sna_handle_uevents(pfd.fd, sna);
+
+ return true;
+}
+
static void
sna_uevent_fini(struct sna *sna)
{
@@ -887,9 +904,21 @@ sna_uevent_fini(struct sna *sna)
}
#else
static void sna_uevent_init(struct sna *sna) { }
+static bool sna_uevent_poll(struct sna *sna) { return false; }
static void sna_uevent_fini(struct sna *sna) { }
#endif /* HAVE_UDEV */
+static Bool
+sna_randr_getinfo(ScreenPtr screen, Rotation *rotations)
+{
+ struct sna *sna = to_sna_from_screen(screen);
+
+ if (!sna_uevent_poll(sna))
+ sna_mode_discover(sna);
+
+ return sna->mode.rrGetInfo(screen, rotations);
+}
+
static void sna_leave_vt(VT_FUNC_ARGS_DECL)
{
SCRN_INFO_PTR(arg);
@@ -1035,6 +1064,25 @@ agp_aperture_size(struct pci_device *dev, int gen)
}
static Bool
+sna_mode_init(struct sna *sna, ScreenPtr screen)
+{
+ rrScrPrivPtr rp;
+
+ if (!xf86CrtcScreenInit(screen))
+ return FALSE;
+
+ xf86RandR12SetRotations(screen, RR_Rotate_All | RR_Reflect_All);
+ xf86RandR12SetTransformSupport(screen, TRUE);
+
+ /* Wrap RR queries to catch pending MST topology changes */
+ rp = rrGetScrPriv(screen);
+ sna->mode.rrGetInfo = rp->rrGetInfo;
+ rp->rrGetInfo = sna_randr_getinfo;
+
+ return TRUE;
+}
+
+static Bool
sna_screen_init(SCREEN_INIT_ARGS_DECL)
{
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
@@ -1134,12 +1182,9 @@ sna_screen_init(SCREEN_INIT_ARGS_DECL)
sna->CloseScreen = screen->CloseScreen;
screen->CloseScreen = sna_early_close_screen;
- if (!xf86CrtcScreenInit(screen))
+ if (!sna_mode_init(sna, screen))
return FALSE;
- xf86RandR12SetRotations(screen, RR_Rotate_All | RR_Reflect_All);
- xf86RandR12SetTransformSupport(screen, TRUE);
-
if (!miCreateDefColormap(screen))
return FALSE;
@@ -1151,6 +1196,7 @@ sna_screen_init(SCREEN_INIT_ARGS_DECL)
xf86DPMSInit(screen, sna_dpms_set, 0);
+ sna_uevent_init(sna);
sna_video_init(sna, screen);
sna_dri_init(sna, screen);
@@ -1165,8 +1211,6 @@ sna_screen_init(SCREEN_INIT_ARGS_DECL)
sna->suspended = FALSE;
- sna_uevent_init(sna);
-
return TRUE;
}