105 lines
		
	
	
	
		
			3.2 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
			
		
		
	
	
			105 lines
		
	
	
	
		
			3.2 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
| package com.mojang.blaze3d.platform;
 | |
| 
 | |
| import com.mojang.blaze3d.systems.RenderSystem;
 | |
| import com.mojang.logging.LogUtils;
 | |
| import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
 | |
| import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
 | |
| import net.fabricmc.api.EnvType;
 | |
| import net.fabricmc.api.Environment;
 | |
| import org.jetbrains.annotations.Nullable;
 | |
| import org.lwjgl.PointerBuffer;
 | |
| import org.lwjgl.glfw.GLFW;
 | |
| import org.lwjgl.glfw.GLFWMonitorCallback;
 | |
| import org.slf4j.Logger;
 | |
| 
 | |
| @Environment(EnvType.CLIENT)
 | |
| public class ScreenManager {
 | |
| 	private static final Logger LOGGER = LogUtils.getLogger();
 | |
| 	private final Long2ObjectMap<Monitor> monitors = new Long2ObjectOpenHashMap<>();
 | |
| 	private final MonitorCreator monitorCreator;
 | |
| 
 | |
| 	public ScreenManager(MonitorCreator monitorCreator) {
 | |
| 		this.monitorCreator = monitorCreator;
 | |
| 		GLFW.glfwSetMonitorCallback(this::onMonitorChange);
 | |
| 		PointerBuffer pointerBuffer = GLFW.glfwGetMonitors();
 | |
| 		if (pointerBuffer != null) {
 | |
| 			for (int i = 0; i < pointerBuffer.limit(); i++) {
 | |
| 				long l = pointerBuffer.get(i);
 | |
| 				this.monitors.put(l, monitorCreator.createMonitor(l));
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	private void onMonitorChange(long monitorID, int opCode) {
 | |
| 		RenderSystem.assertOnRenderThread();
 | |
| 		if (opCode == 262145) {
 | |
| 			this.monitors.put(monitorID, this.monitorCreator.createMonitor(monitorID));
 | |
| 			LOGGER.debug("Monitor {} connected. Current monitors: {}", monitorID, this.monitors);
 | |
| 		} else if (opCode == 262146) {
 | |
| 			this.monitors.remove(monitorID);
 | |
| 			LOGGER.debug("Monitor {} disconnected. Current monitors: {}", monitorID, this.monitors);
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	@Nullable
 | |
| 	public Monitor getMonitor(long monitorID) {
 | |
| 		return this.monitors.get(monitorID);
 | |
| 	}
 | |
| 
 | |
| 	@Nullable
 | |
| 	public Monitor findBestMonitor(Window window) {
 | |
| 		long l = GLFW.glfwGetWindowMonitor(window.getWindow());
 | |
| 		if (l != 0L) {
 | |
| 			return this.getMonitor(l);
 | |
| 		} else {
 | |
| 			int i = window.getX();
 | |
| 			int j = i + window.getScreenWidth();
 | |
| 			int k = window.getY();
 | |
| 			int m = k + window.getScreenHeight();
 | |
| 			int n = -1;
 | |
| 			Monitor monitor = null;
 | |
| 			long o = GLFW.glfwGetPrimaryMonitor();
 | |
| 			LOGGER.debug("Selecting monitor - primary: {}, current monitors: {}", o, this.monitors);
 | |
| 
 | |
| 			for (Monitor monitor2 : this.monitors.values()) {
 | |
| 				int p = monitor2.getX();
 | |
| 				int q = p + monitor2.getCurrentMode().getWidth();
 | |
| 				int r = monitor2.getY();
 | |
| 				int s = r + monitor2.getCurrentMode().getHeight();
 | |
| 				int t = clamp(i, p, q);
 | |
| 				int u = clamp(j, p, q);
 | |
| 				int v = clamp(k, r, s);
 | |
| 				int w = clamp(m, r, s);
 | |
| 				int x = Math.max(0, u - t);
 | |
| 				int y = Math.max(0, w - v);
 | |
| 				int z = x * y;
 | |
| 				if (z > n) {
 | |
| 					monitor = monitor2;
 | |
| 					n = z;
 | |
| 				} else if (z == n && o == monitor2.getMonitor()) {
 | |
| 					LOGGER.debug("Primary monitor {} is preferred to monitor {}", monitor2, monitor);
 | |
| 					monitor = monitor2;
 | |
| 				}
 | |
| 			}
 | |
| 
 | |
| 			LOGGER.debug("Selected monitor: {}", monitor);
 | |
| 			return monitor;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	public static int clamp(int value, int min, int max) {
 | |
| 		if (value < min) {
 | |
| 			return min;
 | |
| 		} else {
 | |
| 			return value > max ? max : value;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	public void shutdown() {
 | |
| 		RenderSystem.assertOnRenderThread();
 | |
| 		GLFWMonitorCallback gLFWMonitorCallback = GLFW.glfwSetMonitorCallback(null);
 | |
| 		if (gLFWMonitorCallback != null) {
 | |
| 			gLFWMonitorCallback.free();
 | |
| 		}
 | |
| 	}
 | |
| }
 |