Linux: Added alpha mask support to Display.setIcon
This commit is contained in:
parent
abd3f75d6c
commit
395cf797cb
|
@ -962,8 +962,7 @@ final class LinuxDisplay implements DisplayImplementation {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ByteBuffer convertIcon(ByteBuffer icon, int width, int height) {
|
private static void convertIcon(ByteBuffer icon, int width, int height, ByteBuffer icon_rgb, ByteBuffer icon_mask) {
|
||||||
ByteBuffer icon_copy = BufferUtils.createByteBuffer(icon.capacity());
|
|
||||||
int x = 0;
|
int x = 0;
|
||||||
int y = 5;
|
int y = 5;
|
||||||
byte r,g,b,a;
|
byte r,g,b,a;
|
||||||
|
@ -977,13 +976,14 @@ final class LinuxDisplay implements DisplayImplementation {
|
||||||
b = icon.get((x*4)+(y*width*4)+2);
|
b = icon.get((x*4)+(y*width*4)+2);
|
||||||
a = icon.get((x*4)+(y*width*4)+3);
|
a = icon.get((x*4)+(y*width*4)+3);
|
||||||
|
|
||||||
icon_copy.put((x*depth)+(y*width*depth), b); // blue
|
icon_rgb.put((x*depth)+(y*width*depth), b); // blue
|
||||||
icon_copy.put((x*depth)+(y*width*depth)+1, g); // green
|
icon_rgb.put((x*depth)+(y*width*depth)+1, g); // green
|
||||||
icon_copy.put((x*depth)+(y*width*depth)+2, r);
|
icon_rgb.put((x*depth)+(y*width*depth)+2, r);
|
||||||
icon_copy.put((x*depth)+(y*width*depth)+3, a);
|
icon_mask.put((x*depth)+(y*width*depth), a);
|
||||||
|
icon_mask.put((x*depth)+(y*width*depth)+1, a);
|
||||||
|
icon_mask.put((x*depth)+(y*width*depth)+2, a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return icon_copy;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1006,8 +1006,11 @@ final class LinuxDisplay implements DisplayImplementation {
|
||||||
for (int i=0;i<icons.length;i++) {
|
for (int i=0;i<icons.length;i++) {
|
||||||
int size = icons[i].limit() / 4;
|
int size = icons[i].limit() / 4;
|
||||||
int dimension = (int)Math.sqrt(size);
|
int dimension = (int)Math.sqrt(size);
|
||||||
ByteBuffer icon = convertIcon(icons[i], dimension, dimension);
|
int cap = icons[i].capacity();
|
||||||
nSetWindowIcon(getDisplay(), getWindow(), icon, icon.capacity(), dimension, dimension);
|
ByteBuffer icon_rgb = BufferUtils.createByteBuffer(cap);
|
||||||
|
ByteBuffer icon_mask = BufferUtils.createByteBuffer(cap);
|
||||||
|
convertIcon(icons[i], dimension, dimension, icon_rgb, icon_mask);
|
||||||
|
nSetWindowIcon(getDisplay(), getWindow(), icon_rgb, icon_mask, cap, dimension, dimension);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1022,7 +1025,7 @@ final class LinuxDisplay implements DisplayImplementation {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static native void nSetWindowIcon(long display, long window, ByteBuffer icon, int icons_size, int width, int height);
|
private static native void nSetWindowIcon(long display, long window, ByteBuffer icon_rgb, ByteBuffer icon_mask, int icon_size, int width, int height);
|
||||||
|
|
||||||
public int getWidth() {
|
public int getWidth() {
|
||||||
return Display.getDisplayMode().getWidth();
|
return Display.getDisplayMode().getWidth();
|
||||||
|
|
|
@ -72,6 +72,7 @@ static GLXWindow glx_window = None;
|
||||||
static Colormap cmap;
|
static Colormap cmap;
|
||||||
static int current_depth;
|
static int current_depth;
|
||||||
static Pixmap current_icon_pixmap;
|
static Pixmap current_icon_pixmap;
|
||||||
|
static Pixmap current_icon_mask_pixmap;
|
||||||
|
|
||||||
static Visual *current_visual;
|
static Visual *current_visual;
|
||||||
|
|
||||||
|
@ -185,6 +186,10 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nSetTitle(JNIEnv * env
|
||||||
}
|
}
|
||||||
|
|
||||||
static void freeIconPixmap(Display *disp) {
|
static void freeIconPixmap(Display *disp) {
|
||||||
|
if (current_icon_mask_pixmap != 0) {
|
||||||
|
XFreePixmap(disp, current_icon_mask_pixmap);
|
||||||
|
current_icon_mask_pixmap = 0;
|
||||||
|
}
|
||||||
if (current_icon_pixmap != 0) {
|
if (current_icon_pixmap != 0) {
|
||||||
XFreePixmap(disp, current_icon_pixmap);
|
XFreePixmap(disp, current_icon_pixmap);
|
||||||
current_icon_pixmap = 0;
|
current_icon_pixmap = 0;
|
||||||
|
@ -349,33 +354,46 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nUnlockAWT(JNIEnv *env
|
||||||
jawt.Unlock(env);
|
jawt.Unlock(env);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setIcon(JNIEnv *env, Display *disp, Window window, char *data, int icon_size, int width,int height) {
|
static Pixmap createPixmapFromBuffer(JNIEnv *env, Display *disp, Window window, char *data, int data_size, int width, int height) {
|
||||||
XWMHints* win_hints;
|
Pixmap pixmap = XCreatePixmap(disp, window, width, height, current_depth);
|
||||||
freeIconPixmap(disp);
|
|
||||||
current_icon_pixmap = XCreatePixmap(disp, window, width, height, current_depth);
|
|
||||||
/* We need to copy the image data since XDestroyImage will also free its data buffer, which can't be allowed
|
/* We need to copy the image data since XDestroyImage will also free its data buffer, which can't be allowed
|
||||||
* since the data buffer is managed by the jvm (it's the storage for the direct ByteBuffer)
|
* since the data buffer is managed by the jvm (it's the storage for the direct ByteBuffer)
|
||||||
*/
|
*/
|
||||||
char *icon_copy = (char *)malloc(sizeof(*icon_copy)*icon_size);
|
char *icon_copy = (char *)malloc(sizeof(*icon_copy)*data_size);
|
||||||
|
|
||||||
if (icon_copy == NULL) {
|
if (icon_copy == NULL) {
|
||||||
|
XFreePixmap(disp, pixmap);
|
||||||
throwException(env, "malloc failed");
|
throwException(env, "malloc failed");
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
memcpy(icon_copy, data, icon_size);
|
memcpy(icon_copy, data, data_size);
|
||||||
XImage *image = XCreateImage(disp, current_visual, current_depth, ZPixmap, 0, icon_copy, width, height, 32, 0);
|
XImage *image = XCreateImage(disp, current_visual, current_depth, ZPixmap, 0, icon_copy, width, height, 32, 0);
|
||||||
if (image == NULL) {
|
if (image == NULL) {
|
||||||
freeIconPixmap(disp);
|
XFreePixmap(disp, pixmap);
|
||||||
free(icon_copy);
|
free(icon_copy);
|
||||||
throwException(env, "XCreateImage failed");
|
throwException(env, "XCreateImage failed");
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
GC gc = XCreateGC(disp, current_icon_pixmap, 0, NULL);
|
GC gc = XCreateGC(disp, pixmap, 0, NULL);
|
||||||
XPutImage(disp, current_icon_pixmap, gc, image, 0, 0, 0, 0, width, height);
|
XPutImage(disp, pixmap, gc, image, 0, 0, 0, 0, width, height);
|
||||||
XFreeGC(disp, gc);
|
XFreeGC(disp, gc);
|
||||||
XDestroyImage(image);
|
XDestroyImage(image);
|
||||||
// We won't free icon_copy because it is freed by XDestroyImage
|
// We won't free icon_copy because it is freed by XDestroyImage
|
||||||
|
return pixmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void setIcon(JNIEnv *env, Display *disp, Window window, char *rgb_data, char *mask_data, int icon_size, int width, int height) {
|
||||||
|
XWMHints* win_hints;
|
||||||
|
freeIconPixmap(disp);
|
||||||
|
current_icon_pixmap = createPixmapFromBuffer(env, disp, window, rgb_data, icon_size, width, height);
|
||||||
|
if ((*env)->ExceptionCheck(env))
|
||||||
|
return;
|
||||||
|
current_icon_mask_pixmap = createPixmapFromBuffer(env, disp, window, mask_data, icon_size, width, height);
|
||||||
|
if ((*env)->ExceptionCheck(env)) {
|
||||||
|
freeIconPixmap(disp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
win_hints = XAllocWMHints();
|
win_hints = XAllocWMHints();
|
||||||
if (win_hints == NULL) {
|
if (win_hints == NULL) {
|
||||||
|
@ -383,8 +401,9 @@ static void setIcon(JNIEnv *env, Display *disp, Window window, char *data, int i
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
win_hints->flags = IconPixmapHint;
|
win_hints->flags = IconPixmapHint | IconMaskHint;
|
||||||
win_hints->icon_pixmap = current_icon_pixmap;
|
win_hints->icon_pixmap = current_icon_pixmap;
|
||||||
|
win_hints->icon_mask = current_icon_mask_pixmap;
|
||||||
|
|
||||||
XSetWMHints(disp, window, win_hints);
|
XSetWMHints(disp, window, win_hints);
|
||||||
XFree(win_hints);
|
XFree(win_hints);
|
||||||
|
@ -392,13 +411,14 @@ static void setIcon(JNIEnv *env, Display *disp, Window window, char *data, int i
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nSetWindowIcon
|
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nSetWindowIcon
|
||||||
(JNIEnv *env, jclass clazz, jlong display, jlong window_ptr, jobject iconBuffer, jint icon_size, jint width, jint height)
|
(JNIEnv *env, jclass clazz, jlong display, jlong window_ptr, jobject icon_rgb_buffer, jobject icon_mask_buffer, jint icon_size, jint width, jint height)
|
||||||
{
|
{
|
||||||
Display *disp = (Display *)(intptr_t)display;
|
Display *disp = (Display *)(intptr_t)display;
|
||||||
Window window = (Window)window_ptr;
|
Window window = (Window)window_ptr;
|
||||||
char *imgData = (char *)(*env)->GetDirectBufferAddress(env, iconBuffer);
|
char *rgb_data= (char *)(*env)->GetDirectBufferAddress(env, icon_rgb_buffer);
|
||||||
|
char *mask_data= (char *)(*env)->GetDirectBufferAddress(env, icon_mask_buffer);
|
||||||
|
|
||||||
setIcon(env, disp, window, imgData, icon_size, width, height);
|
setIcon(env, disp, window, rgb_data, mask_data, icon_size, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nUngrabKeyboard(JNIEnv *env, jclass unused, jlong display_ptr) {
|
JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nUngrabKeyboard(JNIEnv *env, jclass unused, jlong display_ptr) {
|
||||||
|
|
Loading…
Reference in New Issue