Skip to content

Commit b7f21a1

Browse files
committed
PoC - Use Foreign Function & Memory API for GTK3 OS Support
1 parent 60dc886 commit b7f21a1

File tree

17 files changed

+622
-14
lines changed

17 files changed

+622
-14
lines changed

org.eclipse.wb.os.linux/.classpath

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,16 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<classpath>
3-
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-21"/>
3+
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-24">
4+
<attributes>
5+
<attribute name="module" value="true"/>
6+
</attributes>
7+
</classpathentry>
48
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
59
<classpathentry kind="src" path="src"/>
10+
<classpathentry kind="src" path="src_java25">
11+
<attributes>
12+
<attribute name="release" value="25"/>
13+
</attributes>
14+
</classpathentry>
615
<classpathentry kind="output" path="bin"/>
716
</classpath>

org.eclipse.wb.os.linux/.settings/org.eclipse.jdt.core.prefs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
eclipse.preferences.version=1
22
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
3-
org.eclipse.jdt.core.compiler.codegen.targetPlatform=21
3+
org.eclipse.jdt.core.compiler.codegen.targetPlatform=24
44
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
5-
org.eclipse.jdt.core.compiler.compliance=21
5+
org.eclipse.jdt.core.compiler.compliance=24
66
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
77
org.eclipse.jdt.core.compiler.debug.localVariable=generate
88
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
@@ -65,7 +65,7 @@ org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disa
6565
org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
6666
org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
6767
org.eclipse.jdt.core.compiler.release=enabled
68-
org.eclipse.jdt.core.compiler.source=21
68+
org.eclipse.jdt.core.compiler.source=24
6969
org.eclipse.jdt.core.formatter.align_assignment_statements_on_columns=false
7070
org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines=2147483647
7171
org.eclipse.jdt.core.formatter.align_selector_in_method_invocation_on_expression_first_line=true

org.eclipse.wb.os.linux/META-INF/MANIFEST.MF

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Bundle-Name: %pluginName
44
Bundle-SymbolicName: org.eclipse.wb.os.linux;singleton:=true
55
Bundle-Version: 1.10.300.qualifier
66
Bundle-Vendor: %providerName
7-
Bundle-RequiredExecutionEnvironment: JavaSE-21
7+
Bundle-RequiredExecutionEnvironment: JavaSE-24
88
Eclipse-PlatformFilter: (& (osgi.ws=gtk) (osgi.os=linux))
99
Require-Bundle: org.eclipse.swt;bundle-version="[3.126.0,4.0.0)",
1010
org.eclipse.core.runtime;bundle-version="[3.31.100,4.0.0)",
@@ -18,6 +18,7 @@ Bundle-ActivationPolicy: lazy
1818
Bundle-Localization: plugin
1919
Import-Package: org.apache.commons.io;version="[2.16.1,3.0.0)",
2020
org.apache.commons.lang3;version="[3.14.0,4.0.0)",
21+
org.apache.commons.lang3.function;version="[3.14.0,4.0.0)",
2122
org.eclipse.wb.os
2223
Automatic-Module-Name: org.eclipse.wb.os.linux
2324
Provide-Capability: wbp;type=os

org.eclipse.wb.os.linux/src/org/eclipse/wb/internal/os/linux/OSSupportLinux.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import org.eclipse.swt.widgets.Menu;
3636
import org.eclipse.swt.widgets.MenuItem;
3737
import org.eclipse.swt.widgets.Shell;
38+
import org.eclipse.swt.widgets.TabItem;
3839
import org.eclipse.swt.widgets.Tree;
3940
import org.eclipse.swt.widgets.Widget;
4041

@@ -518,7 +519,7 @@ public final int getDefaultMenuBarHeight() {
518519
//
519520
////////////////////////////////////////////////////////////////////////////
520521
@Override
521-
public final Rectangle getTabItemBounds(Object tabItem) {
522+
public final Rectangle getTabItemBounds(TabItem tabItem) {
522523
return getWidgetBounds(tabItem);
523524
}
524525

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2025 Patrick Ziegler and others.
3+
*
4+
* This program and the accompanying materials are made available under the
5+
* terms of the Eclipse Public License 2.0 which is available at
6+
* https://www.eclipse.org/legal/epl-2.0.
7+
*
8+
* SPDX-License-Identifier: EPL-2.0
9+
*
10+
* Contributors:
11+
* Patrick Ziegler - initial API and implementation
12+
*******************************************************************************/
13+
package org.eclipse.wb.internal.os.linux;
14+
15+
import java.lang.foreign.Arena;
16+
import java.lang.foreign.MemoryLayout;
17+
import java.lang.foreign.MemorySegment;
18+
import java.lang.foreign.StructLayout;
19+
import java.lang.foreign.ValueLayout;
20+
21+
/**
22+
* A GdkRectangle data type for representing rectangles.
23+
*
24+
* GdkRectangle is identical to cairo_rectangle_t. Together with Cairo’s
25+
* cairo_region_t data type, these are the central types for representing sets
26+
* of pixels.
27+
*
28+
* The intersection of two rectangles can be computed with
29+
* gdk_rectangle_intersect(); to find the union of two rectangles use
30+
* gdk_rectangle_union().
31+
*
32+
* The cairo_region_t type provided by Cairo is usually used for managing
33+
* non-rectangular clipping of graphical operations.
34+
*
35+
* The Graphene library has a number of other data types for regions and volumes
36+
* in 2D and 3D.
37+
*/
38+
public sealed class GdkRectangle permits GtkAllocation {
39+
private static final StructLayout LAYOUT = MemoryLayout.structLayout( //
40+
ValueLayout.JAVA_INT.withName("x"), //
41+
ValueLayout.JAVA_INT.withName("y"), //
42+
ValueLayout.JAVA_INT.withName("width"), //
43+
ValueLayout.JAVA_INT.withName("height"));
44+
45+
private final MemorySegment segment;
46+
47+
public GdkRectangle(Arena arena) {
48+
segment = arena.allocate(LAYOUT);
49+
}
50+
51+
public final int x() {
52+
return segment.get(ValueLayout.JAVA_INT, 0);
53+
}
54+
55+
public final int y() {
56+
return segment.get(ValueLayout.JAVA_INT, 4);
57+
}
58+
59+
public final int width() {
60+
return segment.get(ValueLayout.JAVA_INT, 8);
61+
}
62+
63+
public final int height() {
64+
return segment.get(ValueLayout.JAVA_INT, 12);
65+
}
66+
67+
public final MemorySegment segment() {
68+
return segment;
69+
}
70+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2025 Patrick Ziegler and others.
3+
*
4+
* This program and the accompanying materials are made available under the
5+
* terms of the Eclipse Public License 2.0 which is available at
6+
* https://www.eclipse.org/legal/epl-2.0.
7+
*
8+
* SPDX-License-Identifier: EPL-2.0
9+
*
10+
* Contributors:
11+
* Patrick Ziegler - initial API and implementation
12+
*******************************************************************************/
13+
package org.eclipse.wb.internal.os.linux;
14+
15+
import java.lang.foreign.Arena;
16+
17+
/**
18+
* A GtkAllocation-struct of a widget represents region which has been allocated
19+
* to the widget by its parent. It is a subregion of its parents allocation.
20+
*/
21+
public final class GtkAllocation extends GdkRectangle {
22+
public GtkAllocation(Arena arena) {
23+
super(arena);
24+
}
25+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2025 Patrick Ziegler and others.
3+
*
4+
* This program and the accompanying materials are made available under the
5+
* terms of the Eclipse Public License 2.0 which is available at
6+
* https://www.eclipse.org/legal/epl-2.0.
7+
*
8+
* SPDX-License-Identifier: EPL-2.0
9+
*
10+
* Contributors:
11+
* Patrick Ziegler - initial API and implementation
12+
*******************************************************************************/
13+
package org.eclipse.wb.internal.os.linux;
14+
15+
import org.eclipse.wb.os.OSRuntimeException;
16+
17+
/**
18+
* Wrapper for all exceptions thrown while accessing native code.
19+
*/
20+
public class GtkRuntimeException extends OSRuntimeException {
21+
private static final long serialVersionUID = 1L;
22+
23+
public GtkRuntimeException(Throwable t) {
24+
super(t);
25+
}
26+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2025 Patrick Ziegler and others.
3+
*
4+
* This program and the accompanying materials are made available under the
5+
* terms of the Eclipse Public License 2.0 which is available at
6+
* https://www.eclipse.org/legal/epl-2.0.
7+
*
8+
* SPDX-License-Identifier: EPL-2.0
9+
*
10+
* Contributors:
11+
* Patrick Ziegler - initial API and implementation
12+
*******************************************************************************/
13+
package org.eclipse.wb.internal.os.linux;
14+
15+
import org.eclipse.wb.internal.core.utils.reflect.ReflectionUtils;
16+
17+
import org.eclipse.swt.widgets.Shell;
18+
import org.eclipse.swt.widgets.Widget;
19+
20+
/**
21+
* GtkWidget is the base class all widgets in GTK+ derive from. It manages the
22+
* widget lifecycle, states and style.
23+
*/
24+
public record GtkWidget(long handle) {
25+
26+
public GtkWidget(Shell shell) {
27+
this(getShellHandle(shell));
28+
}
29+
30+
public GtkWidget(Widget widget) {
31+
this(getHandle(widget));
32+
}
33+
34+
/**
35+
* @return the handle value of the {@link Shell} using reflection.
36+
*/
37+
private static long getShellHandle(Shell shell) {
38+
long widgetHandle = getHandleValue(shell, "fixedHandle");
39+
if (widgetHandle == 0) {
40+
// may be null, roll back to "shellHandle"
41+
widgetHandle = getHandleValue(shell, "shellHandle");
42+
}
43+
return widgetHandle;
44+
}
45+
46+
/**
47+
* @return the handle value of the {@link Widget} using reflection.
48+
*/
49+
private static long getHandle(Widget widget) {
50+
return getHandleValue(widget, "handle");
51+
}
52+
53+
/**
54+
* @return the widget as native pointer for native handles. Note: returns 0 if
55+
* handle cannot be obtained.
56+
*/
57+
private static long getHandleValue(Object widget, String fieldName) {
58+
if (ReflectionUtils.getFieldObject(widget, fieldName) instanceof Long longValue) {
59+
return longValue;
60+
}
61+
// field might be shadowed (e.g. in ImageBasedFrame)
62+
return 0L;
63+
}
64+
}

0 commit comments

Comments
 (0)