diff options
author | Sven Gothel <[email protected]> | 2023-01-31 22:57:23 +0100 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2023-01-31 22:57:23 +0100 |
commit | 7982cc52344c025c40da45fd4b946056a63bc855 (patch) | |
tree | 821c49296827111efc7b4b207ae4cc2726320559 /src/nativewindow | |
parent | ad38d1559854985b1131e5b6c7274a392b5bc265 (diff) |
NEWT Soft-PixelScale (p7): get{Global->}PixelScaleEnv(..): Support per monitor values w/ QT_SCREEN_SCALE_FACTORS syntax, use for X11v2.4.0
Per-monitor values are parsed if value is not a float and stored
in a given Map<String,float[2]>, parallel to a detected global_pixel_scale_xy.
The per-monitor value syntax matches QT_SCREEN_SCALE_FACTORS,
i.e. the regular expression '(<string>=<float>;)+',
e.g. QT_SCREEN_SCALE_FACTORS='DP-1=1.25;DP-2=1.25;HDMI-1=1.25;'
The per-monitor value is preferred and on X11 stored within the MonitorDevice,
matching the MonitorDevice's name.
The following env-var names are searched on X11:
"QT_SCREEN_SCALE_FACTORS", "QT_SCALE_FACTOR", "GDK_SCALE", "SOFT_SCALE"
Diffstat (limited to 'src/nativewindow')
-rw-r--r-- | src/nativewindow/classes/jogamp/nativewindow/SurfaceScaleUtils.java | 100 |
1 files changed, 82 insertions, 18 deletions
diff --git a/src/nativewindow/classes/jogamp/nativewindow/SurfaceScaleUtils.java b/src/nativewindow/classes/jogamp/nativewindow/SurfaceScaleUtils.java index c732151e5..8f45001f9 100644 --- a/src/nativewindow/classes/jogamp/nativewindow/SurfaceScaleUtils.java +++ b/src/nativewindow/classes/jogamp/nativewindow/SurfaceScaleUtils.java @@ -228,42 +228,106 @@ public class SurfaceScaleUtils { } /** + * Returns a proper string representation of the monitor-name to float[2] pixel-scale map. + */ + public static String toString(final Map<String,float[/*2*/]> monitorNameToScale) { + final StringBuilder sb = new StringBuilder(); + sb.append("{ "); + for(final String name: monitorNameToScale.keySet()) { + sb.append("'").append(name).append("'").append(" = ( "); + final float[] value = monitorNameToScale.get(name); + if( null != value && 2 == value.length ) { + sb.append(value[0]).append(" / ").append(value[1]); + } + sb.append(" ), "); + } + sb.append(" }"); + return sb.toString(); + } + + /** * Get global pixel-scale values from environment variables, e.g.: + * - QT_SCREEN_SCALE_FACTORS * - QT_SCALE_FACTOR * - GDK_SCALE * See https://wiki.archlinux.org/title/HiDPI * @param env_var_names array of potential environment variable names, treated as float. - * @param pixel_scale_xy store for resulting scale factors - * @return index of first found variable name within env_var_names, otherwise -1 + * @param global_pixel_scale_xy store for resulting scale factors + * @param monitorNameToScale storage mapping monitor names to their pixel_scale_xy, if variable value is of regular expression '(<string>=<float>;)+', + * i.e. QT_SCREEN_SCALE_FACTORS='DP-1=1.25;DP-2=1.25;HDMI-1=1.25;' + * @return index of first found global variable name within env_var_names, otherwise -1 */ - public static int getGlobalPixelScaleEnv(final String[] env_var_names, final float[] pixel_scale_xy) { + public static int getPixelScaleEnv(final String[] env_var_names, final float[] global_pixel_scale_xy, final Map<String,float[/*2*/]> monitorNameToScale) { final Map<String, String> env = SecurityUtil.doPrivileged(new PrivilegedAction<Map<String, String>>() { @Override public Map<String, String> run() { return System.getenv(); } }); - float value = -1.0f; + float global_value = -1.0f; + int global_idx = -1; + int mapping_idx = -1; boolean done = false; - int var_idx = 0; - while( var_idx < env_var_names.length && !done ) { + for(int var_idx = 0; var_idx < env_var_names.length && !done; ++var_idx ) { final String env_var_name = env_var_names[var_idx]; final String s_value = env.get(env_var_name); - if( null != s_value ) { - try { - value = Float.valueOf(s_value); - done = true; - } catch(final NumberFormatException nfe) { - ++var_idx; + if( null == s_value || s_value.isEmpty()) { + continue; // next + } + try { + final float v = Float.valueOf(s_value); + if( 0 > global_idx ) { // no overwrite + global_value = v; + global_idx = var_idx; + } + } catch(final NumberFormatException nfe) { + if( 0 <= mapping_idx ) { + continue; + } + // Attempt to parse regular expression '(<string>=<float>;)+', + // i.e. QT_SCREEN_SCALE_FACTORS='DP-1=1.25;DP-2=1.25;HDMI-1=1.25;' + final String[] pairs = s_value.split(";"); + if( null != pairs ) { + for(final String pair : pairs) { + if( null == pair || pair.isEmpty() ) { + continue; // empty is OK, next + } + final String[] elems = pair.split("="); + if( null == elems || 2 != elems.length ) { + // syntax error, bail out + monitorNameToScale.clear(); + break; + } + if( null == elems[0] || elems[0].isEmpty() ) { + // syntax error (empty name), bail out + monitorNameToScale.clear(); + break; + } + if( null == elems[1] || elems[1].isEmpty() ) { + // syntax error (empty value), bail out + monitorNameToScale.clear(); + break; + } + try { + final float pair_value = Float.valueOf(elems[1]); + monitorNameToScale.put(elems[0], new float[] { pair_value, pair_value} ); + mapping_idx = var_idx; + } catch(final NumberFormatException nfe2) { + // syntax error, bail out + monitorNameToScale.clear(); + break; + } + } } - } else { - ++var_idx; } + done = 0 <= mapping_idx && 0 <= global_idx; } - if( done ) { - pixel_scale_xy[0] = value; - pixel_scale_xy[1] = value; - return var_idx; + if( 0 <= global_idx ) { + global_pixel_scale_xy[0] = global_value; + global_pixel_scale_xy[1] = global_value; + return global_idx; + } else if( 0 <= mapping_idx ) { + return mapping_idx; } else { return -1; } |