Text encoding improvements.
This commit is contained in:
parent
6502050630
commit
87c04cc995
|
@ -33,26 +33,28 @@ package org.lwjgl;
|
|||
|
||||
import java.lang.reflect.Field;
|
||||
import java.nio.*;
|
||||
import java.nio.charset.CharacterCodingException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.CharsetEncoder;
|
||||
import java.nio.charset.CoderResult;
|
||||
|
||||
/**
|
||||
* [INTERNAL USE ONLY]
|
||||
* <p/>
|
||||
* This class provides utility methods for passing buffer addresses to JNI API calls.
|
||||
* This class provides utility methods for passing buffers to JNI API calls.
|
||||
*
|
||||
* @author Spasi
|
||||
*/
|
||||
public final class MemoryUtil {
|
||||
|
||||
private static final CharsetEncoder textEncoder;
|
||||
private static final Charset ascii;
|
||||
private static final Charset utf8;
|
||||
private static final Charset utf16;
|
||||
|
||||
static {
|
||||
CharsetEncoder encoder = Charset.defaultCharset().newEncoder();
|
||||
if ( 1.0f < encoder.maxBytesPerChar() )
|
||||
encoder = Charset.forName("ISO-8859-1").newEncoder();
|
||||
|
||||
textEncoder = encoder;
|
||||
ascii = Charset.forName("ISO-8859-1");
|
||||
utf8 = Charset.forName("UTF-8");
|
||||
utf16 = Charset.forName("UTF-16LE");
|
||||
}
|
||||
|
||||
private static final Accessor memUtil;
|
||||
|
@ -190,42 +192,7 @@ public final class MemoryUtil {
|
|||
// --- [ String utilities ] ---
|
||||
|
||||
/**
|
||||
* Returns the specified text as a null-terminated CharBuffer.
|
||||
*
|
||||
* @param text the text to encode
|
||||
*
|
||||
* @return the encoded text
|
||||
*/
|
||||
public static CharBuffer encodeUTF16(final CharSequence text) {
|
||||
CharBuffer buffer = BufferUtils.createCharBuffer(text.length() + 1);
|
||||
buffer.append(text).append('\0');
|
||||
buffer.flip();
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the specified text array as a CharBuffer. The CharBuffer is packed
|
||||
* and each text is null-terminated.
|
||||
*
|
||||
* @param text the text array to encode
|
||||
*
|
||||
* @return the encoded text
|
||||
*/
|
||||
public static CharBuffer encodeUTF16(final CharSequence... text) {
|
||||
int len = 0;
|
||||
for ( CharSequence cs : text )
|
||||
len += cs.length();
|
||||
|
||||
final CharBuffer buffer = BufferUtils.createCharBuffer(len + text.length);
|
||||
for ( CharSequence cs : text )
|
||||
buffer.append(cs).append('\0');
|
||||
|
||||
buffer.flip();
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes and null-terminated the specified text and returns a ByteBuffer.
|
||||
* Returns a ByteBuffer containing the specified text ASCII encoded and null-terminated.
|
||||
* If text is null, null is returned.
|
||||
*
|
||||
* @param text the text to encode
|
||||
|
@ -235,16 +202,116 @@ public final class MemoryUtil {
|
|||
* @see String#getBytes()
|
||||
*/
|
||||
public static ByteBuffer encodeASCII(final CharSequence text) {
|
||||
return encode(text, ascii);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a ByteBuffer containing the specified text UTF-8 encoded and null-terminated.
|
||||
* If text is null, null is returned.
|
||||
*
|
||||
* @param text the text to encode
|
||||
*
|
||||
* @return the encoded text or null
|
||||
*
|
||||
* @see String#getBytes()
|
||||
*/
|
||||
public static ByteBuffer encodeUTF8(final CharSequence text) {
|
||||
return encode(text, utf8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a ByteBuffer containing the specified text UTF-16LE encoded and null-terminated.
|
||||
* If text is null, null is returned.
|
||||
*
|
||||
* @param text the text to encode
|
||||
*
|
||||
* @return the encoded text
|
||||
*/
|
||||
public static ByteBuffer encodeUTF16(final CharSequence text) {
|
||||
return encode(text, utf16);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps the specified text in a null-terminated CharBuffer and encodes it using the specified Charset.
|
||||
*
|
||||
* @param text the text to encode
|
||||
* @param charset the charset to use for encoding
|
||||
*
|
||||
* @return the encoded text
|
||||
*/
|
||||
private static ByteBuffer encode(final CharSequence text, final Charset charset) {
|
||||
if ( text == null )
|
||||
return null;
|
||||
|
||||
final ByteBuffer buffer = BufferUtils.createByteBuffer(text.length() + 1);
|
||||
return encode(CharBuffer.wrap(new CharSequenceNT(text)), charset);
|
||||
}
|
||||
|
||||
textEncoder.encode(CharBuffer.wrap(text), buffer, true);
|
||||
buffer.put((byte)0);
|
||||
buffer.flip();
|
||||
/**
|
||||
* A {@link CharsetEncoder#encode(java.nio.CharBuffer)} implementation that uses {@link BufferUtils#createByteBuffer(int)}
|
||||
* instead of {@link ByteBuffer#allocate(int)}.
|
||||
*
|
||||
* @see CharsetEncoder#encode(java.nio.CharBuffer)
|
||||
*/
|
||||
private static ByteBuffer encode(final CharBuffer in, final Charset charset) {
|
||||
final CharsetEncoder encoder = charset.newEncoder(); // encoders are not thread-safe, create a new one on every call
|
||||
|
||||
int n = (int)(in.remaining() * encoder.averageBytesPerChar());
|
||||
ByteBuffer out = BufferUtils.createByteBuffer(n);
|
||||
|
||||
if ( n == 0 && in.remaining() == 0 )
|
||||
return out;
|
||||
|
||||
encoder.reset();
|
||||
while ( true ) {
|
||||
CoderResult cr = in.hasRemaining() ? encoder.encode(in, out, true) : CoderResult.UNDERFLOW;
|
||||
if ( cr.isUnderflow() )
|
||||
cr = encoder.flush(out);
|
||||
|
||||
if ( cr.isUnderflow() )
|
||||
break;
|
||||
|
||||
if ( cr.isOverflow() ) {
|
||||
n = 2 * n + 1; // Ensure progress; n might be 0!
|
||||
ByteBuffer o = BufferUtils.createByteBuffer(n);
|
||||
out.flip();
|
||||
o.put(out);
|
||||
out = o;
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
cr.throwException();
|
||||
} catch (CharacterCodingException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
out.flip();
|
||||
return out;
|
||||
}
|
||||
|
||||
/** A null-terminated CharSequence. */
|
||||
private static class CharSequenceNT implements CharSequence {
|
||||
|
||||
final CharSequence source;
|
||||
|
||||
CharSequenceNT(CharSequence source) {
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
public int length() {
|
||||
return source.length() + 1;
|
||||
|
||||
}
|
||||
|
||||
public char charAt(final int index) {
|
||||
return index == source.length() ? '\0' : source.charAt(index);
|
||||
|
||||
}
|
||||
|
||||
public CharSequence subSequence(final int start, final int end) {
|
||||
return new CharSequenceNT(source.subSequence(start, Math.min(end, source.length())));
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
interface Accessor {
|
||||
|
@ -307,4 +374,4 @@ public final class MemoryUtil {
|
|||
throw new NoSuchFieldException(fieldName + " does not exist in " + type.getSimpleName() + " or any of its superclasses.");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
*/
|
||||
package org.lwjgl;
|
||||
|
||||
import java.nio.CharBuffer;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
import java.security.PrivilegedActionException;
|
||||
import java.security.AccessController;
|
||||
|
@ -99,10 +99,9 @@ final class WindowsSysImplementation extends DefaultSysImplementation {
|
|||
|
||||
LWJGLUtil.log(String.format("*** Alert *** %s\n%s\n", title, message));
|
||||
|
||||
// Pack both strings in the same buffer
|
||||
final CharBuffer buffer = MemoryUtil.encodeUTF16(title, message);
|
||||
final long address = MemoryUtil.getAddress0(buffer);
|
||||
nAlert(getHwnd(), address, address + (title.length() + 1) * 2);
|
||||
final ByteBuffer titleText = MemoryUtil.encodeUTF16(title);
|
||||
final ByteBuffer messageText = MemoryUtil.encodeUTF16(message);
|
||||
nAlert(getHwnd(), MemoryUtil.getAddress(titleText), MemoryUtil.getAddress(messageText));
|
||||
}
|
||||
private static native void nAlert(long parent_hwnd, long title, long message);
|
||||
private static native void initCommonControls();
|
||||
|
|
|
@ -53,6 +53,7 @@ import java.lang.reflect.InvocationTargetException;
|
|||
import org.lwjgl.BufferUtils;
|
||||
import org.lwjgl.LWJGLException;
|
||||
import org.lwjgl.LWJGLUtil;
|
||||
import org.lwjgl.MemoryUtil;
|
||||
import org.lwjgl.opengl.XRandR.Screen;
|
||||
import org.lwjgl.opengles.EGL;
|
||||
|
||||
|
@ -138,7 +139,7 @@ final class LinuxDisplay implements DisplayImplementation {
|
|||
private long current_cursor;
|
||||
private long blank_cursor;
|
||||
private boolean mouseInside = true;
|
||||
|
||||
|
||||
private Canvas parent;
|
||||
private long parent_window;
|
||||
private boolean xembedded;
|
||||
|
@ -148,7 +149,7 @@ final class LinuxDisplay implements DisplayImplementation {
|
|||
|
||||
private LinuxKeyboard keyboard;
|
||||
private LinuxMouse mouse;
|
||||
|
||||
|
||||
private final FocusListener focus_listener = new FocusListener() {
|
||||
public void focusGained(FocusEvent e) {
|
||||
synchronized (GlobalLock.lock) {
|
||||
|
@ -499,7 +500,7 @@ final class LinuxDisplay implements DisplayImplementation {
|
|||
private static native void reparentWindow(long display, long window, long parent, int x, int y);
|
||||
private static native long nGetInputFocus(long display) throws LWJGLException;
|
||||
private static native void nSetInputFocus(long display, long window, long time);
|
||||
|
||||
|
||||
private static boolean isAncestorXEmbedded(long window) throws LWJGLException {
|
||||
long xembed_atom = internAtom("_XEMBED_INFO", true);
|
||||
if (xembed_atom != None) {
|
||||
|
@ -728,12 +729,13 @@ final class LinuxDisplay implements DisplayImplementation {
|
|||
public void setTitle(String title) {
|
||||
lockAWT();
|
||||
try {
|
||||
nSetTitle(getDisplay(), getWindow(), title);
|
||||
final ByteBuffer titleText = MemoryUtil.encodeUTF8(title);
|
||||
nSetTitle(getDisplay(), getWindow(), MemoryUtil.getAddress(titleText), titleText.remaining() - 1);
|
||||
} finally {
|
||||
unlockAWT();
|
||||
}
|
||||
}
|
||||
private static native void nSetTitle(long display, long window, String title);
|
||||
private static native void nSetTitle(long display, long window, long title, int len);
|
||||
|
||||
public boolean isCloseRequested() {
|
||||
boolean result = close_requested;
|
||||
|
@ -915,19 +917,19 @@ final class LinuxDisplay implements DisplayImplementation {
|
|||
unlockAWT();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void checkInput() {
|
||||
if (parent == null) return;
|
||||
|
||||
|
||||
if (xembedded) {
|
||||
long current_focus_window = 0;
|
||||
|
||||
|
||||
try {
|
||||
current_focus_window = nGetInputFocus(getDisplay());
|
||||
} catch (LWJGLException e) {
|
||||
return; // fail silently as it can fail whilst splitting browser tabs
|
||||
}
|
||||
|
||||
|
||||
if (last_window_focus != current_focus_window || parent_focused != focused) {
|
||||
if (isParentWindowActive(current_focus_window)) {
|
||||
if (parent_focused) {
|
||||
|
@ -963,49 +965,49 @@ final class LinuxDisplay implements DisplayImplementation {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method will check if the parent window is active when running
|
||||
* in xembed mode. Every xembed embedder window has a focus proxy
|
||||
* window that recieves all the input. This method will test whether
|
||||
* the provided window handle is the focus proxy, if so it will get its
|
||||
* in xembed mode. Every xembed embedder window has a focus proxy
|
||||
* window that recieves all the input. This method will test whether
|
||||
* the provided window handle is the focus proxy, if so it will get its
|
||||
* parent window and then test whether this is an ancestor to our
|
||||
* current_window. If so then parent window is active.
|
||||
*
|
||||
*
|
||||
* @param window - the window handle to test
|
||||
*/
|
||||
private boolean isParentWindowActive(long window) {
|
||||
try {
|
||||
// parent window already active as window is current_window
|
||||
if (window == current_window) return true;
|
||||
|
||||
|
||||
// xembed focus proxy will have no children
|
||||
if (getChildCount(getDisplay(), window) != 0) return false;
|
||||
|
||||
|
||||
// get parent, will be xembed embedder window and ancestor of current_window
|
||||
long parent_window = getParentWindow(getDisplay(), window);
|
||||
|
||||
|
||||
// parent must not be None
|
||||
if (parent_window == None) return false;
|
||||
|
||||
|
||||
// scroll current_window's ancestors to find parent_window
|
||||
long w = current_window;
|
||||
|
||||
|
||||
while (w != None) {
|
||||
w = getParentWindow(getDisplay(), w);
|
||||
if (w == parent_window) {
|
||||
parent_proxy_focus_window = window; // save focus proxy window
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (LWJGLException e) {
|
||||
LWJGLUtil.log("Failed to detect if parent window is active: " + e.getMessage());
|
||||
return true; // on failure assume still active
|
||||
}
|
||||
|
||||
|
||||
return false; // failed to find an active parent window
|
||||
}
|
||||
|
||||
|
||||
private void setFocused(boolean got_focus, int focus_detail) {
|
||||
if (focused == got_focus || focus_detail == NotifyDetailNone || focus_detail == NotifyPointer || focus_detail == NotifyPointerRoot || parent != null)
|
||||
return;
|
||||
|
@ -1356,11 +1358,11 @@ final class LinuxDisplay implements DisplayImplementation {
|
|||
public boolean isInsideWindow() {
|
||||
return mouseInside;
|
||||
}
|
||||
|
||||
|
||||
public void setResizable(boolean resizable) {
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public boolean wasResized() {
|
||||
return false;
|
||||
}
|
||||
|
@ -1552,4 +1554,4 @@ final class LinuxDisplay implements DisplayImplementation {
|
|||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -438,7 +438,7 @@ final class WindowsDisplay implements DisplayImplementation {
|
|||
private static native DisplayMode getCurrentDisplayMode() throws LWJGLException;
|
||||
|
||||
public void setTitle(String title) {
|
||||
CharBuffer buffer = MemoryUtil.encodeUTF16(title);
|
||||
ByteBuffer buffer = MemoryUtil.encodeUTF16(title);
|
||||
nSetTitle(hwnd, MemoryUtil.getAddress0(buffer));
|
||||
}
|
||||
private static native void nSetTitle(long hwnd, long title);
|
||||
|
|
|
@ -1,31 +1,31 @@
|
|||
/*
|
||||
/*
|
||||
* Copyright (c) 2002-2008 LWJGL Project
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of 'LWJGL' nor the names of
|
||||
* its contributors may be used to endorse or promote products derived
|
||||
* * Neither the name of 'LWJGL' nor the names of
|
||||
* its contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
@ -72,8 +72,8 @@ static GLXWindow glx_window = None;
|
|||
|
||||
static Colormap cmap;
|
||||
static int current_depth;
|
||||
static Pixmap current_icon_pixmap;
|
||||
static Pixmap current_icon_mask_pixmap;
|
||||
static Pixmap current_icon_pixmap;
|
||||
static Pixmap current_icon_mask_pixmap;
|
||||
|
||||
static Visual *current_visual;
|
||||
|
||||
|
@ -94,7 +94,7 @@ static int global_error_handler(Display *disp, XErrorEvent *error) {
|
|||
jmethodID handler_method = (*env)->GetStaticMethodID(env, org_lwjgl_LinuxDisplay_class, "globalErrorHandler", "(JJJJJJJ)I");
|
||||
if (handler_method == NULL)
|
||||
return 0;
|
||||
return (*env)->CallStaticIntMethod(env, org_lwjgl_LinuxDisplay_class, handler_method, (jlong)(intptr_t)disp, (jlong)(intptr_t)error,
|
||||
return (*env)->CallStaticIntMethod(env, org_lwjgl_LinuxDisplay_class, handler_method, (jlong)(intptr_t)disp, (jlong)(intptr_t)error,
|
||||
(jlong)(intptr_t)error->display, (jlong)error->serial, (jlong)error->error_code, (jlong)error->request_code, (jlong)error->minor_code);
|
||||
} else
|
||||
return 0;
|
||||
|
@ -170,15 +170,16 @@ static bool isLegacyFullscreen(jint window_mode) {
|
|||
return window_mode == org_lwjgl_opengl_LinuxDisplay_FULLSCREEN_LEGACY;
|
||||
}
|
||||
|
||||
static void setWindowTitle(Display *disp, Window window, const char *title) {
|
||||
XStoreName(disp, window, title);
|
||||
static void setWindowTitle(Display *disp, Window window, jlong title, jint len) {
|
||||
// ASCII fallback if XChangeProperty fails.
|
||||
XStoreName(disp, window, (const char *)(intptr_t)title);
|
||||
|
||||
// tell WM to use Unicode
|
||||
// Set the UTF-8 encoded title
|
||||
XChangeProperty(disp, window,
|
||||
XInternAtom(disp, "_NET_WM_NAME", False),
|
||||
XInternAtom(disp, "UTF8_STRING", False),
|
||||
8, PropModeReplace, (unsigned char *) title,
|
||||
strlen(title));
|
||||
8, PropModeReplace, (const char *)(intptr_t)title,
|
||||
len);
|
||||
}
|
||||
|
||||
JNIEXPORT jlong JNICALL Java_org_lwjgl_opengl_LinuxDisplay_openDisplay(JNIEnv *env, jclass clazz) {
|
||||
|
@ -202,13 +203,11 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplayPeerInfo_initDefaultPee
|
|||
Display *disp = (Display *)(intptr_t)display;
|
||||
initPeerInfo(env, peer_info_handle, disp, screen, pixel_format, true, GLX_WINDOW_BIT, true, false);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nSetTitle(JNIEnv * env, jclass clazz, jlong display, jlong window_ptr, jstring title_obj) {
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nSetTitle(JNIEnv * env, jclass clazz, jlong display, jlong window_ptr, jlong title, jint len) {
|
||||
Display *disp = (Display *)(intptr_t)display;
|
||||
Window window = (Window)window_ptr;
|
||||
char * title = GetStringNativeChars(env, title_obj);
|
||||
setWindowTitle(disp, window, title);
|
||||
free(title);
|
||||
setWindowTitle(disp, window, title, len);
|
||||
}
|
||||
|
||||
static void freeIconPixmap(Display *disp) {
|
||||
|
@ -285,7 +284,7 @@ static void updateWindowHints(JNIEnv *env, Display *disp, Window window) {
|
|||
throwException(env, "XAllocWMHints failed");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
win_hints->flags = InputHint;
|
||||
win_hints->input = True;
|
||||
if (current_icon_pixmap != 0) {
|
||||
|
@ -321,10 +320,10 @@ static Window createWindow(JNIEnv* env, Display *disp, int screen, jint window_m
|
|||
attribs.override_redirect = True;
|
||||
}
|
||||
win = XCreateWindow(disp, parent, x, y, width, height, 0, vis_info->depth, InputOutput, vis_info->visual, attribmask, &attribs);
|
||||
|
||||
|
||||
current_depth = vis_info->depth;
|
||||
current_visual = vis_info->visual;
|
||||
|
||||
|
||||
XFree(vis_info);
|
||||
if (!checkXError(env, disp)) {
|
||||
XFreeColormap(disp, cmap);
|
||||
|
@ -511,7 +510,7 @@ static Pixmap createPixmapFromBuffer(JNIEnv *env, Display *disp, Window window,
|
|||
throwException(env, "XCreateImage failed");
|
||||
return None;
|
||||
}
|
||||
|
||||
|
||||
GC gc = XCreateGC(disp, pixmap, 0, NULL);
|
||||
XPutImage(disp, pixmap, gc, image, 0, 0, 0, 0, width, height);
|
||||
XFreeGC(disp, gc);
|
||||
|
@ -530,7 +529,7 @@ static void setIcon(JNIEnv *env, Display *disp, Window window, char *rgb_data, i
|
|||
freeIconPixmap(disp);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
updateWindowHints(env, disp, window);
|
||||
}
|
||||
|
||||
|
|
|
@ -167,15 +167,16 @@ static bool isLegacyFullscreen(jint window_mode) {
|
|||
return window_mode == org_lwjgl_opengl_LinuxDisplay_FULLSCREEN_LEGACY;
|
||||
}
|
||||
|
||||
static void setWindowTitle(Display *disp, Window window, const char *title) {
|
||||
XStoreName(disp, window, title);
|
||||
static void setWindowTitle(Display *disp, Window window, jlong title, jint len) {
|
||||
// ASCII fallback if XChangeProperty fails.
|
||||
XStoreName(disp, window, (const char *)(intptr_t)title);
|
||||
|
||||
// tell WM to use Unicode
|
||||
// Set the UTF-8 encoded title
|
||||
XChangeProperty(disp, window,
|
||||
XInternAtom(disp, "_NET_WM_NAME", False),
|
||||
XInternAtom(disp, "UTF8_STRING", False),
|
||||
8, PropModeReplace, (unsigned char *) title,
|
||||
strlen(title));
|
||||
8, PropModeReplace, (const char *)(intptr_t)title,
|
||||
len);
|
||||
}
|
||||
|
||||
JNIEXPORT jlong JNICALL Java_org_lwjgl_opengl_LinuxDisplay_openDisplay(JNIEnv *env, jclass clazz) {
|
||||
|
@ -197,12 +198,10 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplayPeerInfo_initDefaultPee
|
|||
//initPeerInfo(env, peer_info_handle, disp, screen);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nSetTitle(JNIEnv * env, jclass clazz, jlong display, jlong window_ptr, jstring title_obj) {
|
||||
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nSetTitle(JNIEnv * env, jclass clazz, jlong display, jlong window_ptr, jlong title, jint len) {
|
||||
Display *disp = (Display *)(intptr_t)display;
|
||||
Window window = (Window)window_ptr;
|
||||
char * title = GetStringNativeChars(env, title_obj);
|
||||
setWindowTitle(disp, window, title);
|
||||
free(title);
|
||||
setWindowTitle(disp, window, title, len);
|
||||
}
|
||||
|
||||
static void freeIconPixmap(Display *disp) {
|
||||
|
|
Loading…
Reference in New Issue