mirror of
https://github.com/refactorinqq/SLC-1.8.9.git
synced 2024-11-10 08:51:32 +01:00
Better Cursors
This commit is contained in:
parent
c18c49d54a
commit
5713b06f6f
@ -1,5 +1,6 @@
|
|||||||
package net.silentclient.client.utils;
|
package net.silentclient.client.utils;
|
||||||
|
|
||||||
|
import net.silentclient.client.utils.cursors.SystemCursors;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.lwjgl.BufferUtils;
|
import org.lwjgl.BufferUtils;
|
||||||
import org.lwjgl.LWJGLException;
|
import org.lwjgl.LWJGLException;
|
||||||
@ -69,6 +70,10 @@ public class MouseCursorHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean enableCursor(final CursorType cursorType) {
|
public boolean enableCursor(final CursorType cursorType) {
|
||||||
|
if(SystemCursors.isSupported()) {
|
||||||
|
SystemCursors.setCursor(cursorType.getCursor());
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
if (this.customCursorDisabled) {
|
if (this.customCursorDisabled) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -92,8 +97,12 @@ public class MouseCursorHandler {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void disableCursor() {
|
public void disableCursor() {
|
||||||
|
if(SystemCursors.isSupported()) {
|
||||||
|
SystemCursors.setCursor(SystemCursors.ARROW);
|
||||||
|
} else {
|
||||||
if (this.customCursorDisabled) {
|
if (this.customCursorDisabled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -107,18 +116,29 @@ public class MouseCursorHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public CursorType getCurrentCursor() {
|
public CursorType getCurrentCursor() {
|
||||||
return currentCursor;
|
return CursorType.NORMAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum CursorType
|
public enum CursorType
|
||||||
{
|
{
|
||||||
NORMAL,
|
NORMAL(SystemCursors.ARROW),
|
||||||
NESW_RESIZE,
|
NESW_RESIZE(SystemCursors.RESIZE_NESW),
|
||||||
NWSE_RESIZE,
|
NWSE_RESIZE(SystemCursors.RESIZE_NWSE),
|
||||||
MOVE,
|
MOVE(SystemCursors.CROSSHAIR),
|
||||||
EDIT_TEXT,
|
EDIT_TEXT(SystemCursors.IBEAM),
|
||||||
POINTER;
|
POINTER(SystemCursors.POINTING_HAND);
|
||||||
|
|
||||||
|
private final byte cursor;
|
||||||
|
|
||||||
|
CursorType(byte cursor) {
|
||||||
|
this.cursor = cursor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte getCursor() {
|
||||||
|
return cursor;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,56 @@
|
|||||||
|
package net.silentclient.client.utils.cursors;
|
||||||
|
|
||||||
|
import org.apache.logging.log4j.*;
|
||||||
|
import org.lwjgl.LWJGLUtil;
|
||||||
|
import org.lwjgl.input.Mouse;
|
||||||
|
|
||||||
|
public class SystemCursors {
|
||||||
|
public static final byte ARROW = 0;
|
||||||
|
public static final byte IBEAM = 1;
|
||||||
|
public static final byte CROSSHAIR = 2;
|
||||||
|
public static final byte POINTING_HAND = 3;
|
||||||
|
public static final byte RESIZE_EW = 4;
|
||||||
|
public static final byte RESIZE_NS = 5;
|
||||||
|
public static final byte RESIZE_NWSE = 6;
|
||||||
|
public static final byte RESIZE_NESW = 7;
|
||||||
|
public static final byte ALL_CURSOR = 8;
|
||||||
|
public static final byte NOT_ALLOWED = 9;
|
||||||
|
public static final byte SIZE = size();
|
||||||
|
private static final Logger LOGGER = LogManager.getLogger();
|
||||||
|
private static boolean supported = true;
|
||||||
|
|
||||||
|
static void markUnsupported() {
|
||||||
|
supported = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setCursor(byte cursor) {
|
||||||
|
if (!supported)
|
||||||
|
return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (cursor == ARROW) {
|
||||||
|
Mouse.setNativeCursor(null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cursor < 0 || cursor >= SIZE)
|
||||||
|
throw new IllegalArgumentException(Byte.toString(cursor));
|
||||||
|
|
||||||
|
if (LWJGLUtil.getPlatform() == LWJGLUtil.PLATFORM_LINUX || LWJGLUtil.getPlatform() == LWJGLUtil.PLATFORM_MACOSX)
|
||||||
|
X11SystemCursors.setCursor(cursor);
|
||||||
|
else if (LWJGLUtil.getPlatform() == LWJGLUtil.PLATFORM_WINDOWS)
|
||||||
|
Win32SystemCursors.setCursor(cursor);
|
||||||
|
} catch (Throwable error) {
|
||||||
|
LOGGER.error("Error occured; not trying again", error);
|
||||||
|
markUnsupported();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isSupported() {
|
||||||
|
return supported;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static byte size() {
|
||||||
|
return NOT_ALLOWED + 1;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,77 @@
|
|||||||
|
package net.silentclient.client.utils.cursors;
|
||||||
|
|
||||||
|
import org.apache.commons.io.FileUtils;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.lwjgl.input.Mouse;
|
||||||
|
import org.lwjgl.opengl.Display;
|
||||||
|
import org.lwjgl.opengl.InputImplementation;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.UncheckedIOException;
|
||||||
|
import java.lang.invoke.MethodHandle;
|
||||||
|
import java.lang.invoke.MethodHandles;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
|
public class Util {
|
||||||
|
private static final Logger LOGGER = LogManager.getLogger();
|
||||||
|
private static MethodHandle getInputImplementationMethod;
|
||||||
|
private static MethodHandle getDisplayImplementationMethod;
|
||||||
|
|
||||||
|
static {
|
||||||
|
try {
|
||||||
|
Method getInputImplementation = Mouse.class.getDeclaredMethod("getImplementation");
|
||||||
|
getInputImplementation.setAccessible(true);
|
||||||
|
getInputImplementationMethod = MethodHandles.lookup().unreflect(getInputImplementation);
|
||||||
|
|
||||||
|
Method getDisplayImplementation = Display.class.getDeclaredMethod("getImplementation");
|
||||||
|
getDisplayImplementation.setAccessible(true);
|
||||||
|
getDisplayImplementationMethod = MethodHandles.lookup().unreflect(getDisplayImplementation);
|
||||||
|
} catch (Throwable error) {
|
||||||
|
LOGGER.error("Could not perform reflection", error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static RuntimeException sneakyThrow(Throwable error) {
|
||||||
|
if (error instanceof Error)
|
||||||
|
throw (Error) error;
|
||||||
|
if (error instanceof RuntimeException)
|
||||||
|
throw (RuntimeException) error;
|
||||||
|
if (error instanceof IOException)
|
||||||
|
throw new UncheckedIOException((IOException) error);
|
||||||
|
|
||||||
|
throw new IllegalStateException(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean foundInputImplementationMethod() {
|
||||||
|
return getInputImplementationMethod != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static InputImplementation getInputImplementation() {
|
||||||
|
try {
|
||||||
|
return (InputImplementation) getInputImplementationMethod.invokeExact();
|
||||||
|
} catch (Throwable error) {
|
||||||
|
throw sneakyThrow(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Object getDisplayImplementation() {
|
||||||
|
try {
|
||||||
|
return getDisplayImplementationMethod.invoke();
|
||||||
|
} catch (Throwable error) {
|
||||||
|
throw sneakyThrow(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void loadLibrary(String name) throws IOException {
|
||||||
|
String resourceName = System.mapLibraryName(name);
|
||||||
|
File file = File.createTempFile(resourceName, "");
|
||||||
|
file.deleteOnExit();
|
||||||
|
try (InputStream in = Util.class.getResourceAsStream('/' + resourceName)) {
|
||||||
|
FileUtils.copyInputStreamToFile(in, file);
|
||||||
|
}
|
||||||
|
System.load(file.getAbsolutePath());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,54 @@
|
|||||||
|
package net.silentclient.client.utils.cursors;
|
||||||
|
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
|
import java.lang.invoke.MethodHandle;
|
||||||
|
import java.lang.invoke.MethodHandles;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
|
public class Win32SystemCursors {
|
||||||
|
private static final Logger LOGGER = LogManager.getLogger();
|
||||||
|
private static final Long[] CACHE = new Long[SystemCursors.SIZE];
|
||||||
|
private static MethodHandle getHwndMethod;
|
||||||
|
|
||||||
|
static {
|
||||||
|
if (Util.foundInputImplementationMethod()) {
|
||||||
|
try {
|
||||||
|
Class<?> windowsDisplay = Class.forName("org.lwjgl.opengl.WindowsDisplay");
|
||||||
|
Method getHwnd = windowsDisplay.getDeclaredMethod("getHwnd");
|
||||||
|
getHwnd.setAccessible(true);
|
||||||
|
getHwndMethod = MethodHandles.lookup().unreflect(getHwnd);
|
||||||
|
|
||||||
|
Util.loadLibrary("lwjglLegacyCursorsWin32");
|
||||||
|
} catch (Throwable error) {
|
||||||
|
LOGGER.error("Could not perform reflection/load natives", error);
|
||||||
|
SystemCursors.markUnsupported();
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
SystemCursors.markUnsupported();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setCursor(byte cursor) {
|
||||||
|
nSetCursor(getHwnd(), getDefaultCursorHandle(cursor));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static long getDefaultCursorHandle(byte cursor) {
|
||||||
|
if (CACHE[cursor] != null)
|
||||||
|
return CACHE[cursor];
|
||||||
|
|
||||||
|
return CACHE[cursor] = nGetDefaultCursorHandle(cursor);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static long getHwnd() {
|
||||||
|
try {
|
||||||
|
return (long) getHwndMethod.invoke(Util.getDisplayImplementation());
|
||||||
|
} catch (Throwable error) {
|
||||||
|
throw Util.sneakyThrow(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static native long nGetDefaultCursorHandle(byte cursor);
|
||||||
|
|
||||||
|
private static native void nSetCursor(long hwnd, long cursor);
|
||||||
|
}
|
@ -0,0 +1,53 @@
|
|||||||
|
package net.silentclient.client.utils.cursors;
|
||||||
|
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.lwjgl.LWJGLException;
|
||||||
|
|
||||||
|
import java.lang.invoke.MethodHandle;
|
||||||
|
import java.lang.invoke.MethodHandles;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
|
public class X11SystemCursors {
|
||||||
|
private static final Logger LOGGER = LogManager.getLogger();
|
||||||
|
private static final Long[] CACHE = new Long[SystemCursors.SIZE];
|
||||||
|
private static MethodHandle getDisplayMethod;
|
||||||
|
|
||||||
|
static {
|
||||||
|
if (Util.foundInputImplementationMethod()) {
|
||||||
|
try {
|
||||||
|
Class<?> linuxDisplay = Class.forName("org.lwjgl.opengl.LinuxDisplay");
|
||||||
|
Method getDisplay = linuxDisplay.getDeclaredMethod("getDisplay");
|
||||||
|
getDisplay.setAccessible(true);
|
||||||
|
getDisplayMethod = MethodHandles.lookup().unreflect(getDisplay);
|
||||||
|
|
||||||
|
Util.loadLibrary("lwjglLegacyCursorsX11");
|
||||||
|
} catch (Throwable error) {
|
||||||
|
LOGGER.error("Could not perform reflection/load natives", error);
|
||||||
|
SystemCursors.markUnsupported();
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
SystemCursors.markUnsupported();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setCursor(byte cursor) throws LWJGLException {
|
||||||
|
Util.getInputImplementation().setNativeCursor(getDefaultCursorHandle(cursor));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static long getDefaultCursorHandle(byte cursor) {
|
||||||
|
if (CACHE[cursor] != null)
|
||||||
|
return CACHE[cursor];
|
||||||
|
|
||||||
|
return CACHE[cursor] = nGetDefaultCursorHandle(getDisplay(), cursor);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static long getDisplay() {
|
||||||
|
try {
|
||||||
|
return (long) getDisplayMethod.invokeExact();
|
||||||
|
} catch (Throwable error) {
|
||||||
|
throw Util.sneakyThrow(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static native long nGetDefaultCursorHandle(long display, byte cursor);
|
||||||
|
}
|
23
src/main/resources/liblwjglLegacyCursorsX11.c
Normal file
23
src/main/resources/liblwjglLegacyCursorsX11.c
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
#include <Xcursor/Xcursor.h>
|
||||||
|
#include <jni.h>
|
||||||
|
|
||||||
|
const char *LOOKUP[] = {
|
||||||
|
"default",
|
||||||
|
"text",
|
||||||
|
"crosshair",
|
||||||
|
"pointer",
|
||||||
|
"ew-resize",
|
||||||
|
"ns-resize",
|
||||||
|
"nwse-resize",
|
||||||
|
"nesw-resize",
|
||||||
|
"all-scroll",
|
||||||
|
"not-allowed"
|
||||||
|
};
|
||||||
|
|
||||||
|
JNIEXPORT jlong JNICALL Java_io_github_solclient_client_util_cursors_X11SystemCursors_nGetDefaultCursorHandle(
|
||||||
|
JNIEnv *env, jclass unused, jlong display, jbyte cursor) {
|
||||||
|
if (cursor < 0 || cursor >= sizeof(LOOKUP) / sizeof(*LOOKUP))
|
||||||
|
cursor = 0;
|
||||||
|
|
||||||
|
return XcursorLibraryLoadCursor((Display *) display, LOOKUP[cursor]);
|
||||||
|
}
|
BIN
src/main/resources/liblwjglLegacyCursorsX11.so
Normal file
BIN
src/main/resources/liblwjglLegacyCursorsX11.so
Normal file
Binary file not shown.
36
src/main/resources/lwjglLegacyCursorsWin32.c
Normal file
36
src/main/resources/lwjglLegacyCursorsWin32.c
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
#include <windows.h>
|
||||||
|
#include <winuser.h>
|
||||||
|
#include <jni.h>
|
||||||
|
|
||||||
|
JNIEXPORT jlong JNICALL Java_io_github_solclient_client_util_cursors_Win32SystemCursors_nGetDefaultCursorHandle(
|
||||||
|
JNIEnv *env, jclass unused, jbyte cursor) {
|
||||||
|
switch (cursor) {
|
||||||
|
case 0:
|
||||||
|
default:
|
||||||
|
return (jlong) LoadCursor(NULL, IDC_ARROW);
|
||||||
|
case 1:
|
||||||
|
return (jlong) LoadCursor(NULL, IDC_IBEAM);
|
||||||
|
case 2:
|
||||||
|
return (jlong) LoadCursor(NULL, IDC_CROSS);
|
||||||
|
case 3:
|
||||||
|
return (jlong) LoadCursor(NULL, IDC_HAND);
|
||||||
|
case 4:
|
||||||
|
return (jlong) LoadCursor(NULL, IDC_SIZEWE);
|
||||||
|
case 5:
|
||||||
|
return (jlong) LoadCursor(NULL, IDC_SIZENS);
|
||||||
|
case 6:
|
||||||
|
return (jlong) LoadCursor(NULL, IDC_SIZENWSE);
|
||||||
|
case 7:
|
||||||
|
return (jlong) LoadCursor(NULL, IDC_SIZENESW);
|
||||||
|
case 8:
|
||||||
|
return (jlong) LoadCursor(NULL, IDC_SIZEALL);
|
||||||
|
case 9:
|
||||||
|
return (jlong) LoadCursor(NULL, IDC_NO);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT void JNICALL Java_io_github_solclient_client_util_cursors_Win32SystemCursors_nSetCursor(
|
||||||
|
JNIEnv *env, jclass unused, jlong hwnd, jlong cursor) {
|
||||||
|
SetClassLongPtr((HWND) hwnd, GCLP_HCURSOR, NULL);
|
||||||
|
SetCursor((HCURSOR) cursor);
|
||||||
|
}
|
BIN
src/main/resources/lwjglLegacyCursorsWin32.dll
Normal file
BIN
src/main/resources/lwjglLegacyCursorsWin32.dll
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user