1--- a/src/dummy.h	2016-12-17 23:02:53.396287041 +0100
2+++ b/src/dummy.h	2016-12-17 23:03:30.319616550 +0100
3@@ -51,6 +51,7 @@
4     /* options */
5     OptionInfoPtr Options;
6     Bool swCursor;
7+    Bool constantDPI;
8     /* proc pointer */
9     CloseScreenProcPtr CloseScreen;
10     xf86CursorInfoPtr CursorInfo;
11--- a/src/dummy_driver.c	2016-12-14 21:54:20.000000000 +0100
12+++ b/src/dummy_driver.c	2016-12-17 23:04:59.916416126 +0100
13@@ -17,6 +17,12 @@
14 /* All drivers using the mi colormap manipulation need this */
15 #include "micmap.h"
16
17+#ifdef RANDR
18+#include "randrstr.h"
19+#endif
20+
21+#include "windowstr.h"
22+
23 /* identifying atom needed by magnifiers */
24 #include <X11/Xatom.h>
25 #include "property.h"
26@@ -115,11 +121,15 @@
27 };
28
29 typedef enum {
30-    OPTION_SW_CURSOR
31+    OPTION_SW_CURSOR,
32+    OPTION_CONSTANT_DPI
33 } DUMMYOpts;
34
35 static const OptionInfoRec DUMMYOptions[] = {
36     { OPTION_SW_CURSOR,	"SWcursor",	OPTV_BOOLEAN,	{0}, FALSE },
37+#ifdef RANDR
38+    { OPTION_CONSTANT_DPI,	"ConstantDPI",	OPTV_BOOLEAN,	{0}, FALSE },
39+#endif
40     { -1,                  NULL,           OPTV_NONE,	{0}, FALSE }
41 };
42
43@@ -359,6 +369,7 @@
44     xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, dPtr->Options);
45
46     xf86GetOptValBool(dPtr->Options, OPTION_SW_CURSOR,&dPtr->swCursor);
47+    xf86GetOptValBool(dPtr->Options, OPTION_CONSTANT_DPI, &dPtr->constantDPI);
48
49     if (device->videoRam != 0) {
50 	pScrn->videoRam = device->videoRam;
51@@ -639,10 +650,45 @@
52     return TRUE;
53 }
54
55+const char *XDPY_PROPERTY = "dummy-constant-xdpi";
56+const char *YDPY_PROPERTY = "dummy-constant-ydpi";
57+static int get_dpi_value(WindowPtr root, const char *property_name, int default_dpi)
58+{
59+    PropertyPtr prop;
60+    Atom type_atom = MakeAtom("CARDINAL", 8, TRUE);
61+    Atom prop_atom = MakeAtom(property_name, strlen(property_name), FALSE);
62+
63+    for (prop = wUserProps(root); prop; prop = prop->next) {
64+       if (prop->propertyName == prop_atom && prop->type == type_atom && prop->data) {
65+           int v = (int) (*((CARD32 *) prop->data));
66+           if ((v>0) && (v<4096)) {
67+               xf86DrvMsg(0, X_INFO, "get_constant_dpi_value() found property \"%s\" with value=%i\n", property_name, (int) v);
68+               return (int) v;
69+           }
70+           break;
71+       }
72+    }
73+    return default_dpi;
74+}
75+
76 /* Mandatory */
77 Bool
78 DUMMYSwitchMode(SWITCH_MODE_ARGS_DECL)
79 {
80+    SCRN_INFO_PTR(arg);
81+#ifdef RANDR
82+    DUMMYPtr dPtr = DUMMYPTR(pScrn);
83+    if (dPtr->constantDPI) {
84+        int xDpi = get_dpi_value(pScrn->pScreen->root, XDPY_PROPERTY, pScrn->xDpi);
85+        int yDpi = get_dpi_value(pScrn->pScreen->root, YDPY_PROPERTY, pScrn->yDpi);
86+        //25.4 mm per inch: (254/10)
87+        pScrn->pScreen->mmWidth = mode->HDisplay * 254 / xDpi / 10;
88+        pScrn->pScreen->mmHeight = mode->VDisplay * 254 / yDpi / 10;
89+        xf86DrvMsg(pScrn->scrnIndex, X_INFO, "mm(dpi %ix%i)=%ix%i\n", xDpi, yDpi, pScrn->pScreen->mmWidth, pScrn->pScreen->mmHeight);
90+        RRScreenSizeNotify(pScrn->pScreen);
91+        RRTellChanged(pScrn->pScreen);
92+    }
93+#endif
94     return TRUE;
95 }
96
97