func WaitEventsTimeout(timeout float64) {
	C.glfwWaitEventsTimeout(C.double(timeout))
	panicError()
}
WaitEventsTimeout puts the calling thread to sleep until at least one event is available in the
event queue, or until the specified timeout is reached. If one or more events are available,
it behaves exactly like PollEvents, i.e. the events in the queue are processed and the function
then returns immediately. Processing events will cause the window and input callbacks associated
with those events to be called.

The timeout value must be a positive finite number.

Since not all events are associated with callbacks, this function may return without a callback
having been called even if you are monitoring all callbacks.

On some platforms, a window move, resize or menu operation will cause event processing to block.
This is due to how event processing is designed on those platforms. You can use the window
refresh callback to redraw the contents of your window when necessary during such operations.

On some platforms, certain callbacks may be called outside of a call to one of the event
processing functions.

If no windows exist, this function returns immediately. For synchronization of threads in
applications that do not create windows, use native Go primitives.

Event processing is not required for joystick input to work.
package glfw
import "C"
import (
	"image"
	"image/draw"
	"sync"
	"unsafe"
)
type windowList struct {
	l sync.Mutex
	m map[*C.GLFWwindow]*Window
}
var windows = windowList{m: map[*C.GLFWwindow]*Window{}}
func (w *windowList) put(wnd *Window) {
	w.l.Lock()
	defer w.l.Unlock()
	w.m[wnd.data] = wnd
}
func (w *windowList) remove(wnd *C.GLFWwindow) {
	w.l.Lock()
	defer w.l.Unlock()
	delete(w.m, wnd)
}
func (w *windowList) get(wnd *C.GLFWwindow) *Window {
	w.l.Lock()
	defer w.l.Unlock()
	return w.m[wnd]
}
type Hint int
const (
	Focused     Hint = C.GLFW_FOCUSED       
	Iconified   Hint = C.GLFW_ICONIFIED     
	Maximized   Hint = C.GLFW_MAXIMIZED     
	Visible     Hint = C.GLFW_VISIBLE       
	Resizable   Hint = C.GLFW_RESIZABLE     
	Decorated   Hint = C.GLFW_DECORATED     
	Floating    Hint = C.GLFW_FLOATING      
	AutoIconify Hint = C.GLFW_AUTO_ICONIFY  
)
const (
	ClientAPI               Hint = C.GLFW_CLIENT_API                
	ContextVersionMajor     Hint = C.GLFW_CONTEXT_VERSION_MAJOR     
	ContextVersionMinor     Hint = C.GLFW_CONTEXT_VERSION_MINOR     
	ContextRobustness       Hint = C.GLFW_CONTEXT_ROBUSTNESS        
	ContextReleaseBehavior  Hint = C.GLFW_CONTEXT_RELEASE_BEHAVIOR  
	OpenGLForwardCompatible Hint = C.GLFW_OPENGL_FORWARD_COMPAT     
	OpenGLDebugContext      Hint = C.GLFW_OPENGL_DEBUG_CONTEXT      
	OpenGLProfile           Hint = C.GLFW_OPENGL_PROFILE            
	ContextCreationAPI      Hint = C.GLFW_CONTEXT_CREATION_API      
)
const (
	ContextRevision Hint = C.GLFW_CONTEXT_REVISION
	RedBits         Hint = C.GLFW_RED_BITS          
	GreenBits       Hint = C.GLFW_GREEN_BITS        
	BlueBits        Hint = C.GLFW_BLUE_BITS         
	AlphaBits       Hint = C.GLFW_ALPHA_BITS        
	DepthBits       Hint = C.GLFW_DEPTH_BITS        
	StencilBits     Hint = C.GLFW_STENCIL_BITS      
	AccumRedBits    Hint = C.GLFW_ACCUM_RED_BITS    
	AccumGreenBits  Hint = C.GLFW_ACCUM_GREEN_BITS  
	AccumBlueBits   Hint = C.GLFW_ACCUM_BLUE_BITS   
	AccumAlphaBits  Hint = C.GLFW_ACCUM_ALPHA_BITS  
	AuxBuffers      Hint = C.GLFW_AUX_BUFFERS       
	Stereo          Hint = C.GLFW_STEREO            
	Samples         Hint = C.GLFW_SAMPLES           
	SRGBCapable     Hint = C.GLFW_SRGB_CAPABLE      
	RefreshRate     Hint = C.GLFW_REFRESH_RATE      
	DoubleBuffer    Hint = C.GLFW_DOUBLEBUFFER      
)
const (
	OpenGLAPI   int = C.GLFW_OPENGL_API
	OpenGLESAPI int = C.GLFW_OPENGL_ES_API
	NoAPI       int = C.GLFW_NO_API
)
const (
	NativeContextAPI int = C.GLFW_NATIVE_CONTEXT_API
	EGLContextAPI    int = C.GLFW_EGL_CONTEXT_API
)
const (
	NoRobustness        int = C.GLFW_NO_ROBUSTNESS
	NoResetNotification int = C.GLFW_NO_RESET_NOTIFICATION
	LoseContextOnReset  int = C.GLFW_LOSE_CONTEXT_ON_RESET
)
const (
	AnyReleaseBehavior   int = C.GLFW_ANY_RELEASE_BEHAVIOR
	ReleaseBehaviorFlush int = C.GLFW_RELEASE_BEHAVIOR_FLUSH
	ReleaseBehaviorNone  int = C.GLFW_RELEASE_BEHAVIOR_NONE
)
const (
	OpenGLAnyProfile    int = C.GLFW_OPENGL_ANY_PROFILE
	OpenGLCoreProfile   int = C.GLFW_OPENGL_CORE_PROFILE
	OpenGLCompatProfile int = C.GLFW_OPENGL_COMPAT_PROFILE
)
const (
	True     int = C.GL_TRUE
	False    int = C.GL_FALSE
	DontCare int = C.GLFW_DONT_CARE
)
type Window struct {
	data *C.GLFWwindow
	fPosHolder             func(w *Window, xpos int, ypos int)
	fSizeHolder            func(w *Window, width int, height int)
	fFramebufferSizeHolder func(w *Window, width int, height int)
	fCloseHolder           func(w *Window)
	fRefreshHolder         func(w *Window)
	fFocusHolder           func(w *Window, focused bool)
	fIconifyHolder         func(w *Window, iconified bool)
	fMouseButtonHolder func(w *Window, button MouseButton, action Action, mod ModifierKey)
	fCursorPosHolder   func(w *Window, xpos float64, ypos float64)
	fCursorEnterHolder func(w *Window, entered bool)
	fScrollHolder      func(w *Window, xoff float64, yoff float64)
	fKeyHolder         func(w *Window, key Key, scancode int, action Action, mods ModifierKey)
	fCharHolder        func(w *Window, char rune)
	fCharModsHolder    func(w *Window, char rune, mods ModifierKey)
	fDropHolder        func(w *Window, names []string)
}
func (w *Window) GLFWWindow() uintptr {
	return uintptr(unsafe.Pointer(w.data))
}
func goWindowPosCB(window unsafe.Pointer, xpos, ypos C.int) {
	w := windows.get((*C.GLFWwindow)(window))
	w.fPosHolder(w, int(xpos), int(ypos))
}
func goWindowSizeCB(window unsafe.Pointer, width, height C.int) {
	w := windows.get((*C.GLFWwindow)(window))
	w.fSizeHolder(w, int(width), int(height))
}
func goFramebufferSizeCB(window unsafe.Pointer, width, height C.int) {
	w := windows.get((*C.GLFWwindow)(window))
	w.fFramebufferSizeHolder(w, int(width), int(height))
}
func goWindowCloseCB(window unsafe.Pointer) {
	w := windows.get((*C.GLFWwindow)(window))
	w.fCloseHolder(w)
}
func goWindowRefreshCB(window unsafe.Pointer) {
	w := windows.get((*C.GLFWwindow)(window))
	w.fRefreshHolder(w)
}
func goWindowFocusCB(window unsafe.Pointer, focused C.int) {
	w := windows.get((*C.GLFWwindow)(window))
	isFocused := glfwbool(focused)
	w.fFocusHolder(w, isFocused)
}
func goWindowIconifyCB(window unsafe.Pointer, iconified C.int) {
	isIconified := glfwbool(iconified)
	w := windows.get((*C.GLFWwindow)(window))
	w.fIconifyHolder(w, isIconified)
}
func DefaultWindowHints() {
	C.glfwDefaultWindowHints()
	panicError()
}
func WindowHint(target Hint, hint int) {
	C.glfwWindowHint(C.int(target), C.int(hint))
	panicError()
}
func CreateWindow(width, height int, title string, monitor *Monitor, share *Window) (*Window, error) {
	var (
		m *C.GLFWmonitor
		s *C.GLFWwindow
	)
	t := C.CString(title)
	defer C.free(unsafe.Pointer(t))
	if monitor != nil {
		m = monitor.data
	}
	if share != nil {
		s = share.data
	}
	w := C.glfwCreateWindow(C.int(width), C.int(height), t, m, s)
	if w == nil {
		return nil, acceptError(APIUnavailable, VersionUnavailable)
	}
	wnd := &Window{data: w}
	windows.put(wnd)
	return wnd, nil
}
func (w *Window) Destroy() {
	windows.remove(w.data)
	C.glfwDestroyWindow(w.data)
	panicError()
}
func (w *Window) ShouldClose() bool {
	ret := glfwbool(C.glfwWindowShouldClose(w.data))
	panicError()
	return ret
}
func (w *Window) SetShouldClose(value bool) {
	if !value {
		C.glfwSetWindowShouldClose(w.data, C.GL_FALSE)
	} else {
		C.glfwSetWindowShouldClose(w.data, C.GL_TRUE)
	}
	panicError()
}
func (w *Window) SetTitle(title string) {
	t := C.CString(title)
	defer C.free(unsafe.Pointer(t))
	C.glfwSetWindowTitle(w.data, t)
	panicError()
}
func (w *Window) SetIcon(images []image.Image) {
	count := len(images)
	cimages := make([]C.GLFWimage, count)
	freePixels := make([]func(), count)
	for i, img := range images {
		var pixels []uint8
		b := img.Bounds()
		switch img := img.(type) {
		case *image.NRGBA:
			pixels = img.Pix
		default:
			m := image.NewNRGBA(image.Rect(0, 0, b.Dx(), b.Dy()))
			draw.Draw(m, m.Bounds(), img, b.Min, draw.Src)
			pixels = m.Pix
		}
		pix, free := bytes(pixels)
		freePixels[i] = free
		cimages[i].width = C.int(b.Dx())
		cimages[i].height = C.int(b.Dy())
		cimages[i].pixels = (*C.uchar)(pix)
	}
	var p *C.GLFWimage
	if count > 0 {
		p = &cimages[0]
	}
	C.glfwSetWindowIcon(w.data, C.int(count), p)
	for _, v := range freePixels {
		v()
	}
	panicError()
}
func (w *Window) GetPos() (x, y int) {
	var xpos, ypos C.int
	C.glfwGetWindowPos(w.data, &xpos, &ypos)
	panicError()
	return int(xpos), int(ypos)
}
func (w *Window) SetPos(xpos, ypos int) {
	C.glfwSetWindowPos(w.data, C.int(xpos), C.int(ypos))
	panicError()
}
func (w *Window) GetSize() (width, height int) {
	var wi, h C.int
	C.glfwGetWindowSize(w.data, &wi, &h)
	panicError()
	return int(wi), int(h)
}
func (w *Window) SetSize(width, height int) {
	C.glfwSetWindowSize(w.data, C.int(width), C.int(height))
	panicError()
}
func (w *Window) SetSizeLimits(minw, minh, maxw, maxh int) {
	C.glfwSetWindowSizeLimits(w.data, C.int(minw), C.int(minh), C.int(maxw), C.int(maxh))
	panicError()
}
func (w *Window) SetAspectRatio(numer, denom int) {
	C.glfwSetWindowAspectRatio(w.data, C.int(numer), C.int(denom))
	panicError()
}
func (w *Window) GetFramebufferSize() (width, height int) {
	var wi, h C.int
	C.glfwGetFramebufferSize(w.data, &wi, &h)
	panicError()
	return int(wi), int(h)
}
func (w *Window) GetFrameSize() (left, top, right, bottom int) {
	var l, t, r, b C.int
	C.glfwGetWindowFrameSize(w.data, &l, &t, &r, &b)
	panicError()
	return int(l), int(t), int(r), int(b)
}
func (w *Window) Focus() error {
	C.glfwFocusWindow(w.data)
	return acceptError(APIUnavailable)
}
func (w *Window) Iconify() error {
	C.glfwIconifyWindow(w.data)
	return acceptError(APIUnavailable)
}
func (w *Window) Maximize() error {
	C.glfwMaximizeWindow(w.data)
	return acceptError(APIUnavailable)
}
func (w *Window) Restore() error {
	C.glfwRestoreWindow(w.data)
	return acceptError(APIUnavailable)
}
func (w *Window) Show() {
	C.glfwShowWindow(w.data)
	panicError()
}
func (w *Window) Hide() {
	C.glfwHideWindow(w.data)
	panicError()
}
func (w *Window) GetMonitor() *Monitor {
	m := C.glfwGetWindowMonitor(w.data)
	panicError()
	if m == nil {
		return nil
	}
	return &Monitor{m}
}
func (w *Window) SetMonitor(monitor *Monitor, xpos, ypos, width, height, refreshRate int) {
	var m *C.GLFWmonitor
	if monitor == nil {
		m = nil
	} else {
		m = monitor.data
	}
	C.glfwSetWindowMonitor(w.data, m, C.int(xpos), C.int(ypos), C.int(width), C.int(height), C.int(refreshRate))
	panicError()
}
func (w *Window) GetAttrib(attrib Hint) int {
	ret := int(C.glfwGetWindowAttrib(w.data, C.int(attrib)))
	panicError()
	return ret
}
func (w *Window) SetUserPointer(pointer unsafe.Pointer) {
	C.glfwSetWindowUserPointer(w.data, pointer)
	panicError()
}
func (w *Window) GetUserPointer() unsafe.Pointer {
	ret := C.glfwGetWindowUserPointer(w.data)
	panicError()
	return ret
}
type PosCallback func(w *Window, xpos int, ypos int)
func (w *Window) SetPosCallback(cbfun PosCallback) (previous PosCallback) {
	previous = w.fPosHolder
	w.fPosHolder = cbfun
	if cbfun == nil {
		C.glfwSetWindowPosCallback(w.data, nil)
	} else {
		C.glfwSetWindowPosCallbackCB(w.data)
	}
	panicError()
	return previous
}
type SizeCallback func(w *Window, width int, height int)
func (w *Window) SetSizeCallback(cbfun SizeCallback) (previous SizeCallback) {
	previous = w.fSizeHolder
	w.fSizeHolder = cbfun
	if cbfun == nil {
		C.glfwSetWindowSizeCallback(w.data, nil)
	} else {
		C.glfwSetWindowSizeCallbackCB(w.data)
	}
	panicError()
	return previous
}
type FramebufferSizeCallback func(w *Window, width int, height int)
func (w *Window) SetFramebufferSizeCallback(cbfun FramebufferSizeCallback) (previous FramebufferSizeCallback) {
	previous = w.fFramebufferSizeHolder
	w.fFramebufferSizeHolder = cbfun
	if cbfun == nil {
		C.glfwSetFramebufferSizeCallback(w.data, nil)
	} else {
		C.glfwSetFramebufferSizeCallbackCB(w.data)
	}
	panicError()
	return previous
}
type CloseCallback func(w *Window)
func (w *Window) SetCloseCallback(cbfun CloseCallback) (previous CloseCallback) {
	previous = w.fCloseHolder
	w.fCloseHolder = cbfun
	if cbfun == nil {
		C.glfwSetWindowCloseCallback(w.data, nil)
	} else {
		C.glfwSetWindowCloseCallbackCB(w.data)
	}
	panicError()
	return previous
}
type RefreshCallback func(w *Window)
func (w *Window) SetRefreshCallback(cbfun RefreshCallback) (previous RefreshCallback) {
	previous = w.fRefreshHolder
	w.fRefreshHolder = cbfun
	if cbfun == nil {
		C.glfwSetWindowRefreshCallback(w.data, nil)
	} else {
		C.glfwSetWindowRefreshCallbackCB(w.data)
	}
	panicError()
	return previous
}
type FocusCallback func(w *Window, focused bool)
func (w *Window) SetFocusCallback(cbfun FocusCallback) (previous FocusCallback) {
	previous = w.fFocusHolder
	w.fFocusHolder = cbfun
	if cbfun == nil {
		C.glfwSetWindowFocusCallback(w.data, nil)
	} else {
		C.glfwSetWindowFocusCallbackCB(w.data)
	}
	panicError()
	return previous
}
type IconifyCallback func(w *Window, iconified bool)
func (w *Window) SetIconifyCallback(cbfun IconifyCallback) (previous IconifyCallback) {
	previous = w.fIconifyHolder
	w.fIconifyHolder = cbfun
	if cbfun == nil {
		C.glfwSetWindowIconifyCallback(w.data, nil)
	} else {
		C.glfwSetWindowIconifyCallbackCB(w.data)
	}
	panicError()
	return previous
}
func (w *Window) SetClipboardString(str string) {
	cp := C.CString(str)
	defer C.free(unsafe.Pointer(cp))
	C.glfwSetClipboardString(w.data, cp)
	panicError()
}
func (w *Window) GetClipboardString() (string, error) {
	cs := C.glfwGetClipboardString(w.data)
	if cs == nil {
		return "", acceptError(FormatUnavailable)
	}
	return C.GoString(cs), nil
}
func PollEvents() {
	C.glfwPollEvents()
	panicError()
}
func WaitEvents() {
	C.glfwWaitEvents()
	panicError()
}