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  }