code.witches.io/go/sdl2@v0.1.1/events.go (about)

     1  package sdl
     2  
     3  // #include <SDL2/SDL_events.h>
     4  // #include "events.h"
     5  import "C"
     6  import (
     7  	"encoding/binary"
     8  	"fmt"
     9  	"math"
    10  	"os"
    11  	"os/signal"
    12  	"runtime"
    13  	"sync"
    14  	"sync/atomic"
    15  	"time"
    16  	"unsafe"
    17  
    18  	"code.witches.io/go/sdl2/internal"
    19  )
    20  
    21  const (
    22  	Query   = -1
    23  	Ignore  = 0
    24  	Disable = 0
    25  	Enable  = 1
    26  )
    27  
    28  type EventType uint32
    29  
    30  const (
    31  	EventFirstEvent EventType = iota
    32  )
    33  
    34  const (
    35  	EventQuit EventType = 0x100 + iota
    36  	EventApplicationTerminating
    37  	EventApplicationLowMemory
    38  	EventApplicationWillEnterBackground
    39  	EventApplicationDidEnterBackground
    40  	EventApplicationWillEnterForeground
    41  	EventApplicationDidEnterForeground
    42  )
    43  
    44  const (
    45  	EventWindowEvent EventType = 0x200 + iota
    46  	EventSystemWindowManagerEvent
    47  )
    48  
    49  const (
    50  	EventKeyDown EventType = 0x300 + iota
    51  	EventKeyUp
    52  	EventTextEditing
    53  	EventTextInput
    54  	EventKeyMapChanged
    55  )
    56  
    57  const (
    58  	EventMouseMotion EventType = 0x400 + iota
    59  	EventMouseButtonDown
    60  	EventMouseButtonUp
    61  	EventMouseWheel
    62  )
    63  
    64  const (
    65  	EventJoystickAxisMotion EventType = 0x600 + iota
    66  	EventJoystickTrackballMotion
    67  	EventJoystickHatMotion
    68  	EventJoystickButtonDown
    69  	EventJoystickButtonUp
    70  	EventJoystickDeviceAdded
    71  	EventJoystickDeviceRemoved
    72  )
    73  
    74  const (
    75  	EventControllerAxisMotion EventType = 0x650 + iota
    76  	EventControllerButtonDown
    77  	EventControllerButtonUp
    78  	EventControllerDeviceAdded
    79  	EventControllerDeviceRemoved
    80  	EventControllerDeviceRemapped
    81  	EventControllerTouchpadDown
    82  	EventControllerTouchpadMotion
    83  	EventControllerTouchpadUp
    84  	EventControllerSensorUpdate
    85  )
    86  
    87  const (
    88  	EventFingerDown EventType = 0x700 + iota
    89  	EventFingerUp
    90  	EventFingerMotion
    91  )
    92  
    93  const (
    94  	EventDollarGesture EventType = 0x800 + iota
    95  	EventDollarRecord
    96  	EventMultiGesture
    97  )
    98  
    99  const (
   100  	EventClipboardUpdate EventType = 0x900 + iota
   101  )
   102  
   103  const (
   104  	EventDropFile EventType = 0x1000 + iota
   105  	EventDropText
   106  	EventDropBegin
   107  	EventDropComplete
   108  )
   109  
   110  const (
   111  	EventAudioDeviceAdded EventType = 0x1100 + iota
   112  	EventAudioDeviceRemoved
   113  )
   114  
   115  const (
   116  	EventRenderTargetsReset EventType = 0x2000 + iota
   117  	EventRenderDeviceReset
   118  )
   119  
   120  const (
   121  	EventUserEvent EventType = 0x8000 + iota
   122  )
   123  
   124  const (
   125  	EventLastEvent EventType = 0xffff
   126  )
   127  
   128  var eventTypeToStringMap = map[EventType]string{
   129  	EventFirstEvent:                     "first event",
   130  	EventQuit:                           "quit",
   131  	EventApplicationTerminating:         "application terminating",
   132  	EventApplicationLowMemory:           "application low memory",
   133  	EventApplicationWillEnterBackground: "application will enter background",
   134  	EventApplicationDidEnterBackground:  "application did enter background",
   135  	EventApplicationWillEnterForeground: "application will enter foreground",
   136  	EventApplicationDidEnterForeground:  "application did enter foreground",
   137  	EventWindowEvent:                    "window event",
   138  	EventSystemWindowManagerEvent:       "system window manager event",
   139  	EventKeyDown:                        "key down",
   140  	EventKeyUp:                          "key up",
   141  	EventTextEditing:                    "text editing",
   142  	EventTextInput:                      "text input",
   143  	EventKeyMapChanged:                  "key map changed",
   144  	EventMouseMotion:                    "mouse motion",
   145  	EventMouseButtonDown:                "mouse button down",
   146  	EventMouseButtonUp:                  "mouse button up",
   147  	EventMouseWheel:                     "mouse wheel",
   148  	EventJoystickAxisMotion:             "joystick axis motion",
   149  	EventJoystickTrackballMotion:        "joystick trackball motion",
   150  	EventJoystickHatMotion:              "joystick hat motion",
   151  	EventJoystickButtonDown:             "joystick button down",
   152  	EventJoystickButtonUp:               "joystick button up",
   153  	EventJoystickDeviceAdded:            "joystick device added",
   154  	EventJoystickDeviceRemoved:          "joystick device removed",
   155  	EventControllerAxisMotion:           "controller axis motion",
   156  	EventControllerButtonDown:           "controller button down",
   157  	EventControllerButtonUp:             "controller button up",
   158  	EventControllerDeviceAdded:          "controller device added",
   159  	EventControllerDeviceRemoved:        "controller device removed",
   160  	EventControllerDeviceRemapped:       "controller device remapped",
   161  	EventControllerTouchpadDown:         "controller touchpad down",
   162  	EventControllerTouchpadMotion:       "controller touchpad motion",
   163  	EventControllerTouchpadUp:           "controller touchpad up",
   164  	EventControllerSensorUpdate:         "controller sensor update",
   165  	EventFingerDown:                     "finger down",
   166  	EventFingerUp:                       "finger up",
   167  	EventFingerMotion:                   "finger motion",
   168  	EventDollarGesture:                  "dollar gesture",
   169  	EventDollarRecord:                   "dollar record",
   170  	EventMultiGesture:                   "multi gesture",
   171  	EventClipboardUpdate:                "clipboard update",
   172  	EventDropFile:                       "drop file",
   173  	EventDropText:                       "drop text",
   174  	EventDropBegin:                      "drop begin",
   175  	EventDropComplete:                   "drop complete",
   176  	EventAudioDeviceAdded:               "audio device added",
   177  	EventAudioDeviceRemoved:             "audio device removed",
   178  	EventRenderTargetsReset:             "render targets reset",
   179  	EventRenderDeviceReset:              "render device reset",
   180  }
   181  
   182  func (t EventType) String() string {
   183  	s, ok := eventTypeToStringMap[t]
   184  	if !ok {
   185  		if t >= EventUserEvent && t <= EventLastEvent {
   186  			return "user event"
   187  		}
   188  		return "unknown event"
   189  	}
   190  	return s
   191  }
   192  
   193  type Event interface {
   194  	eventFunc()
   195  }
   196  
   197  type CommonEvent struct {
   198  	Type      EventType
   199  	Timestamp time.Time
   200  	Event     Event
   201  }
   202  
   203  type WindowEvent struct {
   204  	Type      EventType
   205  	Timestamp time.Time
   206  	WindowID  int
   207  	Event     WindowEventID
   208  	Data1     int
   209  	Data2     int
   210  }
   211  
   212  type KeyboardEvent struct {
   213  	Type      EventType
   214  	Timestamp time.Time
   215  	WindowID  int
   216  	Pressed   bool
   217  	Repeat    uint
   218  	KeySymbol KeySymbol
   219  }
   220  
   221  type MouseMotionEvent struct {
   222  	Type      EventType
   223  	Timestamp time.Time
   224  	WindowID  int
   225  	Which     int
   226  	Buttons   MouseButtons
   227  	X         int
   228  	Y         int
   229  	DeltaX    int
   230  	DeltaY    int
   231  }
   232  
   233  type MouseButtonEvent struct {
   234  	Type      EventType
   235  	Timestamp time.Time
   236  	WindowID  int
   237  	Which     int
   238  	Button    int
   239  	Pressed   bool
   240  	Clicks    int
   241  	X         int
   242  	Y         int
   243  }
   244  
   245  type AudioDeviceEvent struct {
   246  	Type      EventType
   247  	Timestamp time.Time
   248  	Which     int
   249  	IsCapture bool
   250  }
   251  
   252  type TouchFingerEvent struct {
   253  	Type      EventType
   254  	Timestamp time.Time
   255  	TouchID   TouchID
   256  	FingerID  FingerID
   257  	X         float32
   258  	Y         float32
   259  	DeltaX    float32
   260  	DeltaY    float32
   261  	Pressure  float32
   262  }
   263  
   264  type MultiGestureEvent struct {
   265  	Type       EventType
   266  	Timestamp  time.Time
   267  	TouchID    TouchID
   268  	Angle      float32
   269  	Distance   float32
   270  	X          float32
   271  	Y          float32
   272  	NumFingers uint16
   273  	Padding    uint16
   274  }
   275  
   276  type DollarGestureEvent struct {
   277  	Type       EventType
   278  	Timestamp  time.Time
   279  	TouchID    TouchID
   280  	GestureID  GestureID
   281  	NumFingers uint32
   282  	Error      float32
   283  	X          float32
   284  	Y          float32
   285  }
   286  
   287  type ControllerAxisEvent struct {
   288  	Type      EventType
   289  	Timestamp time.Time
   290  	Which     JoystickID
   291  	Axis      uint8
   292  	_         [3]uint8
   293  	Value     int16
   294  	_         uint16
   295  }
   296  
   297  type ControllerButtonEvent struct {
   298  	Type      EventType
   299  	Timestamp time.Time
   300  	Which     JoystickID
   301  	Button    uint8
   302  	State     uint8
   303  	_         [2]uint8
   304  }
   305  
   306  type ControllerDeviceEvent struct {
   307  	Type      EventType
   308  	Timestamp time.Time
   309  	Which     int
   310  }
   311  
   312  type ControllerTouchpadEvent struct {
   313  	Type      EventType
   314  	Timestamp time.Time
   315  	Which     JoystickID
   316  	Touchpad  int32
   317  	Finger    int32
   318  	X         float32
   319  	Y         float32
   320  	Pressure  float32
   321  }
   322  
   323  type ControllerSensorEvent struct {
   324  	Type      EventType
   325  	Timestamp time.Time
   326  	Which     JoystickID
   327  	Sensor    SensorType
   328  	Data      [3]float32
   329  }
   330  
   331  var events = make(chan C.SDL_Event, 16)
   332  
   333  //export propevent
   334  func propevent(ev *C.SDL_Event) {
   335  	if ev == nil {
   336  		return
   337  	}
   338  	goev := *ev
   339  	select {
   340  	case events <- goev:
   341  	case <-quit:
   342  	}
   343  }
   344  
   345  //export didQuit
   346  func didQuit(c chan<- struct{}) {
   347  	c <- struct{}{}
   348  }
   349  
   350  var evo sync.Once
   351  var quit chan struct{} = make(chan struct{})
   352  
   353  func PollEvent() *CommonEvent {
   354  	evo.Do(func() {
   355  		sc := make(chan os.Signal, 2)
   356  		//dq := make(chan struct{})
   357  		internal.Cleanup.Add(1)
   358  		var collectEventsQuit uint32
   359  		go func() {
   360  			select {
   361  			case <-sc:
   362  			case <-quit:
   363  			}
   364  			//y := (*uint32)(unsafe.Pointer(&C.collectEventsQuit))
   365  			atomic.StoreUint32(&collectEventsQuit, 1)
   366  			for {
   367  				x := atomic.LoadUint32(&collectEventsQuit)
   368  				//fmt.Println(x)
   369  				if x == 2 {
   370  					break
   371  				}
   372  				runtime.Gosched()
   373  			}
   374  			internal.Cleanup.Done()
   375  		}()
   376  		signal.Notify(sc, os.Interrupt, os.Kill)
   377  		go C.collectEvents((*C.Uint32)(unsafe.Pointer(&collectEventsQuit))) //C.GoChan(unsafe.Pointer(&dq)))
   378  	})
   379  
   380  	var e C.SDL_Event
   381  
   382  	//runtime.LockOSThread()
   383  	//defer runtime.UnlockOSThread()
   384  
   385  	//if C.SDL_PollEvent((*C.SDL_Event)(unsafe.Pointer(&e))) != 1 {
   386  	//	return nil
   387  	//}
   388  	select {
   389  	case e = <-events:
   390  
   391  	default:
   392  		return nil
   393  	}
   394  
   395  	_type := EventType(binary.LittleEndian.Uint32(e[0:4]))
   396  	_timestamp := time.Duration(binary.LittleEndian.Uint32(e[4:8]))
   397  
   398  	wrapper := &CommonEvent{
   399  		Type:      EventType(binary.LittleEndian.Uint32(e[0:4])),
   400  		Timestamp: timeInit.Add(_timestamp * time.Millisecond),
   401  	}
   402  
   403  	switch _type {
   404  	case EventWindowEvent:
   405  		wrapper.Event = WindowEvent{
   406  			Type:      wrapper.Type,
   407  			Timestamp: wrapper.Timestamp,
   408  			WindowID:  int(binary.LittleEndian.Uint32(e[8:12])),
   409  			Event:     WindowEventID(e[12]),
   410  			Data1:     int(binary.LittleEndian.Uint32(e[16:20])),
   411  			Data2:     int(binary.LittleEndian.Uint32(e[20:24])),
   412  		}
   413  	case EventKeyDown, EventKeyUp:
   414  		wrapper.Event = KeyboardEvent{
   415  			Type:      wrapper.Type,
   416  			Timestamp: wrapper.Timestamp,
   417  			WindowID:  int(binary.LittleEndian.Uint32(e[8:12])),
   418  			Pressed:   bool(e[12] != 0),
   419  			Repeat:    uint(e[13]),
   420  			KeySymbol: KeySymbol{
   421  				Scancode:  ScanCode(binary.LittleEndian.Uint32(e[16:20])),
   422  				Keycode:   KeyCode(binary.LittleEndian.Uint32(e[20:24])),
   423  				Modifiers: KeyModifiers(binary.LittleEndian.Uint16(e[24:26])),
   424  			},
   425  		}
   426  	case EventAudioDeviceAdded, EventAudioDeviceRemoved:
   427  		wrapper.Event = AudioDeviceEvent{
   428  			Type:      wrapper.Type,
   429  			Timestamp: wrapper.Timestamp,
   430  			Which:     int(binary.LittleEndian.Uint32(e[8:12])),
   431  			IsCapture: bool(e[12] != 0),
   432  		}
   433  	case EventMouseMotion:
   434  		wrapper.Event = MouseMotionEvent{
   435  			Type:      wrapper.Type,
   436  			Timestamp: wrapper.Timestamp,
   437  			WindowID:  int(binary.LittleEndian.Uint32(e[8:12])),
   438  			Which:     int(binary.LittleEndian.Uint32(e[12:16])),
   439  			Buttons: MouseButtons{
   440  				Left:   (e[16]>>0)&1 == 1,
   441  				Middle: (e[16]>>1)&1 == 1,
   442  				Right:  (e[16]>>2)&1 == 1,
   443  				X1:     (e[16]>>3)&1 == 1,
   444  				X2:     (e[16]>>4)&1 == 1,
   445  			},
   446  			X:      int(int32(binary.LittleEndian.Uint32(e[20:24]))),
   447  			Y:      int(int32(binary.LittleEndian.Uint32(e[24:28]))),
   448  			DeltaX: int(int32(binary.LittleEndian.Uint32(e[28:32]))),
   449  			DeltaY: int(int32(binary.LittleEndian.Uint32(e[32:36]))),
   450  		}
   451  	case EventMouseButtonDown:
   452  		wrapper.Event = MouseButtonEvent{
   453  			Type:      wrapper.Type,
   454  			Timestamp: wrapper.Timestamp,
   455  			WindowID:  int(binary.LittleEndian.Uint32(e[8:12])),
   456  			Which:     int(binary.LittleEndian.Uint32(e[12:16])),
   457  			Button:    int(e[16]),
   458  			Pressed:   e[17] == 1,
   459  			Clicks:    int(e[18]),
   460  			X:         int(binary.LittleEndian.Uint32(e[20:24])),
   461  			Y:         int(binary.LittleEndian.Uint32(e[24:28])),
   462  		}
   463  	case EventMouseButtonUp:
   464  		wrapper.Event = MouseButtonEvent{
   465  			Type:      wrapper.Type,
   466  			Timestamp: wrapper.Timestamp,
   467  			WindowID:  int(binary.LittleEndian.Uint32(e[8:12])),
   468  			Which:     int(binary.LittleEndian.Uint32(e[12:16])),
   469  			Button:    int(e[16]),
   470  			Pressed:   e[17] == 1,
   471  			Clicks:    int(e[18]),
   472  			X:         int(binary.LittleEndian.Uint32(e[20:24])),
   473  			Y:         int(binary.LittleEndian.Uint32(e[24:28])),
   474  		}
   475  	case EventFingerDown, EventFingerMotion, EventFingerUp:
   476  		wrapper.Event = TouchFingerEvent{
   477  			Type:      wrapper.Type,
   478  			Timestamp: wrapper.Timestamp,
   479  			TouchID:   TouchID(binary.LittleEndian.Uint64(e[8:16])),
   480  			FingerID:  FingerID(binary.LittleEndian.Uint64(e[16:24])),
   481  			X:         math.Float32frombits(binary.LittleEndian.Uint32(e[24:28])),
   482  			Y:         math.Float32frombits(binary.LittleEndian.Uint32(e[28:32])),
   483  			DeltaX:    math.Float32frombits(binary.LittleEndian.Uint32(e[32:36])),
   484  			DeltaY:    math.Float32frombits(binary.LittleEndian.Uint32(e[36:40])),
   485  			Pressure:  math.Float32frombits(binary.LittleEndian.Uint32(e[40:44])),
   486  		}
   487  		if !VersionAtLeast(2, 0, 7) {
   488  			// todo: normalize values
   489  		}
   490  	case EventMultiGesture:
   491  		wrapper.Event = MultiGestureEvent{
   492  			Type:       wrapper.Type,
   493  			Timestamp:  wrapper.Timestamp,
   494  			TouchID:    TouchID(binary.LittleEndian.Uint64(e[8:16])),
   495  			Angle:      math.Float32frombits(binary.LittleEndian.Uint32(e[16:20])),
   496  			Distance:   math.Float32frombits(binary.LittleEndian.Uint32(e[20:24])),
   497  			X:          math.Float32frombits(binary.LittleEndian.Uint32(e[24:28])),
   498  			Y:          math.Float32frombits(binary.LittleEndian.Uint32(e[28:32])),
   499  			NumFingers: binary.LittleEndian.Uint16(e[32:34]),
   500  			Padding:    binary.LittleEndian.Uint16(e[34:36]),
   501  		}
   502  	case EventDollarGesture, EventDollarRecord:
   503  		wrapper.Event = DollarGestureEvent{
   504  			Type:       wrapper.Type,
   505  			Timestamp:  wrapper.Timestamp,
   506  			TouchID:    TouchID(binary.LittleEndian.Uint64(e[8:16])),
   507  			GestureID:  GestureID(binary.LittleEndian.Uint64(e[16:24])),
   508  			NumFingers: binary.LittleEndian.Uint32(e[24:28]),
   509  			Error:      math.Float32frombits(binary.LittleEndian.Uint32(e[28:32])),
   510  			X:          math.Float32frombits(binary.LittleEndian.Uint32(e[32:36])),
   511  			Y:          math.Float32frombits(binary.LittleEndian.Uint32(e[36:40])),
   512  		}
   513  	case EventControllerAxisMotion:
   514  		wrapper.Event = ControllerAxisEvent{
   515  			Type:      wrapper.Type,
   516  			Timestamp: wrapper.Timestamp,
   517  			Which:     JoystickID(binary.LittleEndian.Uint32(e[8:12])),
   518  			Axis:      e[12],
   519  			Value:     int16(binary.LittleEndian.Uint16(e[16:18])),
   520  		}
   521  	case EventControllerButtonDown, EventControllerButtonUp:
   522  		wrapper.Event = ControllerButtonEvent{
   523  			Type:      wrapper.Type,
   524  			Timestamp: wrapper.Timestamp,
   525  			Which:     JoystickID(binary.LittleEndian.Uint32(e[8:12])),
   526  			Button:    e[12],
   527  			State:     e[13],
   528  		}
   529  	case EventControllerDeviceAdded, EventControllerDeviceRemapped, EventControllerDeviceRemoved:
   530  		wrapper.Event = ControllerDeviceEvent{
   531  			Type:      wrapper.Type,
   532  			Timestamp: wrapper.Timestamp,
   533  			Which:     int(binary.LittleEndian.Uint32(e[8:12])),
   534  		}
   535  	case EventControllerTouchpadDown, EventControllerTouchpadMotion, EventControllerTouchpadUp:
   536  		wrapper.Event = ControllerTouchpadEvent{
   537  			Type:      wrapper.Type,
   538  			Timestamp: wrapper.Timestamp,
   539  			Which:     JoystickID(binary.LittleEndian.Uint32(e[8:12])),
   540  			Touchpad:  int32(binary.LittleEndian.Uint32(e[12:16])),
   541  			Finger:    int32(binary.LittleEndian.Uint32(e[16:20])),
   542  			X:         math.Float32frombits(binary.LittleEndian.Uint32(e[20:24])),
   543  			Y:         math.Float32frombits(binary.LittleEndian.Uint32(e[24:28])),
   544  			Pressure:  math.Float32frombits(binary.LittleEndian.Uint32(e[28:32])),
   545  		}
   546  	case EventControllerSensorUpdate:
   547  		wrapper.Event = ControllerSensorEvent{
   548  			Type:      wrapper.Type,
   549  			Timestamp: wrapper.Timestamp,
   550  			Which:     JoystickID(binary.LittleEndian.Uint32(e[8:12])),
   551  			Sensor:    SensorType(binary.LittleEndian.Uint32(e[12:16])),
   552  			Data: [3]float32{
   553  				math.Float32frombits(binary.LittleEndian.Uint32(e[16:20])),
   554  				math.Float32frombits(binary.LittleEndian.Uint32(e[20:24])),
   555  				math.Float32frombits(binary.LittleEndian.Uint32(e[24:28])),
   556  			},
   557  		}
   558  	default:
   559  		wrapper.Event = CommonEvent{
   560  			Type:      wrapper.Type,
   561  			Timestamp: wrapper.Timestamp,
   562  			Event:     wrapper,
   563  		}
   564  	}
   565  
   566  	return wrapper
   567  }
   568  
   569  type EventAction uint32
   570  
   571  const (
   572  	AddEvent  EventAction = C.SDL_ADDEVENT
   573  	PeekEvent EventAction = C.SDL_PEEKEVENT
   574  	GetEvent  EventAction = C.SDL_GETEVENT
   575  )
   576  
   577  func PeepEvents(n uint, action EventAction, min, max EventType) ([]Event, error) {
   578  	_events := (*C.SDL_Event)(C.calloc(C.size_t(n), C.size_t(unsafe.Sizeof(C.SDL_Event{}))))
   579  	defer C.free(unsafe.Pointer(_events))
   580  
   581  	result := C.SDL_PeepEvents(_events, C.int(n), C.SDL_eventaction(action), C.Uint32(min), C.Uint32(max))
   582  	if result < 1 {
   583  		return nil, GetError()
   584  	}
   585  
   586  	events := make([]Event, result)
   587  	return events, nil
   588  }
   589  
   590  func PumpEvents() {
   591  	C.SDL_PumpEvents()
   592  }
   593  
   594  func PushEvent(event Event) (filtered bool, err error) {
   595  	var e C.SDL_Event
   596  
   597  	switch event := event.(type) {
   598  	case CommonEvent:
   599  		binary.LittleEndian.PutUint32(e[0:4], uint32(event.Type))
   600  		binary.LittleEndian.PutUint32(e[4:8], uint32(event.Timestamp.UnixNano()*int64(time.Millisecond)/int64(time.Nanosecond)))
   601  	default:
   602  		return false, fmt.Errorf("not yet supported")
   603  	}
   604  
   605  	switch int(C.SDL_PushEvent(&e)) {
   606  	case 0:
   607  		return true, nil
   608  	case 1:
   609  		return false, nil
   610  	default:
   611  		return false, GetError()
   612  	}
   613  }
   614  
   615  func (CommonEvent) eventFunc()             {}
   616  func (WindowEvent) eventFunc()             {}
   617  func (KeyboardEvent) eventFunc()           {}
   618  func (MouseMotionEvent) eventFunc()        {}
   619  func (MouseButtonEvent) eventFunc()        {}
   620  func (AudioDeviceEvent) eventFunc()        {}
   621  func (TouchFingerEvent) eventFunc()        {}
   622  func (MultiGestureEvent) eventFunc()       {}
   623  func (DollarGestureEvent) eventFunc()      {}
   624  func (ControllerAxisEvent) eventFunc()     {}
   625  func (ControllerButtonEvent) eventFunc()   {}
   626  func (ControllerDeviceEvent) eventFunc()   {}
   627  func (ControllerTouchpadEvent) eventFunc() {}
   628  func (ControllerSensorEvent) eventFunc()   {}
   629  
   630  func (e CommonEvent) String() string {
   631  	return fmt.Sprintf("%s", e.Type)
   632  }
   633  
   634  func (e WindowEvent) String() string {
   635  	return fmt.Sprintf("%s, window: %2d, data1: %16p, data2: %16p, event: %s", e.Type, e.WindowID, e.Data1, e.Data2, e.Event)
   636  }
   637  
   638  func (e KeyboardEvent) String() string {
   639  	return fmt.Sprintf("%s, window: %2d, pressed: %5t, repeat: %2d, %v %v %v", e.Type, e.WindowID, e.Pressed, e.Repeat, e.KeySymbol.Scancode, e.KeySymbol.Keycode, e.KeySymbol.Modifiers)
   640  }
   641  
   642  func (e MouseMotionEvent) String() string {
   643  	return fmt.Sprintf("%s, window: %2d, device: %2d, X: %4d, Y: %4d, ΔX: %+3d, ΔY: %+3d, buttons: %s", e.Type, e.WindowID, e.Which, e.X, e.Y, e.DeltaX, e.DeltaY, e.Buttons)
   644  }
   645  
   646  func (e MouseButtonEvent) String() string {
   647  	return fmt.Sprintf("%s, window: %2d, device: %2d, button: %2d, pressed: %5t, clicks: %2d, X: %4d, Y: %4d", e.Type, e.WindowID, e.Which, e.Button, e.Pressed, e.Clicks, e.X, e.Y)
   648  }
   649  
   650  func (e AudioDeviceEvent) String() string {
   651  	name, err := GetAudioDeviceName(e.Which, e.IsCapture)
   652  	if err == nil {
   653  		return fmt.Sprintf("%s, device: %2d, capture: %5t, name: %q", e.Type, e.Which, e.IsCapture, name)
   654  	}
   655  	return fmt.Sprintf("%s, device: %2d, capture: %5t", e.Type, e.Which, e.IsCapture)
   656  }
   657  
   658  func (e TouchFingerEvent) String() string {
   659  	return fmt.Sprintf("%s, touch: %2d, finger: %2d, X: %6.2f, Y: %6.2f, ΔX: %+5.2f, ΔY: %+5.2f, pressure: %3.2f", e.Type, e.TouchID, e.FingerID, e.X, e.Y, e.DeltaX, e.DeltaY, e.Pressure)
   660  }
   661  
   662  func (e MultiGestureEvent) String() string {
   663  	return fmt.Sprintf("%s, touch: %2d, rotation: %+5.4f, pinch: %+5.4f, X: %6.2f, Y: %6.2f, fingers: %2d, padding: %2d", e.Type, e.TouchID, e.Angle, e.Distance, e.X, e.Y, e.NumFingers, e.Padding)
   664  }
   665  
   666  func (e DollarGestureEvent) String() string {
   667  	return fmt.Sprintf("%s, touch: %2d, gesture: %2d, fingers: %2d, error: %3.2f, X: %6.2f, Y: %6.2f", e.Type, e.TouchID, e.GestureID, e.NumFingers, e.Error, e.X, e.Y)
   668  }
   669  
   670  func (e ControllerAxisEvent) String() string {
   671  	return fmt.Sprintf("%s, which: %2d, axis: %2d, value: %4d", e.Type, e.Which, e.Axis, e.Value)
   672  }
   673  
   674  func (e ControllerButtonEvent) String() string {
   675  	return fmt.Sprintf("%s, which: %2d, button: %2d, state: %2d", e.Type, e.Which, e.Button, e.State)
   676  }
   677  
   678  func (e ControllerDeviceEvent) String() string {
   679  	return fmt.Sprintf("%s, which: %2d", e.Type, e.Which)
   680  }
   681  
   682  func (e ControllerTouchpadEvent) String() string {
   683  	return fmt.Sprintf("%s, which: %2d, touchpad: %2d, finger: %2d, X: %6.2f, Y: %6.2, pressure: %6.2f", e.Type, e.Which, e.Touchpad, e.Finger, e.X, e.Y, e.Pressure)
   684  }
   685  
   686  func (e ControllerSensorEvent) String() string {
   687  	return fmt.Sprintf("%s, which: %2d, sensor: %2d, data: [%6.2f %6.2f %6.2f]", e.Type, e.Which, e.Sensor, e.Data[0], e.Data[1], e.Data[2])
   688  }