I have two snippets, in C and Nim which supposed to be exact copies of eachother.
#include <stdio.h>
#include <X11/Xlib.h>
#include <X11/XKBlib.h>
typedef struct keymap {
int keycode_high;
int keycode_low;
} keymap_t;
keymap_t keymap_new(Display *dpy) {
keymap_t result;
XDisplayKeycodes(dpy, &(result.keycode_low), &(result.keycode_high));
XkbDescPtr desc = XkbGetMap(dpy, XkbAllClientInfoMask, XkbUseCoreKbd);
for (int keycode = result.keycode_low; keycode <= result.keycode_high; keycode++) {
int groups = XkbKeyNumGroups(desc, keycode);
printf("%d\n", groups);
}
XkbFreeClientMap(desc, 0, 1);
return result;
}
int main(){
Display *dpy = XOpenDisplay(NULL);
keymap_t x = keymap_new(dpy);
XCloseDisplay(dpy);
}
import x11/[xlib, xkblib]
import x11/xkb except X_kbGetMap
type Keymap = object
keycodeHigh, keycodeLow: cint
proc newKeymap(display: PDisplay): Keymap =
discard XDisplayKeycodes(display, addr result.keycodeLow, addr result.keycodeHigh)
let desc = XkbGetMap(display, XkbAllClientInfoMask, XkbUseCoreKbd)
for keycode in result.keycodeLow..result.keycodeHigh:
let groups = XkbKeyNumGroups(desc, keycode.int16)
echo groups
XkbFreeClientMap(desc, 0, true)
let
display = XOpenDisplay(nil)
keymap = newKeymap(display)
discard XCloseDisplay display
They are supposed to have same output, but it differs, which in nim version can lead to segfaults in further usage of returned data. I looked at structure definitions in bindings and they seem correct, so im out of ideas now.
Idk too, but try to wrap the functionality in some proc like main or anything and just call that proc.
Another thing, you can always use gdb to check each variable which one has nil.
As far as I can tell, group_info values differ
desc.map.key_sym_map[keycode].group_info
desc->map->key_sym_map[keycode].group_info
there is no nil, it reports wrong size.
I remember something when doing ffmpeg c binding. At first I wrote the binding without adding the header pragma, and just simply importc pragma only. In the c header file, that particular object actually internal struct that isn't included in dev headers, and it's there just as to declare the type/struct.
I debugged that and it was returning nil or something that not nil but would crash/segfault if I tried to deref it.
After adding the header pragma then it ran smoothly and when debugging, the gdb returning the correct struct name.
Idk if it's related or not, but you can try looking that part.