Window.java

com.mojang.blaze3d.platform.Window

信息

  • 全限定名:com.mojang.blaze3d.platform.Window
  • 类型:public final class
  • 包:com.mojang.blaze3d.platform
  • 源码路径:src/main/java/com/mojang/blaze3d/platform/Window.java
  • 起始行号:L39
  • 实现:AutoCloseable
  • 职责:

    TODO

字段/常量

  • LOGGER

    • 类型: Logger
    • 修饰符: private static final
    • 源码定位: L40
    • 说明:

      TODO

  • BASE_WIDTH

    • 类型: int
    • 修饰符: public static final
    • 源码定位: L41
    • 说明:

      TODO

  • BASE_HEIGHT

    • 类型: int
    • 修饰符: public static final
    • 源码定位: L42
    • 说明:

      TODO

  • defaultErrorCallback

    • 类型: GLFWErrorCallback
    • 修饰符: private final
    • 源码定位: L43
    • 说明:

      TODO

  • eventHandler

    • 类型: WindowEventHandler
    • 修饰符: private final
    • 源码定位: L44
    • 说明:

      TODO

  • screenManager

    • 类型: ScreenManager
    • 修饰符: private final
    • 源码定位: L45
    • 说明:

      TODO

  • handle

    • 类型: long
    • 修饰符: private final
    • 源码定位: L46
    • 说明:

      TODO

  • windowedX

    • 类型: int
    • 修饰符: private
    • 源码定位: L47
    • 说明:

      TODO

  • windowedY

    • 类型: int
    • 修饰符: private
    • 源码定位: L48
    • 说明:

      TODO

  • windowedWidth

    • 类型: int
    • 修饰符: private
    • 源码定位: L49
    • 说明:

      TODO

  • windowedHeight

    • 类型: int
    • 修饰符: private
    • 源码定位: L50
    • 说明:

      TODO

  • preferredFullscreenVideoMode

    • 类型: Optional<VideoMode>
    • 修饰符: private
    • 源码定位: L51
    • 说明:

      TODO

  • fullscreen

    • 类型: boolean
    • 修饰符: private
    • 源码定位: L52
    • 说明:

      TODO

  • actuallyFullscreen

    • 类型: boolean
    • 修饰符: private
    • 源码定位: L53
    • 说明:

      TODO

  • x

    • 类型: int
    • 修饰符: private
    • 源码定位: L54
    • 说明:

      TODO

  • y

    • 类型: int
    • 修饰符: private
    • 源码定位: L55
    • 说明:

      TODO

  • width

    • 类型: int
    • 修饰符: private
    • 源码定位: L56
    • 说明:

      TODO

  • height

    • 类型: int
    • 修饰符: private
    • 源码定位: L57
    • 说明:

      TODO

  • framebufferWidth

    • 类型: int
    • 修饰符: private
    • 源码定位: L58
    • 说明:

      TODO

  • framebufferHeight

    • 类型: int
    • 修饰符: private
    • 源码定位: L59
    • 说明:

      TODO

  • guiScaledWidth

    • 类型: int
    • 修饰符: private
    • 源码定位: L60
    • 说明:

      TODO

  • guiScaledHeight

    • 类型: int
    • 修饰符: private
    • 源码定位: L61
    • 说明:

      TODO

  • isResized

    • 类型: boolean
    • 修饰符: private
    • 源码定位: L62
    • 说明:

      TODO

  • guiScale

    • 类型: int
    • 修饰符: private
    • 源码定位: L63
    • 说明:

      TODO

  • errorSection

    • 类型: String
    • 修饰符: private
    • 源码定位: L64
    • 说明:

      TODO

  • dirty

    • 类型: boolean
    • 修饰符: private
    • 源码定位: L65
    • 说明:

      TODO

  • vsync

    • 类型: boolean
    • 修饰符: private
    • 源码定位: L66
    • 说明:

      TODO

  • iconified

    • 类型: boolean
    • 修饰符: private
    • 源码定位: L67
    • 说明:

      TODO

  • focused

    • 类型: boolean
    • 修饰符: private
    • 源码定位: L68
    • 说明:

      TODO

  • minimized

    • 类型: boolean
    • 修饰符: private
    • 源码定位: L69
    • 说明:

      TODO

  • allowCursorChanges

    • 类型: boolean
    • 修饰符: private
    • 源码定位: L70
    • 说明:

      TODO

  • currentCursor

    • 类型: CursorType
    • 修饰符: private
    • 源码定位: L71
    • 说明:

      TODO

  • backend

    • 类型: GpuBackend
    • 修饰符: private final
    • 源码定位: L72
    • 说明:

      TODO

内部类/嵌套类型

  • com.mojang.blaze3d.platform.Window.WindowInitFailed
    • 类型: class
    • 修饰符: public static
    • 源码定位: L553
    • 说明:

      TODO

构造器

public Window(WindowEventHandler eventHandler, DisplayData displayData, String fullscreenVideoModeString, String title, GpuBackend backend) @ L74

  • 构造器名:Window
  • 源码定位:L74
  • 修饰符:public

参数:

  • eventHandler: WindowEventHandler
  • displayData: DisplayData
  • fullscreenVideoModeString: String
  • title: String
  • backend: GpuBackend

说明:

TODO

方法

下面的方法块按源码顺序生成。

public static long createGlfwWindow(int width, int height, String title, long monitor, GpuBackend backend) @ L118

  • 方法名:createGlfwWindow
  • 源码定位:L118
  • 返回类型:long
  • 修饰符:public static

参数:

  • width: int
  • height: int
  • title: String
  • monitor: long
  • backend: GpuBackend

说明:

TODO

private long createWindow(GpuBackend backend, int width, int height, String title, long initialMonitor) @ L137

  • 方法名:createWindow
  • 源码定位:L137
  • 返回类型:long
  • 修饰符:private

参数:

  • backend: GpuBackend
  • width: int
  • height: int
  • title: String
  • initialMonitor: long

说明:

TODO

public static String getPlatform() @ L141

  • 方法名:getPlatform
  • 源码定位:L141
  • 返回类型:String
  • 修饰符:public static

参数:

说明:

TODO

public int getRefreshRate() @ L155

  • 方法名:getRefreshRate
  • 源码定位:L155
  • 返回类型:int
  • 修饰符:public

参数:

说明:

TODO

public boolean shouldClose() @ L160

  • 方法名:shouldClose
  • 源码定位:L160
  • 返回类型:boolean
  • 修饰符:public

参数:

说明:

TODO

public static void checkGlfwError(BiConsumer<Integer,String> errorConsumer) @ L164

  • 方法名:checkGlfwError
  • 源码定位:L164
  • 返回类型:void
  • 修饰符:public static

参数:

  • errorConsumer: BiConsumer<Integer,String>

说明:

TODO

public void setIcon(PackResources resources, IconSet iconSet) @ L176

  • 方法名:setIcon
  • 源码定位:L176
  • 返回类型:void
  • 修饰符:public

参数:

  • resources: PackResources
  • iconSet: IconSet

说明:

TODO

public void setErrorSection(String string) @ L214

  • 方法名:setErrorSection
  • 源码定位:L214
  • 返回类型:void
  • 修饰符:public

参数:

  • string: String

说明:

TODO

private void setBootErrorCallback() @ L218

  • 方法名:setBootErrorCallback
  • 源码定位:L218
  • 返回类型:void
  • 修饰符:private

参数:

说明:

TODO

private static void bootCrash(int error, long description) @ L222

  • 方法名:bootCrash
  • 源码定位:L222
  • 返回类型:void
  • 修饰符:private static

参数:

  • error: int
  • description: long

说明:

TODO

public void defaultErrorCallback(int errorCode, long description) @ L228

  • 方法名:defaultErrorCallback
  • 源码定位:L228
  • 返回类型:void
  • 修饰符:public

参数:

  • errorCode: int
  • description: long

说明:

TODO

public void setDefaultErrorCallback() @ L236

  • 方法名:setDefaultErrorCallback
  • 源码定位:L236
  • 返回类型:void
  • 修饰符:public

参数:

说明:

TODO

public void updateVsync(boolean enableVsync) @ L243

  • 方法名:updateVsync
  • 源码定位:L243
  • 返回类型:void
  • 修饰符:public

参数:

  • enableVsync: boolean

说明:

TODO

public void close() @ L249

  • 方法名:close
  • 源码定位:L249
  • 返回类型:void
  • 修饰符:public

参数:

说明:

TODO

private void onMove(long handle, int x, int y) @ L259

  • 方法名:onMove
  • 源码定位:L259
  • 返回类型:void
  • 修饰符:private

参数:

  • handle: long
  • x: int
  • y: int

说明:

TODO

private void onFramebufferResize(long handle, int newWidth, int newHeight) @ L264

  • 方法名:onFramebufferResize
  • 源码定位:L264
  • 返回类型:void
  • 修饰符:private

参数:

  • handle: long
  • newWidth: int
  • newHeight: int

说明:

TODO

private void refreshFramebufferSize() @ L291

  • 方法名:refreshFramebufferSize
  • 源码定位:L291
  • 返回类型:void
  • 修饰符:private

参数:

说明:

TODO

private void onResize(long handle, int newWidth, int newHeight) @ L299

  • 方法名:onResize
  • 源码定位:L299
  • 返回类型:void
  • 修饰符:private

参数:

  • handle: long
  • newWidth: int
  • newHeight: int

说明:

TODO

private void onFocus(long handle, boolean focused) @ L304

  • 方法名:onFocus
  • 源码定位:L304
  • 返回类型:void
  • 修饰符:private

参数:

  • handle: long
  • focused: boolean

说明:

TODO

private void onEnter(long handle, boolean entered) @ L310

  • 方法名:onEnter
  • 源码定位:L310
  • 返回类型:void
  • 修饰符:private

参数:

  • handle: long
  • entered: boolean

说明:

TODO

private void onIconify(long handle, boolean iconified) @ L316

  • 方法名:onIconify
  • 源码定位:L316
  • 返回类型:void
  • 修饰符:private

参数:

  • handle: long
  • iconified: boolean

说明:

TODO

public void updateFullscreenIfChanged() @ L320

  • 方法名:updateFullscreenIfChanged
  • 源码定位:L320
  • 返回类型:void
  • 修饰符:public

参数:

说明:

TODO

public Optional<VideoMode> getPreferredFullscreenVideoMode() @ L327

  • 方法名:getPreferredFullscreenVideoMode
  • 源码定位:L327
  • 返回类型:Optional
  • 修饰符:public

参数:

说明:

TODO

public void setPreferredFullscreenVideoMode(Optional<VideoMode> preferredFullscreenVideoMode) @ L331

  • 方法名:setPreferredFullscreenVideoMode
  • 源码定位:L331
  • 返回类型:void
  • 修饰符:public

参数:

  • preferredFullscreenVideoMode: Optional

说明:

TODO

public void changeFullscreenVideoMode() @ L339

  • 方法名:changeFullscreenVideoMode
  • 源码定位:L339
  • 返回类型:void
  • 修饰符:public

参数:

说明:

TODO

private void setMode() @ L347

  • 方法名:setMode
  • 源码定位:L347
  • 返回类型:void
  • 修饰符:private

参数:

说明:

TODO

public void toggleFullScreen() @ L387

  • 方法名:toggleFullScreen
  • 源码定位:L387
  • 返回类型:void
  • 修饰符:public

参数:

说明:

TODO

public void setWindowed(int width, int height) @ L391

  • 方法名:setWindowed
  • 源码定位:L391
  • 返回类型:void
  • 修饰符:public

参数:

  • width: int
  • height: int

说明:

TODO

private void updateFullscreen(boolean enableVsync) @ L398

  • 方法名:updateFullscreen
  • 源码定位:L398
  • 返回类型:void
  • 修饰符:private

参数:

  • enableVsync: boolean

说明:

TODO

public int calculateScale(int maxScale, boolean enforceUnicode) @ L408

  • 方法名:calculateScale
  • 源码定位:L408
  • 返回类型:int
  • 修饰符:public

参数:

  • maxScale: int
  • enforceUnicode: boolean

说明:

TODO

public void setGuiScale(int guiScale) @ L428

  • 方法名:setGuiScale
  • 源码定位:L428
  • 返回类型:void
  • 修饰符:public

参数:

  • guiScale: int

说明:

TODO

public void setTitle(String title) @ L437

  • 方法名:setTitle
  • 源码定位:L437
  • 返回类型:void
  • 修饰符:public

参数:

  • title: String

说明:

TODO

public long handle() @ L441

  • 方法名:handle
  • 源码定位:L441
  • 返回类型:long
  • 修饰符:public

参数:

说明:

TODO

public boolean isFullscreen() @ L445

  • 方法名:isFullscreen
  • 源码定位:L445
  • 返回类型:boolean
  • 修饰符:public

参数:

说明:

TODO

public boolean isIconified() @ L449

  • 方法名:isIconified
  • 源码定位:L449
  • 返回类型:boolean
  • 修饰符:public

参数:

说明:

TODO

public boolean isFocused() @ L453

  • 方法名:isFocused
  • 源码定位:L453
  • 返回类型:boolean
  • 修饰符:public

参数:

说明:

TODO

public int getWidth() @ L457

  • 方法名:getWidth
  • 源码定位:L457
  • 返回类型:int
  • 修饰符:public

参数:

说明:

TODO

public int getHeight() @ L461

  • 方法名:getHeight
  • 源码定位:L461
  • 返回类型:int
  • 修饰符:public

参数:

说明:

TODO

public void setWidth(int width) @ L465

  • 方法名:setWidth
  • 源码定位:L465
  • 返回类型:void
  • 修饰符:public

参数:

  • width: int

说明:

TODO

public void setHeight(int height) @ L469

  • 方法名:setHeight
  • 源码定位:L469
  • 返回类型:void
  • 修饰符:public

参数:

  • height: int

说明:

TODO

public int getScreenWidth() @ L473

  • 方法名:getScreenWidth
  • 源码定位:L473
  • 返回类型:int
  • 修饰符:public

参数:

说明:

TODO

public int getScreenHeight() @ L477

  • 方法名:getScreenHeight
  • 源码定位:L477
  • 返回类型:int
  • 修饰符:public

参数:

说明:

TODO

public int getGuiScaledWidth() @ L481

  • 方法名:getGuiScaledWidth
  • 源码定位:L481
  • 返回类型:int
  • 修饰符:public

参数:

说明:

TODO

public int getGuiScaledHeight() @ L485

  • 方法名:getGuiScaledHeight
  • 源码定位:L485
  • 返回类型:int
  • 修饰符:public

参数:

说明:

TODO

public int getX() @ L489

  • 方法名:getX
  • 源码定位:L489
  • 返回类型:int
  • 修饰符:public

参数:

说明:

TODO

public int getY() @ L493

  • 方法名:getY
  • 源码定位:L493
  • 返回类型:int
  • 修饰符:public

参数:

说明:

TODO

public int getGuiScale() @ L497

  • 方法名:getGuiScale
  • 源码定位:L497
  • 返回类型:int
  • 修饰符:public

参数:

说明:

TODO

public Monitor findBestMonitor() @ L501

  • 方法名:findBestMonitor
  • 源码定位:L501
  • 返回类型:Monitor
  • 修饰符:public

参数:

说明:

TODO

public void updateRawMouseInput(boolean value) @ L505

  • 方法名:updateRawMouseInput
  • 源码定位:L505
  • 返回类型:void
  • 修饰符:public

参数:

  • value: boolean

说明:

TODO

public void setWindowCloseCallback(Runnable task) @ L509

  • 方法名:setWindowCloseCallback
  • 源码定位:L509
  • 返回类型:void
  • 修饰符:public

参数:

  • task: Runnable

说明:

TODO

public boolean isResized() @ L516

  • 方法名:isResized
  • 源码定位:L516
  • 返回类型:boolean
  • 修饰符:public

参数:

说明:

TODO

public void resetIsResized() @ L520

  • 方法名:resetIsResized
  • 源码定位:L520
  • 返回类型:void
  • 修饰符:public

参数:

说明:

TODO

public boolean isMinimized() @ L524

  • 方法名:isMinimized
  • 源码定位:L524
  • 返回类型:boolean
  • 修饰符:public

参数:

说明:

TODO

public void setAllowCursorChanges(boolean value) @ L528

  • 方法名:setAllowCursorChanges
  • 源码定位:L528
  • 返回类型:void
  • 修饰符:public

参数:

  • value: boolean

说明:

TODO

public void selectCursor(CursorType cursor) @ L532

  • 方法名:selectCursor
  • 源码定位:L532
  • 返回类型:void
  • 修饰符:public

参数:

  • cursor: CursorType

说明:

TODO

public float getAppropriateLineWidth() @ L540

  • 方法名:getAppropriateLineWidth
  • 源码定位:L540
  • 返回类型:float
  • 修饰符:public

参数:

说明:

TODO

public GpuBackend backend() @ L544

  • 方法名:backend
  • 源码定位:L544
  • 返回类型:GpuBackend
  • 修饰符:public

参数:

说明:

TODO

private static int allowedWindowMinSize(int size) @ L548

  • 方法名:allowedWindowMinSize
  • 源码定位:L548
  • 返回类型:int
  • 修饰符:private static

参数:

  • size: int

说明:

TODO

代码

@OnlyIn(Dist.CLIENT)
public final class Window implements AutoCloseable {
    private static final Logger LOGGER = LogUtils.getLogger();
    public static final int BASE_WIDTH = 320;
    public static final int BASE_HEIGHT = 240;
    private final GLFWErrorCallback defaultErrorCallback = GLFWErrorCallback.create(this::defaultErrorCallback);
    private final WindowEventHandler eventHandler;
    private final ScreenManager screenManager;
    private final long handle;
    private int windowedX;
    private int windowedY;
    private int windowedWidth;
    private int windowedHeight;
    private Optional<VideoMode> preferredFullscreenVideoMode;
    private boolean fullscreen;
    private boolean actuallyFullscreen;
    private int x;
    private int y;
    private int width;
    private int height;
    private int framebufferWidth;
    private int framebufferHeight;
    private int guiScaledWidth;
    private int guiScaledHeight;
    private boolean isResized;
    private int guiScale;
    private String errorSection = "";
    private boolean dirty;
    private boolean vsync;
    private boolean iconified;
    private boolean focused = true;
    private boolean minimized;
    private boolean allowCursorChanges;
    private CursorType currentCursor = CursorType.DEFAULT;
    private final GpuBackend backend;
 
    public Window(WindowEventHandler eventHandler, DisplayData displayData, @Nullable String fullscreenVideoModeString, String title, GpuBackend backend) throws BackendCreationException {
        this.screenManager = new ScreenManager(Monitor::new);
        this.setBootErrorCallback();
        this.setErrorSection("Pre startup");
        this.eventHandler = eventHandler;
        Optional<VideoMode> optionsMode = VideoMode.read(fullscreenVideoModeString);
        if (optionsMode.isPresent()) {
            this.preferredFullscreenVideoMode = optionsMode;
        } else if (displayData.fullscreenWidth().isPresent() && displayData.fullscreenHeight().isPresent()) {
            this.preferredFullscreenVideoMode = Optional.of(
                new VideoMode(displayData.fullscreenWidth().getAsInt(), displayData.fullscreenHeight().getAsInt(), 8, 8, 8, 60)
            );
        } else {
            this.preferredFullscreenVideoMode = Optional.empty();
        }
 
        this.actuallyFullscreen = this.fullscreen = displayData.isFullscreen();
        Monitor initialMonitor = this.screenManager.getMonitor(GLFW.glfwGetPrimaryMonitor());
        this.windowedWidth = this.width = allowedWindowMinSize(displayData.width());
        this.windowedHeight = this.height = allowedWindowMinSize(displayData.height());
        this.handle = this.createWindow(backend, this.width, this.height, title, this.fullscreen && initialMonitor != null ? initialMonitor.getMonitor() : 0L);
        this.backend = backend;
        if (initialMonitor != null) {
            VideoMode mode = initialMonitor.getPreferredVidMode(this.fullscreen ? this.preferredFullscreenVideoMode : Optional.empty());
            this.windowedX = this.x = initialMonitor.getX() + mode.getWidth() / 2 - this.width / 2;
            this.windowedY = this.y = initialMonitor.getY() + mode.getHeight() / 2 - this.height / 2;
        } else {
            int[] actualX = new int[1];
            int[] actualY = new int[1];
            GLFW.glfwGetWindowPos(this.handle, actualX, actualY);
            this.windowedX = this.x = actualX[0];
            this.windowedY = this.y = actualY[0];
        }
 
        this.setMode();
        this.refreshFramebufferSize();
        GLFW.glfwSetFramebufferSizeCallback(this.handle, this::onFramebufferResize);
        GLFW.glfwSetWindowPosCallback(this.handle, this::onMove);
        GLFW.glfwSetWindowSizeCallback(this.handle, this::onResize);
        GLFW.glfwSetWindowFocusCallback(this.handle, this::onFocus);
        GLFW.glfwSetCursorEnterCallback(this.handle, this::onEnter);
        GLFW.glfwSetWindowIconifyCallback(this.handle, this::onIconify);
    }
 
    public static long createGlfwWindow(int width, int height, String title, long monitor, GpuBackend backend) throws BackendCreationException {
        GLFWErrorCapture glfwErrors = new GLFWErrorCapture();
 
        long windowHandle;
        try (GLFWErrorScope var9 = new GLFWErrorScope(glfwErrors)) {
            backend.setWindowHints();
            windowHandle = GLFW.glfwCreateWindow(width, height, title, monitor, 0L);
            if (windowHandle == 0L) {
                backend.handleWindowCreationErrors(glfwErrors.firstError());
            }
        }
 
        for (GLFWErrorCapture.Error error : glfwErrors) {
            LOGGER.error("GLFW error collected during GL backend initialization: {}", error);
        }
 
        return windowHandle;
    }
 
    private long createWindow(GpuBackend backend, int width, int height, String title, long initialMonitor) throws BackendCreationException {
        return createGlfwWindow(width, height, title, initialMonitor, backend);
    }
 
    public static String getPlatform() {
        int platform = GLFW.glfwGetPlatform();
 
        return switch (platform) {
            case 0 -> "<error>";
            case 393217 -> "win32";
            case 393218 -> "cocoa";
            case 393219 -> "wayland";
            case 393220 -> "x11";
            case 393221 -> "null";
            default -> String.format(Locale.ROOT, "unknown (%08X)", platform);
        };
    }
 
    public int getRefreshRate() {
        RenderSystem.assertOnRenderThread();
        return GLX._getRefreshRate(this);
    }
 
    public boolean shouldClose() {
        return GLX._shouldClose(this);
    }
 
    public static void checkGlfwError(BiConsumer<Integer, String> errorConsumer) {
        try (MemoryStack stack = MemoryStack.stackPush()) {
            PointerBuffer errorDescription = stack.mallocPointer(1);
            int errorCode = GLFW.glfwGetError(errorDescription);
            if (errorCode != 0) {
                long errorDescriptionAddress = errorDescription.get();
                String errorMessage = errorDescriptionAddress == 0L ? "" : MemoryUtil.memUTF8(errorDescriptionAddress);
                errorConsumer.accept(errorCode, errorMessage);
            }
        }
    }
 
    public void setIcon(PackResources resources, IconSet iconSet) throws IOException {
        int platform = GLFW.glfwGetPlatform();
        switch (platform) {
            case 393217:
            case 393220:
                List<IoSupplier<InputStream>> iconStreams = iconSet.getStandardIcons(resources);
                List<ByteBuffer> allocatedBuffers = new ArrayList<>(iconStreams.size());
 
                try (MemoryStack stack = MemoryStack.stackPush()) {
                    Buffer icons = GLFWImage.malloc(iconStreams.size(), stack);
 
                    for (int i = 0; i < iconStreams.size(); i++) {
                        try (NativeImage image = NativeImage.read(iconStreams.get(i).get())) {
                            ByteBuffer pixels = MemoryUtil.memAlloc(image.getWidth() * image.getHeight() * 4);
                            allocatedBuffers.add(pixels);
                            pixels.asIntBuffer().put(image.getPixelsABGR());
                            icons.position(i);
                            icons.width(image.getWidth());
                            icons.height(image.getHeight());
                            icons.pixels(pixels);
                        }
                    }
 
                    GLFW.glfwSetWindowIcon(this.handle, icons.position(0));
                    break;
                } finally {
                    allocatedBuffers.forEach(MemoryUtil::memFree);
                }
            case 393218:
                MacosUtil.loadIcon(iconSet.getMacIcon(resources));
            case 393219:
            case 393221:
                break;
            default:
                LOGGER.warn("Not setting icon for unrecognized platform: {}", platform);
        }
    }
 
    public void setErrorSection(String string) {
        this.errorSection = string;
    }
 
    private void setBootErrorCallback() {
        GLFW.glfwSetErrorCallback(Window::bootCrash);
    }
 
    private static void bootCrash(int error, long description) {
        String message = "GLFW error " + error + ": " + MemoryUtil.memUTF8(description);
        MessageBox.error(message + ".\n\nPlease make sure you have up-to-date drivers (see aka.ms/mcdriver for instructions).");
        throw new Window.WindowInitFailed(message);
    }
 
    public void defaultErrorCallback(int errorCode, long description) {
        RenderSystem.assertOnRenderThread();
        String errorString = MemoryUtil.memUTF8(description);
        LOGGER.error("########## GL ERROR ##########");
        LOGGER.error("@ {}", this.errorSection);
        LOGGER.error("{}: {}", errorCode, errorString);
    }
 
    public void setDefaultErrorCallback() {
        GLFWErrorCallback previousCallback = GLFW.glfwSetErrorCallback(this.defaultErrorCallback);
        if (previousCallback != null) {
            previousCallback.free();
        }
    }
 
    public void updateVsync(boolean enableVsync) {
        RenderSystem.assertOnRenderThread();
        this.vsync = enableVsync;
        RenderSystem.getDevice().setVsync(enableVsync);
    }
 
    @Override
    public void close() {
        RenderSystem.assertOnRenderThread();
        this.screenManager.shutdown();
        Callbacks.glfwFreeCallbacks(this.handle);
        this.defaultErrorCallback.close();
        GLFW.glfwDestroyWindow(this.handle);
        GLFW.glfwTerminate();
    }
 
    private void onMove(long handle, int x, int y) {
        this.x = x;
        this.y = y;
    }
 
    private void onFramebufferResize(long handle, int newWidth, int newHeight) {
        if (handle == this.handle) {
            int oldWidth = this.getWidth();
            int oldHeight = this.getHeight();
            if (newWidth != 0 && newHeight != 0) {
                this.minimized = false;
                if (newWidth != oldWidth || newHeight != oldHeight) {
                    this.framebufferWidth = newWidth;
                    this.framebufferHeight = newHeight;
                    this.isResized = true;
 
                    try {
                        this.eventHandler.resizeGui();
                    } catch (Exception var10) {
                        CrashReport report = CrashReport.forThrowable(var10, "Window resize");
                        CrashReportCategory windowSizeDetails = report.addCategory("Window Dimensions");
                        windowSizeDetails.setDetail("Old", oldWidth + "x" + oldHeight);
                        windowSizeDetails.setDetail("New", newWidth + "x" + newHeight);
                        throw new ReportedException(report);
                    }
                }
            } else {
                this.minimized = true;
            }
        }
    }
 
    private void refreshFramebufferSize() {
        int[] outWidth = new int[1];
        int[] outHeight = new int[1];
        GLFW.glfwGetFramebufferSize(this.handle, outWidth, outHeight);
        this.framebufferWidth = outWidth[0] > 0 ? outWidth[0] : 1;
        this.framebufferHeight = outHeight[0] > 0 ? outHeight[0] : 1;
    }
 
    private void onResize(long handle, int newWidth, int newHeight) {
        this.width = newWidth;
        this.height = newHeight;
    }
 
    private void onFocus(long handle, boolean focused) {
        if (handle == this.handle) {
            this.focused = focused;
        }
    }
 
    private void onEnter(long handle, boolean entered) {
        if (entered) {
            this.eventHandler.cursorEntered();
        }
    }
 
    private void onIconify(long handle, boolean iconified) {
        this.iconified = iconified;
    }
 
    public void updateFullscreenIfChanged() {
        if (this.fullscreen != this.actuallyFullscreen) {
            this.actuallyFullscreen = this.fullscreen;
            this.updateFullscreen(this.vsync);
        }
    }
 
    public Optional<VideoMode> getPreferredFullscreenVideoMode() {
        return this.preferredFullscreenVideoMode;
    }
 
    public void setPreferredFullscreenVideoMode(Optional<VideoMode> preferredFullscreenVideoMode) {
        boolean changed = !preferredFullscreenVideoMode.equals(this.preferredFullscreenVideoMode);
        this.preferredFullscreenVideoMode = preferredFullscreenVideoMode;
        if (changed) {
            this.dirty = true;
        }
    }
 
    public void changeFullscreenVideoMode() {
        if (this.fullscreen && this.dirty) {
            this.dirty = false;
            this.setMode();
            this.eventHandler.resizeGui();
        }
    }
 
    private void setMode() {
        boolean wasFullscreen = GLFW.glfwGetWindowMonitor(this.handle) != 0L;
        if (this.fullscreen) {
            Monitor monitor = this.screenManager.findBestMonitor(this);
            if (monitor == null) {
                LOGGER.warn("Failed to find suitable monitor for fullscreen mode");
                this.fullscreen = false;
            } else {
                if (MacosUtil.IS_MACOS) {
                    MacosUtil.exitNativeFullscreen(this);
                }
 
                VideoMode mode = monitor.getPreferredVidMode(this.preferredFullscreenVideoMode);
                if (!wasFullscreen) {
                    this.windowedX = this.x;
                    this.windowedY = this.y;
                    this.windowedWidth = allowedWindowMinSize(this.width);
                    this.windowedHeight = allowedWindowMinSize(this.height);
                }
 
                this.x = 0;
                this.y = 0;
                this.width = allowedWindowMinSize(mode.getWidth());
                this.height = allowedWindowMinSize(mode.getHeight());
                this.isResized = true;
                GLFW.glfwSetWindowMonitor(this.handle, monitor.getMonitor(), this.x, this.y, this.width, this.height, mode.getRefreshRate());
                if (MacosUtil.IS_MACOS) {
                    MacosUtil.clearResizableBit(this);
                }
            }
        } else {
            this.x = this.windowedX;
            this.y = this.windowedY;
            this.width = allowedWindowMinSize(this.windowedWidth);
            this.height = allowedWindowMinSize(this.windowedHeight);
            this.isResized = true;
            GLFW.glfwSetWindowMonitor(this.handle, 0L, this.x, this.y, this.width, this.height, -1);
        }
    }
 
    public void toggleFullScreen() {
        this.fullscreen = !this.fullscreen;
    }
 
    public void setWindowed(int width, int height) {
        this.windowedWidth = allowedWindowMinSize(width);
        this.windowedHeight = allowedWindowMinSize(height);
        this.fullscreen = false;
        this.setMode();
    }
 
    private void updateFullscreen(boolean enableVsync) {
        try {
            this.setMode();
            this.eventHandler.resizeGui();
            this.updateVsync(enableVsync);
        } catch (Exception var3) {
            LOGGER.error("Couldn't toggle fullscreen", (Throwable)var3);
        }
    }
 
    public int calculateScale(int maxScale, boolean enforceUnicode) {
        int scale = 1;
 
        while (
            scale != maxScale
                && scale < this.framebufferWidth
                && scale < this.framebufferHeight
                && this.framebufferWidth / (scale + 1) >= 320
                && this.framebufferHeight / (scale + 1) >= 240
        ) {
            scale++;
        }
 
        if (enforceUnicode && scale % 2 != 0) {
            scale++;
        }
 
        return scale;
    }
 
    public void setGuiScale(int guiScale) {
        this.guiScale = guiScale;
        double doubleGuiScale = guiScale;
        int width = (int)(this.framebufferWidth / doubleGuiScale);
        this.guiScaledWidth = this.framebufferWidth / doubleGuiScale > width ? width + 1 : width;
        int height = (int)(this.framebufferHeight / doubleGuiScale);
        this.guiScaledHeight = this.framebufferHeight / doubleGuiScale > height ? height + 1 : height;
    }
 
    public void setTitle(String title) {
        GLFW.glfwSetWindowTitle(this.handle, title);
    }
 
    public long handle() {
        return this.handle;
    }
 
    public boolean isFullscreen() {
        return this.fullscreen;
    }
 
    public boolean isIconified() {
        return this.iconified;
    }
 
    public boolean isFocused() {
        return this.focused;
    }
 
    public int getWidth() {
        return this.framebufferWidth;
    }
 
    public int getHeight() {
        return this.framebufferHeight;
    }
 
    public void setWidth(int width) {
        this.framebufferWidth = width;
    }
 
    public void setHeight(int height) {
        this.framebufferHeight = height;
    }
 
    public int getScreenWidth() {
        return this.width;
    }
 
    public int getScreenHeight() {
        return this.height;
    }
 
    public int getGuiScaledWidth() {
        return this.guiScaledWidth;
    }
 
    public int getGuiScaledHeight() {
        return this.guiScaledHeight;
    }
 
    public int getX() {
        return this.x;
    }
 
    public int getY() {
        return this.y;
    }
 
    public int getGuiScale() {
        return this.guiScale;
    }
 
    public @Nullable Monitor findBestMonitor() {
        return this.screenManager.findBestMonitor(this);
    }
 
    public void updateRawMouseInput(boolean value) {
        InputConstants.updateRawMouseInput(this, value);
    }
 
    public void setWindowCloseCallback(Runnable task) {
        GLFWWindowCloseCallback prev = GLFW.glfwSetWindowCloseCallback(this.handle, id -> task.run());
        if (prev != null) {
            prev.free();
        }
    }
 
    public boolean isResized() {
        return this.isResized;
    }
 
    public void resetIsResized() {
        this.isResized = false;
    }
 
    public boolean isMinimized() {
        return this.minimized;
    }
 
    public void setAllowCursorChanges(boolean value) {
        this.allowCursorChanges = value;
    }
 
    public void selectCursor(CursorType cursor) {
        CursorType effectiveCursor = this.allowCursorChanges ? cursor : CursorType.DEFAULT;
        if (this.currentCursor != effectiveCursor) {
            this.currentCursor = effectiveCursor;
            effectiveCursor.select(this);
        }
    }
 
    public float getAppropriateLineWidth() {
        return Math.max(2.5F, this.getWidth() / 1920.0F * 2.5F);
    }
 
    public GpuBackend backend() {
        return this.backend;
    }
 
    private static int allowedWindowMinSize(int size) {
        return Math.max(size, 1);
    }
 
    @OnlyIn(Dist.CLIENT)
    public static class WindowInitFailed extends SilentInitException {
        public WindowInitFailed(String message) {
            super(message);
        }
    }
}

引用的其他类

  • GLFWErrorCapture

    • 引用位置: 构造调用
    • 关联成员: GLFWErrorCapture()
  • GLFWErrorScope

    • 引用位置: 构造调用
    • 关联成员: GLFWErrorScope()
  • DisplayData

    • 引用位置: 参数
  • GLX

    • 引用位置: 方法调用
    • 关联成员: GLX._getRefreshRate(), GLX._shouldClose()
  • IconSet

    • 引用位置: 参数
  • InputConstants

    • 引用位置: 方法调用
    • 关联成员: InputConstants.updateRawMouseInput()
  • MacosUtil

    • 引用位置: 方法调用
    • 关联成员: MacosUtil.clearResizableBit(), MacosUtil.exitNativeFullscreen(), MacosUtil.loadIcon()
  • MessageBox

    • 引用位置: 方法调用
    • 关联成员: MessageBox.error()
  • Monitor

    • 引用位置: 返回值
  • NativeImage

    • 引用位置: 方法调用
    • 关联成员: NativeImage.read()
  • ScreenManager

    • 引用位置: 字段/构造调用
    • 关联成员: ScreenManager()
  • VideoMode

    • 引用位置: 参数/字段/方法调用/构造调用/返回值
    • 关联成员: VideoMode(), VideoMode.read()
  • WindowEventHandler

    • 引用位置: 参数/字段
  • CursorType

    • 引用位置: 参数/字段
  • GpuBackend

    • 引用位置: 参数/字段/返回值
  • RenderSystem

    • 引用位置: 方法调用
    • 关联成员: RenderSystem.assertOnRenderThread(), RenderSystem.getDevice()
  • CrashReport

    • 引用位置: 方法调用
    • 关联成员: CrashReport.forThrowable()
  • ReportedException

    • 引用位置: 构造调用
    • 关联成员: ReportedException()
  • PackResources

    • 引用位置: 参数