aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/kr
diff options
context:
space:
mode:
authorsyeyoung <cyong06@naver.com>2021-07-28 00:05:09 +0900
committersyeyoung <cyong06@naver.com>2021-07-28 00:05:09 +0900
commit0de8a42a2eade5e527b957263f25e3e906e6df8a (patch)
tree471d0a9205cb1bb6e9655420de52381c8b49e234 /src/main/java/kr
parent132378adb3407b1238c3958070c584fdb3adb6cd (diff)
downloadSkyblock-Dungeons-Guide-0de8a42a2eade5e527b957263f25e3e906e6df8a.tar.gz
Skyblock-Dungeons-Guide-0de8a42a2eade5e527b957263f25e3e906e6df8a.tar.bz2
Skyblock-Dungeons-Guide-0de8a42a2eade5e527b957263f25e3e906e6df8a.zip
Cursors!
Diffstat (limited to 'src/main/java/kr')
-rw-r--r--src/main/java/kr/syeyoung/dungeonsguide/utils/cursor/EnumCursor.java46
-rw-r--r--src/main/java/kr/syeyoung/dungeonsguide/utils/cursor/Foundation.java34
-rw-r--r--src/main/java/kr/syeyoung/dungeonsguide/utils/cursor/GLCursors.java179
-rw-r--r--src/main/java/kr/syeyoung/dungeonsguide/utils/cursor/User32.java67
-rw-r--r--src/main/java/kr/syeyoung/dungeonsguide/utils/cursor/X11.java37
5 files changed, 363 insertions, 0 deletions
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/utils/cursor/EnumCursor.java b/src/main/java/kr/syeyoung/dungeonsguide/utils/cursor/EnumCursor.java
new file mode 100644
index 00000000..caea4d61
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/utils/cursor/EnumCursor.java
@@ -0,0 +1,46 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2021 cyoung06
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package kr.syeyoung.dungeonsguide.utils.cursor;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+
+@AllArgsConstructor
+@Getter
+public enum EnumCursor {
+ DEFAULT(32512,68,"arrowCursor","arrowCursor"),
+ POINTING_HAND(32649,60,"pointingHandCursor", "pointingHandCursor"),
+ OPEN_HAND(32649,60,"openHandCursor","openHandCursor"),
+ CLOSED_HAND(32646,52,"closedHandCursor","closedHandCursor"),
+ BEAM_CURSOR(32513, 152, "IBeamCursor", "IBeamCursor"),
+ RESIZE_LEFT(32644, 70,"resizeLeftCursor", "resizeLeftCursor"),
+ RESIZE_RIGHT(32644, 96,"resizeRightCursor", "resizeRightCursor"),
+ RESIZE_LEFT_RIGHT(32644, 108, "resizeLeftRightCursor", "resizeLeftRightCursor"),
+ RESIZE_UP(32645,138,"resizeUpCursor", "resizeUpCursor"),
+ RESIZE_DOWN(32645,16,"resizeDownCursor", "resizeDownCursor"),
+ RESIZE_UP_DOWN(32645,116,"resizeUpDownCursor", "resizeUpDownCursor"),
+ CROSS(32515, 34,"crosshairCursor", "crosshairCursor");
+
+
+ private int windows;
+ private int linux;
+ private String macos;
+ private String altFileName;
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/utils/cursor/Foundation.java b/src/main/java/kr/syeyoung/dungeonsguide/utils/cursor/Foundation.java
new file mode 100644
index 00000000..995ee101
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/utils/cursor/Foundation.java
@@ -0,0 +1,34 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2021 cyoung06
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package kr.syeyoung.dungeonsguide.utils.cursor;
+
+import com.sun.jna.Library;
+import com.sun.jna.Native;
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+
+public interface Foundation extends Library {
+ Foundation INSTANCE = (Foundation) Native.loadLibrary("Foundation",
+ Foundation.class);
+
+ Pointer objc_getClass(String className);
+ Pointer sel_registerName(String selectorName);
+ void objc_msgSend(Pointer receiver, Pointer selector, Object... args);
+ Structure objc_msgSend_stret(Pointer receiver, Pointer selector, Object... args);
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/utils/cursor/GLCursors.java b/src/main/java/kr/syeyoung/dungeonsguide/utils/cursor/GLCursors.java
new file mode 100644
index 00000000..415e82bf
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/utils/cursor/GLCursors.java
@@ -0,0 +1,179 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2021 cyoung06
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package kr.syeyoung.dungeonsguide.utils.cursor;
+
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+import net.minecraft.client.Minecraft;
+import net.minecraft.util.MathHelper;
+import net.minecraft.util.ResourceLocation;
+import org.apache.commons.io.IOUtils;
+import org.lwjgl.BufferUtils;
+import org.lwjgl.LWJGLException;
+import org.lwjgl.LWJGLUtil;
+import org.lwjgl.input.Cursor;
+import sun.misc.Unsafe;
+
+import javax.imageio.ImageIO;
+import java.awt.image.BufferedImage;
+import java.lang.reflect.Array;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.nio.IntBuffer;
+import java.util.HashMap;
+import java.util.Map;
+
+
+public class GLCursors {
+ private static Unsafe unsafe;
+ private static Class cursorElement;
+ private static Constructor constructor;
+ private static Field cursorField;
+
+ private static Map<EnumCursor, Cursor> enumCursorCursorMap = new HashMap<>();
+
+
+ static {
+ try {
+ Field f = Unsafe.class.getDeclaredField("theUnsafe");
+ f.setAccessible(true);
+ unsafe = (Unsafe) f.get(null);
+ cursorElement = Class.forName("org.lwjgl.input.Cursor$CursorElement");
+ constructor = cursorElement.getDeclaredConstructor(Object.class, long.class, long.class);
+ constructor.setAccessible(true);
+ cursorField = Cursor.class.getDeclaredField("cursors");
+ cursorField.setAccessible(true);
+ } catch (NoSuchFieldException | IllegalAccessException | ClassNotFoundException | NoSuchMethodException e) {
+ e.printStackTrace();
+ }
+ }
+
+
+ static {
+ setupCursors();
+ }
+
+ public static void setupCursors() {
+ if (enumCursorCursorMap.size() != 0) return;
+ int platform = LWJGLUtil.getPlatform();
+ for (EnumCursor value : EnumCursor.values()) {
+ Cursor c = null;
+ try {
+ switch(platform) {
+ case LWJGLUtil.PLATFORM_WINDOWS:
+ if (value.getWindows() == -1) continue;
+ c = createCursorWindows(value.getWindows());
+ break;
+ case LWJGLUtil.PLATFORM_LINUX:
+ if (value.getLinux() == -1) continue;
+ c = createCursorLinux(value.getLinux());
+ break;
+ case LWJGLUtil.PLATFORM_MACOSX:
+ if (value.getMacos() == null) continue;
+ c = createCursorMac(value.getMacos());
+ break;
+ }
+ } catch (Throwable e) {
+ System.out.println("Error occured while loading cursor: "+value);
+ e.printStackTrace();
+ }
+ try {
+ if (c == null) {
+ int hotspotX = 0, hotspotY = 0;
+ try {
+ ResourceLocation cursorinfo = new ResourceLocation("dungeonsguide:cursors/"+value.getAltFileName()+".curinfo");
+ String cursorinfoStr = IOUtils.toString(Minecraft.getMinecraft().getResourceManager().getResource(cursorinfo).getInputStream());
+ hotspotX = Integer.parseInt(cursorinfoStr.split(":")[0]);
+ hotspotY = Integer.parseInt(cursorinfoStr.split(":")[1]);
+ } catch (Throwable t) {t.printStackTrace();}
+
+ ResourceLocation cursor = new ResourceLocation("dungeonsguide:cursors/"+value.getAltFileName()+".png");
+
+ BufferedImage bufferedImage = ImageIO.read(Minecraft.getMinecraft().getResourceManager().getResource(cursor).getInputStream());
+
+
+ int width = bufferedImage.getWidth();
+ int height = bufferedImage.getHeight();
+ int effWidth = MathHelper.clamp_int(width, Cursor.getMinCursorSize(), Cursor.getMaxCursorSize());
+ int effHeight = MathHelper.clamp_int(height, Cursor.getMinCursorSize(), Cursor.getMaxCursorSize());
+ int length = effHeight * effWidth;
+ IntBuffer intBuffer = BufferUtils.createIntBuffer(length);
+ for (int i = 0; i < length; i++) {
+ int x = i % effWidth;
+ int y = i / effWidth;
+ if (x >= width || y >= height) {
+ intBuffer.put(0);
+ } else {
+ intBuffer.put(bufferedImage.getRGB(x, height - y - 1));
+ }
+ }
+ intBuffer.flip();
+ c = new Cursor(effWidth, effHeight, hotspotX, hotspotY,1,intBuffer, null);
+ }
+ } catch (Throwable e) {
+ System.out.println("Error occured while loading cursor from resource: "+value);
+ e.printStackTrace();
+ }
+ if (c != null) enumCursorCursorMap.put(value, c);
+ }
+ }
+
+ public static Cursor getCursor(EnumCursor enumCursor) {
+ return enumCursorCursorMap.get(enumCursor);
+ }
+
+ private static Cursor createCursorWindows(int cursor) throws LWJGLException, InstantiationException, InvocationTargetException, IllegalAccessException {
+ User32 user32 = User32.INSTANCE;
+ Pointer hIcon = user32
+ .LoadCursorW(Pointer.NULL, cursor);
+ long iconPtr = Pointer.nativeValue(hIcon);
+
+ return createCursor(iconPtr);
+ }
+ private static Cursor createCursorLinux(int cursor) throws LWJGLException, InstantiationException, InvocationTargetException, IllegalAccessException {
+ X11.Display display = X11.INSTANCE.XOpenDisplay(null);
+ Pointer fontCursor = X11.INSTANCE.XCreateFontCursor(display, cursor);
+ long iconPtr = Pointer.nativeValue(fontCursor);
+
+ return createCursor(iconPtr);
+ }
+ private static Cursor createCursorMac(String cursor) throws LWJGLException, InstantiationException, InvocationTargetException, IllegalAccessException {
+ // trust me, it's horrible.
+ Foundation foundation = Foundation.INSTANCE;
+ Pointer nsCursor = foundation.objc_getClass("NSCursor");
+ Pointer selector = foundation.sel_registerName(cursor);
+ Structure structure = foundation.objc_msgSend_stret(nsCursor, selector);
+ Pointer thePointer = structure.getPointer();
+ long iconPtr = Pointer.nativeValue(thePointer);
+
+ return createCursor(iconPtr);
+ }
+
+
+ private static Cursor createCursor(Object handle) throws IllegalAccessException, InvocationTargetException, InstantiationException {
+ // Yes. I had no way.
+ Cursor ADANGEROUSOBJECT = (Cursor) unsafe.allocateInstance(Cursor.class);
+ Object cursorElement = constructor.newInstance(handle, 0, LWJGLUtil.getPlatform() == LWJGLUtil.PLATFORM_LINUX ? -1 : System.currentTimeMillis());
+ Object array = Array.newInstance(GLCursors.cursorElement, 1);
+ Array.set(array, 0, cursorElement);
+ cursorField.set(ADANGEROUSOBJECT, array);
+ return ADANGEROUSOBJECT;
+ }
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/utils/cursor/User32.java b/src/main/java/kr/syeyoung/dungeonsguide/utils/cursor/User32.java
new file mode 100644
index 00000000..a5e594ba
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/utils/cursor/User32.java
@@ -0,0 +1,67 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2021 cyoung06
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package kr.syeyoung.dungeonsguide.utils.cursor;
+
+import com.sun.jna.Library;
+import com.sun.jna.Native;
+import com.sun.jna.Pointer;
+
+public interface User32 extends Library {
+
+ public static User32 INSTANCE = (User32) Native
+ .loadLibrary("User32", User32.class);
+
+ /** @see #LoadCursorW(Pointer, int) */
+ public static final int IDC_ARROW = 32512;
+ /** @see #LoadCursorW(Pointer, int) */
+ public static final int IDC_IBEAM = 32513;
+ /** @see #LoadCursorW(Pointer, int) */
+ public static final int IDC_WAIT = 32514;
+ /** @see #LoadCursorW(Pointer, int) */
+ public static final int IDC_CROSS = 32515;
+ /** @see #LoadCursorW(Pointer, int) */
+ public static final int IDC_UPARROW = 32516;
+ /** @see #LoadCursorW(Pointer, int) */
+ public static final int IDC_SIZENWSE = 32642;
+ /** @see #LoadCursorW(Pointer, int) */
+ public static final int IDC_SIZENESW = 32643;
+ /** @see #LoadCursorW(Pointer, int) */
+ public static final int IDC_SIZEWE = 32644;
+ /** @see #LoadCursorW(Pointer, int) */
+ public static final int IDC_SIZENS = 32645;
+ /** @see #LoadCursorW(Pointer, int) */
+ public static final int IDC_SIZEALL = 32646;
+ /** @see #LoadCursorW(Pointer, int) */
+ public static final int IDC_NO = 32648;
+ /** @see #LoadCursorW(Pointer, int) */
+ public static final int IDC_HAND = 32649;
+ /** @see #LoadCursorW(Pointer, int) */
+ public static final int IDC_APPSTARTING = 32650;
+ /** @see #LoadCursorW(Pointer, int) */
+ public static final int IDC_HELP = 32651;
+ /** @see #LoadCursorW(Pointer, int) */
+ public static final int IDC_ICON = 32641;
+ /** @see #LoadCursorW(Pointer, int) */
+ public static final int IDC_SIZE = 32640;
+
+ /** http://msdn.microsoft.com/en-us/library/ms648391(VS.85).aspx */
+ public Pointer LoadCursorW(Pointer hInstance,
+ int lpCursorName);
+
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/utils/cursor/X11.java b/src/main/java/kr/syeyoung/dungeonsguide/utils/cursor/X11.java
new file mode 100644
index 00000000..caf8ae10
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/utils/cursor/X11.java
@@ -0,0 +1,37 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2021 cyoung06
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package kr.syeyoung.dungeonsguide.utils.cursor;
+
+import com.sun.jna.Library;
+import com.sun.jna.Native;
+import com.sun.jna.Pointer;
+import com.sun.jna.PointerType;
+
+public interface X11 extends Library {
+ X11 INSTANCE = (X11) Native.loadLibrary("X11", X11.class);
+ public Pointer XCreateFontCursor(Display display,
+ int shape);
+ public Display XOpenDisplay(String var1);
+
+ public static class Display extends PointerType {
+ public Display() {
+ }
+ }
+
+}