1/*
2* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
3* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*
5* This code is free software; you can redistribute it and/or modify it
6* under the terms of the GNU General Public License version 2 only, as
7* published by the Free Software Foundation.
8*
9* This code is distributed in the hope that it will be useful, but WITHOUT
10* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11* FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12* version 2 for more details (a copy is included in the LICENSE file that
13* accompanied this code).
14*
15* You should have received a copy of the GNU General Public License version
16* 2 along with this work; if not, write to the Free Software Foundation,
17* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18*
19* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20* or visit www.oracle.com if you need additional information or have any
21* questions.
22*/
23#include "systemScale.h"
24#include <d2d1.h>
25#pragma comment(lib, "d2d1")
26#include <jdk_util.h>
27#ifndef MDT_EFFECTIVE_DPI
28#define MDT_EFFECTIVE_DPI 0
29#endif
30
31void GetScreenDpi(HMONITOR hmon, float *dpiX, float *dpiY)
32{
33    unsigned x = 0;
34    unsigned y = 0;
35
36    // for debug purposes
37    static float scale = -2.0f;
38    if (scale == -2) {
39        scale = -1;
40        char *uiScale = getenv("J2D_UISCALE");
41        if (uiScale != NULL) {
42            scale = (float)strtod(uiScale, NULL);
43            if (errno == ERANGE || scale <= 0) {
44                scale = -1;
45            }
46        }
47    }
48
49    if (scale > 0) {
50        *dpiX = *dpiY = scale;
51        return;
52    }
53
54    typedef HRESULT(WINAPI GetDpiForMonitorFunc)(HMONITOR, int, UINT*, UINT*);
55    static HMODULE hLibSHCoreDll = NULL;
56    static GetDpiForMonitorFunc *lpGetDpiForMonitor = NULL;
57
58    if (hLibSHCoreDll == NULL) {
59        hLibSHCoreDll = JDK_LoadSystemLibrary("shcore.dll");
60        if (hLibSHCoreDll != NULL) {
61            lpGetDpiForMonitor = (GetDpiForMonitorFunc*)GetProcAddress(
62                hLibSHCoreDll, "GetDpiForMonitor");
63        }
64    }
65
66    if (lpGetDpiForMonitor != NULL) {
67        HRESULT hResult = lpGetDpiForMonitor(hmon,
68                                             MDT_EFFECTIVE_DPI, &x, &y);
69        if (hResult == S_OK) {
70            *dpiX = static_cast<float>(x);
71            *dpiY = static_cast<float>(y);
72        }
73    } else {
74        ID2D1Factory* m_pDirect2dFactory;
75        HRESULT res = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED,
76                                        &m_pDirect2dFactory);
77        if (res == S_OK) {
78            m_pDirect2dFactory->GetDesktopDpi(dpiX, dpiY);
79            m_pDirect2dFactory->Release();
80        }
81    }
82    return;
83}
84
85HMONITOR WINAPI getPrimaryMonitor()
86{
87    const POINT point = { 0, 0 };
88    return MonitorFromPoint(point, MONITOR_DEFAULTTOPRIMARY);
89}
90