-
Notifications
You must be signed in to change notification settings - Fork 7
Notes on the translation process
The C sources for GLFW 3.3.2 were copied into a dub project, and the .c
and .h
files were translated one by one.
The initial translation was done automatically using a program I made: ctod. (if that link 404's it's probably still private)
That program was being developed in tandem with this translation.
I started with the x11 target, and also had to (partially) translate certain header files (X11.h
, input.h
) that GLFW uses.
The x11 target also depends on regex.h
, but only for linux_joystick to detect file names of the form event[0-9]+
.
I implemented a function that manually checks that pattern, since that was easier than actually translating the regex header.
The automatic conversion converts a lot of C syntax to D, but there were still semantic differences to translate manually:
- passing static arrays to function require a
.ptr
- taking function addresses require a
&
-
switch
statements need a default case - the result of
calloc
needs to be explicitly cast fromvoid*
to the wanted pointer type - aliases to dynamically loaded function pointers
_glfw.x11.func
are not allowed (needthis
for global variable_glfw
) - many macros (
GLFW_REQUIRE_INIT
) need a stringmixin
at the usage site, and other macros were translated to a function
The translation was mostly uneventful, except for these things:
- I assumed
long
in C is 4 bytes big and onlylong long
is 8 bytes. This is true on Windows 32/64 bit, but on Linux 64-bit along
is 8 bytes. I had to manually changelong
intoc_long
fromcore.stdc.config
. - Public GLFW functions have a
GLFWAPI
macro to make them exported in a DLL build. This macro placement was seen as a syntax error by the C parser, so some of the return types were 'eaten' and replaced byGLFWAPI
, which I manually corrected. - there were some link errors because the headers were initially not mentioned as source files in
dub.sdl
, but that led to certain missingstruct.init
symbols. Even though I try to initialize every struct member with 0 to avoid these 'init' symbols, it seems older versions ofdmd
still emit the all-zero init symbol. - linux joystick used to not work because a
memcpy
had a wrongly translated length parameter. meaning the button mapping remained all zero.
After that the Windows target was translated.
- I found out that while most WinAPI functions in GLFW use late-binding,
AdjustWindowRectEx
seems to be linked using import libraries. Inwin32_window.d
it often appears right next toAdjustWindowRectExForDpi
, which is manually loaded. Looks like an oversight in the original GLFW source, but I am not sure. -
dinput.h
uses Windows' Component Object Model (COM) to simulate OOP structures. TheIDirectInputDevice8W
andIDirectInput8W
interfaces are declared using macros, so it took a little digging to find what structures were actually being declared. It turns out the first member of these structs is a pointer to the Vtable, which is a struct with the interfaces member functions in order of appearance in the header. I translated the Vtables correctly, but initially I put the Vtable structure itself as the first member, instead of a pointer to the Vtable.
Here's an overview of the newly introduced header files:
File | Header it replaces |
---|---|
directinput8.d | dinput.h |
xinput.d | xinput.h |
x11_header.d | X11.h |
linuxinput.d |
input.h and input-event-codes.h
|