github.com/u-root/u-root@v7.0.1-0.20200915234505-ad7babab0a8e+incompatible/cmds/core/elvish/sys/console_windows.go (about) 1 package sys 2 3 import ( 4 "errors" 5 "unsafe" 6 7 "golang.org/x/sys/windows" 8 ) 9 10 var ( 11 readConsoleInput = kernel32.NewProc("ReadConsoleInputW") 12 errNr0 = errors.New("ReadConsoleInput reads 0 records") 13 ) 14 15 // ReadInputEvent wraps ReadConsoleInput into a Go-friendly interface. 16 func ReadInputEvent(h windows.Handle) (InputEvent, error) { 17 var buf [1]InputRecord 18 nr, err := ReadConsoleInput(h, buf[:]) 19 if err != nil { 20 return nil, err 21 } else if nr == 0 { 22 return nil, errNr0 23 } 24 return buf[0].GetEvent(), nil 25 } 26 27 // ReadConsoleInput input wraps the homonymous Windows API call. 28 // 29 // BOOL WINAPI ReadConsoleInput( 30 // _In_ HANDLE hConsoleInput, 31 // _Out_ PINPUT_RECORD lpBuffer, 32 // _In_ DWORD nLength, 33 // _Out_ LPDWORD lpNumberOfEventsRead 34 // ); 35 func ReadConsoleInput(h windows.Handle, buf []InputRecord) (int, error) { 36 var nr uintptr 37 r, _, err := readConsoleInput.Call(uintptr(h), 38 uintptr(unsafe.Pointer(&buf[0])), uintptr(len(buf)), uintptr(unsafe.Pointer(&nr))) 39 if r != 0 { 40 err = nil 41 } 42 return int(nr), err 43 } 44 45 // InputEvent is either a KeyEvent, MouseEvent, WindowBufferSizeEvent, 46 // MenuEvent or FocusEvent. 47 type InputEvent interface { 48 isInputEvent() 49 } 50 51 func (*KeyEvent) isInputEvent() {} 52 func (*MouseEvent) isInputEvent() {} 53 func (*WindowBufferSizeEvent) isInputEvent() {} 54 func (*MenuEvent) isInputEvent() {} 55 func (*FocusEvent) isInputEvent() {} 56 57 // GetEvent converts InputRecord to InputEvent. 58 func (input *InputRecord) GetEvent() InputEvent { 59 switch input.EventType { 60 case KEY_EVENT: 61 return (*KeyEvent)(unsafe.Pointer(&input.Event)) 62 case MOUSE_EVENT: 63 return (*MouseEvent)(unsafe.Pointer(&input.Event)) 64 case WINDOW_BUFFER_SIZE_EVENT: 65 return (*WindowBufferSizeEvent)(unsafe.Pointer(&input.Event)) 66 case MENU_EVENT: 67 return (*MenuEvent)(unsafe.Pointer(&input.Event)) 68 case FOCUS_EVENT: 69 return (*FocusEvent)(unsafe.Pointer(&input.Event)) 70 default: 71 return nil 72 } 73 }