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 }