Add vendor
Specifically because I want to modify a dependency
This commit is contained in:
34
vendor/golang.org/x/exp/shiny/driver/internal/drawer/drawer.go
generated
vendored
Normal file
34
vendor/golang.org/x/exp/shiny/driver/internal/drawer/drawer.go
generated
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package drawer provides functions that help implement screen.Drawer methods.
|
||||
package drawer // import "golang.org/x/exp/shiny/driver/internal/drawer"
|
||||
|
||||
import (
|
||||
"image"
|
||||
"image/draw"
|
||||
|
||||
"golang.org/x/exp/shiny/screen"
|
||||
"golang.org/x/image/math/f64"
|
||||
)
|
||||
|
||||
// Copy implements the Copy method of the screen.Drawer interface by calling
|
||||
// the Draw method of that same interface.
|
||||
func Copy(dst screen.Drawer, dp image.Point, src screen.Texture, sr image.Rectangle, op draw.Op, opts *screen.DrawOptions) {
|
||||
dst.Draw(f64.Aff3{
|
||||
1, 0, float64(dp.X - sr.Min.X),
|
||||
0, 1, float64(dp.Y - sr.Min.Y),
|
||||
}, src, sr, op, opts)
|
||||
}
|
||||
|
||||
// Scale implements the Scale method of the screen.Drawer interface by calling
|
||||
// the Draw method of that same interface.
|
||||
func Scale(dst screen.Drawer, dr image.Rectangle, src screen.Texture, sr image.Rectangle, op draw.Op, opts *screen.DrawOptions) {
|
||||
rx := float64(dr.Dx()) / float64(sr.Dx())
|
||||
ry := float64(dr.Dy()) / float64(sr.Dy())
|
||||
dst.Draw(f64.Aff3{
|
||||
rx, 0, float64(dr.Min.X) - rx*float64(sr.Min.X),
|
||||
0, ry, float64(dr.Min.Y) - ry*float64(sr.Min.Y),
|
||||
}, src, sr, op, opts)
|
||||
}
|
||||
25
vendor/golang.org/x/exp/shiny/driver/internal/errscreen/errscreen.go
generated
vendored
Normal file
25
vendor/golang.org/x/exp/shiny/driver/internal/errscreen/errscreen.go
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
// Copyright 2015 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package errscreen provides a stub Screen implementation.
|
||||
package errscreen // import "golang.org/x/exp/shiny/driver/internal/errscreen"
|
||||
|
||||
import (
|
||||
"image"
|
||||
|
||||
"golang.org/x/exp/shiny/screen"
|
||||
)
|
||||
|
||||
// Stub returns a Screen whose methods all return the given error.
|
||||
func Stub(err error) screen.Screen {
|
||||
return stub{err}
|
||||
}
|
||||
|
||||
type stub struct {
|
||||
err error
|
||||
}
|
||||
|
||||
func (s stub) NewBuffer(size image.Point) (screen.Buffer, error) { return nil, s.err }
|
||||
func (s stub) NewTexture(size image.Point) (screen.Texture, error) { return nil, s.err }
|
||||
func (s stub) NewWindow(opts *screen.NewWindowOptions) (screen.Window, error) { return nil, s.err }
|
||||
68
vendor/golang.org/x/exp/shiny/driver/internal/event/event.go
generated
vendored
Normal file
68
vendor/golang.org/x/exp/shiny/driver/internal/event/event.go
generated
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
// Copyright 2015 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package event provides an infinitely buffered double-ended queue of events.
|
||||
package event // import "golang.org/x/exp/shiny/driver/internal/event"
|
||||
|
||||
import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
// Deque is an infinitely buffered double-ended queue of events. The zero value
|
||||
// is usable, but a Deque value must not be copied.
|
||||
type Deque struct {
|
||||
mu sync.Mutex
|
||||
cond sync.Cond // cond.L is lazily initialized to &Deque.mu.
|
||||
back []interface{} // FIFO.
|
||||
front []interface{} // LIFO.
|
||||
}
|
||||
|
||||
func (q *Deque) lockAndInit() {
|
||||
q.mu.Lock()
|
||||
if q.cond.L == nil {
|
||||
q.cond.L = &q.mu
|
||||
}
|
||||
}
|
||||
|
||||
// NextEvent implements the screen.EventDeque interface.
|
||||
func (q *Deque) NextEvent() interface{} {
|
||||
q.lockAndInit()
|
||||
defer q.mu.Unlock()
|
||||
|
||||
for {
|
||||
if n := len(q.front); n > 0 {
|
||||
e := q.front[n-1]
|
||||
q.front[n-1] = nil
|
||||
q.front = q.front[:n-1]
|
||||
return e
|
||||
}
|
||||
|
||||
if n := len(q.back); n > 0 {
|
||||
e := q.back[0]
|
||||
q.back[0] = nil
|
||||
q.back = q.back[1:]
|
||||
return e
|
||||
}
|
||||
|
||||
q.cond.Wait()
|
||||
}
|
||||
}
|
||||
|
||||
// Send implements the screen.EventDeque interface.
|
||||
func (q *Deque) Send(event interface{}) {
|
||||
q.lockAndInit()
|
||||
defer q.mu.Unlock()
|
||||
|
||||
q.back = append(q.back, event)
|
||||
q.cond.Signal()
|
||||
}
|
||||
|
||||
// SendFirst implements the screen.EventDeque interface.
|
||||
func (q *Deque) SendFirst(event interface{}) {
|
||||
q.lockAndInit()
|
||||
defer q.mu.Unlock()
|
||||
|
||||
q.front = append(q.front, event)
|
||||
q.cond.Signal()
|
||||
}
|
||||
80
vendor/golang.org/x/exp/shiny/driver/internal/lifecycler/lifecycler.go
generated
vendored
Normal file
80
vendor/golang.org/x/exp/shiny/driver/internal/lifecycler/lifecycler.go
generated
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package lifecycler tracks a window's lifecycle state.
|
||||
//
|
||||
// It eliminates sending redundant lifecycle events, ones where the From and To
|
||||
// stages are equal. For example, moving a window from one part of the screen
|
||||
// to another should not send multiple events from StageVisible to
|
||||
// StageVisible, even though the underlying window system's message might only
|
||||
// hold the new position, and not whether the window was previously visible.
|
||||
package lifecycler // import "golang.org/x/exp/shiny/driver/internal/lifecycler"
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"golang.org/x/mobile/event/lifecycle"
|
||||
)
|
||||
|
||||
// State is a window's lifecycle state.
|
||||
type State struct {
|
||||
mu sync.Mutex
|
||||
stage lifecycle.Stage
|
||||
dead bool
|
||||
focused bool
|
||||
visible bool
|
||||
}
|
||||
|
||||
func (s *State) SetDead(b bool) {
|
||||
s.mu.Lock()
|
||||
s.dead = b
|
||||
s.mu.Unlock()
|
||||
}
|
||||
|
||||
func (s *State) SetFocused(b bool) {
|
||||
s.mu.Lock()
|
||||
s.focused = b
|
||||
s.mu.Unlock()
|
||||
}
|
||||
|
||||
func (s *State) SetVisible(b bool) {
|
||||
s.mu.Lock()
|
||||
s.visible = b
|
||||
s.mu.Unlock()
|
||||
}
|
||||
|
||||
func (s *State) SendEvent(r Sender, drawContext interface{}) {
|
||||
s.mu.Lock()
|
||||
from, to := s.stage, lifecycle.StageAlive
|
||||
// The order of these if's is important. For example, once a window becomes
|
||||
// StageDead, it should never change stage again.
|
||||
//
|
||||
// Similarly, focused trumps visible. It's hard to imagine a situation
|
||||
// where a window is focused and not visible on screen, but in that
|
||||
// unlikely case, StageFocused seems the most appropriate stage.
|
||||
if s.dead {
|
||||
to = lifecycle.StageDead
|
||||
} else if s.focused {
|
||||
to = lifecycle.StageFocused
|
||||
} else if s.visible {
|
||||
to = lifecycle.StageVisible
|
||||
}
|
||||
s.stage = to
|
||||
s.mu.Unlock()
|
||||
|
||||
if from != to {
|
||||
r.Send(lifecycle.Event{
|
||||
From: from,
|
||||
To: to,
|
||||
|
||||
// TODO: does shiny use this at all?
|
||||
DrawContext: drawContext,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Sender is who to send the lifecycle event to.
|
||||
type Sender interface {
|
||||
Send(event interface{})
|
||||
}
|
||||
350
vendor/golang.org/x/exp/shiny/driver/internal/win32/key.go
generated
vendored
Normal file
350
vendor/golang.org/x/exp/shiny/driver/internal/win32/key.go
generated
vendored
Normal file
@@ -0,0 +1,350 @@
|
||||
// Copyright 2015 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build windows
|
||||
|
||||
package win32
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"syscall"
|
||||
"unicode/utf16"
|
||||
|
||||
"golang.org/x/mobile/event/key"
|
||||
)
|
||||
|
||||
// convVirtualKeyCode converts a Win32 virtual key code number
|
||||
// into the standard keycodes used by the key package.
|
||||
func convVirtualKeyCode(vKey uint32) key.Code {
|
||||
switch vKey {
|
||||
case 0x01: // VK_LBUTTON left mouse button
|
||||
case 0x02: // VK_RBUTTON right mouse button
|
||||
case 0x03: // VK_CANCEL control-break processing
|
||||
case 0x04: // VK_MBUTTON middle mouse button
|
||||
case 0x05: // VK_XBUTTON1 X1 mouse button
|
||||
case 0x06: // VK_XBUTTON2 X2 mouse button
|
||||
case 0x08: // VK_BACK
|
||||
return key.CodeDeleteBackspace
|
||||
case 0x09: // VK_TAB
|
||||
return key.CodeTab
|
||||
case 0x0C: // VK_CLEAR
|
||||
case 0x0D: // VK_RETURN
|
||||
return key.CodeReturnEnter
|
||||
case 0x10: // VK_SHIFT
|
||||
return key.CodeLeftShift
|
||||
case 0x11: // VK_CONTROL
|
||||
return key.CodeLeftControl
|
||||
case 0x12: // VK_MENU
|
||||
return key.CodeLeftAlt
|
||||
case 0x13: // VK_PAUSE
|
||||
case 0x14: // VK_CAPITAL
|
||||
return key.CodeCapsLock
|
||||
case 0x15: // VK_KANA, VK_HANGUEL, VK_HANGUL
|
||||
case 0x17: // VK_JUNJA
|
||||
case 0x18: // VK_FINA, L
|
||||
case 0x19: // VK_HANJA, VK_KANJI
|
||||
case 0x1B: // VK_ESCAPE
|
||||
return key.CodeEscape
|
||||
case 0x1C: // VK_CONVERT
|
||||
case 0x1D: // VK_NONCONVERT
|
||||
case 0x1E: // VK_ACCEPT
|
||||
case 0x1F: // VK_MODECHANGE
|
||||
case 0x20: // VK_SPACE
|
||||
return key.CodeSpacebar
|
||||
case 0x21: // VK_PRIOR
|
||||
return key.CodePageUp
|
||||
case 0x22: // VK_NEXT
|
||||
return key.CodePageDown
|
||||
case 0x23: // VK_END
|
||||
return key.CodeEnd
|
||||
case 0x24: // VK_HOME
|
||||
return key.CodeHome
|
||||
case 0x25: // VK_LEFT
|
||||
return key.CodeLeftArrow
|
||||
case 0x26: // VK_UP
|
||||
return key.CodeUpArrow
|
||||
case 0x27: // VK_RIGHT
|
||||
return key.CodeRightArrow
|
||||
case 0x28: // VK_DOWN
|
||||
return key.CodeDownArrow
|
||||
case 0x29: // VK_SELECT
|
||||
case 0x2A: // VK_PRINT
|
||||
case 0x2B: // VK_EXECUTE
|
||||
case 0x2C: // VK_SNAPSHOT
|
||||
case 0x2D: // VK_INSERT
|
||||
case 0x2E: // VK_DELETE
|
||||
return key.CodeDeleteForward
|
||||
case 0x2F: // VK_HELP
|
||||
return key.CodeHelp
|
||||
case 0x30:
|
||||
return key.Code0
|
||||
case 0x31:
|
||||
return key.Code1
|
||||
case 0x32:
|
||||
return key.Code2
|
||||
case 0x33:
|
||||
return key.Code3
|
||||
case 0x34:
|
||||
return key.Code4
|
||||
case 0x35:
|
||||
return key.Code5
|
||||
case 0x36:
|
||||
return key.Code6
|
||||
case 0x37:
|
||||
return key.Code7
|
||||
case 0x38:
|
||||
return key.Code8
|
||||
case 0x39:
|
||||
return key.Code9
|
||||
case 0x41:
|
||||
return key.CodeA
|
||||
case 0x42:
|
||||
return key.CodeB
|
||||
case 0x43:
|
||||
return key.CodeC
|
||||
case 0x44:
|
||||
return key.CodeD
|
||||
case 0x45:
|
||||
return key.CodeE
|
||||
case 0x46:
|
||||
return key.CodeF
|
||||
case 0x47:
|
||||
return key.CodeG
|
||||
case 0x48:
|
||||
return key.CodeH
|
||||
case 0x49:
|
||||
return key.CodeI
|
||||
case 0x4A:
|
||||
return key.CodeJ
|
||||
case 0x4B:
|
||||
return key.CodeK
|
||||
case 0x4C:
|
||||
return key.CodeL
|
||||
case 0x4D:
|
||||
return key.CodeM
|
||||
case 0x4E:
|
||||
return key.CodeN
|
||||
case 0x4F:
|
||||
return key.CodeO
|
||||
case 0x50:
|
||||
return key.CodeP
|
||||
case 0x51:
|
||||
return key.CodeQ
|
||||
case 0x52:
|
||||
return key.CodeR
|
||||
case 0x53:
|
||||
return key.CodeS
|
||||
case 0x54:
|
||||
return key.CodeT
|
||||
case 0x55:
|
||||
return key.CodeU
|
||||
case 0x56:
|
||||
return key.CodeV
|
||||
case 0x57:
|
||||
return key.CodeW
|
||||
case 0x58:
|
||||
return key.CodeX
|
||||
case 0x59:
|
||||
return key.CodeY
|
||||
case 0x5A:
|
||||
return key.CodeZ
|
||||
case 0x5B: // VK_LWIN
|
||||
return key.CodeLeftGUI
|
||||
case 0x5C: // VK_RWIN
|
||||
return key.CodeRightGUI
|
||||
case 0x5D: // VK_APPS
|
||||
case 0x5F: // VK_SLEEP
|
||||
case 0x60: // VK_NUMPAD0
|
||||
return key.CodeKeypad0
|
||||
case 0x61: // VK_NUMPAD1
|
||||
return key.CodeKeypad1
|
||||
case 0x62: // VK_NUMPAD2
|
||||
return key.CodeKeypad2
|
||||
case 0x63: // VK_NUMPAD3
|
||||
return key.CodeKeypad3
|
||||
case 0x64: // VK_NUMPAD4
|
||||
return key.CodeKeypad4
|
||||
case 0x65: // VK_NUMPAD5
|
||||
return key.CodeKeypad5
|
||||
case 0x66: // VK_NUMPAD6
|
||||
return key.CodeKeypad6
|
||||
case 0x67: // VK_NUMPAD7
|
||||
return key.CodeKeypad7
|
||||
case 0x68: // VK_NUMPAD8
|
||||
return key.CodeKeypad8
|
||||
case 0x69: // VK_NUMPAD9
|
||||
return key.CodeKeypad9
|
||||
case 0x6A: // VK_MULTIPLY
|
||||
return key.CodeKeypadAsterisk
|
||||
case 0x6B: // VK_ADD
|
||||
return key.CodeKeypadPlusSign
|
||||
case 0x6C: // VK_SEPARATOR
|
||||
case 0x6D: // VK_SUBTRACT
|
||||
return key.CodeKeypadHyphenMinus
|
||||
case 0x6E: // VK_DECIMAL
|
||||
return key.CodeFullStop
|
||||
case 0x6F: // VK_DIVIDE
|
||||
return key.CodeKeypadSlash
|
||||
case 0x70: // VK_F1
|
||||
return key.CodeF1
|
||||
case 0x71: // VK_F2
|
||||
return key.CodeF2
|
||||
case 0x72: // VK_F3
|
||||
return key.CodeF3
|
||||
case 0x73: // VK_F4
|
||||
return key.CodeF4
|
||||
case 0x74: // VK_F5
|
||||
return key.CodeF5
|
||||
case 0x75: // VK_F6
|
||||
return key.CodeF6
|
||||
case 0x76: // VK_F7
|
||||
return key.CodeF7
|
||||
case 0x77: // VK_F8
|
||||
return key.CodeF8
|
||||
case 0x78: // VK_F9
|
||||
return key.CodeF9
|
||||
case 0x79: // VK_F10
|
||||
return key.CodeF10
|
||||
case 0x7A: // VK_F11
|
||||
return key.CodeF11
|
||||
case 0x7B: // VK_F12
|
||||
return key.CodeF12
|
||||
case 0x7C: // VK_F13
|
||||
return key.CodeF13
|
||||
case 0x7D: // VK_F14
|
||||
return key.CodeF14
|
||||
case 0x7E: // VK_F15
|
||||
return key.CodeF15
|
||||
case 0x7F: // VK_F16
|
||||
return key.CodeF16
|
||||
case 0x80: // VK_F17
|
||||
return key.CodeF17
|
||||
case 0x81: // VK_F18
|
||||
return key.CodeF18
|
||||
case 0x82: // VK_F19
|
||||
return key.CodeF19
|
||||
case 0x83: // VK_F20
|
||||
return key.CodeF20
|
||||
case 0x84: // VK_F21
|
||||
return key.CodeF21
|
||||
case 0x85: // VK_F22
|
||||
return key.CodeF22
|
||||
case 0x86: // VK_F23
|
||||
return key.CodeF23
|
||||
case 0x87: // VK_F24
|
||||
return key.CodeF24
|
||||
case 0x90: // VK_NUMLOCK
|
||||
return key.CodeKeypadNumLock
|
||||
case 0x91: // VK_SCROLL
|
||||
case 0xA0: // VK_LSHIFT
|
||||
return key.CodeLeftShift
|
||||
case 0xA1: // VK_RSHIFT
|
||||
return key.CodeRightShift
|
||||
case 0xA2: // VK_LCONTROL
|
||||
return key.CodeLeftControl
|
||||
case 0xA3: // VK_RCONTROL
|
||||
return key.CodeRightControl
|
||||
case 0xA4: // VK_LMENU
|
||||
case 0xA5: // VK_RMENU
|
||||
case 0xA6: // VK_BROWSER_BACK
|
||||
case 0xA7: // VK_BROWSER_FORWARD
|
||||
case 0xA8: // VK_BROWSER_REFRESH
|
||||
case 0xA9: // VK_BROWSER_STOP
|
||||
case 0xAA: // VK_BROWSER_SEARCH
|
||||
case 0xAB: // VK_BROWSER_FAVORITES
|
||||
case 0xAC: // VK_BROWSER_HOME
|
||||
case 0xAD: // VK_VOLUME_MUTE
|
||||
return key.CodeMute
|
||||
case 0xAE: // VK_VOLUME_DOWN
|
||||
return key.CodeVolumeDown
|
||||
case 0xAF: // VK_VOLUME_UP
|
||||
return key.CodeVolumeUp
|
||||
case 0xB0: // VK_MEDIA_NEXT_TRACK
|
||||
case 0xB1: // VK_MEDIA_PREV_TRACK
|
||||
case 0xB2: // VK_MEDIA_STOP
|
||||
case 0xB3: // VK_MEDIA_PLAY_PAUSE
|
||||
case 0xB4: // VK_LAUNCH_MAIL
|
||||
case 0xB5: // VK_LAUNCH_MEDIA_SELECT
|
||||
case 0xB6: // VK_LAUNCH_APP1
|
||||
case 0xB7: // VK_LAUNCH_APP2
|
||||
case 0xBA: // VK_OEM_1 ';:'
|
||||
return key.CodeSemicolon
|
||||
case 0xBB: // VK_OEM_PLUS '+'
|
||||
return key.CodeEqualSign
|
||||
case 0xBC: // VK_OEM_COMMA ','
|
||||
return key.CodeComma
|
||||
case 0xBD: // VK_OEM_MINUS '-'
|
||||
return key.CodeHyphenMinus
|
||||
case 0xBE: // VK_OEM_PERIOD '.'
|
||||
return key.CodeFullStop
|
||||
case 0xBF: // VK_OEM_2 '/?'
|
||||
return key.CodeSlash
|
||||
case 0xC0: // VK_OEM_3 '`~'
|
||||
return key.CodeGraveAccent
|
||||
case 0xDB: // VK_OEM_4 '[{'
|
||||
return key.CodeLeftSquareBracket
|
||||
case 0xDC: // VK_OEM_5 '\|'
|
||||
return key.CodeBackslash
|
||||
case 0xDD: // VK_OEM_6 ']}'
|
||||
return key.CodeRightSquareBracket
|
||||
case 0xDE: // VK_OEM_7 'single-quote/double-quote'
|
||||
return key.CodeApostrophe
|
||||
case 0xDF: // VK_OEM_8
|
||||
return key.CodeUnknown
|
||||
case 0xE2: // VK_OEM_102
|
||||
case 0xE5: // VK_PROCESSKEY
|
||||
case 0xE7: // VK_PACKET
|
||||
case 0xF6: // VK_ATTN
|
||||
case 0xF7: // VK_CRSEL
|
||||
case 0xF8: // VK_EXSEL
|
||||
case 0xF9: // VK_EREOF
|
||||
case 0xFA: // VK_PLAY
|
||||
case 0xFB: // VK_ZOOM
|
||||
case 0xFC: // VK_NONAME
|
||||
case 0xFD: // VK_PA1
|
||||
case 0xFE: // VK_OEM_CLEAR
|
||||
}
|
||||
return key.CodeUnknown
|
||||
}
|
||||
|
||||
func readRune(vKey uint32, scanCode uint8) rune {
|
||||
var (
|
||||
keystate [256]byte
|
||||
buf [4]uint16
|
||||
)
|
||||
if err := _GetKeyboardState(&keystate[0]); err != nil {
|
||||
panic(fmt.Sprintf("win32: %v", err))
|
||||
}
|
||||
// TODO: cache GetKeyboardLayout result, update on WM_INPUTLANGCHANGE
|
||||
layout := _GetKeyboardLayout(0)
|
||||
ret := _ToUnicodeEx(vKey, uint32(scanCode), &keystate[0], &buf[0], int32(len(buf)), 0, layout)
|
||||
if ret < 1 {
|
||||
return -1
|
||||
}
|
||||
return utf16.Decode(buf[:ret])[0]
|
||||
}
|
||||
|
||||
func sendKeyEvent(hwnd syscall.Handle, uMsg uint32, wParam, lParam uintptr) (lResult uintptr) {
|
||||
e := key.Event{
|
||||
Rune: readRune(uint32(wParam), uint8(lParam>>16)),
|
||||
Code: convVirtualKeyCode(uint32(wParam)),
|
||||
Modifiers: keyModifiers(),
|
||||
}
|
||||
switch uMsg {
|
||||
case _WM_KEYDOWN, _WM_SYSKEYDOWN:
|
||||
const prevMask = 1 << 30
|
||||
if repeat := lParam&prevMask == prevMask; repeat {
|
||||
e.Direction = key.DirNone
|
||||
} else {
|
||||
e.Direction = key.DirPress
|
||||
}
|
||||
case _WM_KEYUP, _WM_SYSKEYUP:
|
||||
e.Direction = key.DirRelease
|
||||
default:
|
||||
panic(fmt.Sprintf("win32: unexpected key message: %d", uMsg))
|
||||
}
|
||||
|
||||
KeyEvent(hwnd, e)
|
||||
return 0
|
||||
}
|
||||
7
vendor/golang.org/x/exp/shiny/driver/internal/win32/syscall.go
generated
vendored
Normal file
7
vendor/golang.org/x/exp/shiny/driver/internal/win32/syscall.go
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
// Copyright 2015 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:generate go run $GOROOT/src/syscall/mksyscall_windows.go -output zsyscall_windows.go syscall_windows.go
|
||||
|
||||
package win32
|
||||
186
vendor/golang.org/x/exp/shiny/driver/internal/win32/syscall_windows.go
generated
vendored
Normal file
186
vendor/golang.org/x/exp/shiny/driver/internal/win32/syscall_windows.go
generated
vendored
Normal file
@@ -0,0 +1,186 @@
|
||||
// Copyright 2015 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package win32
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
)
|
||||
|
||||
type _COLORREF uint32
|
||||
|
||||
func _RGB(r, g, b byte) _COLORREF {
|
||||
return _COLORREF(r) | _COLORREF(g)<<8 | _COLORREF(b)<<16
|
||||
}
|
||||
|
||||
type _POINT struct {
|
||||
X int32
|
||||
Y int32
|
||||
}
|
||||
|
||||
type _RECT struct {
|
||||
Left int32
|
||||
Top int32
|
||||
Right int32
|
||||
Bottom int32
|
||||
}
|
||||
|
||||
type _MSG struct {
|
||||
HWND syscall.Handle
|
||||
Message uint32
|
||||
Wparam uintptr
|
||||
Lparam uintptr
|
||||
Time uint32
|
||||
Pt _POINT
|
||||
}
|
||||
|
||||
type _WNDCLASS struct {
|
||||
Style uint32
|
||||
LpfnWndProc uintptr
|
||||
CbClsExtra int32
|
||||
CbWndExtra int32
|
||||
HInstance syscall.Handle
|
||||
HIcon syscall.Handle
|
||||
HCursor syscall.Handle
|
||||
HbrBackground syscall.Handle
|
||||
LpszMenuName *uint16
|
||||
LpszClassName *uint16
|
||||
}
|
||||
|
||||
type _WINDOWPOS struct {
|
||||
HWND syscall.Handle
|
||||
HWNDInsertAfter syscall.Handle
|
||||
X int32
|
||||
Y int32
|
||||
Cx int32
|
||||
Cy int32
|
||||
Flags uint32
|
||||
}
|
||||
|
||||
const (
|
||||
_WM_SETFOCUS = 7
|
||||
_WM_KILLFOCUS = 8
|
||||
_WM_PAINT = 15
|
||||
_WM_CLOSE = 16
|
||||
_WM_WINDOWPOSCHANGED = 71
|
||||
_WM_KEYDOWN = 256
|
||||
_WM_KEYUP = 257
|
||||
_WM_SYSKEYDOWN = 260
|
||||
_WM_SYSKEYUP = 261
|
||||
_WM_MOUSEMOVE = 512
|
||||
_WM_MOUSEWHEEL = 522
|
||||
_WM_LBUTTONDOWN = 513
|
||||
_WM_LBUTTONUP = 514
|
||||
_WM_RBUTTONDOWN = 516
|
||||
_WM_RBUTTONUP = 517
|
||||
_WM_MBUTTONDOWN = 519
|
||||
_WM_MBUTTONUP = 520
|
||||
_WM_USER = 0x0400
|
||||
)
|
||||
|
||||
const (
|
||||
_WS_OVERLAPPED = 0x00000000
|
||||
_WS_CAPTION = 0x00C00000
|
||||
_WS_SYSMENU = 0x00080000
|
||||
_WS_THICKFRAME = 0x00040000
|
||||
_WS_MINIMIZEBOX = 0x00020000
|
||||
_WS_MAXIMIZEBOX = 0x00010000
|
||||
_WS_OVERLAPPEDWINDOW = _WS_OVERLAPPED | _WS_CAPTION | _WS_SYSMENU | _WS_THICKFRAME | _WS_MINIMIZEBOX | _WS_MAXIMIZEBOX
|
||||
)
|
||||
|
||||
const (
|
||||
_VK_SHIFT = 16
|
||||
_VK_CONTROL = 17
|
||||
_VK_MENU = 18
|
||||
_VK_LWIN = 0x5B
|
||||
_VK_RWIN = 0x5C
|
||||
)
|
||||
|
||||
const (
|
||||
_MK_LBUTTON = 0x0001
|
||||
_MK_MBUTTON = 0x0010
|
||||
_MK_RBUTTON = 0x0002
|
||||
)
|
||||
|
||||
const (
|
||||
_COLOR_BTNFACE = 15
|
||||
)
|
||||
|
||||
const (
|
||||
_IDI_APPLICATION = 32512
|
||||
_IDC_ARROW = 32512
|
||||
)
|
||||
|
||||
const (
|
||||
_CW_USEDEFAULT = 0x80000000 - 0x100000000
|
||||
|
||||
_SW_SHOWDEFAULT = 10
|
||||
|
||||
_HWND_MESSAGE = syscall.Handle(^uintptr(2)) // -3
|
||||
|
||||
_SWP_NOSIZE = 0x0001
|
||||
)
|
||||
|
||||
const (
|
||||
_BI_RGB = 0
|
||||
_DIB_RGB_COLORS = 0
|
||||
|
||||
_AC_SRC_OVER = 0x00
|
||||
_AC_SRC_ALPHA = 0x01
|
||||
|
||||
_SRCCOPY = 0x00cc0020
|
||||
|
||||
_WHEEL_DELTA = 120
|
||||
)
|
||||
|
||||
func _GET_X_LPARAM(lp uintptr) int32 {
|
||||
return int32(_LOWORD(lp))
|
||||
}
|
||||
|
||||
func _GET_Y_LPARAM(lp uintptr) int32 {
|
||||
return int32(_HIWORD(lp))
|
||||
}
|
||||
|
||||
func _GET_WHEEL_DELTA_WPARAM(lp uintptr) int16 {
|
||||
return int16(_HIWORD(lp))
|
||||
}
|
||||
|
||||
func _LOWORD(l uintptr) uint16 {
|
||||
return uint16(uint32(l))
|
||||
}
|
||||
|
||||
func _HIWORD(l uintptr) uint16 {
|
||||
return uint16(uint32(l >> 16))
|
||||
}
|
||||
|
||||
// notes to self
|
||||
// UINT = uint32
|
||||
// callbacks = uintptr
|
||||
// strings = *uint16
|
||||
|
||||
//sys GetDC(hwnd syscall.Handle) (dc syscall.Handle, err error) = user32.GetDC
|
||||
//sys ReleaseDC(hwnd syscall.Handle, dc syscall.Handle) (err error) = user32.ReleaseDC
|
||||
//sys sendMessage(hwnd syscall.Handle, uMsg uint32, wParam uintptr, lParam uintptr) (lResult uintptr) = user32.SendMessageW
|
||||
|
||||
//sys _CreateWindowEx(exstyle uint32, className *uint16, windowText *uint16, style uint32, x int32, y int32, width int32, height int32, parent syscall.Handle, menu syscall.Handle, hInstance syscall.Handle, lpParam uintptr) (hwnd syscall.Handle, err error) = user32.CreateWindowExW
|
||||
//sys _DefWindowProc(hwnd syscall.Handle, uMsg uint32, wParam uintptr, lParam uintptr) (lResult uintptr) = user32.DefWindowProcW
|
||||
//sys _DestroyWindow(hwnd syscall.Handle) (err error) = user32.DestroyWindow
|
||||
//sys _DispatchMessage(msg *_MSG) (ret int32) = user32.DispatchMessageW
|
||||
//sys _GetClientRect(hwnd syscall.Handle, rect *_RECT) (err error) = user32.GetClientRect
|
||||
//sys _GetWindowRect(hwnd syscall.Handle, rect *_RECT) (err error) = user32.GetWindowRect
|
||||
//sys _GetKeyboardLayout(threadID uint32) (locale syscall.Handle) = user32.GetKeyboardLayout
|
||||
//sys _GetKeyboardState(lpKeyState *byte) (err error) = user32.GetKeyboardState
|
||||
//sys _GetKeyState(virtkey int32) (keystatus int16) = user32.GetKeyState
|
||||
//sys _GetMessage(msg *_MSG, hwnd syscall.Handle, msgfiltermin uint32, msgfiltermax uint32) (ret int32, err error) [failretval==-1] = user32.GetMessageW
|
||||
//sys _LoadCursor(hInstance syscall.Handle, cursorName uintptr) (cursor syscall.Handle, err error) = user32.LoadCursorW
|
||||
//sys _LoadIcon(hInstance syscall.Handle, iconName uintptr) (icon syscall.Handle, err error) = user32.LoadIconW
|
||||
//sys _MoveWindow(hwnd syscall.Handle, x int32, y int32, w int32, h int32, repaint bool) (err error) = user32.MoveWindow
|
||||
//sys _PostMessage(hwnd syscall.Handle, uMsg uint32, wParam uintptr, lParam uintptr) (lResult bool) = user32.PostMessageW
|
||||
//sys _PostQuitMessage(exitCode int32) = user32.PostQuitMessage
|
||||
//sys _RegisterClass(wc *_WNDCLASS) (atom uint16, err error) = user32.RegisterClassW
|
||||
//sys _ShowWindow(hwnd syscall.Handle, cmdshow int32) (wasvisible bool) = user32.ShowWindow
|
||||
//sys _ScreenToClient(hwnd syscall.Handle, lpPoint *_POINT) (ok bool) = user32.ScreenToClient
|
||||
//sys _ToUnicodeEx(wVirtKey uint32, wScanCode uint32, lpKeyState *byte, pwszBuff *uint16, cchBuff int32, wFlags uint32, dwhkl syscall.Handle) (ret int32) = user32.ToUnicodeEx
|
||||
//sys _TranslateMessage(msg *_MSG) (done bool) = user32.TranslateMessage
|
||||
//sys _UnregisterClass(lpClassName *uint16, hInstance syscall.Handle) (done bool) = user32.UnregisterClassW
|
||||
519
vendor/golang.org/x/exp/shiny/driver/internal/win32/win32.go
generated
vendored
Normal file
519
vendor/golang.org/x/exp/shiny/driver/internal/win32/win32.go
generated
vendored
Normal file
@@ -0,0 +1,519 @@
|
||||
// Copyright 2015 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build windows
|
||||
|
||||
// Package win32 implements a partial shiny screen driver using the Win32 API.
|
||||
// It provides window, lifecycle, key, and mouse management, but no drawing.
|
||||
// That is left to windriver (using GDI) or gldriver (using DirectX via ANGLE).
|
||||
package win32 // import "golang.org/x/exp/shiny/driver/internal/win32"
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"runtime"
|
||||
"sync"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/exp/shiny/screen"
|
||||
"golang.org/x/mobile/event/key"
|
||||
"golang.org/x/mobile/event/lifecycle"
|
||||
"golang.org/x/mobile/event/mouse"
|
||||
"golang.org/x/mobile/event/paint"
|
||||
"golang.org/x/mobile/event/size"
|
||||
"golang.org/x/mobile/geom"
|
||||
)
|
||||
|
||||
// screenHWND is the handle to the "Screen window".
|
||||
// The Screen window encapsulates all screen.Screen operations
|
||||
// in an actual Windows window so they all run on the main thread.
|
||||
// Since any messages sent to a window will be executed on the
|
||||
// main thread, we can safely use the messages below.
|
||||
var screenHWND syscall.Handle
|
||||
|
||||
const (
|
||||
msgCreateWindow = _WM_USER + iota
|
||||
msgMainCallback
|
||||
msgShow
|
||||
msgQuit
|
||||
msgLast
|
||||
)
|
||||
|
||||
// userWM is used to generate private (WM_USER and above) window message IDs
|
||||
// for use by screenWindowWndProc and windowWndProc.
|
||||
type userWM struct {
|
||||
sync.Mutex
|
||||
id uint32
|
||||
}
|
||||
|
||||
func (m *userWM) next() uint32 {
|
||||
m.Lock()
|
||||
if m.id == 0 {
|
||||
m.id = msgLast
|
||||
}
|
||||
r := m.id
|
||||
m.id++
|
||||
m.Unlock()
|
||||
return r
|
||||
}
|
||||
|
||||
var currentUserWM userWM
|
||||
|
||||
func newWindow(opts *screen.NewWindowOptions) (syscall.Handle, error) {
|
||||
// TODO(brainman): convert windowClass to *uint16 once (in initWindowClass)
|
||||
wcname, err := syscall.UTF16PtrFromString(windowClass)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
title, err := syscall.UTF16PtrFromString(opts.GetTitle())
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
hwnd, err := _CreateWindowEx(0,
|
||||
wcname, title,
|
||||
_WS_OVERLAPPEDWINDOW,
|
||||
_CW_USEDEFAULT, _CW_USEDEFAULT,
|
||||
_CW_USEDEFAULT, _CW_USEDEFAULT,
|
||||
0, 0, hThisInstance, 0)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
// TODO(andlabs): use proper nCmdShow
|
||||
// TODO(andlabs): call UpdateWindow()
|
||||
|
||||
return hwnd, nil
|
||||
}
|
||||
|
||||
// ResizeClientRect makes hwnd client rectangle opts.Width by opts.Height in size.
|
||||
func ResizeClientRect(hwnd syscall.Handle, opts *screen.NewWindowOptions) error {
|
||||
if opts == nil || opts.Width <= 0 || opts.Height <= 0 {
|
||||
return nil
|
||||
}
|
||||
var cr, wr _RECT
|
||||
err := _GetClientRect(hwnd, &cr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = _GetWindowRect(hwnd, &wr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
w := (wr.Right - wr.Left) - (cr.Right - int32(opts.Width))
|
||||
h := (wr.Bottom - wr.Top) - (cr.Bottom - int32(opts.Height))
|
||||
return _MoveWindow(hwnd, wr.Left, wr.Top, w, h, false)
|
||||
}
|
||||
|
||||
// Show shows a newly created window.
|
||||
// It sends the appropriate lifecycle events, makes the window appear
|
||||
// on the screen, and sends an initial size event.
|
||||
//
|
||||
// This is a separate step from NewWindow to give the driver a chance
|
||||
// to setup its internal state for a window before events start being
|
||||
// delivered.
|
||||
func Show(hwnd syscall.Handle) {
|
||||
SendMessage(hwnd, msgShow, 0, 0)
|
||||
}
|
||||
|
||||
func Release(hwnd syscall.Handle) {
|
||||
SendMessage(hwnd, _WM_CLOSE, 0, 0)
|
||||
}
|
||||
|
||||
func sendFocus(hwnd syscall.Handle, uMsg uint32, wParam, lParam uintptr) (lResult uintptr) {
|
||||
switch uMsg {
|
||||
case _WM_SETFOCUS:
|
||||
LifecycleEvent(hwnd, lifecycle.StageFocused)
|
||||
case _WM_KILLFOCUS:
|
||||
LifecycleEvent(hwnd, lifecycle.StageVisible)
|
||||
default:
|
||||
panic(fmt.Sprintf("unexpected focus message: %d", uMsg))
|
||||
}
|
||||
return _DefWindowProc(hwnd, uMsg, wParam, lParam)
|
||||
}
|
||||
|
||||
func sendShow(hwnd syscall.Handle, uMsg uint32, wParam, lParam uintptr) (lResult uintptr) {
|
||||
LifecycleEvent(hwnd, lifecycle.StageVisible)
|
||||
_ShowWindow(hwnd, _SW_SHOWDEFAULT)
|
||||
sendSize(hwnd)
|
||||
return 0
|
||||
}
|
||||
|
||||
func sendSizeEvent(hwnd syscall.Handle, uMsg uint32, wParam, lParam uintptr) (lResult uintptr) {
|
||||
wp := (*_WINDOWPOS)(unsafe.Pointer(lParam))
|
||||
if wp.Flags&_SWP_NOSIZE != 0 {
|
||||
return 0
|
||||
}
|
||||
sendSize(hwnd)
|
||||
return 0
|
||||
}
|
||||
|
||||
func sendSize(hwnd syscall.Handle) {
|
||||
var r _RECT
|
||||
if err := _GetClientRect(hwnd, &r); err != nil {
|
||||
panic(err) // TODO(andlabs)
|
||||
}
|
||||
|
||||
width := int(r.Right - r.Left)
|
||||
height := int(r.Bottom - r.Top)
|
||||
|
||||
// TODO(andlabs): don't assume that PixelsPerPt == 1
|
||||
SizeEvent(hwnd, size.Event{
|
||||
WidthPx: width,
|
||||
HeightPx: height,
|
||||
WidthPt: geom.Pt(width),
|
||||
HeightPt: geom.Pt(height),
|
||||
PixelsPerPt: 1,
|
||||
})
|
||||
}
|
||||
|
||||
func sendClose(hwnd syscall.Handle, uMsg uint32, wParam, lParam uintptr) (lResult uintptr) {
|
||||
// TODO(ktye): DefWindowProc calls DestroyWindow by default.
|
||||
// To intercept destruction of the window, return 0 and call
|
||||
// DestroyWindow when appropriate.
|
||||
LifecycleEvent(hwnd, lifecycle.StageDead)
|
||||
return _DefWindowProc(hwnd, uMsg, wParam, lParam)
|
||||
}
|
||||
|
||||
func sendMouseEvent(hwnd syscall.Handle, uMsg uint32, wParam, lParam uintptr) (lResult uintptr) {
|
||||
e := mouse.Event{
|
||||
X: float32(_GET_X_LPARAM(lParam)),
|
||||
Y: float32(_GET_Y_LPARAM(lParam)),
|
||||
Modifiers: keyModifiers(),
|
||||
}
|
||||
|
||||
switch uMsg {
|
||||
case _WM_MOUSEMOVE:
|
||||
e.Direction = mouse.DirNone
|
||||
case _WM_LBUTTONDOWN, _WM_MBUTTONDOWN, _WM_RBUTTONDOWN:
|
||||
e.Direction = mouse.DirPress
|
||||
case _WM_LBUTTONUP, _WM_MBUTTONUP, _WM_RBUTTONUP:
|
||||
e.Direction = mouse.DirRelease
|
||||
case _WM_MOUSEWHEEL:
|
||||
// TODO: On a trackpad, a scroll can be a drawn-out affair with a
|
||||
// distinct beginning and end. Should the intermediate events be
|
||||
// DirNone?
|
||||
e.Direction = mouse.DirStep
|
||||
|
||||
// Convert from screen to window coordinates.
|
||||
p := _POINT{
|
||||
int32(e.X),
|
||||
int32(e.Y),
|
||||
}
|
||||
_ScreenToClient(hwnd, &p)
|
||||
e.X = float32(p.X)
|
||||
e.Y = float32(p.Y)
|
||||
default:
|
||||
panic("sendMouseEvent() called on non-mouse message")
|
||||
}
|
||||
|
||||
switch uMsg {
|
||||
case _WM_MOUSEMOVE:
|
||||
// No-op.
|
||||
case _WM_LBUTTONDOWN, _WM_LBUTTONUP:
|
||||
e.Button = mouse.ButtonLeft
|
||||
case _WM_MBUTTONDOWN, _WM_MBUTTONUP:
|
||||
e.Button = mouse.ButtonMiddle
|
||||
case _WM_RBUTTONDOWN, _WM_RBUTTONUP:
|
||||
e.Button = mouse.ButtonRight
|
||||
case _WM_MOUSEWHEEL:
|
||||
// TODO: handle horizontal scrolling
|
||||
delta := _GET_WHEEL_DELTA_WPARAM(wParam) / _WHEEL_DELTA
|
||||
switch {
|
||||
case delta > 0:
|
||||
e.Button = mouse.ButtonWheelUp
|
||||
case delta < 0:
|
||||
e.Button = mouse.ButtonWheelDown
|
||||
delta = -delta
|
||||
default:
|
||||
return
|
||||
}
|
||||
for delta > 0 {
|
||||
MouseEvent(hwnd, e)
|
||||
delta--
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
MouseEvent(hwnd, e)
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
// Precondition: this is called in immediate response to the message that triggered the event (so not after w.Send).
|
||||
func keyModifiers() (m key.Modifiers) {
|
||||
down := func(x int32) bool {
|
||||
// GetKeyState gets the key state at the time of the message, so this is what we want.
|
||||
return _GetKeyState(x)&0x80 != 0
|
||||
}
|
||||
|
||||
if down(_VK_CONTROL) {
|
||||
m |= key.ModControl
|
||||
}
|
||||
if down(_VK_MENU) {
|
||||
m |= key.ModAlt
|
||||
}
|
||||
if down(_VK_SHIFT) {
|
||||
m |= key.ModShift
|
||||
}
|
||||
if down(_VK_LWIN) || down(_VK_RWIN) {
|
||||
m |= key.ModMeta
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
var (
|
||||
MouseEvent func(hwnd syscall.Handle, e mouse.Event)
|
||||
PaintEvent func(hwnd syscall.Handle, e paint.Event)
|
||||
SizeEvent func(hwnd syscall.Handle, e size.Event)
|
||||
KeyEvent func(hwnd syscall.Handle, e key.Event)
|
||||
LifecycleEvent func(hwnd syscall.Handle, e lifecycle.Stage)
|
||||
|
||||
// TODO: use the golang.org/x/exp/shiny/driver/internal/lifecycler package
|
||||
// instead of or together with the LifecycleEvent callback?
|
||||
)
|
||||
|
||||
func sendPaint(hwnd syscall.Handle, uMsg uint32, wParam, lParam uintptr) (lResult uintptr) {
|
||||
PaintEvent(hwnd, paint.Event{})
|
||||
return _DefWindowProc(hwnd, uMsg, wParam, lParam)
|
||||
}
|
||||
|
||||
var screenMsgs = map[uint32]func(hwnd syscall.Handle, uMsg uint32, wParam, lParam uintptr) (lResult uintptr){}
|
||||
|
||||
func AddScreenMsg(fn func(hwnd syscall.Handle, uMsg uint32, wParam, lParam uintptr)) uint32 {
|
||||
uMsg := currentUserWM.next()
|
||||
screenMsgs[uMsg] = func(hwnd syscall.Handle, uMsg uint32, wParam, lParam uintptr) uintptr {
|
||||
fn(hwnd, uMsg, wParam, lParam)
|
||||
return 0
|
||||
}
|
||||
return uMsg
|
||||
}
|
||||
|
||||
func screenWindowWndProc(hwnd syscall.Handle, uMsg uint32, wParam uintptr, lParam uintptr) (lResult uintptr) {
|
||||
switch uMsg {
|
||||
case msgCreateWindow:
|
||||
p := (*newWindowParams)(unsafe.Pointer(lParam))
|
||||
p.w, p.err = newWindow(p.opts)
|
||||
case msgMainCallback:
|
||||
go func() {
|
||||
mainCallback()
|
||||
SendScreenMessage(msgQuit, 0, 0)
|
||||
}()
|
||||
case msgQuit:
|
||||
_PostQuitMessage(0)
|
||||
}
|
||||
fn := screenMsgs[uMsg]
|
||||
if fn != nil {
|
||||
return fn(hwnd, uMsg, wParam, lParam)
|
||||
}
|
||||
return _DefWindowProc(hwnd, uMsg, wParam, lParam)
|
||||
}
|
||||
|
||||
//go:uintptrescapes
|
||||
|
||||
func SendScreenMessage(uMsg uint32, wParam uintptr, lParam uintptr) (lResult uintptr) {
|
||||
return SendMessage(screenHWND, uMsg, wParam, lParam)
|
||||
}
|
||||
|
||||
var windowMsgs = map[uint32]func(hwnd syscall.Handle, uMsg uint32, wParam, lParam uintptr) (lResult uintptr){
|
||||
_WM_SETFOCUS: sendFocus,
|
||||
_WM_KILLFOCUS: sendFocus,
|
||||
_WM_PAINT: sendPaint,
|
||||
msgShow: sendShow,
|
||||
_WM_WINDOWPOSCHANGED: sendSizeEvent,
|
||||
_WM_CLOSE: sendClose,
|
||||
|
||||
_WM_LBUTTONDOWN: sendMouseEvent,
|
||||
_WM_LBUTTONUP: sendMouseEvent,
|
||||
_WM_MBUTTONDOWN: sendMouseEvent,
|
||||
_WM_MBUTTONUP: sendMouseEvent,
|
||||
_WM_RBUTTONDOWN: sendMouseEvent,
|
||||
_WM_RBUTTONUP: sendMouseEvent,
|
||||
_WM_MOUSEMOVE: sendMouseEvent,
|
||||
_WM_MOUSEWHEEL: sendMouseEvent,
|
||||
|
||||
_WM_KEYDOWN: sendKeyEvent,
|
||||
_WM_KEYUP: sendKeyEvent,
|
||||
_WM_SYSKEYDOWN: sendKeyEvent,
|
||||
_WM_SYSKEYUP: sendKeyEvent,
|
||||
}
|
||||
|
||||
func AddWindowMsg(fn func(hwnd syscall.Handle, uMsg uint32, wParam, lParam uintptr)) uint32 {
|
||||
uMsg := currentUserWM.next()
|
||||
windowMsgs[uMsg] = func(hwnd syscall.Handle, uMsg uint32, wParam, lParam uintptr) uintptr {
|
||||
fn(hwnd, uMsg, wParam, lParam)
|
||||
return 0
|
||||
}
|
||||
return uMsg
|
||||
}
|
||||
|
||||
func windowWndProc(hwnd syscall.Handle, uMsg uint32, wParam uintptr, lParam uintptr) (lResult uintptr) {
|
||||
fn := windowMsgs[uMsg]
|
||||
if fn != nil {
|
||||
return fn(hwnd, uMsg, wParam, lParam)
|
||||
}
|
||||
return _DefWindowProc(hwnd, uMsg, wParam, lParam)
|
||||
}
|
||||
|
||||
type newWindowParams struct {
|
||||
opts *screen.NewWindowOptions
|
||||
w syscall.Handle
|
||||
err error
|
||||
}
|
||||
|
||||
func NewWindow(opts *screen.NewWindowOptions) (syscall.Handle, error) {
|
||||
var p newWindowParams
|
||||
p.opts = opts
|
||||
SendScreenMessage(msgCreateWindow, 0, uintptr(unsafe.Pointer(&p)))
|
||||
return p.w, p.err
|
||||
}
|
||||
|
||||
const windowClass = "shiny_Window"
|
||||
const screenWindowClass = "shiny_ScreenWindow"
|
||||
|
||||
func initWindowClass() (err error) {
|
||||
wcname, err := syscall.UTF16PtrFromString(windowClass)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = _RegisterClass(&_WNDCLASS{
|
||||
LpszClassName: wcname,
|
||||
LpfnWndProc: syscall.NewCallback(windowWndProc),
|
||||
HIcon: hDefaultIcon,
|
||||
HCursor: hDefaultCursor,
|
||||
HInstance: hThisInstance,
|
||||
// TODO(andlabs): change this to something else? NULL? the hollow brush?
|
||||
HbrBackground: syscall.Handle(_COLOR_BTNFACE + 1),
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
func closeWindowClass() (err error) {
|
||||
wcname, err := syscall.UTF16PtrFromString(windowClass)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_UnregisterClass(wcname, hThisInstance)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func initScreenWindow() (err error) {
|
||||
swc, err := syscall.UTF16PtrFromString(screenWindowClass)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
emptyString, err := syscall.UTF16PtrFromString("")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
wc := _WNDCLASS{
|
||||
LpszClassName: swc,
|
||||
LpfnWndProc: syscall.NewCallback(screenWindowWndProc),
|
||||
HIcon: hDefaultIcon,
|
||||
HCursor: hDefaultCursor,
|
||||
HInstance: hThisInstance,
|
||||
HbrBackground: syscall.Handle(_COLOR_BTNFACE + 1),
|
||||
}
|
||||
_, err = _RegisterClass(&wc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
screenHWND, err = _CreateWindowEx(0,
|
||||
swc, emptyString,
|
||||
_WS_OVERLAPPEDWINDOW,
|
||||
_CW_USEDEFAULT, _CW_USEDEFAULT,
|
||||
_CW_USEDEFAULT, _CW_USEDEFAULT,
|
||||
_HWND_MESSAGE, 0, hThisInstance, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func closeScreenWindow() (err error) {
|
||||
// first destroy window
|
||||
_DestroyWindow(screenHWND)
|
||||
|
||||
// then unregister class
|
||||
swc, err := syscall.UTF16PtrFromString(screenWindowClass)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_UnregisterClass(swc, hThisInstance)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
var (
|
||||
hDefaultIcon syscall.Handle
|
||||
hDefaultCursor syscall.Handle
|
||||
hThisInstance syscall.Handle
|
||||
)
|
||||
|
||||
func initCommon() (err error) {
|
||||
hDefaultIcon, err = _LoadIcon(0, _IDI_APPLICATION)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
hDefaultCursor, err = _LoadCursor(0, _IDC_ARROW)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// TODO(andlabs) hThisInstance
|
||||
return nil
|
||||
}
|
||||
|
||||
//go:uintptrescapes
|
||||
|
||||
func SendMessage(hwnd syscall.Handle, uMsg uint32, wParam uintptr, lParam uintptr) (lResult uintptr) {
|
||||
return sendMessage(hwnd, uMsg, wParam, lParam)
|
||||
}
|
||||
|
||||
var mainCallback func()
|
||||
|
||||
func Main(f func()) (retErr error) {
|
||||
// It does not matter which OS thread we are on.
|
||||
// All that matters is that we confine all UI operations
|
||||
// to the thread that created the respective window.
|
||||
runtime.LockOSThread()
|
||||
|
||||
if err := initCommon(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := initScreenWindow(); err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
// TODO(andlabs): log an error if this fails?
|
||||
closeScreenWindow()
|
||||
}()
|
||||
|
||||
if err := initWindowClass(); err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
// TODO(andlabs): log an error if this fails?
|
||||
closeWindowClass()
|
||||
}()
|
||||
|
||||
// Prime the pump.
|
||||
mainCallback = f
|
||||
_PostMessage(screenHWND, msgMainCallback, 0, 0)
|
||||
|
||||
// Main message pump.
|
||||
var m _MSG
|
||||
for {
|
||||
done, err := _GetMessage(&m, 0, 0, 0)
|
||||
if err != nil {
|
||||
return fmt.Errorf("win32 GetMessage failed: %v", err)
|
||||
}
|
||||
if done == 0 { // WM_QUIT
|
||||
break
|
||||
}
|
||||
_TranslateMessage(&m)
|
||||
_DispatchMessage(&m)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
293
vendor/golang.org/x/exp/shiny/driver/internal/win32/zsyscall_windows.go
generated
vendored
Normal file
293
vendor/golang.org/x/exp/shiny/driver/internal/win32/zsyscall_windows.go
generated
vendored
Normal file
@@ -0,0 +1,293 @@
|
||||
// MACHINE GENERATED BY 'go generate' COMMAND; DO NOT EDIT
|
||||
|
||||
package win32
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
var _ unsafe.Pointer
|
||||
|
||||
// Do the interface allocations only once for common
|
||||
// Errno values.
|
||||
const (
|
||||
errnoERROR_IO_PENDING = 997
|
||||
)
|
||||
|
||||
var (
|
||||
errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING)
|
||||
)
|
||||
|
||||
// errnoErr returns common boxed Errno values, to prevent
|
||||
// allocations at runtime.
|
||||
func errnoErr(e syscall.Errno) error {
|
||||
switch e {
|
||||
case 0:
|
||||
return nil
|
||||
case errnoERROR_IO_PENDING:
|
||||
return errERROR_IO_PENDING
|
||||
}
|
||||
// TODO: add more here, after collecting data on the common
|
||||
// error values see on Windows. (perhaps when running
|
||||
// all.bat?)
|
||||
return e
|
||||
}
|
||||
|
||||
var (
|
||||
moduser32 = windows.NewLazySystemDLL("user32.dll")
|
||||
|
||||
procGetDC = moduser32.NewProc("GetDC")
|
||||
procReleaseDC = moduser32.NewProc("ReleaseDC")
|
||||
procSendMessageW = moduser32.NewProc("SendMessageW")
|
||||
procCreateWindowExW = moduser32.NewProc("CreateWindowExW")
|
||||
procDefWindowProcW = moduser32.NewProc("DefWindowProcW")
|
||||
procDestroyWindow = moduser32.NewProc("DestroyWindow")
|
||||
procDispatchMessageW = moduser32.NewProc("DispatchMessageW")
|
||||
procGetClientRect = moduser32.NewProc("GetClientRect")
|
||||
procGetWindowRect = moduser32.NewProc("GetWindowRect")
|
||||
procGetKeyboardLayout = moduser32.NewProc("GetKeyboardLayout")
|
||||
procGetKeyboardState = moduser32.NewProc("GetKeyboardState")
|
||||
procGetKeyState = moduser32.NewProc("GetKeyState")
|
||||
procGetMessageW = moduser32.NewProc("GetMessageW")
|
||||
procLoadCursorW = moduser32.NewProc("LoadCursorW")
|
||||
procLoadIconW = moduser32.NewProc("LoadIconW")
|
||||
procMoveWindow = moduser32.NewProc("MoveWindow")
|
||||
procPostMessageW = moduser32.NewProc("PostMessageW")
|
||||
procPostQuitMessage = moduser32.NewProc("PostQuitMessage")
|
||||
procRegisterClassW = moduser32.NewProc("RegisterClassW")
|
||||
procShowWindow = moduser32.NewProc("ShowWindow")
|
||||
procScreenToClient = moduser32.NewProc("ScreenToClient")
|
||||
procToUnicodeEx = moduser32.NewProc("ToUnicodeEx")
|
||||
procTranslateMessage = moduser32.NewProc("TranslateMessage")
|
||||
procUnregisterClassW = moduser32.NewProc("UnregisterClassW")
|
||||
)
|
||||
|
||||
func GetDC(hwnd syscall.Handle) (dc syscall.Handle, err error) {
|
||||
r0, _, e1 := syscall.Syscall(procGetDC.Addr(), 1, uintptr(hwnd), 0, 0)
|
||||
dc = syscall.Handle(r0)
|
||||
if dc == 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func ReleaseDC(hwnd syscall.Handle, dc syscall.Handle) (err error) {
|
||||
r1, _, e1 := syscall.Syscall(procReleaseDC.Addr(), 2, uintptr(hwnd), uintptr(dc), 0)
|
||||
if r1 == 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func sendMessage(hwnd syscall.Handle, uMsg uint32, wParam uintptr, lParam uintptr) (lResult uintptr) {
|
||||
r0, _, _ := syscall.Syscall6(procSendMessageW.Addr(), 4, uintptr(hwnd), uintptr(uMsg), uintptr(wParam), uintptr(lParam), 0, 0)
|
||||
lResult = uintptr(r0)
|
||||
return
|
||||
}
|
||||
|
||||
func _CreateWindowEx(exstyle uint32, className *uint16, windowText *uint16, style uint32, x int32, y int32, width int32, height int32, parent syscall.Handle, menu syscall.Handle, hInstance syscall.Handle, lpParam uintptr) (hwnd syscall.Handle, err error) {
|
||||
r0, _, e1 := syscall.Syscall12(procCreateWindowExW.Addr(), 12, uintptr(exstyle), uintptr(unsafe.Pointer(className)), uintptr(unsafe.Pointer(windowText)), uintptr(style), uintptr(x), uintptr(y), uintptr(width), uintptr(height), uintptr(parent), uintptr(menu), uintptr(hInstance), uintptr(lpParam))
|
||||
hwnd = syscall.Handle(r0)
|
||||
if hwnd == 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func _DefWindowProc(hwnd syscall.Handle, uMsg uint32, wParam uintptr, lParam uintptr) (lResult uintptr) {
|
||||
r0, _, _ := syscall.Syscall6(procDefWindowProcW.Addr(), 4, uintptr(hwnd), uintptr(uMsg), uintptr(wParam), uintptr(lParam), 0, 0)
|
||||
lResult = uintptr(r0)
|
||||
return
|
||||
}
|
||||
|
||||
func _DestroyWindow(hwnd syscall.Handle) (err error) {
|
||||
r1, _, e1 := syscall.Syscall(procDestroyWindow.Addr(), 1, uintptr(hwnd), 0, 0)
|
||||
if r1 == 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func _DispatchMessage(msg *_MSG) (ret int32) {
|
||||
r0, _, _ := syscall.Syscall(procDispatchMessageW.Addr(), 1, uintptr(unsafe.Pointer(msg)), 0, 0)
|
||||
ret = int32(r0)
|
||||
return
|
||||
}
|
||||
|
||||
func _GetClientRect(hwnd syscall.Handle, rect *_RECT) (err error) {
|
||||
r1, _, e1 := syscall.Syscall(procGetClientRect.Addr(), 2, uintptr(hwnd), uintptr(unsafe.Pointer(rect)), 0)
|
||||
if r1 == 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func _GetWindowRect(hwnd syscall.Handle, rect *_RECT) (err error) {
|
||||
r1, _, e1 := syscall.Syscall(procGetWindowRect.Addr(), 2, uintptr(hwnd), uintptr(unsafe.Pointer(rect)), 0)
|
||||
if r1 == 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func _GetKeyboardLayout(threadID uint32) (locale syscall.Handle) {
|
||||
r0, _, _ := syscall.Syscall(procGetKeyboardLayout.Addr(), 1, uintptr(threadID), 0, 0)
|
||||
locale = syscall.Handle(r0)
|
||||
return
|
||||
}
|
||||
|
||||
func _GetKeyboardState(lpKeyState *byte) (err error) {
|
||||
r1, _, e1 := syscall.Syscall(procGetKeyboardState.Addr(), 1, uintptr(unsafe.Pointer(lpKeyState)), 0, 0)
|
||||
if r1 == 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func _GetKeyState(virtkey int32) (keystatus int16) {
|
||||
r0, _, _ := syscall.Syscall(procGetKeyState.Addr(), 1, uintptr(virtkey), 0, 0)
|
||||
keystatus = int16(r0)
|
||||
return
|
||||
}
|
||||
|
||||
func _GetMessage(msg *_MSG, hwnd syscall.Handle, msgfiltermin uint32, msgfiltermax uint32) (ret int32, err error) {
|
||||
r0, _, e1 := syscall.Syscall6(procGetMessageW.Addr(), 4, uintptr(unsafe.Pointer(msg)), uintptr(hwnd), uintptr(msgfiltermin), uintptr(msgfiltermax), 0, 0)
|
||||
ret = int32(r0)
|
||||
if ret == -1 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func _LoadCursor(hInstance syscall.Handle, cursorName uintptr) (cursor syscall.Handle, err error) {
|
||||
r0, _, e1 := syscall.Syscall(procLoadCursorW.Addr(), 2, uintptr(hInstance), uintptr(cursorName), 0)
|
||||
cursor = syscall.Handle(r0)
|
||||
if cursor == 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func _LoadIcon(hInstance syscall.Handle, iconName uintptr) (icon syscall.Handle, err error) {
|
||||
r0, _, e1 := syscall.Syscall(procLoadIconW.Addr(), 2, uintptr(hInstance), uintptr(iconName), 0)
|
||||
icon = syscall.Handle(r0)
|
||||
if icon == 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func _MoveWindow(hwnd syscall.Handle, x int32, y int32, w int32, h int32, repaint bool) (err error) {
|
||||
var _p0 uint32
|
||||
if repaint {
|
||||
_p0 = 1
|
||||
} else {
|
||||
_p0 = 0
|
||||
}
|
||||
r1, _, e1 := syscall.Syscall6(procMoveWindow.Addr(), 6, uintptr(hwnd), uintptr(x), uintptr(y), uintptr(w), uintptr(h), uintptr(_p0))
|
||||
if r1 == 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func _PostMessage(hwnd syscall.Handle, uMsg uint32, wParam uintptr, lParam uintptr) (lResult bool) {
|
||||
r0, _, _ := syscall.Syscall6(procPostMessageW.Addr(), 4, uintptr(hwnd), uintptr(uMsg), uintptr(wParam), uintptr(lParam), 0, 0)
|
||||
lResult = r0 != 0
|
||||
return
|
||||
}
|
||||
|
||||
func _PostQuitMessage(exitCode int32) {
|
||||
syscall.Syscall(procPostQuitMessage.Addr(), 1, uintptr(exitCode), 0, 0)
|
||||
return
|
||||
}
|
||||
|
||||
func _RegisterClass(wc *_WNDCLASS) (atom uint16, err error) {
|
||||
r0, _, e1 := syscall.Syscall(procRegisterClassW.Addr(), 1, uintptr(unsafe.Pointer(wc)), 0, 0)
|
||||
atom = uint16(r0)
|
||||
if atom == 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func _ShowWindow(hwnd syscall.Handle, cmdshow int32) (wasvisible bool) {
|
||||
r0, _, _ := syscall.Syscall(procShowWindow.Addr(), 2, uintptr(hwnd), uintptr(cmdshow), 0)
|
||||
wasvisible = r0 != 0
|
||||
return
|
||||
}
|
||||
|
||||
func _ScreenToClient(hwnd syscall.Handle, lpPoint *_POINT) (ok bool) {
|
||||
r0, _, _ := syscall.Syscall(procScreenToClient.Addr(), 2, uintptr(hwnd), uintptr(unsafe.Pointer(lpPoint)), 0)
|
||||
ok = r0 != 0
|
||||
return
|
||||
}
|
||||
|
||||
func _ToUnicodeEx(wVirtKey uint32, wScanCode uint32, lpKeyState *byte, pwszBuff *uint16, cchBuff int32, wFlags uint32, dwhkl syscall.Handle) (ret int32) {
|
||||
r0, _, _ := syscall.Syscall9(procToUnicodeEx.Addr(), 7, uintptr(wVirtKey), uintptr(wScanCode), uintptr(unsafe.Pointer(lpKeyState)), uintptr(unsafe.Pointer(pwszBuff)), uintptr(cchBuff), uintptr(wFlags), uintptr(dwhkl), 0, 0)
|
||||
ret = int32(r0)
|
||||
return
|
||||
}
|
||||
|
||||
func _TranslateMessage(msg *_MSG) (done bool) {
|
||||
r0, _, _ := syscall.Syscall(procTranslateMessage.Addr(), 1, uintptr(unsafe.Pointer(msg)), 0, 0)
|
||||
done = r0 != 0
|
||||
return
|
||||
}
|
||||
|
||||
func _UnregisterClass(lpClassName *uint16, hInstance syscall.Handle) (done bool) {
|
||||
r0, _, _ := syscall.Syscall(procUnregisterClassW.Addr(), 2, uintptr(unsafe.Pointer(lpClassName)), uintptr(hInstance), 0)
|
||||
done = r0 != 0
|
||||
return
|
||||
}
|
||||
1577
vendor/golang.org/x/exp/shiny/driver/internal/x11key/table.go
generated
vendored
Normal file
1577
vendor/golang.org/x/exp/shiny/driver/internal/x11key/table.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
323
vendor/golang.org/x/exp/shiny/driver/internal/x11key/x11key.go
generated
vendored
Normal file
323
vendor/golang.org/x/exp/shiny/driver/internal/x11key/x11key.go
generated
vendored
Normal file
@@ -0,0 +1,323 @@
|
||||
// Copyright 2015 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:generate go run gen.go
|
||||
|
||||
// x11key contains X11 numeric codes for the keyboard and mouse.
|
||||
package x11key // import "golang.org/x/exp/shiny/driver/internal/x11key"
|
||||
|
||||
import (
|
||||
"unicode"
|
||||
|
||||
"golang.org/x/mobile/event/key"
|
||||
)
|
||||
|
||||
// These constants come from /usr/include/X11/X.h
|
||||
const (
|
||||
ShiftMask = 1 << 0
|
||||
LockMask = 1 << 1
|
||||
ControlMask = 1 << 2
|
||||
Mod1Mask = 1 << 3
|
||||
Mod2Mask = 1 << 4
|
||||
Mod3Mask = 1 << 5
|
||||
Mod4Mask = 1 << 6
|
||||
Mod5Mask = 1 << 7
|
||||
Button1Mask = 1 << 8
|
||||
Button2Mask = 1 << 9
|
||||
Button3Mask = 1 << 10
|
||||
Button4Mask = 1 << 11
|
||||
Button5Mask = 1 << 12
|
||||
)
|
||||
|
||||
type KeysymTable struct {
|
||||
Table [256][6]uint32
|
||||
|
||||
NumLockMod, ModeSwitchMod, ISOLevel3ShiftMod uint16
|
||||
}
|
||||
|
||||
func (t *KeysymTable) Lookup(detail uint8, state uint16) (rune, key.Code) {
|
||||
te := t.Table[detail][0:2]
|
||||
if state&t.ModeSwitchMod != 0 {
|
||||
te = t.Table[detail][2:4]
|
||||
}
|
||||
if state&t.ISOLevel3ShiftMod != 0 {
|
||||
te = t.Table[detail][4:6]
|
||||
}
|
||||
|
||||
// The key event's rune depends on whether the shift key is down.
|
||||
unshifted := rune(te[0])
|
||||
r := unshifted
|
||||
if state&t.NumLockMod != 0 && isKeypad(te[1]) {
|
||||
if state&ShiftMask == 0 {
|
||||
r = rune(te[1])
|
||||
}
|
||||
} else if state&ShiftMask != 0 {
|
||||
r = rune(te[1])
|
||||
// In X11, a zero keysym when shift is down means to use what the
|
||||
// keysym is when shift is up.
|
||||
if r == 0 {
|
||||
r = unshifted
|
||||
}
|
||||
}
|
||||
|
||||
// The key event's code is independent of whether the shift key is down.
|
||||
var c key.Code
|
||||
if 0 <= unshifted && unshifted < 0x80 {
|
||||
c = asciiKeycodes[unshifted]
|
||||
if state&LockMask != 0 {
|
||||
r = unicode.ToUpper(r)
|
||||
}
|
||||
} else if kk, isKeypad := keypadKeysyms[r]; isKeypad {
|
||||
r, c = kk.rune, kk.code
|
||||
} else if nuk := nonUnicodeKeycodes[unshifted]; nuk != key.CodeUnknown {
|
||||
r, c = -1, nuk
|
||||
} else {
|
||||
r = keysymCodePoints[r]
|
||||
if state&LockMask != 0 {
|
||||
r = unicode.ToUpper(r)
|
||||
}
|
||||
}
|
||||
|
||||
return r, c
|
||||
}
|
||||
|
||||
func isKeypad(keysym uint32) bool {
|
||||
return keysym >= 0xff80 && keysym <= 0xffbd
|
||||
}
|
||||
|
||||
func KeyModifiers(state uint16) (m key.Modifiers) {
|
||||
if state&ShiftMask != 0 {
|
||||
m |= key.ModShift
|
||||
}
|
||||
if state&ControlMask != 0 {
|
||||
m |= key.ModControl
|
||||
}
|
||||
if state&Mod1Mask != 0 {
|
||||
m |= key.ModAlt
|
||||
}
|
||||
if state&Mod4Mask != 0 {
|
||||
m |= key.ModMeta
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
// These constants come from /usr/include/X11/{keysymdef,XF86keysym}.h
|
||||
const (
|
||||
xkISOLeftTab = 0xfe20
|
||||
xkBackSpace = 0xff08
|
||||
xkTab = 0xff09
|
||||
xkReturn = 0xff0d
|
||||
xkEscape = 0xff1b
|
||||
xkMultiKey = 0xff20
|
||||
xkHome = 0xff50
|
||||
xkLeft = 0xff51
|
||||
xkUp = 0xff52
|
||||
xkRight = 0xff53
|
||||
xkDown = 0xff54
|
||||
xkPageUp = 0xff55
|
||||
xkPageDown = 0xff56
|
||||
xkEnd = 0xff57
|
||||
xkInsert = 0xff63
|
||||
xkMenu = 0xff67
|
||||
xkHelp = 0xff6a
|
||||
|
||||
xkNumLock = 0xff7f
|
||||
xkKeypadEnter = 0xff8d
|
||||
xkKeypadHome = 0xff95
|
||||
xkKeypadLeft = 0xff96
|
||||
xkKeypadUp = 0xff97
|
||||
xkKeypadRight = 0xff98
|
||||
xkKeypadDown = 0xff99
|
||||
xkKeypadPageUp = 0xff9a
|
||||
xkKeypadPageDown = 0xff9b
|
||||
xkKeypadEnd = 0xff9c
|
||||
xkKeypadInsert = 0xff9e
|
||||
xkKeypadDelete = 0xff9f
|
||||
xkKeypadEqual = 0xffbd
|
||||
xkKeypadMultiply = 0xffaa
|
||||
xkKeypadAdd = 0xffab
|
||||
xkKeypadSubtract = 0xffad
|
||||
xkKeypadDecimal = 0xffae
|
||||
xkKeypadDivide = 0xffaf
|
||||
xkKeypad0 = 0xffb0
|
||||
xkKeypad1 = 0xffb1
|
||||
xkKeypad2 = 0xffb2
|
||||
xkKeypad3 = 0xffb3
|
||||
xkKeypad4 = 0xffb4
|
||||
xkKeypad5 = 0xffb5
|
||||
xkKeypad6 = 0xffb6
|
||||
xkKeypad7 = 0xffb7
|
||||
xkKeypad8 = 0xffb8
|
||||
xkKeypad9 = 0xffb9
|
||||
|
||||
xkF1 = 0xffbe
|
||||
xkF2 = 0xffbf
|
||||
xkF3 = 0xffc0
|
||||
xkF4 = 0xffc1
|
||||
xkF5 = 0xffc2
|
||||
xkF6 = 0xffc3
|
||||
xkF7 = 0xffc4
|
||||
xkF8 = 0xffc5
|
||||
xkF9 = 0xffc6
|
||||
xkF10 = 0xffc7
|
||||
xkF11 = 0xffc8
|
||||
xkF12 = 0xffc9
|
||||
xkShiftL = 0xffe1
|
||||
xkShiftR = 0xffe2
|
||||
xkControlL = 0xffe3
|
||||
xkControlR = 0xffe4
|
||||
xkCapsLock = 0xffe5
|
||||
xkAltL = 0xffe9
|
||||
xkAltR = 0xffea
|
||||
xkSuperL = 0xffeb
|
||||
xkSuperR = 0xffec
|
||||
xkDelete = 0xffff
|
||||
|
||||
xf86xkAudioLowerVolume = 0x1008ff11
|
||||
xf86xkAudioMute = 0x1008ff12
|
||||
xf86xkAudioRaiseVolume = 0x1008ff13
|
||||
)
|
||||
|
||||
// nonUnicodeKeycodes maps from those xproto.Keysym values (converted to runes)
|
||||
// that do not correspond to a Unicode code point, such as "Page Up", "F1" or
|
||||
// "Left Shift", to key.Code values.
|
||||
var nonUnicodeKeycodes = map[rune]key.Code{
|
||||
xkISOLeftTab: key.CodeTab,
|
||||
xkBackSpace: key.CodeDeleteBackspace,
|
||||
xkTab: key.CodeTab,
|
||||
xkReturn: key.CodeReturnEnter,
|
||||
xkEscape: key.CodeEscape,
|
||||
xkHome: key.CodeHome,
|
||||
xkLeft: key.CodeLeftArrow,
|
||||
xkUp: key.CodeUpArrow,
|
||||
xkRight: key.CodeRightArrow,
|
||||
xkDown: key.CodeDownArrow,
|
||||
xkPageUp: key.CodePageUp,
|
||||
xkPageDown: key.CodePageDown,
|
||||
xkEnd: key.CodeEnd,
|
||||
xkInsert: key.CodeInsert,
|
||||
xkMenu: key.CodeRightGUI, // TODO: CodeRightGUI or CodeMenu??
|
||||
xkHelp: key.CodeHelp,
|
||||
xkNumLock: key.CodeKeypadNumLock,
|
||||
xkMultiKey: key.CodeCompose,
|
||||
|
||||
xkKeypadEnter: key.CodeKeypadEnter,
|
||||
xkKeypadHome: key.CodeHome,
|
||||
xkKeypadLeft: key.CodeLeftArrow,
|
||||
xkKeypadUp: key.CodeUpArrow,
|
||||
xkKeypadRight: key.CodeRightArrow,
|
||||
xkKeypadDown: key.CodeDownArrow,
|
||||
xkKeypadPageUp: key.CodePageUp,
|
||||
xkKeypadPageDown: key.CodePageDown,
|
||||
xkKeypadEnd: key.CodeEnd,
|
||||
xkKeypadInsert: key.CodeInsert,
|
||||
xkKeypadDelete: key.CodeDeleteForward,
|
||||
|
||||
xkF1: key.CodeF1,
|
||||
xkF2: key.CodeF2,
|
||||
xkF3: key.CodeF3,
|
||||
xkF4: key.CodeF4,
|
||||
xkF5: key.CodeF5,
|
||||
xkF6: key.CodeF6,
|
||||
xkF7: key.CodeF7,
|
||||
xkF8: key.CodeF8,
|
||||
xkF9: key.CodeF9,
|
||||
xkF10: key.CodeF10,
|
||||
xkF11: key.CodeF11,
|
||||
xkF12: key.CodeF12,
|
||||
|
||||
xkShiftL: key.CodeLeftShift,
|
||||
xkShiftR: key.CodeRightShift,
|
||||
xkControlL: key.CodeLeftControl,
|
||||
xkControlR: key.CodeRightControl,
|
||||
xkCapsLock: key.CodeCapsLock,
|
||||
xkAltL: key.CodeLeftAlt,
|
||||
xkAltR: key.CodeRightAlt,
|
||||
xkSuperL: key.CodeLeftGUI,
|
||||
xkSuperR: key.CodeRightGUI,
|
||||
|
||||
xkDelete: key.CodeDeleteForward,
|
||||
|
||||
xf86xkAudioRaiseVolume: key.CodeVolumeUp,
|
||||
xf86xkAudioLowerVolume: key.CodeVolumeDown,
|
||||
xf86xkAudioMute: key.CodeMute,
|
||||
}
|
||||
|
||||
// asciiKeycodes maps lower-case ASCII runes to key.Code values.
|
||||
var asciiKeycodes = [0x80]key.Code{
|
||||
'a': key.CodeA,
|
||||
'b': key.CodeB,
|
||||
'c': key.CodeC,
|
||||
'd': key.CodeD,
|
||||
'e': key.CodeE,
|
||||
'f': key.CodeF,
|
||||
'g': key.CodeG,
|
||||
'h': key.CodeH,
|
||||
'i': key.CodeI,
|
||||
'j': key.CodeJ,
|
||||
'k': key.CodeK,
|
||||
'l': key.CodeL,
|
||||
'm': key.CodeM,
|
||||
'n': key.CodeN,
|
||||
'o': key.CodeO,
|
||||
'p': key.CodeP,
|
||||
'q': key.CodeQ,
|
||||
'r': key.CodeR,
|
||||
's': key.CodeS,
|
||||
't': key.CodeT,
|
||||
'u': key.CodeU,
|
||||
'v': key.CodeV,
|
||||
'w': key.CodeW,
|
||||
'x': key.CodeX,
|
||||
'y': key.CodeY,
|
||||
'z': key.CodeZ,
|
||||
|
||||
'1': key.Code1,
|
||||
'2': key.Code2,
|
||||
'3': key.Code3,
|
||||
'4': key.Code4,
|
||||
'5': key.Code5,
|
||||
'6': key.Code6,
|
||||
'7': key.Code7,
|
||||
'8': key.Code8,
|
||||
'9': key.Code9,
|
||||
'0': key.Code0,
|
||||
|
||||
' ': key.CodeSpacebar,
|
||||
'-': key.CodeHyphenMinus,
|
||||
'=': key.CodeEqualSign,
|
||||
'[': key.CodeLeftSquareBracket,
|
||||
']': key.CodeRightSquareBracket,
|
||||
'\\': key.CodeBackslash,
|
||||
';': key.CodeSemicolon,
|
||||
'\'': key.CodeApostrophe,
|
||||
'`': key.CodeGraveAccent,
|
||||
',': key.CodeComma,
|
||||
'.': key.CodeFullStop,
|
||||
'/': key.CodeSlash,
|
||||
}
|
||||
|
||||
type keypadKeysym struct {
|
||||
rune rune
|
||||
code key.Code
|
||||
}
|
||||
|
||||
var keypadKeysyms = map[rune]keypadKeysym{
|
||||
xkKeypadEqual: {'=', key.CodeKeypadEqualSign},
|
||||
xkKeypadMultiply: {'*', key.CodeKeypadAsterisk},
|
||||
xkKeypadAdd: {'+', key.CodeKeypadPlusSign},
|
||||
xkKeypadSubtract: {'-', key.CodeKeypadHyphenMinus},
|
||||
xkKeypadDecimal: {'.', key.CodeKeypadFullStop},
|
||||
xkKeypadDivide: {'/', key.CodeKeypadSlash},
|
||||
xkKeypad0: {'0', key.CodeKeypad0},
|
||||
xkKeypad1: {'1', key.CodeKeypad1},
|
||||
xkKeypad2: {'2', key.CodeKeypad2},
|
||||
xkKeypad3: {'3', key.CodeKeypad3},
|
||||
xkKeypad4: {'4', key.CodeKeypad4},
|
||||
xkKeypad5: {'5', key.CodeKeypad5},
|
||||
xkKeypad6: {'6', key.CodeKeypad6},
|
||||
xkKeypad7: {'7', key.CodeKeypad7},
|
||||
xkKeypad8: {'8', key.CodeKeypad8},
|
||||
xkKeypad9: {'9', key.CodeKeypad9},
|
||||
}
|
||||
Reference in New Issue
Block a user