提交 1d3c26d0 编写于 作者: P prr

8207322: Backport GTK3 support on Linux to 8u

Reviewed-by: prr, ssadetsky
上级 b07ece7a
# #
# Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. # Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# #
# This code is free software; you can redistribute it and/or modify it # This code is free software; you can redistribute it and/or modify it
...@@ -606,7 +606,9 @@ ifeq ($(findstring $(OPENJDK_TARGET_OS),windows macosx),) ...@@ -606,7 +606,9 @@ ifeq ($(findstring $(OPENJDK_TARGET_OS),windows macosx),)
debug_trace.c \ debug_trace.c \
debug_util.c \ debug_util.c \
gnome_interface.c \ gnome_interface.c \
gtk_interface.c \
gtk2_interface.c \ gtk2_interface.c \
gtk3_interface.c \
swing_GTKEngine.c \ swing_GTKEngine.c \
swing_GTKStyle.c \ swing_GTKStyle.c \
rect.c \ rect.c \
......
# #
# Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. # Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# #
# This code is free software; you can redistribute it and/or modify it # This code is free software; you can redistribute it and/or modify it
...@@ -174,6 +174,7 @@ SUNWprivate_1.1 { ...@@ -174,6 +174,7 @@ SUNWprivate_1.1 {
Java_sun_awt_UNIXToolkit_load_1gtk_1icon; Java_sun_awt_UNIXToolkit_load_1gtk_1icon;
Java_sun_awt_UNIXToolkit_nativeSync; Java_sun_awt_UNIXToolkit_nativeSync;
Java_sun_awt_UNIXToolkit_gtkCheckVersionImpl; Java_sun_awt_UNIXToolkit_gtkCheckVersionImpl;
Java_sun_awt_UNIXToolkit_get_1gtk_1version;
Java_java_awt_AWTEvent_initIDs; Java_java_awt_AWTEvent_initIDs;
Java_java_awt_event_InputEvent_initIDs; Java_java_awt_event_InputEvent_initIDs;
Java_java_awt_event_KeyEvent_initIDs; Java_java_awt_event_KeyEvent_initIDs;
......
/* /*
* Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -158,8 +158,8 @@ class GTKEngine { ...@@ -158,8 +158,8 @@ class GTKEngine {
int widgetType, int state, int shadowType, String detail, int widgetType, int state, int shadowType, String detail,
int x, int y, int width, int height, int synthState, int dir); int x, int y, int width, int height, int synthState, int dir);
private native void native_paint_slider( private native void native_paint_slider(
int widgetType, int state, int shadowType, String detail, int widgetType, int state, int shadowType, String detail, int x,
int x, int y, int width, int height, int orientation); int y, int width, int height, int orientation, boolean hasFocus);
private native void native_paint_vline( private native void native_paint_vline(
int widgetType, int state, String detail, int widgetType, int state, String detail,
int x, int y, int width, int height); int x, int y, int width, int height);
...@@ -491,6 +491,14 @@ class GTKEngine { ...@@ -491,6 +491,14 @@ class GTKEngine {
int gtkState = int gtkState =
GTKLookAndFeel.synthStateToGTKStateType(state).ordinal(); GTKLookAndFeel.synthStateToGTKStateType(state).ordinal();
int synthState = context.getComponentState(); int synthState = context.getComponentState();
Container parent = context.getComponent().getParent();
if(GTKLookAndFeel.is3()) {
if (parent != null && parent.getParent() instanceof JComboBox) {
if (parent.getParent().hasFocus()) {
synthState |= SynthConstants.FOCUSED;
}
}
}
int dir = getTextDirection(context); int dir = getTextDirection(context);
int widget = getWidgetType(context.getComponent(), id).ordinal(); int widget = getWidgetType(context.getComponent(), id).ordinal();
native_paint_shadow(widget, gtkState, shadowType.ordinal(), detail, native_paint_shadow(widget, gtkState, shadowType.ordinal(), detail,
...@@ -498,13 +506,13 @@ class GTKEngine { ...@@ -498,13 +506,13 @@ class GTKEngine {
} }
public void paintSlider(Graphics g, SynthContext context, public void paintSlider(Graphics g, SynthContext context,
Region id, int state, ShadowType shadowType, String detail, Region id, int state, ShadowType shadowType, String detail, int x,
int x, int y, int w, int h, Orientation orientation) { int y, int w, int h, Orientation orientation, boolean hasFocus) {
state = GTKLookAndFeel.synthStateToGTKStateType(state).ordinal(); state = GTKLookAndFeel.synthStateToGTKStateType(state).ordinal();
int widget = getWidgetType(context.getComponent(), id).ordinal(); int widget = getWidgetType(context.getComponent(), id).ordinal();
native_paint_slider(widget, state, shadowType.ordinal(), detail, native_paint_slider(widget, state, shadowType.ordinal(), detail,
x - x0, y - y0, w, h, orientation.ordinal()); x - x0, y - y0, w, h, orientation.ordinal(), hasFocus);
} }
public void paintVline(Graphics g, SynthContext context, public void paintVline(Graphics g, SynthContext context,
...@@ -578,8 +586,8 @@ class GTKEngine { ...@@ -578,8 +586,8 @@ class GTKEngine {
* Convenience method that delegates to finishPainting() with * Convenience method that delegates to finishPainting() with
* caching enabled. * caching enabled.
*/ */
public void finishPainting() { public BufferedImage finishPainting() {
finishPainting(true); return finishPainting(true);
} }
/** /**
...@@ -587,7 +595,7 @@ class GTKEngine { ...@@ -587,7 +595,7 @@ class GTKEngine {
* BufferedImage from the offscreen buffer, (optionally) cache it, * BufferedImage from the offscreen buffer, (optionally) cache it,
* and paint it. * and paint it.
*/ */
public void finishPainting(boolean useCache) { public BufferedImage finishPainting(boolean useCache) {
DataBufferInt dataBuffer = new DataBufferInt(w0 * h0); DataBufferInt dataBuffer = new DataBufferInt(w0 * h0);
// Note that stealData() requires a markDirty() afterwards // Note that stealData() requires a markDirty() afterwards
// since we modify the data in it. // since we modify the data in it.
...@@ -601,11 +609,12 @@ class GTKEngine { ...@@ -601,11 +609,12 @@ class GTKEngine {
dataBuffer, w0, h0, w0, bands, null); dataBuffer, w0, h0, w0, bands, null);
ColorModel cm = COLOR_MODELS[transparency - 1]; ColorModel cm = COLOR_MODELS[transparency - 1];
Image img = new BufferedImage(cm, raster, false, null); BufferedImage img = new BufferedImage(cm, raster, false, null);
if (useCache) { if (useCache) {
cache.setImage(getClass(), null, w0, h0, cacheArgs, img); cache.setImage(getClass(), null, w0, h0, cacheArgs, img);
} }
graphics.drawImage(img, x0, y0, null); graphics.drawImage(img, x0, y0, null);
return img;
} }
/** /**
......
/* /*
* Copyright (c) 2002, 2006, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -47,21 +47,6 @@ class GTKGraphicsUtils extends SynthGraphicsUtils { ...@@ -47,21 +47,6 @@ class GTKGraphicsUtils extends SynthGraphicsUtils {
return; return;
} }
int componentState = context.getComponentState(); int componentState = context.getComponentState();
if ((componentState & SynthConstants.DISABLED) ==
SynthConstants.DISABLED){
Color orgColor = g.getColor();
g.setColor(context.getStyle().getColor(context,
GTKColorType.WHITE));
x += 1;
y += 1;
super.paintText(context, g, text, x, y, mnemonicIndex);
g.setColor(orgColor);
x -= 1;
y -= 1;
super.paintText(context, g, text, x, y, mnemonicIndex);
}
else {
String themeName = GTKLookAndFeel.getGtkThemeName(); String themeName = GTKLookAndFeel.getGtkThemeName();
if (themeName != null && themeName.startsWith("blueprint") && if (themeName != null && themeName.startsWith("blueprint") &&
shouldShadowText(context.getRegion(), componentState)) { shouldShadowText(context.getRegion(), componentState)) {
...@@ -70,10 +55,8 @@ class GTKGraphicsUtils extends SynthGraphicsUtils { ...@@ -70,10 +55,8 @@ class GTKGraphicsUtils extends SynthGraphicsUtils {
super.paintText(context, g, text, x+1, y+1, mnemonicIndex); super.paintText(context, g, text, x+1, y+1, mnemonicIndex);
g.setColor(Color.WHITE); g.setColor(Color.WHITE);
} }
super.paintText(context, g, text, x, y, mnemonicIndex); super.paintText(context, g, text, x, y, mnemonicIndex);
} }
}
/** /**
* Paints text at the specified location. This will not attempt to * Paints text at the specified location. This will not attempt to
......
/* /*
* Copyright (c) 2002, 2006, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -214,6 +214,18 @@ class GTKIconFactory { ...@@ -214,6 +214,18 @@ class GTKIconFactory {
Region region = context.getRegion(); Region region = context.getRegion();
GTKStyle style = (GTKStyle) context.getStyle(); GTKStyle style = (GTKStyle) context.getStyle();
if (GTKLookAndFeel.is3() && region == Region.MENU) {
Object value = style.getClassSpecificValue("arrow-scaling");
if (value instanceof Number) {
iconDimension = (int)(((Number) value).floatValue() *
(style.getFont(context).getSize2D() +
2 * style.getClassSpecificIntValue(context,
"indicator-spacing", DEFAULT_ICON_SPACING)));
if (iconDimension > 0) {
return iconDimension;
}
}
}
iconDimension = style.getClassSpecificIntValue(context, iconDimension = style.getClassSpecificIntValue(context,
"indicator-size", "indicator-size",
(region == Region.CHECK_BOX_MENU_ITEM || (region == Region.CHECK_BOX_MENU_ITEM ||
......
/* /*
* Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -52,7 +52,8 @@ import sun.swing.SwingUtilities2; ...@@ -52,7 +52,8 @@ import sun.swing.SwingUtilities2;
* @author Scott Violet * @author Scott Violet
*/ */
public class GTKLookAndFeel extends SynthLookAndFeel { public class GTKLookAndFeel extends SynthLookAndFeel {
private static final boolean IS_22; private static boolean IS_22;
private static boolean IS_3;
/** /**
* Whether or not text is drawn antialiased. This keys off the * Whether or not text is drawn antialiased. This keys off the
...@@ -105,16 +106,6 @@ public class GTKLookAndFeel extends SynthLookAndFeel { ...@@ -105,16 +106,6 @@ public class GTKLookAndFeel extends SynthLookAndFeel {
private static String gtkThemeName = "Default"; private static String gtkThemeName = "Default";
static { static {
// Backup for specifying the version, this isn't currently documented.
// If you pass in anything but 2.2 you got the 2.0 colors/look.
String version = AccessController.doPrivileged(
new GetPropertyAction("swing.gtk.version"));
if (version != null) {
IS_22 = version.equals("2.2");
}
else {
IS_22 = true;
}
String language = Locale.getDefault().getLanguage(); String language = Locale.getDefault().getLanguage();
boolean cjkLocale = boolean cjkLocale =
...@@ -156,6 +147,10 @@ public class GTKLookAndFeel extends SynthLookAndFeel { ...@@ -156,6 +147,10 @@ public class GTKLookAndFeel extends SynthLookAndFeel {
return IS_22; return IS_22;
} }
static boolean is3() {
return IS_3;
}
/** /**
* Maps a swing constant to a GTK constant. * Maps a swing constant to a GTK constant.
*/ */
...@@ -545,7 +540,7 @@ public class GTKLookAndFeel extends SynthLookAndFeel { ...@@ -545,7 +540,7 @@ public class GTKLookAndFeel extends SynthLookAndFeel {
public Object createValue(UIDefaults table) { public Object createValue(UIDefaults table) {
GTKStyleFactory factory = (GTKStyleFactory)getStyleFactory(); GTKStyleFactory factory = (GTKStyleFactory)getStyleFactory();
GTKStyle style = (GTKStyle)factory.getStyle(null, region); GTKStyle style = (GTKStyle)factory.getStyle(null, region);
return style.getFontForState(null); return style.getDefaultFont();
} }
} }
...@@ -1457,6 +1452,19 @@ public class GTKLookAndFeel extends SynthLookAndFeel { ...@@ -1457,6 +1452,19 @@ public class GTKLookAndFeel extends SynthLookAndFeel {
throw new InternalError("Unable to load native GTK libraries"); throw new InternalError("Unable to load native GTK libraries");
} }
if (UNIXToolkit.getGtkVersion() == UNIXToolkit.GtkVersions.GTK2) {
String version = AccessController.doPrivileged(
new GetPropertyAction("jdk.gtk.version"));
if (version != null) {
IS_22 = version.equals("2.2");
} else {
IS_22 = true;
}
} else if (UNIXToolkit.getGtkVersion() ==
UNIXToolkit.GtkVersions.GTK3) {
IS_3 = true;
}
super.initialize(); super.initialize();
inInitialize = true; inInitialize = true;
loadStyles(); loadStyles();
......
/* /*
* Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -26,6 +26,8 @@ package com.sun.java.swing.plaf.gtk; ...@@ -26,6 +26,8 @@ package com.sun.java.swing.plaf.gtk;
import sun.awt.UNIXToolkit; import sun.awt.UNIXToolkit;
import sun.awt.ModalExclude;
import sun.awt.SunToolkit;
import javax.swing.plaf.synth.*; import javax.swing.plaf.synth.*;
import java.awt.*; import java.awt.*;
import javax.swing.*; import javax.swing.*;
...@@ -36,6 +38,7 @@ import com.sun.java.swing.plaf.gtk.GTKConstants.ExpanderStyle; ...@@ -36,6 +38,7 @@ import com.sun.java.swing.plaf.gtk.GTKConstants.ExpanderStyle;
import com.sun.java.swing.plaf.gtk.GTKConstants.Orientation; import com.sun.java.swing.plaf.gtk.GTKConstants.Orientation;
import com.sun.java.swing.plaf.gtk.GTKConstants.PositionType; import com.sun.java.swing.plaf.gtk.GTKConstants.PositionType;
import com.sun.java.swing.plaf.gtk.GTKConstants.ShadowType; import com.sun.java.swing.plaf.gtk.GTKConstants.ShadowType;
import java.awt.image.BufferedImage;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
...@@ -567,8 +570,10 @@ class GTKPainter extends SynthPainter { ...@@ -567,8 +570,10 @@ class GTKPainter extends SynthPainter {
Region id = context.getRegion(); Region id = context.getRegion();
int gtkState = GTKLookAndFeel.synthStateToGTKState( int gtkState = GTKLookAndFeel.synthStateToGTKState(
id, context.getComponentState()); id, context.getComponentState());
boolean isHW = SunToolkit.getHeavyweightComponent(
context.getComponent()) instanceof ModalExclude;
synchronized (UNIXToolkit.GTK_LOCK) { synchronized (UNIXToolkit.GTK_LOCK) {
if (ENGINE.paintCachedImage(g, x, y, w, h, id, gtkState)) { if (ENGINE.paintCachedImage(g, x, y, w, h, id, gtkState, isHW)) {
return; return;
} }
ENGINE.startPainting(g, x, y, w, h, id, gtkState); ENGINE.startPainting(g, x, y, w, h, id, gtkState);
...@@ -582,7 +587,25 @@ class GTKPainter extends SynthPainter { ...@@ -582,7 +587,25 @@ class GTKPainter extends SynthPainter {
style.getGTKColor(context, gtkState, GTKColorType.BACKGROUND), style.getGTKColor(context, gtkState, GTKColorType.BACKGROUND),
x + xThickness, y + yThickness, x + xThickness, y + yThickness,
w - xThickness - xThickness, h - yThickness - yThickness); w - xThickness - xThickness, h - yThickness - yThickness);
ENGINE.finishPainting(); BufferedImage img = ENGINE.finishPainting();
if(!isHW) {
int border = img.getRGB(0, h / 2);
if (img != null && border == img.getRGB(w / 2, h / 2)) {
// fix no menu borders in Adwaita theme
Graphics g2 = img.getGraphics();
Color c = new Color(border);
g2.setColor(new Color(Math.max((int) (c.getRed() * 0.8), 0),
Math.max((int) (c.getGreen() * 0.8), 0),
Math.max((int) (c.getBlue() * 0.8), 0)));
g2.drawLine(0, 0, w - 1, 0);
g2.drawLine(w - 1, 0, w - 1, h - 1);
g2.drawLine(0, h - 1, 0, 1);
g2.setColor(c.darker());
g2.drawLine(w - 1, h - 1, 0, h - 1);
g2.dispose();
g.drawImage(img, x, y, null);
}
}
} }
} }
...@@ -699,6 +722,17 @@ class GTKPainter extends SynthPainter { ...@@ -699,6 +722,17 @@ class GTKPainter extends SynthPainter {
} else { } else {
h -= (insets.top + insets.bottom); h -= (insets.top + insets.bottom);
} }
if (GTKLookAndFeel.is3()) {
if (id == Region.POPUP_MENU_SEPARATOR) {
detail = "menuitem";
h -= (insets.top + insets.bottom);
} else {
detail = "separator";
}
} else {
detail = orientation == JSeparator.HORIZONTAL ?
"hseparator" : "vseparator";
}
} }
synchronized (UNIXToolkit.GTK_LOCK) { synchronized (UNIXToolkit.GTK_LOCK) {
...@@ -743,6 +777,15 @@ class GTKPainter extends SynthPainter { ...@@ -743,6 +777,15 @@ class GTKPainter extends SynthPainter {
// The ubuntulooks engine paints slider troughs differently depending // The ubuntulooks engine paints slider troughs differently depending
// on the current slider value and its component orientation. // on the current slider value and its component orientation.
JSlider slider = (JSlider)context.getComponent(); JSlider slider = (JSlider)context.getComponent();
if (GTKLookAndFeel.is3()) {
if (slider.getOrientation() == JSlider.VERTICAL) {
y += 1;
h -= 2;
} else {
x += 1;
w -= 2;
}
}
double value = slider.getValue(); double value = slider.getValue();
double min = slider.getMinimum(); double min = slider.getMinimum();
double max = slider.getMaximum(); double max = slider.getMaximum();
...@@ -776,15 +819,17 @@ class GTKPainter extends SynthPainter { ...@@ -776,15 +819,17 @@ class GTKPainter extends SynthPainter {
Region id = context.getRegion(); Region id = context.getRegion();
int gtkState = GTKLookAndFeel.synthStateToGTKState( int gtkState = GTKLookAndFeel.synthStateToGTKState(
id, context.getComponentState()); id, context.getComponentState());
boolean hasFocus = GTKLookAndFeel.is3() &&
((context.getComponentState() & SynthConstants.FOCUSED) != 0);
synchronized (UNIXToolkit.GTK_LOCK) { synchronized (UNIXToolkit.GTK_LOCK) {
if (! ENGINE.paintCachedImage(g, x, y, w, h, id, gtkState, dir)) { if (! ENGINE.paintCachedImage(g, x, y, w, h, id, gtkState, dir, hasFocus)) {
Orientation orientation = (dir == JSlider.HORIZONTAL ? Orientation orientation = (dir == JSlider.HORIZONTAL ?
Orientation.HORIZONTAL : Orientation.VERTICAL); Orientation.HORIZONTAL : Orientation.VERTICAL);
String detail = (dir == JSlider.HORIZONTAL ? String detail = (dir == JSlider.HORIZONTAL ?
"hscale" : "vscale"); "hscale" : "vscale");
ENGINE.startPainting(g, x, y, w, h, id, gtkState, dir); ENGINE.startPainting(g, x, y, w, h, id, gtkState, dir);
ENGINE.paintSlider(g, context, id, gtkState, ENGINE.paintSlider(g, context, id, gtkState,
ShadowType.OUT, detail, x, y, w, h, orientation); ShadowType.OUT, detail, x, y, w, h, orientation, hasFocus);
ENGINE.finishPainting(); ENGINE.finishPainting();
} }
} }
...@@ -963,8 +1008,13 @@ class GTKPainter extends SynthPainter { ...@@ -963,8 +1008,13 @@ class GTKPainter extends SynthPainter {
int yThickness = style.getYThickness(); int yThickness = style.getYThickness();
ENGINE.startPainting(g, x, y, w, h, id, state); ENGINE.startPainting(g, x, y, w, h, id, state);
if (GTKLookAndFeel.is3()) {
ENGINE.paintBackground(g, context, id, gtkState, null,
x, y, w, h);
}
ENGINE.paintShadow(g, context, id, gtkState, ENGINE.paintShadow(g, context, id, gtkState,
ShadowType.IN, "entry", x, y, w, h); ShadowType.IN, "entry", x, y, w, h);
if (!GTKLookAndFeel.is3()) {
ENGINE.paintFlatBox(g, context, id, ENGINE.paintFlatBox(g, context, id,
gtkState, ShadowType.NONE, "entry_bg", gtkState, ShadowType.NONE, "entry_bg",
x + xThickness, x + xThickness,
...@@ -972,6 +1022,7 @@ class GTKPainter extends SynthPainter { ...@@ -972,6 +1022,7 @@ class GTKPainter extends SynthPainter {
w - (2 * xThickness), w - (2 * xThickness),
h - (2 * yThickness), h - (2 * yThickness),
ColorType.TEXT_BACKGROUND); ColorType.TEXT_BACKGROUND);
}
if (focusSize > 0 && (state & SynthConstants.FOCUSED) != 0) { if (focusSize > 0 && (state & SynthConstants.FOCUSED) != 0) {
if (!interiorFocus) { if (!interiorFocus) {
...@@ -982,14 +1033,14 @@ class GTKPainter extends SynthPainter { ...@@ -982,14 +1033,14 @@ class GTKPainter extends SynthPainter {
} else { } else {
if (containerParent instanceof JComboBox) { if (containerParent instanceof JComboBox) {
x += (focusSize + 2); x += (focusSize + 2);
y += (focusSize + 1); y += focusSize + (GTKLookAndFeel.is3() ? 3 : 1);
w -= (2 * focusSize + 1); w -= 2 * focusSize + (GTKLookAndFeel.is3() ? 4 : 1);
h -= (2 * focusSize + 2); h -= 2 * focusSize + (GTKLookAndFeel.is3() ? 6 : 2);
} else { } else {
x += focusSize; x += focusSize + (GTKLookAndFeel.is3() ? 2 : 0);
y += focusSize; y += focusSize + (GTKLookAndFeel.is3() ? 2 :0 );
w -= 2 * focusSize; w -= 2 * focusSize + (GTKLookAndFeel.is3() ? 4 : 0);
h -= 2 * focusSize; h -= 2 * focusSize + (GTKLookAndFeel.is3() ? 4 : 0);
} }
} }
ENGINE.paintFocus(g, context, id, gtkState, ENGINE.paintFocus(g, context, id, gtkState,
...@@ -1139,7 +1190,7 @@ class GTKPainter extends SynthPainter { ...@@ -1139,7 +1190,7 @@ class GTKPainter extends SynthPainter {
Orientation.HORIZONTAL : Orientation.VERTICAL); Orientation.HORIZONTAL : Orientation.VERTICAL);
ENGINE.setRangeValue(context, id, value, min, max, visible); ENGINE.setRangeValue(context, id, value, min, max, visible);
ENGINE.paintSlider(g, context, id, gtkState, ENGINE.paintSlider(g, context, id, gtkState,
ShadowType.OUT, "slider", x, y, w, h, orientation); ShadowType.OUT, "slider", x, y, w, h, orientation, false);
ENGINE.finishPainting(); ENGINE.finishPainting();
} }
} }
...@@ -1295,14 +1346,14 @@ class GTKPainter extends SynthPainter { ...@@ -1295,14 +1346,14 @@ class GTKPainter extends SynthPainter {
Graphics g, int state, int x, int y, int w, int h) { Graphics g, int state, int x, int y, int w, int h) {
ENGINE.paintExpander(g, context, Region.TREE, ENGINE.paintExpander(g, context, Region.TREE,
GTKLookAndFeel.synthStateToGTKState(context.getRegion(), state), GTKLookAndFeel.synthStateToGTKState(context.getRegion(), state),
ExpanderStyle.EXPANDED, "treeview", x, y, w, h); ExpanderStyle.EXPANDED, "expander", x, y, w, h);
} }
public void paintTreeCollapsedIcon(SynthContext context, public void paintTreeCollapsedIcon(SynthContext context,
Graphics g, int state, int x, int y, int w, int h) { Graphics g, int state, int x, int y, int w, int h) {
ENGINE.paintExpander(g, context, Region.TREE, ENGINE.paintExpander(g, context, Region.TREE,
GTKLookAndFeel.synthStateToGTKState(context.getRegion(), state), GTKLookAndFeel.synthStateToGTKState(context.getRegion(), state),
ExpanderStyle.COLLAPSED, "treeview", x, y, w, h); ExpanderStyle.COLLAPSED, "expander", x, y, w, h);
} }
public void paintCheckBoxIcon(SynthContext context, public void paintCheckBoxIcon(SynthContext context,
...@@ -1337,8 +1388,13 @@ class GTKPainter extends SynthPainter { ...@@ -1337,8 +1388,13 @@ class GTKPainter extends SynthPainter {
if (gtkState == SynthConstants.MOUSE_OVER) { if (gtkState == SynthConstants.MOUSE_OVER) {
shadow = ShadowType.IN; shadow = ShadowType.IN;
} }
if (!GTKLookAndFeel.is3()) {
x += 3;
y += 3;
w = h = 7;
}
ENGINE.paintArrow(g, context, Region.MENU_ITEM, gtkState, shadow, ENGINE.paintArrow(g, context, Region.MENU_ITEM, gtkState, shadow,
dir, "menuitem", x + 3, y + 3, 7, 7); dir, "menuitem", x, y, w, h);
} }
public void paintCheckBoxMenuItemCheckIcon(SynthContext context, public void paintCheckBoxMenuItemCheckIcon(SynthContext context,
......
/* /*
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -278,7 +278,17 @@ class GTKStyle extends SynthStyle implements GTKConstants { ...@@ -278,7 +278,17 @@ class GTKStyle extends SynthStyle implements GTKConstants {
return getColorForState(context, type); return getColorForState(context, type);
} }
Font getDefaultFont() {
return font;
}
protected Font getFontForState(SynthContext context) { protected Font getFontForState(SynthContext context) {
Font propFont = UIManager
.getFont(context.getRegion().getName() + ".font");
if (propFont != null) {
// if font property got a value then return it
return propFont;
}
return font; return font;
} }
...@@ -711,29 +721,33 @@ class GTKStyle extends SynthStyle implements GTKConstants { ...@@ -711,29 +721,33 @@ class GTKStyle extends SynthStyle implements GTKConstants {
if (region == Region.COMBO_BOX || if (region == Region.COMBO_BOX ||
region == Region.DESKTOP_PANE || region == Region.DESKTOP_PANE ||
region == Region.DESKTOP_ICON || region == Region.DESKTOP_ICON ||
region == Region.EDITOR_PANE ||
region == Region.FORMATTED_TEXT_FIELD ||
region == Region.INTERNAL_FRAME || region == Region.INTERNAL_FRAME ||
region == Region.LIST || region == Region.LIST ||
region == Region.MENU_BAR || region == Region.MENU_BAR ||
region == Region.PANEL || region == Region.PANEL ||
region == Region.PASSWORD_FIELD ||
region == Region.POPUP_MENU || region == Region.POPUP_MENU ||
region == Region.PROGRESS_BAR || region == Region.PROGRESS_BAR ||
region == Region.ROOT_PANE || region == Region.ROOT_PANE ||
region == Region.SCROLL_PANE || region == Region.SCROLL_PANE ||
region == Region.SPINNER ||
region == Region.SPLIT_PANE_DIVIDER || region == Region.SPLIT_PANE_DIVIDER ||
region == Region.TABLE || region == Region.TABLE ||
region == Region.TEXT_AREA || region == Region.TEXT_AREA ||
region == Region.TEXT_FIELD ||
region == Region.TEXT_PANE ||
region == Region.TOOL_BAR_DRAG_WINDOW || region == Region.TOOL_BAR_DRAG_WINDOW ||
region == Region.TOOL_TIP || region == Region.TOOL_TIP ||
region == Region.TREE || region == Region.TREE ||
region == Region.VIEWPORT) { region == Region.VIEWPORT) {
return true; return true;
} }
if (!GTKLookAndFeel.is3()) {
if (region == Region.EDITOR_PANE ||
region == Region.FORMATTED_TEXT_FIELD ||
region == Region.PASSWORD_FIELD ||
region == Region.SPINNER ||
region == Region.TEXT_FIELD ||
region == Region.TEXT_PANE) {
return true;
}
}
Component c = context.getComponent(); Component c = context.getComponent();
String name = c.getName(); String name = c.getName();
if (name == "ComboBox.renderer" || name == "ComboBox.listRenderer") { if (name == "ComboBox.renderer" || name == "ComboBox.listRenderer") {
...@@ -829,6 +843,14 @@ class GTKStyle extends SynthStyle implements GTKConstants { ...@@ -829,6 +843,14 @@ class GTKStyle extends SynthStyle implements GTKConstants {
int focusPad = int focusPad =
getClassSpecificIntValue(context, "focus-padding", 1); getClassSpecificIntValue(context, "focus-padding", 1);
return indicatorSpacing + focusSize + focusPad; return indicatorSpacing + focusSize + focusPad;
} else if (GTKLookAndFeel.is3() && "ComboBox.forceOpaque".equals(key)) {
return true;
} else if ("Tree.expanderSize".equals(key)) {
Object value = getClassSpecificValue("expander-size");
if (value instanceof Integer) {
return (Integer)value + 4;
}
return null;
} }
// Is it a stock icon ? // Is it a stock icon ?
...@@ -1108,9 +1130,9 @@ class GTKStyle extends SynthStyle implements GTKConstants { ...@@ -1108,9 +1130,9 @@ class GTKStyle extends SynthStyle implements GTKConstants {
static { static {
CLASS_SPECIFIC_MAP = new HashMap<String,String>(); CLASS_SPECIFIC_MAP = new HashMap<String,String>();
CLASS_SPECIFIC_MAP.put("Slider.thumbHeight", "slider-width"); CLASS_SPECIFIC_MAP.put("Slider.thumbHeight", "slider-width");
CLASS_SPECIFIC_MAP.put("Slider.thumbWidth", "slider-length");
CLASS_SPECIFIC_MAP.put("Slider.trackBorder", "trough-border"); CLASS_SPECIFIC_MAP.put("Slider.trackBorder", "trough-border");
CLASS_SPECIFIC_MAP.put("SplitPane.size", "handle-size"); CLASS_SPECIFIC_MAP.put("SplitPane.size", "handle-size");
CLASS_SPECIFIC_MAP.put("Tree.expanderSize", "expander-size");
CLASS_SPECIFIC_MAP.put("ScrollBar.thumbHeight", "slider-width"); CLASS_SPECIFIC_MAP.put("ScrollBar.thumbHeight", "slider-width");
CLASS_SPECIFIC_MAP.put("ScrollBar.width", "slider-width"); CLASS_SPECIFIC_MAP.put("ScrollBar.width", "slider-width");
CLASS_SPECIFIC_MAP.put("TextArea.caretForeground", "cursor-color"); CLASS_SPECIFIC_MAP.put("TextArea.caretForeground", "cursor-color");
......
/* /*
* Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -29,9 +29,11 @@ import static java.awt.RenderingHints.*; ...@@ -29,9 +29,11 @@ import static java.awt.RenderingHints.*;
import java.awt.color.ColorSpace; import java.awt.color.ColorSpace;
import java.awt.image.*; import java.awt.image.*;
import java.security.AccessController; import java.security.AccessController;
import java.security.PrivilegedAction;
import sun.security.action.GetIntegerAction; import sun.security.action.GetIntegerAction;
import com.sun.java.swing.plaf.gtk.GTKConstants.TextDirection; import com.sun.java.swing.plaf.gtk.GTKConstants.TextDirection;
import sun.java2d.opengl.OGLRenderQueue; import sun.java2d.opengl.OGLRenderQueue;
import sun.security.action.GetPropertyAction;
public abstract class UNIXToolkit extends SunToolkit public abstract class UNIXToolkit extends SunToolkit
{ {
...@@ -42,6 +44,40 @@ public abstract class UNIXToolkit extends SunToolkit ...@@ -42,6 +44,40 @@ public abstract class UNIXToolkit extends SunToolkit
private static final int[] BAND_OFFSETS_ALPHA = { 0, 1, 2, 3 }; private static final int[] BAND_OFFSETS_ALPHA = { 0, 1, 2, 3 };
private static final int DEFAULT_DATATRANSFER_TIMEOUT = 10000; private static final int DEFAULT_DATATRANSFER_TIMEOUT = 10000;
// Allowed GTK versions
public enum GtkVersions {
ANY(0),
GTK2(Constants.GTK2_MAJOR_NUMBER),
GTK3(Constants.GTK3_MAJOR_NUMBER);
static class Constants {
static final int GTK2_MAJOR_NUMBER = 2;
static final int GTK3_MAJOR_NUMBER = 3;
}
final int number;
GtkVersions(int number) {
this.number = number;
}
public static GtkVersions getVersion(int number) {
switch (number) {
case Constants.GTK2_MAJOR_NUMBER:
return GTK2;
case Constants.GTK3_MAJOR_NUMBER:
return GTK3;
default:
return ANY;
}
}
// major GTK version number
public int getNumber() {
return number;
}
};
private Boolean nativeGTKAvailable; private Boolean nativeGTKAvailable;
private Boolean nativeGTKLoaded; private Boolean nativeGTKLoaded;
private BufferedImage tmpImage = null; private BufferedImage tmpImage = null;
...@@ -79,7 +115,7 @@ public abstract class UNIXToolkit extends SunToolkit ...@@ -79,7 +115,7 @@ public abstract class UNIXToolkit extends SunToolkit
return nativeGTKAvailable; return nativeGTKAvailable;
} else { } else {
boolean success = check_gtk(); boolean success = check_gtk(getEnabledGtkVersion().getNumber());
nativeGTKAvailable = success; nativeGTKAvailable = success;
return success; return success;
} }
...@@ -97,7 +133,8 @@ public abstract class UNIXToolkit extends SunToolkit ...@@ -97,7 +133,8 @@ public abstract class UNIXToolkit extends SunToolkit
public boolean loadGTK() { public boolean loadGTK() {
synchronized (GTK_LOCK) { synchronized (GTK_LOCK) {
if (nativeGTKLoaded == null) { if (nativeGTKLoaded == null) {
nativeGTKLoaded = load_gtk(); nativeGTKLoaded = load_gtk(getEnabledGtkVersion().getNumber(),
isGtkVerbose());
} }
} }
return nativeGTKLoaded; return nativeGTKLoaded;
...@@ -240,14 +277,15 @@ public abstract class UNIXToolkit extends SunToolkit ...@@ -240,14 +277,15 @@ public abstract class UNIXToolkit extends SunToolkit
tmpImage = new BufferedImage(colorModel, raster, false, null); tmpImage = new BufferedImage(colorModel, raster, false, null);
} }
private static native boolean check_gtk(); private static native boolean check_gtk(int version);
private static native boolean load_gtk(); private static native boolean load_gtk(int version, boolean verbose);
private static native boolean unload_gtk(); private static native boolean unload_gtk();
private native boolean load_gtk_icon(String filename); private native boolean load_gtk_icon(String filename);
private native boolean load_stock_icon(int widget_type, String stock_id, private native boolean load_stock_icon(int widget_type, String stock_id,
int iconSize, int textDirection, String detail); int iconSize, int textDirection, String detail);
private native void nativeSync(); private native void nativeSync();
private static native int get_gtk_version();
@Override @Override
public void sync() { public void sync() {
...@@ -337,4 +375,26 @@ public abstract class UNIXToolkit extends SunToolkit ...@@ -337,4 +375,26 @@ public abstract class UNIXToolkit extends SunToolkit
} }
return false; return false;
} }
public static GtkVersions getEnabledGtkVersion() {
String version = AccessController.doPrivileged(
new GetPropertyAction("jdk.gtk.version"));
if (version == null) {
return GtkVersions.ANY;
} else if (version.startsWith("2")) {
return GtkVersions.GTK2;
} else if("3".equals(version) ){
return GtkVersions.GTK3;
}
return GtkVersions.ANY;
}
public static GtkVersions getGtkVersion() {
return GtkVersions.getVersion(get_gtk_version());
}
public static boolean isGtkVerbose() {
return AccessController.doPrivileged((PrivilegedAction<Boolean>)()
-> Boolean.getBoolean("jdk.gtk.verbose"));
}
} }
/* /*
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
package sun.awt.X11; package sun.awt.X11;
import sun.awt.UNIXToolkit;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
...@@ -57,7 +58,8 @@ public class XDesktopPeer implements DesktopPeer { ...@@ -57,7 +58,8 @@ public class XDesktopPeer implements DesktopPeer {
XToolkit.awtLock(); XToolkit.awtLock();
try { try {
if (!initExecuted) { if (!initExecuted) {
nativeLibraryLoaded = init(); nativeLibraryLoaded = init(UNIXToolkit.getEnabledGtkVersion()
.getNumber(), UNIXToolkit.isGtkVerbose());
} }
} finally { } finally {
initExecuted = true; initExecuted = true;
...@@ -123,5 +125,5 @@ public class XDesktopPeer implements DesktopPeer { ...@@ -123,5 +125,5 @@ public class XDesktopPeer implements DesktopPeer {
} }
private native boolean gnome_url_show(byte[] url); private native boolean gnome_url_show(byte[] url);
private static native boolean init(); private static native boolean init(int gtkVersion, boolean verbose);
} }
...@@ -1125,7 +1125,8 @@ public final class XToolkit extends UNIXToolkit implements Runnable { ...@@ -1125,7 +1125,8 @@ public final class XToolkit extends UNIXToolkit implements Runnable {
public FileDialogPeer createFileDialog(FileDialog target) { public FileDialogPeer createFileDialog(FileDialog target) {
FileDialogPeer peer = null; FileDialogPeer peer = null;
// The current GtkFileChooser is available from GTK+ 2.4 // The current GtkFileChooser is available from GTK+ 2.4
if (!getSunAwtDisableGtkFileDialogs() && checkGtkVersion(2, 4, 0)) { if (!getSunAwtDisableGtkFileDialogs() &&
(checkGtkVersion(2, 4, 0) || checkGtkVersion(3, 0, 0))) {
peer = new GtkFileDialogPeer(target); peer = new GtkFileDialogPeer(target);
} else { } else {
peer = new XFileDialogPeer(target); peer = new XFileDialogPeer(target);
......
/* /*
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <X11/Xlib.h> #include <X11/Xlib.h>
#include <X11/keysym.h>
#include <sys/time.h> #include <sys/time.h>
#include "awt.h" #include "awt.h"
......
/* /*
* Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
#ifndef HEADLESS #ifndef HEADLESS
#include "awt.h" #include "awt.h"
#include "gtk2_interface.h" #include "gtk_interface.h"
#endif /* !HEADLESS */ #endif /* !HEADLESS */
...@@ -45,13 +45,12 @@ static jmethodID icon_upcall_method = NULL; ...@@ -45,13 +45,12 @@ static jmethodID icon_upcall_method = NULL;
/* /*
* Class: sun_awt_UNIXToolkit * Class: sun_awt_UNIXToolkit
* Method: check_gtk * Method: check_gtk
* Signature: ()Z * Signature: (I)Z
*/ */
JNIEXPORT jboolean JNICALL JNIEXPORT jboolean JNICALL
Java_sun_awt_UNIXToolkit_check_1gtk(JNIEnv *env, jclass klass) Java_sun_awt_UNIXToolkit_check_1gtk(JNIEnv *env, jclass klass, jint version) {
{
#ifndef HEADLESS #ifndef HEADLESS
return (jboolean)gtk2_check_version(); return (jboolean)gtk_check_version(version);
#else #else
return JNI_FALSE; return JNI_FALSE;
#endif /* !HEADLESS */ #endif /* !HEADLESS */
...@@ -61,13 +60,13 @@ Java_sun_awt_UNIXToolkit_check_1gtk(JNIEnv *env, jclass klass) ...@@ -61,13 +60,13 @@ Java_sun_awt_UNIXToolkit_check_1gtk(JNIEnv *env, jclass klass)
/* /*
* Class: sun_awt_UNIXToolkit * Class: sun_awt_UNIXToolkit
* Method: load_gtk * Method: load_gtk
* Signature: ()Z * Signature: (I)Z
*/ */
JNIEXPORT jboolean JNICALL JNIEXPORT jboolean JNICALL
Java_sun_awt_UNIXToolkit_load_1gtk(JNIEnv *env, jclass klass) Java_sun_awt_UNIXToolkit_load_1gtk(JNIEnv *env, jclass klass, jint version,
{ jboolean verbose) {
#ifndef HEADLESS #ifndef HEADLESS
return (jboolean)gtk2_load(env); return (jboolean)gtk_load(env, version, verbose);
#else #else
return JNI_FALSE; return JNI_FALSE;
#endif /* !HEADLESS */ #endif /* !HEADLESS */
...@@ -83,16 +82,14 @@ JNIEXPORT jboolean JNICALL ...@@ -83,16 +82,14 @@ JNIEXPORT jboolean JNICALL
Java_sun_awt_UNIXToolkit_unload_1gtk(JNIEnv *env, jclass klass) Java_sun_awt_UNIXToolkit_unload_1gtk(JNIEnv *env, jclass klass)
{ {
#ifndef HEADLESS #ifndef HEADLESS
return (jboolean)gtk2_unload(); return (jboolean)gtk->unload();
#else #else
return JNI_FALSE; return JNI_FALSE;
#endif /* !HEADLESS */ #endif /* !HEADLESS */
} }
jboolean _icon_upcall(JNIEnv *env, jobject this, GdkPixbuf *pixbuf) jboolean init_method(JNIEnv *env, jobject this)
{ {
jboolean result = JNI_FALSE;
if (this_class == NULL) { if (this_class == NULL) {
this_class = (*env)->NewGlobalRef(env, this_class = (*env)->NewGlobalRef(env,
(*env)->GetObjectClass(env, this)); (*env)->GetObjectClass(env, this));
...@@ -101,32 +98,7 @@ jboolean _icon_upcall(JNIEnv *env, jobject this, GdkPixbuf *pixbuf) ...@@ -101,32 +98,7 @@ jboolean _icon_upcall(JNIEnv *env, jobject this, GdkPixbuf *pixbuf)
CHECK_NULL_RETURN(icon_upcall_method, JNI_FALSE); CHECK_NULL_RETURN(icon_upcall_method, JNI_FALSE);
} }
if (pixbuf != NULL) return JNI_TRUE;
{
guchar *pixbuf_data = (*fp_gdk_pixbuf_get_pixels)(pixbuf);
int row_stride = (*fp_gdk_pixbuf_get_rowstride)(pixbuf);
int width = (*fp_gdk_pixbuf_get_width)(pixbuf);
int height = (*fp_gdk_pixbuf_get_height)(pixbuf);
int bps = (*fp_gdk_pixbuf_get_bits_per_sample)(pixbuf);
int channels = (*fp_gdk_pixbuf_get_n_channels)(pixbuf);
gboolean alpha = (*fp_gdk_pixbuf_get_has_alpha)(pixbuf);
/* Copy the data array into a Java structure so we can pass it back. */
jbyteArray data = (*env)->NewByteArray(env, (row_stride * height));
JNU_CHECK_EXCEPTION_RETURN(env, JNI_FALSE);
(*env)->SetByteArrayRegion(env, data, 0, (row_stride * height),
(jbyte *)pixbuf_data);
/* Release the pixbuf. */
(*fp_g_object_unref)(pixbuf);
/* Call the callback method to create the image on the Java side. */
(*env)->CallVoidMethod(env, this, icon_upcall_method, data,
width, height, row_stride, bps, channels, alpha);
result = JNI_TRUE;
}
return result;
} }
/* /*
...@@ -144,7 +116,6 @@ Java_sun_awt_UNIXToolkit_load_1gtk_1icon(JNIEnv *env, jobject this, ...@@ -144,7 +116,6 @@ Java_sun_awt_UNIXToolkit_load_1gtk_1icon(JNIEnv *env, jobject this,
int len; int len;
char *filename_str = NULL; char *filename_str = NULL;
GError **error = NULL; GError **error = NULL;
GdkPixbuf *pixbuf;
if (filename == NULL) if (filename == NULL)
{ {
...@@ -158,13 +129,18 @@ Java_sun_awt_UNIXToolkit_load_1gtk_1icon(JNIEnv *env, jobject this, ...@@ -158,13 +129,18 @@ Java_sun_awt_UNIXToolkit_load_1gtk_1icon(JNIEnv *env, jobject this,
JNU_ThrowOutOfMemoryError(env, "OutOfMemoryError"); JNU_ThrowOutOfMemoryError(env, "OutOfMemoryError");
return JNI_FALSE; return JNI_FALSE;
} }
if (!init_method(env, this) ) {
free(filename_str);
return JNI_FALSE;
}
(*env)->GetStringUTFRegion(env, filename, 0, len, filename_str); (*env)->GetStringUTFRegion(env, filename, 0, len, filename_str);
pixbuf = (*fp_gdk_pixbuf_new_from_file)(filename_str, error); jboolean result = gtk->get_file_icon_data(env, filename_str, error,
icon_upcall_method, this);
/* Release the strings we've allocated. */ /* Release the strings we've allocated. */
free(filename_str); free(filename_str);
return _icon_upcall(env, this, pixbuf); return result;
#else /* HEADLESS */ #else /* HEADLESS */
return JNI_FALSE; return JNI_FALSE;
#endif /* !HEADLESS */ #endif /* !HEADLESS */
...@@ -186,7 +162,6 @@ Java_sun_awt_UNIXToolkit_load_1stock_1icon(JNIEnv *env, jobject this, ...@@ -186,7 +162,6 @@ Java_sun_awt_UNIXToolkit_load_1stock_1icon(JNIEnv *env, jobject this,
int len; int len;
char *stock_id_str = NULL; char *stock_id_str = NULL;
char *detail_str = NULL; char *detail_str = NULL;
GdkPixbuf *pixbuf;
if (stock_id == NULL) if (stock_id == NULL)
{ {
...@@ -215,8 +190,12 @@ Java_sun_awt_UNIXToolkit_load_1stock_1icon(JNIEnv *env, jobject this, ...@@ -215,8 +190,12 @@ Java_sun_awt_UNIXToolkit_load_1stock_1icon(JNIEnv *env, jobject this,
(*env)->GetStringUTFRegion(env, detail, 0, len, detail_str); (*env)->GetStringUTFRegion(env, detail, 0, len, detail_str);
} }
pixbuf = gtk2_get_stock_icon(widget_type, stock_id_str, icon_size, if (!init_method(env, this) ) {
text_direction, detail_str); return JNI_FALSE;
}
jboolean result = gtk->get_icon_data(env, widget_type, stock_id_str,
icon_size, text_direction, detail_str,
icon_upcall_method, this);
/* Release the strings we've allocated. */ /* Release the strings we've allocated. */
free(stock_id_str); free(stock_id_str);
...@@ -225,7 +204,7 @@ Java_sun_awt_UNIXToolkit_load_1stock_1icon(JNIEnv *env, jobject this, ...@@ -225,7 +204,7 @@ Java_sun_awt_UNIXToolkit_load_1stock_1icon(JNIEnv *env, jobject this,
free(detail_str); free(detail_str);
} }
return _icon_upcall(env, this, pixbuf); return result;
#else /* HEADLESS */ #else /* HEADLESS */
return JNI_FALSE; return JNI_FALSE;
#endif /* !HEADLESS */ #endif /* !HEADLESS */
...@@ -279,11 +258,25 @@ Java_sun_awt_UNIXToolkit_gtkCheckVersionImpl(JNIEnv *env, jobject this, ...@@ -279,11 +258,25 @@ Java_sun_awt_UNIXToolkit_gtkCheckVersionImpl(JNIEnv *env, jobject this,
{ {
char *ret; char *ret;
ret = fp_gtk_check_version(major, minor, micro); ret = gtk->gtk_check_version(major, minor, micro);
if (ret == NULL) { if (ret == NULL) {
return TRUE; return TRUE;
} }
free(ret);
return FALSE; return FALSE;
} }
/*
* Class: sun_awt_UNIXToolkit
* Method: get_gtk_version
* Signature: ()I
*/
JNIEXPORT jint JNICALL
Java_sun_awt_UNIXToolkit_get_1gtk_1version(JNIEnv *env, jclass klass)
{
#ifndef HEADLESS
return gtk ? gtk->version : GTK_ANY;
#else
return GTK_ANY;
#endif /* !HEADLESS */
}
...@@ -35,52 +35,15 @@ ...@@ -35,52 +35,15 @@
#include <jni_util.h> #include <jni_util.h>
#include "awt.h" #include "awt.h"
#define GTK2_LIB_VERSIONED VERSIONED_JNI_LIB_NAME("gtk-x11-2.0", "0")
#define GTK2_LIB JNI_LIB_NAME("gtk-x11-2.0")
#define GTHREAD_LIB_VERSIONED VERSIONED_JNI_LIB_NAME("gthread-2.0", "0")
#define GTHREAD_LIB JNI_LIB_NAME("gthread-2.0")
#define G_TYPE_INVALID G_TYPE_MAKE_FUNDAMENTAL (0)
#define G_TYPE_NONE G_TYPE_MAKE_FUNDAMENTAL (1)
#define G_TYPE_INTERFACE G_TYPE_MAKE_FUNDAMENTAL (2)
#define G_TYPE_CHAR G_TYPE_MAKE_FUNDAMENTAL (3)
#define G_TYPE_UCHAR G_TYPE_MAKE_FUNDAMENTAL (4)
#define G_TYPE_BOOLEAN G_TYPE_MAKE_FUNDAMENTAL (5)
#define G_TYPE_INT G_TYPE_MAKE_FUNDAMENTAL (6)
#define G_TYPE_UINT G_TYPE_MAKE_FUNDAMENTAL (7)
#define G_TYPE_LONG G_TYPE_MAKE_FUNDAMENTAL (8)
#define G_TYPE_ULONG G_TYPE_MAKE_FUNDAMENTAL (9)
#define G_TYPE_INT64 G_TYPE_MAKE_FUNDAMENTAL (10)
#define G_TYPE_UINT64 G_TYPE_MAKE_FUNDAMENTAL (11)
#define G_TYPE_ENUM G_TYPE_MAKE_FUNDAMENTAL (12)
#define G_TYPE_FLAGS G_TYPE_MAKE_FUNDAMENTAL (13)
#define G_TYPE_FLOAT G_TYPE_MAKE_FUNDAMENTAL (14)
#define G_TYPE_DOUBLE G_TYPE_MAKE_FUNDAMENTAL (15)
#define G_TYPE_STRING G_TYPE_MAKE_FUNDAMENTAL (16)
#define G_TYPE_POINTER G_TYPE_MAKE_FUNDAMENTAL (17)
#define G_TYPE_BOXED G_TYPE_MAKE_FUNDAMENTAL (18)
#define G_TYPE_PARAM G_TYPE_MAKE_FUNDAMENTAL (19)
#define G_TYPE_OBJECT G_TYPE_MAKE_FUNDAMENTAL (20)
#define GTK_TYPE_BORDER ((*fp_gtk_border_get_type)()) #define GTK_TYPE_BORDER ((*fp_gtk_border_get_type)())
#define G_TYPE_FUNDAMENTAL_SHIFT (2) #define G_TYPE_FUNDAMENTAL_SHIFT (2)
#define G_TYPE_MAKE_FUNDAMENTAL(x) ((GType) ((x) << G_TYPE_FUNDAMENTAL_SHIFT)) #define G_TYPE_MAKE_FUNDAMENTAL(x) ((GType) ((x) << G_TYPE_FUNDAMENTAL_SHIFT))
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#define CONV_BUFFER_SIZE 128 #define CONV_BUFFER_SIZE 128
#define NO_SYMBOL_EXCEPTION 1 #define NO_SYMBOL_EXCEPTION 1
/* SynthConstants */
const gint ENABLED = 1 << 0;
const gint MOUSE_OVER = 1 << 1;
const gint PRESSED = 1 << 2;
const gint DISABLED = 1 << 3;
const gint FOCUSED = 1 << 8;
const gint SELECTED = 1 << 9;
const gint DEFAULT = 1 << 10;
static void *gtk2_libhandle = NULL; static void *gtk2_libhandle = NULL;
static void *gthread_libhandle = NULL; static void *gthread_libhandle = NULL;
...@@ -105,55 +68,6 @@ static char convertionBuffer[CONV_BUFFER_SIZE]; ...@@ -105,55 +68,6 @@ static char convertionBuffer[CONV_BUFFER_SIZE];
static gboolean new_combo = TRUE; static gboolean new_combo = TRUE;
const char ENV_PREFIX[] = "GTK_MODULES="; const char ENV_PREFIX[] = "GTK_MODULES=";
/*******************/
enum GtkWidgetType
{
_GTK_ARROW_TYPE,
_GTK_BUTTON_TYPE,
_GTK_CHECK_BUTTON_TYPE,
_GTK_CHECK_MENU_ITEM_TYPE,
_GTK_COLOR_SELECTION_DIALOG_TYPE,
_GTK_COMBO_BOX_TYPE,
_GTK_COMBO_BOX_ARROW_BUTTON_TYPE,
_GTK_COMBO_BOX_TEXT_FIELD_TYPE,
_GTK_CONTAINER_TYPE,
_GTK_ENTRY_TYPE,
_GTK_FRAME_TYPE,
_GTK_HANDLE_BOX_TYPE,
_GTK_HPANED_TYPE,
_GTK_HPROGRESS_BAR_TYPE,
_GTK_HSCALE_TYPE,
_GTK_HSCROLLBAR_TYPE,
_GTK_HSEPARATOR_TYPE,
_GTK_IMAGE_TYPE,
_GTK_MENU_TYPE,
_GTK_MENU_BAR_TYPE,
_GTK_MENU_ITEM_TYPE,
_GTK_NOTEBOOK_TYPE,
_GTK_LABEL_TYPE,
_GTK_RADIO_BUTTON_TYPE,
_GTK_RADIO_MENU_ITEM_TYPE,
_GTK_SCROLLED_WINDOW_TYPE,
_GTK_SEPARATOR_MENU_ITEM_TYPE,
_GTK_SEPARATOR_TOOL_ITEM_TYPE,
_GTK_SPIN_BUTTON_TYPE,
_GTK_TEXT_VIEW_TYPE,
_GTK_TOGGLE_BUTTON_TYPE,
_GTK_TOOLBAR_TYPE,
_GTK_TOOLTIP_TYPE,
_GTK_TREE_VIEW_TYPE,
_GTK_VIEWPORT_TYPE,
_GTK_VPANED_TYPE,
_GTK_VPROGRESS_BAR_TYPE,
_GTK_VSCALE_TYPE,
_GTK_VSCROLLBAR_TYPE,
_GTK_VSEPARATOR_TYPE,
_GTK_WINDOW_TYPE,
_GTK_DIALOG_TYPE,
_GTK_WIDGET_TYPE_SIZE
};
static GtkWidget *gtk2_widgets[_GTK_WIDGET_TYPE_SIZE]; static GtkWidget *gtk2_widgets[_GTK_WIDGET_TYPE_SIZE];
/************************* /*************************
...@@ -362,20 +276,6 @@ static void (*fp_gtk_widget_size_request)(GtkWidget *widget, ...@@ -362,20 +276,6 @@ static void (*fp_gtk_widget_size_request)(GtkWidget *widget,
static GtkAdjustment* (*fp_gtk_range_get_adjustment)(GtkRange* range); static GtkAdjustment* (*fp_gtk_range_get_adjustment)(GtkRange* range);
/* Method bodies */ /* Method bodies */
const char *getStrFor(JNIEnv *env, jstring val)
{
int length = (*env)->GetStringLength(env, val);
if (length > CONV_BUFFER_SIZE-1)
{
length = CONV_BUFFER_SIZE-1;
#ifdef INTERNAL_BUILD
fprintf(stderr, "Note: Detail is too long: %d chars\n", length);
#endif /* INTERNAL_BUILD */
}
(*env)->GetStringUTFRegion(env, val, 0, length, convertionBuffer);
return convertionBuffer;
}
static void throw_exception(JNIEnv *env, const char* name, const char* message) static void throw_exception(JNIEnv *env, const char* name, const char* message)
{ {
...@@ -411,33 +311,43 @@ static void* dl_symbol_gthread(const char* name) ...@@ -411,33 +311,43 @@ static void* dl_symbol_gthread(const char* name)
return result; return result;
} }
gboolean gtk2_check_version() gboolean gtk2_check(const char* lib_name, gboolean load)
{ {
if (gtk2_libhandle != NULL) { if (gtk2_libhandle != NULL) {
/* We've already successfully opened the GTK libs, so return true. */ /* We've already successfully opened the GTK libs, so return true. */
return TRUE; return TRUE;
} else { } else {
void *lib = NULL; void *lib = NULL;
gboolean result = FALSE; #ifdef RTLD_NOLOAD
/* Just check if gtk libs are already in the process space */
lib = dlopen(lib_name, RTLD_LAZY | RTLD_NOLOAD);
if (!load || lib != NULL) {
return lib != NULL;
}
#else
#ifdef _AIX
/* On AIX we could implement this with the help of loadquery(L_GETINFO, ..) */
/* (see reload_table() in hotspot/src/os/aix/vm/loadlib_aix.cpp) but it is */
/* probably not worth it because most AIX servers don't have GTK libs anyway */
#endif
#endif
lib = dlopen(lib_name, RTLD_LAZY | RTLD_LOCAL);
lib = dlopen(GTK2_LIB_VERSIONED, RTLD_LAZY | RTLD_LOCAL);
if (lib == NULL) {
lib = dlopen(GTK2_LIB, RTLD_LAZY | RTLD_LOCAL);
if (lib == NULL) { if (lib == NULL) {
return FALSE; return FALSE;
} }
}
fp_gtk_check_version = dlsym(lib, "gtk_check_version"); fp_gtk_check_version = dlsym(lib, "gtk_check_version");
/* Check for GTK 2.2+ */ /* Check for GTK 2.2+ */
if (!fp_gtk_check_version(2, 2, 0)) { if (!fp_gtk_check_version(2, 2, 0)) {
result = TRUE; return TRUE;
} }
// 8048289: workaround for https://bugzilla.gnome.org/show_bug.cgi?id=733065 // 8048289: workaround for https://bugzilla.gnome.org/show_bug.cgi?id=733065
// dlclose(lib); // dlclose(lib);
return result; return FALSE;
} }
} }
...@@ -453,7 +363,7 @@ do { \ ...@@ -453,7 +363,7 @@ do { \
} while(0); } while(0);
void update_supported_actions(JNIEnv *env) { static void update_supported_actions(JNIEnv *env) {
GVfs * (*fp_g_vfs_get_default) (void); GVfs * (*fp_g_vfs_get_default) (void);
const gchar * const * (*fp_g_vfs_get_supported_uri_schemes) (GVfs * vfs); const gchar * const * (*fp_g_vfs_get_supported_uri_schemes) (GVfs * vfs);
const gchar * const * schemes = NULL; const gchar * const * schemes = NULL;
...@@ -516,7 +426,7 @@ void update_supported_actions(JNIEnv *env) { ...@@ -516,7 +426,7 @@ void update_supported_actions(JNIEnv *env) {
/** /**
* Functions for awt_Desktop.c * Functions for awt_Desktop.c
*/ */
gboolean gtk2_show_uri_load(JNIEnv *env) { static gboolean gtk2_show_uri_load(JNIEnv *env) {
gboolean success = FALSE; gboolean success = FALSE;
dlerror(); dlerror();
const char *gtk_version = fp_gtk_check_version(2, 14, 0); const char *gtk_version = fp_gtk_check_version(2, 14, 0);
...@@ -540,6 +450,7 @@ gboolean gtk2_show_uri_load(JNIEnv *env) { ...@@ -540,6 +450,7 @@ gboolean gtk2_show_uri_load(JNIEnv *env) {
fprintf(stderr, "dlsym(gtk_show_uri) returned NULL\n"); fprintf(stderr, "dlsym(gtk_show_uri) returned NULL\n");
#endif /* INTERNAL_BUILD */ #endif /* INTERNAL_BUILD */
} else { } else {
gtk->gtk_show_uri = fp_gtk_show_uri;
update_supported_actions(env); update_supported_actions(env);
success = TRUE; success = TRUE;
} }
...@@ -550,7 +461,7 @@ gboolean gtk2_show_uri_load(JNIEnv *env) { ...@@ -550,7 +461,7 @@ gboolean gtk2_show_uri_load(JNIEnv *env) {
/** /**
* Functions for sun_awt_X11_GtkFileDialogPeer.c * Functions for sun_awt_X11_GtkFileDialogPeer.c
*/ */
void gtk2_file_chooser_load() static void gtk2_file_chooser_load()
{ {
fp_gtk_file_chooser_get_filename = dl_symbol( fp_gtk_file_chooser_get_filename = dl_symbol(
"gtk_file_chooser_get_filename"); "gtk_file_chooser_get_filename");
...@@ -578,7 +489,7 @@ void gtk2_file_chooser_load() ...@@ -578,7 +489,7 @@ void gtk2_file_chooser_load()
fp_gtk_g_slist_length = dl_symbol("g_slist_length"); fp_gtk_g_slist_length = dl_symbol("g_slist_length");
} }
gboolean gtk2_load(JNIEnv *env) GtkApi* gtk2_load(JNIEnv *env, const char* lib_name)
{ {
gboolean result; gboolean result;
int i; int i;
...@@ -586,10 +497,8 @@ gboolean gtk2_load(JNIEnv *env) ...@@ -586,10 +497,8 @@ gboolean gtk2_load(JNIEnv *env)
int (*io_handler)(); int (*io_handler)();
char *gtk_modules_env; char *gtk_modules_env;
gtk2_libhandle = dlopen(GTK2_LIB_VERSIONED, RTLD_LAZY | RTLD_LOCAL); gtk2_libhandle = dlopen(lib_name, RTLD_LAZY | RTLD_LOCAL);
if (gtk2_libhandle == NULL) { if (gtk2_libhandle == NULL) {
gtk2_libhandle = dlopen(GTK2_LIB, RTLD_LAZY | RTLD_LOCAL);
if (gtk2_libhandle == NULL)
return FALSE; return FALSE;
} }
...@@ -931,7 +840,12 @@ gboolean gtk2_load(JNIEnv *env) ...@@ -931,7 +840,12 @@ gboolean gtk2_load(JNIEnv *env)
gtk2_widgets[i] = NULL; gtk2_widgets[i] = NULL;
} }
return result; if (result) {
GtkApi* gtk = (GtkApi*)malloc(sizeof(GtkApi));
gtk2_init(gtk);
return gtk;
}
return NULL;
} }
int gtk2_unload() int gtk2_unload()
...@@ -975,7 +889,7 @@ int gtk2_unload() ...@@ -975,7 +889,7 @@ int gtk2_unload()
/* Dispatch all pending events from the GTK event loop. /* Dispatch all pending events from the GTK event loop.
* This is needed to catch theme change and update widgets' style. * This is needed to catch theme change and update widgets' style.
*/ */
void flush_gtk_event_loop() static void flush_gtk_event_loop()
{ {
while( (*fp_g_main_context_iteration)(NULL, FALSE)); while( (*fp_g_main_context_iteration)(NULL, FALSE));
} }
...@@ -1024,7 +938,7 @@ static void init_containers() ...@@ -1024,7 +938,7 @@ static void init_containers()
* comparing results. This can be optimized by using subclassed pixmap and * comparing results. This can be optimized by using subclassed pixmap and
* doing the second drawing only if necessary. * doing the second drawing only if necessary.
*/ */
void gtk2_init_painting(JNIEnv *env, gint width, gint height) static void gtk2_init_painting(JNIEnv *env, gint width, gint height)
{ {
GdkGC *gc; GdkGC *gc;
GdkPixbuf *white, *black; GdkPixbuf *white, *black;
...@@ -1084,7 +998,7 @@ void gtk2_init_painting(JNIEnv *env, gint width, gint height) ...@@ -1084,7 +998,7 @@ void gtk2_init_painting(JNIEnv *env, gint width, gint height)
* one of java_awt_Transparency_OPAQUE, java_awt_Transparency_BITMASK, and * one of java_awt_Transparency_OPAQUE, java_awt_Transparency_BITMASK, and
* java_awt_Transparency_TRANSLUCENT. * java_awt_Transparency_TRANSLUCENT.
*/ */
gint gtk2_copy_image(gint *dst, gint width, gint height) static gint gtk2_copy_image(gint *dst, gint width, gint height)
{ {
gint i, j, r, g, b; gint i, j, r, g, b;
guchar *white, *black; guchar *white, *black;
...@@ -1746,7 +1660,7 @@ void gtk2_paint_arrow(WidgetType widget_type, GtkStateType state_type, ...@@ -1746,7 +1660,7 @@ void gtk2_paint_arrow(WidgetType widget_type, GtkStateType state_type,
x, y, w, h); x, y, w, h);
} }
void gtk2_paint_box(WidgetType widget_type, GtkStateType state_type, static void gtk2_paint_box(WidgetType widget_type, GtkStateType state_type,
GtkShadowType shadow_type, const gchar *detail, GtkShadowType shadow_type, const gchar *detail,
gint x, gint y, gint width, gint height, gint x, gint y, gint width, gint height,
gint synth_state, GtkTextDirection dir) gint synth_state, GtkTextDirection dir)
...@@ -1916,7 +1830,7 @@ void gtk2_paint_box_gap(WidgetType widget_type, GtkStateType state_type, ...@@ -1916,7 +1830,7 @@ void gtk2_paint_box_gap(WidgetType widget_type, GtkStateType state_type,
x, y, width, height, gap_side, gap_x, gap_width); x, y, width, height, gap_side, gap_x, gap_width);
} }
void gtk2_paint_check(WidgetType widget_type, gint synth_state, static void gtk2_paint_check(WidgetType widget_type, gint synth_state,
const gchar *detail, gint x, gint y, gint width, gint height) const gchar *detail, gint x, gint y, gint width, gint height)
{ {
GtkStateType state_type = get_gtk_state_type(widget_type, synth_state); GtkStateType state_type = get_gtk_state_type(widget_type, synth_state);
...@@ -1933,7 +1847,7 @@ void gtk2_paint_check(WidgetType widget_type, gint synth_state, ...@@ -1933,7 +1847,7 @@ void gtk2_paint_check(WidgetType widget_type, gint synth_state,
x, y, width, height); x, y, width, height);
} }
void gtk2_paint_diamond(WidgetType widget_type, GtkStateType state_type, static void gtk2_paint_diamond(WidgetType widget_type, GtkStateType state_type,
GtkShadowType shadow_type, const gchar *detail, GtkShadowType shadow_type, const gchar *detail,
gint x, gint y, gint width, gint height) gint x, gint y, gint width, gint height)
{ {
...@@ -1946,7 +1860,7 @@ void gtk2_paint_diamond(WidgetType widget_type, GtkStateType state_type, ...@@ -1946,7 +1860,7 @@ void gtk2_paint_diamond(WidgetType widget_type, GtkStateType state_type,
x, y, width, height); x, y, width, height);
} }
void gtk2_paint_expander(WidgetType widget_type, GtkStateType state_type, static void gtk2_paint_expander(WidgetType widget_type, GtkStateType state_type,
const gchar *detail, gint x, gint y, gint width, gint height, const gchar *detail, gint x, gint y, gint width, gint height,
GtkExpanderStyle expander_style) GtkExpanderStyle expander_style)
{ {
...@@ -1959,7 +1873,7 @@ void gtk2_paint_expander(WidgetType widget_type, GtkStateType state_type, ...@@ -1959,7 +1873,7 @@ void gtk2_paint_expander(WidgetType widget_type, GtkStateType state_type,
x + width / 2, y + height / 2, expander_style); x + width / 2, y + height / 2, expander_style);
} }
void gtk2_paint_extension(WidgetType widget_type, GtkStateType state_type, static void gtk2_paint_extension(WidgetType widget_type, GtkStateType state_type,
GtkShadowType shadow_type, const gchar *detail, GtkShadowType shadow_type, const gchar *detail,
gint x, gint y, gint width, gint height, GtkPositionType gap_side) gint x, gint y, gint width, gint height, GtkPositionType gap_side)
{ {
...@@ -1972,7 +1886,7 @@ void gtk2_paint_extension(WidgetType widget_type, GtkStateType state_type, ...@@ -1972,7 +1886,7 @@ void gtk2_paint_extension(WidgetType widget_type, GtkStateType state_type,
x, y, width, height, gap_side); x, y, width, height, gap_side);
} }
void gtk2_paint_flat_box(WidgetType widget_type, GtkStateType state_type, static void gtk2_paint_flat_box(WidgetType widget_type, GtkStateType state_type,
GtkShadowType shadow_type, const gchar *detail, GtkShadowType shadow_type, const gchar *detail,
gint x, gint y, gint width, gint height, gboolean has_focus) gint x, gint y, gint width, gint height, gboolean has_focus)
{ {
...@@ -1991,7 +1905,7 @@ void gtk2_paint_flat_box(WidgetType widget_type, GtkStateType state_type, ...@@ -1991,7 +1905,7 @@ void gtk2_paint_flat_box(WidgetType widget_type, GtkStateType state_type,
x, y, width, height); x, y, width, height);
} }
void gtk2_paint_focus(WidgetType widget_type, GtkStateType state_type, static void gtk2_paint_focus(WidgetType widget_type, GtkStateType state_type,
const char *detail, gint x, gint y, gint width, gint height) const char *detail, gint x, gint y, gint width, gint height)
{ {
gtk2_widget = gtk2_get_widget(widget_type); gtk2_widget = gtk2_get_widget(widget_type);
...@@ -2001,7 +1915,7 @@ void gtk2_paint_focus(WidgetType widget_type, GtkStateType state_type, ...@@ -2001,7 +1915,7 @@ void gtk2_paint_focus(WidgetType widget_type, GtkStateType state_type,
NULL, gtk2_widget, detail, x, y, width, height); NULL, gtk2_widget, detail, x, y, width, height);
} }
void gtk2_paint_handle(WidgetType widget_type, GtkStateType state_type, static void gtk2_paint_handle(WidgetType widget_type, GtkStateType state_type,
GtkShadowType shadow_type, const gchar *detail, GtkShadowType shadow_type, const gchar *detail,
gint x, gint y, gint width, gint height, GtkOrientation orientation) gint x, gint y, gint width, gint height, GtkOrientation orientation)
{ {
...@@ -2014,7 +1928,7 @@ void gtk2_paint_handle(WidgetType widget_type, GtkStateType state_type, ...@@ -2014,7 +1928,7 @@ void gtk2_paint_handle(WidgetType widget_type, GtkStateType state_type,
x, y, width, height, orientation); x, y, width, height, orientation);
} }
void gtk2_paint_hline(WidgetType widget_type, GtkStateType state_type, static void gtk2_paint_hline(WidgetType widget_type, GtkStateType state_type,
const gchar *detail, gint x, gint y, gint width, gint height) const gchar *detail, gint x, gint y, gint width, gint height)
{ {
gtk2_widget = gtk2_get_widget(widget_type); gtk2_widget = gtk2_get_widget(widget_type);
...@@ -2024,7 +1938,7 @@ void gtk2_paint_hline(WidgetType widget_type, GtkStateType state_type, ...@@ -2024,7 +1938,7 @@ void gtk2_paint_hline(WidgetType widget_type, GtkStateType state_type,
NULL, gtk2_widget, detail, x, x + width, y); NULL, gtk2_widget, detail, x, x + width, y);
} }
void gtk2_paint_option(WidgetType widget_type, gint synth_state, static void gtk2_paint_option(WidgetType widget_type, gint synth_state,
const gchar *detail, gint x, gint y, gint width, gint height) const gchar *detail, gint x, gint y, gint width, gint height)
{ {
GtkStateType state_type = get_gtk_state_type(widget_type, synth_state); GtkStateType state_type = get_gtk_state_type(widget_type, synth_state);
...@@ -2041,7 +1955,7 @@ void gtk2_paint_option(WidgetType widget_type, gint synth_state, ...@@ -2041,7 +1955,7 @@ void gtk2_paint_option(WidgetType widget_type, gint synth_state,
x, y, width, height); x, y, width, height);
} }
void gtk2_paint_shadow(WidgetType widget_type, GtkStateType state_type, static void gtk2_paint_shadow(WidgetType widget_type, GtkStateType state_type,
GtkShadowType shadow_type, const gchar *detail, GtkShadowType shadow_type, const gchar *detail,
gint x, gint y, gint width, gint height, gint x, gint y, gint width, gint height,
gint synth_state, GtkTextDirection dir) gint synth_state, GtkTextDirection dir)
...@@ -2091,9 +2005,10 @@ void gtk2_paint_shadow(WidgetType widget_type, GtkStateType state_type, ...@@ -2091,9 +2005,10 @@ void gtk2_paint_shadow(WidgetType widget_type, GtkStateType state_type,
gtk2_set_direction(gtk2_widget, GTK_TEXT_DIR_LTR); gtk2_set_direction(gtk2_widget, GTK_TEXT_DIR_LTR);
} }
void gtk2_paint_slider(WidgetType widget_type, GtkStateType state_type, static void gtk2_paint_slider(WidgetType widget_type, GtkStateType state_type,
GtkShadowType shadow_type, const gchar *detail, GtkShadowType shadow_type, const gchar *detail,
gint x, gint y, gint width, gint height, GtkOrientation orientation) gint x, gint y, gint width, gint height, GtkOrientation orientation,
gboolean has_focus)
{ {
gtk2_widget = gtk2_get_widget(widget_type); gtk2_widget = gtk2_get_widget(widget_type);
(*fp_gtk_paint_slider)(gtk2_widget->style, gtk2_white_pixmap, state_type, (*fp_gtk_paint_slider)(gtk2_widget->style, gtk2_white_pixmap, state_type,
...@@ -2104,7 +2019,7 @@ void gtk2_paint_slider(WidgetType widget_type, GtkStateType state_type, ...@@ -2104,7 +2019,7 @@ void gtk2_paint_slider(WidgetType widget_type, GtkStateType state_type,
x, y, width, height, orientation); x, y, width, height, orientation);
} }
void gtk2_paint_vline(WidgetType widget_type, GtkStateType state_type, static void gtk2_paint_vline(WidgetType widget_type, GtkStateType state_type,
const gchar *detail, gint x, gint y, gint width, gint height) const gchar *detail, gint x, gint y, gint width, gint height)
{ {
gtk2_widget = gtk2_get_widget(widget_type); gtk2_widget = gtk2_get_widget(widget_type);
...@@ -2114,7 +2029,7 @@ void gtk2_paint_vline(WidgetType widget_type, GtkStateType state_type, ...@@ -2114,7 +2029,7 @@ void gtk2_paint_vline(WidgetType widget_type, GtkStateType state_type,
NULL, gtk2_widget, detail, y, y + height, x); NULL, gtk2_widget, detail, y, y + height, x);
} }
void gtk_paint_background(WidgetType widget_type, GtkStateType state_type, static void gtk_paint_background(WidgetType widget_type, GtkStateType state_type,
gint x, gint y, gint width, gint height) gint x, gint y, gint width, gint height)
{ {
gtk2_widget = gtk2_get_widget(widget_type); gtk2_widget = gtk2_get_widget(widget_type);
...@@ -2124,7 +2039,7 @@ void gtk_paint_background(WidgetType widget_type, GtkStateType state_type, ...@@ -2124,7 +2039,7 @@ void gtk_paint_background(WidgetType widget_type, GtkStateType state_type,
gtk2_black_pixmap, TRUE, state_type, NULL, x, y, width, height); gtk2_black_pixmap, TRUE, state_type, NULL, x, y, width, height);
} }
GdkPixbuf *gtk2_get_stock_icon(gint widget_type, const gchar *stock_id, static GdkPixbuf *gtk2_get_stock_icon(gint widget_type, const gchar *stock_id,
GtkIconSize size, GtkTextDirection direction, const char *detail) GtkIconSize size, GtkTextDirection direction, const char *detail)
{ {
init_containers(); init_containers();
...@@ -2134,8 +2049,52 @@ GdkPixbuf *gtk2_get_stock_icon(gint widget_type, const gchar *stock_id, ...@@ -2134,8 +2049,52 @@ GdkPixbuf *gtk2_get_stock_icon(gint widget_type, const gchar *stock_id,
return (*fp_gtk_widget_render_icon)(gtk2_widget, stock_id, size, detail); return (*fp_gtk_widget_render_icon)(gtk2_widget, stock_id, size, detail);
} }
static jboolean gtk2_get_pixbuf_data(JNIEnv *env, GdkPixbuf* pixbuf,
jmethodID icon_upcall_method, jobject this) {
if (!pixbuf) {
return JNI_FALSE;
}
guchar *pixbuf_data = (*fp_gdk_pixbuf_get_pixels)(pixbuf);
if (pixbuf_data) {
int row_stride = (*fp_gdk_pixbuf_get_rowstride)(pixbuf);
int width = (*fp_gdk_pixbuf_get_width)(pixbuf);
int height = (*fp_gdk_pixbuf_get_height)(pixbuf);
int bps = (*fp_gdk_pixbuf_get_bits_per_sample)(pixbuf);
int channels = (*fp_gdk_pixbuf_get_n_channels)(pixbuf);
gboolean alpha = (*fp_gdk_pixbuf_get_has_alpha)(pixbuf);
jbyteArray data = (*env)->NewByteArray(env, (row_stride * height));
JNU_CHECK_EXCEPTION_RETURN(env, JNI_FALSE);
(*env)->SetByteArrayRegion(env, data, 0, (row_stride * height),
(jbyte *)pixbuf_data);
(*fp_g_object_unref)(pixbuf);
/* Call the callback method to create the image on the Java side. */
(*env)->CallVoidMethod(env, this, icon_upcall_method, data,
width, height, row_stride, bps, channels, alpha);
return JNI_TRUE;
}
return JNI_FALSE;
}
static jboolean gtk2_get_file_icon_data(JNIEnv *env, const char *filename,
GError **error, jmethodID icon_upcall_method, jobject this) {
GdkPixbuf* pixbuf = fp_gdk_pixbuf_new_from_file(filename, error);
return gtk2_get_pixbuf_data(env, pixbuf, icon_upcall_method, this);
}
static jboolean gtk2_get_icon_data(JNIEnv *env, gint widget_type,
const gchar *stock_id, GtkIconSize size,
GtkTextDirection direction, const char *detail,
jmethodID icon_upcall_method, jobject this) {
GdkPixbuf* pixbuf = gtk2_get_stock_icon(widget_type, stock_id, size,
direction, detail);
return gtk2_get_pixbuf_data(env, pixbuf, icon_upcall_method, this);
}
/*************************************************/ /*************************************************/
gint gtk2_get_xthickness(JNIEnv *env, WidgetType widget_type) static gint gtk2_get_xthickness(JNIEnv *env, WidgetType widget_type)
{ {
init_containers(); init_containers();
...@@ -2144,7 +2103,7 @@ gint gtk2_get_xthickness(JNIEnv *env, WidgetType widget_type) ...@@ -2144,7 +2103,7 @@ gint gtk2_get_xthickness(JNIEnv *env, WidgetType widget_type)
return style->xthickness; return style->xthickness;
} }
gint gtk2_get_ythickness(JNIEnv *env, WidgetType widget_type) static gint gtk2_get_ythickness(JNIEnv *env, WidgetType widget_type)
{ {
init_containers(); init_containers();
...@@ -2154,12 +2113,12 @@ gint gtk2_get_ythickness(JNIEnv *env, WidgetType widget_type) ...@@ -2154,12 +2113,12 @@ gint gtk2_get_ythickness(JNIEnv *env, WidgetType widget_type)
} }
/*************************************************/ /*************************************************/
guint8 recode_color(guint16 channel) static guint8 recode_color(guint16 channel)
{ {
return (guint8)(channel>>8); return (guint8)(channel>>8);
} }
gint gtk2_get_color_for_state(JNIEnv *env, WidgetType widget_type, static gint gtk2_get_color_for_state(JNIEnv *env, WidgetType widget_type,
GtkStateType state_type, ColorType color_type) GtkStateType state_type, ColorType color_type)
{ {
gint result = 0; gint result = 0;
...@@ -2211,19 +2170,19 @@ gint gtk2_get_color_for_state(JNIEnv *env, WidgetType widget_type, ...@@ -2211,19 +2170,19 @@ gint gtk2_get_color_for_state(JNIEnv *env, WidgetType widget_type,
} }
/*************************************************/ /*************************************************/
jobject create_Boolean(JNIEnv *env, jboolean boolean_value); static jobject create_Boolean(JNIEnv *env, jboolean boolean_value);
jobject create_Integer(JNIEnv *env, jint int_value); static jobject create_Integer(JNIEnv *env, jint int_value);
jobject create_Long(JNIEnv *env, jlong long_value); static jobject create_Long(JNIEnv *env, jlong long_value);
jobject create_Float(JNIEnv *env, jfloat float_value); static jobject create_Float(JNIEnv *env, jfloat float_value);
jobject create_Double(JNIEnv *env, jdouble double_value); static jobject create_Double(JNIEnv *env, jdouble double_value);
jobject create_Character(JNIEnv *env, jchar char_value); static jobject create_Character(JNIEnv *env, jchar char_value);
jobject create_Insets(JNIEnv *env, GtkBorder *border); static jobject create_Insets(JNIEnv *env, GtkBorder *border);
jobject gtk2_get_class_value(JNIEnv *env, WidgetType widget_type, jstring jkey) static jobject gtk2_get_class_value(JNIEnv *env, WidgetType widget_type,
const char* key)
{ {
init_containers(); init_containers();
const char* key = getStrFor(env, jkey);
gtk2_widget = gtk2_get_widget(widget_type); gtk2_widget = gtk2_get_widget(widget_type);
GValue value; GValue value;
...@@ -2344,7 +2303,7 @@ jobject gtk2_get_class_value(JNIEnv *env, WidgetType widget_type, jstring jkey) ...@@ -2344,7 +2303,7 @@ jobject gtk2_get_class_value(JNIEnv *env, WidgetType widget_type, jstring jkey)
return NULL; return NULL;
} }
void gtk2_set_range_value(WidgetType widget_type, jdouble value, static void gtk2_set_range_value(WidgetType widget_type, jdouble value,
jdouble min, jdouble max, jdouble visible) jdouble min, jdouble max, jdouble visible)
{ {
GtkAdjustment *adj; GtkAdjustment *adj;
...@@ -2359,7 +2318,7 @@ void gtk2_set_range_value(WidgetType widget_type, jdouble value, ...@@ -2359,7 +2318,7 @@ void gtk2_set_range_value(WidgetType widget_type, jdouble value,
} }
/*************************************************/ /*************************************************/
jobject create_Object(JNIEnv *env, jmethodID *cid, static jobject create_Object(JNIEnv *env, jmethodID *cid,
const char* class_name, const char* class_name,
const char* signature, const char* signature,
jvalue* value) jvalue* value)
...@@ -2462,7 +2421,7 @@ jobject create_Insets(JNIEnv *env, GtkBorder *border) ...@@ -2462,7 +2421,7 @@ jobject create_Insets(JNIEnv *env, GtkBorder *border)
} }
/*********************************************/ /*********************************************/
jstring gtk2_get_pango_font_name(JNIEnv *env, WidgetType widget_type) static jstring gtk2_get_pango_font_name(JNIEnv *env, WidgetType widget_type)
{ {
init_containers(); init_containers();
...@@ -2481,7 +2440,7 @@ jstring gtk2_get_pango_font_name(JNIEnv *env, WidgetType widget_type) ...@@ -2481,7 +2440,7 @@ jstring gtk2_get_pango_font_name(JNIEnv *env, WidgetType widget_type)
} }
/***********************************************/ /***********************************************/
jobject get_string_property(JNIEnv *env, GtkSettings* settings, const gchar* key) static jobject get_string_property(JNIEnv *env, GtkSettings* settings, const gchar* key)
{ {
jobject result = NULL; jobject result = NULL;
gchar* strval = NULL; gchar* strval = NULL;
...@@ -2493,21 +2452,21 @@ jobject get_string_property(JNIEnv *env, GtkSettings* settings, const gchar* key ...@@ -2493,21 +2452,21 @@ jobject get_string_property(JNIEnv *env, GtkSettings* settings, const gchar* key
return result; return result;
} }
jobject get_integer_property(JNIEnv *env, GtkSettings* settings, const gchar* key) static jobject get_integer_property(JNIEnv *env, GtkSettings* settings, const gchar* key)
{ {
gint intval = NULL; gint intval = 0;
(*fp_g_object_get)(settings, key, &intval, NULL); (*fp_g_object_get)(settings, key, &intval, NULL);
return create_Integer(env, intval); return create_Integer(env, intval);
} }
jobject get_boolean_property(JNIEnv *env, GtkSettings* settings, const gchar* key) static jobject get_boolean_property(JNIEnv *env, GtkSettings* settings, const gchar* key)
{ {
gint intval = NULL; gint intval = 0;
(*fp_g_object_get)(settings, key, &intval, NULL); (*fp_g_object_get)(settings, key, &intval, NULL);
return create_Boolean(env, intval); return create_Boolean(env, intval);
} }
jobject gtk2_get_setting(JNIEnv *env, Setting property) static jobject gtk2_get_setting(JNIEnv *env, Setting property)
{ {
GtkSettings* settings = (*fp_gtk_settings_get_default)(); GtkSettings* settings = (*fp_gtk_settings_get_default)();
...@@ -2525,3 +2484,87 @@ jobject gtk2_get_setting(JNIEnv *env, Setting property) ...@@ -2525,3 +2484,87 @@ jobject gtk2_get_setting(JNIEnv *env, Setting property)
return NULL; return NULL;
} }
static GdkWindow* gtk2_get_window(void *widget) {
return ((GtkWidget*)widget)->window;
}
void gtk2_init(GtkApi* gtk) {
gtk->version = GTK_2;
gtk->show_uri_load = &gtk2_show_uri_load;
gtk->unload = &gtk2_unload;
gtk->flush_event_loop = &flush_gtk_event_loop;
gtk->gtk_check_version = fp_gtk_check_version;
gtk->get_setting = &gtk2_get_setting;
gtk->paint_arrow = &gtk2_paint_arrow;
gtk->paint_box = &gtk2_paint_box;
gtk->paint_box_gap = &gtk2_paint_box_gap;
gtk->paint_expander = &gtk2_paint_expander;
gtk->paint_extension = &gtk2_paint_extension;
gtk->paint_flat_box = &gtk2_paint_flat_box;
gtk->paint_focus = &gtk2_paint_focus;
gtk->paint_handle = &gtk2_paint_handle;
gtk->paint_hline = &gtk2_paint_hline;
gtk->paint_vline = &gtk2_paint_vline;
gtk->paint_option = &gtk2_paint_option;
gtk->paint_shadow = &gtk2_paint_shadow;
gtk->paint_slider = &gtk2_paint_slider;
gtk->paint_background = &gtk_paint_background;
gtk->paint_check = &gtk2_paint_check;
gtk->set_range_value = &gtk2_set_range_value;
gtk->init_painting = &gtk2_init_painting;
gtk->copy_image = &gtk2_copy_image;
gtk->get_xthickness = &gtk2_get_xthickness;
gtk->get_ythickness = &gtk2_get_ythickness;
gtk->get_color_for_state = &gtk2_get_color_for_state;
gtk->get_class_value = &gtk2_get_class_value;
gtk->get_pango_font_name = &gtk2_get_pango_font_name;
gtk->get_icon_data = &gtk2_get_icon_data;
gtk->get_file_icon_data = &gtk2_get_file_icon_data;
gtk->gdk_threads_enter = fp_gdk_threads_enter;
gtk->gdk_threads_leave = fp_gdk_threads_leave;
gtk->gtk_show_uri = fp_gtk_show_uri;
gtk->g_free = fp_g_free;
gtk->gtk_file_chooser_get_filename = fp_gtk_file_chooser_get_filename;
gtk->gtk_widget_hide = fp_gtk_widget_hide;
gtk->gtk_main_quit = fp_gtk_main_quit;
gtk->gtk_file_chooser_dialog_new = fp_gtk_file_chooser_dialog_new;
gtk->gtk_file_chooser_set_current_folder =
fp_gtk_file_chooser_set_current_folder;
gtk->gtk_file_chooser_set_filename = fp_gtk_file_chooser_set_filename;
gtk->gtk_file_chooser_set_current_name =
fp_gtk_file_chooser_set_current_name;
gtk->gtk_file_filter_add_custom = fp_gtk_file_filter_add_custom;
gtk->gtk_file_chooser_set_filter = fp_gtk_file_chooser_set_filter;
gtk->gtk_file_chooser_get_type = fp_gtk_file_chooser_get_type;
gtk->gtk_file_filter_new = fp_gtk_file_filter_new;
gtk->gtk_file_chooser_set_do_overwrite_confirmation =
fp_gtk_file_chooser_set_do_overwrite_confirmation;
gtk->gtk_file_chooser_set_select_multiple =
fp_gtk_file_chooser_set_select_multiple;
gtk->gtk_file_chooser_get_current_folder =
fp_gtk_file_chooser_get_current_folder;
gtk->gtk_file_chooser_get_filenames = fp_gtk_file_chooser_get_filenames;
gtk->gtk_g_slist_length = fp_gtk_g_slist_length;
gtk->g_signal_connect_data = fp_g_signal_connect_data;
gtk->gtk_widget_show = fp_gtk_widget_show;
gtk->gtk_main = fp_gtk_main;
gtk->gtk_main_level = fp_gtk_main_level;
gtk->g_path_get_dirname = fp_g_path_get_dirname;
gtk->gtk_widget_destroy = fp_gtk_widget_destroy;
gtk->gtk_window_present = fp_gtk_window_present;
gtk->gtk_window_move = fp_gtk_window_move;
gtk->gtk_window_resize = fp_gtk_window_resize;
gtk->get_window = &gtk2_get_window;
gtk->g_object_unref = fp_g_object_unref;
gtk->g_list_append = fp_g_list_append;
gtk->g_list_free = fp_g_list_free;
gtk->g_list_free_full = fp_g_list_free_full;
}
/* /*
* Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -27,232 +27,11 @@ ...@@ -27,232 +27,11 @@
#include <stdlib.h> #include <stdlib.h>
#include <jni.h> #include <jni.h>
#include "gtk_interface.h"
#define _G_TYPE_CIC(ip, gt, ct) ((ct*) ip)
#define G_TYPE_CHECK_INSTANCE_CAST(instance, g_type, c_type) (_G_TYPE_CIC ((instance), (g_type), c_type))
#define GTK_TYPE_FILE_CHOOSER (fp_gtk_file_chooser_get_type ())
#define GTK_FILE_CHOOSER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_FILE_CHOOSER, GtkFileChooser))
#define fp_g_signal_connect(instance, detailed_signal, c_handler, data) \
fp_g_signal_connect_data ((instance), (detailed_signal), (c_handler), (data), NULL, (GConnectFlags) 0)
#define G_CALLBACK(f) ((GCallback) (f))
#define G_TYPE_FUNDAMENTAL_SHIFT (2)
#define G_TYPE_MAKE_FUNDAMENTAL(x) ((GType) ((x) << G_TYPE_FUNDAMENTAL_SHIFT))
#define G_TYPE_OBJECT G_TYPE_MAKE_FUNDAMENTAL (20)
#define G_OBJECT(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), G_TYPE_OBJECT, GObject))
#define GTK_STOCK_CANCEL "gtk-cancel"
#define GTK_STOCK_SAVE "gtk-save"
#define GTK_STOCK_OPEN "gtk-open"
#define GDK_CURRENT_TIME 0L
typedef enum _WidgetType
{
BUTTON, /* GtkButton */
CHECK_BOX, /* GtkCheckButton */
CHECK_BOX_MENU_ITEM, /* GtkCheckMenuItem */
COLOR_CHOOSER, /* GtkColorSelectionDialog */
COMBO_BOX, /* GtkComboBox */
COMBO_BOX_ARROW_BUTTON, /* GtkComboBoxEntry */
COMBO_BOX_TEXT_FIELD, /* GtkComboBoxEntry */
DESKTOP_ICON, /* GtkLabel */
DESKTOP_PANE, /* GtkContainer */
EDITOR_PANE, /* GtkTextView */
FORMATTED_TEXT_FIELD, /* GtkEntry */
HANDLE_BOX, /* GtkHandleBox */
HPROGRESS_BAR, /* GtkProgressBar */
HSCROLL_BAR, /* GtkHScrollbar */
HSCROLL_BAR_BUTTON_LEFT, /* GtkHScrollbar */
HSCROLL_BAR_BUTTON_RIGHT, /* GtkHScrollbar */
HSCROLL_BAR_TRACK, /* GtkHScrollbar */
HSCROLL_BAR_THUMB, /* GtkHScrollbar */
HSEPARATOR, /* GtkHSeparator */
HSLIDER, /* GtkHScale */
HSLIDER_TRACK, /* GtkHScale */
HSLIDER_THUMB, /* GtkHScale */
HSPLIT_PANE_DIVIDER, /* GtkHPaned */
INTERNAL_FRAME, /* GtkWindow */
INTERNAL_FRAME_TITLE_PANE, /* GtkLabel */
IMAGE, /* GtkImage */
LABEL, /* GtkLabel */
LIST, /* GtkTreeView */
MENU, /* GtkMenu */
MENU_BAR, /* GtkMenuBar */
MENU_ITEM, /* GtkMenuItem */
MENU_ITEM_ACCELERATOR, /* GtkLabel */
OPTION_PANE, /* GtkMessageDialog */
PANEL, /* GtkContainer */
PASSWORD_FIELD, /* GtkEntry */
POPUP_MENU, /* GtkMenu */
POPUP_MENU_SEPARATOR, /* GtkSeparatorMenuItem */
RADIO_BUTTON, /* GtkRadioButton */
RADIO_BUTTON_MENU_ITEM, /* GtkRadioMenuItem */
ROOT_PANE, /* GtkContainer */
SCROLL_PANE, /* GtkScrolledWindow */
SPINNER, /* GtkSpinButton */
SPINNER_ARROW_BUTTON, /* GtkSpinButton */
SPINNER_TEXT_FIELD, /* GtkSpinButton */
SPLIT_PANE, /* GtkPaned */
TABBED_PANE, /* GtkNotebook */
TABBED_PANE_TAB_AREA, /* GtkNotebook */
TABBED_PANE_CONTENT, /* GtkNotebook */
TABBED_PANE_TAB, /* GtkNotebook */
TABLE, /* GtkTreeView */
TABLE_HEADER, /* GtkButton */
TEXT_AREA, /* GtkTextView */
TEXT_FIELD, /* GtkEntry */
TEXT_PANE, /* GtkTextView */
TITLED_BORDER, /* GtkFrame */
TOGGLE_BUTTON, /* GtkToggleButton */
TOOL_BAR, /* GtkToolbar */
TOOL_BAR_DRAG_WINDOW, /* GtkToolbar */
TOOL_BAR_SEPARATOR, /* GtkSeparatorToolItem */
TOOL_TIP, /* GtkWindow */
TREE, /* GtkTreeView */
TREE_CELL, /* GtkTreeView */
VIEWPORT, /* GtkViewport */
VPROGRESS_BAR, /* GtkProgressBar */
VSCROLL_BAR, /* GtkVScrollbar */
VSCROLL_BAR_BUTTON_UP, /* GtkVScrollbar */
VSCROLL_BAR_BUTTON_DOWN, /* GtkVScrollbar */
VSCROLL_BAR_TRACK, /* GtkVScrollbar */
VSCROLL_BAR_THUMB, /* GtkVScrollbar */
VSEPARATOR, /* GtkVSeparator */
VSLIDER, /* GtkVScale */
VSLIDER_TRACK, /* GtkVScale */
VSLIDER_THUMB, /* GtkVScale */
VSPLIT_PANE_DIVIDER, /* GtkVPaned */
WIDGET_TYPE_SIZE
} WidgetType;
typedef enum _ColorType
{
FOREGROUND,
BACKGROUND,
TEXT_FOREGROUND,
TEXT_BACKGROUND,
FOCUS,
LIGHT,
DARK,
MID,
BLACK,
WHITE
} ColorType;
typedef enum _Setting
{
GTK_FONT_NAME,
GTK_ICON_SIZES,
GTK_CURSOR_BLINK,
GTK_CURSOR_BLINK_TIME
} Setting;
/* GTK types, here to eliminate need for GTK headers at compile time */
#ifndef FALSE
#define FALSE (0)
#define TRUE (!FALSE)
#endif
#define GTK_HAS_FOCUS (1 << 12) #define GTK_HAS_FOCUS (1 << 12)
#define GTK_HAS_DEFAULT (1 << 14) #define GTK_HAS_DEFAULT (1 << 14)
/* basic types */
typedef char gchar;
typedef short gshort;
typedef int gint;
typedef long glong;
typedef float gfloat;
typedef double gdouble;
typedef void* gpointer;
typedef gint gboolean;
typedef signed char gint8;
typedef signed short gint16;
typedef signed int gint32;
typedef unsigned char guchar;
typedef unsigned char guint8;
typedef unsigned short gushort;
typedef unsigned short guint16;
typedef unsigned int guint;
typedef unsigned int guint32;
typedef unsigned int gsize;
typedef unsigned long gulong;
typedef signed long long gint64;
typedef unsigned long long guint64;
/* enumerated constants */
typedef enum
{
GTK_ARROW_UP,
GTK_ARROW_DOWN,
GTK_ARROW_LEFT,
GTK_ARROW_RIGHT
} GtkArrowType;
typedef enum {
GDK_COLORSPACE_RGB
} GdkColorspace;
typedef enum
{
GTK_EXPANDER_COLLAPSED,
GTK_EXPANDER_SEMI_COLLAPSED,
GTK_EXPANDER_SEMI_EXPANDED,
GTK_EXPANDER_EXPANDED
} GtkExpanderStyle;
typedef enum
{
GTK_ICON_SIZE_INVALID,
GTK_ICON_SIZE_MENU,
GTK_ICON_SIZE_SMALL_TOOLBAR,
GTK_ICON_SIZE_LARGE_TOOLBAR,
GTK_ICON_SIZE_BUTTON,
GTK_ICON_SIZE_DND,
GTK_ICON_SIZE_DIALOG
} GtkIconSize;
typedef enum
{
GTK_ORIENTATION_HORIZONTAL,
GTK_ORIENTATION_VERTICAL
} GtkOrientation;
typedef enum
{
GTK_POS_LEFT,
GTK_POS_RIGHT,
GTK_POS_TOP,
GTK_POS_BOTTOM
} GtkPositionType;
typedef enum
{
GTK_SHADOW_NONE,
GTK_SHADOW_IN,
GTK_SHADOW_OUT,
GTK_SHADOW_ETCHED_IN,
GTK_SHADOW_ETCHED_OUT
} GtkShadowType;
typedef enum
{
GTK_STATE_NORMAL,
GTK_STATE_ACTIVE,
GTK_STATE_PRELIGHT,
GTK_STATE_SELECTED,
GTK_STATE_INSENSITIVE
} GtkStateType;
typedef enum
{
GTK_TEXT_DIR_NONE,
GTK_TEXT_DIR_LTR,
GTK_TEXT_DIR_RTL
} GtkTextDirection;
typedef enum typedef enum
{ {
GTK_WINDOW_TOPLEVEL, GTK_WINDOW_TOPLEVEL,
...@@ -270,24 +49,14 @@ typedef enum ...@@ -270,24 +49,14 @@ typedef enum
} GParamFlags; } GParamFlags;
/* We define all structure pointers to be void* */ /* We define all structure pointers to be void* */
typedef void GError;
typedef void GMainContext; typedef void GMainContext;
typedef void GVfs; typedef void GVfs;
typedef struct _GSList GSList;
struct _GSList
{
gpointer data;
GSList *next;
};
typedef void GdkColormap; typedef void GdkColormap;
typedef void GdkDrawable; typedef void GdkDrawable;
typedef void GdkGC; typedef void GdkGC;
typedef void GdkScreen;
typedef void GdkPixbuf; typedef void GdkPixbuf;
typedef void GdkPixmap; typedef void GdkPixmap;
typedef void GdkWindow;
typedef void GtkFixed; typedef void GtkFixed;
typedef void GtkMenuItem; typedef void GtkMenuItem;
...@@ -347,7 +116,6 @@ typedef struct { ...@@ -347,7 +116,6 @@ typedef struct {
* structures. This is a place where getting rid of gtk * structures. This is a place where getting rid of gtk
* headers may be dangerous. * headers may be dangerous.
******************************************************/ ******************************************************/
typedef gulong GType;
typedef struct typedef struct
{ {
...@@ -582,70 +350,6 @@ struct _GtkProgressBar ...@@ -582,70 +350,6 @@ struct _GtkProgressBar
guint ellipsize : 3; guint ellipsize : 3;
}; };
typedef enum {
GTK_RESPONSE_NONE = -1,
GTK_RESPONSE_REJECT = -2,
GTK_RESPONSE_ACCEPT = -3,
GTK_RESPONSE_DELETE_EVENT = -4,
GTK_RESPONSE_OK = -5,
GTK_RESPONSE_CANCEL = -6,
GTK_RESPONSE_CLOSE = -7,
GTK_RESPONSE_YES = -8,
GTK_RESPONSE_NO = -9,
GTK_RESPONSE_APPLY = -10,
GTK_RESPONSE_HELP = -11
} GtkResponseType;
typedef struct _GtkWindow GtkWindow;
typedef struct _GtkFileChooser GtkFileChooser;
typedef enum {
GTK_FILE_CHOOSER_ACTION_OPEN,
GTK_FILE_CHOOSER_ACTION_SAVE,
GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER
} GtkFileChooserAction;
typedef struct _GtkFileFilter GtkFileFilter;
typedef enum {
GTK_FILE_FILTER_FILENAME = 1 << 0,
GTK_FILE_FILTER_URI = 1 << 1,
GTK_FILE_FILTER_DISPLAY_NAME = 1 << 2,
GTK_FILE_FILTER_MIME_TYPE = 1 << 3
} GtkFileFilterFlags;
typedef struct {
GtkFileFilterFlags contains;
const gchar *filename;
const gchar *uri;
const gchar *display_name;
const gchar *mime_type;
} GtkFileFilterInfo;
typedef gboolean (*GtkFileFilterFunc)(const GtkFileFilterInfo *filter_info,
gpointer data);
typedef void (*GDestroyNotify)(gpointer data);
typedef void (*GCallback)(void);
typedef struct _GClosure GClosure;
typedef void (*GClosureNotify)(gpointer data, GClosure *closure);
typedef enum {
G_CONNECT_AFTER = 1 << 0, G_CONNECT_SWAPPED = 1 << 1
} GConnectFlags;
typedef struct _GThreadFunctions GThreadFunctions;
/*
* Converts java.lang.String object to UTF-8 character string.
*/
const char *getStrFor(JNIEnv *env, jstring value);
/** /**
* Returns : * Returns :
* NULL if the GLib library is compatible with the given version, or a string * NULL if the GLib library is compatible with the given version, or a string
...@@ -653,7 +357,7 @@ const char *getStrFor(JNIEnv *env, jstring value); ...@@ -653,7 +357,7 @@ const char *getStrFor(JNIEnv *env, jstring value);
* Please note that the glib_check_version() is available since 2.6, * Please note that the glib_check_version() is available since 2.6,
* so you should use GLIB_CHECK_VERSION macro instead. * so you should use GLIB_CHECK_VERSION macro instead.
*/ */
gchar* (*fp_glib_check_version)(guint required_major, guint required_minor, static gchar* (*fp_glib_check_version)(guint required_major, guint required_minor,
guint required_micro); guint required_micro);
/** /**
...@@ -663,176 +367,74 @@ gchar* (*fp_glib_check_version)(guint required_major, guint required_minor, ...@@ -663,176 +367,74 @@ gchar* (*fp_glib_check_version)(guint required_major, guint required_minor,
#define GLIB_CHECK_VERSION(major, minor, micro) \ #define GLIB_CHECK_VERSION(major, minor, micro) \
(fp_glib_check_version && fp_glib_check_version(major, minor, micro) == NULL) (fp_glib_check_version && fp_glib_check_version(major, minor, micro) == NULL)
/*
* Check whether the gtk2 library is available and meets the minimum
* version requirement. If the library is already loaded this method has no
* effect and returns success.
* Returns FALSE on failure and TRUE on success.
*/
gboolean gtk2_check_version();
/** /**
* Returns : * Returns :
* NULL if the GTK+ library is compatible with the given version, or a string * NULL if the GTK+ library is compatible with the given version, or a string
* describing the version mismatch. * describing the version mismatch.
*/ */
gchar* (*fp_gtk_check_version)(guint required_major, guint required_minor, static gchar* (*fp_gtk_check_version)(guint required_major, guint required_minor,
guint required_micro); guint required_micro);
/*
* Load the gtk2 library. If the library is already loaded this method has no
* effect and returns success.
* Returns FALSE on failure and TRUE on success.
*/
gboolean gtk2_load(JNIEnv *env);
/* static void gtk2_init(GtkApi* gtk);
* Loads fp_gtk_show_uri function pointer. This initialization is static void (*fp_g_free)(gpointer mem);
* separated because the function is required only static void (*fp_g_object_unref)(gpointer object);
* for java.awt.Desktop API. The function relies on initialization in
* gtk2_load, so it must be invoked only after a successful gtk2_load
* invocation
*/
gboolean gtk2_show_uri_load(JNIEnv *env);
/* static int (*fp_gdk_pixbuf_get_bits_per_sample)(const GdkPixbuf *pixbuf);
* Unload the gtk2 library. If the library is already unloaded this method has static guchar *(*fp_gdk_pixbuf_get_pixels)(const GdkPixbuf *pixbuf);
* no effect and returns success. static gboolean (*fp_gdk_pixbuf_get_has_alpha)(const GdkPixbuf *pixbuf);
* Returns FALSE on failure and TRUE on success. static int (*fp_gdk_pixbuf_get_height)(const GdkPixbuf *pixbuf);
*/ static int (*fp_gdk_pixbuf_get_n_channels)(const GdkPixbuf *pixbuf);
gboolean gtk2_unload(); static int (*fp_gdk_pixbuf_get_rowstride)(const GdkPixbuf *pixbuf);
static int (*fp_gdk_pixbuf_get_width)(const GdkPixbuf *pixbuf);
void gtk2_paint_arrow(WidgetType widget_type, GtkStateType state_type, static GdkPixbuf *(*fp_gdk_pixbuf_new_from_file)(const char *filename, GError **error);
GtkShadowType shadow_type, const gchar *detail,
gint x, gint y, gint width, gint height, static void (*fp_gtk_widget_destroy)(void *widget);
GtkArrowType arrow_type, gboolean fill); static void (*fp_gtk_window_present)(GtkWindow *window);
void gtk2_paint_box(WidgetType widget_type, GtkStateType state_type, static void (*fp_gtk_window_move)(GtkWindow *window, gint x, gint y);
GtkShadowType shadow_type, const gchar *detail, static void (*fp_gtk_window_resize)(GtkWindow *window, gint width, gint height);
gint x, gint y, gint width, gint height,
gint synth_state, GtkTextDirection dir);
void gtk2_paint_box_gap(WidgetType widget_type, GtkStateType state_type,
GtkShadowType shadow_type, const gchar *detail,
gint x, gint y, gint width, gint height,
GtkPositionType gap_side, gint gap_x, gint gap_width);
void gtk2_paint_check(WidgetType widget_type, gint synth_state,
const gchar *detail, gint x, gint y, gint width, gint height);
void gtk2_paint_diamond(WidgetType widget_type, GtkStateType state_type,
GtkShadowType shadow_type, const gchar *detail,
gint x, gint y, gint width, gint height);
void gtk2_paint_expander(WidgetType widget_type, GtkStateType state_type,
const gchar *detail, gint x, gint y, gint width, gint height,
GtkExpanderStyle expander_style);
void gtk2_paint_extension(WidgetType widget_type, GtkStateType state_type,
GtkShadowType shadow_type, const gchar *detail,
gint x, gint y, gint width, gint height, GtkPositionType gap_side);
void gtk2_paint_flat_box(WidgetType widget_type, GtkStateType state_type,
GtkShadowType shadow_type, const gchar *detail,
gint x, gint y, gint width, gint height, gboolean has_focus);
void gtk2_paint_focus(WidgetType widget_type, GtkStateType state_type,
const char *detail, gint x, gint y, gint width, gint height);
void gtk2_paint_handle(WidgetType widget_type, GtkStateType state_type,
GtkShadowType shadow_type, const gchar *detail,
gint x, gint y, gint width, gint height, GtkOrientation orientation);
void gtk2_paint_hline(WidgetType widget_type, GtkStateType state_type,
const gchar *detail, gint x, gint y, gint width, gint height);
void gtk2_paint_option(WidgetType widget_type, gint synth_state,
const gchar *detail, gint x, gint y, gint width, gint height);
void gtk2_paint_shadow(WidgetType widget_type, GtkStateType state_type,
GtkShadowType shadow_type, const gchar *detail,
gint x, gint y, gint width, gint height,
gint synth_state, GtkTextDirection dir);
void gtk2_paint_slider(WidgetType widget_type, GtkStateType state_type,
GtkShadowType shadow_type, const gchar *detail,
gint x, gint y, gint width, gint height, GtkOrientation orientation);
void gtk2_paint_vline(WidgetType widget_type, GtkStateType state_type,
const gchar *detail, gint x, gint y, gint width, gint height);
void gtk_paint_background(WidgetType widget_type, GtkStateType state_type,
gint x, gint y, gint width, gint height);
void gtk2_init_painting(JNIEnv *env, gint w, gint h);
gint gtk2_copy_image(gint *dest, gint width, gint height);
gint gtk2_get_xthickness(JNIEnv *env, WidgetType widget_type);
gint gtk2_get_ythickness(JNIEnv *env, WidgetType widget_type);
gint gtk2_get_color_for_state(JNIEnv *env, WidgetType widget_type,
GtkStateType state_type, ColorType color_type);
jobject gtk2_get_class_value(JNIEnv *env, WidgetType widget_type, jstring key);
GdkPixbuf *gtk2_get_stock_icon(gint widget_type, const gchar *stock_id,
GtkIconSize size, GtkTextDirection direction, const char *detail);
GdkPixbuf *gtk2_get_icon(const gchar *filename, gint size);
jstring gtk2_get_pango_font_name(JNIEnv *env, WidgetType widget_type);
void flush_gtk_event_loop();
jobject gtk2_get_setting(JNIEnv *env, Setting property);
void gtk2_set_range_value(WidgetType widget_type, jdouble value,
jdouble min, jdouble max, jdouble visible);
void (*fp_g_free)(gpointer mem);
void (*fp_g_object_unref)(gpointer object);
int (*fp_gdk_pixbuf_get_bits_per_sample)(const GdkPixbuf *pixbuf);
guchar *(*fp_gdk_pixbuf_get_pixels)(const GdkPixbuf *pixbuf);
gboolean (*fp_gdk_pixbuf_get_has_alpha)(const GdkPixbuf *pixbuf);
int (*fp_gdk_pixbuf_get_height)(const GdkPixbuf *pixbuf);
int (*fp_gdk_pixbuf_get_n_channels)(const GdkPixbuf *pixbuf);
int (*fp_gdk_pixbuf_get_rowstride)(const GdkPixbuf *pixbuf);
int (*fp_gdk_pixbuf_get_width)(const GdkPixbuf *pixbuf);
GdkPixbuf *(*fp_gdk_pixbuf_new_from_file)(const char *filename, GError **error);
void (*fp_gtk_widget_destroy)(GtkWidget *widget);
void (*fp_gtk_window_present)(GtkWindow *window);
void (*fp_gtk_window_move)(GtkWindow *window, gint x, gint y);
void (*fp_gtk_window_resize)(GtkWindow *window, gint width, gint height);
/** /**
* Function Pointers for GtkFileChooser * Function Pointers for GtkFileChooser
*/ */
gchar* (*fp_gtk_file_chooser_get_filename)(GtkFileChooser *chooser); static gchar* (*fp_gtk_file_chooser_get_filename)(GtkFileChooser *chooser);
void (*fp_gtk_widget_hide)(GtkWidget *widget); static void (*fp_gtk_widget_hide)(void *widget);
void (*fp_gtk_main_quit)(void); static void (*fp_gtk_main_quit)(void);
GtkWidget* (*fp_gtk_file_chooser_dialog_new)(const gchar *title, static void* (*fp_gtk_file_chooser_dialog_new)(const gchar *title,
GtkWindow *parent, GtkFileChooserAction action, GtkWindow *parent, GtkFileChooserAction action,
const gchar *first_button_text, ...); const gchar *first_button_text, ...);
gboolean (*fp_gtk_file_chooser_set_current_folder)(GtkFileChooser *chooser, static gboolean (*fp_gtk_file_chooser_set_current_folder)(GtkFileChooser *chooser,
const gchar *filename); const gchar *filename);
gboolean (*fp_gtk_file_chooser_set_filename)(GtkFileChooser *chooser, static gboolean (*fp_gtk_file_chooser_set_filename)(GtkFileChooser *chooser,
const char *filename); const char *filename);
void (*fp_gtk_file_chooser_set_current_name)(GtkFileChooser *chooser, static void (*fp_gtk_file_chooser_set_current_name)(GtkFileChooser *chooser,
const gchar *name); const gchar *name);
void (*fp_gtk_file_filter_add_custom)(GtkFileFilter *filter, static void (*fp_gtk_file_filter_add_custom)(GtkFileFilter *filter,
GtkFileFilterFlags needed, GtkFileFilterFunc func, gpointer data, GtkFileFilterFlags needed, GtkFileFilterFunc func, gpointer data,
GDestroyNotify notify); GDestroyNotify notify);
void (*fp_gtk_file_chooser_set_filter)(GtkFileChooser *chooser, static void (*fp_gtk_file_chooser_set_filter)(GtkFileChooser *chooser,
GtkFileFilter *filter); GtkFileFilter *filter);
GType (*fp_gtk_file_chooser_get_type)(void); static GType (*fp_gtk_file_chooser_get_type)(void);
GtkFileFilter* (*fp_gtk_file_filter_new)(void); static GtkFileFilter* (*fp_gtk_file_filter_new)(void);
void (*fp_gtk_file_chooser_set_do_overwrite_confirmation)( static void (*fp_gtk_file_chooser_set_do_overwrite_confirmation)(
GtkFileChooser *chooser, gboolean do_overwrite_confirmation); GtkFileChooser *chooser, gboolean do_overwrite_confirmation);
void (*fp_gtk_file_chooser_set_select_multiple)( static void (*fp_gtk_file_chooser_set_select_multiple)(
GtkFileChooser *chooser, gboolean select_multiple); GtkFileChooser *chooser, gboolean select_multiple);
gchar* (*fp_gtk_file_chooser_get_current_folder)(GtkFileChooser *chooser); static gchar* (*fp_gtk_file_chooser_get_current_folder)(GtkFileChooser *chooser);
GSList* (*fp_gtk_file_chooser_get_filenames)(GtkFileChooser *chooser); static GSList* (*fp_gtk_file_chooser_get_filenames)(GtkFileChooser *chooser);
guint (*fp_gtk_g_slist_length)(GSList *list); static guint (*fp_gtk_g_slist_length)(GSList *list);
gulong (*fp_g_signal_connect_data)(gpointer instance, static gulong (*fp_g_signal_connect_data)(gpointer instance,
const gchar *detailed_signal, GCallback c_handler, gpointer data, const gchar *detailed_signal, GCallback c_handler, gpointer data,
GClosureNotify destroy_data, GConnectFlags connect_flags); GClosureNotify destroy_data, GConnectFlags connect_flags);
void (*fp_gtk_widget_show)(GtkWidget *widget); static void (*fp_gtk_widget_show)(void *widget);
void (*fp_gtk_main)(void); static void (*fp_gtk_main)(void);
guint (*fp_gtk_main_level)(void); static guint (*fp_gtk_main_level)(void);
gchar* (*fp_g_path_get_dirname) (const gchar *file_name); static gchar* (*fp_g_path_get_dirname) (const gchar *file_name);
/**
* This function is available for GLIB > 2.20, so it MUST be
* called within GLIB_CHECK_VERSION(2, 20, 0) check.
*/
gboolean (*fp_g_thread_get_initialized)(void);
void (*fp_g_thread_init)(GThreadFunctions *vtable); static GList* (*fp_g_list_append) (GList *list, gpointer data);
void (*fp_gdk_threads_init)(void); static void (*fp_g_list_free) (GList *list);
void (*fp_gdk_threads_enter)(void); static void (*fp_g_list_free_full) (GList *list, GDestroyNotify free_func);
void (*fp_gdk_threads_leave)(void);
gboolean (*fp_gtk_show_uri)(GdkScreen *screen, const gchar *uri, static gboolean (*fp_gtk_show_uri)(GdkScreen *screen, const gchar *uri,
guint32 timestamp, GError **error); guint32 timestamp, GError **error);
#endif /* !_GTK2_INTERFACE_H */ #endif /* !_GTK2_INTERFACE_H */
/*
* Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#include <dlfcn.h>
#include <setjmp.h>
#include <X11/Xlib.h>
#include <limits.h>
#include <string.h>
#include "gtk3_interface.h"
#include "java_awt_Transparency.h"
#include "sizecalc.h"
#include <jni_util.h>
#include <stdio.h>
#include "awt.h"
static void *gtk3_libhandle = NULL;
static void *gthread_libhandle = NULL;
static jmp_buf j;
/* Widgets */
static GtkWidget *gtk3_widget = NULL;
static GtkWidget *gtk3_window = NULL;
static GtkFixed *gtk3_fixed = NULL;
static GtkStyleProvider *gtk3_css = NULL;
/* Paint system */
static cairo_surface_t *surface = NULL;
static cairo_t *cr = NULL;
static const char ENV_PREFIX[] = "GTK_MODULES=";
static GtkWidget *gtk3_widgets[_GTK_WIDGET_TYPE_SIZE];
static void throw_exception(JNIEnv *env, const char* name, const char* message)
{
jclass class = (*env)->FindClass(env, name);
if (class != NULL)
(*env)->ThrowNew(env, class, message);
(*env)->DeleteLocalRef(env, class);
}
static void gtk3_add_state(GtkWidget *widget, GtkStateType state) {
GtkStateType old_state = fp_gtk_widget_get_state(widget);
fp_gtk_widget_set_state(widget, old_state | state);
}
static void gtk3_remove_state(GtkWidget *widget, GtkStateType state) {
GtkStateType old_state = fp_gtk_widget_get_state(widget);
fp_gtk_widget_set_state(widget, old_state & ~state);
}
/* This is a workaround for the bug:
* http://sourceware.org/bugzilla/show_bug.cgi?id=1814
* (dlsym/dlopen clears dlerror state)
* This bug is specific to Linux, but there is no harm in
* applying this workaround on Solaris as well.
*/
static void* dl_symbol(const char* name)
{
void* result = dlsym(gtk3_libhandle, name);
if (!result)
longjmp(j, NO_SYMBOL_EXCEPTION);
return result;
}
static void* dl_symbol_gthread(const char* name)
{
void* result = dlsym(gthread_libhandle, name);
if (!result)
longjmp(j, NO_SYMBOL_EXCEPTION);
return result;
}
gboolean gtk3_check(const char* lib_name, gboolean load)
{
if (gtk3_libhandle != NULL) {
/* We've already successfully opened the GTK libs, so return true. */
return TRUE;
} else {
#ifdef RTLD_NOLOAD
void *lib = dlopen(lib_name, RTLD_LAZY | RTLD_NOLOAD);
if (!load || lib != NULL) {
return lib != NULL;
}
#else
#ifdef _AIX
/* On AIX we could implement this with the help of loadquery(L_GETINFO, ..) */
/* (see reload_table() in hotspot/src/os/aix/vm/loadlib_aix.cpp) but it is */
/* probably not worth it because most AIX servers don't have GTK libs anyway */
#endif
#endif
return dlopen(lib_name, RTLD_LAZY | RTLD_LOCAL) != NULL;
}
}
#define ADD_SUPPORTED_ACTION(actionStr) \
do { \
jfieldID fld_action = (*env)->GetStaticFieldID(env, cls_action, actionStr, \
"Ljava/awt/Desktop$Action;"); \
if (!(*env)->ExceptionCheck(env)) { \
jobject action = (*env)->GetStaticObjectField(env, cls_action, \
fld_action); \
(*env)->CallBooleanMethod(env, supportedActions, mid_arrayListAdd, \
action); \
} else { \
(*env)->ExceptionClear(env); \
} \
} while(0);
static void update_supported_actions(JNIEnv *env) {
GVfs * (*fp_g_vfs_get_default) (void);
const gchar * const * (*fp_g_vfs_get_supported_uri_schemes) (GVfs * vfs);
const gchar * const * schemes = NULL;
jclass cls_action = (*env)->FindClass(env, "java/awt/Desktop$Action");
CHECK_NULL(cls_action);
jclass cls_xDesktopPeer = (*env)->
FindClass(env, "sun/awt/X11/XDesktopPeer");
CHECK_NULL(cls_xDesktopPeer);
jfieldID fld_supportedActions = (*env)->GetStaticFieldID(env,
cls_xDesktopPeer, "supportedActions", "Ljava/util/List;");
CHECK_NULL(fld_supportedActions);
jobject supportedActions = (*env)->GetStaticObjectField(env,
cls_xDesktopPeer, fld_supportedActions);
jclass cls_arrayList = (*env)->FindClass(env, "java/util/ArrayList");
CHECK_NULL(cls_arrayList);
jmethodID mid_arrayListAdd = (*env)->GetMethodID(env, cls_arrayList, "add",
"(Ljava/lang/Object;)Z");
CHECK_NULL(mid_arrayListAdd);
jmethodID mid_arrayListClear = (*env)->GetMethodID(env, cls_arrayList,
"clear", "()V");
CHECK_NULL(mid_arrayListClear);
(*env)->CallVoidMethod(env, supportedActions, mid_arrayListClear);
ADD_SUPPORTED_ACTION("OPEN");
/**
* gtk_show_uri() documentation says:
*
* > you need to install gvfs to get support for uri schemes such as http://
* > or ftp://, as only local files are handled by GIO itself.
*
* So OPEN action was safely added here.
* However, it looks like Solaris 11 have gvfs support only for 32-bit
* applications only by default.
*/
fp_g_vfs_get_default = dl_symbol("g_vfs_get_default");
fp_g_vfs_get_supported_uri_schemes =
dl_symbol("g_vfs_get_supported_uri_schemes");
dlerror();
if (fp_g_vfs_get_default && fp_g_vfs_get_supported_uri_schemes) {
GVfs * vfs = fp_g_vfs_get_default();
schemes = vfs ? fp_g_vfs_get_supported_uri_schemes(vfs) : NULL;
if (schemes) {
int i = 0;
while (schemes[i]) {
if (strcmp(schemes[i], "http") == 0) {
ADD_SUPPORTED_ACTION("BROWSE");
ADD_SUPPORTED_ACTION("MAIL");
break;
}
i++;
}
}
} else {
#ifdef DEBUG
fprintf(stderr, "Cannot load g_vfs_get_supported_uri_schemes\n");
#endif /* DEBUG */
}
}
/**
* Functions for awt_Desktop.c
*/
static gboolean gtk3_show_uri_load(JNIEnv *env) {
gboolean success = FALSE;
dlerror();
fp_gtk_show_uri = dl_symbol("gtk_show_uri");
const char *dlsym_error = dlerror();
if (dlsym_error) {
#ifdef DEBUG
fprintf (stderr, "Cannot load symbol: %s \n", dlsym_error);
#endif /* DEBUG */
} else if (fp_gtk_show_uri == NULL) {
#ifdef DEBUG
fprintf(stderr, "dlsym(gtk_show_uri) returned NULL\n");
#endif /* DEBUG */
} else {
gtk->gtk_show_uri = fp_gtk_show_uri;
update_supported_actions(env);
success = TRUE;
}
return success;
}
/**
* Functions for sun_awt_X11_GtkFileDialogPeer.c
*/
static void gtk3_file_chooser_load()
{
fp_gtk_file_chooser_get_filename = dl_symbol(
"gtk_file_chooser_get_filename");
fp_gtk_file_chooser_dialog_new = dl_symbol("gtk_file_chooser_dialog_new");
fp_gtk_file_chooser_set_current_folder = dl_symbol(
"gtk_file_chooser_set_current_folder");
fp_gtk_file_chooser_set_filename = dl_symbol(
"gtk_file_chooser_set_filename");
fp_gtk_file_chooser_set_current_name = dl_symbol(
"gtk_file_chooser_set_current_name");
fp_gtk_file_filter_add_custom = dl_symbol("gtk_file_filter_add_custom");
fp_gtk_file_chooser_set_filter = dl_symbol("gtk_file_chooser_set_filter");
fp_gtk_file_chooser_get_type = dl_symbol("gtk_file_chooser_get_type");
fp_gtk_file_filter_new = dl_symbol("gtk_file_filter_new");
fp_gtk_file_chooser_set_do_overwrite_confirmation = dl_symbol(
"gtk_file_chooser_set_do_overwrite_confirmation");
fp_gtk_file_chooser_set_select_multiple = dl_symbol(
"gtk_file_chooser_set_select_multiple");
fp_gtk_file_chooser_get_current_folder = dl_symbol(
"gtk_file_chooser_get_current_folder");
fp_gtk_file_chooser_get_filenames = dl_symbol(
"gtk_file_chooser_get_filenames");
fp_gtk_g_slist_length = dl_symbol("g_slist_length");
fp_gdk_x11_drawable_get_xid = dl_symbol("gdk_x11_window_get_xid");
}
static void empty() {}
static gboolean gtk3_version_3_10 = TRUE;
static gboolean gtk3_version_3_14 = FALSE;
GtkApi* gtk3_load(JNIEnv *env, const char* lib_name)
{
gboolean result;
int i;
int (*handler)();
int (*io_handler)();
char *gtk_modules_env;
gtk3_libhandle = dlopen(lib_name, RTLD_LAZY | RTLD_LOCAL);
if (gtk3_libhandle == NULL) {
return FALSE;
}
gthread_libhandle = dlopen(GTHREAD_LIB_VERSIONED, RTLD_LAZY | RTLD_LOCAL);
if (gthread_libhandle == NULL) {
gthread_libhandle = dlopen(GTHREAD_LIB, RTLD_LAZY | RTLD_LOCAL);
if (gthread_libhandle == NULL)
return FALSE;
}
if (setjmp(j) == 0)
{
fp_gtk_check_version = dl_symbol("gtk_check_version");
/* GLib */
fp_glib_check_version = dlsym(gtk3_libhandle, "glib_check_version");
if (!fp_glib_check_version) {
dlerror();
}
fp_g_free = dl_symbol("g_free");
fp_g_object_unref = dl_symbol("g_object_unref");
fp_g_main_context_iteration =
dl_symbol("g_main_context_iteration");
fp_g_value_init = dl_symbol("g_value_init");
fp_g_type_is_a = dl_symbol("g_type_is_a");
fp_g_value_get_boolean = dl_symbol("g_value_get_boolean");
fp_g_value_get_char = dl_symbol("g_value_get_char");
fp_g_value_get_uchar = dl_symbol("g_value_get_uchar");
fp_g_value_get_int = dl_symbol("g_value_get_int");
fp_g_value_get_uint = dl_symbol("g_value_get_uint");
fp_g_value_get_long = dl_symbol("g_value_get_long");
fp_g_value_get_ulong = dl_symbol("g_value_get_ulong");
fp_g_value_get_int64 = dl_symbol("g_value_get_int64");
fp_g_value_get_uint64 = dl_symbol("g_value_get_uint64");
fp_g_value_get_float = dl_symbol("g_value_get_float");
fp_g_value_get_double = dl_symbol("g_value_get_double");
fp_g_value_get_string = dl_symbol("g_value_get_string");
fp_g_value_get_enum = dl_symbol("g_value_get_enum");
fp_g_value_get_flags = dl_symbol("g_value_get_flags");
fp_g_value_get_param = dl_symbol("g_value_get_param");
fp_g_value_get_boxed = dl_symbol("g_value_get_boxed");
fp_g_value_get_pointer = dl_symbol("g_value_get_pointer");
fp_g_object_get = dl_symbol("g_object_get");
fp_g_object_set = dl_symbol("g_object_set");
fp_g_str_has_prefix = dl_symbol("g_str_has_prefix");
fp_g_strsplit = dl_symbol("g_strsplit");
fp_g_strfreev = dl_symbol("g_strfreev");
/* GDK */
fp_gdk_get_default_root_window =
dl_symbol("gdk_get_default_root_window");
/* Pixbuf */
fp_gdk_pixbuf_new = dl_symbol("gdk_pixbuf_new");
fp_gdk_pixbuf_new_from_file =
dl_symbol("gdk_pixbuf_new_from_file");
fp_gdk_pixbuf_get_from_drawable =
dl_symbol("gdk_pixbuf_get_from_window");
fp_gdk_pixbuf_get_width = dl_symbol("gdk_pixbuf_get_width");
fp_gdk_pixbuf_get_height = dl_symbol("gdk_pixbuf_get_height");
fp_gdk_pixbuf_get_pixels = dl_symbol("gdk_pixbuf_get_pixels");
fp_gdk_pixbuf_get_rowstride =
dl_symbol("gdk_pixbuf_get_rowstride");
fp_gdk_pixbuf_get_has_alpha =
dl_symbol("gdk_pixbuf_get_has_alpha");
fp_gdk_pixbuf_get_bits_per_sample =
dl_symbol("gdk_pixbuf_get_bits_per_sample");
fp_gdk_pixbuf_get_n_channels =
dl_symbol("gdk_pixbuf_get_n_channels");
fp_gdk_pixbuf_get_colorspace =
dl_symbol("gdk_pixbuf_get_colorspace");
fp_cairo_image_surface_create = dl_symbol("cairo_image_surface_create");
fp_cairo_surface_destroy = dl_symbol("cairo_surface_destroy");
fp_cairo_create = dl_symbol("cairo_create");
fp_cairo_destroy = dl_symbol("cairo_destroy");
fp_cairo_fill = dl_symbol("cairo_fill");
fp_cairo_rectangle = dl_symbol("cairo_rectangle");
fp_cairo_set_source_rgb = dl_symbol("cairo_set_source_rgb");
fp_cairo_set_source_rgba = dl_symbol("cairo_set_source_rgba");
fp_cairo_surface_flush = dl_symbol("cairo_surface_flush");
fp_cairo_paint = dl_symbol("cairo_paint");
fp_cairo_clip = dl_symbol("cairo_clip");
fp_cairo_image_surface_get_data =
dl_symbol("cairo_image_surface_get_data");
fp_cairo_image_surface_get_stride =
dl_symbol("cairo_image_surface_get_stride");
fp_gdk_pixbuf_get_from_surface =
dl_symbol("gdk_pixbuf_get_from_surface");
fp_gtk_widget_get_state = dl_symbol("gtk_widget_get_state");
fp_gtk_widget_set_state = dl_symbol("gtk_widget_set_state");
fp_gtk_widget_is_focus = dl_symbol("gtk_widget_is_focus");
fp_gtk_widget_set_allocation = dl_symbol("gtk_widget_set_allocation");
fp_gtk_widget_get_parent = dl_symbol("gtk_widget_get_parent");
fp_gtk_widget_get_window = dl_symbol("gtk_widget_get_window");
fp_gtk_widget_get_style_context =
dl_symbol("gtk_widget_get_style_context");
fp_gtk_style_context_get_color =
dl_symbol("gtk_style_context_get_color");
fp_gtk_style_context_get_background_color =
dl_symbol("gtk_style_context_get_background_color");
fp_gtk_widget_get_state_flags = dl_symbol("gtk_widget_get_state_flags");
fp_gtk_style_context_set_state =
dl_symbol("gtk_style_context_set_state");
fp_gtk_style_context_add_class =
dl_symbol("gtk_style_context_add_class");
fp_gtk_style_context_save = dl_symbol("gtk_style_context_save");
fp_gtk_style_context_restore = dl_symbol("gtk_style_context_restore");
fp_gtk_render_check = dl_symbol("gtk_render_check");
fp_gtk_render_option = dl_symbol("gtk_render_option");
fp_gtk_render_extension = dl_symbol("gtk_render_extension");
fp_gtk_render_expander = dl_symbol("gtk_render_expander");
fp_gtk_render_frame_gap = dl_symbol("gtk_render_frame_gap");
fp_gtk_render_line = dl_symbol("gtk_render_line");
fp_gtk_widget_render_icon_pixbuf =
dl_symbol("gtk_widget_render_icon_pixbuf");
if (fp_gtk_check_version(3, 10, 0)) {
gtk3_version_3_10 = FALSE;
} else {
fp_gdk_window_create_similar_image_surface =
dl_symbol("gdk_window_create_similar_image_surface");
}
gtk3_version_3_14 = !fp_gtk_check_version(3, 14, 0);
fp_gdk_window_create_similar_surface =
dl_symbol("gdk_window_create_similar_surface");
fp_gtk_settings_get_for_screen =
dl_symbol("gtk_settings_get_for_screen");
fp_gtk_widget_get_screen = dl_symbol("gtk_widget_get_screen");
fp_gtk_css_provider_get_named = dl_symbol("gtk_css_provider_get_named");
fp_gtk_style_context_add_provider =
dl_symbol("gtk_style_context_add_provider");
fp_gtk_render_frame = dl_symbol("gtk_render_frame");
fp_gtk_render_focus = dl_symbol("gtk_render_focus");
fp_gtk_render_handle = dl_symbol("gtk_render_handle");
fp_gtk_render_arrow = dl_symbol("gtk_render_arrow");
fp_gtk_style_context_get_property =
dl_symbol("gtk_style_context_get_property");
fp_gtk_scrolled_window_set_shadow_type =
dl_symbol("gtk_scrolled_window_set_shadow_type");
fp_gtk_render_slider = dl_symbol("gtk_render_slider");
fp_gtk_style_context_get_padding =
dl_symbol("gtk_style_context_get_padding");
fp_gtk_range_set_inverted = dl_symbol("gtk_range_set_inverted");
fp_gtk_style_context_get_font = dl_symbol("gtk_style_context_get_font");
fp_gtk_widget_get_allocated_width =
dl_symbol("gtk_widget_get_allocated_width");
fp_gtk_widget_get_allocated_height =
dl_symbol("gtk_widget_get_allocated_height");
fp_gtk_icon_theme_get_default = dl_symbol("gtk_icon_theme_get_default");
fp_gtk_icon_theme_load_icon = dl_symbol("gtk_icon_theme_load_icon");
fp_gtk_adjustment_set_lower = dl_symbol("gtk_adjustment_set_lower");
fp_gtk_adjustment_set_page_increment =
dl_symbol("gtk_adjustment_set_page_increment");
fp_gtk_adjustment_set_page_size =
dl_symbol("gtk_adjustment_set_page_size");
fp_gtk_adjustment_set_step_increment =
dl_symbol("gtk_adjustment_set_step_increment");
fp_gtk_adjustment_set_upper = dl_symbol("gtk_adjustment_set_upper");
fp_gtk_adjustment_set_value = dl_symbol("gtk_adjustment_set_value");
fp_gtk_render_activity = dl_symbol("gtk_render_activity");
fp_gtk_render_background = dl_symbol("gtk_render_background");
fp_gtk_style_context_has_class =
dl_symbol("gtk_style_context_has_class");
fp_gtk_style_context_set_junction_sides =
dl_symbol("gtk_style_context_set_junction_sides");
fp_gtk_style_context_add_region =
dl_symbol("gtk_style_context_add_region");
fp_gtk_init_check = dl_symbol("gtk_init_check");
/* GTK widgets */
fp_gtk_arrow_new = dl_symbol("gtk_arrow_new");
fp_gtk_button_new = dl_symbol("gtk_button_new");
fp_gtk_spin_button_new = dl_symbol("gtk_spin_button_new");
fp_gtk_check_button_new = dl_symbol("gtk_check_button_new");
fp_gtk_check_menu_item_new =
dl_symbol("gtk_check_menu_item_new");
fp_gtk_color_selection_dialog_new =
dl_symbol("gtk_color_selection_dialog_new");
fp_gtk_entry_new = dl_symbol("gtk_entry_new");
fp_gtk_fixed_new = dl_symbol("gtk_fixed_new");
fp_gtk_handle_box_new = dl_symbol("gtk_handle_box_new");
fp_gtk_image_new = dl_symbol("gtk_image_new");
fp_gtk_hpaned_new = dl_symbol("gtk_hpaned_new");
fp_gtk_vpaned_new = dl_symbol("gtk_vpaned_new");
fp_gtk_scale_new = dl_symbol("gtk_scale_new");
fp_gtk_hscrollbar_new = dl_symbol("gtk_hscrollbar_new");
fp_gtk_vscrollbar_new = dl_symbol("gtk_vscrollbar_new");
fp_gtk_hseparator_new = dl_symbol("gtk_hseparator_new");
fp_gtk_vseparator_new = dl_symbol("gtk_vseparator_new");
fp_gtk_label_new = dl_symbol("gtk_label_new");
fp_gtk_menu_new = dl_symbol("gtk_menu_new");
fp_gtk_menu_bar_new = dl_symbol("gtk_menu_bar_new");
fp_gtk_menu_item_new = dl_symbol("gtk_menu_item_new");
fp_gtk_menu_item_set_submenu =
dl_symbol("gtk_menu_item_set_submenu");
fp_gtk_notebook_new = dl_symbol("gtk_notebook_new");
fp_gtk_progress_bar_new =
dl_symbol("gtk_progress_bar_new");
fp_gtk_progress_bar_set_orientation =
dl_symbol("gtk_orientable_set_orientation");
fp_gtk_radio_button_new =
dl_symbol("gtk_radio_button_new");
fp_gtk_radio_menu_item_new =
dl_symbol("gtk_radio_menu_item_new");
fp_gtk_scrolled_window_new =
dl_symbol("gtk_scrolled_window_new");
fp_gtk_separator_menu_item_new =
dl_symbol("gtk_separator_menu_item_new");
fp_gtk_text_view_new = dl_symbol("gtk_text_view_new");
fp_gtk_toggle_button_new =
dl_symbol("gtk_toggle_button_new");
fp_gtk_toolbar_new = dl_symbol("gtk_toolbar_new");
fp_gtk_tree_view_new = dl_symbol("gtk_tree_view_new");
fp_gtk_viewport_new = dl_symbol("gtk_viewport_new");
fp_gtk_window_new = dl_symbol("gtk_window_new");
fp_gtk_window_present = dl_symbol("gtk_window_present");
fp_gtk_window_move = dl_symbol("gtk_window_move");
fp_gtk_window_resize = dl_symbol("gtk_window_resize");
fp_gtk_dialog_new = dl_symbol("gtk_dialog_new");
fp_gtk_frame_new = dl_symbol("gtk_frame_new");
fp_gtk_adjustment_new = dl_symbol("gtk_adjustment_new");
fp_gtk_container_add = dl_symbol("gtk_container_add");
fp_gtk_menu_shell_append =
dl_symbol("gtk_menu_shell_append");
fp_gtk_widget_realize = dl_symbol("gtk_widget_realize");
fp_gtk_widget_destroy = dl_symbol("gtk_widget_destroy");
fp_gtk_widget_render_icon =
dl_symbol("gtk_widget_render_icon");
fp_gtk_widget_set_name =
dl_symbol("gtk_widget_set_name");
fp_gtk_widget_set_parent =
dl_symbol("gtk_widget_set_parent");
fp_gtk_widget_set_direction =
dl_symbol("gtk_widget_set_direction");
fp_gtk_widget_style_get =
dl_symbol("gtk_widget_style_get");
fp_gtk_widget_class_install_style_property =
dl_symbol("gtk_widget_class_install_style_property");
fp_gtk_widget_class_find_style_property =
dl_symbol("gtk_widget_class_find_style_property");
fp_gtk_widget_style_get_property =
dl_symbol("gtk_widget_style_get_property");
fp_pango_font_description_to_string =
dl_symbol("pango_font_description_to_string");
fp_gtk_settings_get_default =
dl_symbol("gtk_settings_get_default");
fp_gtk_widget_get_settings =
dl_symbol("gtk_widget_get_settings");
fp_gtk_border_get_type = dl_symbol("gtk_border_get_type");
fp_gtk_arrow_set = dl_symbol("gtk_arrow_set");
fp_gtk_widget_size_request =
dl_symbol("gtk_widget_size_request");
fp_gtk_range_get_adjustment =
dl_symbol("gtk_range_get_adjustment");
fp_gtk_widget_hide = dl_symbol("gtk_widget_hide");
fp_gtk_main_quit = dl_symbol("gtk_main_quit");
fp_g_signal_connect_data = dl_symbol("g_signal_connect_data");
fp_gtk_widget_show = dl_symbol("gtk_widget_show");
fp_gtk_main = dl_symbol("gtk_main");
fp_g_path_get_dirname = dl_symbol("g_path_get_dirname");
fp_gdk_threads_init = dl_symbol("gdk_threads_init");
fp_gdk_threads_enter = dl_symbol("gdk_threads_enter");
fp_gdk_threads_leave = dl_symbol("gdk_threads_leave");
/**
* Functions for sun_awt_X11_GtkFileDialogPeer.c
*/
gtk3_file_chooser_load();
fp_gtk_combo_box_new = dlsym(gtk3_libhandle, "gtk_combo_box_new");
fp_gtk_combo_box_entry_new = dlsym(gtk3_libhandle,
"gtk_combo_box_new_with_entry");
fp_gtk_separator_tool_item_new = dlsym(gtk3_libhandle,
"gtk_separator_tool_item_new");
fp_g_list_append = dl_symbol("g_list_append");
fp_g_list_free = dl_symbol("g_list_free");
fp_g_list_free_full = dl_symbol("g_list_free_full");
}
/* Now we have only one kind of exceptions: NO_SYMBOL_EXCEPTION
* Otherwise we can check the return value of setjmp method.
*/
else
{
dlclose(gtk3_libhandle);
gtk3_libhandle = NULL;
dlclose(gthread_libhandle);
gthread_libhandle = NULL;
return NULL;
}
/*
* Strip the AT-SPI GTK_MODULES if present
*/
gtk_modules_env = getenv ("GTK_MODULES");
if ((gtk_modules_env && strstr(gtk_modules_env, "atk-bridge")) ||
(gtk_modules_env && strstr(gtk_modules_env, "gail"))) {
/* careful, strtok modifies its args */
gchar *tmp_env = strdup(gtk_modules_env);
if (tmp_env) {
/* the new env will be smaller than the old one */
gchar *s, *new_env = SAFE_SIZE_STRUCT_ALLOC(malloc,
sizeof(ENV_PREFIX), 1, strlen (gtk_modules_env));
if (new_env) {
strcpy(new_env, ENV_PREFIX);
/* strip out 'atk-bridge' and 'gail' */
size_t PREFIX_LENGTH = strlen(ENV_PREFIX);
gchar *tmp_ptr = NULL;
for (s = strtok_r(tmp_env, ":", &tmp_ptr); s;
s = strtok_r(NULL, ":", &tmp_ptr)) {
if ((!strstr(s, "atk-bridge")) && (!strstr(s, "gail"))) {
if (strlen(new_env) > PREFIX_LENGTH) {
new_env = strcat(new_env, ":");
}
new_env = strcat(new_env, s);
}
}
if (putenv(new_env) != 0) {
/* no free() on success, putenv() doesn't copy string */
free(new_env);
}
}
free (tmp_env);
}
}
/*
* GTK should be initialized with gtk_init_check() before use.
*
* gtk_init_check installs its own error handlers. It is critical that
* we preserve error handler set from AWT. Otherwise we'll crash on
* BadMatch errors which we would normally ignore. The IO error handler
* is preserved here, too, just for consistency.
*/
AWT_LOCK();
handler = XSetErrorHandler(NULL);
io_handler = XSetIOErrorHandler(NULL);
//According the GTK documentation, gdk_threads_init() should be
//called before gtk_init() or gtk_init_check()
fp_gdk_threads_init();
result = (*fp_gtk_init_check)(NULL, NULL);
XSetErrorHandler(handler);
XSetIOErrorHandler(io_handler);
AWT_UNLOCK();
/* Initialize widget array. */
for (i = 0; i < _GTK_WIDGET_TYPE_SIZE; i++)
{
gtk3_widgets[i] = NULL;
}
if (result) {
GtkApi* gtk = (GtkApi*)malloc(sizeof(GtkApi));
gtk3_init(gtk);
return gtk;
}
return NULL;
}
static int gtk3_unload()
{
int i;
char *gtk3_error;
if (!gtk3_libhandle)
return TRUE;
/* Release painting objects */
if (surface != NULL) {
fp_cairo_destroy(cr);
fp_cairo_surface_destroy(surface);
surface = NULL;
}
if (gtk3_window != NULL) {
/* Destroying toplevel widget will destroy all contained widgets */
(*fp_gtk_widget_destroy)(gtk3_window);
/* Unset some static data so they get reinitialized on next load */
gtk3_window = NULL;
}
dlerror();
dlclose(gtk3_libhandle);
dlclose(gthread_libhandle);
if ((gtk3_error = dlerror()) != NULL)
{
return FALSE;
}
return TRUE;
}
/* Dispatch all pending events from the GTK event loop.
* This is needed to catch theme change and update widgets' style.
*/
static void flush_gtk_event_loop()
{
while((*fp_g_main_context_iteration)(NULL));
}
/*
* Initialize components of containment hierarchy. This creates a GtkFixed
* inside a GtkWindow. All widgets get realized.
*/
static void init_containers()
{
if (gtk3_window == NULL)
{
gtk3_window = (*fp_gtk_window_new)(GTK_WINDOW_TOPLEVEL);
gtk3_fixed = (GtkFixed *)(*fp_gtk_fixed_new)();
(*fp_gtk_container_add)((GtkContainer*)gtk3_window,
(GtkWidget *)gtk3_fixed);
(*fp_gtk_widget_realize)(gtk3_window);
(*fp_gtk_widget_realize)((GtkWidget *)gtk3_fixed);
GtkSettings* settings = fp_gtk_settings_get_for_screen(
fp_gtk_widget_get_screen(gtk3_window));
gchar* strval = NULL;
fp_g_object_get(settings, "gtk-theme-name", &strval, NULL);
gtk3_css = fp_gtk_css_provider_get_named(strval, NULL);
}
}
/*
* Ensure everything is ready for drawing an element of the specified width
* and height.
*
* We should somehow handle translucent images. GTK can draw to X Drawables
* only, which don't support alpha. When we retrieve the image back from
* the server, translucency information is lost. There're several ways to
* work around this:
* 1) Subclass GdkPixmap and cache translucent objects on client side. This
* requires us to implement parts of X server drawing logic on client side.
* Many X requests can potentially be "translucent"; e.g. XDrawLine with
* fill=tile and a translucent tile is a "translucent" operation, whereas
* XDrawLine with fill=solid is an "opaque" one. Moreover themes can (and some
* do) intermix transparent and opaque operations which makes caching even
* more problematic.
* 2) Use Xorg 32bit ARGB visual when available. GDK has no native support
* for it (as of version 2.6). Also even in JDS 3 Xorg does not support
* these visuals by default, which makes optimizing for them pointless.
* We can consider doing this at a later point when ARGB visuals become more
* popular.
* 3') GTK has plans to use Cairo as its graphical backend (presumably in
* 2.8), and Cairo supports alpha. With it we could also get rid of the
* unnecessary round trip to server and do all the drawing on client side.
* 4) For now we draw to two different pixmaps and restore alpha channel by
* comparing results. This can be optimized by using subclassed pixmap and
*/
static void gtk3_init_painting(JNIEnv *env, gint width, gint height)
{
init_containers();
if (cr) {
fp_cairo_destroy(cr);
}
if (surface != NULL) {
/* free old stuff */
fp_cairo_surface_destroy(surface);
}
if (gtk3_version_3_10) {
surface = fp_gdk_window_create_similar_image_surface(
fp_gtk_widget_get_window(gtk3_window),
CAIRO_FORMAT_ARGB32, width, height, 1);
} else {
surface = fp_cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
width, height);
}
cr = fp_cairo_create(surface);
}
/*
* Restore image from white and black pixmaps and copy it into destination
* buffer. This method compares two pixbufs taken from white and black
* pixmaps and decodes color and alpha components. Pixbufs are RGB without
* alpha, destination buffer is ABGR.
*
* The return value is the transparency type of the resulting image, either
* one of java_awt_Transparency_OPAQUE, java_awt_Transparency_BITMASK, and
* java_awt_Transparency_TRANSLUCENT.
*/
static gint gtk3_copy_image(gint *dst, gint width, gint height)
{
gint i, j, r, g, b;
guchar *data;
gint stride, padding;
fp_cairo_surface_flush(surface);
data = (*fp_cairo_image_surface_get_data)(surface);
stride = (*fp_cairo_image_surface_get_stride)(surface);
padding = stride - width * 4;
for (i = 0; i < height; i++) {
for (j = 0; j < width; j++) {
int r = *data++;
int g = *data++;
int b = *data++;
int a = *data++;
*dst++ = (a << 24 | b << 16 | g << 8 | r);
}
data += padding;
}
return java_awt_Transparency_TRANSLUCENT;
}
static void gtk3_set_direction(GtkWidget *widget, GtkTextDirection dir)
{
/*
* Some engines (inexplicably) look at the direction of the widget's
* parent, so we need to set the direction of both the widget and its
* parent.
*/
(*fp_gtk_widget_set_direction)(widget, dir);
GtkWidget* parent = fp_gtk_widget_get_parent(widget);
if (parent != NULL) {
fp_gtk_widget_set_direction(parent, dir);
}
}
/* GTK state_type filter */
static GtkStateType get_gtk_state_type(WidgetType widget_type, gint synth_state)
{
GtkStateType result = GTK_STATE_NORMAL;
if ((synth_state & DISABLED) != 0) {
result = GTK_STATE_INSENSITIVE;
} else if ((synth_state & PRESSED) != 0) {
result = GTK_STATE_ACTIVE;
} else if ((synth_state & MOUSE_OVER) != 0) {
result = GTK_STATE_PRELIGHT;
}
return result;
}
static GtkStateFlags get_gtk_state_flags(gint synth_state)
{
GtkStateFlags flags = 0;
if ((synth_state & DISABLED) != 0) {
flags |= GTK_STATE_FLAG_INSENSITIVE;
}
if (((synth_state & PRESSED) != 0 || (synth_state & SELECTED) != 0)) {
flags |= GTK_STATE_FLAG_ACTIVE;
}
if ((synth_state & MOUSE_OVER) != 0) {
flags |= GTK_STATE_FLAG_PRELIGHT;
}
if ((synth_state & FOCUSED) != 0) {
flags |= GTK_STATE_FLAG_FOCUSED;
}
return flags;
}
static GtkStateFlags get_gtk_flags(GtkStateType state_type) {
GtkStateFlags flags = 0;
switch (state_type)
{
case GTK_STATE_PRELIGHT:
flags |= GTK_STATE_FLAG_PRELIGHT;
break;
case GTK_STATE_SELECTED:
flags |= GTK_STATE_FLAG_SELECTED;
break;
case GTK_STATE_INSENSITIVE:
flags |= GTK_STATE_FLAG_INSENSITIVE;
break;
case GTK_STATE_ACTIVE:
flags |= GTK_STATE_FLAG_ACTIVE;
break;
case GTK_STATE_FOCUSED:
flags |= GTK_STATE_FLAG_FOCUSED;
break;
default:
break;
}
return flags;
}
/* GTK shadow_type filter */
static GtkShadowType get_gtk_shadow_type(WidgetType widget_type,
gint synth_state)
{
GtkShadowType result = GTK_SHADOW_OUT;
if ((synth_state & SELECTED) != 0) {
result = GTK_SHADOW_IN;
}
return result;
}
static GtkWidget* gtk3_get_arrow(GtkArrowType arrow_type,
GtkShadowType shadow_type)
{
GtkWidget *arrow = NULL;
if (NULL == gtk3_widgets[_GTK_ARROW_TYPE])
{
gtk3_widgets[_GTK_ARROW_TYPE] = (*fp_gtk_arrow_new)(arrow_type,
shadow_type);
(*fp_gtk_container_add)((GtkContainer *)gtk3_fixed,
gtk3_widgets[_GTK_ARROW_TYPE]);
(*fp_gtk_widget_realize)(gtk3_widgets[_GTK_ARROW_TYPE]);
}
arrow = gtk3_widgets[_GTK_ARROW_TYPE];
(*fp_gtk_arrow_set)(arrow, arrow_type, shadow_type);
return arrow;
}
static GtkAdjustment* create_adjustment()
{
return (GtkAdjustment *)
(*fp_gtk_adjustment_new)(50.0, 0.0, 100.0, 10.0, 20.0, 20.0);
}
/**
* Returns a pointer to the cached native widget for the specified widget
* type.
*/
static GtkWidget *gtk3_get_widget(WidgetType widget_type)
{
gboolean init_result = FALSE;
GtkWidget *result = NULL;
switch (widget_type)
{
case BUTTON:
case TABLE_HEADER:
if (init_result = (NULL == gtk3_widgets[_GTK_BUTTON_TYPE]))
{
gtk3_widgets[_GTK_BUTTON_TYPE] = (*fp_gtk_button_new)();
}
result = gtk3_widgets[_GTK_BUTTON_TYPE];
break;
case CHECK_BOX:
if (init_result = (NULL == gtk3_widgets[_GTK_CHECK_BUTTON_TYPE]))
{
gtk3_widgets[_GTK_CHECK_BUTTON_TYPE] =
(*fp_gtk_check_button_new)();
}
result = gtk3_widgets[_GTK_CHECK_BUTTON_TYPE];
break;
case CHECK_BOX_MENU_ITEM:
if (init_result = (NULL == gtk3_widgets[_GTK_CHECK_MENU_ITEM_TYPE]))
{
gtk3_widgets[_GTK_CHECK_MENU_ITEM_TYPE] =
(*fp_gtk_check_menu_item_new)();
}
result = gtk3_widgets[_GTK_CHECK_MENU_ITEM_TYPE];
break;
/************************************************************
* Creation a dedicated color chooser is dangerous because
* it deadlocks the EDT
************************************************************/
/* case COLOR_CHOOSER:
if (init_result =
(NULL == gtk3_widgets[_GTK_COLOR_SELECTION_DIALOG_TYPE]))
{
gtk3_widgets[_GTK_COLOR_SELECTION_DIALOG_TYPE] =
(*fp_gtk_color_selection_dialog_new)(NULL);
}
result = gtk3_widgets[_GTK_COLOR_SELECTION_DIALOG_TYPE];
break;*/
case COMBO_BOX:
if (init_result = (NULL == gtk3_widgets[_GTK_COMBO_BOX_TYPE]))
{
gtk3_widgets[_GTK_COMBO_BOX_TYPE] =
(*fp_gtk_combo_box_new)();
}
result = gtk3_widgets[_GTK_COMBO_BOX_TYPE];
break;
case COMBO_BOX_ARROW_BUTTON:
if (init_result =
(NULL == gtk3_widgets[_GTK_COMBO_BOX_ARROW_BUTTON_TYPE]))
{
gtk3_widgets[_GTK_COMBO_BOX_ARROW_BUTTON_TYPE] =
(*fp_gtk_toggle_button_new)();
}
result = gtk3_widgets[_GTK_COMBO_BOX_ARROW_BUTTON_TYPE];
break;
case COMBO_BOX_TEXT_FIELD:
if (init_result =
(NULL == gtk3_widgets[_GTK_COMBO_BOX_TEXT_FIELD_TYPE]))
{
result = gtk3_widgets[_GTK_COMBO_BOX_TEXT_FIELD_TYPE] =
(*fp_gtk_entry_new)();
}
result = gtk3_widgets[_GTK_COMBO_BOX_TEXT_FIELD_TYPE];
break;
case DESKTOP_ICON:
case INTERNAL_FRAME_TITLE_PANE:
case LABEL:
if (init_result = (NULL == gtk3_widgets[_GTK_LABEL_TYPE]))
{
gtk3_widgets[_GTK_LABEL_TYPE] =
(*fp_gtk_label_new)(NULL);
}
result = gtk3_widgets[_GTK_LABEL_TYPE];
break;
case DESKTOP_PANE:
case PANEL:
case ROOT_PANE:
if (init_result = (NULL == gtk3_widgets[_GTK_CONTAINER_TYPE]))
{
/* There is no constructor for a container type. I've
* chosen GtkFixed container since it has a default
* constructor.
*/
gtk3_widgets[_GTK_CONTAINER_TYPE] =
(*fp_gtk_fixed_new)();
}
result = gtk3_widgets[_GTK_CONTAINER_TYPE];
break;
case EDITOR_PANE:
case TEXT_AREA:
case TEXT_PANE:
if (init_result = (NULL == gtk3_widgets[_GTK_TEXT_VIEW_TYPE]))
{
gtk3_widgets[_GTK_TEXT_VIEW_TYPE] =
(*fp_gtk_text_view_new)();
}
result = gtk3_widgets[_GTK_TEXT_VIEW_TYPE];
break;
case FORMATTED_TEXT_FIELD:
case PASSWORD_FIELD:
case TEXT_FIELD:
if (init_result = (NULL == gtk3_widgets[_GTK_ENTRY_TYPE]))
{
gtk3_widgets[_GTK_ENTRY_TYPE] =
(*fp_gtk_entry_new)();
}
result = gtk3_widgets[_GTK_ENTRY_TYPE];
break;
case HANDLE_BOX:
if (init_result = (NULL == gtk3_widgets[_GTK_HANDLE_BOX_TYPE]))
{
gtk3_widgets[_GTK_HANDLE_BOX_TYPE] =
(*fp_gtk_handle_box_new)();
}
result = gtk3_widgets[_GTK_HANDLE_BOX_TYPE];
break;
case HSCROLL_BAR:
case HSCROLL_BAR_BUTTON_LEFT:
case HSCROLL_BAR_BUTTON_RIGHT:
case HSCROLL_BAR_TRACK:
case HSCROLL_BAR_THUMB:
if (init_result = (NULL == gtk3_widgets[_GTK_HSCROLLBAR_TYPE]))
{
gtk3_widgets[_GTK_HSCROLLBAR_TYPE] =
(*fp_gtk_hscrollbar_new)(create_adjustment());
}
result = gtk3_widgets[_GTK_HSCROLLBAR_TYPE];
break;
case HSEPARATOR:
if (init_result = (NULL == gtk3_widgets[_GTK_HSEPARATOR_TYPE]))
{
gtk3_widgets[_GTK_HSEPARATOR_TYPE] =
(*fp_gtk_hseparator_new)();
}
result = gtk3_widgets[_GTK_HSEPARATOR_TYPE];
break;
case HSLIDER:
case HSLIDER_THUMB:
case HSLIDER_TRACK:
if (init_result = (NULL == gtk3_widgets[_GTK_HSCALE_TYPE]))
{
gtk3_widgets[_GTK_HSCALE_TYPE] =
(*fp_gtk_scale_new)(GTK_ORIENTATION_HORIZONTAL, NULL);
}
result = gtk3_widgets[_GTK_HSCALE_TYPE];
break;
case HSPLIT_PANE_DIVIDER:
case SPLIT_PANE:
if (init_result = (NULL == gtk3_widgets[_GTK_HPANED_TYPE]))
{
gtk3_widgets[_GTK_HPANED_TYPE] = (*fp_gtk_hpaned_new)();
}
result = gtk3_widgets[_GTK_HPANED_TYPE];
break;
case IMAGE:
if (init_result = (NULL == gtk3_widgets[_GTK_IMAGE_TYPE]))
{
gtk3_widgets[_GTK_IMAGE_TYPE] = (*fp_gtk_image_new)();
}
result = gtk3_widgets[_GTK_IMAGE_TYPE];
break;
case INTERNAL_FRAME:
if (init_result = (NULL == gtk3_widgets[_GTK_WINDOW_TYPE]))
{
gtk3_widgets[_GTK_WINDOW_TYPE] =
(*fp_gtk_window_new)(GTK_WINDOW_TOPLEVEL);
}
result = gtk3_widgets[_GTK_WINDOW_TYPE];
break;
case TOOL_TIP:
if (init_result = (NULL == gtk3_widgets[_GTK_TOOLTIP_TYPE]))
{
result = (*fp_gtk_window_new)(GTK_WINDOW_TOPLEVEL);
gtk3_widgets[_GTK_TOOLTIP_TYPE] = result;
}
result = gtk3_widgets[_GTK_TOOLTIP_TYPE];
break;
case LIST:
case TABLE:
case TREE:
case TREE_CELL:
if (init_result = (NULL == gtk3_widgets[_GTK_TREE_VIEW_TYPE]))
{
gtk3_widgets[_GTK_TREE_VIEW_TYPE] =
(*fp_gtk_tree_view_new)();
}
result = gtk3_widgets[_GTK_TREE_VIEW_TYPE];
break;
case TITLED_BORDER:
if (init_result = (NULL == gtk3_widgets[_GTK_FRAME_TYPE]))
{
gtk3_widgets[_GTK_FRAME_TYPE] = fp_gtk_frame_new(NULL);
}
result = gtk3_widgets[_GTK_FRAME_TYPE];
break;
case POPUP_MENU:
if (init_result = (NULL == gtk3_widgets[_GTK_MENU_TYPE]))
{
gtk3_widgets[_GTK_MENU_TYPE] =
(*fp_gtk_menu_new)();
}
result = gtk3_widgets[_GTK_MENU_TYPE];
break;
case MENU:
case MENU_ITEM:
case MENU_ITEM_ACCELERATOR:
if (init_result = (NULL == gtk3_widgets[_GTK_MENU_ITEM_TYPE]))
{
gtk3_widgets[_GTK_MENU_ITEM_TYPE] =
(*fp_gtk_menu_item_new)();
}
result = gtk3_widgets[_GTK_MENU_ITEM_TYPE];
break;
case MENU_BAR:
if (init_result = (NULL == gtk3_widgets[_GTK_MENU_BAR_TYPE]))
{
gtk3_widgets[_GTK_MENU_BAR_TYPE] =
(*fp_gtk_menu_bar_new)();
}
result = gtk3_widgets[_GTK_MENU_BAR_TYPE];
break;
case COLOR_CHOOSER:
case OPTION_PANE:
if (init_result = (NULL == gtk3_widgets[_GTK_DIALOG_TYPE]))
{
gtk3_widgets[_GTK_DIALOG_TYPE] =
(*fp_gtk_dialog_new)();
}
result = gtk3_widgets[_GTK_DIALOG_TYPE];
break;
case POPUP_MENU_SEPARATOR:
if (init_result =
(NULL == gtk3_widgets[_GTK_SEPARATOR_MENU_ITEM_TYPE]))
{
gtk3_widgets[_GTK_SEPARATOR_MENU_ITEM_TYPE] =
(*fp_gtk_separator_menu_item_new)();
}
result = gtk3_widgets[_GTK_SEPARATOR_MENU_ITEM_TYPE];
break;
case HPROGRESS_BAR:
if (init_result = (NULL == gtk3_widgets[_GTK_HPROGRESS_BAR_TYPE]))
{
gtk3_widgets[_GTK_HPROGRESS_BAR_TYPE] =
(*fp_gtk_progress_bar_new)();
}
result = gtk3_widgets[_GTK_HPROGRESS_BAR_TYPE];
break;
case VPROGRESS_BAR:
if (init_result = (NULL == gtk3_widgets[_GTK_VPROGRESS_BAR_TYPE]))
{
gtk3_widgets[_GTK_VPROGRESS_BAR_TYPE] =
(*fp_gtk_progress_bar_new)();
/*
* Vertical JProgressBars always go bottom-to-top,
* regardless of the ComponentOrientation.
*/
(*fp_gtk_progress_bar_set_orientation)(
(GtkProgressBar *)gtk3_widgets[_GTK_VPROGRESS_BAR_TYPE],
GTK_PROGRESS_BOTTOM_TO_TOP);
}
result = gtk3_widgets[_GTK_VPROGRESS_BAR_TYPE];
break;
case RADIO_BUTTON:
if (init_result = (NULL == gtk3_widgets[_GTK_RADIO_BUTTON_TYPE]))
{
gtk3_widgets[_GTK_RADIO_BUTTON_TYPE] =
(*fp_gtk_radio_button_new)(NULL);
}
result = gtk3_widgets[_GTK_RADIO_BUTTON_TYPE];
break;
case RADIO_BUTTON_MENU_ITEM:
if (init_result =
(NULL == gtk3_widgets[_GTK_RADIO_MENU_ITEM_TYPE]))
{
gtk3_widgets[_GTK_RADIO_MENU_ITEM_TYPE] =
(*fp_gtk_radio_menu_item_new)(NULL);
}
result = gtk3_widgets[_GTK_RADIO_MENU_ITEM_TYPE];
break;
case SCROLL_PANE:
if (init_result =
(NULL == gtk3_widgets[_GTK_SCROLLED_WINDOW_TYPE]))
{
gtk3_widgets[_GTK_SCROLLED_WINDOW_TYPE] =
(*fp_gtk_scrolled_window_new)(NULL, NULL);
}
result = gtk3_widgets[_GTK_SCROLLED_WINDOW_TYPE];
break;
case SPINNER:
case SPINNER_ARROW_BUTTON:
case SPINNER_TEXT_FIELD:
if (init_result = (NULL == gtk3_widgets[_GTK_SPIN_BUTTON_TYPE]))
{
result = gtk3_widgets[_GTK_SPIN_BUTTON_TYPE] =
(*fp_gtk_spin_button_new)(NULL, 0, 0);
}
result = gtk3_widgets[_GTK_SPIN_BUTTON_TYPE];
break;
case TABBED_PANE:
case TABBED_PANE_TAB_AREA:
case TABBED_PANE_CONTENT:
case TABBED_PANE_TAB:
if (init_result = (NULL == gtk3_widgets[_GTK_NOTEBOOK_TYPE]))
{
gtk3_widgets[_GTK_NOTEBOOK_TYPE] =
(*fp_gtk_notebook_new)(NULL);
}
result = gtk3_widgets[_GTK_NOTEBOOK_TYPE];
break;
case TOGGLE_BUTTON:
if (init_result = (NULL == gtk3_widgets[_GTK_TOGGLE_BUTTON_TYPE]))
{
gtk3_widgets[_GTK_TOGGLE_BUTTON_TYPE] =
(*fp_gtk_toggle_button_new)(NULL);
}
result = gtk3_widgets[_GTK_TOGGLE_BUTTON_TYPE];
break;
case TOOL_BAR:
case TOOL_BAR_DRAG_WINDOW:
if (init_result = (NULL == gtk3_widgets[_GTK_TOOLBAR_TYPE]))
{
gtk3_widgets[_GTK_TOOLBAR_TYPE] =
(*fp_gtk_toolbar_new)(NULL);
}
result = gtk3_widgets[_GTK_TOOLBAR_TYPE];
break;
case TOOL_BAR_SEPARATOR:
if (init_result =
(NULL == gtk3_widgets[_GTK_SEPARATOR_TOOL_ITEM_TYPE]))
{
gtk3_widgets[_GTK_SEPARATOR_TOOL_ITEM_TYPE] =
(*fp_gtk_separator_tool_item_new)();
}
result = gtk3_widgets[_GTK_SEPARATOR_TOOL_ITEM_TYPE];
break;
case VIEWPORT:
if (init_result = (NULL == gtk3_widgets[_GTK_VIEWPORT_TYPE]))
{
GtkAdjustment *adjustment = create_adjustment();
gtk3_widgets[_GTK_VIEWPORT_TYPE] =
(*fp_gtk_viewport_new)(adjustment, adjustment);
}
result = gtk3_widgets[_GTK_VIEWPORT_TYPE];
break;
case VSCROLL_BAR:
case VSCROLL_BAR_BUTTON_UP:
case VSCROLL_BAR_BUTTON_DOWN:
case VSCROLL_BAR_TRACK:
case VSCROLL_BAR_THUMB:
if (init_result = (NULL == gtk3_widgets[_GTK_VSCROLLBAR_TYPE]))
{
gtk3_widgets[_GTK_VSCROLLBAR_TYPE] =
(*fp_gtk_vscrollbar_new)(create_adjustment());
}
result = gtk3_widgets[_GTK_VSCROLLBAR_TYPE];
break;
case VSEPARATOR:
if (init_result = (NULL == gtk3_widgets[_GTK_VSEPARATOR_TYPE]))
{
gtk3_widgets[_GTK_VSEPARATOR_TYPE] =
(*fp_gtk_vseparator_new)();
}
result = gtk3_widgets[_GTK_VSEPARATOR_TYPE];
break;
case VSLIDER:
case VSLIDER_THUMB:
case VSLIDER_TRACK:
if (init_result = (NULL == gtk3_widgets[_GTK_VSCALE_TYPE]))
{
gtk3_widgets[_GTK_VSCALE_TYPE] =
(*fp_gtk_scale_new)(GTK_ORIENTATION_VERTICAL, NULL);
}
result = gtk3_widgets[_GTK_VSCALE_TYPE];
/*
* Vertical JSliders start at the bottom, while vertical
* GtkVScale widgets start at the top (by default), so to fix
* this we set the "inverted" flag to get the Swing behavior.
*/
fp_gtk_range_set_inverted((GtkRange*)result, TRUE);
break;
case VSPLIT_PANE_DIVIDER:
if (init_result = (NULL == gtk3_widgets[_GTK_VPANED_TYPE]))
{
gtk3_widgets[_GTK_VPANED_TYPE] = (*fp_gtk_vpaned_new)();
}
result = gtk3_widgets[_GTK_VPANED_TYPE];
break;
default:
result = NULL;
break;
}
if (result != NULL && init_result)
{
if (widget_type == RADIO_BUTTON_MENU_ITEM ||
widget_type == CHECK_BOX_MENU_ITEM ||
widget_type == MENU_ITEM ||
widget_type == MENU ||
widget_type == POPUP_MENU_SEPARATOR)
{
GtkWidget *menu = gtk3_get_widget(POPUP_MENU);
(*fp_gtk_menu_shell_append)((GtkMenuShell *)menu, result);
}
else if (widget_type == POPUP_MENU)
{
GtkWidget *menu_bar = gtk3_get_widget(MENU_BAR);
GtkWidget *root_menu = (*fp_gtk_menu_item_new)();
(*fp_gtk_menu_item_set_submenu)((GtkMenuItem*)root_menu, result);
(*fp_gtk_menu_shell_append)((GtkMenuShell *)menu_bar, root_menu);
}
else if (widget_type == COMBO_BOX_TEXT_FIELD )
{
GtkWidget* combo = gtk3_get_widget(COMBO_BOX);
/*
* We add a regular GtkButton/GtkEntry to a GtkComboBoxEntry
* in order to trick engines into thinking it's a real combobox
* arrow button/text field.
*/
fp_gtk_container_add ((GtkContainer*)(combo), result);
GtkStyleContext* context = fp_gtk_widget_get_style_context (combo);
fp_gtk_style_context_add_class (context, "combobox-entry");
context = fp_gtk_widget_get_style_context (result);
fp_gtk_style_context_add_class (context, "combobox");
fp_gtk_style_context_add_class (context, "entry");
}
else if (widget_type == COMBO_BOX_ARROW_BUTTON )
{
GtkWidget* combo = gtk3_get_widget(COMBO_BOX);
fp_gtk_widget_set_parent(result, combo);
}
else if (widget_type != TOOL_TIP &&
widget_type != INTERNAL_FRAME &&
widget_type != OPTION_PANE)
{
(*fp_gtk_container_add)((GtkContainer *)gtk3_fixed, result);
}
(*fp_gtk_widget_realize)(result);
}
return result;
}
static void gtk3_paint_arrow(WidgetType widget_type, GtkStateType state_type,
GtkShadowType shadow_type, const gchar *detail,
gint x, gint y, gint width, gint height,
GtkArrowType arrow_type, gboolean fill)
{
gdouble xx, yy, a = G_PI;
int s = width;
gtk3_widget = gtk3_get_arrow(arrow_type, shadow_type);
switch (widget_type)
{
case SPINNER_ARROW_BUTTON:
s = (int)(0.4 * width + 0.5) + 1;
if (arrow_type == GTK_ARROW_UP) {
a = 0;
} else if (arrow_type == GTK_ARROW_DOWN) {
a = G_PI;
}
break;
case HSCROLL_BAR_BUTTON_LEFT:
s = (int)(0.5 * MIN(height, width * 2) + 0.5) + 1;
a = 3 * G_PI / 2;
break;
case HSCROLL_BAR_BUTTON_RIGHT:
s = (int)(0.5 * MIN(height, width * 2) + 0.5) + 1;
a = G_PI / 2;
break;
case VSCROLL_BAR_BUTTON_UP:
s = (int)(0.5 * MIN(height * 2, width) + 0.5) + 1;
a = 0;
break;
case VSCROLL_BAR_BUTTON_DOWN:
s = (int)(0.5 * MIN(height * 2, width) + 0.5) + 1;
a = G_PI;
break;
case COMBO_BOX_ARROW_BUTTON:
s = (int)(0.3 * height + 0.5) + 1;
a = G_PI;
break;
case TABLE:
s = (int)(0.8 * height + 0.5) + 1;
if (arrow_type == GTK_ARROW_UP) {
a = G_PI;
} else if (arrow_type == GTK_ARROW_DOWN) {
a = 0;
}
break;
case MENU_ITEM:
if (arrow_type == GTK_ARROW_UP) {
a = G_PI;
} else if (arrow_type == GTK_ARROW_DOWN) {
a = 0;
} else if (arrow_type == GTK_ARROW_RIGHT) {
a = G_PI / 2;
} else if (arrow_type == GTK_ARROW_LEFT) {
a = 3 * G_PI / 2;
}
break;
default:
if (arrow_type == GTK_ARROW_UP) {
a = G_PI;
} else if (arrow_type == GTK_ARROW_DOWN) {
a = 0;
} else if (arrow_type == GTK_ARROW_RIGHT) {
a = G_PI / 2;
} else if (arrow_type == GTK_ARROW_LEFT) {
a = 3 * G_PI / 2;
}
break;
}
if (s < width && s < height) {
xx = x + (0.5 * (width - s) + 0.5);
yy = y + (0.5 * (height - s) + 0.5);
} else {
xx = x;
yy = y;
}
GtkStyleContext* context = fp_gtk_widget_get_style_context (gtk3_widget);
fp_gtk_style_context_save (context);
if (detail != NULL) {
transform_detail_string(detail, context);
}
GtkStateFlags flags = get_gtk_flags(state_type);
fp_gtk_style_context_set_state (context, flags);
(*fp_gtk_render_arrow)(context, cr, a, xx, yy, s);
fp_gtk_style_context_restore (context);
}
static void gtk3_paint_box(WidgetType widget_type, GtkStateType state_type,
GtkShadowType shadow_type, const gchar *detail,
gint x, gint y, gint width, gint height,
gint synth_state, GtkTextDirection dir)
{
gtk3_widget = gtk3_get_widget(widget_type);
if (widget_type == HSLIDER_TRACK) {
/*
* For horizontal JSliders with right-to-left orientation, we need
* to set the "inverted" flag to match the native GTK behavior where
* the foreground highlight is on the right side of the slider thumb.
* This is needed especially for the ubuntulooks engine, which looks
* exclusively at the "inverted" flag to determine on which side of
* the thumb to paint the highlight...
*/
fp_gtk_range_set_inverted((GtkRange*)gtk3_widget, dir ==
GTK_TEXT_DIR_RTL);
/*
* Note however that other engines like clearlooks will look at both
* the "inverted" field and the text direction to determine how
* the foreground highlight is painted:
* !inverted && ltr --> paint highlight on left side
* !inverted && rtl --> paint highlight on right side
* inverted && ltr --> paint highlight on right side
* inverted && rtl --> paint highlight on left side
* So the only way to reliably get the desired results for horizontal
* JSlider (i.e., highlight on left side for LTR ComponentOrientation
* and highlight on right side for RTL ComponentOrientation) is to
* always override text direction as LTR, and then set the "inverted"
* flag accordingly (as we have done above).
*/
dir = GTK_TEXT_DIR_LTR;
}
/*
* Some engines (e.g. clearlooks) will paint the shadow of certain
* widgets (e.g. COMBO_BOX_ARROW_BUTTON) differently depending on the
* the text direction.
*/
gtk3_set_direction(gtk3_widget, dir);
GtkStyleContext* context = fp_gtk_widget_get_style_context (gtk3_widget);
fp_gtk_style_context_save (context);
transform_detail_string(detail, context);
GtkStateFlags flags = get_gtk_flags(state_type);
if (shadow_type == GTK_SHADOW_IN && widget_type != COMBO_BOX_ARROW_BUTTON) {
flags |= GTK_STATE_FLAG_ACTIVE;
}
if (synth_state & MOUSE_OVER) {
flags |= GTK_STATE_FLAG_PRELIGHT;
}
if (synth_state & FOCUSED) {
flags |= GTK_STATE_FLAG_FOCUSED;
}
if (synth_state & DEFAULT) {
fp_gtk_style_context_add_class (context, "default");
}
fp_gtk_style_context_set_state (context, flags);
if (fp_gtk_style_context_has_class(context, "progressbar")) {
fp_gtk_render_activity (context, cr, x, y, width, height);
} else {
fp_gtk_render_background (context, cr, x, y, width, height);
if (shadow_type != GTK_SHADOW_NONE) {
fp_gtk_render_frame(context, cr, x, y, width, height);
}
}
fp_gtk_style_context_restore (context);
/*
* Reset the text direction to the default value so that we don't
* accidentally affect other operations and widgets.
*/
gtk3_set_direction(gtk3_widget, GTK_TEXT_DIR_LTR);
}
static void gtk3_paint_box_gap(WidgetType widget_type, GtkStateType state_type,
GtkShadowType shadow_type, const gchar *detail,
gint x, gint y, gint width, gint height,
GtkPositionType gap_side, gint gap_x, gint gap_width)
{
gtk3_widget = gtk3_get_widget(widget_type);
GtkStyleContext* context = fp_gtk_widget_get_style_context (gtk3_widget);
fp_gtk_style_context_save (context);
GtkStateFlags flags = get_gtk_flags(state_type);
fp_gtk_style_context_set_state(context, flags);
if (detail != 0) {
transform_detail_string(detail, context);
}
fp_gtk_render_background(context, cr, x, y, width, height);
if (shadow_type != GTK_SHADOW_NONE) {
fp_gtk_render_frame_gap(context, cr, x, y, width, height, gap_side,
(gdouble)gap_x, (gdouble)gap_x + gap_width);
}
fp_gtk_style_context_restore (context);
}
static void gtk3_paint_check(WidgetType widget_type, gint synth_state,
const gchar *detail, gint x, gint y, gint width, gint height)
{
gtk3_widget = gtk3_get_widget(widget_type);
GtkStyleContext* context = fp_gtk_widget_get_style_context (gtk3_widget);
fp_gtk_style_context_save (context);
GtkStateFlags flags = get_gtk_state_flags(synth_state);
if (gtk3_version_3_14 && (synth_state & SELECTED)) {
flags = GTK_STATE_FLAG_CHECKED;
}
fp_gtk_style_context_set_state(context, flags);
fp_gtk_style_context_add_class (context, "check");
fp_gtk_render_check (context, cr, x, y, width, height);
fp_gtk_style_context_restore (context);
}
static void gtk3_paint_expander(WidgetType widget_type, GtkStateType state_type,
const gchar *detail, gint x, gint y, gint width, gint height,
GtkExpanderStyle expander_style)
{
gtk3_widget = gtk3_get_widget(widget_type);
GtkStyleContext* context = fp_gtk_widget_get_style_context (gtk3_widget);
fp_gtk_style_context_save (context);
GtkStateFlags flags = get_gtk_flags(state_type);
if (expander_style == GTK_EXPANDER_EXPANDED) {
flags |= GTK_STATE_FLAG_ACTIVE;
}
fp_gtk_style_context_set_state(context, flags);
if (detail != 0) {
transform_detail_string(detail, context);
}
fp_gtk_render_expander (context, cr, x + 2, y + 2, width - 4, height - 4);
fp_gtk_style_context_restore (context);
}
static void gtk3_paint_extension(WidgetType widget_type, GtkStateType state_type,
GtkShadowType shadow_type, const gchar *detail,
gint x, gint y, gint width, gint height, GtkPositionType gap_side)
{
gtk3_widget = gtk3_get_widget(widget_type);
GtkStyleContext* context = fp_gtk_widget_get_style_context (gtk3_widget);
fp_gtk_style_context_save (context);
GtkStateFlags flags = GTK_STATE_FLAG_NORMAL;
if (state_type == 0) {
flags = GTK_STATE_FLAG_ACTIVE;
}
fp_gtk_style_context_set_state(context, flags);
if (detail != 0) {
transform_detail_string(detail, context);
}
switch(gap_side) {
case GTK_POS_LEFT:
fp_gtk_style_context_add_class(context, "right");
break;
case GTK_POS_RIGHT:
fp_gtk_style_context_add_class(context, "left");
break;
case GTK_POS_TOP:
fp_gtk_style_context_add_class(context, "bottom");
break;
case GTK_POS_BOTTOM:
fp_gtk_style_context_add_class(context, "top");
break;
default:
break;
}
fp_gtk_render_extension(context, cr, x, y, width, height, gap_side);
fp_gtk_style_context_restore (context);
}
static void gtk3_paint_flat_box(WidgetType widget_type, GtkStateType state_type,
GtkShadowType shadow_type, const gchar *detail,
gint x, gint y, gint width, gint height, gboolean has_focus)
{
if (state_type == GTK_STATE_PRELIGHT &&
(widget_type == CHECK_BOX || widget_type == RADIO_BUTTON)) {
return;
}
gtk3_widget = gtk3_get_widget(widget_type);
GtkStyleContext* context = fp_gtk_widget_get_style_context (gtk3_widget);
fp_gtk_style_context_save (context);
if (detail != 0) {
transform_detail_string(detail, context);
}
GtkStateFlags flags = get_gtk_flags(state_type);
if (has_focus) {
flags |= GTK_STATE_FLAG_FOCUSED;
}
fp_gtk_style_context_set_state (context, flags);
if (widget_type == COMBO_BOX_TEXT_FIELD) {
width += height /2;
}
fp_gtk_render_background (context, cr, x, y, width, height);
fp_gtk_style_context_restore (context);
}
static void gtk3_paint_focus(WidgetType widget_type, GtkStateType state_type,
const char *detail, gint x, gint y, gint width, gint height)
{
gtk3_widget = gtk3_get_widget(widget_type);
GtkStyleContext* context = fp_gtk_widget_get_style_context (gtk3_widget);
fp_gtk_style_context_save (context);
transform_detail_string(detail, context);
fp_gtk_render_focus (context, cr, x, y, width, height);
fp_gtk_style_context_restore (context);
}
static void gtk3_paint_handle(WidgetType widget_type, GtkStateType state_type,
GtkShadowType shadow_type, const gchar *detail,
gint x, gint y, gint width, gint height, GtkOrientation orientation)
{
gtk3_widget = gtk3_get_widget(widget_type);
GtkStyleContext* context = fp_gtk_widget_get_style_context (gtk3_widget);
fp_gtk_style_context_save (context);
GtkStateFlags flags = get_gtk_flags(state_type);
fp_gtk_style_context_set_state(context, GTK_STATE_FLAG_PRELIGHT);
if (detail != 0) {
transform_detail_string(detail, context);
fp_gtk_style_context_add_class (context, "handlebox_bin");
}
fp_gtk_render_handle(context, cr, x, y, width, height);
fp_gtk_render_background(context, cr, x, y, width, height);
fp_gtk_style_context_restore (context);
}
static void gtk3_paint_hline(WidgetType widget_type, GtkStateType state_type,
const gchar *detail, gint x, gint y, gint width, gint height)
{
gtk3_widget = gtk3_get_widget(widget_type);
GtkStyleContext* context = fp_gtk_widget_get_style_context (gtk3_widget);
fp_gtk_style_context_save (context);
if (detail != 0) {
transform_detail_string(detail, context);
}
fp_gtk_render_line(context, cr, x, y, x + width, y);
fp_gtk_style_context_restore (context);
}
static void gtk3_paint_vline(WidgetType widget_type, GtkStateType state_type,
const gchar *detail, gint x, gint y, gint width, gint height)
{
gtk3_widget = gtk3_get_widget(widget_type);
GtkStyleContext* context = fp_gtk_widget_get_style_context (gtk3_widget);
fp_gtk_style_context_save (context);
if (detail != 0) {
transform_detail_string(detail, context);
}
fp_gtk_render_line(context, cr, x, y, x, y + height);
fp_gtk_style_context_restore (context);
}
static void gtk3_paint_option(WidgetType widget_type, gint synth_state,
const gchar *detail, gint x, gint y, gint width, gint height)
{
gtk3_widget = gtk3_get_widget(widget_type);
GtkStyleContext* context = fp_gtk_widget_get_style_context (gtk3_widget);
fp_gtk_style_context_save (context);
GtkStateFlags flags = get_gtk_state_flags(synth_state);
if (gtk3_version_3_14 && (synth_state & SELECTED)) {
flags = GTK_STATE_FLAG_CHECKED;
}
fp_gtk_style_context_set_state(context, flags);
if (detail != 0) {
transform_detail_string(detail, context);
}
fp_gtk_render_option(context, cr, x, y, width, height);
fp_gtk_style_context_restore (context);
}
static void gtk3_paint_shadow(WidgetType widget_type, GtkStateType state_type,
GtkShadowType shadow_type, const gchar *detail,
gint x, gint y, gint width, gint height,
gint synth_state, GtkTextDirection dir)
{
if (shadow_type == GTK_SHADOW_NONE) {
return;
}
gtk3_widget = gtk3_get_widget(widget_type);
/*
* Some engines (e.g. clearlooks) will paint the shadow of certain
* widgets (e.g. COMBO_BOX_TEXT_FIELD) differently depending on the
* the text direction.
*/
gtk3_set_direction(gtk3_widget, dir);
GtkStyleContext* context = fp_gtk_widget_get_style_context (gtk3_widget);
fp_gtk_style_context_save (context);
if (detail) {
transform_detail_string(detail, context);
}
GtkStateFlags flags = get_gtk_flags(state_type);
if (synth_state & MOUSE_OVER) {
flags |= GTK_STATE_FLAG_PRELIGHT;
}
if (synth_state & FOCUSED) {
flags |= GTK_STATE_FLAG_FOCUSED;
}
fp_gtk_style_context_set_state (context, flags);
if (widget_type == COMBO_BOX_TEXT_FIELD) {
width += height / 2;
}
fp_gtk_render_frame(context, cr, x, y, width, height);
fp_gtk_style_context_restore (context);
/*
* Reset the text direction to the default value so that we don't
* accidentally affect other operations and widgets.
*/
gtk3_set_direction(gtk3_widget, GTK_TEXT_DIR_LTR);
}
static void gtk3_paint_slider(WidgetType widget_type, GtkStateType state_type,
GtkShadowType shadow_type, const gchar *detail,
gint x, gint y, gint width, gint height, GtkOrientation orientation,
gboolean has_focus)
{
gtk3_widget = gtk3_get_widget(widget_type);
GtkStyleContext* context = fp_gtk_widget_get_style_context (gtk3_widget);
fp_gtk_style_context_save (context);
if (detail) {
transform_detail_string(detail, context);
}
GtkStateFlags flags = get_gtk_flags(state_type);
if (state_type == GTK_STATE_ACTIVE) {
flags |= GTK_STATE_FLAG_PRELIGHT;
}
if (has_focus) {
flags |= GTK_STATE_FLAG_FOCUSED;
}
fp_gtk_style_context_set_state (context, flags);
(*fp_gtk_render_slider)(context, cr, x, y, width, height, orientation);
fp_gtk_style_context_restore (context);
}
static void gtk3_paint_background(WidgetType widget_type,
GtkStateType state_type, gint x, gint y, gint width, gint height) {
gtk3_widget = gtk3_get_widget(widget_type);
GtkStyleContext* context = fp_gtk_widget_get_style_context (gtk3_widget);
fp_gtk_style_context_save (context);
GtkStateFlags flags = get_gtk_flags(state_type);
fp_gtk_style_context_set_state (context, flags);
fp_gtk_render_background (context, cr, x, y, width, height);
fp_gtk_style_context_restore (context);
}
static GdkPixbuf *gtk3_get_stock_icon(gint widget_type, const gchar *stock_id,
GtkIconSize size, GtkTextDirection direction, const char *detail)
{
int sz;
switch(size) {
case GTK_ICON_SIZE_MENU:
sz = 16;
break;
case GTK_ICON_SIZE_SMALL_TOOLBAR:
sz = 18;
break;
case GTK_ICON_SIZE_LARGE_TOOLBAR:
sz = 24;
break;
case GTK_ICON_SIZE_BUTTON:
sz = 20;
break;
case GTK_ICON_SIZE_DND:
sz = 32;
break;
case GTK_ICON_SIZE_DIALOG:
sz = 48;
break;
default:
sz = 0;
break;
}
init_containers();
gtk3_widget = gtk3_get_widget((widget_type < 0) ? IMAGE : widget_type);
(*fp_gtk_widget_set_direction)(gtk3_widget, direction);
GtkIconTheme *icon_theme = fp_gtk_icon_theme_get_default();
GdkPixbuf *result = fp_gtk_icon_theme_load_icon(icon_theme, stock_id, sz,
GTK_ICON_LOOKUP_USE_BUILTIN, NULL);
return result;
}
static jboolean gtk3_get_pixbuf_data(JNIEnv *env, GdkPixbuf* pixbuf,
jmethodID icon_upcall_method, jobject this) {
if (!pixbuf) {
return JNI_FALSE;
}
guchar *pixbuf_data = (*fp_gdk_pixbuf_get_pixels)(pixbuf);
if (pixbuf_data) {
int row_stride = (*fp_gdk_pixbuf_get_rowstride)(pixbuf);
int width = (*fp_gdk_pixbuf_get_width)(pixbuf);
int height = (*fp_gdk_pixbuf_get_height)(pixbuf);
int bps = (*fp_gdk_pixbuf_get_bits_per_sample)(pixbuf);
int channels = (*fp_gdk_pixbuf_get_n_channels)(pixbuf);
gboolean alpha = (*fp_gdk_pixbuf_get_has_alpha)(pixbuf);
jbyteArray data = (*env)->NewByteArray(env, (row_stride * height));
JNU_CHECK_EXCEPTION_RETURN(env, JNI_FALSE);
(*env)->SetByteArrayRegion(env, data, 0, (row_stride * height),
(jbyte *)pixbuf_data);
(*fp_g_object_unref)(pixbuf);
/* Call the callback method to create the image on the Java side. */
(*env)->CallVoidMethod(env, this, icon_upcall_method, data,
width, height, row_stride, bps, channels, alpha);
return JNI_TRUE;
}
return JNI_FALSE;
}
static jboolean gtk3_get_file_icon_data(JNIEnv *env, const char *filename,
GError **error, jmethodID icon_upcall_method, jobject this) {
GdkPixbuf* pixbuf = fp_gdk_pixbuf_new_from_file(filename, error);
return gtk3_get_pixbuf_data(env, pixbuf, icon_upcall_method, this);
}
static jboolean gtk3_get_icon_data(JNIEnv *env, gint widget_type,
const gchar *stock_id, GtkIconSize size,
GtkTextDirection direction, const char *detail,
jmethodID icon_upcall_method, jobject this) {
GdkPixbuf* pixbuf = gtk3_get_stock_icon(widget_type, stock_id, size,
direction, detail);
return gtk3_get_pixbuf_data(env, pixbuf, icon_upcall_method, this);
}
/*************************************************/
static gint gtk3_get_xthickness(JNIEnv *env, WidgetType widget_type)
{
init_containers();
gtk3_widget = gtk3_get_widget(widget_type);
GtkStyleContext* context = fp_gtk_widget_get_style_context (gtk3_widget);
if (context) {
GtkBorder padding;
fp_gtk_style_context_get_padding(context, 0, &padding);
return padding.left + 1;
}
return 0;
}
static gint gtk3_get_ythickness(JNIEnv *env, WidgetType widget_type)
{
init_containers();
gtk3_widget = gtk3_get_widget(widget_type);
GtkStyleContext* context = fp_gtk_widget_get_style_context (gtk3_widget);
if (context) {
GtkBorder padding;
fp_gtk_style_context_get_padding(context, 0, &padding);
return padding.top + 1;
}
return 0;
}
/*************************************************/
static guint8 recode_color(gdouble channel)
{
guint16 result = (guint16)(channel * 65535);
if (result > 65535) {
result = 65535;
}
return (guint8)( result >> 8);
}
static GtkStateFlags gtk3_get_state_flags(GtkStateType state_type) {
switch (state_type)
{
case GTK_STATE_NORMAL:
return GTK_STATE_FLAG_NORMAL;
case GTK_STATE_ACTIVE:
return GTK_STATE_FLAG_ACTIVE;
case GTK_STATE_PRELIGHT:
return GTK_STATE_FLAG_PRELIGHT;
case GTK_STATE_SELECTED:
return GTK_STATE_FLAG_SELECTED;
case GTK_STATE_INSENSITIVE:
return GTK_STATE_FLAG_INSENSITIVE;
case GTK_STATE_INCONSISTENT:
return GTK_STATE_FLAG_INCONSISTENT;
case GTK_STATE_FOCUSED:
return GTK_STATE_FLAG_FOCUSED;
}
return 0;
}
static void rgb_to_hls (gdouble *r, gdouble *g, gdouble *b) {
gdouble min;
gdouble max;
gdouble red;
gdouble green;
gdouble blue;
gdouble h, l, s;
gdouble delta;
red = *r;
green = *g;
blue = *b;
if (red > green)
{
if (red > blue)
max = red;
else
max = blue;
if (green < blue)
min = green;
else
min = blue;
}
else
{
if (green > blue)
max = green;
else
max = blue;
if (red < blue)
min = red;
else
min = blue;
}
l = (max + min) / 2;
s = 0;
h = 0;
if (max != min)
{
if (l <= 0.5)
s = (max - min) / (max + min);
else
s = (max - min) / (2 - max - min);
delta = max -min;
if (red == max)
h = (green - blue) / delta;
else if (green == max)
h = 2 + (blue - red) / delta;
else if (blue == max)
h = 4 + (red - green) / delta;
h *= 60;
if (h < 0.0)
h += 360;
}
*r = h;
*g = l;
*b = s;
}
static void hls_to_rgb (gdouble *h, gdouble *l, gdouble *s)
{
gdouble hue;
gdouble lightness;
gdouble saturation;
gdouble m1, m2;
gdouble r, g, b;
lightness = *l;
saturation = *s;
if (lightness <= 0.5)
m2 = lightness * (1 + saturation);
else
m2 = lightness + saturation - lightness * saturation;
m1 = 2 * lightness - m2;
if (saturation == 0)
{
*h = lightness;
*l = lightness;
*s = lightness;
}
else
{
hue = *h + 120;
while (hue > 360)
hue -= 360;
while (hue < 0)
hue += 360;
if (hue < 60)
r = m1 + (m2 - m1) * hue / 60;
else if (hue < 180)
r = m2;
else if (hue < 240)
r = m1 + (m2 - m1) * (240 - hue) / 60;
else
r = m1;
hue = *h;
while (hue > 360)
hue -= 360;
while (hue < 0)
hue += 360;
if (hue < 60)
g = m1 + (m2 - m1) * hue / 60;
else if (hue < 180)
g = m2;
else if (hue < 240)
g = m1 + (m2 - m1) * (240 - hue) / 60;
else
g = m1;
hue = *h - 120;
while (hue > 360)
hue -= 360;
while (hue < 0)
hue += 360;
if (hue < 60)
b = m1 + (m2 - m1) * hue / 60;
else if (hue < 180)
b = m2;
else if (hue < 240)
b = m1 + (m2 - m1) * (240 - hue) / 60;
else
b = m1;
*h = r;
*l = g;
*s = b;
}
}
static void gtk3_style_shade (const GdkRGBA *a, GdkRGBA *b, gdouble k) {
gdouble red = a->red;
gdouble green = a->green;
gdouble blue = a->blue;
rgb_to_hls (&red, &green, &blue);
green *= k;
if (green > 1.0)
green = 1.0;
else if (green < 0.0)
green = 0.0;
blue *= k;
if (blue > 1.0)
blue = 1.0;
else if (blue < 0.0)
blue = 0.0;
hls_to_rgb (&red, &green, &blue);
b->red = red;
b->green = green;
b->blue = blue;
}
static GdkRGBA gtk3_get_color_for_flags(GtkStyleContext* context,
GtkStateFlags flags, ColorType color_type) {
GdkRGBA c, color;
color.alpha = 1;
switch (color_type)
{
case FOREGROUND:
case TEXT_FOREGROUND:
fp_gtk_style_context_get_color(context, flags, &color);
break;
case BACKGROUND:
case TEXT_BACKGROUND:
fp_gtk_style_context_get_background_color(context, flags, &color);
break;
case LIGHT:
c = gtk3_get_color_for_flags(context, flags, BACKGROUND);
gtk3_style_shade(&c, &color, LIGHTNESS_MULT);
break;
case DARK:
c = gtk3_get_color_for_flags(context, flags, BACKGROUND);
gtk3_style_shade (&c, &color, DARKNESS_MULT);
break;
case MID:
{
GdkRGBA c1 = gtk3_get_color_for_flags(context, flags, LIGHT);
GdkRGBA c2 = gtk3_get_color_for_flags(context, flags, DARK);
color.red = (c1.red + c2.red) / 2;
color.green = (c1.green + c2.green) / 2;
color.blue = (c1.blue + c2.blue) / 2;
}
break;
case FOCUS:
case BLACK:
color.red = 0;
color.green = 0;
color.blue = 0;
break;
case WHITE:
color.red = 1;
color.green = 1;
color.blue = 1;
break;
}
return color;
}
static gint gtk3_get_color_for_state(JNIEnv *env, WidgetType widget_type,
GtkStateType state_type, ColorType color_type)
{
gint result = 0;
GtkStateFlags flags = gtk3_get_state_flags(state_type);
init_containers();
gtk3_widget = gtk3_get_widget(widget_type);
GtkStyleContext* context = fp_gtk_widget_get_style_context(gtk3_widget);
if (widget_type == TOOL_TIP) {
fp_gtk_style_context_add_class(context, "tooltip");
}
if (widget_type == CHECK_BOX_MENU_ITEM
|| widget_type == RADIO_BUTTON_MENU_ITEM) {
flags &= GTK_STATE_FLAG_NORMAL | GTK_STATE_FLAG_SELECTED
| GTK_STATE_FLAG_INSENSITIVE | GTK_STATE_FLAG_FOCUSED;
}
GdkRGBA color = gtk3_get_color_for_flags(context, flags, color_type);
if (recode_color(color.alpha) == 0) {
color = gtk3_get_color_for_flags(
fp_gtk_widget_get_style_context(gtk3_get_widget(INTERNAL_FRAME)),
0, BACKGROUND);
}
result = recode_color(color.alpha) << 24 | recode_color(color.red) << 16 |
recode_color(color.green) << 8 | recode_color(color.blue);
return result;
}
/*************************************************/
static jobject create_Boolean(JNIEnv *env, jboolean boolean_value);
static jobject create_Integer(JNIEnv *env, jint int_value);
static jobject create_Long(JNIEnv *env, jlong long_value);
static jobject create_Float(JNIEnv *env, jfloat float_value);
static jobject create_Double(JNIEnv *env, jdouble double_value);
static jobject create_Character(JNIEnv *env, jchar char_value);
static jobject create_Insets(JNIEnv *env, GtkBorder *border);
static jobject gtk3_get_class_value(JNIEnv *env, WidgetType widget_type,
const char* key)
{
init_containers();
gtk3_widget = gtk3_get_widget(widget_type);
GValue value = { 0, { { 0 } } };
GParamSpec* param = (*fp_gtk_widget_class_find_style_property)(
((GTypeInstance*)gtk3_widget)->g_class, key);
if ( param )
{
(*fp_g_value_init)( &value, param->value_type );
(*fp_gtk_widget_style_get_property)(gtk3_widget, key, &value);
if ((*fp_g_type_is_a)( param->value_type, G_TYPE_BOOLEAN ))
{
gboolean val = (*fp_g_value_get_boolean)(&value);
return create_Boolean(env, (jboolean)val);
}
else if ((*fp_g_type_is_a)( param->value_type, G_TYPE_CHAR ))
{
gchar val = (*fp_g_value_get_char)(&value);
return create_Character(env, (jchar)val);
}
else if ((*fp_g_type_is_a)( param->value_type, G_TYPE_UCHAR ))
{
guchar val = (*fp_g_value_get_uchar)(&value);
return create_Character(env, (jchar)val);
}
else if ((*fp_g_type_is_a)( param->value_type, G_TYPE_INT ))
{
gint val = (*fp_g_value_get_int)(&value);
return create_Integer(env, (jint)val);
}
else if ((*fp_g_type_is_a)( param->value_type, G_TYPE_UINT ))
{
guint val = (*fp_g_value_get_uint)(&value);
return create_Integer(env, (jint)val);
}
else if ((*fp_g_type_is_a)( param->value_type, G_TYPE_LONG ))
{
glong val = (*fp_g_value_get_long)(&value);
return create_Long(env, (jlong)val);
}
else if ((*fp_g_type_is_a)( param->value_type, G_TYPE_ULONG ))
{
gulong val = (*fp_g_value_get_ulong)(&value);
return create_Long(env, (jlong)val);
}
else if ((*fp_g_type_is_a)( param->value_type, G_TYPE_INT64 ))
{
gint64 val = (*fp_g_value_get_int64)(&value);
return create_Long(env, (jlong)val);
}
else if ((*fp_g_type_is_a)( param->value_type, G_TYPE_UINT64 ))
{
guint64 val = (*fp_g_value_get_uint64)(&value);
return create_Long(env, (jlong)val);
}
else if ((*fp_g_type_is_a)( param->value_type, G_TYPE_FLOAT ))
{
gfloat val = (*fp_g_value_get_float)(&value);
return create_Float(env, (jfloat)val);
}
else if ((*fp_g_type_is_a)( param->value_type, G_TYPE_DOUBLE ))
{
gdouble val = (*fp_g_value_get_double)(&value);
return create_Double(env, (jdouble)val);
}
else if ((*fp_g_type_is_a)( param->value_type, G_TYPE_ENUM ))
{
gint val = (*fp_g_value_get_enum)(&value);
return create_Integer(env, (jint)val);
}
else if ((*fp_g_type_is_a)( param->value_type, G_TYPE_FLAGS ))
{
guint val = (*fp_g_value_get_flags)(&value);
return create_Integer(env, (jint)val);
}
else if ((*fp_g_type_is_a)( param->value_type, G_TYPE_STRING ))
{
const gchar* val = (*fp_g_value_get_string)(&value);
/* We suppose that all values come in C locale and
* utf-8 representation of a string is the same as
* the string itself. If this isn't so we should
* use g_convert.
*/
return (*env)->NewStringUTF(env, val);
}
else if ((*fp_g_type_is_a)( param->value_type, GTK_TYPE_BORDER ))
{
GtkBorder *border = (GtkBorder*)(*fp_g_value_get_boxed)(&value);
return border ? create_Insets(env, border) : NULL;
}
/* TODO: Other types are not supported yet.*/
/* else if((*fp_g_type_is_a)( param->value_type, G_TYPE_PARAM ))
{
GParamSpec* val = (*fp_g_value_get_param)(&value);
printf( "Param: %p\n", val );
}
else if((*fp_g_type_is_a)( param->value_type, G_TYPE_BOXED ))
{
gpointer* val = (*fp_g_value_get_boxed)(&value);
printf( "Boxed: %p\n", val );
}
else if((*fp_g_type_is_a)( param->value_type, G_TYPE_POINTER ))
{
gpointer* val = (*fp_g_value_get_pointer)(&value);
printf( "Pointer: %p\n", val );
}
else if((*fp_g_type_is_a)( param->value_type, G_TYPE_OBJECT ))
{
GObject* val = (GObject*)(*fp_g_value_get_object)(&value);
printf( "Object: %p\n", val );
}*/
}
return NULL;
}
static void gtk3_set_range_value(WidgetType widget_type, jdouble value,
jdouble min, jdouble max, jdouble visible)
{
GtkAdjustment *adj;
gtk3_widget = gtk3_get_widget(widget_type);
adj = (*fp_gtk_range_get_adjustment)((GtkRange *)gtk3_widget);
fp_gtk_adjustment_set_value(adj, value);
fp_gtk_adjustment_set_lower(adj, min);
fp_gtk_adjustment_set_upper(adj, max);
fp_gtk_adjustment_set_page_size(adj, visible);
}
/*************************************************/
static jobject create_Object(JNIEnv *env, jmethodID *cid,
const char* class_name,
const char* signature,
jvalue* value)
{
jclass class;
jobject result;
class = (*env)->FindClass(env, class_name);
if (class == NULL)
return NULL; /* can't find/load the class, exception thrown */
if (*cid == NULL)
{
*cid = (*env)->GetMethodID(env, class, "<init>", signature);
if (*cid == NULL)
{
(*env)->DeleteLocalRef(env, class);
return NULL; /* can't find/get the method, exception thrown */
}
}
result = (*env)->NewObjectA(env, class, *cid, value);
(*env)->DeleteLocalRef(env, class);
return result;
}
jobject create_Boolean(JNIEnv *env, jboolean boolean_value)
{
static jmethodID cid = NULL;
jvalue value;
value.z = boolean_value;
return create_Object(env, &cid, "java/lang/Boolean", "(Z)V", &value);
}
jobject create_Integer(JNIEnv *env, jint int_value)
{
static jmethodID cid = NULL;
jvalue value;
value.i = int_value;
return create_Object(env, &cid, "java/lang/Integer", "(I)V", &value);
}
jobject create_Long(JNIEnv *env, jlong long_value)
{
static jmethodID cid = NULL;
jvalue value;
value.j = long_value;
return create_Object(env, &cid, "java/lang/Long", "(J)V", &value);
}
jobject create_Float(JNIEnv *env, jfloat float_value)
{
static jmethodID cid = NULL;
jvalue value;
value.f = float_value;
return create_Object(env, &cid, "java/lang/Float", "(F)V", &value);
}
jobject create_Double(JNIEnv *env, jdouble double_value)
{
static jmethodID cid = NULL;
jvalue value;
value.d = double_value;
return create_Object(env, &cid, "java/lang/Double", "(D)V", &value);
}
jobject create_Character(JNIEnv *env, jchar char_value)
{
static jmethodID cid = NULL;
jvalue value;
value.c = char_value;
return create_Object(env, &cid, "java/lang/Character", "(C)V", &value);
}
jobject create_Insets(JNIEnv *env, GtkBorder *border)
{
static jmethodID cid = NULL;
jvalue values[4];
values[0].i = border->top;
values[1].i = border->left;
values[2].i = border->bottom;
values[3].i = border->right;
return create_Object(env, &cid, "java/awt/Insets", "(IIII)V", values);
}
/*********************************************/
static jstring gtk3_get_pango_font_name(JNIEnv *env, WidgetType widget_type)
{
init_containers();
gtk3_widget = gtk3_get_widget(widget_type);
jstring result = NULL;
GtkStyleContext* context = fp_gtk_widget_get_style_context (gtk3_widget);
if (context)
{
PangoFontDescription* fd = fp_gtk_style_context_get_font(context, 0);
gchar* val = (*fp_pango_font_description_to_string)(fd);
result = (*env)->NewStringUTF(env, val);
(*fp_g_free)( val );
}
return result;
}
/***********************************************/
static jobject get_string_property(JNIEnv *env, GtkSettings* settings,
const gchar* key) {
jobject result = NULL;
gchar* strval = NULL;
(*fp_g_object_get)(settings, key, &strval, NULL);
result = (*env)->NewStringUTF(env, strval);
(*fp_g_free)(strval);
return result;
}
static jobject get_integer_property(JNIEnv *env, GtkSettings* settings,
const gchar* key) {
gint intval = 0;
(*fp_g_object_get)(settings, key, &intval, NULL);
return create_Integer(env, intval);
}
static jobject get_boolean_property(JNIEnv *env, GtkSettings* settings,
const gchar* key) {
gint intval = 0;
(*fp_g_object_get)(settings, key, &intval, NULL);
return create_Boolean(env, intval);
}
static jobject gtk3_get_setting(JNIEnv *env, Setting property)
{
GtkSettings* settings = (*fp_gtk_settings_get_default)();
switch (property)
{
case GTK_FONT_NAME:
return get_string_property(env, settings, "gtk-font-name");
case GTK_ICON_SIZES:
return get_string_property(env, settings, "gtk-icon-sizes");
case GTK_CURSOR_BLINK:
return get_boolean_property(env, settings, "gtk-cursor-blink");
case GTK_CURSOR_BLINK_TIME:
return get_integer_property(env, settings, "gtk-cursor-blink-time");
}
return NULL;
}
static void transform_detail_string (const gchar *detail,
GtkStyleContext *context) {
if (!detail)
return;
if (strcmp (detail, "arrow") == 0)
fp_gtk_style_context_add_class (context, "arrow");
else if (strcmp (detail, "button") == 0)
fp_gtk_style_context_add_class (context, "button");
else if (strcmp (detail, "buttondefault") == 0)
{
fp_gtk_style_context_add_class (context, "button");
fp_gtk_style_context_add_class (context, "default");
}
else if (strcmp (detail, "calendar") == 0)
fp_gtk_style_context_add_class (context, "calendar");
else if (strcmp (detail, "cellcheck") == 0)
{
fp_gtk_style_context_add_class (context, "cell");
fp_gtk_style_context_add_class (context, "check");
}
else if (strcmp (detail, "cellradio") == 0)
{
fp_gtk_style_context_add_class (context, "cell");
fp_gtk_style_context_add_class (context, "radio");
}
else if (strcmp (detail, "checkbutton") == 0)
fp_gtk_style_context_add_class (context, "check");
else if (strcmp (detail, "check") == 0)
{
fp_gtk_style_context_add_class (context, "check");
fp_gtk_style_context_add_class (context, "menu");
}
else if (strcmp (detail, "radiobutton") == 0)
{
fp_gtk_style_context_add_class (context, "radio");
}
else if (strcmp (detail, "option") == 0)
{
fp_gtk_style_context_add_class (context, "radio");
fp_gtk_style_context_add_class (context, "menu");
}
else if (strcmp (detail, "entry") == 0 ||
strcmp (detail, "entry_bg") == 0)
fp_gtk_style_context_add_class (context, "entry");
else if (strcmp (detail, "expander") == 0)
fp_gtk_style_context_add_class (context, "expander");
else if (strcmp (detail, "tooltip") == 0)
fp_gtk_style_context_add_class (context, "tooltip");
else if (strcmp (detail, "frame") == 0)
fp_gtk_style_context_add_class (context, "frame");
else if (strcmp (detail, "scrolled_window") == 0)
fp_gtk_style_context_add_class (context, "scrolled-window");
else if (strcmp (detail, "viewport") == 0 ||
strcmp (detail, "viewportbin") == 0)
fp_gtk_style_context_add_class (context, "viewport");
else if (strncmp (detail, "trough", 6) == 0)
fp_gtk_style_context_add_class (context, "trough");
else if (strcmp (detail, "spinbutton") == 0)
fp_gtk_style_context_add_class (context, "spinbutton");
else if (strcmp (detail, "spinbutton_up") == 0)
{
fp_gtk_style_context_add_class (context, "spinbutton");
fp_gtk_style_context_add_class (context, "button");
fp_gtk_style_context_set_junction_sides (context, GTK_JUNCTION_BOTTOM);
}
else if (strcmp (detail, "spinbutton_down") == 0)
{
fp_gtk_style_context_add_class (context, "spinbutton");
fp_gtk_style_context_add_class (context, "button");
fp_gtk_style_context_set_junction_sides (context, GTK_JUNCTION_TOP);
}
else if ((detail[0] == 'h' || detail[0] == 'v') &&
strncmp (&detail[1], "scrollbar_", 9) == 0)
{
fp_gtk_style_context_add_class (context, "button");
fp_gtk_style_context_add_class (context, "scrollbar");
}
else if (strcmp (detail, "slider") == 0)
{
fp_gtk_style_context_add_class (context, "slider");
fp_gtk_style_context_add_class (context, "scrollbar");
}
else if (strcmp (detail, "vscale") == 0 ||
strcmp (detail, "hscale") == 0)
{
fp_gtk_style_context_add_class (context, "slider");
fp_gtk_style_context_add_class (context, "scale");
}
else if (strcmp (detail, "menuitem") == 0)
{
fp_gtk_style_context_add_class (context, "menuitem");
fp_gtk_style_context_add_class (context, "menu");
}
else if (strcmp (detail, "menu") == 0)
{
fp_gtk_style_context_add_class (context, "popup");
fp_gtk_style_context_add_class (context, "menu");
}
else if (strcmp (detail, "accellabel") == 0)
fp_gtk_style_context_add_class (context, "accelerator");
else if (strcmp (detail, "menubar") == 0)
fp_gtk_style_context_add_class (context, "menubar");
else if (strcmp (detail, "base") == 0)
fp_gtk_style_context_add_class (context, "background");
else if (strcmp (detail, "bar") == 0 ||
strcmp (detail, "progressbar") == 0)
fp_gtk_style_context_add_class (context, "progressbar");
else if (strcmp (detail, "toolbar") == 0)
fp_gtk_style_context_add_class (context, "toolbar");
else if (strcmp (detail, "handlebox_bin") == 0)
fp_gtk_style_context_add_class (context, "dock");
else if (strcmp (detail, "notebook") == 0)
fp_gtk_style_context_add_class (context, "notebook");
else if (strcmp (detail, "tab") == 0)
{
fp_gtk_style_context_add_class (context, "notebook");
fp_gtk_style_context_add_region (context, "tab", 0);
} else if (strcmp (detail, "paned") == 0) {
fp_gtk_style_context_add_class (context, "pane-separator");
}
else if (fp_g_str_has_prefix (detail, "cell"))
{
GtkRegionFlags row, col;
gboolean ruled = FALSE;
gchar** tokens;
guint i;
tokens = fp_g_strsplit (detail, "_", -1);
row = col = 0;
i = 0;
while (tokens[i])
{
if (strcmp (tokens[i], "even") == 0)
row |= GTK_REGION_EVEN;
else if (strcmp (tokens[i], "odd") == 0)
row |= GTK_REGION_ODD;
else if (strcmp (tokens[i], "start") == 0)
col |= GTK_REGION_FIRST;
else if (strcmp (tokens[i], "end") == 0)
col |= GTK_REGION_LAST;
else if (strcmp (tokens[i], "ruled") == 0)
ruled = TRUE;
else if (strcmp (tokens[i], "sorted") == 0)
col |= GTK_REGION_SORTED;
i++;
}
if (!ruled)
row &= ~(GTK_REGION_EVEN | GTK_REGION_ODD);
fp_gtk_style_context_add_class (context, "cell");
fp_gtk_style_context_add_region (context, "row", row);
fp_gtk_style_context_add_region (context, "column", col);
fp_g_strfreev (tokens);
}
}
static GdkWindow* gtk3_get_window(void *widget) {
return fp_gtk_widget_get_window((GtkWidget*)widget);
}
static void gtk3_init(GtkApi* gtk) {
gtk->version = GTK_3;
gtk->show_uri_load = &gtk3_show_uri_load;
gtk->unload = &gtk3_unload;
gtk->flush_event_loop = &flush_gtk_event_loop;
gtk->gtk_check_version = fp_gtk_check_version;
gtk->get_setting = &gtk3_get_setting;
gtk->paint_arrow = &gtk3_paint_arrow;
gtk->paint_box = &gtk3_paint_box;
gtk->paint_box_gap = &gtk3_paint_box_gap;
gtk->paint_expander = &gtk3_paint_expander;
gtk->paint_extension = &gtk3_paint_extension;
gtk->paint_flat_box = &gtk3_paint_flat_box;
gtk->paint_focus = &gtk3_paint_focus;
gtk->paint_handle = &gtk3_paint_handle;
gtk->paint_hline = &gtk3_paint_hline;
gtk->paint_vline = &gtk3_paint_vline;
gtk->paint_option = &gtk3_paint_option;
gtk->paint_shadow = &gtk3_paint_shadow;
gtk->paint_slider = &gtk3_paint_slider;
gtk->paint_background = &gtk3_paint_background;
gtk->paint_check = &gtk3_paint_check;
gtk->set_range_value = &gtk3_set_range_value;
gtk->init_painting = &gtk3_init_painting;
gtk->copy_image = &gtk3_copy_image;
gtk->get_xthickness = &gtk3_get_xthickness;
gtk->get_ythickness = &gtk3_get_ythickness;
gtk->get_color_for_state = &gtk3_get_color_for_state;
gtk->get_class_value = &gtk3_get_class_value;
gtk->get_pango_font_name = &gtk3_get_pango_font_name;
gtk->get_icon_data = &gtk3_get_icon_data;
gtk->get_file_icon_data = &gtk3_get_file_icon_data;
gtk->gdk_threads_enter = fp_gdk_threads_enter;
gtk->gdk_threads_leave = fp_gdk_threads_leave;
gtk->gtk_show_uri = fp_gtk_show_uri;
gtk->g_free = fp_g_free;
gtk->gtk_file_chooser_get_filename = fp_gtk_file_chooser_get_filename;
gtk->gtk_widget_hide = fp_gtk_widget_hide;
gtk->gtk_main_quit = fp_gtk_main_quit;
gtk->gtk_file_chooser_dialog_new = fp_gtk_file_chooser_dialog_new;
gtk->gtk_file_chooser_set_current_folder =
fp_gtk_file_chooser_set_current_folder;
gtk->gtk_file_chooser_set_filename = fp_gtk_file_chooser_set_filename;
gtk->gtk_file_chooser_set_current_name =
fp_gtk_file_chooser_set_current_name;
gtk->gtk_file_filter_add_custom = fp_gtk_file_filter_add_custom;
gtk->gtk_file_chooser_set_filter = fp_gtk_file_chooser_set_filter;
gtk->gtk_file_chooser_get_type = fp_gtk_file_chooser_get_type;
gtk->gtk_file_filter_new = fp_gtk_file_filter_new;
gtk->gtk_file_chooser_set_do_overwrite_confirmation =
fp_gtk_file_chooser_set_do_overwrite_confirmation;
gtk->gtk_file_chooser_set_select_multiple =
fp_gtk_file_chooser_set_select_multiple;
gtk->gtk_file_chooser_get_current_folder =
fp_gtk_file_chooser_get_current_folder;
gtk->gtk_file_chooser_get_filenames = fp_gtk_file_chooser_get_filenames;
gtk->gtk_g_slist_length = fp_gtk_g_slist_length;
gtk->g_signal_connect_data = fp_g_signal_connect_data;
gtk->gtk_widget_show = fp_gtk_widget_show;
gtk->gtk_main = fp_gtk_main;
gtk->gtk_main_level = fp_gtk_main_level;
gtk->g_path_get_dirname = fp_g_path_get_dirname;
gtk->gtk_widget_destroy = fp_gtk_widget_destroy;
gtk->gtk_window_present = fp_gtk_window_present;
gtk->gtk_window_move = fp_gtk_window_move;
gtk->gtk_window_resize = fp_gtk_window_resize;
gtk->get_window = &gtk3_get_window;
gtk->g_object_unref = fp_g_object_unref;
gtk->g_list_append = fp_g_list_append;
gtk->g_list_free = fp_g_list_free;
gtk->g_list_free_full = fp_g_list_free_full;
}
/*
* Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#ifndef _GTK3_INTERFACE_H
#define _GTK3_INTERFACE_H
#include <stdlib.h>
#include <jni.h>
#include <X11/X.h>
#include "gtk_interface.h"
#define LIGHTNESS_MULT 1.3
#define DARKNESS_MULT 0.7
#define G_PI 3.1415926535897932384626433832795028841971693993751
typedef enum
{
GTK_STATE_FLAG_NORMAL = 0,
GTK_STATE_FLAG_ACTIVE = 1 << 0,
GTK_STATE_FLAG_PRELIGHT = 1 << 1,
GTK_STATE_FLAG_SELECTED = 1 << 2,
GTK_STATE_FLAG_INSENSITIVE = 1 << 3,
GTK_STATE_FLAG_INCONSISTENT = 1 << 4,
GTK_STATE_FLAG_FOCUSED = 1 << 5,
GTK_STATE_FLAG_BACKDROP = 1 << 6,
GTK_STATE_FLAG_DIR_LTR = 1 << 7,
GTK_STATE_FLAG_DIR_RTL = 1 << 8,
GTK_STATE_FLAG_LINK = 1 << 9,
GTK_STATE_FLAG_VISITED = 1 << 10,
GTK_STATE_FLAG_CHECKED = 1 << 11
} GtkStateFlags;
typedef enum {
GTK_JUNCTION_NONE = 0,
GTK_JUNCTION_CORNER_TOPLEFT = 1 << 0,
GTK_JUNCTION_CORNER_TOPRIGHT = 1 << 1,
GTK_JUNCTION_CORNER_BOTTOMLEFT = 1 << 2,
GTK_JUNCTION_CORNER_BOTTOMRIGHT = 1 << 3,
GTK_JUNCTION_TOP =
(GTK_JUNCTION_CORNER_TOPLEFT | GTK_JUNCTION_CORNER_TOPRIGHT),
GTK_JUNCTION_BOTTOM =
(GTK_JUNCTION_CORNER_BOTTOMLEFT | GTK_JUNCTION_CORNER_BOTTOMRIGHT),
GTK_JUNCTION_LEFT =
(GTK_JUNCTION_CORNER_TOPLEFT | GTK_JUNCTION_CORNER_BOTTOMLEFT),
GTK_JUNCTION_RIGHT =
(GTK_JUNCTION_CORNER_TOPRIGHT | GTK_JUNCTION_CORNER_BOTTOMRIGHT)
} GtkJunctionSides;
typedef enum {
GTK_REGION_EVEN = 1 << 0,
GTK_REGION_ODD = 1 << 1,
GTK_REGION_FIRST = 1 << 2,
GTK_REGION_LAST = 1 << 3,
GTK_REGION_ONLY = 1 << 4,
GTK_REGION_SORTED = 1 << 5
} GtkRegionFlags;
typedef enum
{
GTK_WINDOW_TOPLEVEL,
GTK_WINDOW_POPUP
} GtkWindowType;
typedef enum
{
G_PARAM_READABLE = 1 << 0,
G_PARAM_WRITABLE = 1 << 1,
G_PARAM_CONSTRUCT = 1 << 2,
G_PARAM_CONSTRUCT_ONLY = 1 << 3,
G_PARAM_LAX_VALIDATION = 1 << 4,
G_PARAM_STATIC_NAME = 1 << 5
} GParamFlags;
typedef enum
{
GTK_ICON_LOOKUP_NO_SVG = 1 << 0,
GTK_ICON_LOOKUP_FORCE_SVG = 1 << 1,
GTK_ICON_LOOKUP_USE_BUILTIN = 1 << 2,
GTK_ICON_LOOKUP_GENERIC_FALLBACK = 1 << 3,
GTK_ICON_LOOKUP_FORCE_SIZE = 1 << 4
} GtkIconLookupFlags;
typedef enum
{
GTK_UPDATE_CONTINUOUS,
GTK_UPDATE_DISCONTINUOUS,
GTK_UPDATE_DELAYED
} GtkUpdateType;
typedef enum
{
GTK_PROGRESS_CONTINUOUS,
GTK_PROGRESS_DISCRETE
} GtkProgressBarStyle;
typedef enum
{
GTK_PROGRESS_LEFT_TO_RIGHT,
GTK_PROGRESS_RIGHT_TO_LEFT,
GTK_PROGRESS_BOTTOM_TO_TOP,
GTK_PROGRESS_TOP_TO_BOTTOM
} GtkProgressBarOrientation;
typedef enum {
CAIRO_FORMAT_INVALID = -1,
CAIRO_FORMAT_ARGB32 = 0,
CAIRO_FORMAT_RGB24 = 1,
CAIRO_FORMAT_A8 = 2,
CAIRO_FORMAT_A1 = 3,
CAIRO_FORMAT_RGB16_565 = 4
} cairo_format_t;
/* We define all structure pointers to be void* */
typedef void GdkPixbuf;
typedef void GMainContext;
typedef void GVfs;
typedef void GdkColormap;
typedef void GdkDrawable;
typedef void GdkGC;
typedef void GdkPixmap;
typedef void GtkStyleContext;
typedef void GtkFixed;
typedef void GtkMenuItem;
typedef void GtkMenuShell;
typedef void GtkWidgetClass;
typedef void PangoFontDescription;
typedef void GtkSettings;
typedef void GtkStyleProvider;
typedef void cairo_pattern_t;
typedef void cairo_t;
typedef void cairo_surface_t;
typedef void GtkScrolledWindow;
typedef void GtkIconTheme;
typedef void GtkWidget;
typedef void GtkMisc;
typedef void GtkContainer;
typedef void GtkBin;
typedef void GtkAdjustment;
typedef void GtkRange;
typedef void GtkProgressBar;
typedef void GtkProgress;
/* Some real structures */
typedef struct
{
guint32 pixel;
guint16 red;
guint16 green;
guint16 blue;
} GdkColor;
typedef struct
{
gdouble red;
gdouble green;
gdouble blue;
gdouble alpha;
} GdkRGBA;
typedef struct {
gint fd;
gushort events;
gushort revents;
} GPollFD;
typedef struct {
gint x;
gint y;
gint width;
gint height;
} GdkRectangle;
typedef struct {
int x, y;
int width, height;
} GtkAllocation;
typedef struct {
gint width;
gint height;
} GtkRequisition;
typedef struct {
GtkWidgetClass *g_class;
} GTypeInstance;
typedef struct {
gint16 left;
gint16 right;
gint16 top;
gint16 bottom;
} GtkBorder;
typedef struct
{
GType g_type;
union {
gint v_int;
guint v_uint;
glong v_long;
gulong v_ulong;
gint64 v_int64;
guint64 v_uint64;
gfloat v_float;
gdouble v_double;
gpointer v_pointer;
} data[2];
} GValue;
typedef struct {
GTypeInstance g_type_instance;
const gchar *name;
GParamFlags flags;
GType value_type;
GType owner_type;
} GParamSpec;
static gchar* (*fp_glib_check_version)(guint required_major,
guint required_minor, guint required_micro);
/**
* Returns :
* NULL if the GTK+ library is compatible with the given version, or a string
* describing the version mismatch.
*/
static gchar* (*fp_gtk_check_version)(guint required_major, guint
required_minor, guint required_micro);
static void (*fp_g_free)(gpointer mem);
static void (*fp_g_object_unref)(gpointer object);
static GdkWindow *(*fp_gdk_get_default_root_window) (void);
static int (*fp_gdk_pixbuf_get_bits_per_sample)(const GdkPixbuf *pixbuf);
static guchar *(*fp_gdk_pixbuf_get_pixels)(const GdkPixbuf *pixbuf);
static gboolean (*fp_gdk_pixbuf_get_has_alpha)(const GdkPixbuf *pixbuf);
static int (*fp_gdk_pixbuf_get_height)(const GdkPixbuf *pixbuf);
static int (*fp_gdk_pixbuf_get_n_channels)(const GdkPixbuf *pixbuf);
static int (*fp_gdk_pixbuf_get_rowstride)(const GdkPixbuf *pixbuf);
static int (*fp_gdk_pixbuf_get_width)(const GdkPixbuf *pixbuf);
static GdkPixbuf *(*fp_gdk_pixbuf_new_from_file)(const char *filename,
GError **error);
static GdkColorspace (*fp_gdk_pixbuf_get_colorspace)(const GdkPixbuf *pixbuf);
static GdkPixbuf *(*fp_gdk_pixbuf_get_from_drawable)(GdkWindow *window,
int src_x, int src_y, int width, int height);
static GdkPixbuf *(*fp_gdk_pixbuf_scale_simple)(GdkPixbuf *src,
int dest_width, int dest_heigh, GdkInterpType interp_type);
static void (*fp_gtk_widget_destroy)(void *widget);
static void (*fp_gtk_window_present)(GtkWindow *window);
static void (*fp_gtk_window_move)(GtkWindow *window, gint x, gint y);
static void (*fp_gtk_window_resize)(GtkWindow *window, gint width, gint height);
/**
* Function Pointers for GtkFileChooser
*/
static gchar* (*fp_gtk_file_chooser_get_filename)(GtkFileChooser *chooser);
static void (*fp_gtk_widget_hide)(void *widget);
static void (*fp_gtk_main_quit)(void);
static void* (*fp_gtk_file_chooser_dialog_new)(const gchar *title,
GtkWindow *parent, GtkFileChooserAction action,
const gchar *first_button_text, ...);
static gboolean (*fp_gtk_file_chooser_set_current_folder)
(GtkFileChooser *chooser, const gchar *filename);
static gboolean (*fp_gtk_file_chooser_set_filename)(GtkFileChooser *chooser,
const char *filename);
static void (*fp_gtk_file_chooser_set_current_name)(GtkFileChooser *chooser,
const gchar *name);
static void (*fp_gtk_file_filter_add_custom)(GtkFileFilter *filter,
GtkFileFilterFlags needed, GtkFileFilterFunc func, gpointer data,
GDestroyNotify notify);
static void (*fp_gtk_file_chooser_set_filter)(GtkFileChooser *chooser,
GtkFileFilter *filter);
static GType (*fp_gtk_file_chooser_get_type)(void);
static GtkFileFilter* (*fp_gtk_file_filter_new)(void);
static void (*fp_gtk_file_chooser_set_do_overwrite_confirmation)(
GtkFileChooser *chooser, gboolean do_overwrite_confirmation);
static void (*fp_gtk_file_chooser_set_select_multiple)(
GtkFileChooser *chooser, gboolean select_multiple);
static gchar* (*fp_gtk_file_chooser_get_current_folder)
(GtkFileChooser *chooser);
static GSList* (*fp_gtk_file_chooser_get_filenames)(GtkFileChooser *chooser);
static guint (*fp_gtk_g_slist_length)(GSList *list);
static gulong (*fp_g_signal_connect_data)(gpointer instance,
const gchar *detailed_signal, GCallback c_handler, gpointer data,
GClosureNotify destroy_data, GConnectFlags connect_flags);
static void (*fp_gtk_widget_show)(void *widget);
static void (*fp_gtk_main)(void);
static guint (*fp_gtk_main_level)(void);
static gchar* (*fp_g_path_get_dirname) (const gchar *file_name);
static XID (*fp_gdk_x11_drawable_get_xid) (GdkWindow *drawable);
static GList* (*fp_g_list_append) (GList *list, gpointer data);
static void (*fp_g_list_free) (GList *list);
static void (*fp_g_list_free_full) (GList *list, GDestroyNotify free_func);
static void (*fp_gdk_threads_enter)(void);
static void (*fp_gdk_threads_leave)(void);
static gboolean (*fp_gtk_show_uri)(GdkScreen *screen, const gchar *uri,
guint32 timestamp, GError **error);
// Implementation functions prototypes
static void gtk3_init(GtkApi* gtk);
static GValue* (*fp_g_value_init)(GValue *value, GType g_type);
static gboolean (*fp_g_type_is_a)(GType type, GType is_a_type);
static gboolean (*fp_g_value_get_boolean)(const GValue *value);
static gchar (*fp_g_value_get_char)(const GValue *value);
static guchar (*fp_g_value_get_uchar)(const GValue *value);
static gint (*fp_g_value_get_int)(const GValue *value);
static guint (*fp_g_value_get_uint)(const GValue *value);
static glong (*fp_g_value_get_long)(const GValue *value);
static gulong (*fp_g_value_get_ulong)(const GValue *value);
static gint64 (*fp_g_value_get_int64)(const GValue *value);
static guint64 (*fp_g_value_get_uint64)(const GValue *value);
static gfloat (*fp_g_value_get_float)(const GValue *value);
static gdouble (*fp_g_value_get_double)(const GValue *value);
static const gchar* (*fp_g_value_get_string)(const GValue *value);
static gint (*fp_g_value_get_enum)(const GValue *value);
static guint (*fp_g_value_get_flags)(const GValue *value);
static GParamSpec* (*fp_g_value_get_param)(const GValue *value);
static gpointer* (*fp_g_value_get_boxed)(const GValue *value);
static gpointer* (*fp_g_value_get_pointer)(const GValue *value);
static void (*fp_g_object_get)(gpointer object,
const gchar* fpn, ...);
static void (*fp_g_object_set)(gpointer object,
const gchar *first_property_name,
...);
static gboolean (*fp_g_main_context_iteration)(GMainContext *context);
static gboolean (*fp_g_str_has_prefix)(const gchar *str, const gchar *prefix);
static gchar** (*fp_g_strsplit)(const gchar *string, const gchar *delimiter,
gint max_tokens);
static void (*fp_g_strfreev)(gchar **str_array);
static cairo_surface_t* (*fp_cairo_image_surface_create)(cairo_format_t format,
int width, int height);
static void (*fp_cairo_surface_destroy)(cairo_surface_t *surface);
static cairo_t* (*fp_cairo_create)(cairo_surface_t *target);
static void (*fp_cairo_destroy)(cairo_t *cr);
static void (*fp_cairo_fill)(cairo_t *cr);
static void (*fp_cairo_surface_flush)(cairo_surface_t *surface);
static void (*fp_cairo_rectangle)(cairo_t *cr, double x, double y, double width,
double height);
static void (*fp_cairo_set_source_rgb)(cairo_t *cr, double red, double green,
double blue);
static void (*fp_cairo_set_source_rgba)(cairo_t *cr, double red, double green,
double blue, double alpha);
static void (*fp_cairo_paint)(cairo_t *cr);
static void (*fp_cairo_clip)(cairo_t *cr);
static unsigned char* (*fp_cairo_image_surface_get_data)(
cairo_surface_t *surface);
static int (*fp_cairo_image_surface_get_stride) (cairo_surface_t *surface);
static GdkPixbuf* (*fp_gdk_pixbuf_get_from_surface)(cairo_surface_t *surface,
gint src_x, gint src_y, gint width, gint height);
static GtkStateType (*fp_gtk_widget_get_state)(GtkWidget *widget);
static void (*fp_gtk_widget_set_state)(GtkWidget *widget, GtkStateType state);
static gboolean (*fp_gtk_widget_is_focus)(GtkWidget *widget);
static void (*fp_gtk_widget_set_allocation)(GtkWidget *widget,
const GtkAllocation *allocation);
static GtkWidget* (*fp_gtk_widget_get_parent)(GtkWidget *widget);
static GtkStyleContext* (*fp_gtk_widget_get_style_context)(GtkWidget *widget);
static void (*fp_gtk_style_context_get_color)(GtkStyleContext *context,
GtkStateFlags state, GdkRGBA *color);
static void (*fp_gtk_style_context_get_background_color)
(GtkStyleContext *context, GtkStateFlags state, GdkRGBA *color);
static void (*fp_gtk_style_context_get)(GtkStyleContext *context,
GtkStateFlags state, ...);
static GtkStateFlags (*fp_gtk_widget_get_state_flags)(GtkWidget* widget);
static void (*fp_gtk_style_context_set_state)(GtkStyleContext* style,
GtkStateFlags flags);
static void (*fp_gtk_style_context_add_class)(GtkStyleContext *context,
const gchar *class_name);
static void (*fp_gtk_style_context_save)(GtkStyleContext *context);
static void (*fp_gtk_style_context_restore)(GtkStyleContext *context);
static void (*fp_gtk_render_check)(GtkStyleContext *context, cairo_t *cr,
gdouble x, gdouble y, gdouble width, gdouble height);
static void (*fp_gtk_render_option)(GtkStyleContext *context, cairo_t *cr,
gdouble x, gdouble y, gdouble width, gdouble height);
static void (*fp_gtk_render_extension)(GtkStyleContext *context, cairo_t *cr,
gdouble x, gdouble y, gdouble width, gdouble height,
GtkPositionType gap_side);
static void (*fp_gtk_render_expander)(GtkStyleContext *context, cairo_t *cr,
gdouble x, gdouble y, gdouble width, gdouble height);
static void (*fp_gtk_render_frame_gap)(GtkStyleContext *context, cairo_t *cr,
gdouble x, gdouble y, gdouble width, gdouble height,
GtkPositionType gap_side, gdouble xy0_gap,
gdouble xy1_gap);
static void (*fp_gtk_render_line)(GtkStyleContext *context, cairo_t *cr,
gdouble x0, gdouble y0, gdouble x1, gdouble y1);
static GdkPixbuf* (*fp_gtk_widget_render_icon_pixbuf)(GtkWidget *widget,
const gchar *stock_id, GtkIconSize size);
static cairo_surface_t* (*fp_gdk_window_create_similar_image_surface)(
GdkWindow *window, cairo_format_t format, int width,
int height, int scale);
static cairo_surface_t* (*fp_gdk_window_create_similar_surface)(
GdkWindow *window, cairo_format_t format,
int width, int height);
static GdkWindow* (*fp_gtk_widget_get_window)(GtkWidget *widget);
static GtkSettings *(*fp_gtk_settings_get_for_screen)(GdkScreen *screen);
static GdkScreen *(*fp_gtk_widget_get_screen)(GtkWidget *widget);
static GtkStyleProvider* (*fp_gtk_css_provider_get_named)(const gchar *name,
const gchar *variant);
static void (*fp_gtk_style_context_add_provider)(GtkStyleContext *context,
GtkStyleProvider *provider, guint priority);
static void (*fp_gtk_render_frame)(GtkStyleContext *context,cairo_t *cr,
gdouble x, gdouble y, gdouble width, gdouble height);
static void (*fp_gtk_render_focus)(GtkStyleContext *context,cairo_t *cr,
gdouble x, gdouble y, gdouble width, gdouble height);
static void (*fp_gtk_render_handle)(GtkStyleContext *context,cairo_t *cr,
gdouble x, gdouble y, gdouble width, gdouble height);
static void (*fp_gtk_style_context_get_property)(GtkStyleContext *context,
const gchar *property, GtkStateFlags state, GValue *value);
static void (*fp_gtk_render_activity)(GtkStyleContext *context, cairo_t *cr,
gdouble x, gdouble y, gdouble width, gdouble height);
static void (*fp_gtk_render_background)(GtkStyleContext *context, cairo_t *cr,
gdouble x, gdouble y, gdouble width, gdouble height);
static gboolean (*fp_gtk_style_context_has_class)(GtkStyleContext *context,
const gchar *class_name);
static void transform_detail_string (const gchar *detail,
GtkStyleContext *context);
void (*fp_gtk_style_context_set_junction_sides)(GtkStyleContext *context,
GtkJunctionSides sides);
void (*fp_gtk_style_context_add_region)(GtkStyleContext *context,
const gchar *region_name, GtkRegionFlags flags);
void (*fp_gtk_render_arrow)(GtkStyleContext *context, cairo_t *cr,
gdouble angle, gdouble x, gdouble y, gdouble size);
void (*fp_gtk_bin_set_child)(GtkBin *bin, GtkWidget *widget);
void (*fp_gtk_scrolled_window_set_shadow_type)(
GtkScrolledWindow *scrolled_window, GtkShadowType type);
static void (*fp_gtk_render_slider)(GtkStyleContext *context, cairo_t *cr,
gdouble x, gdouble y, gdouble width, gdouble height,
GtkOrientation orientation);
static void (*fp_gtk_style_context_get_padding)(GtkStyleContext *self,
GtkStateFlags state, GtkBorder* padding);
static void (*fp_gtk_range_set_inverted)(GtkRange *range, gboolean setting);
static PangoFontDescription* (*fp_gtk_style_context_get_font)(
GtkStyleContext *context, GtkStateFlags state);
static int (*fp_gtk_widget_get_allocated_width)(GtkWidget *widget);
static int (*fp_gtk_widget_get_allocated_height)(GtkWidget *widget);
static GtkIconTheme* (*fp_gtk_icon_theme_get_default)(void);
static GdkPixbuf* (*fp_gtk_icon_theme_load_icon)(GtkIconTheme *icon_theme,
const gchar *icon_name, gint size,
GtkIconLookupFlags flags, GError **error);
static void (*fp_gtk_adjustment_set_lower)(GtkAdjustment *adjustment,
gdouble lower);
static void (*fp_gtk_adjustment_set_page_increment)(GtkAdjustment *adjustment,
gdouble page_increment);
static void (*fp_gtk_adjustment_set_page_size)(GtkAdjustment *adjustment,
gdouble page_size);
static void (*fp_gtk_adjustment_set_step_increment)(GtkAdjustment *adjustment,
gdouble step_increment);
static void (*fp_gtk_adjustment_set_upper)(GtkAdjustment *adjustment,
gdouble upper);
static void (*fp_gtk_adjustment_set_value)(GtkAdjustment *adjustment,
gdouble value);
static GdkGC *(*fp_gdk_gc_new)(GdkDrawable*);
static void (*fp_gdk_rgb_gc_set_foreground)(GdkGC*, guint32);
static void (*fp_gdk_draw_rectangle)(GdkDrawable*, GdkGC*, gboolean,
gint, gint, gint, gint);
static GdkPixbuf *(*fp_gdk_pixbuf_new)(GdkColorspace colorspace,
gboolean has_alpha, int bits_per_sample, int width, int height);
static void (*fp_gdk_drawable_get_size)(GdkDrawable *drawable,
gint* width, gint* height);
static gboolean (*fp_gtk_init_check)(int* argc, char** argv);
/* Widget creation */
static GtkWidget* (*fp_gtk_arrow_new)(GtkArrowType arrow_type,
GtkShadowType shadow_type);
static GtkWidget* (*fp_gtk_button_new)();
static GtkWidget* (*fp_gtk_check_button_new)();
static GtkWidget* (*fp_gtk_check_menu_item_new)();
static GtkWidget* (*fp_gtk_color_selection_dialog_new)(const gchar* title);
static GtkWidget* (*fp_gtk_combo_box_new)();
static GtkWidget* (*fp_gtk_combo_box_entry_new)();
static GtkWidget* (*fp_gtk_entry_new)();
static GtkWidget* (*fp_gtk_fixed_new)();
static GtkWidget* (*fp_gtk_handle_box_new)();
static GtkWidget* (*fp_gtk_hpaned_new)();
static GtkWidget* (*fp_gtk_vpaned_new)();
static GtkWidget* (*fp_gtk_scale_new)(GtkOrientation orientation,
GtkAdjustment* adjustment);
static GtkWidget* (*fp_gtk_hscrollbar_new)(GtkAdjustment* adjustment);
static GtkWidget* (*fp_gtk_vscrollbar_new)(GtkAdjustment* adjustment);
static GtkWidget* (*fp_gtk_hseparator_new)();
static GtkWidget* (*fp_gtk_vseparator_new)();
static GtkWidget* (*fp_gtk_image_new)();
static GtkWidget* (*fp_gtk_label_new)(const gchar* str);
static GtkWidget* (*fp_gtk_menu_new)();
static GtkWidget* (*fp_gtk_menu_bar_new)();
static GtkWidget* (*fp_gtk_menu_item_new)();
static GtkWidget* (*fp_gtk_notebook_new)();
static GtkWidget* (*fp_gtk_progress_bar_new)();
static GtkWidget* (*fp_gtk_progress_bar_set_orientation)(
GtkProgressBar *pbar,
GtkProgressBarOrientation orientation);
static GtkWidget* (*fp_gtk_radio_button_new)(GSList *group);
static GtkWidget* (*fp_gtk_radio_menu_item_new)(GSList *group);
static GtkWidget* (*fp_gtk_scrolled_window_new)(GtkAdjustment *hadjustment,
GtkAdjustment *vadjustment);
static GtkWidget* (*fp_gtk_separator_menu_item_new)();
static GtkWidget* (*fp_gtk_separator_tool_item_new)();
static GtkWidget* (*fp_gtk_text_view_new)();
static GtkWidget* (*fp_gtk_toggle_button_new)();
static GtkWidget* (*fp_gtk_toolbar_new)();
static GtkWidget* (*fp_gtk_tree_view_new)();
static GtkWidget* (*fp_gtk_viewport_new)(GtkAdjustment *hadjustment,
GtkAdjustment *vadjustment);
static GtkWidget* (*fp_gtk_window_new)(GtkWindowType type);
static GtkWidget* (*fp_gtk_dialog_new)();
static GtkWidget* (*fp_gtk_spin_button_new)(GtkAdjustment *adjustment,
gdouble climb_rate, guint digits);
static GtkWidget* (*fp_gtk_frame_new)(const gchar *label);
/* Other widget operations */
static GtkAdjustment* (*fp_gtk_adjustment_new)(gdouble value,
gdouble lower, gdouble upper, gdouble step_increment,
gdouble page_increment, gdouble page_size);
static void (*fp_gtk_container_add)(GtkContainer *window, GtkWidget *widget);
static void (*fp_gtk_menu_shell_append)(GtkMenuShell *menu_shell,
GtkWidget *child);
static void (*fp_gtk_menu_item_set_submenu)(GtkMenuItem *menu_item,
GtkWidget *submenu);
static void (*fp_gtk_widget_realize)(GtkWidget *widget);
static GdkPixbuf* (*fp_gtk_widget_render_icon)(GtkWidget *widget,
const gchar *stock_id, GtkIconSize size, const gchar *detail);
static void (*fp_gtk_widget_set_name)(GtkWidget *widget, const gchar *name);
static void (*fp_gtk_widget_set_parent)(GtkWidget *widget, GtkWidget *parent);
static void (*fp_gtk_widget_set_direction)(GtkWidget *widget,
GtkTextDirection direction);
static void (*fp_gtk_widget_style_get)(GtkWidget *widget,
const gchar *first_property_name, ...);
static void (*fp_gtk_widget_class_install_style_property)(
GtkWidgetClass* class, GParamSpec *pspec);
static GParamSpec* (*fp_gtk_widget_class_find_style_property)(
GtkWidgetClass* class, const gchar* property_name);
static void (*fp_gtk_widget_style_get_property)(GtkWidget* widget,
const gchar* property_name, GValue* value);
static char* (*fp_pango_font_description_to_string)(
const PangoFontDescription* fd);
static GtkSettings* (*fp_gtk_settings_get_default)();
static GtkSettings* (*fp_gtk_widget_get_settings)(GtkWidget *widget);
static GType (*fp_gtk_border_get_type)();
static void (*fp_gtk_arrow_set)(GtkWidget* arrow,
GtkArrowType arrow_type,
GtkShadowType shadow_type);
static void (*fp_gtk_widget_size_request)(GtkWidget *widget,
GtkRequisition *requisition);
static GtkAdjustment* (*fp_gtk_range_get_adjustment)(GtkRange* range);
#endif /* !_GTK3_INTERFACE_H */
/*
* Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#include <dlfcn.h>
#include <stdlib.h>
#include "jvm_md.h"
#include "gtk_interface.h"
GtkApi* gtk2_load(JNIEnv *env, const char* lib_name);
GtkApi* gtk3_load(JNIEnv *env, const char* lib_name);
gboolean gtk2_check(const char* lib_name, gboolean load);
gboolean gtk3_check(const char* lib_name, gboolean load);
GtkApi *gtk;
typedef struct {
GtkVersion version;
const char* name;
const char* vname;
GtkApi* (*load)(JNIEnv *env, const char* lib_name);
gboolean (*check)(const char* lib_name, gboolean load);
} GtkLib;
static GtkLib gtk_libs[] = {
{
GTK_2,
JNI_LIB_NAME("gtk-x11-2.0"),
VERSIONED_JNI_LIB_NAME("gtk-x11-2.0", "0"),
&gtk2_load,
&gtk2_check
},
{
GTK_3,
JNI_LIB_NAME("gtk-3"),
VERSIONED_JNI_LIB_NAME("gtk-3", "0"),
&gtk3_load,
&gtk3_check
}
};
static GtkLib** get_libs_order(GtkVersion version) {
static GtkLib** load_order;
static int n_libs = 0;
if (!n_libs) {
n_libs = sizeof(gtk_libs) / sizeof(GtkLib);
load_order = calloc(n_libs + 1, sizeof(GtkLib *));
}
int i, first = 0;
for (i = 0; i < n_libs; i++) {
load_order[i] = &gtk_libs[i];
if (load_order[i]->version == version) {
first = i;
}
}
if (first) {
for (i = first; i > 0; i--) {
load_order[i] = load_order[i - 1];
}
load_order[0] = &gtk_libs[first];
}
return load_order;
}
static GtkLib* get_loaded() {
GtkLib** libs = get_libs_order(GTK_ANY);
while(!gtk && *libs) {
GtkLib* lib = *libs++;
if (lib->check(lib->vname, /* load = */FALSE)) {
return lib;
}
if (lib->check(lib->name, /* load = */FALSE)) {
return lib;
}
}
return NULL;
}
gboolean gtk_load(JNIEnv *env, GtkVersion version, gboolean verbose) {
if (gtk == NULL) {
GtkLib* lib = get_loaded();
if (lib) {
if (verbose) {
fprintf(stderr, "Looking for GTK%d library...\n",
lib->version);
}
gtk = lib->load(env, lib->vname);
if (!gtk) {
gtk = lib->load(env, lib->name);
}
} else {
GtkLib** libs = get_libs_order(version);
while (!gtk && *libs) {
lib = *libs++;
if (version == GTK_ANY || lib->version == version) {
if (verbose) {
fprintf(stderr, "Looking for GTK%d library...\n",
lib->version);
}
gtk = lib->load(env, lib->vname);
if (!gtk) {
gtk = lib->load(env, lib->name);
}
if (verbose && !gtk) {
fprintf(stderr, "Not found.\n");
}
}
}
}
if (verbose) {
if (gtk) {
fprintf(stderr, "GTK%d library loaded.\n", lib->version);
} else {
fprintf(stderr, "Failed to load GTK library.\n");
}
}
}
return gtk != NULL;
}
static gboolean check_version(GtkVersion version) {
GtkLib** libs = get_libs_order(version);
while (*libs) {
GtkLib* lib = *libs++;
if (lib->check(lib->vname, /* load = */TRUE)) {
return TRUE;
}
if (lib->check(lib->name, /* load = */TRUE)) {
return TRUE;
}
}
return FALSE;
}
gboolean gtk_check_version(GtkVersion version) {
if (gtk || get_loaded()) {
return TRUE;
}
return check_version(version);
}
/*
* Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#ifndef _GTK_INTERFACE_H
#define _GTK_INTERFACE_H
#include <X11/X.h>
#include <jni.h>
#ifndef FALSE
#define FALSE (0)
#define TRUE (!FALSE)
#endif
#define GTHREAD_LIB_VERSIONED VERSIONED_JNI_LIB_NAME("gthread-2.0", "0")
#define GTHREAD_LIB JNI_LIB_NAME("gthread-2.0")
#define _G_TYPE_CIC(ip, gt, ct) ((ct*) ip)
#define G_TYPE_CHECK_INSTANCE_CAST(instance, g_type, c_type) \
(_G_TYPE_CIC ((instance), (g_type), c_type))
#define GTK_TYPE_FILE_CHOOSER (fp_gtk_file_chooser_get_type ())
#define GTK_FILE_CHOOSER(obj) \
(G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_FILE_CHOOSER, GtkFileChooser))
#define G_CALLBACK(f) ((GCallback) (f))
#define G_TYPE_FUNDAMENTAL_SHIFT (2)
#define G_TYPE_MAKE_FUNDAMENTAL(x) ((GType) ((x) << G_TYPE_FUNDAMENTAL_SHIFT))
#define G_TYPE_OBJECT G_TYPE_MAKE_FUNDAMENTAL (20)
#define GTK_STOCK_CANCEL "gtk-cancel"
#define GTK_STOCK_SAVE "gtk-save"
#define GTK_STOCK_OPEN "gtk-open"
#define GDK_CURRENT_TIME 0L
#define G_TYPE_INVALID G_TYPE_MAKE_FUNDAMENTAL (0)
#define G_TYPE_NONE G_TYPE_MAKE_FUNDAMENTAL (1)
#define G_TYPE_INTERFACE G_TYPE_MAKE_FUNDAMENTAL (2)
#define G_TYPE_CHAR G_TYPE_MAKE_FUNDAMENTAL (3)
#define G_TYPE_UCHAR G_TYPE_MAKE_FUNDAMENTAL (4)
#define G_TYPE_BOOLEAN G_TYPE_MAKE_FUNDAMENTAL (5)
#define G_TYPE_INT G_TYPE_MAKE_FUNDAMENTAL (6)
#define G_TYPE_UINT G_TYPE_MAKE_FUNDAMENTAL (7)
#define G_TYPE_LONG G_TYPE_MAKE_FUNDAMENTAL (8)
#define G_TYPE_ULONG G_TYPE_MAKE_FUNDAMENTAL (9)
#define G_TYPE_INT64 G_TYPE_MAKE_FUNDAMENTAL (10)
#define G_TYPE_UINT64 G_TYPE_MAKE_FUNDAMENTAL (11)
#define G_TYPE_ENUM G_TYPE_MAKE_FUNDAMENTAL (12)
#define G_TYPE_FLAGS G_TYPE_MAKE_FUNDAMENTAL (13)
#define G_TYPE_FLOAT G_TYPE_MAKE_FUNDAMENTAL (14)
#define G_TYPE_DOUBLE G_TYPE_MAKE_FUNDAMENTAL (15)
#define G_TYPE_STRING G_TYPE_MAKE_FUNDAMENTAL (16)
#define G_TYPE_POINTER G_TYPE_MAKE_FUNDAMENTAL (17)
#define G_TYPE_BOXED G_TYPE_MAKE_FUNDAMENTAL (18)
#define G_TYPE_PARAM G_TYPE_MAKE_FUNDAMENTAL (19)
#define G_TYPE_OBJECT G_TYPE_MAKE_FUNDAMENTAL (20)
#define GTK_TYPE_BORDER ((*fp_gtk_border_get_type)())
#define G_TYPE_FUNDAMENTAL_SHIFT (2)
#define G_TYPE_MAKE_FUNDAMENTAL(x) ((GType) ((x) << G_TYPE_FUNDAMENTAL_SHIFT))
#ifndef MIN
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#endif
#define CONV_BUFFER_SIZE 128
#define NO_SYMBOL_EXCEPTION 1
/* basic types */
typedef char gchar;
typedef short gshort;
typedef int gint;
typedef long glong;
typedef float gfloat;
typedef double gdouble;
typedef void* gpointer;
typedef gint gboolean;
typedef signed char gint8;
typedef signed short gint16;
typedef signed int gint32;
typedef unsigned char guchar;
typedef unsigned char guint8;
typedef unsigned short gushort;
typedef unsigned short guint16;
typedef unsigned int guint;
typedef unsigned int guint32;
typedef unsigned int gsize;
typedef unsigned long gulong;
typedef signed long long gint64;
typedef unsigned long long guint64;
typedef gulong GType;
typedef struct _GList GList;
struct _GList
{
gpointer data;
GList *next;
GList *prev;
};
typedef struct _GSList GSList;
struct _GSList {
gpointer data;
GSList *next;
};
typedef enum {
BUTTON, /* GtkButton */
CHECK_BOX, /* GtkCheckButton */
CHECK_BOX_MENU_ITEM, /* GtkCheckMenuItem */
COLOR_CHOOSER, /* GtkColorSelectionDialog */
COMBO_BOX, /* GtkComboBox */
COMBO_BOX_ARROW_BUTTON, /* GtkComboBoxEntry */
COMBO_BOX_TEXT_FIELD, /* GtkComboBoxEntry */
DESKTOP_ICON, /* GtkLabel */
DESKTOP_PANE, /* GtkContainer */
EDITOR_PANE, /* GtkTextView */
FORMATTED_TEXT_FIELD, /* GtkEntry */
HANDLE_BOX, /* GtkHandleBox */
HPROGRESS_BAR, /* GtkProgressBar */
HSCROLL_BAR, /* GtkHScrollbar */
HSCROLL_BAR_BUTTON_LEFT, /* GtkHScrollbar */
HSCROLL_BAR_BUTTON_RIGHT, /* GtkHScrollbar */
HSCROLL_BAR_TRACK, /* GtkHScrollbar */
HSCROLL_BAR_THUMB, /* GtkHScrollbar */
HSEPARATOR, /* GtkHSeparator */
HSLIDER, /* GtkHScale */
HSLIDER_TRACK, /* GtkHScale */
HSLIDER_THUMB, /* GtkHScale */
HSPLIT_PANE_DIVIDER, /* GtkHPaned */
INTERNAL_FRAME, /* GtkWindow */
INTERNAL_FRAME_TITLE_PANE, /* GtkLabel */
IMAGE, /* GtkImage */
LABEL, /* GtkLabel */
LIST, /* GtkTreeView */
MENU, /* GtkMenu */
MENU_BAR, /* GtkMenuBar */
MENU_ITEM, /* GtkMenuItem */
MENU_ITEM_ACCELERATOR, /* GtkLabel */
OPTION_PANE, /* GtkMessageDialog */
PANEL, /* GtkContainer */
PASSWORD_FIELD, /* GtkEntry */
POPUP_MENU, /* GtkMenu */
POPUP_MENU_SEPARATOR, /* GtkSeparatorMenuItem */
RADIO_BUTTON, /* GtkRadioButton */
RADIO_BUTTON_MENU_ITEM, /* GtkRadioMenuItem */
ROOT_PANE, /* GtkContainer */
SCROLL_PANE, /* GtkScrolledWindow */
SPINNER, /* GtkSpinButton */
SPINNER_ARROW_BUTTON, /* GtkSpinButton */
SPINNER_TEXT_FIELD, /* GtkSpinButton */
SPLIT_PANE, /* GtkPaned */
TABBED_PANE, /* GtkNotebook */
TABBED_PANE_TAB_AREA, /* GtkNotebook */
TABBED_PANE_CONTENT, /* GtkNotebook */
TABBED_PANE_TAB, /* GtkNotebook */
TABLE, /* GtkTreeView */
TABLE_HEADER, /* GtkButton */
TEXT_AREA, /* GtkTextView */
TEXT_FIELD, /* GtkEntry */
TEXT_PANE, /* GtkTextView */
TITLED_BORDER, /* GtkFrame */
TOGGLE_BUTTON, /* GtkToggleButton */
TOOL_BAR, /* GtkToolbar */
TOOL_BAR_DRAG_WINDOW, /* GtkToolbar */
TOOL_BAR_SEPARATOR, /* GtkSeparatorToolItem */
TOOL_TIP, /* GtkWindow */
TREE, /* GtkTreeView */
TREE_CELL, /* GtkTreeView */
VIEWPORT, /* GtkViewport */
VPROGRESS_BAR, /* GtkProgressBar */
VSCROLL_BAR, /* GtkVScrollbar */
VSCROLL_BAR_BUTTON_UP, /* GtkVScrollbar */
VSCROLL_BAR_BUTTON_DOWN, /* GtkVScrollbar */
VSCROLL_BAR_TRACK, /* GtkVScrollbar */
VSCROLL_BAR_THUMB, /* GtkVScrollbar */
VSEPARATOR, /* GtkVSeparator */
VSLIDER, /* GtkVScale */
VSLIDER_TRACK, /* GtkVScale */
VSLIDER_THUMB, /* GtkVScale */
VSPLIT_PANE_DIVIDER, /* GtkVPaned */
WIDGET_TYPE_SIZE
} WidgetType;
typedef enum
{
_GTK_ARROW_TYPE,
_GTK_BUTTON_TYPE,
_GTK_CHECK_BUTTON_TYPE,
_GTK_CHECK_MENU_ITEM_TYPE,
_GTK_COLOR_SELECTION_DIALOG_TYPE,
_GTK_COMBO_BOX_TYPE,
_GTK_COMBO_BOX_ARROW_BUTTON_TYPE,
_GTK_COMBO_BOX_TEXT_FIELD_TYPE,
_GTK_CONTAINER_TYPE,
_GTK_ENTRY_TYPE,
_GTK_FRAME_TYPE,
_GTK_HANDLE_BOX_TYPE,
_GTK_HPANED_TYPE,
_GTK_HPROGRESS_BAR_TYPE,
_GTK_HSCALE_TYPE,
_GTK_HSCROLLBAR_TYPE,
_GTK_HSEPARATOR_TYPE,
_GTK_IMAGE_TYPE,
_GTK_MENU_TYPE,
_GTK_MENU_BAR_TYPE,
_GTK_MENU_ITEM_TYPE,
_GTK_NOTEBOOK_TYPE,
_GTK_LABEL_TYPE,
_GTK_RADIO_BUTTON_TYPE,
_GTK_RADIO_MENU_ITEM_TYPE,
_GTK_SCROLLED_WINDOW_TYPE,
_GTK_SEPARATOR_MENU_ITEM_TYPE,
_GTK_SEPARATOR_TOOL_ITEM_TYPE,
_GTK_SPIN_BUTTON_TYPE,
_GTK_TEXT_VIEW_TYPE,
_GTK_TOGGLE_BUTTON_TYPE,
_GTK_TOOLBAR_TYPE,
_GTK_TOOLTIP_TYPE,
_GTK_TREE_VIEW_TYPE,
_GTK_VIEWPORT_TYPE,
_GTK_VPANED_TYPE,
_GTK_VPROGRESS_BAR_TYPE,
_GTK_VSCALE_TYPE,
_GTK_VSCROLLBAR_TYPE,
_GTK_VSEPARATOR_TYPE,
_GTK_WINDOW_TYPE,
_GTK_DIALOG_TYPE,
_GTK_WIDGET_TYPE_SIZE
} GtkWidgetType;
typedef enum
{
GTK_STATE_NORMAL,
GTK_STATE_ACTIVE,
GTK_STATE_PRELIGHT,
GTK_STATE_SELECTED,
GTK_STATE_INSENSITIVE,
GTK_STATE_INCONSISTENT,
GTK_STATE_FOCUSED
} GtkStateType;
typedef enum
{
GTK_SHADOW_NONE,
GTK_SHADOW_IN,
GTK_SHADOW_OUT,
GTK_SHADOW_ETCHED_IN,
GTK_SHADOW_ETCHED_OUT
} GtkShadowType;
typedef enum
{
GTK_EXPANDER_COLLAPSED,
GTK_EXPANDER_SEMI_COLLAPSED,
GTK_EXPANDER_SEMI_EXPANDED,
GTK_EXPANDER_EXPANDED
} GtkExpanderStyle;
typedef enum
{
GTK_ICON_SIZE_INVALID,
GTK_ICON_SIZE_MENU,
GTK_ICON_SIZE_SMALL_TOOLBAR,
GTK_ICON_SIZE_LARGE_TOOLBAR,
GTK_ICON_SIZE_BUTTON,
GTK_ICON_SIZE_DND,
GTK_ICON_SIZE_DIALOG
} GtkIconSize;
typedef enum
{
GTK_ORIENTATION_HORIZONTAL,
GTK_ORIENTATION_VERTICAL
} GtkOrientation;
typedef enum
{
FOREGROUND,
BACKGROUND,
TEXT_FOREGROUND,
TEXT_BACKGROUND,
FOCUS,
LIGHT,
DARK,
MID,
BLACK,
WHITE
} ColorType;
typedef enum
{
GTK_FONT_NAME,
GTK_ICON_SIZES,
GTK_CURSOR_BLINK,
GTK_CURSOR_BLINK_TIME
} Setting;
typedef enum
{
GTK_ARROW_UP,
GTK_ARROW_DOWN,
GTK_ARROW_LEFT,
GTK_ARROW_RIGHT,
GTK_ARROW_NONE
} GtkArrowType;
typedef enum
{
GTK_TEXT_DIR_NONE,
GTK_TEXT_DIR_LTR,
GTK_TEXT_DIR_RTL
} GtkTextDirection;
typedef enum
{
GTK_POS_LEFT,
GTK_POS_RIGHT,
GTK_POS_TOP,
GTK_POS_BOTTOM
} GtkPositionType;
/* SynthConstants */
static const gint ENABLED = 1 << 0;
static const gint MOUSE_OVER = 1 << 1;
static const gint PRESSED = 1 << 2;
static const gint DISABLED = 1 << 3;
static const gint FOCUSED = 1 << 8;
static const gint SELECTED = 1 << 9;
static const gint DEFAULT = 1 << 10;
typedef enum
{
GTK_ANY,
GTK_1,
GTK_2,
GTK_3
} GtkVersion;
//------------------------------
typedef enum {
GTK_RESPONSE_NONE = -1,
GTK_RESPONSE_REJECT = -2,
GTK_RESPONSE_ACCEPT = -3,
GTK_RESPONSE_DELETE_EVENT = -4,
GTK_RESPONSE_OK = -5,
GTK_RESPONSE_CANCEL = -6,
GTK_RESPONSE_CLOSE = -7,
GTK_RESPONSE_YES = -8,
GTK_RESPONSE_NO = -9,
GTK_RESPONSE_APPLY = -10,
GTK_RESPONSE_HELP = -11
} GtkResponseType;
typedef enum {
GTK_FILE_CHOOSER_ACTION_OPEN,
GTK_FILE_CHOOSER_ACTION_SAVE,
GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER
} GtkFileChooserAction;
typedef enum {
GTK_FILE_FILTER_FILENAME = 1 << 0,
GTK_FILE_FILTER_URI = 1 << 1,
GTK_FILE_FILTER_DISPLAY_NAME = 1 << 2,
GTK_FILE_FILTER_MIME_TYPE = 1 << 3
} GtkFileFilterFlags;
typedef enum {
GDK_COLORSPACE_RGB
} GdkColorspace;
typedef enum {
GDK_INTERP_NEAREST,
GDK_INTERP_TILES,
GDK_INTERP_BILINEAR,
GDK_INTERP_HYPER
} GdkInterpType;
typedef enum {
G_CONNECT_AFTER = 1 << 0, G_CONNECT_SWAPPED = 1 << 1
} GConnectFlags;
//------------------------------
typedef void GError;
typedef void GdkScreen;
typedef void GtkWindow;
typedef void GdkWindow;
typedef void GClosure;
typedef void GtkFileChooser;
typedef void GtkFileFilter;
typedef struct {
GtkFileFilterFlags contains;
const gchar *filename;
const gchar *uri;
const gchar *display_name;
const gchar *mime_type;
} GtkFileFilterInfo;
typedef gboolean (*GtkFileFilterFunc)(const GtkFileFilterInfo *filter_info,
gpointer data);
typedef void (*GClosureNotify)(gpointer data, GClosure *closure);
typedef void (*GDestroyNotify)(gpointer data);
typedef void (*GCallback)(void);
typedef struct GtkApi {
int version;
gboolean (*show_uri_load)(JNIEnv *env);
gboolean (*unload)();
void (*flush_event_loop)();
gchar* (*gtk_check_version)(guint required_major, guint required_minor,
guint required_micro);
jobject (*get_setting)(JNIEnv *env, Setting property);
void (*paint_arrow)(WidgetType widget_type, GtkStateType state_type,
GtkShadowType shadow_type, const gchar *detail,
gint x, gint y, gint width, gint height,
GtkArrowType arrow_type, gboolean fill);
void (*paint_box)(WidgetType widget_type, GtkStateType state_type,
GtkShadowType shadow_type, const gchar *detail,
gint x, gint y, gint width, gint height,
gint synth_state, GtkTextDirection dir);
void (*paint_box_gap)(WidgetType widget_type, GtkStateType state_type,
GtkShadowType shadow_type, const gchar *detail,
gint x, gint y, gint width, gint height,
GtkPositionType gap_side, gint gap_x, gint gap_width);
void (*paint_expander)(WidgetType widget_type, GtkStateType state_type,
const gchar *detail, gint x, gint y, gint width, gint height,
GtkExpanderStyle expander_style);
void (*paint_extension)(WidgetType widget_type, GtkStateType state_type,
GtkShadowType shadow_type, const gchar *detail,
gint x, gint y, gint width, gint height, GtkPositionType gap_side);
void (*paint_flat_box)(WidgetType widget_type, GtkStateType state_type,
GtkShadowType shadow_type, const gchar *detail,
gint x, gint y, gint width, gint height, gboolean has_focus);
void (*paint_focus)(WidgetType widget_type, GtkStateType state_type,
const char *detail, gint x, gint y, gint width, gint height);
void (*paint_handle)(WidgetType widget_type, GtkStateType state_type,
GtkShadowType shadow_type, const gchar *detail,
gint x, gint y, gint width, gint height, GtkOrientation orientation);
void (*paint_hline)(WidgetType widget_type, GtkStateType state_type,
const gchar *detail, gint x, gint y, gint width, gint height);
void (*paint_vline)(WidgetType widget_type, GtkStateType state_type,
const gchar *detail, gint x, gint y, gint width, gint height);
void (*paint_option)(WidgetType widget_type, gint synth_state,
const gchar *detail, gint x, gint y, gint width, gint height);
void (*paint_shadow)(WidgetType widget_type, GtkStateType state_type,
GtkShadowType shadow_type, const gchar *detail,
gint x, gint y, gint width, gint height,
gint synth_state, GtkTextDirection dir);
void (*paint_slider)(WidgetType widget_type, GtkStateType state_type,
GtkShadowType shadow_type, const gchar *detail,
gint x, gint y, gint width, gint height, GtkOrientation orientation,
gboolean has_focus);
void (*paint_background)(WidgetType widget_type, GtkStateType state_type,
gint x, gint y, gint width, gint height);
void (*paint_check)(WidgetType widget_type, gint synth_state,
const gchar *detail, gint x, gint y, gint width, gint height);
void (*set_range_value)(WidgetType widget_type, jdouble value,
jdouble min, jdouble max, jdouble visible);
void (*init_painting)(JNIEnv *env, gint w, gint h);
gint (*copy_image)(gint *dest, gint width, gint height);
gint (*get_xthickness)(JNIEnv *env, WidgetType widget_type);
gint (*get_ythickness)(JNIEnv *env, WidgetType widget_type);
gint (*get_color_for_state)(JNIEnv *env, WidgetType widget_type,
GtkStateType state_type, ColorType color_type);
jobject (*get_class_value)(JNIEnv *env, WidgetType widget_type,
const char* key);
jstring (*get_pango_font_name)(JNIEnv *env, WidgetType widget_type);
jboolean (*get_icon_data)(JNIEnv *env, gint widget_type,
const gchar *stock_id, GtkIconSize size,
GtkTextDirection direction, const char *detail,
jmethodID icon_upcall_method, jobject this);
jboolean (*get_file_icon_data)(JNIEnv *env, const char *filename,
GError **error, jmethodID icon_upcall_method, jobject this);
void (*gdk_threads_enter)(void);
void (*gdk_threads_leave)(void);
gboolean (*gtk_show_uri)(GdkScreen *screen, const gchar *uri,
guint32 timestamp, GError **error);
void (*g_free)(gpointer mem);
gchar* (*gtk_file_chooser_get_filename)(GtkFileChooser *chooser);
void (*gtk_widget_hide)(void* widget);
void (*gtk_main_quit)(void);
void* (*gtk_file_chooser_dialog_new)(const gchar *title,
GtkWindow *parent, GtkFileChooserAction action,
const gchar *first_button_text, ...);
gboolean (*gtk_file_chooser_set_current_folder)(GtkFileChooser *chooser,
const gchar *filename);
gboolean (*gtk_file_chooser_set_filename)(GtkFileChooser *chooser,
const char *filename);
void (*gtk_file_chooser_set_current_name)(GtkFileChooser *chooser,
const gchar *name);
void (*gtk_file_filter_add_custom)(GtkFileFilter *filter,
GtkFileFilterFlags needed, GtkFileFilterFunc func, gpointer data,
GDestroyNotify notify);
void (*gtk_file_chooser_set_filter)(GtkFileChooser *chooser,
GtkFileFilter *filter);
GType (*gtk_file_chooser_get_type)(void);
GtkFileFilter* (*gtk_file_filter_new)(void);
void (*gtk_file_chooser_set_do_overwrite_confirmation)(
GtkFileChooser *chooser, gboolean do_overwrite_confirmation);
void (*gtk_file_chooser_set_select_multiple)(
GtkFileChooser *chooser, gboolean select_multiple);
gchar* (*gtk_file_chooser_get_current_folder)(GtkFileChooser *chooser);
GSList* (*gtk_file_chooser_get_filenames)(GtkFileChooser *chooser);
guint (*gtk_g_slist_length)(GSList *list);
gulong (*g_signal_connect_data)(gpointer instance,
const gchar *detailed_signal, GCallback c_handler, gpointer data,
GClosureNotify destroy_data, GConnectFlags connect_flags);
void (*gtk_widget_show)(void *widget);
void (*gtk_main)(void);
guint (*gtk_main_level)(void);
gchar* (*g_path_get_dirname) (const gchar *file_name);
XID (*gdk_x11_drawable_get_xid) (void *drawable);
void (*gtk_widget_destroy)(void *widget);
void (*gtk_window_present)(void *window);
void (*gtk_window_move)(void *window, gint x, gint y);
void (*gtk_window_resize)(void *window, gint width, gint height);
GdkWindow *(*get_window)(void *widget);
void (*g_object_unref)(gpointer object);
GList* (*g_list_append) (GList *list, gpointer data);
void (*g_list_free) (GList *list);
void (*g_list_free_full) (GList *list, GDestroyNotify free_func);
} GtkApi;
gboolean gtk_load(JNIEnv *env, GtkVersion version, gboolean verbose);
gboolean gtk_check_version(GtkVersion version);
typedef struct _GThreadFunctions GThreadFunctions;
static gboolean (*fp_g_thread_get_initialized)(void);
static void (*fp_g_thread_init)(GThreadFunctions *vtable);
static void (*fp_gdk_threads_init)(void);
static void (*fp_gdk_threads_enter)(void);
static void (*fp_gdk_threads_leave)(void);
extern GtkApi* gtk;
#endif /* !_GTK_INTERFACE_H */
/* /*
* Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2010, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -27,11 +27,12 @@ ...@@ -27,11 +27,12 @@
#include <stdio.h> #include <stdio.h>
#include <jni_util.h> #include <jni_util.h>
#include <string.h> #include <string.h>
#include "gtk2_interface.h" #include "gtk_interface.h"
#include "sun_awt_X11_GtkFileDialogPeer.h" #include "sun_awt_X11_GtkFileDialogPeer.h"
#include "java_awt_FileDialog.h" #include "java_awt_FileDialog.h"
#include "debug_assert.h" #include "debug_assert.h"
typedef void GtkWidget;
static JavaVM *jvm; static JavaVM *jvm;
/* To cache some method IDs */ /* To cache some method IDs */
...@@ -84,20 +85,20 @@ static void quit(JNIEnv * env, jobject jpeer, gboolean isSignalHandler) ...@@ -84,20 +85,20 @@ static void quit(JNIEnv * env, jobject jpeer, gboolean isSignalHandler)
{ {
// Callbacks from GTK signals are made within the GTK lock // Callbacks from GTK signals are made within the GTK lock
// So, within a signal handler there is no need to call // So, within a signal handler there is no need to call
// gdk_threads_enter() / fp_gdk_threads_leave() // gdk_threads_enter() / gtk->gdk_threads_leave()
if (!isSignalHandler) { if (!isSignalHandler) {
fp_gdk_threads_enter(); gtk->gdk_threads_enter();
} }
fp_gtk_widget_hide (dialog); gtk->gtk_widget_hide (dialog);
fp_gtk_widget_destroy (dialog); gtk->gtk_widget_destroy (dialog);
fp_gtk_main_quit (); gtk->gtk_main_quit ();
(*env)->SetLongField(env, jpeer, widgetFieldID, 0); (*env)->SetLongField(env, jpeer, widgetFieldID, 0);
if (!isSignalHandler) { if (!isSignalHandler) {
fp_gdk_threads_leave(); gtk->gdk_threads_leave();
} }
} }
...@@ -127,16 +128,16 @@ JNIEXPORT void JNICALL Java_sun_awt_X11_GtkFileDialogPeer_toFront ...@@ -127,16 +128,16 @@ JNIEXPORT void JNICALL Java_sun_awt_X11_GtkFileDialogPeer_toFront
{ {
GtkWidget * dialog; GtkWidget * dialog;
fp_gdk_threads_enter(); gtk->gdk_threads_enter();
dialog = (GtkWidget*)jlong_to_ptr( dialog = (GtkWidget*)jlong_to_ptr(
(*env)->GetLongField(env, jpeer, widgetFieldID)); (*env)->GetLongField(env, jpeer, widgetFieldID));
if (dialog != NULL) { if (dialog != NULL) {
fp_gtk_window_present((GtkWindow*)dialog); gtk->gtk_window_present((GtkWindow*)dialog);
} }
fp_gdk_threads_leave(); gtk->gdk_threads_leave();
} }
/* /*
...@@ -149,21 +150,21 @@ JNIEXPORT void JNICALL Java_sun_awt_X11_GtkFileDialogPeer_setBounds ...@@ -149,21 +150,21 @@ JNIEXPORT void JNICALL Java_sun_awt_X11_GtkFileDialogPeer_setBounds
{ {
GtkWindow* dialog; GtkWindow* dialog;
fp_gdk_threads_enter(); gtk->gdk_threads_enter();
dialog = (GtkWindow*)jlong_to_ptr( dialog = (GtkWindow*)jlong_to_ptr(
(*env)->GetLongField(env, jpeer, widgetFieldID)); (*env)->GetLongField(env, jpeer, widgetFieldID));
if (dialog != NULL) { if (dialog != NULL) {
if (x >= 0 && y >= 0) { if (x >= 0 && y >= 0) {
fp_gtk_window_move(dialog, (gint)x, (gint)y); gtk->gtk_window_move(dialog, (gint)x, (gint)y);
} }
if (width > 0 && height > 0) { if (width > 0 && height > 0) {
fp_gtk_window_resize(dialog, (gint)width, (gint)height); gtk->gtk_window_resize(dialog, (gint)width, (gint)height);
} }
} }
fp_gdk_threads_leave(); gtk->gdk_threads_leave();
} }
/* /*
...@@ -176,18 +177,18 @@ static gboolean isFromSameDirectory(GSList* list, gchar** baseDir) { ...@@ -176,18 +177,18 @@ static gboolean isFromSameDirectory(GSList* list, gchar** baseDir) {
gboolean isAllDirsSame = TRUE; gboolean isAllDirsSame = TRUE;
while (it) { while (it) {
gchar* dir = fp_g_path_get_dirname((gchar*) it->data); gchar* dir = gtk->g_path_get_dirname((gchar*) it->data);
if (prevDir && strcmp(prevDir, dir) != 0) { if (prevDir && strcmp(prevDir, dir) != 0) {
isAllDirsSame = FALSE; isAllDirsSame = FALSE;
fp_g_free(dir); gtk->g_free(dir);
break; break;
} }
if (!prevDir) { if (!prevDir) {
prevDir = strdup(dir); prevDir = strdup(dir);
} }
fp_g_free(dir); gtk->g_free(dir);
it = it->next; it = it->next;
} }
...@@ -227,7 +228,7 @@ static jobjectArray toFilenamesArray(JNIEnv *env, GSList* list, jstring* jcurren ...@@ -227,7 +228,7 @@ static jobjectArray toFilenamesArray(JNIEnv *env, GSList* list, jstring* jcurren
return NULL; return NULL;
} }
array = (*env)->NewObjectArray(env, fp_gtk_g_slist_length(list), stringCls, NULL); array = (*env)->NewObjectArray(env, gtk->gtk_g_slist_length(list), stringCls, NULL);
if (array == NULL) { if (array == NULL) {
(*env)->ExceptionClear(env); (*env)->ExceptionClear(env);
JNU_ThrowInternalError(env, "Could not instantiate array files array"); JNU_ThrowInternalError(env, "Could not instantiate array files array");
...@@ -281,7 +282,7 @@ static void handle_response(GtkWidget* aDialog, gint responseId, gpointer obj) ...@@ -281,7 +282,7 @@ static void handle_response(GtkWidget* aDialog, gint responseId, gpointer obj)
filenames = NULL; filenames = NULL;
if (responseId == GTK_RESPONSE_ACCEPT) { if (responseId == GTK_RESPONSE_ACCEPT) {
filenames = fp_gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(aDialog)); filenames = gtk->gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(aDialog));
} }
jfilenames = toFilenamesArray(env, filenames, &jcurrent_folder); jfilenames = toFilenamesArray(env, filenames, &jcurrent_folder);
...@@ -312,7 +313,7 @@ Java_sun_awt_X11_GtkFileDialogPeer_run(JNIEnv * env, jobject jpeer, ...@@ -312,7 +313,7 @@ Java_sun_awt_X11_GtkFileDialogPeer_run(JNIEnv * env, jobject jpeer,
JNU_CHECK_EXCEPTION(env); JNU_CHECK_EXCEPTION(env);
} }
fp_gdk_threads_enter(); gtk->gdk_threads_enter();
const char *title = jtitle == NULL? "": (*env)->GetStringUTFChars(env, jtitle, 0); const char *title = jtitle == NULL? "": (*env)->GetStringUTFChars(env, jtitle, 0);
if (title == NULL) { if (title == NULL) {
...@@ -323,19 +324,19 @@ Java_sun_awt_X11_GtkFileDialogPeer_run(JNIEnv * env, jobject jpeer, ...@@ -323,19 +324,19 @@ Java_sun_awt_X11_GtkFileDialogPeer_run(JNIEnv * env, jobject jpeer,
if (mode == java_awt_FileDialog_SAVE) { if (mode == java_awt_FileDialog_SAVE) {
/* Save action */ /* Save action */
dialog = fp_gtk_file_chooser_dialog_new(title, NULL, dialog = gtk->gtk_file_chooser_dialog_new(title, NULL,
GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL, GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL,
GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, NULL); GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, NULL);
} }
else { else {
/* Default action OPEN */ /* Default action OPEN */
dialog = fp_gtk_file_chooser_dialog_new(title, NULL, dialog = gtk->gtk_file_chooser_dialog_new(title, NULL,
GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL,
GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL); GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL);
/* Set multiple selection mode, that is allowed only in OPEN action */ /* Set multiple selection mode, that is allowed only in OPEN action */
if (multiple) { if (multiple) {
fp_gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog), gtk->gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog),
multiple); multiple);
} }
} }
...@@ -352,7 +353,7 @@ Java_sun_awt_X11_GtkFileDialogPeer_run(JNIEnv * env, jobject jpeer, ...@@ -352,7 +353,7 @@ Java_sun_awt_X11_GtkFileDialogPeer_run(JNIEnv * env, jobject jpeer,
JNU_ThrowOutOfMemoryError(env, "Could not get dir"); JNU_ThrowOutOfMemoryError(env, "Could not get dir");
return; return;
} }
fp_gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), dir); gtk->gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), dir);
(*env)->ReleaseStringUTFChars(env, jdir, dir); (*env)->ReleaseStringUTFChars(env, jdir, dir);
} }
...@@ -365,43 +366,44 @@ Java_sun_awt_X11_GtkFileDialogPeer_run(JNIEnv * env, jobject jpeer, ...@@ -365,43 +366,44 @@ Java_sun_awt_X11_GtkFileDialogPeer_run(JNIEnv * env, jobject jpeer,
return; return;
} }
if (mode == java_awt_FileDialog_SAVE) { if (mode == java_awt_FileDialog_SAVE) {
fp_gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), filename); gtk->gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), filename);
} else { } else {
fp_gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog), filename); gtk->gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog), filename);
} }
(*env)->ReleaseStringUTFChars(env, jfile, filename); (*env)->ReleaseStringUTFChars(env, jfile, filename);
} }
/* Set the file filter */ /* Set the file filter */
if (jfilter != NULL) { if (jfilter != NULL) {
filter = fp_gtk_file_filter_new(); filter = gtk->gtk_file_filter_new();
fp_gtk_file_filter_add_custom(filter, GTK_FILE_FILTER_FILENAME, gtk->gtk_file_filter_add_custom(filter, GTK_FILE_FILTER_FILENAME,
filenameFilterCallback, jpeer, NULL); filenameFilterCallback, jpeer, NULL);
fp_gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(dialog), filter); gtk->gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(dialog), filter);
} }
/* Other Properties */ /* Other Properties */
if (fp_gtk_check_version(2, 8, 0) == NULL) { if (gtk->gtk_check_version(2, 8, 0) == NULL ||
fp_gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER( gtk->gtk_check_version(3, 0, 0) == NULL) {
gtk->gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(
dialog), TRUE); dialog), TRUE);
} }
/* Set the initial location */ /* Set the initial location */
if (x >= 0 && y >= 0) { if (x >= 0 && y >= 0) {
fp_gtk_window_move((GtkWindow*)dialog, (gint)x, (gint)y); gtk->gtk_window_move((GtkWindow*)dialog, (gint)x, (gint)y);
// NOTE: it doesn't set the initial size for the file chooser // NOTE: it doesn't set the initial size for the file chooser
// as it seems like the file chooser overrides the size internally // as it seems like the file chooser overrides the size internally
} }
fp_g_signal_connect(G_OBJECT(dialog), "response", G_CALLBACK( gtk->g_signal_connect_data(dialog, "response", G_CALLBACK(
handle_response), jpeer); handle_response), jpeer, 0, 0);
(*env)->SetLongField(env, jpeer, widgetFieldID, ptr_to_jlong(dialog)); (*env)->SetLongField(env, jpeer, widgetFieldID, ptr_to_jlong(dialog));
fp_gtk_widget_show(dialog); gtk->gtk_widget_show(dialog);
fp_gtk_main(); gtk->gtk_main();
fp_gdk_threads_leave(); gtk->gdk_threads_leave();
} }
/* /*
* Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -24,9 +24,24 @@ ...@@ -24,9 +24,24 @@
*/ */
#include <stdlib.h> #include <stdlib.h>
#include "gtk2_interface.h" #include "gtk_interface.h"
#include "com_sun_java_swing_plaf_gtk_GTKEngine.h" #include "com_sun_java_swing_plaf_gtk_GTKEngine.h"
/* Static buffer for conversion from java.lang.String to UTF-8 */
static char conversionBuffer[CONV_BUFFER_SIZE];
const char *getStrFor(JNIEnv *env, jstring val)
{
int length = (*env)->GetStringLength(env, val);
if (length > CONV_BUFFER_SIZE-1)
{
length = CONV_BUFFER_SIZE-1;
}
(*env)->GetStringUTFRegion(env, val, 0, length, conversionBuffer);
return conversionBuffer;
}
/* /*
* Class: com_sun_java_swing_plaf_gtk_GTKEngine * Class: com_sun_java_swing_plaf_gtk_GTKEngine
* Method: native_paint_arrow * Method: native_paint_arrow
...@@ -38,10 +53,10 @@ Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1arrow( ...@@ -38,10 +53,10 @@ Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1arrow(
jint widget_type, jint state, jint shadow_type, jstring detail, jint widget_type, jint state, jint shadow_type, jstring detail,
jint x, jint y, jint w, jint h, jint arrow_type) jint x, jint y, jint w, jint h, jint arrow_type)
{ {
fp_gdk_threads_enter(); gtk->gdk_threads_enter();
gtk2_paint_arrow(widget_type, state, shadow_type, getStrFor(env, detail), gtk->paint_arrow(widget_type, state, shadow_type, getStrFor(env, detail),
x, y, w, h, arrow_type, TRUE); x, y, w, h, arrow_type, TRUE);
fp_gdk_threads_leave(); gtk->gdk_threads_leave();
} }
/* /*
...@@ -56,10 +71,10 @@ Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1box( ...@@ -56,10 +71,10 @@ Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1box(
jint x, jint y, jint w, jint h, jint x, jint y, jint w, jint h,
jint synth_state, jint dir) jint synth_state, jint dir)
{ {
fp_gdk_threads_enter(); gtk->gdk_threads_enter();
gtk2_paint_box(widget_type, state, shadow_type, getStrFor(env, detail), gtk->paint_box(widget_type, state, shadow_type, getStrFor(env, detail),
x, y, w, h, synth_state, dir); x, y, w, h, synth_state, dir);
fp_gdk_threads_leave(); gtk->gdk_threads_leave();
} }
/* /*
...@@ -74,10 +89,10 @@ Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1box_1gap( ...@@ -74,10 +89,10 @@ Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1box_1gap(
jint x, jint y, jint w, jint h, jint x, jint y, jint w, jint h,
jint gap_side, jint gap_x, jint gap_w) jint gap_side, jint gap_x, jint gap_w)
{ {
fp_gdk_threads_enter(); gtk->gdk_threads_enter();
gtk2_paint_box_gap(widget_type, state, shadow_type, getStrFor(env, detail), gtk->paint_box_gap(widget_type, state, shadow_type, getStrFor(env, detail),
x, y, w, h, gap_side, gap_x, gap_w); x, y, w, h, gap_side, gap_x, gap_w);
fp_gdk_threads_leave(); gtk->gdk_threads_leave();
} }
/* /*
...@@ -91,10 +106,10 @@ Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1check( ...@@ -91,10 +106,10 @@ Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1check(
jint widget_type, jint synth_state, jstring detail, jint widget_type, jint synth_state, jstring detail,
jint x, jint y, jint w, jint h) jint x, jint y, jint w, jint h)
{ {
fp_gdk_threads_enter(); gtk->gdk_threads_enter();
gtk2_paint_check(widget_type, synth_state, getStrFor(env, detail), gtk->paint_check(widget_type, synth_state, getStrFor(env, detail),
x, y, w, h); x, y, w, h);
fp_gdk_threads_leave(); gtk->gdk_threads_leave();
} }
/* /*
...@@ -108,10 +123,10 @@ Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1expander( ...@@ -108,10 +123,10 @@ Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1expander(
jint widget_type, jint state, jstring detail, jint widget_type, jint state, jstring detail,
jint x, jint y, jint w, jint h, jint expander_style) jint x, jint y, jint w, jint h, jint expander_style)
{ {
fp_gdk_threads_enter(); gtk->gdk_threads_enter();
gtk2_paint_expander(widget_type, state, getStrFor(env, detail), gtk->paint_expander(widget_type, state, getStrFor(env, detail),
x, y, w, h, expander_style); x, y, w, h, expander_style);
fp_gdk_threads_leave(); gtk->gdk_threads_leave();
} }
/* /*
...@@ -125,10 +140,10 @@ Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1extension( ...@@ -125,10 +140,10 @@ Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1extension(
jint widget_type, jint state, jint shadow_type, jstring detail, jint widget_type, jint state, jint shadow_type, jstring detail,
jint x, jint y, jint w, jint h, jint placement) jint x, jint y, jint w, jint h, jint placement)
{ {
fp_gdk_threads_enter(); gtk->gdk_threads_enter();
gtk2_paint_extension(widget_type, state, shadow_type, gtk->paint_extension(widget_type, state, shadow_type,
getStrFor(env, detail), x, y, w, h, placement); getStrFor(env, detail), x, y, w, h, placement);
fp_gdk_threads_leave(); gtk->gdk_threads_leave();
} }
/* /*
...@@ -142,10 +157,10 @@ Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1flat_1box( ...@@ -142,10 +157,10 @@ Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1flat_1box(
jint widget_type, jint state, jint shadow_type, jstring detail, jint widget_type, jint state, jint shadow_type, jstring detail,
jint x, jint y, jint w, jint h, jboolean has_focus) jint x, jint y, jint w, jint h, jboolean has_focus)
{ {
fp_gdk_threads_enter(); gtk->gdk_threads_enter();
gtk2_paint_flat_box(widget_type, state, shadow_type, gtk->paint_flat_box(widget_type, state, shadow_type,
getStrFor(env, detail), x, y, w, h, has_focus); getStrFor(env, detail), x, y, w, h, has_focus);
fp_gdk_threads_leave(); gtk->gdk_threads_leave();
} }
/* /*
...@@ -159,10 +174,10 @@ Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1focus( ...@@ -159,10 +174,10 @@ Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1focus(
jint widget_type, jint state, jstring detail, jint widget_type, jint state, jstring detail,
jint x, jint y, jint w, jint h) jint x, jint y, jint w, jint h)
{ {
fp_gdk_threads_enter(); gtk->gdk_threads_enter();
gtk2_paint_focus(widget_type, state, getStrFor(env, detail), gtk->paint_focus(widget_type, state, getStrFor(env, detail),
x, y, w, h); x, y, w, h);
fp_gdk_threads_leave(); gtk->gdk_threads_leave();
} }
/* /*
...@@ -176,10 +191,10 @@ Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1handle( ...@@ -176,10 +191,10 @@ Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1handle(
jint widget_type, jint state, jint shadow_type, jstring detail, jint widget_type, jint state, jint shadow_type, jstring detail,
jint x, jint y, jint w, jint h, jint orientation) jint x, jint y, jint w, jint h, jint orientation)
{ {
fp_gdk_threads_enter(); gtk->gdk_threads_enter();
gtk2_paint_handle(widget_type, state, shadow_type, getStrFor(env, detail), gtk->paint_handle(widget_type, state, shadow_type, getStrFor(env, detail),
x, y, w, h, orientation); x, y, w, h, orientation);
fp_gdk_threads_leave(); gtk->gdk_threads_leave();
} }
/* /*
...@@ -193,10 +208,10 @@ Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1hline( ...@@ -193,10 +208,10 @@ Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1hline(
jint widget_type, jint state, jstring detail, jint widget_type, jint state, jstring detail,
jint x, jint y, jint w, jint h) jint x, jint y, jint w, jint h)
{ {
fp_gdk_threads_enter(); gtk->gdk_threads_enter();
gtk2_paint_hline(widget_type, state, getStrFor(env, detail), gtk->paint_hline(widget_type, state, getStrFor(env, detail),
x, y, w, h); x, y, w, h);
fp_gdk_threads_leave(); gtk->gdk_threads_leave();
} }
/* /*
...@@ -210,10 +225,10 @@ Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1option( ...@@ -210,10 +225,10 @@ Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1option(
jint widget_type, jint synth_state, jstring detail, jint widget_type, jint synth_state, jstring detail,
jint x, jint y, jint w, jint h) jint x, jint y, jint w, jint h)
{ {
fp_gdk_threads_enter(); gtk->gdk_threads_enter();
gtk2_paint_option(widget_type, synth_state, getStrFor(env, detail), gtk->paint_option(widget_type, synth_state, getStrFor(env, detail),
x, y, w, h); x, y, w, h);
fp_gdk_threads_leave(); gtk->gdk_threads_leave();
} }
/* /*
...@@ -228,10 +243,10 @@ Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1shadow( ...@@ -228,10 +243,10 @@ Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1shadow(
jint x, jint y, jint w, jint h, jint x, jint y, jint w, jint h,
jint synth_state, jint dir) jint synth_state, jint dir)
{ {
fp_gdk_threads_enter(); gtk->gdk_threads_enter();
gtk2_paint_shadow(widget_type, state, shadow_type, getStrFor(env, detail), gtk->paint_shadow(widget_type, state, shadow_type, getStrFor(env, detail),
x, y, w, h, synth_state, dir); x, y, w, h, synth_state, dir);
fp_gdk_threads_leave(); gtk->gdk_threads_leave();
} }
/* /*
...@@ -243,12 +258,12 @@ JNIEXPORT void JNICALL ...@@ -243,12 +258,12 @@ JNIEXPORT void JNICALL
Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1slider( Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1slider(
JNIEnv *env, jobject this, JNIEnv *env, jobject this,
jint widget_type, jint state, jint shadow_type, jstring detail, jint widget_type, jint state, jint shadow_type, jstring detail,
jint x, jint y, jint w, jint h, jint orientation) jint x, jint y, jint w, jint h, jint orientation, jboolean has_focus)
{ {
fp_gdk_threads_enter(); gtk->gdk_threads_enter();
gtk2_paint_slider(widget_type, state, shadow_type, getStrFor(env, detail), gtk->paint_slider(widget_type, state, shadow_type, getStrFor(env, detail),
x, y, w, h, orientation); x, y, w, h, orientation, has_focus);
fp_gdk_threads_leave(); gtk->gdk_threads_leave();
} }
/* /*
...@@ -262,10 +277,10 @@ Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1vline( ...@@ -262,10 +277,10 @@ Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1vline(
jint widget_type, jint state, jstring detail, jint widget_type, jint state, jstring detail,
jint x, jint y, jint w, jint h) jint x, jint y, jint w, jint h)
{ {
fp_gdk_threads_enter(); gtk->gdk_threads_enter();
gtk2_paint_vline(widget_type, state, getStrFor(env, detail), gtk->paint_vline(widget_type, state, getStrFor(env, detail),
x, y, w, h); x, y, w, h);
fp_gdk_threads_leave(); gtk->gdk_threads_leave();
} }
/* /*
...@@ -278,9 +293,9 @@ Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1background( ...@@ -278,9 +293,9 @@ Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1background(
JNIEnv *env, jobject this, jint widget_type, jint state, JNIEnv *env, jobject this, jint widget_type, jint state,
jint x, jint y, jint w, jint h) jint x, jint y, jint w, jint h)
{ {
fp_gdk_threads_enter(); gtk->gdk_threads_enter();
gtk_paint_background(widget_type, state, x, y, w, h); gtk->paint_background(widget_type, state, x, y, w, h);
fp_gdk_threads_leave(); gtk->gdk_threads_leave();
} }
/* /*
...@@ -292,9 +307,9 @@ JNIEXPORT void JNICALL ...@@ -292,9 +307,9 @@ JNIEXPORT void JNICALL
Java_com_sun_java_swing_plaf_gtk_GTKEngine_nativeStartPainting( Java_com_sun_java_swing_plaf_gtk_GTKEngine_nativeStartPainting(
JNIEnv *env, jobject this, jint w, jint h) JNIEnv *env, jobject this, jint w, jint h)
{ {
fp_gdk_threads_enter(); gtk->gdk_threads_enter();
gtk2_init_painting(env, w, h); gtk->init_painting(env, w, h);
fp_gdk_threads_leave(); gtk->gdk_threads_leave();
} }
/* /*
...@@ -308,9 +323,9 @@ Java_com_sun_java_swing_plaf_gtk_GTKEngine_nativeFinishPainting( ...@@ -308,9 +323,9 @@ Java_com_sun_java_swing_plaf_gtk_GTKEngine_nativeFinishPainting(
{ {
jint transparency; jint transparency;
gint *buffer = (gint*) (*env)->GetPrimitiveArrayCritical(env, dest, 0); gint *buffer = (gint*) (*env)->GetPrimitiveArrayCritical(env, dest, 0);
fp_gdk_threads_enter(); gtk->gdk_threads_enter();
transparency = gtk2_copy_image(buffer, width, height); transparency = gtk->copy_image(buffer, width, height);
fp_gdk_threads_leave(); gtk->gdk_threads_leave();
(*env)->ReleasePrimitiveArrayCritical(env, dest, buffer, 0); (*env)->ReleasePrimitiveArrayCritical(env, dest, buffer, 0);
return transparency; return transparency;
} }
...@@ -324,7 +339,9 @@ JNIEXPORT void JNICALL Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1switch ...@@ -324,7 +339,9 @@ JNIEXPORT void JNICALL Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1switch
JNIEnv *env, jobject this) JNIEnv *env, jobject this)
{ {
// Note that flush_gtk_event_loop takes care of locks (7053002) // Note that flush_gtk_event_loop takes care of locks (7053002)
flush_gtk_event_loop(); gtk->gdk_threads_enter();
gtk->flush_event_loop();
gtk->gdk_threads_leave();
} }
/* /*
...@@ -336,9 +353,9 @@ JNIEXPORT jobject JNICALL Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1get ...@@ -336,9 +353,9 @@ JNIEXPORT jobject JNICALL Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1get
JNIEnv *env, jobject this, jint property) JNIEnv *env, jobject this, jint property)
{ {
jobject obj; jobject obj;
fp_gdk_threads_enter(); gtk->gdk_threads_enter();
obj = gtk2_get_setting(env, property); obj = gtk->get_setting(env, property);
fp_gdk_threads_leave(); gtk->gdk_threads_leave();
return obj; return obj;
} }
...@@ -352,7 +369,7 @@ Java_com_sun_java_swing_plaf_gtk_GTKEngine_nativeSetRangeValue( ...@@ -352,7 +369,7 @@ Java_com_sun_java_swing_plaf_gtk_GTKEngine_nativeSetRangeValue(
JNIEnv *env, jobject this, jint widget_type, JNIEnv *env, jobject this, jint widget_type,
jdouble value, jdouble min, jdouble max, jdouble visible) jdouble value, jdouble min, jdouble max, jdouble visible)
{ {
fp_gdk_threads_enter(); gtk->gdk_threads_enter();
gtk2_set_range_value(widget_type, value, min, max, visible); gtk->set_range_value(widget_type, value, min, max, visible);
fp_gdk_threads_leave(); gtk->gdk_threads_leave();
} }
/* /*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -24,9 +24,12 @@ ...@@ -24,9 +24,12 @@
*/ */
#include <stdlib.h> #include <stdlib.h>
#include "gtk2_interface.h" #include <stdio.h>
#include "gtk_interface.h"
#include "com_sun_java_swing_plaf_gtk_GTKStyle.h" #include "com_sun_java_swing_plaf_gtk_GTKStyle.h"
const char *getStrFor(JNIEnv *env, jstring val);
/* /*
* Class: com_sun_java_swing_plaf_gtk_GTKStyle * Class: com_sun_java_swing_plaf_gtk_GTKStyle
* Method: nativeGetXThickness * Method: nativeGetXThickness
...@@ -37,9 +40,9 @@ Java_com_sun_java_swing_plaf_gtk_GTKStyle_nativeGetXThickness( ...@@ -37,9 +40,9 @@ Java_com_sun_java_swing_plaf_gtk_GTKStyle_nativeGetXThickness(
JNIEnv *env, jclass klass, jint widget_type) JNIEnv *env, jclass klass, jint widget_type)
{ {
jint ret; jint ret;
fp_gdk_threads_enter(); gtk->gdk_threads_enter();
ret = gtk2_get_xthickness(env, widget_type); ret = gtk->get_xthickness(env, widget_type);
fp_gdk_threads_leave(); gtk->gdk_threads_leave();
return ret; return ret;
} }
...@@ -53,9 +56,9 @@ Java_com_sun_java_swing_plaf_gtk_GTKStyle_nativeGetYThickness( ...@@ -53,9 +56,9 @@ Java_com_sun_java_swing_plaf_gtk_GTKStyle_nativeGetYThickness(
JNIEnv *env, jclass klass, jint widget_type) JNIEnv *env, jclass klass, jint widget_type)
{ {
jint ret; jint ret;
fp_gdk_threads_enter(); gtk->gdk_threads_enter();
ret = gtk2_get_ythickness(env, widget_type); ret = gtk->get_ythickness(env, widget_type);
fp_gdk_threads_leave(); gtk->gdk_threads_leave();
return ret; return ret;
} }
...@@ -70,9 +73,9 @@ Java_com_sun_java_swing_plaf_gtk_GTKStyle_nativeGetColorForState( ...@@ -70,9 +73,9 @@ Java_com_sun_java_swing_plaf_gtk_GTKStyle_nativeGetColorForState(
jint state_type, jint type_id) jint state_type, jint type_id)
{ {
jint ret; jint ret;
fp_gdk_threads_enter(); gtk->gdk_threads_enter();
ret = gtk2_get_color_for_state(env, widget_type, state_type, type_id); ret = gtk->get_color_for_state(env, widget_type, state_type, type_id);
fp_gdk_threads_leave(); gtk->gdk_threads_leave();
return ret; return ret;
} }
...@@ -86,9 +89,9 @@ Java_com_sun_java_swing_plaf_gtk_GTKStyle_nativeGetClassValue( ...@@ -86,9 +89,9 @@ Java_com_sun_java_swing_plaf_gtk_GTKStyle_nativeGetClassValue(
JNIEnv *env, jclass klass, jint widget_type, jstring key) JNIEnv *env, jclass klass, jint widget_type, jstring key)
{ {
jobject ret; jobject ret;
fp_gdk_threads_enter(); gtk->gdk_threads_enter();
ret = gtk2_get_class_value(env, widget_type, key); ret = gtk->get_class_value(env, widget_type, getStrFor(env, key));
fp_gdk_threads_leave(); gtk->gdk_threads_leave();
return ret; return ret;
} }
...@@ -102,8 +105,8 @@ Java_com_sun_java_swing_plaf_gtk_GTKStyle_nativeGetPangoFontName( ...@@ -102,8 +105,8 @@ Java_com_sun_java_swing_plaf_gtk_GTKStyle_nativeGetPangoFontName(
JNIEnv *env, jclass klass, jint widget_type) JNIEnv *env, jclass klass, jint widget_type)
{ {
jstring ret; jstring ret;
fp_gdk_threads_enter(); gtk->gdk_threads_enter();
ret = gtk2_get_pango_font_name(env, widget_type); ret = gtk->get_pango_font_name(env, widget_type);
fp_gdk_threads_leave(); gtk->gdk_threads_leave();
return ret; return ret;
} }
/* /*
* Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -579,7 +579,7 @@ static void update_poll_timeout(int timeout_control) { ...@@ -579,7 +579,7 @@ static void update_poll_timeout(int timeout_control) {
*/ */
static uint32_t get_poll_timeout(jlong nextTaskTime) static uint32_t get_poll_timeout(jlong nextTaskTime)
{ {
uint32_t ret_timeout; uint32_t ret_timeout = 0;
uint32_t timeout; uint32_t timeout;
uint32_t taskTimeout; uint32_t taskTimeout;
uint32_t flushTimeout; uint32_t flushTimeout;
......
/* /*
* Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
*/ */
#include "jni_util.h" #include "jni_util.h"
#include "gtk2_interface.h" #include "gtk_interface.h"
#include "gnome_interface.h" #include "gnome_interface.h"
static gboolean gtk_has_been_loaded = FALSE; static gboolean gtk_has_been_loaded = FALSE;
...@@ -36,14 +36,14 @@ static gboolean gnome_has_been_loaded = FALSE; ...@@ -36,14 +36,14 @@ static gboolean gnome_has_been_loaded = FALSE;
* Signature: ()Z * Signature: ()Z
*/ */
JNIEXPORT jboolean JNICALL Java_sun_awt_X11_XDesktopPeer_init JNIEXPORT jboolean JNICALL Java_sun_awt_X11_XDesktopPeer_init
(JNIEnv *env, jclass cls) (JNIEnv *env, jclass cls, jint version, jboolean verbose)
{ {
if (gtk_has_been_loaded || gnome_has_been_loaded) { if (gtk_has_been_loaded || gnome_has_been_loaded) {
return JNI_TRUE; return JNI_TRUE;
} }
if (gtk2_load(env) && gtk2_show_uri_load(env)) { if (gtk_load(env, version, verbose) && gtk->show_uri_load(env)) {
gtk_has_been_loaded = TRUE; gtk_has_been_loaded = TRUE;
return JNI_TRUE; return JNI_TRUE;
} else if (gnome_load()) { } else if (gnome_load()) {
...@@ -74,9 +74,9 @@ JNIEXPORT jboolean JNICALL Java_sun_awt_X11_XDesktopPeer_gnome_1url_1show ...@@ -74,9 +74,9 @@ JNIEXPORT jboolean JNICALL Java_sun_awt_X11_XDesktopPeer_gnome_1url_1show
} }
if (gtk_has_been_loaded) { if (gtk_has_been_loaded) {
fp_gdk_threads_enter(); gtk->gdk_threads_enter();
success = fp_gtk_show_uri(NULL, url_c, GDK_CURRENT_TIME, NULL); success = gtk->gtk_show_uri(NULL, url_c, GDK_CURRENT_TIME, NULL);
fp_gdk_threads_leave(); gtk->gdk_threads_leave();
} else if (gnome_has_been_loaded) { } else if (gnome_has_been_loaded) {
success = (*gnome_url_show)(url_c, NULL); success = (*gnome_url_show)(url_c, NULL);
} }
......
/* /*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
#ifndef _GNOME_INTERFACE_H #ifndef _GNOME_INTERFACE_H
#define _GNOME_INTERFACE_H #define _GNOME_INTERFACE_H
#include "gtk2_interface.h" #include "gtk_interface.h"
#include <dlfcn.h> #include <dlfcn.h>
#include <jvm_md.h> #include <jvm_md.h>
#include <jni.h> #include <jni.h>
......
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/* @test
* @bug 8157827
* @summary AWT_Desktop/Automated/Exceptions/BasicTest loads incorrect GTK
* version when jdk.gtk.version=3
* @requires (os.family == "linux")
* @run main DesktopGtkLoadTest
*/
import java.awt.*;
import java.io.*;
public class DesktopGtkLoadTest {
public static class RunDesktop {
public static void main(String[] args) {
Desktop.getDesktop();
}
}
public static void main(String[] args) throws Exception {
Process p = Runtime.getRuntime().exec(System.getProperty("java.home") +
"/bin/java -Djdk.gtk.version=3 -Djdk.gtk.verbose=true " +
"-cp " + System.getProperty("java.class.path", ".") +
" DesktopGtkLoadTest$RunDesktop");
p.waitFor();
try (BufferedReader br = new BufferedReader(
new InputStreamReader(p.getErrorStream()))) {
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
if (line.contains("Looking for GTK2 library")) {
break;
}
if (line.contains("Looking for GTK3 library")) {
return;
}
}
throw new RuntimeException("Wrong GTK library version: \n" + line);
}
}
}
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/* @test
* @bug 8156121
* @summary "Fail forward" fails for GTK3 if no GTK2 available
* @modules java.desktop/sun.awt
* @requires (os.family == "linux")
* @run main GtkVersionTest
*/
import sun.awt.UNIXToolkit;
import java.awt.*;
import java.io.*;
public class GtkVersionTest {
public static class LoadGtk {
public static void main(String[] args) {
((UNIXToolkit)Toolkit.getDefaultToolkit()).loadGTK();
}
}
public static void main(String[] args) throws Exception {
test(null, "2");
test("2", "2");
test("2.2", "2");
test("3", "3");
}
private static void test(String version, String expect) throws Exception {
System.out.println( "Test " +
(version == null ? "no" : " GTK" + version) + " preference.");
System.out.println("java home "+System.getProperty("java.home"));
Process p = Runtime.getRuntime().exec(System.getProperty("java.home") +
"/bin/java " +
(version == null ? "" : "-Djdk.gtk.version=" + version) +
" -Djdk.gtk.verbose=true " +
"-cp " + System.getProperty("java.class.path", ".") +
" GtkVersionTest$LoadGtk");
p.waitFor();
try (BufferedReader br = new BufferedReader(
new InputStreamReader(p.getErrorStream()))) {
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
if (line.contains("Looking for GTK" + expect + " library")) {
return;
} else if (line.contains("Looking for GTK")) {
break;
}
}
throw new RuntimeException("Wrong GTK library version: expected: " + expect + " actual: " + line + " version: " + version);
}
}
}
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
@test
@summary Tests that GTK LaF is supported on solaris
regardless of jdk.gtk.version flag values.
@bug 8156121
@requires (os.name == "linux" | os.name == "solaris")
@run main/othervm -Djdk.gtk.version=2 DemandGTK
@run main/othervm -Djdk.gtk.version=3 DemandGTK
*/
import javax.swing.JFrame;
import javax.swing.UIManager;
import javax.swing.SwingUtilities;
import java.awt.Robot;
public class DemandGTK {
static JFrame frame;
public static void createAndShow() {
try {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.gtk.GTKLookAndFeel");
} catch(Exception cnf) {
cnf.printStackTrace();
throw new RuntimeException("GTK LaF must be supported");
}
frame = new JFrame("JFrame");
frame.setSize(200, 200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) throws Exception {
SwingUtilities.invokeAndWait(DemandGTK::createAndShow);
Robot robot = new Robot();
robot.waitForIdle();
robot.delay(1000);
SwingUtilities.invokeAndWait( () -> {
frame.setVisible(false);
frame.dispose();
});
}
}
#!/bin/ksh -p
#
# Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation.
#
# This code 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 General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
#
# @test
# @summary Try to force GTK2. We must bail out to GTK3 (if any) if no 2 available.
#
# @compile ProvokeGTK.java
# @requires os.family == "linux"
# @run shell/timeout=400 DemandGTK2.sh
#
# Note that we depend on
# strace in the PATH
# /sbin/ldconfig (which may be not in PATH)
# It is true for OEL 7 and Ubuntu 14, 16
# but may fail in future. Save tomorrow for tomorrow.
#
# Read DemandGTK2.txt how to prepare GTK2-less machine.
#
which strace
if [ $? -ne 0 ]
then
echo "Please provide strace: \"which strace\" failed."
exit 1
fi
HAVE_2=`/sbin/ldconfig -v 2>/dev/null | grep libgtk-x11-2 | wc -l`
HAVE_3=`/sbin/ldconfig -v 2>/dev/null | grep libgtk-3.so | wc -l`
if [ "${HAVE_2}" = "0" ]
then
if [ "${HAVE_3}" = "0" ]
then
echo "Neither GTK2 nor GTK3 found: system misconfiguration. Exit."
exit 1
fi
echo "No GTK 2 library found: we should bail out to 3"
strace -o strace.log -fe open ${TESTJAVA}/bin/java -cp ${TESTCLASSPATH} -Djdk.gtk.version=2 ProvokeGTK
EXECRES=$?
grep 'libgtk-3.*=\ *[0-9]*$' strace.log > logg
else
echo "There is GTK 2 library: we should use it"
strace -o strace.log -fe open ${TESTJAVA}/bin/java -cp ${TESTCLASSPATH} -Djdk.gtk.version=2 ProvokeGTK
EXECRES=$?
grep 'libgtk-x11.*=\ *[0-9]*$' strace.log > logg
fi
if [ ${EXECRES} -ne 0 ]
then
echo "java execution failed for unknown reason, see logs"
exit 2
fi
cat logg
if [ -s logg ]
then
echo "Success."
exit 0
else
echo "Failed. Examine logs."
exit 3
fi
How to prepare an Ubuntu machine for GTK-2-less test run.
The test DemandGTK2.sh should work well without GTK-2 switching to version 3
if there's no GTK-2 library available.
At the moment, it's not easy to find a system with GTK-3 and without GTK-2:
many programs still depend on version 2.
We can, however, rename GTK-2 library for a single test run and then restore
it back.
(1) Find GTK2 library: run
/sbin/ldconfig -v 2>/dev/null | grep libgtk-x11-2
It will output one or two lines like
libgtk-x11-2.0.so.0 -> libgtk-x11-2.0.so.0.2400.23
Search for the target of that symlink for instance with locate:
locate libgtk-x11-2.0.so.0.2400.23
Finally, you'll find the libraries. On my current machine they are
/usr/lib/i386-linux-gnu/libgtk-x11-2.0.so.0.2400.23
/usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0.2400.23
I'm running 64-bit JDK and need to tamper with x86_64 copy only.
(2) Find running programs depending on this library. They probably would crash
if you rename it. Stop them for this test run.
That said, I'm afraid it would be impossible to do on a system older than Ubuntu 16.04.
On my Ubuntu 16.04 I have only hud-service using this library, and that's OK, it will restart
after a crash, if any.
To find these programs, run
lsof /usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0.2400.23
(3) Now,
sudo mv /usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0.2400.23 /usr/lib/x86_64-linux-gnu/bak.libgtk-x11-2.0.so.0.2400.23
jtreg DemandGTK2.sh
sudo mv /usr/lib/x86_64-linux-gnu/bak.libgtk-x11-2.0.so.0.2400.23 /usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0.2400.23
Needless to say, you should substitute your own library path and however you run jtreg.
#!/bin/ksh -p
#
# Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation.
#
# This code 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 General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
#
# @test
# @summary Try to force GTK3. We must bail out to GTK2 if no 3 available.
#
# @compile ProvokeGTK.java
# @requires os.family == "linux"
# @run shell/timeout=400 DemandGTK3.sh
#
# Note that we depend on
# strace in the PATH
# /sbin/ldconfig (which may be is not in PATH)
# It is true for OEL 7 and Ubuntu 14, 16
# but may fail in future. Save tomorrow for tomorrow.
#
which strace
if [ $? -ne 0 ]
then
echo "Please provide strace: \"which strace\" failed."
exit 1
fi
HAVE_3=`/sbin/ldconfig -v 2>/dev/null | grep libgtk-3.so | wc -l`
if [ "${HAVE_3}" = "0" ]
then
echo "No GTK 3 library found: we should bail out to 2"
strace -o strace.log -fe open ${TESTJAVA}/bin/java -cp ${TESTCLASSPATH} -Djdk.gtk.version=3 ProvokeGTK
EXECRES=$?
grep 'libgtk-x11.*=\ *[0-9]*$' strace.log > logg
else
echo "There is GTK 3 library: we should use it"
strace -o strace.log -fe open ${TESTJAVA}/bin/java -cp ${TESTCLASSPATH} -Djdk.gtk.version=3 ProvokeGTK
EXECRES=$?
grep 'libgtk-3.*=\ *[0-9]*$' strace.log > logg
fi
if [ ${EXECRES} -ne 0 ]
then
echo "java execution failed for unknown reason, see logs"
exit 2
fi
cat logg
if [ -s logg ]
then
echo "Success."
exit 0
else
echo "Failed. Examine logs."
exit 3
fi
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import javax.swing.JFrame;
import javax.swing.UIManager;
import javax.swing.SwingUtilities;
public class ProvokeGTK {
static JFrame frame;
public static void createAndShow() {
try {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.gtk.GTKLookAndFeel");
} catch(Exception cnf) {
cnf.printStackTrace();
}
frame = new JFrame("JFrame");
frame.setSize(200, 200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) throws Exception {
SwingUtilities.invokeAndWait(ProvokeGTK::createAndShow);
Thread.sleep(1000);
SwingUtilities.invokeAndWait( () -> {
frame.setVisible(false);
frame.dispose();
});
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册