package imgui import ( "mxl-player/internal/sdl" "unsafe" cimgui "github.com/AllenDang/cimgui-go/imgui" ) const ( sdlKModShift uint16 = 0x0001 | 0x0002 sdlKModCtrl uint16 = 0x0040 | 0x0080 sdlKModAlt uint16 = 0x0100 | 0x0200 sdlKModGUI uint16 = 0x0400 | 0x0800 ) // SDL3 event (128 byte raw buffer) -> imgui func (c *Context) ProcessEvent(event *[128]byte) { eventType := *(*uint32)(unsafe.Pointer(&event[0])) // CommonEvent (16 bytes: type uint32 + reserved uint32 + timestamp uint64) switch eventType { case sdl.EventKeyDown, sdl.EventKeyUp: scancode := *(*uint32)(unsafe.Pointer(&event[24])) modifiers := *(*uint16)(unsafe.Pointer(&event[32])) down := eventType == sdl.EventKeyDown c.addKeyModifiers(modifiers) key := sdlScancodeToImGuiKey(scancode) if key >= 0 { c.io.AddKeyEvent(key, down) } // MouseMotionEvent: +16 windowID(4), +20 which(4), +24 state(4), +28 x(float32), +32 y(float32) case sdl.EventMouseMotion: x := *(*float32)(unsafe.Pointer(&event[28])) y := *(*float32)(unsafe.Pointer(&event[32])) c.io.AddMousePosEvent(x, y) // MouseButtonEvent: +16 windowID(4), +20 which(4), +24 button(1), +25 down(bool) case sdl.EventMouseButtonDown, sdl.EventMouseButtonUp: button := *(*uint8)(unsafe.Pointer(&event[24])) down := eventType == sdl.EventMouseButtonDown c.io.AddMouseButtonEvent(int32(button-1), down) // MouseWheelEvent: +16 windowID(4), +20 which(4), +24 x(float32), +28 y(float32) case sdl.EventMouseWheel: x := *(*float32)(unsafe.Pointer(&event[24])) y := *(*float32)(unsafe.Pointer(&event[28])) c.io.AddMouseWheelEvent(x, y) // TextInputEvent: +16 windowID(4), +20 text(*char pointer, 8 bytes on 64-bit) case sdl.EventTextInput: // text pointer is at offset 24, 8 bytes (pointer) ptr := *(*uintptr)(unsafe.Pointer(&event[24])) if ptr != 0 { text := cstr(ptr) c.io.AddInputCharactersUTF8(text) } } } func (c *Context) addKeyModifiers(modifiers uint16) { c.io.AddKeyEvent(cimgui.ModCtrl, modifiers&sdlKModCtrl != 0) c.io.AddKeyEvent(cimgui.ModShift, modifiers&sdlKModShift != 0) c.io.AddKeyEvent(cimgui.ModAlt, modifiers&sdlKModAlt != 0) c.io.AddKeyEvent(cimgui.ModSuper, modifiers&sdlKModGUI != 0) } func sdlScancodeToImGuiKey(scancode uint32) cimgui.Key { switch scancode { case 40: // SDL_SCANCODE_RETURN return cimgui.KeyEnter case 42: // SDL_SCANCODE_BACKSPACE return cimgui.KeyBackspace case 41: // SDL_SCANCODE_ESCAPE return cimgui.KeyEscape case 43: // SDL_SCANCODE_TAB return cimgui.KeyTab case 44: // SDL_SCANCODE_SPACE return cimgui.KeySpace case 80: // SDL_SCANCODE_LEFT return cimgui.KeyLeftArrow case 79: // SDL_SCANCODE_RIGHT return cimgui.KeyRightArrow case 82: // SDL_SCANCODE_UP return cimgui.KeyUpArrow case 81: // SDL_SCANCODE_DOWN return cimgui.KeyDownArrow case 225: // SDL_SCANCODE_LSHIFT return cimgui.KeyLeftShift case 229: // SDL_SCANCODE_RSHIFT return cimgui.KeyRightShift case 224: // SDL_SCANCODE_LCTRL return cimgui.KeyLeftCtrl case 228: // SDL_SCANCODE_RCTRL return cimgui.KeyRightCtrl case 226: // SDL_SCANCODE_LALT return cimgui.KeyLeftAlt case 230: // SDL_SCANCODE_RALT return cimgui.KeyRightAlt case 227: // SDL_SCANCODE_LGUI return cimgui.KeyLeftSuper case 231: // SDL_SCANCODE_RGUI return cimgui.KeyRightSuper default: // Letters A-Z: scancodes 4-29 map to ImGui KeyA-KeyZ if scancode >= 4 && scancode <= 29 { return cimgui.Key(int(cimgui.KeyA) + int(scancode-4)) } // Numbers 0-9: scancodes 30-39 if scancode >= 30 && scancode <= 39 { return cimgui.Key(int(cimgui.Key0) + int(scancode-30)) } return -1 } } // cstr reads a NUL-terminated C string at p. // TODO: same func used in Vulkan // Maybe i should create something like "package common" // for funcs like this func cstr(p uintptr) string { if p == 0 { return "" } var n int for *(*byte)(unsafe.Pointer(p + uintptr(n))) != 0 { n++ } return string(unsafe.Slice((*byte)(unsafe.Pointer(p)), n)) }