zorldo

Goofing around with Ebiten
git clone git://bsandro.tech/zorldo
Log | Files | Refs | README

input.go (35755B)


      1 package glfw
      2 
      3 //#include <stdlib.h>
      4 //#define GLFW_INCLUDE_NONE
      5 //#include "glfw/include/GLFW/glfw3.h"
      6 //void glfwSetJoystickCallbackCB();
      7 //void glfwSetKeyCallbackCB(GLFWwindow *window);
      8 //void glfwSetCharCallbackCB(GLFWwindow *window);
      9 //void glfwSetCharModsCallbackCB(GLFWwindow *window);
     10 //void glfwSetMouseButtonCallbackCB(GLFWwindow *window);
     11 //void glfwSetCursorPosCallbackCB(GLFWwindow *window);
     12 //void glfwSetCursorEnterCallbackCB(GLFWwindow *window);
     13 //void glfwSetScrollCallbackCB(GLFWwindow *window);
     14 //void glfwSetDropCallbackCB(GLFWwindow *window);
     15 //float GetAxisAtIndex(float *axis, int i);
     16 //unsigned char GetButtonsAtIndex(unsigned char *buttons, int i);
     17 //float GetGamepadAxisAtIndex(GLFWgamepadstate *gp, int i);
     18 //unsigned char GetGamepadButtonAtIndex(GLFWgamepadstate *gp, int i);
     19 import "C"
     20 
     21 import (
     22 	"image"
     23 	"image/draw"
     24 	"unsafe"
     25 )
     26 
     27 // Joystick corresponds to a joystick.
     28 type Joystick int
     29 
     30 // Joystick IDs.
     31 const (
     32 	Joystick1    Joystick = C.GLFW_JOYSTICK_1
     33 	Joystick2    Joystick = C.GLFW_JOYSTICK_2
     34 	Joystick3    Joystick = C.GLFW_JOYSTICK_3
     35 	Joystick4    Joystick = C.GLFW_JOYSTICK_4
     36 	Joystick5    Joystick = C.GLFW_JOYSTICK_5
     37 	Joystick6    Joystick = C.GLFW_JOYSTICK_6
     38 	Joystick7    Joystick = C.GLFW_JOYSTICK_7
     39 	Joystick8    Joystick = C.GLFW_JOYSTICK_8
     40 	Joystick9    Joystick = C.GLFW_JOYSTICK_9
     41 	Joystick10   Joystick = C.GLFW_JOYSTICK_10
     42 	Joystick11   Joystick = C.GLFW_JOYSTICK_11
     43 	Joystick12   Joystick = C.GLFW_JOYSTICK_12
     44 	Joystick13   Joystick = C.GLFW_JOYSTICK_13
     45 	Joystick14   Joystick = C.GLFW_JOYSTICK_14
     46 	Joystick15   Joystick = C.GLFW_JOYSTICK_15
     47 	Joystick16   Joystick = C.GLFW_JOYSTICK_16
     48 	JoystickLast Joystick = C.GLFW_JOYSTICK_LAST
     49 )
     50 
     51 // JoystickHatState corresponds to joystick hat states.
     52 type JoystickHatState int
     53 
     54 // Joystick Hat State IDs.
     55 const (
     56 	HatCentered  JoystickHatState = C.GLFW_HAT_CENTERED
     57 	HatUp        JoystickHatState = C.GLFW_HAT_UP
     58 	HatRight     JoystickHatState = C.GLFW_HAT_RIGHT
     59 	HatDown      JoystickHatState = C.GLFW_HAT_DOWN
     60 	HatLeft      JoystickHatState = C.GLFW_HAT_LEFT
     61 	HatRightUp   JoystickHatState = C.GLFW_HAT_RIGHT_UP
     62 	HatRightDown JoystickHatState = C.GLFW_HAT_RIGHT_DOWN
     63 	HatLeftUp    JoystickHatState = C.GLFW_HAT_LEFT_UP
     64 	HatLeftDown  JoystickHatState = C.GLFW_HAT_LEFT_DOWN
     65 )
     66 
     67 // GamepadAxis corresponds to a gamepad axis.
     68 type GamepadAxis int
     69 
     70 // Gamepad axis IDs.
     71 const (
     72 	AxisLeftX        GamepadAxis = C.GLFW_GAMEPAD_AXIS_LEFT_X
     73 	AxisLeftY        GamepadAxis = C.GLFW_GAMEPAD_AXIS_LEFT_Y
     74 	AxisRightX       GamepadAxis = C.GLFW_GAMEPAD_AXIS_RIGHT_X
     75 	AxisRightY       GamepadAxis = C.GLFW_GAMEPAD_AXIS_RIGHT_Y
     76 	AxisLeftTrigger  GamepadAxis = C.GLFW_GAMEPAD_AXIS_LEFT_TRIGGER
     77 	AxisRightTrigger GamepadAxis = C.GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER
     78 	AxisLast         GamepadAxis = C.GLFW_GAMEPAD_AXIS_LAST
     79 )
     80 
     81 // GamepadButton corresponds to a gamepad button.
     82 type GamepadButton int
     83 
     84 // Gamepad button IDs.
     85 const (
     86 	ButtonA           GamepadButton = C.GLFW_GAMEPAD_BUTTON_A
     87 	ButtonB           GamepadButton = C.GLFW_GAMEPAD_BUTTON_B
     88 	ButtonX           GamepadButton = C.GLFW_GAMEPAD_BUTTON_X
     89 	ButtonY           GamepadButton = C.GLFW_GAMEPAD_BUTTON_Y
     90 	ButtonLeftBumper  GamepadButton = C.GLFW_GAMEPAD_BUTTON_LEFT_BUMPER
     91 	ButtonRightBumper GamepadButton = C.GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER
     92 	ButtonBack        GamepadButton = C.GLFW_GAMEPAD_BUTTON_BACK
     93 	ButtonStart       GamepadButton = C.GLFW_GAMEPAD_BUTTON_START
     94 	ButtonGuide       GamepadButton = C.GLFW_GAMEPAD_BUTTON_GUIDE
     95 	ButtonLeftThumb   GamepadButton = C.GLFW_GAMEPAD_BUTTON_LEFT_THUMB
     96 	ButtonRightThumb  GamepadButton = C.GLFW_GAMEPAD_BUTTON_RIGHT_THUMB
     97 	ButtonDpadUp      GamepadButton = C.GLFW_GAMEPAD_BUTTON_DPAD_UP
     98 	ButtonDpadRight   GamepadButton = C.GLFW_GAMEPAD_BUTTON_DPAD_RIGHT
     99 	ButtonDpadDown    GamepadButton = C.GLFW_GAMEPAD_BUTTON_DPAD_DOWN
    100 	ButtonDpadLeft    GamepadButton = C.GLFW_GAMEPAD_BUTTON_DPAD_LEFT
    101 	ButtonLast        GamepadButton = C.GLFW_GAMEPAD_BUTTON_LAST
    102 	ButtonCross       GamepadButton = C.GLFW_GAMEPAD_BUTTON_CROSS
    103 	ButtonCircle      GamepadButton = C.GLFW_GAMEPAD_BUTTON_CIRCLE
    104 	ButtonSquare      GamepadButton = C.GLFW_GAMEPAD_BUTTON_SQUARE
    105 	ButtonTriangle    GamepadButton = C.GLFW_GAMEPAD_BUTTON_TRIANGLE
    106 )
    107 
    108 // GamepadState describes the input state of a gamepad.
    109 type GamepadState struct {
    110 	Buttons [15]Action
    111 	Axes    [6]float32
    112 }
    113 
    114 // Key corresponds to a keyboard key.
    115 type Key int
    116 
    117 // These key codes are inspired by the USB HID Usage Tables v1.12 (p. 53-60),
    118 // but re-arranged to map to 7-bit ASCII for printable keys (function keys are
    119 // put in the 256+ range).
    120 const (
    121 	KeyUnknown      Key = C.GLFW_KEY_UNKNOWN
    122 	KeySpace        Key = C.GLFW_KEY_SPACE
    123 	KeyApostrophe   Key = C.GLFW_KEY_APOSTROPHE
    124 	KeyComma        Key = C.GLFW_KEY_COMMA
    125 	KeyMinus        Key = C.GLFW_KEY_MINUS
    126 	KeyPeriod       Key = C.GLFW_KEY_PERIOD
    127 	KeySlash        Key = C.GLFW_KEY_SLASH
    128 	Key0            Key = C.GLFW_KEY_0
    129 	Key1            Key = C.GLFW_KEY_1
    130 	Key2            Key = C.GLFW_KEY_2
    131 	Key3            Key = C.GLFW_KEY_3
    132 	Key4            Key = C.GLFW_KEY_4
    133 	Key5            Key = C.GLFW_KEY_5
    134 	Key6            Key = C.GLFW_KEY_6
    135 	Key7            Key = C.GLFW_KEY_7
    136 	Key8            Key = C.GLFW_KEY_8
    137 	Key9            Key = C.GLFW_KEY_9
    138 	KeySemicolon    Key = C.GLFW_KEY_SEMICOLON
    139 	KeyEqual        Key = C.GLFW_KEY_EQUAL
    140 	KeyA            Key = C.GLFW_KEY_A
    141 	KeyB            Key = C.GLFW_KEY_B
    142 	KeyC            Key = C.GLFW_KEY_C
    143 	KeyD            Key = C.GLFW_KEY_D
    144 	KeyE            Key = C.GLFW_KEY_E
    145 	KeyF            Key = C.GLFW_KEY_F
    146 	KeyG            Key = C.GLFW_KEY_G
    147 	KeyH            Key = C.GLFW_KEY_H
    148 	KeyI            Key = C.GLFW_KEY_I
    149 	KeyJ            Key = C.GLFW_KEY_J
    150 	KeyK            Key = C.GLFW_KEY_K
    151 	KeyL            Key = C.GLFW_KEY_L
    152 	KeyM            Key = C.GLFW_KEY_M
    153 	KeyN            Key = C.GLFW_KEY_N
    154 	KeyO            Key = C.GLFW_KEY_O
    155 	KeyP            Key = C.GLFW_KEY_P
    156 	KeyQ            Key = C.GLFW_KEY_Q
    157 	KeyR            Key = C.GLFW_KEY_R
    158 	KeyS            Key = C.GLFW_KEY_S
    159 	KeyT            Key = C.GLFW_KEY_T
    160 	KeyU            Key = C.GLFW_KEY_U
    161 	KeyV            Key = C.GLFW_KEY_V
    162 	KeyW            Key = C.GLFW_KEY_W
    163 	KeyX            Key = C.GLFW_KEY_X
    164 	KeyY            Key = C.GLFW_KEY_Y
    165 	KeyZ            Key = C.GLFW_KEY_Z
    166 	KeyLeftBracket  Key = C.GLFW_KEY_LEFT_BRACKET
    167 	KeyBackslash    Key = C.GLFW_KEY_BACKSLASH
    168 	KeyRightBracket Key = C.GLFW_KEY_RIGHT_BRACKET
    169 	KeyGraveAccent  Key = C.GLFW_KEY_GRAVE_ACCENT
    170 	KeyWorld1       Key = C.GLFW_KEY_WORLD_1
    171 	KeyWorld2       Key = C.GLFW_KEY_WORLD_2
    172 	KeyEscape       Key = C.GLFW_KEY_ESCAPE
    173 	KeyEnter        Key = C.GLFW_KEY_ENTER
    174 	KeyTab          Key = C.GLFW_KEY_TAB
    175 	KeyBackspace    Key = C.GLFW_KEY_BACKSPACE
    176 	KeyInsert       Key = C.GLFW_KEY_INSERT
    177 	KeyDelete       Key = C.GLFW_KEY_DELETE
    178 	KeyRight        Key = C.GLFW_KEY_RIGHT
    179 	KeyLeft         Key = C.GLFW_KEY_LEFT
    180 	KeyDown         Key = C.GLFW_KEY_DOWN
    181 	KeyUp           Key = C.GLFW_KEY_UP
    182 	KeyPageUp       Key = C.GLFW_KEY_PAGE_UP
    183 	KeyPageDown     Key = C.GLFW_KEY_PAGE_DOWN
    184 	KeyHome         Key = C.GLFW_KEY_HOME
    185 	KeyEnd          Key = C.GLFW_KEY_END
    186 	KeyCapsLock     Key = C.GLFW_KEY_CAPS_LOCK
    187 	KeyScrollLock   Key = C.GLFW_KEY_SCROLL_LOCK
    188 	KeyNumLock      Key = C.GLFW_KEY_NUM_LOCK
    189 	KeyPrintScreen  Key = C.GLFW_KEY_PRINT_SCREEN
    190 	KeyPause        Key = C.GLFW_KEY_PAUSE
    191 	KeyF1           Key = C.GLFW_KEY_F1
    192 	KeyF2           Key = C.GLFW_KEY_F2
    193 	KeyF3           Key = C.GLFW_KEY_F3
    194 	KeyF4           Key = C.GLFW_KEY_F4
    195 	KeyF5           Key = C.GLFW_KEY_F5
    196 	KeyF6           Key = C.GLFW_KEY_F6
    197 	KeyF7           Key = C.GLFW_KEY_F7
    198 	KeyF8           Key = C.GLFW_KEY_F8
    199 	KeyF9           Key = C.GLFW_KEY_F9
    200 	KeyF10          Key = C.GLFW_KEY_F10
    201 	KeyF11          Key = C.GLFW_KEY_F11
    202 	KeyF12          Key = C.GLFW_KEY_F12
    203 	KeyF13          Key = C.GLFW_KEY_F13
    204 	KeyF14          Key = C.GLFW_KEY_F14
    205 	KeyF15          Key = C.GLFW_KEY_F15
    206 	KeyF16          Key = C.GLFW_KEY_F16
    207 	KeyF17          Key = C.GLFW_KEY_F17
    208 	KeyF18          Key = C.GLFW_KEY_F18
    209 	KeyF19          Key = C.GLFW_KEY_F19
    210 	KeyF20          Key = C.GLFW_KEY_F20
    211 	KeyF21          Key = C.GLFW_KEY_F21
    212 	KeyF22          Key = C.GLFW_KEY_F22
    213 	KeyF23          Key = C.GLFW_KEY_F23
    214 	KeyF24          Key = C.GLFW_KEY_F24
    215 	KeyF25          Key = C.GLFW_KEY_F25
    216 	KeyKP0          Key = C.GLFW_KEY_KP_0
    217 	KeyKP1          Key = C.GLFW_KEY_KP_1
    218 	KeyKP2          Key = C.GLFW_KEY_KP_2
    219 	KeyKP3          Key = C.GLFW_KEY_KP_3
    220 	KeyKP4          Key = C.GLFW_KEY_KP_4
    221 	KeyKP5          Key = C.GLFW_KEY_KP_5
    222 	KeyKP6          Key = C.GLFW_KEY_KP_6
    223 	KeyKP7          Key = C.GLFW_KEY_KP_7
    224 	KeyKP8          Key = C.GLFW_KEY_KP_8
    225 	KeyKP9          Key = C.GLFW_KEY_KP_9
    226 	KeyKPDecimal    Key = C.GLFW_KEY_KP_DECIMAL
    227 	KeyKPDivide     Key = C.GLFW_KEY_KP_DIVIDE
    228 	KeyKPMultiply   Key = C.GLFW_KEY_KP_MULTIPLY
    229 	KeyKPSubtract   Key = C.GLFW_KEY_KP_SUBTRACT
    230 	KeyKPAdd        Key = C.GLFW_KEY_KP_ADD
    231 	KeyKPEnter      Key = C.GLFW_KEY_KP_ENTER
    232 	KeyKPEqual      Key = C.GLFW_KEY_KP_EQUAL
    233 	KeyLeftShift    Key = C.GLFW_KEY_LEFT_SHIFT
    234 	KeyLeftControl  Key = C.GLFW_KEY_LEFT_CONTROL
    235 	KeyLeftAlt      Key = C.GLFW_KEY_LEFT_ALT
    236 	KeyLeftSuper    Key = C.GLFW_KEY_LEFT_SUPER
    237 	KeyRightShift   Key = C.GLFW_KEY_RIGHT_SHIFT
    238 	KeyRightControl Key = C.GLFW_KEY_RIGHT_CONTROL
    239 	KeyRightAlt     Key = C.GLFW_KEY_RIGHT_ALT
    240 	KeyRightSuper   Key = C.GLFW_KEY_RIGHT_SUPER
    241 	KeyMenu         Key = C.GLFW_KEY_MENU
    242 	KeyLast         Key = C.GLFW_KEY_LAST
    243 )
    244 
    245 // ModifierKey corresponds to a modifier key.
    246 type ModifierKey int
    247 
    248 // Modifier keys.
    249 const (
    250 	ModShift    ModifierKey = C.GLFW_MOD_SHIFT
    251 	ModControl  ModifierKey = C.GLFW_MOD_CONTROL
    252 	ModAlt      ModifierKey = C.GLFW_MOD_ALT
    253 	ModSuper    ModifierKey = C.GLFW_MOD_SUPER
    254 	ModCapsLock ModifierKey = C.GLFW_MOD_CAPS_LOCK
    255 	ModNumLock  ModifierKey = C.GLFW_MOD_NUM_LOCK
    256 )
    257 
    258 // MouseButton corresponds to a mouse button.
    259 type MouseButton int
    260 
    261 // Mouse buttons.
    262 const (
    263 	MouseButton1      MouseButton = C.GLFW_MOUSE_BUTTON_1
    264 	MouseButton2      MouseButton = C.GLFW_MOUSE_BUTTON_2
    265 	MouseButton3      MouseButton = C.GLFW_MOUSE_BUTTON_3
    266 	MouseButton4      MouseButton = C.GLFW_MOUSE_BUTTON_4
    267 	MouseButton5      MouseButton = C.GLFW_MOUSE_BUTTON_5
    268 	MouseButton6      MouseButton = C.GLFW_MOUSE_BUTTON_6
    269 	MouseButton7      MouseButton = C.GLFW_MOUSE_BUTTON_7
    270 	MouseButton8      MouseButton = C.GLFW_MOUSE_BUTTON_8
    271 	MouseButtonLast   MouseButton = C.GLFW_MOUSE_BUTTON_LAST
    272 	MouseButtonLeft   MouseButton = C.GLFW_MOUSE_BUTTON_LEFT
    273 	MouseButtonRight  MouseButton = C.GLFW_MOUSE_BUTTON_RIGHT
    274 	MouseButtonMiddle MouseButton = C.GLFW_MOUSE_BUTTON_MIDDLE
    275 )
    276 
    277 // StandardCursor corresponds to a standard cursor icon.
    278 type StandardCursor int
    279 
    280 // Standard cursors
    281 const (
    282 	ArrowCursor     StandardCursor = C.GLFW_ARROW_CURSOR
    283 	IBeamCursor     StandardCursor = C.GLFW_IBEAM_CURSOR
    284 	CrosshairCursor StandardCursor = C.GLFW_CROSSHAIR_CURSOR
    285 	HandCursor      StandardCursor = C.GLFW_HAND_CURSOR
    286 	HResizeCursor   StandardCursor = C.GLFW_HRESIZE_CURSOR
    287 	VResizeCursor   StandardCursor = C.GLFW_VRESIZE_CURSOR
    288 )
    289 
    290 // Action corresponds to a key or button action.
    291 type Action int
    292 
    293 // Action types.
    294 const (
    295 	Release Action = C.GLFW_RELEASE // The key or button was released.
    296 	Press   Action = C.GLFW_PRESS   // The key or button was pressed.
    297 	Repeat  Action = C.GLFW_REPEAT  // The key was held down until it repeated.
    298 )
    299 
    300 // InputMode corresponds to an input mode.
    301 type InputMode int
    302 
    303 // Input modes.
    304 const (
    305 	CursorMode             InputMode = C.GLFW_CURSOR               // See Cursor mode values
    306 	StickyKeysMode         InputMode = C.GLFW_STICKY_KEYS          // Value can be either 1 or 0
    307 	StickyMouseButtonsMode InputMode = C.GLFW_STICKY_MOUSE_BUTTONS // Value can be either 1 or 0
    308 	LockKeyMods            InputMode = C.GLFW_LOCK_KEY_MODS        // Value can be either 1 or 0
    309 	RawMouseMotion         InputMode = C.GLFW_RAW_MOUSE_MOTION     // Value can be either 1 or 0
    310 )
    311 
    312 // Cursor mode values.
    313 const (
    314 	CursorNormal   int = C.GLFW_CURSOR_NORMAL
    315 	CursorHidden   int = C.GLFW_CURSOR_HIDDEN
    316 	CursorDisabled int = C.GLFW_CURSOR_DISABLED
    317 )
    318 
    319 // Cursor represents a cursor.
    320 type Cursor struct {
    321 	data *C.GLFWcursor
    322 }
    323 
    324 var fJoystickHolder func(joy Joystick, event PeripheralEvent)
    325 
    326 //export goJoystickCB
    327 func goJoystickCB(joy, event C.int) {
    328 	fJoystickHolder(Joystick(joy), PeripheralEvent(event))
    329 }
    330 
    331 //export goMouseButtonCB
    332 func goMouseButtonCB(window unsafe.Pointer, button, action, mods C.int) {
    333 	w := windows.get((*C.GLFWwindow)(window))
    334 	w.fMouseButtonHolder(w, MouseButton(button), Action(action), ModifierKey(mods))
    335 }
    336 
    337 //export goCursorPosCB
    338 func goCursorPosCB(window unsafe.Pointer, xpos, ypos C.double) {
    339 	w := windows.get((*C.GLFWwindow)(window))
    340 	w.fCursorPosHolder(w, float64(xpos), float64(ypos))
    341 }
    342 
    343 //export goCursorEnterCB
    344 func goCursorEnterCB(window unsafe.Pointer, entered C.int) {
    345 	w := windows.get((*C.GLFWwindow)(window))
    346 	hasEntered := glfwbool(entered)
    347 	w.fCursorEnterHolder(w, hasEntered)
    348 }
    349 
    350 //export goScrollCB
    351 func goScrollCB(window unsafe.Pointer, xoff, yoff C.double) {
    352 	w := windows.get((*C.GLFWwindow)(window))
    353 	w.fScrollHolder(w, float64(xoff), float64(yoff))
    354 }
    355 
    356 //export goKeyCB
    357 func goKeyCB(window unsafe.Pointer, key, scancode, action, mods C.int) {
    358 	w := windows.get((*C.GLFWwindow)(window))
    359 	w.fKeyHolder(w, Key(key), int(scancode), Action(action), ModifierKey(mods))
    360 }
    361 
    362 //export goCharCB
    363 func goCharCB(window unsafe.Pointer, character C.uint) {
    364 	w := windows.get((*C.GLFWwindow)(window))
    365 	w.fCharHolder(w, rune(character))
    366 }
    367 
    368 //export goCharModsCB
    369 func goCharModsCB(window unsafe.Pointer, character C.uint, mods C.int) {
    370 	w := windows.get((*C.GLFWwindow)(window))
    371 	w.fCharModsHolder(w, rune(character), ModifierKey(mods))
    372 }
    373 
    374 //export goDropCB
    375 func goDropCB(window unsafe.Pointer, count C.int, names **C.char) { // TODO: The types of name can be `**C.char` or `unsafe.Pointer`, use whichever is better.
    376 	w := windows.get((*C.GLFWwindow)(window))
    377 	namesSlice := make([]string, int(count)) // TODO: Make this better. This part is unfinished, hacky, probably not correct, and not idiomatic.
    378 	for i := 0; i < int(count); i++ {        // TODO: Make this better. It should be cleaned up and vetted.
    379 		var x *C.char                                                                                 // TODO: Make this better.
    380 		p := (**C.char)(unsafe.Pointer(uintptr(unsafe.Pointer(names)) + uintptr(i)*unsafe.Sizeof(x))) // TODO: Make this better.
    381 		namesSlice[i] = C.GoString(*p)                                                                // TODO: Make this better.
    382 	}
    383 	w.fDropHolder(w, namesSlice)
    384 }
    385 
    386 // GetInputMode returns the value of an input option of the window.
    387 func (w *Window) GetInputMode(mode InputMode) int {
    388 	ret := int(C.glfwGetInputMode(w.data, C.int(mode)))
    389 	panicError()
    390 	return ret
    391 }
    392 
    393 // SetInputMode sets an input option for the window.
    394 func (w *Window) SetInputMode(mode InputMode, value int) {
    395 	C.glfwSetInputMode(w.data, C.int(mode), C.int(value))
    396 	panicError()
    397 }
    398 
    399 // RawMouseMotionSupported returns whether raw mouse motion is supported on the
    400 // current system. This status does not change after GLFW has been initialized
    401 // so you only need to check this once. If you attempt to enable raw motion on
    402 // a system that does not support it, PlatformError will be emitted.
    403 //
    404 // Raw mouse motion is closer to the actual motion of the mouse across a
    405 // surface. It is not affected by the scaling and acceleration applied to the
    406 // motion of the desktop cursor. That processing is suitable for a cursor while
    407 // raw motion is better for controlling for example a 3D camera. Because of
    408 // this, raw mouse motion is only provided when the cursor is disabled.
    409 //
    410 // This function must only be called from the main thread.
    411 func RawMouseMotionSupported() bool {
    412 	return int(C.glfwRawMouseMotionSupported()) == int(True)
    413 }
    414 
    415 // GetKeyScancode function returns the platform-specific scancode of the
    416 // specified key.
    417 //
    418 // If the key is KeyUnknown or does not exist on the keyboard this method will
    419 // return -1.
    420 func GetKeyScancode(key Key) int {
    421 	return int(C.glfwGetKeyScancode(C.int(key)))
    422 }
    423 
    424 // GetKey returns the last reported state of a keyboard key. The returned state
    425 // is one of Press or Release. The higher-level state Repeat is only reported to
    426 // the key callback.
    427 //
    428 // If the StickyKeys input mode is enabled, this function returns Press the first
    429 // time you call this function after a key has been pressed, even if the key has
    430 // already been released.
    431 //
    432 // The key functions deal with physical keys, with key tokens named after their
    433 // use on the standard US keyboard layout. If you want to input text, use the
    434 // Unicode character callback instead.
    435 func (w *Window) GetKey(key Key) Action {
    436 	ret := Action(C.glfwGetKey(w.data, C.int(key)))
    437 	panicError()
    438 	return ret
    439 }
    440 
    441 // GetKeyName returns the localized name of the specified printable key.
    442 //
    443 // If the key is glfw.KeyUnknown, the scancode is used, otherwise the scancode is ignored.
    444 func GetKeyName(key Key, scancode int) string {
    445 	ret := C.glfwGetKeyName(C.int(key), C.int(scancode))
    446 	panicError()
    447 	return C.GoString(ret)
    448 }
    449 
    450 // GetMouseButton returns the last state reported for the specified mouse button.
    451 //
    452 // If the StickyMouseButtons input mode is enabled, this function returns Press
    453 // the first time you call this function after a mouse button has been pressed,
    454 // even if the mouse button has already been released.
    455 func (w *Window) GetMouseButton(button MouseButton) Action {
    456 	ret := Action(C.glfwGetMouseButton(w.data, C.int(button)))
    457 	panicError()
    458 	return ret
    459 }
    460 
    461 // GetCursorPos returns the last reported position of the cursor.
    462 //
    463 // If the cursor is disabled (with CursorDisabled) then the cursor position is
    464 // unbounded and limited only by the minimum and maximum values of a double.
    465 //
    466 // The coordinate can be converted to their integer equivalents with the floor
    467 // function. Casting directly to an integer type works for positive coordinates,
    468 // but fails for negative ones.
    469 func (w *Window) GetCursorPos() (x, y float64) {
    470 	var xpos, ypos C.double
    471 	C.glfwGetCursorPos(w.data, &xpos, &ypos)
    472 	panicError()
    473 	return float64(xpos), float64(ypos)
    474 }
    475 
    476 // SetCursorPos sets the position of the cursor. The specified window must
    477 // be focused. If the window does not have focus when this function is called,
    478 // it fails silently.
    479 //
    480 // If the cursor is disabled (with CursorDisabled) then the cursor position is
    481 // unbounded and limited only by the minimum and maximum values of a double.
    482 func (w *Window) SetCursorPos(xpos, ypos float64) {
    483 	C.glfwSetCursorPos(w.data, C.double(xpos), C.double(ypos))
    484 	panicError()
    485 }
    486 
    487 // CreateCursor creates a new custom cursor image that can be set for a window with SetCursor.
    488 // The cursor can be destroyed with Destroy. Any remaining cursors are destroyed by Terminate.
    489 //
    490 // The image is ideally provided in the form of *image.NRGBA.
    491 // The pixels are 32-bit, little-endian, non-premultiplied RGBA, i.e. eight
    492 // bits per channel with the red channel first. They are arranged canonically
    493 // as packed sequential rows, starting from the top-left corner. If the image
    494 // type is not *image.NRGBA, it will be converted to it.
    495 //
    496 // The cursor hotspot is specified in pixels, relative to the upper-left corner of the cursor image.
    497 // Like all other coordinate systems in GLFW, the X-axis points to the right and the Y-axis points down.
    498 func CreateCursor(img image.Image, xhot, yhot int) *Cursor {
    499 	var imgC C.GLFWimage
    500 	var pixels []uint8
    501 	b := img.Bounds()
    502 
    503 	switch img := img.(type) {
    504 	case *image.NRGBA:
    505 		pixels = img.Pix
    506 	default:
    507 		m := image.NewNRGBA(image.Rect(0, 0, b.Dx(), b.Dy()))
    508 		draw.Draw(m, m.Bounds(), img, b.Min, draw.Src)
    509 		pixels = m.Pix
    510 	}
    511 
    512 	pix, free := bytes(pixels)
    513 
    514 	imgC.width = C.int(b.Dx())
    515 	imgC.height = C.int(b.Dy())
    516 	imgC.pixels = (*C.uchar)(pix)
    517 
    518 	c := C.glfwCreateCursor(&imgC, C.int(xhot), C.int(yhot))
    519 
    520 	free()
    521 	panicError()
    522 
    523 	return &Cursor{c}
    524 }
    525 
    526 // CreateStandardCursor returns a cursor with a standard shape,
    527 // that can be set for a window with SetCursor.
    528 func CreateStandardCursor(shape StandardCursor) *Cursor {
    529 	c := C.glfwCreateStandardCursor(C.int(shape))
    530 	panicError()
    531 	return &Cursor{c}
    532 }
    533 
    534 // Destroy destroys a cursor previously created with CreateCursor.
    535 // Any remaining cursors will be destroyed by Terminate.
    536 func (c *Cursor) Destroy() {
    537 	C.glfwDestroyCursor(c.data)
    538 	panicError()
    539 }
    540 
    541 // SetCursor sets the cursor image to be used when the cursor is over the client area
    542 // of the specified window. The set cursor will only be visible when the cursor mode of the
    543 // window is CursorNormal.
    544 //
    545 // On some platforms, the set cursor may not be visible unless the window also has input focus.
    546 func (w *Window) SetCursor(c *Cursor) {
    547 	if c == nil {
    548 		C.glfwSetCursor(w.data, nil)
    549 	} else {
    550 		C.glfwSetCursor(w.data, c.data)
    551 	}
    552 	panicError()
    553 }
    554 
    555 // JoystickCallback is the joystick configuration callback.
    556 type JoystickCallback func(joy Joystick, event PeripheralEvent)
    557 
    558 // SetJoystickCallback sets the joystick configuration callback, or removes the
    559 // currently set callback. This is called when a joystick is connected to or
    560 // disconnected from the system.
    561 func SetJoystickCallback(cbfun JoystickCallback) (previous JoystickCallback) {
    562 	previous = fJoystickHolder
    563 	fJoystickHolder = cbfun
    564 	if cbfun == nil {
    565 		C.glfwSetJoystickCallback(nil)
    566 	} else {
    567 		C.glfwSetJoystickCallbackCB()
    568 	}
    569 	panicError()
    570 	return previous
    571 }
    572 
    573 // KeyCallback is the key callback.
    574 type KeyCallback func(w *Window, key Key, scancode int, action Action, mods ModifierKey)
    575 
    576 // SetKeyCallback sets the key callback which is called when a key is pressed,
    577 // repeated or released.
    578 //
    579 // The key functions deal with physical keys, with layout independent key tokens
    580 // named after their values in the standard US keyboard layout. If you want to
    581 // input text, use the SetCharCallback instead.
    582 //
    583 // When a window loses focus, it will generate synthetic key release events for
    584 // all pressed keys. You can tell these events from user-generated events by the
    585 // fact that the synthetic ones are generated after the window has lost focus,
    586 // i.e. Focused will be false and the focus callback will have already been
    587 // called.
    588 func (w *Window) SetKeyCallback(cbfun KeyCallback) (previous KeyCallback) {
    589 	previous = w.fKeyHolder
    590 	w.fKeyHolder = cbfun
    591 	if cbfun == nil {
    592 		C.glfwSetKeyCallback(w.data, nil)
    593 	} else {
    594 		C.glfwSetKeyCallbackCB(w.data)
    595 	}
    596 	panicError()
    597 	return previous
    598 }
    599 
    600 // CharCallback is the character callback.
    601 type CharCallback func(w *Window, char rune)
    602 
    603 // SetCharCallback sets the character callback which is called when a
    604 // Unicode character is input.
    605 //
    606 // The character callback is intended for Unicode text input. As it deals with
    607 // characters, it is keyboard layout dependent, whereas the
    608 // key callback is not. Characters do not map 1:1
    609 // to physical keys, as a key may produce zero, one or more characters. If you
    610 // want to know whether a specific physical key was pressed or released, see
    611 // the key callback instead.
    612 //
    613 // The character callback behaves as system text input normally does and will
    614 // not be called if modifier keys are held down that would prevent normal text
    615 // input on that platform, for example a Super (Command) key on OS X or Alt key
    616 // on Windows. There is a character with modifiers callback that receives these events.
    617 func (w *Window) SetCharCallback(cbfun CharCallback) (previous CharCallback) {
    618 	previous = w.fCharHolder
    619 	w.fCharHolder = cbfun
    620 	if cbfun == nil {
    621 		C.glfwSetCharCallback(w.data, nil)
    622 	} else {
    623 		C.glfwSetCharCallbackCB(w.data)
    624 	}
    625 	panicError()
    626 	return previous
    627 }
    628 
    629 // CharModsCallback is the character with modifiers callback.
    630 type CharModsCallback func(w *Window, char rune, mods ModifierKey)
    631 
    632 // SetCharModsCallback sets the character with modifiers callback which is called when a
    633 // Unicode character is input regardless of what modifier keys are used.
    634 //
    635 // Deprecated: Scheduled for removal in version 4.0.
    636 //
    637 // The character with modifiers callback is intended for implementing custom
    638 // Unicode character input. For regular Unicode text input, see the
    639 // character callback. Like the character callback, the character with modifiers callback
    640 // deals with characters and is keyboard layout dependent. Characters do not
    641 // map 1:1 to physical keys, as a key may produce zero, one or more characters.
    642 // If you want to know whether a specific physical key was pressed or released,
    643 // see the key callback instead.
    644 func (w *Window) SetCharModsCallback(cbfun CharModsCallback) (previous CharModsCallback) {
    645 	previous = w.fCharModsHolder
    646 	w.fCharModsHolder = cbfun
    647 	if cbfun == nil {
    648 		C.glfwSetCharModsCallback(w.data, nil)
    649 	} else {
    650 		C.glfwSetCharModsCallbackCB(w.data)
    651 	}
    652 	panicError()
    653 	return previous
    654 }
    655 
    656 // MouseButtonCallback is the mouse button callback.
    657 type MouseButtonCallback func(w *Window, button MouseButton, action Action, mods ModifierKey)
    658 
    659 // SetMouseButtonCallback sets the mouse button callback which is called when a
    660 // mouse button is pressed or released.
    661 //
    662 // When a window loses focus, it will generate synthetic mouse button release
    663 // events for all pressed mouse buttons. You can tell these events from
    664 // user-generated events by the fact that the synthetic ones are generated after
    665 // the window has lost focus, i.e. Focused will be false and the focus
    666 // callback will have already been called.
    667 func (w *Window) SetMouseButtonCallback(cbfun MouseButtonCallback) (previous MouseButtonCallback) {
    668 	previous = w.fMouseButtonHolder
    669 	w.fMouseButtonHolder = cbfun
    670 	if cbfun == nil {
    671 		C.glfwSetMouseButtonCallback(w.data, nil)
    672 	} else {
    673 		C.glfwSetMouseButtonCallbackCB(w.data)
    674 	}
    675 	panicError()
    676 	return previous
    677 }
    678 
    679 // CursorPosCallback the cursor position callback.
    680 type CursorPosCallback func(w *Window, xpos float64, ypos float64)
    681 
    682 // SetCursorPosCallback sets the cursor position callback which is called
    683 // when the cursor is moved. The callback is provided with the position relative
    684 // to the upper-left corner of the client area of the window.
    685 func (w *Window) SetCursorPosCallback(cbfun CursorPosCallback) (previous CursorPosCallback) {
    686 	previous = w.fCursorPosHolder
    687 	w.fCursorPosHolder = cbfun
    688 	if cbfun == nil {
    689 		C.glfwSetCursorPosCallback(w.data, nil)
    690 	} else {
    691 		C.glfwSetCursorPosCallbackCB(w.data)
    692 	}
    693 	panicError()
    694 	return previous
    695 }
    696 
    697 // CursorEnterCallback is the cursor boundary crossing callback.
    698 type CursorEnterCallback func(w *Window, entered bool)
    699 
    700 // SetCursorEnterCallback the cursor boundary crossing callback which is called
    701 // when the cursor enters or leaves the client area of the window.
    702 func (w *Window) SetCursorEnterCallback(cbfun CursorEnterCallback) (previous CursorEnterCallback) {
    703 	previous = w.fCursorEnterHolder
    704 	w.fCursorEnterHolder = cbfun
    705 	if cbfun == nil {
    706 		C.glfwSetCursorEnterCallback(w.data, nil)
    707 	} else {
    708 		C.glfwSetCursorEnterCallbackCB(w.data)
    709 	}
    710 	panicError()
    711 	return previous
    712 }
    713 
    714 // ScrollCallback is the scroll callback.
    715 type ScrollCallback func(w *Window, xoff float64, yoff float64)
    716 
    717 // SetScrollCallback sets the scroll callback which is called when a scrolling
    718 // device is used, such as a mouse wheel or scrolling area of a touchpad.
    719 func (w *Window) SetScrollCallback(cbfun ScrollCallback) (previous ScrollCallback) {
    720 	previous = w.fScrollHolder
    721 	w.fScrollHolder = cbfun
    722 	if cbfun == nil {
    723 		C.glfwSetScrollCallback(w.data, nil)
    724 	} else {
    725 		C.glfwSetScrollCallbackCB(w.data)
    726 	}
    727 	panicError()
    728 	return previous
    729 }
    730 
    731 // DropCallback is the drop callback.
    732 type DropCallback func(w *Window, names []string)
    733 
    734 // SetDropCallback sets the drop callback which is called when an object
    735 // is dropped over the window.
    736 func (w *Window) SetDropCallback(cbfun DropCallback) (previous DropCallback) {
    737 	previous = w.fDropHolder
    738 	w.fDropHolder = cbfun
    739 	if cbfun == nil {
    740 		C.glfwSetDropCallback(w.data, nil)
    741 	} else {
    742 		C.glfwSetDropCallbackCB(w.data)
    743 	}
    744 	panicError()
    745 	return previous
    746 }
    747 
    748 // Present returns whether the specified joystick is present.
    749 //
    750 // There is no need to call this function before other methods of Joystick type
    751 // as they all check for presence before performing any other work.
    752 //
    753 // This function must only be called from the main thread.
    754 func (joy Joystick) Present() bool {
    755 	return glfwbool(C.glfwJoystickPresent(C.int(joy)))
    756 }
    757 
    758 // GetAxes returns the values of all axes of the specified joystick. Each
    759 // element in the array is a value between -1.0 and 1.0.
    760 //
    761 // If the specified joystick is not present this function will return nil but
    762 // will not generate an error. This can be used instead of first calling
    763 // Present.
    764 //
    765 // This function must only be called from the main thread.
    766 func (joy Joystick) GetAxes() []float32 {
    767 	var length int
    768 
    769 	axis := C.glfwGetJoystickAxes(C.int(joy), (*C.int)(unsafe.Pointer(&length)))
    770 	if axis == nil {
    771 		return nil
    772 	}
    773 
    774 	a := make([]float32, length)
    775 	for i := 0; i < length; i++ {
    776 		a[i] = float32(C.GetAxisAtIndex(axis, C.int(i)))
    777 	}
    778 	return a
    779 }
    780 
    781 // GetButtons returns the state of all buttons of the specified joystick. Each
    782 // element in the array is either Press or Release.
    783 //
    784 // For backward compatibility with earlier versions that did not have GetHats,
    785 // the button array also includes all hats, each represented as four buttons.
    786 // The hats are in the same order as returned by GetHats and are in the order
    787 // up, right, down and left. To disable these extra buttons, set the
    788 // JoystickHatButtons init hint before initialization.
    789 //
    790 // If the specified joystick is not present this function will return nil but
    791 // will not generate an error. This can be used instead of first calling
    792 // Present.
    793 //
    794 // This function must only be called from the main thread.
    795 func (joy Joystick) GetButtons() []Action {
    796 	var length int
    797 
    798 	buttons := C.glfwGetJoystickButtons(
    799 		C.int(joy),
    800 		(*C.int)(unsafe.Pointer(&length)),
    801 	)
    802 	if buttons == nil {
    803 		return nil
    804 	}
    805 
    806 	b := make([]Action, length)
    807 	for i := 0; i < length; i++ {
    808 		b[i] = Action(C.GetButtonsAtIndex(buttons, C.int(i)))
    809 	}
    810 	return b
    811 }
    812 
    813 // GetHats returns the state of all hats of the specified joystick.
    814 //
    815 // If the specified joystick is not present this function will return nil but
    816 // will not generate an error. This can be used instead of first calling
    817 // Present.
    818 //
    819 // This function must only be called from the main thread.
    820 func (joy Joystick) GetHats() []JoystickHatState {
    821 	var length int
    822 
    823 	hats := C.glfwGetJoystickHats(C.int(joy), (*C.int)(unsafe.Pointer(&length)))
    824 	if hats == nil {
    825 		return nil
    826 	}
    827 
    828 	b := make([]JoystickHatState, length)
    829 	for i := 0; i < length; i++ {
    830 		b[i] = JoystickHatState(C.GetButtonsAtIndex(hats, C.int(i)))
    831 	}
    832 	return b
    833 }
    834 
    835 // GetName returns the name, encoded as UTF-8, of the specified joystick.
    836 //
    837 // If the specified joystick is not present this function will return nil but
    838 // will not generate an error. This can be used instead of first calling
    839 // Present.
    840 //
    841 // This function must only be called from the main thread.
    842 func (joy Joystick) GetName() string {
    843 	jn := C.glfwGetJoystickName(C.int(joy))
    844 	return C.GoString(jn)
    845 }
    846 
    847 // GetGUID returns the SDL compatible GUID, as a UTF-8 encoded
    848 // hexadecimal string, of the specified joystick.
    849 //
    850 // The GUID is what connects a joystick to a gamepad mapping. A connected
    851 // joystick will always have a GUID even if there is no gamepad mapping
    852 // assigned to it.
    853 //
    854 // If the specified joystick is not present this function will return empty
    855 // string but will not generate an error. This can be used instead of first
    856 // calling JoystickPresent.
    857 //
    858 // The GUID uses the format introduced in SDL 2.0.5. This GUID tries to uniquely
    859 // identify the make and model of a joystick but does not identify a specific
    860 // unit, e.g. all wired Xbox 360 controllers will have the same GUID on that
    861 // platform. The GUID for a unit may vary between platforms depending on what
    862 // hardware information the platform specific APIs provide.
    863 //
    864 // This function must only be called from the main thread.
    865 func (joy Joystick) GetGUID() string {
    866 	guid := C.glfwGetJoystickGUID(C.int(joy))
    867 	return C.GoString(guid)
    868 }
    869 
    870 // SetUserPointer sets the user-defined pointer of the joystick. The current value
    871 // is retained until the joystick is disconnected. The initial value is nil.
    872 //
    873 // This function may be called from the joystick callback, even for a joystick
    874 // that is being disconnected.
    875 //
    876 // This function may be called from any thread. Access is not synchronized.
    877 func (joy Joystick) SetUserPointer(pointer unsafe.Pointer) {
    878 	C.glfwSetJoystickUserPointer(C.int(joy), pointer)
    879 }
    880 
    881 // GetUserPointer returns the current value of the user-defined pointer of the
    882 // joystick. The initial value is nil.
    883 //
    884 // This function may be called from the joystick callback, even for a joystick
    885 // that is being disconnected.
    886 //
    887 // This function may be called from any thread. Access is not synchronized.
    888 func (joy Joystick) GetUserPointer() unsafe.Pointer {
    889 	return C.glfwGetJoystickUserPointer(C.int(joy))
    890 }
    891 
    892 // IsGamepad returns whether the specified joystick is both present and
    893 // has a gamepad mapping.
    894 //
    895 // If the specified joystick is present but does not have a gamepad mapping this
    896 // function will return false but will not generate an error. Call Present to
    897 // check if a joystick is present regardless of whether it has a mapping.
    898 //
    899 // This function must only be called from the main thread.
    900 func (joy Joystick) IsGamepad() bool {
    901 	return glfwbool(C.glfwJoystickIsGamepad(C.int(joy)))
    902 }
    903 
    904 // UpdateGamepadMappings parses the specified ASCII encoded string and updates
    905 // the internal list with any gamepad mappings it finds. This string may contain
    906 // either a single gamepad mapping or many mappings separated by newlines. The
    907 // parser supports the full format of the gamecontrollerdb.txt source file
    908 // including empty lines and comments.
    909 //
    910 // See Gamepad mappings for a description of the format.
    911 //
    912 // If there is already a gamepad mapping for a given GUID in the internal list,
    913 // it will be replaced by the one passed to this function. If the library is
    914 // terminated and re-initialized the internal list will revert to the built-in
    915 // default.
    916 //
    917 // This function must only be called from the main thread.
    918 func UpdateGamepadMappings(mapping string) bool {
    919 	m := C.CString(mapping)
    920 	defer C.free(unsafe.Pointer(m))
    921 	return glfwbool(C.glfwUpdateGamepadMappings(m))
    922 }
    923 
    924 // GetGamepadName returns the human-readable name of the gamepad from the
    925 // gamepad mapping assigned to the specified joystick.
    926 //
    927 // If the specified joystick is not present or does not have a gamepad mapping
    928 // this function will return empty string but will not generate an error. Call
    929 // Present to check whether it is present regardless of whether it has a
    930 // mapping.
    931 //
    932 // This function must only be called from the main thread.
    933 func (joy Joystick) GetGamepadName() string {
    934 	gn := C.glfwGetGamepadName(C.int(joy))
    935 	return C.GoString(gn)
    936 }
    937 
    938 // GetGamepadState retrives the state of the specified joystick remapped to an
    939 // Xbox-like gamepad.
    940 //
    941 // If the specified joystick is not present or does not have a gamepad mapping
    942 // this function will return nil but will not generate an error. Call
    943 // Present to check whether it is present regardless of whether it has a
    944 // mapping.
    945 //
    946 // The Guide button may not be available for input as it is often hooked by the
    947 // system or the Steam client.
    948 //
    949 // Not all devices have all the buttons or axes provided by GamepadState.
    950 // Unavailable buttons and axes will always report Release and 0.0 respectively.
    951 //
    952 // This function must only be called from the main thread.
    953 func (joy Joystick) GetGamepadState() *GamepadState {
    954 	var (
    955 		gs  GamepadState
    956 		cgs C.GLFWgamepadstate
    957 	)
    958 
    959 	ret := C.glfwGetGamepadState(C.int(joy), &cgs)
    960 	if ret == C.GLFW_FALSE {
    961 		return nil
    962 	}
    963 
    964 	for i := 0; i < 15; i++ {
    965 		gs.Buttons[i] = Action(C.GetGamepadButtonAtIndex(&cgs, C.int(i)))
    966 	}
    967 
    968 	for i := 0; i < 6; i++ {
    969 		gs.Axes[i] = float32(C.GetGamepadAxisAtIndex(&cgs, C.int(i)))
    970 	}
    971 
    972 	return &gs
    973 }