]> source.dussan.org Git - tigervnc.git/commitdiff
Set user/client requested mode as preferred
authorPierre Ossman <ossman@cendio.se>
Thu, 30 Jul 2015 13:06:37 +0000 (15:06 +0200)
committerPierre Ossman <ossman@cendio.se>
Thu, 30 Jul 2015 13:10:51 +0000 (15:10 +0200)
Desktop environments like to change to the monitor's preferred
mode, especially at login. Lacking one, they pick the highest
resolution they can find. This tends to override what the user
has picked, so try to work around the desktop environments by
setting the preferred mode to what the user has chosen.

Credit goes to Michal Srb who figured out the problem.

unix/xserver/hw/vnc/XorgGlue.c
unix/xserver/hw/vnc/XorgGlue.h
unix/xserver/hw/vnc/vncModule.c
unix/xserver/hw/vnc/xvnc.c

index 8a3a2735dcebe6bb74474f9e393b41385e8dd288..d7892b1839fcd672c5f6c86d7d15e02483aae69c 100644 (file)
@@ -291,25 +291,6 @@ void vncRandRGetOutputDimensions(int scrIdx, int outputIdx,
 #endif
 }
 
-#ifdef RANDR
-static RRModePtr findRandRMode(RROutputPtr output, int width, int height)
-{
-  RRModePtr mode;
-
-  for (int i = 0;i < output->numModes;i++) {
-    if ((output->modes[i]->mode.width == width) &&
-        (output->modes[i]->mode.height == height))
-      return output->modes[i];
-  }
-
-  mode = vncRandRModeGet(width, height);
-  if (mode != NULL)
-    return mode;
-
-  return NULL;
-}
-#endif
-
 int vncRandRReconfigureOutput(int scrIdx, int outputIdx, int x, int y,
                               int width, int height)
 {
@@ -340,15 +321,10 @@ int vncRandRReconfigureOutput(int scrIdx, int outputIdx, int x, int y,
       return -1;
   }
 
-  mode = crtc->mode;
-
-  /* Need to switch mode? */
-  if ((mode == NULL) ||
-      (mode->mode.width != width) || (mode->mode.height != height)) {
-    mode = findRandRMode(output, width, height);
-    if (mode == NULL)
-      return -1;
-  }
+  /* Make sure we have the mode we want */
+  mode = vncRandRCreatePreferredMode(output, width, height);
+  if (mode == NULL)
+    return -1;
 
   /* Reconfigure new mode and position */
   return RRCrtcSet(crtc, mode, x, y, crtc->rotation, 1, &output);
index 05ca7ba997d00737865336627140ae142d71ddf8..92b0d18de074ac91efb80bb4e00e256c0b0ba55f 100644 (file)
@@ -59,8 +59,8 @@ void vncRandRGetOutputDimensions(int scrIdx, int outputIdx,
 
 // These hide in xvnc.c or vncModule.c
 void vncClientGone(int fd);
-void *vncRandRModeGet(int width, int height);
 int vncRandRCreateOutputs(int scrIdx, int extraOutputs);
+void *vncRandRCreatePreferredMode(void *output, int width, int height);
 
 #ifdef __cplusplus
 }
index 8cbf9c2d9d969b40824db393612f6ea03cbe4bbc..21f87ce9200513e21039e02b0898c172e33c9c57 100644 (file)
@@ -112,13 +112,28 @@ void vncClientGone(int fd)
 }
 
 #ifdef RANDR
-void *vncRandRModeGet(int width, int height)
+int vncRandRCreateOutputs(int scrIdx, int extraOutputs)
 {
-    return NULL;
+  return -1;
 }
 
-int vncRandRCreateOutputs(int scrIdx, int extraOutputs)
+void *vncRandRCreatePreferredMode(void *out, int width, int height)
 {
-  return -1;
+  RROutputPtr output;
+
+  /*
+   * We're not going to change which modes are preferred, but let's
+   * see if we can at least find a mode with matching dimensions.
+   */
+
+  output = out;
+
+  for (int i = 0;i < output->numModes;i++) {
+    if ((output->modes[i]->mode.width == width) &&
+        (output->modes[i]->mode.height == height))
+      return output->modes[i];
+  }
+
+  return NULL;
 }
 #endif
index 714d8a2ffedb8a6cf8247eb8577cbb4384653e99..cac2aeeb0f20f2dfc13b19f690243d086cf5a042 100644 (file)
@@ -1071,6 +1071,7 @@ xf86SetRootClip (ScreenPtr pScreen, Bool enable)
 static Bool vncRandRCrtcSet(ScreenPtr pScreen, RRCrtcPtr crtc, RRModePtr mode,
                             int x, int y, Rotation rotation, int num_outputs,
                             RROutputPtr *outputs);
+static RRModePtr vncRandRModeGet(int width, int height);
 
 static Bool vncRandRScreenSetSize(ScreenPtr pScreen,
                                   CARD16 width, CARD16 height,
@@ -1179,7 +1180,7 @@ static Bool vncRandRScreenSetSize(ScreenPtr pScreen,
             continue;
         }
 
-        /* Just needs to be resized */
+        /* Just needs to be resized to a temporary mode */
         mode = vncRandRModeGet(width - crtc->x, height - crtc->y);
         if (mode == NULL) {
             ErrorF("Warning: Unable to create custom mode for %dx%d",
@@ -1244,8 +1245,7 @@ static const int vncRandRHeights[] = { 1200, 1080, 1200, 1050, 1050,  768, 1024,
 
 static int vncRandRIndex = 0;
 
-/* This is a global symbol since findRandRMode() also uses it */
-void *vncRandRModeGet(int width, int height)
+static RRModePtr vncRandRModeGet(int width, int height)
 {
     xRRModeInfo        modeInfo;
     char name[100];
@@ -1267,16 +1267,51 @@ void *vncRandRModeGet(int width, int height)
     return mode;
 }
 
+static void vncRandRSetModes(RROutputPtr output, int pref_width, int pref_height)
+{
+    RRModePtr mode;
+    RRModePtr *modes;
+    int i, num_modes, num_pref;
+
+    num_modes = sizeof(vncRandRWidths)/sizeof(*vncRandRWidths) + 1;
+    modes = malloc(sizeof(RRModePtr)*num_modes);
+    if (modes == NULL)
+        return;
+
+    num_modes = 0;
+    num_pref = 0;
+
+    if ((pref_width > 0) && (pref_height > 0)) {
+        mode = vncRandRModeGet(pref_width, pref_height);
+        if (mode != NULL) {
+            modes[num_modes] = mode;
+            num_modes++;
+            num_pref++;
+        }
+    }
+
+    for (i = 0;i < sizeof(vncRandRWidths)/sizeof(*vncRandRWidths);i++) {
+        if ((vncRandRWidths[i] == pref_width) &&
+            (vncRandRHeights[i] == pref_height))
+            continue;
+        mode = vncRandRModeGet(vncRandRWidths[i], vncRandRHeights[i]);
+        if (mode != NULL) {
+            modes[num_modes] = mode;
+            num_modes++;
+        }
+    }
+
+    RROutputSetModes(output, modes, num_modes, num_pref);
+
+    free(modes);
+}
+
 static RRCrtcPtr vncRandRCrtcCreate(ScreenPtr pScreen)
 {
     RRCrtcPtr crtc;
     RROutputPtr output;
-    RRModePtr mode;
     char name[100];
 
-    RRModePtr *modes;
-    int i, num_modes;
-
     /* First we create the CRTC... */
     crtc = RRCrtcCreate(pScreen, NULL);
 
@@ -1296,22 +1331,7 @@ static RRCrtcPtr vncRandRCrtcCreate(ScreenPtr pScreen)
     vncRandRCrtcSet(pScreen, crtc, NULL, 0, 0, RR_Rotate_0, 1, &output);
 
     /* Populate a list of default modes */
-    modes = malloc(sizeof(RRModePtr)*sizeof(vncRandRWidths)/sizeof(*vncRandRWidths));
-    if (modes == NULL)
-        return NULL;
-
-    num_modes = 0;
-    for (i = 0;i < sizeof(vncRandRWidths)/sizeof(*vncRandRWidths);i++) {
-        mode = vncRandRModeGet(vncRandRWidths[i], vncRandRHeights[i]);
-        if (mode != NULL) {
-            modes[num_modes] = mode;
-            num_modes++;
-        }
-    }
-
-    RROutputSetModes(output, modes, num_modes, 0);
-
-    free(modes);
+    vncRandRSetModes(output, -1, -1);
 
     return crtc;
 }
@@ -1331,6 +1351,30 @@ int vncRandRCreateOutputs(int scrIdx, int extraOutputs)
     return 0;
 }
 
+/* Used to create a preferred mode from various places */
+void *vncRandRCreatePreferredMode(void *out, int width, int height)
+{
+    RROutputPtr output;
+
+    output = out;
+
+    /* Already the preferred mode? */
+    if ((output->numModes >= 1) && (output->numPreferred == 1) &&
+        (output->modes[0]->mode.width == width) &&
+        (output->modes[0]->mode.height == height))
+        return output->modes[0];
+
+    /* Recreate the list, with the mode we want as preferred */
+    vncRandRSetModes(output, width, height);
+
+    if ((output->numModes >= 1) && (output->numPreferred == 1) &&
+        (output->modes[0]->mode.width == width) &&
+        (output->modes[0]->mode.height == height))
+        return output->modes[0];
+
+    return NULL;
+}
+
 static Bool vncRandRInit(ScreenPtr pScreen)
 {
     RRCrtcPtr crtc;
@@ -1350,13 +1394,13 @@ static Bool vncRandRInit(ScreenPtr pScreen)
     crtc = vncRandRCrtcCreate(pScreen);
 
     /* Make sure the current screen size is the active mode */
-    mode = vncRandRModeGet(pScreen->width, pScreen->height);
+    mode = vncRandRCreatePreferredMode(crtc->outputs[0],
+                                       pScreen->width, pScreen->height);
     if (mode == NULL)
         return FALSE;
 
     ret = vncRandRCrtcSet(pScreen, crtc, mode, 0, 0, RR_Rotate_0,
                           crtc->numOutputs, crtc->outputs);
-    RRModeDestroy(mode);
     if (!ret)
         return FALSE;