1 /* 2 * Copyright (c) 2010, 2015, 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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 package com.sun.glass.ui; 26 27 import java.security.AccessController; 28 import java.security.PrivilegedAction; 29 import java.util.Arrays; 30 import java.util.Collections; 31 import java.util.List; 32 33 public final class Screen { 34 35 // the list of attached screens provided by native. 36 // screens[0] is the default/main Screen 37 private static volatile List<Screen> screens = null ; 38 39 // If dpiOverride is non-zero, use its value as screen DPI 40 private static final int dpiOverride; 41 42 static { 43 dpiOverride = AccessController.doPrivileged((PrivilegedAction<Integer>) () -> Integer.getInteger("com.sun.javafx.screenDPI", 0)).intValue(); 44 } 45 46 public static class EventHandler { 47 public void handleSettingsChanged() { 48 } 49 } 50 51 public static double getVideoRefreshPeriod() { 52 Application.checkEventThread(); 53 return Application.GetApplication().staticScreen_getVideoRefreshPeriod(); 54 } 55 56 /** 57 * Could be called from any thread 58 * @return the main screen 59 */ 60 public static Screen getMainScreen() { 61 return getScreens().get(0); 62 } 63 64 /** 65 * Could be called from any thread 66 * @return list of all available screens 67 */ 68 public static List<Screen> getScreens() { 69 if (screens == null) { 70 throw new RuntimeException("Internal graphics not initialized yet"); 71 } 72 73 return screens; 74 } 75 76 private static EventHandler eventHandler; 77 78 private volatile long ptr; 79 private volatile int adapter; 80 81 private final int depth; 82 83 private final int x; 84 private final int y; 85 private final int width; 86 private final int height; 87 88 private final int platformX; 89 private final int platformY; 90 private final int platformWidth; 91 private final int platformHeight; 92 93 private final int visibleX; 94 private final int visibleY; 95 private final int visibleWidth; 96 private final int visibleHeight; 97 98 private final int resolutionX; 99 private final int resolutionY; 100 101 private final float platformScaleX; 102 private final float platformScaleY; 103 private final float outputScaleX; 104 private final float outputScaleY; 105 106 public Screen( 107 long nativePtr, 108 109 int depth, 110 int x, 111 int y, 112 int width, 113 int height, 114 115 int platformX, 116 int platformY, 117 int platformWidth, 118 int platformHeight, 119 120 int visibleX, 121 int visibleY, 122 int visibleWidth, 123 int visibleHeight, 124 125 int resolutionX, 126 int resolutionY, 127 128 float platformScaleX, 129 float platformScaleY, 130 float outputScaleX, 131 float outputScaleY 132 ) { 133 this.ptr = nativePtr; 134 135 this.depth = depth; 136 137 this.x = x; 138 this.y = y; 139 this.width = width; 140 this.height = height; 141 142 this.platformX = platformX; 143 this.platformY = platformY; 144 this.platformWidth = platformWidth; 145 this.platformHeight = platformHeight; 146 147 this.visibleX = visibleX; 148 this.visibleY = visibleY; 149 this.visibleWidth = visibleWidth; 150 this.visibleHeight = visibleHeight; 151 152 if (dpiOverride > 0) { 153 this.resolutionX = this.resolutionY = dpiOverride; 154 } else { 155 this.resolutionX = resolutionX; 156 this.resolutionY = resolutionY; 157 } 158 159 this.platformScaleX = platformScaleX; 160 this.platformScaleY = platformScaleY; 161 this.outputScaleX = outputScaleX; 162 this.outputScaleY = outputScaleY; 163 } 164 165 /** 166 * Could be called from any thread 167 */ 168 public int getDepth() { 169 return this.depth; 170 } 171 172 /** 173 * Could be called from any thread 174 */ 175 public int getX() { 176 return this.x; 177 } 178 179 /** 180 * Could be called from any thread 181 */ 182 public int getY() { 183 return this.y; 184 } 185 186 /** 187 * Could be called from any thread 188 */ 189 public int getWidth() { 190 return this.width; 191 } 192 193 /** 194 * Could be called from any thread 195 */ 196 public int getHeight() { 197 return this.height; 198 } 199 200 /** 201 * Could be called from any thread 202 */ 203 public int getPlatformX() { 204 return this.platformX; 205 } 206 207 /** 208 * Could be called from any thread 209 */ 210 public int getPlatformY() { 211 return this.platformY; 212 } 213 214 /** 215 * Could be called from any thread 216 */ 217 public int getPlatformWidth() { 218 return this.platformWidth; 219 } 220 221 /** 222 * Could be called from any thread 223 */ 224 public int getPlatformHeight() { 225 return this.platformHeight; 226 } 227 228 /** 229 * Returns the horizontal scaling of the UI (window sizes and event 230 * coordinates) from FX logical units to the platform units. 231 * Could be called from any thread 232 * @return platform X scaling 233 */ 234 public float getPlatformScaleX() { 235 return this.platformScaleX; 236 } 237 238 /** 239 * Returns the vertical scaling of the UI (window sizes and event 240 * coordinates) from FX logical units to the platform units. 241 * Could be called from any thread 242 * @return platform Y scaling 243 */ 244 public float getPlatformScaleY() { 245 return this.platformScaleY; 246 } 247 248 /** 249 * Returns the recommended horizontal scaling for the rendered frames. 250 * Could be called from any thread 251 * @return recommended render X scaling 252 */ 253 public float getRecommendedOutputScaleX() { 254 return this.outputScaleX; 255 } 256 257 /** 258 * Returns the recommended vertical scaling for the rendered frames. 259 * Could be called from any thread 260 * @return recommended render Y scaling 261 */ 262 public float getRecommendedOutputScaleY() { 263 return this.outputScaleY; 264 } 265 266 /** 267 * Could be called from any thread 268 */ 269 public int getVisibleX() { 270 return this.visibleX; 271 } 272 273 /** 274 * Could be called from any thread 275 */ 276 public int getVisibleY() { 277 return this.visibleY; 278 } 279 280 /** 281 * Could be called from any thread 282 */ 283 public int getVisibleWidth() { 284 return this.visibleWidth; 285 } 286 287 /** 288 * Could be called from any thread 289 */ 290 public int getVisibleHeight() { 291 return this.visibleHeight; 292 } 293 294 /** 295 * Could be called from any thread 296 */ 297 public int getResolutionX() { 298 return this.resolutionX; 299 } 300 301 /** 302 * Could be called from any thread 303 */ 304 public int getResolutionY() { 305 return this.resolutionY; 306 } 307 308 /** 309 * Could be called from any thread 310 */ 311 public long getNativeScreen() { 312 return this.ptr; 313 } 314 315 private void dispose() { 316 this.ptr = 0L; 317 } 318 319 public int getAdapterOrdinal() { 320 return this.adapter; 321 } 322 323 public void setAdapterOrdinal(int adapter) { 324 this.adapter = adapter; 325 } 326 327 public static void setEventHandler(EventHandler eh) { 328 Application.checkEventThread(); 329 eventHandler = eh; 330 } 331 332 /** 333 * Called from native when the Screen definitions change. 334 */ 335 public static void notifySettingsChanged() { 336 // Save the old screens in order to dispose them later 337 List<Screen> oldScreens = screens; 338 339 // Get the new screens 340 initScreens(); 341 342 if (eventHandler != null) { 343 eventHandler.handleSettingsChanged(); 344 } 345 346 // Update the screen for each window to match the new instance. 347 // Note that if a window has moved to another screen, the window 348 // will be notified separately of that from native code and the 349 // new screen will be updated there 350 List<Window> windows = Window.getWindows(); 351 for (Window w : windows) { 352 Screen oldScreen = w.getScreen(); 353 for (Screen newScreen : screens) { 354 if (oldScreen.getNativeScreen() == newScreen.getNativeScreen()) { 355 w.setScreen(newScreen); 356 break; 357 } 358 } 359 } 360 361 // Dispose the old screens 362 if (oldScreens != null) { 363 for (Screen screen : oldScreens) { 364 screen.dispose(); 365 } 366 } 367 } 368 369 static void initScreens() { 370 Application.checkEventThread(); 371 Screen[] newScreens = Application.GetApplication().staticScreen_getScreens(); 372 if (newScreens == null) { 373 throw new RuntimeException("Internal graphics failed to initialize"); 374 } 375 screens = Collections.unmodifiableList(Arrays.asList(newScreens)); 376 } 377 378 @Override public String toString() { 379 return "Screen:"+"\n"+ 380 " ptr:"+getNativeScreen()+"\n"+ 381 " adapter:"+getAdapterOrdinal()+"\n"+ 382 " depth:"+getDepth()+"\n"+ 383 " x:"+getX()+"\n"+ 384 " y:"+getY()+"\n"+ 385 " width:"+getWidth()+"\n"+ 386 " height:"+getHeight()+"\n"+ 387 " platformX:"+getPlatformX()+"\n"+ 388 " platformY:"+getPlatformY()+"\n"+ 389 " platformWidth:"+getPlatformWidth()+"\n"+ 390 " platformHeight:"+getPlatformHeight()+"\n"+ 391 " visibleX:"+getVisibleX()+"\n"+ 392 " visibleY:"+getVisibleY()+"\n"+ 393 " visibleWidth:"+getVisibleWidth()+"\n"+ 394 " visibleHeight:"+getVisibleHeight()+"\n"+ 395 " platformScaleX:"+getPlatformScaleX()+"\n"+ 396 " platformScaleY:"+getPlatformScaleY()+"\n"+ 397 " outputScaleX:"+getRecommendedOutputScaleX()+"\n"+ 398 " outputScaleY:"+getRecommendedOutputScaleY()+"\n"+ 399 " resolutionX:"+getResolutionX()+"\n"+ 400 " resolutionY:"+getResolutionY()+"\n"; 401 } 402 403 @Override public boolean equals(Object o) { 404 if (this == o) return true; 405 if (o == null || getClass() != o.getClass()) return false; 406 407 Screen screen = (Screen) o; 408 return ptr == screen.ptr 409 && adapter == screen.adapter 410 && depth == screen.depth 411 && x == screen.x 412 && y == screen.y 413 && width == screen.width 414 && height == screen.height 415 && visibleX == screen.visibleX 416 && visibleY == screen.visibleY 417 && visibleWidth == screen.visibleWidth 418 && visibleHeight == screen.visibleHeight 419 && resolutionX == screen.resolutionX 420 && resolutionY == screen.resolutionY 421 && Float.compare(screen.platformScaleX, platformScaleX) == 0 422 && Float.compare(screen.platformScaleY, platformScaleY) == 0 423 && Float.compare(screen.outputScaleX, outputScaleX) == 0 424 && Float.compare(screen.outputScaleY, outputScaleY) == 0; 425 } 426 427 @Override public int hashCode() { 428 int result = 17; 429 result = 31 * result + (int) (ptr ^ (ptr >>> 32)); 430 result = 31 * result + adapter; 431 result = 31 * result + depth; 432 result = 31 * result + x; 433 result = 31 * result + y; 434 result = 31 * result + width; 435 result = 31 * result + height; 436 result = 31 * result + visibleX; 437 result = 31 * result + visibleY; 438 result = 31 * result + visibleWidth; 439 result = 31 * result + visibleHeight; 440 result = 31 * result + resolutionX; 441 result = 31 * result + resolutionY; 442 result = 31 * result + (platformScaleX != +0.0f ? Float.floatToIntBits(platformScaleX) : 0); 443 result = 31 * result + (platformScaleY != +0.0f ? Float.floatToIntBits(platformScaleY) : 0); 444 result = 31 * result + (outputScaleX != +0.0f ? Float.floatToIntBits(outputScaleX) : 0); 445 result = 31 * result + (outputScaleY != +0.0f ? Float.floatToIntBits(outputScaleY) : 0); 446 return result; 447 } 448 }