Skip to content

Commit 95d396f

Browse files
committed
add system dpi method from Arduino
1 parent e976cb5 commit 95d396f

File tree

2 files changed

+63
-51
lines changed

2 files changed

+63
-51
lines changed

app/src/processing/app/platform/DefaultPlatform.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,4 +153,12 @@ public int unsetenv(String variable) {
153153
CLibrary clib = CLibrary.INSTANCE;
154154
return clib.unsetenv(variable);
155155
}
156+
157+
158+
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
159+
160+
161+
public int getSystemDPI() {
162+
return 96;
163+
}
156164
}

app/src/processing/app/platform/WindowsPlatform.java

Lines changed: 55 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,11 @@
2828

2929
import com.sun.jna.Library;
3030
import com.sun.jna.Native;
31+
import com.sun.jna.Pointer;
3132
import com.sun.jna.platform.win32.Shell32Util;
3233
import com.sun.jna.platform.win32.ShlObj;
34+
import com.sun.jna.win32.StdCallLibrary;
35+
import com.sun.jna.win32.W32APIOptions;
3336

3437
import processing.app.Base;
3538
import processing.app.Messages;
@@ -602,56 +605,57 @@ public int unsetenv(String variable) {
602605

603606
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
604607

605-
// JNA code for using SHGetFolderPath to fix Issue 410
606-
// https://code.google.com/p/processing/issues/detail?id=410
607-
// Based on answer provided by McDowell at
608-
// http://stackoverflow.com/questions/585534/what-is-the-best-way-to-find-the-users-home-directory-in-java/586917#586917
609608

610-
// private static Map<String, Object> OPTIONS = new HashMap<String, Object>();
611-
//
612-
// static {
613-
// OPTIONS.put(Library.OPTION_TYPE_MAPPER, W32APITypeMapper.UNICODE);
614-
// OPTIONS.put(Library.OPTION_FUNCTION_MAPPER, W32APIFunctionMapper.UNICODE);
615-
// }
616-
//
617-
//
618-
// static class HANDLE extends PointerType implements NativeMapped {
619-
// public HANDLE() { }
620-
// }
621-
//
622-
// static class HWND extends HANDLE { }
623-
//
624-
//
625-
// public interface Shell32 extends Library {
626-
//
627-
// public static final int MAX_PATH = 260;
628-
// public static final int SHGFP_TYPE_CURRENT = 0;
629-
// public static final int SHGFP_TYPE_DEFAULT = 1;
630-
// public static final int S_OK = 0;
631-
//
632-
// // KNOWNFOLDERIDs are preferred to CSDIL values
633-
// // but Windows XP only supports CSDIL so thats what we have to use
634-
// public static final int CSIDL_APPDATA = 0x001a; // "Application Data"
635-
// public static final int CSIDL_PERSONAL = 0x0005; // "My Documents"
636-
//
637-
// static Shell32 INSTANCE = (Shell32) Native.loadLibrary("shell32", Shell32.class, OPTIONS);
638-
//
639-
// /**
640-
// * see http://msdn.microsoft.com/en-us/library/bb762181(VS.85).aspx
641-
// *
642-
// * HRESULT SHGetFolderPath( HWND hwndOwner, int nFolder, HANDLE hToken,
643-
// * DWORD dwFlags, LPTSTR pszPath);
644-
// */
645-
// public int SHGetFolderPath(HWND hwndOwner, int nFolder, HANDLE hToken,
646-
// int dwFlags, char[] pszPath);
647-
//
648-
// /**
649-
// * This function can be used to copy, move, rename,
650-
// * or delete a file system object.
651-
// * @param fileop Address of an SHFILEOPSTRUCT structure that contains
652-
// * information this function needs to carry out the specified operation.
653-
// * @return Returns zero if successful, or nonzero otherwise.
654-
// */
655-
// public int SHFileOperation(SHFILEOPSTRUCT fileop);
656-
// }
609+
// Need to extend com.sun.jna.platform.win32.User32 to access
610+
// Win32 function GetDpiForSystem()
611+
interface ExtUser32 extends StdCallLibrary, com.sun.jna.platform.win32.User32 {
612+
ExtUser32 INSTANCE = (ExtUser32) Native.loadLibrary("user32", ExtUser32.class, W32APIOptions.DEFAULT_OPTIONS);
613+
614+
public int GetDpiForSystem();
615+
616+
public int SetProcessDpiAwareness(int value);
617+
618+
public final int DPI_AWARENESS_INVALID = -1;
619+
public final int DPI_AWARENESS_UNAWARE = 0;
620+
public final int DPI_AWARENESS_SYSTEM_AWARE = 1;
621+
public final int DPI_AWARENESS_PER_MONITOR_AWARE = 2;
622+
623+
public Pointer SetThreadDpiAwarenessContext(Pointer dpiContext);
624+
625+
public final Pointer DPI_AWARENESS_CONTEXT_UNAWARE = new Pointer(-1);
626+
public final Pointer DPI_AWARENESS_CONTEXT_SYSTEM_AWARE = new Pointer(-2);
627+
public final Pointer DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE = new Pointer(-3);
628+
}
629+
630+
631+
static private int detected = detectSystemDPI();
632+
633+
634+
public int getSystemDPI() {
635+
if (detected == -1) {
636+
return super.getSystemDPI();
637+
}
638+
return detected;
639+
}
640+
641+
642+
public static int detectSystemDPI() {
643+
try {
644+
ExtUser32.INSTANCE.SetProcessDpiAwareness(ExtUser32.DPI_AWARENESS_SYSTEM_AWARE);
645+
} catch (Throwable e) {
646+
// Ignore error
647+
}
648+
try {
649+
ExtUser32.INSTANCE.SetThreadDpiAwarenessContext(ExtUser32.DPI_AWARENESS_CONTEXT_SYSTEM_AWARE);
650+
} catch (Throwable e) {
651+
// Ignore error (call valid only on Windows 10)
652+
}
653+
try {
654+
return ExtUser32.INSTANCE.GetDpiForSystem();
655+
} catch (Throwable e) {
656+
// DPI detection failed, fall back with default
657+
System.out.println("DPI detection failed, fallback to 96 dpi");
658+
return -1;
659+
}
660+
}
657661
}

0 commit comments

Comments
 (0)