diff options
-rw-r--r-- | src/sna/sna.h | 2 | ||||
-rw-r--r-- | src/sna/sna_driver.c | 56 |
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; } |