Progress update:
I just created the first window using the API that's generated through the new code generator. And it's all Java code!
public void testCreateWindow() {
final ByteBuffer wndClassEx = WNDCLASSEX.malloc();
WNDCLASSEX.cbSize(wndClassEx, WNDCLASSEX.SIZEOF);
WNDCLASSEX.style(wndClassEx, CS_OWNDC);
WNDCLASSEX.lpfnWndProc(wndClassEx, WindowsPlatform.getDefWindowProc());
WNDCLASSEX.cbClsExtra(wndClassEx, 0);
WNDCLASSEX.cbWndExtra(wndClassEx, 0);
WNDCLASSEX.hInstance(wndClassEx, WindowsPlatform.getHINSTANCE());
WNDCLASSEX.hIcon(wndClassEx, nLoadIcon(0, IDI_APPLICATION));
WNDCLASSEX.hCursor(wndClassEx, nLoadCursor(0, IDC_ARROW));
WNDCLASSEX.hbrBackground(wndClassEx, 0);
WNDCLASSEX.lpszMenuName(wndClassEx, 0);
WNDCLASSEX.lpszClassName(wndClassEx, memAddress(memEncodeUTF16("LWJGL")));
WNDCLASSEX.hIconSm(wndClassEx, 0);
final short classAtom = RegisterClassEx(wndClassEx);
assertTrue(classAtom != 0);
final long hwnd = CreateWindowEx(
WS_EX_APPWINDOW,
memEncodeUTF16("LWJGL"),
memEncodeUTF16("LWJGL Test"),
WS_OVERLAPPED | WS_BORDER | WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
0, 0, 640, 480,
0, 0, WindowsPlatform.getHINSTANCE(), 0
);
assertTrue(hwnd != 0);
ShowWindow(hwnd, SW_SHOWDEFAULT);
DestroyWindow(hwnd);
}
So, the first milestone is complete, we can now create bindings to arbitrary OS-specific APIs. We also generate "struct classes" that take care of setting up ByteBuffer in a way that the system call understands (WNDCLASSEX in the above example). It supports any primitive value, pointer values (automatically cast to 32 or 64 bits at runtime) and also nested structs. All the struct member offsets are discovered at runtime from auto-generated native code.
The Generator Kotlin-based DSL looks like this:
// A simple type
val DWORD = PrimitiveType("DWORD", PrimitiveMapping.INT)
// A struct type definition
val LPGLYPHMETRICSFLOAT = StructType(
name = "LPGLYPHMETRICSFLOAT",
includesPointer = true,
definition = struct(WINDOWS_PACKAGE, "GLYPHMETRICSFLOAT") {
nativeImport ("WindowsLWJGL.h")
FLOAT _ "gmfBlackBoxX"
FLOAT _ "gmfBlackBoxY"
POINTFLOAT _ "gmfptGlyphOrigin" // Nested struct
FLOAT _ "gmfCellIncX"
FLOAT _ "gmfCellIncY"
}
)
// A Windows function
HWND.func("CreateWindowEx") {
DWORD IN "exStyle"
LPCTSTR IN "className"
LPCTSTR IN "windowName"
DWORD IN "style"
int IN "x"
int IN "y"
int IN "width"
int IN "height"
HWND IN "parent"
HMENU IN "menu"
HINSTANCE IN "instance"
LPVOID IN "param"
}
// A WGL function
BOOL.func("wglMakeCurrent") {
HDC IN "device"
HGLRC IN "context"
javaDoc {
"""
Makes a specified OpenGL rendering context the calling thread's current rendering context.
All subsequent OpenGL calls made by the thread are drawn on the device identified by device.
You can also use wglMakeCurrent to change the calling thread's current rendering context so it's no longer current.
"""
}
}
The next milestone will be adding support for context/device specific functions. Once that's done, I'll create the 3.0 branch and start accepting contributions.