From: Paulo Zanoni <paulo.r.zan...@intel.com>

Don't worry if that fails: only the KVMr feature will be affected.

We still need to change the sna/ code.

Signed-off-by: Paulo Zanoni <paulo.r.zanoni at intel.com>
---
 src/intel.h         |    3 ++
 src/intel_display.c |   79 +++++++++++++++++++++++++++++++++++++++++++++++++++
 src/intel_driver.c  |    2 +
 3 files changed, 84 insertions(+), 0 deletions(-)

diff --git a/src/intel.h b/src/intel.h
index f806aea..29df531 100644
--- a/src/intel.h
+++ b/src/intel.h
@@ -644,4 +644,7 @@ static inline Bool intel_pixmap_is_offscreen(PixmapPtr 
pixmap)
        return priv && priv->offscreen;
 }

+/* intel_display.c */
+void intel_crtc_leave_vt(ScrnInfoPtr scrn);
+
 #endif /* _I830_H_ */
diff --git a/src/intel_display.c b/src/intel_display.c
index abdc372..dad0fe1 100644
--- a/src/intel_display.c
+++ b/src/intel_display.c
@@ -82,6 +82,7 @@ struct intel_crtc {
        uint32_t rotate_fb_id;
        xf86CrtcPtr crtc;
        struct list link;
+       drmModePropertyPtr rotation_prop;
 };

 struct intel_property {
@@ -418,6 +419,44 @@ done:
        return ret;
 }

+static void
+intel_crtc_inform_rotation(xf86CrtcPtr crtc, Rotation rotation)
+{
+       struct intel_crtc *intel_crtc = crtc->driver_private;
+       int ret, int_rotation;
+
+       /* Try to inform the Kernel about our current rotation but don't
+        * worry if that fails */
+       if (intel_crtc->rotation_prop->prop_id) {
+
+               switch (rotation) {
+               case RR_Rotate_0:
+                       int_rotation = 0;
+                       break;
+               case RR_Rotate_90:
+                       int_rotation = 90;
+                       break;
+               case RR_Rotate_180:
+                       int_rotation = 180;
+                       break;
+               case RR_Rotate_270:
+                       int_rotation = 270;
+                       break;
+               default:
+                       int_rotation = 0;
+               }
+
+               ret = drmModeCrtcSetProperty(intel_crtc->mode->fd,
+                                            crtc_id(intel_crtc),
+                                            intel_crtc->rotation_prop->prop_id,
+                                            int_rotation);
+               if (ret)
+                       xf86DrvMsg(crtc->scrn->scrnIndex, X_WARNING,
+                                  "Failed to set CRTC rotation: %s\n",
+                                  strerror(-ret));
+       }
+}
+
 static Bool
 intel_crtc_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
                          Rotation rotation, int x, int y)
@@ -464,6 +503,8 @@ intel_crtc_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr 
mode,
                crtc->y = saved_y;
                crtc->rotation = saved_rotation;
                crtc->mode = saved_mode;
+       } else {
+               intel_crtc_inform_rotation(crtc, rotation);
        }
        return ret;
 }
@@ -640,12 +681,48 @@ intel_crtc_destroy(xf86CrtcPtr crtc)
                intel_crtc->cursor = NULL;
        }

+       if (intel_crtc->rotation_prop)
+               drmModeFreeProperty(intel_crtc->rotation_prop);
+
        list_del(&intel_crtc->link);
        free(intel_crtc);

        crtc->driver_private = NULL;
 }

+static void
+intel_crtc_load_properties(struct intel_mode *mode,
+                          struct intel_crtc *crtc)
+{
+       unsigned int i;
+       drmModeCrtcPropertiesPtr props;
+       drmModePropertyPtr prop;
+
+       crtc->rotation_prop = NULL;
+
+       props = drmModeCrtcGetProperties(mode->fd, crtc_id(crtc));
+       if (props) {
+               for (i = 0; i < props->count_props; i++) {
+                       prop = drmModeGetProperty(mode->fd, props->props[i]);
+                       if (!strcmp(prop->name, "rotation"))
+                               crtc->rotation_prop = prop;
+                       else
+                               drmModeFreeProperty(prop);
+               }
+               drmModeFreeCrtcProperties(props);
+       }
+}
+
+void
+intel_crtc_leave_vt(ScrnInfoPtr scrn)
+{
+       int i;
+       xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+
+       for (i = 0; i < xf86_config->num_crtc; i++)
+               intel_crtc_inform_rotation(xf86_config->crtc[i], RR_Rotate_0);
+}
+
 static const xf86CrtcFuncsRec intel_crtc_funcs = {
        .dpms = intel_crtc_dpms,
        .set_mode_major = intel_crtc_set_mode_major,
@@ -692,6 +769,8 @@ intel_crtc_init(ScrnInfoPtr scrn, struct intel_mode *mode, 
int num)

        intel_crtc->crtc = crtc;
        list_add(&intel_crtc->link, &mode->crtcs);
+
+       intel_crtc_load_properties(mode, intel_crtc);
 }

 static Bool
diff --git a/src/intel_driver.c b/src/intel_driver.c
index 4265de8..98466a3 100644
--- a/src/intel_driver.c
+++ b/src/intel_driver.c
@@ -1115,6 +1115,8 @@ static void I830LeaveVT(int scrnIndex, int flags)
        intel_screen_private *intel = intel_get_screen_private(scrn);
        int ret;

+       intel_crtc_leave_vt(scrn);
+
        xf86RotateFreeShadow(scrn);

        xf86_hide_cursors(scrn);
-- 
1.7.9.1

Reply via email to