mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2026-04-22 15:57:15 +08:00
all: rename objc.SEL variables from selFooBar to sel_fooBar
Rename all objc.SEL variable names to use underscore-separated convention matching the ObjC selector names: sel_fooBar for "fooBar", sel_fooBar_bazQux for "fooBar:bazQux:". Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -60,25 +60,25 @@ func (t *textInput) endIfNeeded() {
|
||||
}
|
||||
|
||||
var (
|
||||
selAddSubview = objc.RegisterName("addSubview:")
|
||||
selAlloc = objc.RegisterName("alloc")
|
||||
selContentView = objc.RegisterName("contentView")
|
||||
selConvertRectToScreen = objc.RegisterName("convertRectToScreen:")
|
||||
selFrame = objc.RegisterName("frame")
|
||||
selInit = objc.RegisterName("init")
|
||||
selMainWindow = objc.RegisterName("mainWindow")
|
||||
selMakeFirstResponder = objc.RegisterName("makeFirstResponder:")
|
||||
selSetFrame = objc.RegisterName("setFrame:")
|
||||
selSharedApplication = objc.RegisterName("sharedApplication")
|
||||
selWindow = objc.RegisterName("window")
|
||||
selString = objc.RegisterName("string")
|
||||
selUTF8String = objc.RegisterName("UTF8String")
|
||||
selLength = objc.RegisterName("length")
|
||||
selCharacterAtIndex = objc.RegisterName("characterAtIndex:")
|
||||
selResignFirstResponder = objc.RegisterName("resignFirstResponder")
|
||||
selIsKindOfClass = objc.RegisterName("isKindOfClass:")
|
||||
selArray = objc.RegisterName("array")
|
||||
selLengthOfBytesUsingEncoding = objc.RegisterName("lengthOfBytesUsingEncoding:")
|
||||
sel_addSubview = objc.RegisterName("addSubview:")
|
||||
sel_alloc = objc.RegisterName("alloc")
|
||||
sel_contentView = objc.RegisterName("contentView")
|
||||
sel_convertRectToScreen = objc.RegisterName("convertRectToScreen:")
|
||||
sel_frame = objc.RegisterName("frame")
|
||||
sel_init = objc.RegisterName("init")
|
||||
sel_mainWindow = objc.RegisterName("mainWindow")
|
||||
sel_makeFirstResponder = objc.RegisterName("makeFirstResponder:")
|
||||
sel_setFrame = objc.RegisterName("setFrame:")
|
||||
sel_sharedApplication = objc.RegisterName("sharedApplication")
|
||||
sel_window = objc.RegisterName("window")
|
||||
sel_string = objc.RegisterName("string")
|
||||
sel_UTF8String = objc.RegisterName("UTF8String")
|
||||
sel_length = objc.RegisterName("length")
|
||||
sel_characterAtIndex = objc.RegisterName("characterAtIndex:")
|
||||
sel_resignFirstResponder = objc.RegisterName("resignFirstResponder")
|
||||
sel_isKindOfClass = objc.RegisterName("isKindOfClass:")
|
||||
sel_array = objc.RegisterName("array")
|
||||
sel_lengthOfBytesUsingEncoding = objc.RegisterName("lengthOfBytesUsingEncoding:")
|
||||
|
||||
classNSArray = objc.GetClass("NSArray")
|
||||
classNSView = objc.GetClass("NSView")
|
||||
@@ -91,7 +91,7 @@ var theTextInputClient objc.ID
|
||||
func getTextInputClient() objc.ID {
|
||||
if theTextInputClient == 0 {
|
||||
class := objc.ID(textInputClientClass)
|
||||
theTextInputClient = class.Send(selAlloc).Send(selInit)
|
||||
theTextInputClient = class.Send(sel_alloc).Send(sel_init)
|
||||
}
|
||||
return theTextInputClient
|
||||
}
|
||||
@@ -122,17 +122,17 @@ func (t *textInput) start(bounds image.Rectangle) (<-chan textInputState, func()
|
||||
t.endIfNeeded()
|
||||
|
||||
tc := getTextInputClient()
|
||||
window := idNSApplication.Send(selSharedApplication).Send(selMainWindow)
|
||||
contentView := window.Send(selContentView)
|
||||
contentView.Send(selAddSubview, tc)
|
||||
window.Send(selMakeFirstResponder, tc)
|
||||
window := idNSApplication.Send(sel_sharedApplication).Send(sel_mainWindow)
|
||||
contentView := window.Send(sel_contentView)
|
||||
contentView.Send(sel_addSubview, tc)
|
||||
window.Send(sel_makeFirstResponder, tc)
|
||||
|
||||
r := objc.Send[nsRect](contentView, selFrame)
|
||||
r := objc.Send[nsRect](contentView, sel_frame)
|
||||
// The Y dirction is upward in the Cocoa coordinate system.
|
||||
y := int(r.size.height) - bounds.Max.Y
|
||||
// X is shifted a little bit, especially for the accent popup.
|
||||
bounds = bounds.Add(image.Pt(6, 0))
|
||||
tc.Send(selSetFrame, nsRect{
|
||||
tc.Send(sel_setFrame, nsRect{
|
||||
origin: nsPoint{float64(bounds.Min.X), float64(y)},
|
||||
size: nsSize{float64(bounds.Dx()), float64(bounds.Dy())},
|
||||
})
|
||||
@@ -195,7 +195,7 @@ func init() {
|
||||
Fn: doCommandBySelector,
|
||||
},
|
||||
{
|
||||
Cmd: selResignFirstResponder,
|
||||
Cmd: sel_resignFirstResponder,
|
||||
Fn: resignFirstResponder,
|
||||
},
|
||||
},
|
||||
@@ -243,12 +243,12 @@ func setMarkedText(_ objc.ID, _ objc.SEL, str objc.ID, selectedRange nsRange, re
|
||||
//
|
||||
// https://developer.apple.com/documentation/appkit/nstextinputclient/setmarkedtext(_:selectedrange:replacementrange:)?language=objc
|
||||
|
||||
if str.Send(selIsKindOfClass, objc.ID(classNSAttributedString)) != 0 {
|
||||
str = str.Send(selString)
|
||||
if str.Send(sel_isKindOfClass, objc.ID(classNSAttributedString)) != 0 {
|
||||
str = str.Send(sel_string)
|
||||
}
|
||||
|
||||
utf8Len := str.Send(selLengthOfBytesUsingEncoding, nsUTF8StringEncoding)
|
||||
charPtr := str.Send(selUTF8String)
|
||||
utf8Len := str.Send(sel_lengthOfBytesUsingEncoding, nsUTF8StringEncoding)
|
||||
charPtr := str.Send(sel_UTF8String)
|
||||
t := string(unsafe.Slice(*(**byte)(unsafe.Pointer(&charPtr)), utf8Len))
|
||||
|
||||
startInBytes := convertUTF16CountToByteCount(t, int(selectedRange.location))
|
||||
@@ -261,7 +261,7 @@ func unmarkText(_ objc.ID, _ objc.SEL) {
|
||||
}
|
||||
|
||||
func validAttributesForMarkedText(_ objc.ID, _ objc.SEL) objc.ID {
|
||||
return objc.ID(classNSArray).Send(selArray)
|
||||
return objc.ID(classNSArray).Send(sel_array)
|
||||
}
|
||||
|
||||
func attributedSubstringForProposedRange(_ objc.ID, _ objc.SEL, _ nsRange, _ unsafe.Pointer) objc.ID {
|
||||
@@ -269,11 +269,11 @@ func attributedSubstringForProposedRange(_ objc.ID, _ objc.SEL, _ nsRange, _ uns
|
||||
}
|
||||
|
||||
func insertText(_ objc.ID, _ objc.SEL, str objc.ID, replacementRange nsRange) {
|
||||
if str.Send(selIsKindOfClass, objc.ID(classNSAttributedString)) != 0 {
|
||||
str = str.Send(selString)
|
||||
if str.Send(sel_isKindOfClass, objc.ID(classNSAttributedString)) != 0 {
|
||||
str = str.Send(sel_string)
|
||||
}
|
||||
|
||||
if str.Send(selLength) == 1 && str.Send(selCharacterAtIndex, 0) < 0x20 {
|
||||
if str.Send(sel_length) == 1 && str.Send(sel_characterAtIndex, 0) < 0x20 {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -281,8 +281,8 @@ func insertText(_ objc.ID, _ objc.SEL, str objc.ID, replacementRange nsRange) {
|
||||
//
|
||||
// https://developer.apple.com/documentation/appkit/nstextinputclient/inserttext(_:replacementrange:)?language=objc
|
||||
|
||||
utf8Len := str.Send(selLengthOfBytesUsingEncoding, nsUTF8StringEncoding)
|
||||
charPtr := str.Send(selUTF8String)
|
||||
utf8Len := str.Send(sel_lengthOfBytesUsingEncoding, nsUTF8StringEncoding)
|
||||
charPtr := str.Send(sel_UTF8String)
|
||||
t := string(unsafe.Slice(*(**byte)(unsafe.Pointer(&charPtr)), utf8Len))
|
||||
|
||||
var delStartInBytes, delEndInBytes int
|
||||
@@ -312,9 +312,9 @@ func firstRectForCharacterRange(self objc.ID, _ objc.SEL, rang nsRange, actualRa
|
||||
}
|
||||
}
|
||||
|
||||
window := self.Send(selWindow)
|
||||
frame := objc.Send[nsRect](self, selFrame)
|
||||
return objc.Send[nsRect](window, selConvertRectToScreen, frame)
|
||||
window := self.Send(sel_window)
|
||||
frame := objc.Send[nsRect](self, sel_frame)
|
||||
return objc.Send[nsRect](window, sel_convertRectToScreen, frame)
|
||||
}
|
||||
|
||||
func doCommandBySelector(_ objc.ID, _ objc.SEL, _ objc.SEL) {
|
||||
|
||||
@@ -69,49 +69,49 @@ func init() {
|
||||
}
|
||||
|
||||
var (
|
||||
selRetain = objc.RegisterName("retain")
|
||||
selAlloc = objc.RegisterName("alloc")
|
||||
selNew = objc.RegisterName("new")
|
||||
selRelease = objc.RegisterName("release")
|
||||
selInvocationWithMethodSignature = objc.RegisterName("invocationWithMethodSignature:")
|
||||
selSetSelector = objc.RegisterName("setSelector:")
|
||||
selSetTarget = objc.RegisterName("setTarget:")
|
||||
selSetArgumentAtIndex = objc.RegisterName("setArgument:atIndex:")
|
||||
selGetReturnValue = objc.RegisterName("getReturnValue:")
|
||||
selInvoke = objc.RegisterName("invoke")
|
||||
selInvokeWithTarget = objc.RegisterName("invokeWithTarget:")
|
||||
selSignatureWithObjCTypes = objc.RegisterName("signatureWithObjCTypes:")
|
||||
selInitWithUTF8String = objc.RegisterName("initWithUTF8String:")
|
||||
selUTF8String = objc.RegisterName("UTF8String")
|
||||
selLength = objc.RegisterName("length")
|
||||
selLengthOfBytesUsingEncoding = objc.RegisterName("lengthOfBytesUsingEncoding:")
|
||||
selFrame = objc.RegisterName("frame")
|
||||
selContentView = objc.RegisterName("contentView")
|
||||
selSetBackgroundColor = objc.RegisterName("setBackgroundColor:")
|
||||
selColorWithSRGBRedGreenBlueAlpha = objc.RegisterName("colorWithSRGBRed:green:blue:alpha:")
|
||||
selSetFrameSize = objc.RegisterName("setFrameSize:")
|
||||
selObject = objc.RegisterName("object")
|
||||
selStyleMask = objc.RegisterName("styleMask")
|
||||
selSetStyleMask = objc.RegisterName("setStyleMask:")
|
||||
selMainScreen = objc.RegisterName("mainScreen")
|
||||
selScreen = objc.RegisterName("screen")
|
||||
selIsVisible = objc.RegisterName("isVisible")
|
||||
selDeviceDescription = objc.RegisterName("deviceDescription")
|
||||
selObjectForKey = objc.RegisterName("objectForKey:")
|
||||
selUnsignedIntValue = objc.RegisterName("unsignedIntValue")
|
||||
selSetLayer = objc.RegisterName("setLayer:")
|
||||
selSetWantsLayer = objc.RegisterName("setWantsLayer:")
|
||||
selMainRunLoop = objc.RegisterName("mainRunLoop")
|
||||
selCurrentRunLoop = objc.RegisterName("currentRunLoop")
|
||||
selRun = objc.RegisterName("run")
|
||||
selPerformBlock = objc.RegisterName("performBlock:")
|
||||
selPort = objc.RegisterName("port")
|
||||
selAddPort = objc.RegisterName("addPort:forMode:")
|
||||
selSharedWorkspace = objc.RegisterName("sharedWorkspace")
|
||||
selNotificationCenter = objc.RegisterName("notificationCenter")
|
||||
selAddObserver = objc.RegisterName("addObserver:selector:name:object:")
|
||||
selAddObserverForName = objc.RegisterName("addObserverForName:object:queue:usingBlock:")
|
||||
selMainQueue = objc.RegisterName("mainQueue")
|
||||
sel_retain = objc.RegisterName("retain")
|
||||
sel_alloc = objc.RegisterName("alloc")
|
||||
sel_new = objc.RegisterName("new")
|
||||
sel_release = objc.RegisterName("release")
|
||||
sel_invocationWithMethodSignature = objc.RegisterName("invocationWithMethodSignature:")
|
||||
sel_setSelector = objc.RegisterName("setSelector:")
|
||||
sel_setTarget = objc.RegisterName("setTarget:")
|
||||
sel_setArgument_atIndex = objc.RegisterName("setArgument:atIndex:")
|
||||
sel_getReturnValue = objc.RegisterName("getReturnValue:")
|
||||
sel_invoke = objc.RegisterName("invoke")
|
||||
sel_invokeWithTarget = objc.RegisterName("invokeWithTarget:")
|
||||
sel_signatureWithObjCTypes = objc.RegisterName("signatureWithObjCTypes:")
|
||||
sel_initWithUTF8String = objc.RegisterName("initWithUTF8String:")
|
||||
sel_UTF8String = objc.RegisterName("UTF8String")
|
||||
sel_length = objc.RegisterName("length")
|
||||
sel_lengthOfBytesUsingEncoding = objc.RegisterName("lengthOfBytesUsingEncoding:")
|
||||
sel_frame = objc.RegisterName("frame")
|
||||
sel_contentView = objc.RegisterName("contentView")
|
||||
sel_setBackgroundColor = objc.RegisterName("setBackgroundColor:")
|
||||
sel_colorWithSRGBRed_green_blue_alpha = objc.RegisterName("colorWithSRGBRed:green:blue:alpha:")
|
||||
sel_setFrameSize = objc.RegisterName("setFrameSize:")
|
||||
sel_object = objc.RegisterName("object")
|
||||
sel_styleMask = objc.RegisterName("styleMask")
|
||||
sel_setStyleMask = objc.RegisterName("setStyleMask:")
|
||||
sel_mainScreen = objc.RegisterName("mainScreen")
|
||||
sel_screen = objc.RegisterName("screen")
|
||||
sel_isVisible = objc.RegisterName("isVisible")
|
||||
sel_deviceDescription = objc.RegisterName("deviceDescription")
|
||||
sel_objectForKey = objc.RegisterName("objectForKey:")
|
||||
sel_unsignedIntValue = objc.RegisterName("unsignedIntValue")
|
||||
sel_setLayer = objc.RegisterName("setLayer:")
|
||||
sel_setWantsLayer = objc.RegisterName("setWantsLayer:")
|
||||
sel_mainRunLoop = objc.RegisterName("mainRunLoop")
|
||||
sel_currentRunLoop = objc.RegisterName("currentRunLoop")
|
||||
sel_run = objc.RegisterName("run")
|
||||
sel_performBlock = objc.RegisterName("performBlock:")
|
||||
sel_port = objc.RegisterName("port")
|
||||
sel_addPort_forMode = objc.RegisterName("addPort:forMode:")
|
||||
sel_sharedWorkspace = objc.RegisterName("sharedWorkspace")
|
||||
sel_notificationCenter = objc.RegisterName("notificationCenter")
|
||||
sel_addObserver_selector_name_object = objc.RegisterName("addObserver:selector:name:object:")
|
||||
sel_addObserverForName_object_queue_usingBlock = objc.RegisterName("addObserverForName:object:queue:usingBlock:")
|
||||
sel_mainQueue = objc.RegisterName("mainQueue")
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -152,7 +152,7 @@ type NSObject struct {
|
||||
}
|
||||
|
||||
func (n NSObject) Retain() {
|
||||
n.Send(selRetain)
|
||||
n.Send(sel_retain)
|
||||
}
|
||||
|
||||
type NSError struct {
|
||||
@@ -164,7 +164,7 @@ type NSColor struct {
|
||||
}
|
||||
|
||||
func NSColor_colorWithSRGBRedGreenBlueAlpha(red, green, blue, alpha CGFloat) (color NSColor) {
|
||||
return NSColor{objc.ID(classNSColor).Send(selColorWithSRGBRedGreenBlueAlpha, red, green, blue, alpha)}
|
||||
return NSColor{objc.ID(classNSColor).Send(sel_colorWithSRGBRed_green_blue_alpha, red, green, blue, alpha)}
|
||||
}
|
||||
|
||||
type NSWindow struct {
|
||||
@@ -172,31 +172,31 @@ type NSWindow struct {
|
||||
}
|
||||
|
||||
func (w NSWindow) StyleMask() NSUInteger {
|
||||
return NSUInteger(w.Send(selStyleMask))
|
||||
return NSUInteger(w.Send(sel_styleMask))
|
||||
}
|
||||
|
||||
func (w NSWindow) SetStyleMask(styleMask NSUInteger) {
|
||||
w.Send(selSetStyleMask, styleMask)
|
||||
w.Send(sel_setStyleMask, styleMask)
|
||||
}
|
||||
|
||||
func (w NSWindow) SetBackgroundColor(color NSColor) {
|
||||
w.Send(selSetBackgroundColor, color.ID)
|
||||
w.Send(sel_setBackgroundColor, color.ID)
|
||||
}
|
||||
|
||||
func (w NSWindow) IsVisible() bool {
|
||||
return w.Send(selIsVisible) != 0
|
||||
return w.Send(sel_isVisible) != 0
|
||||
}
|
||||
|
||||
func (w NSWindow) Screen() NSScreen {
|
||||
return NSScreen{w.Send(selScreen)}
|
||||
return NSScreen{w.Send(sel_screen)}
|
||||
}
|
||||
|
||||
func (w NSWindow) Frame() NSRect {
|
||||
return objc.Send[NSRect](w.ID, selFrame)
|
||||
return objc.Send[NSRect](w.ID, sel_frame)
|
||||
}
|
||||
|
||||
func (w NSWindow) ContentView() NSView {
|
||||
return NSView{w.Send(selContentView)}
|
||||
return NSView{w.Send(sel_contentView)}
|
||||
}
|
||||
|
||||
type NSView struct {
|
||||
@@ -204,19 +204,19 @@ type NSView struct {
|
||||
}
|
||||
|
||||
func (v NSView) SetFrameSize(size CGSize) {
|
||||
v.ID.Send(selSetFrameSize, size)
|
||||
v.ID.Send(sel_setFrameSize, size)
|
||||
}
|
||||
|
||||
func (v NSView) Frame() NSRect {
|
||||
return objc.Send[NSRect](v.ID, selFrame)
|
||||
return objc.Send[NSRect](v.ID, sel_frame)
|
||||
}
|
||||
|
||||
func (v NSView) SetLayer(layer uintptr) {
|
||||
v.Send(selSetLayer, layer)
|
||||
v.Send(sel_setLayer, layer)
|
||||
}
|
||||
|
||||
func (v NSView) SetWantsLayer(wantsLayer bool) {
|
||||
v.Send(selSetWantsLayer, wantsLayer)
|
||||
v.Send(sel_setWantsLayer, wantsLayer)
|
||||
}
|
||||
|
||||
// NSInvocation is being used to call functions that can't be called directly with purego.SyscallN.
|
||||
@@ -226,31 +226,31 @@ type NSInvocation struct {
|
||||
}
|
||||
|
||||
func NSInvocation_invocationWithMethodSignature(sig NSMethodSignature) NSInvocation {
|
||||
return NSInvocation{objc.ID(classNSInvocation).Send(selInvocationWithMethodSignature, sig.ID)}
|
||||
return NSInvocation{objc.ID(classNSInvocation).Send(sel_invocationWithMethodSignature, sig.ID)}
|
||||
}
|
||||
|
||||
func (i NSInvocation) SetSelector(cmd objc.SEL) {
|
||||
i.Send(selSetSelector, cmd)
|
||||
i.Send(sel_setSelector, cmd)
|
||||
}
|
||||
|
||||
func (i NSInvocation) SetTarget(target objc.ID) {
|
||||
i.Send(selSetTarget, target)
|
||||
i.Send(sel_setTarget, target)
|
||||
}
|
||||
|
||||
func (i NSInvocation) SetArgumentAtIndex(arg unsafe.Pointer, idx int) {
|
||||
i.Send(selSetArgumentAtIndex, arg, idx)
|
||||
i.Send(sel_setArgument_atIndex, arg, idx)
|
||||
}
|
||||
|
||||
func (i NSInvocation) GetReturnValue(ret unsafe.Pointer) {
|
||||
i.Send(selGetReturnValue, ret)
|
||||
i.Send(sel_getReturnValue, ret)
|
||||
}
|
||||
|
||||
func (i NSInvocation) Invoke() {
|
||||
i.Send(selInvoke)
|
||||
i.Send(sel_invoke)
|
||||
}
|
||||
|
||||
func (i NSInvocation) InvokeWithTarget(target objc.ID) {
|
||||
i.Send(selInvokeWithTarget, target)
|
||||
i.Send(sel_invokeWithTarget, target)
|
||||
}
|
||||
|
||||
type NSMethodSignature struct {
|
||||
@@ -262,7 +262,7 @@ type NSMethodSignature struct {
|
||||
//
|
||||
// [Apple Docs]: https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtTypeEncodings.html#//apple_ref/doc/uid/TP40008048-CH100
|
||||
func NSMethodSignature_signatureWithObjCTypes(types string) NSMethodSignature {
|
||||
return NSMethodSignature{objc.ID(classNSMethodSignature).Send(selSignatureWithObjCTypes, types)}
|
||||
return NSMethodSignature{objc.ID(classNSMethodSignature).Send(sel_signatureWithObjCTypes, types)}
|
||||
}
|
||||
|
||||
type NSAutoreleasePool struct {
|
||||
@@ -270,11 +270,11 @@ type NSAutoreleasePool struct {
|
||||
}
|
||||
|
||||
func NSAutoreleasePool_new() NSAutoreleasePool {
|
||||
return NSAutoreleasePool{objc.ID(classNSAutoreleasePool).Send(selNew)}
|
||||
return NSAutoreleasePool{objc.ID(classNSAutoreleasePool).Send(sel_new)}
|
||||
}
|
||||
|
||||
func (p NSAutoreleasePool) Release() {
|
||||
p.Send(selRelease)
|
||||
p.Send(sel_release)
|
||||
}
|
||||
|
||||
type NSString struct {
|
||||
@@ -282,19 +282,19 @@ type NSString struct {
|
||||
}
|
||||
|
||||
func NSString_alloc() NSString {
|
||||
return NSString{objc.ID(classNSString).Send(selAlloc)}
|
||||
return NSString{objc.ID(classNSString).Send(sel_alloc)}
|
||||
}
|
||||
|
||||
func (s NSString) InitWithUTF8String(utf8 string) NSString {
|
||||
return NSString{s.Send(selInitWithUTF8String, utf8)}
|
||||
return NSString{s.Send(sel_initWithUTF8String, utf8)}
|
||||
}
|
||||
|
||||
func (s NSString) String() string {
|
||||
// Use lengthOfBytesUsingEncoding: with NSUTF8StringEncoding (4) to get the
|
||||
// correct UTF-8 byte count. NSString.length returns UTF-16 code units which
|
||||
// differs from UTF-8 byte count for non-ASCII characters.
|
||||
length := s.Send(selLengthOfBytesUsingEncoding, 4)
|
||||
return string(unsafe.Slice((*byte)(unsafe.Pointer(s.Send(selUTF8String))), length))
|
||||
length := s.Send(sel_lengthOfBytesUsingEncoding, 4)
|
||||
return string(unsafe.Slice((*byte)(unsafe.Pointer(s.Send(sel_UTF8String))), length))
|
||||
}
|
||||
|
||||
type NSNotification struct {
|
||||
@@ -302,7 +302,7 @@ type NSNotification struct {
|
||||
}
|
||||
|
||||
func (n NSNotification) Object() objc.ID {
|
||||
return n.Send(selObject)
|
||||
return n.Send(sel_object)
|
||||
}
|
||||
|
||||
type NSScreen struct {
|
||||
@@ -310,11 +310,11 @@ type NSScreen struct {
|
||||
}
|
||||
|
||||
func NSScreen_mainScreen() NSScreen {
|
||||
return NSScreen{objc.ID(classNSScreen).Send(selMainScreen)}
|
||||
return NSScreen{objc.ID(classNSScreen).Send(sel_mainScreen)}
|
||||
}
|
||||
|
||||
func (s NSScreen) DeviceDescription() NSDictionary {
|
||||
return NSDictionary{s.Send(selDeviceDescription)}
|
||||
return NSDictionary{s.Send(sel_deviceDescription)}
|
||||
}
|
||||
|
||||
type NSDictionary struct {
|
||||
@@ -322,7 +322,7 @@ type NSDictionary struct {
|
||||
}
|
||||
|
||||
func (d NSDictionary) ObjectForKey(object objc.ID) objc.ID {
|
||||
return d.Send(selObjectForKey, object)
|
||||
return d.Send(sel_objectForKey, object)
|
||||
}
|
||||
|
||||
type NSNumber struct {
|
||||
@@ -330,7 +330,7 @@ type NSNumber struct {
|
||||
}
|
||||
|
||||
func (n NSNumber) UnsignedIntValue() uint {
|
||||
return uint(n.Send(selUnsignedIntValue))
|
||||
return uint(n.Send(sel_unsignedIntValue))
|
||||
}
|
||||
|
||||
type NSRunLoop struct {
|
||||
@@ -338,23 +338,23 @@ type NSRunLoop struct {
|
||||
}
|
||||
|
||||
func NSRunLoop_mainRunLoop() NSRunLoop {
|
||||
return NSRunLoop{objc.ID(classNSRunLoop).Send(selMainRunLoop)}
|
||||
return NSRunLoop{objc.ID(classNSRunLoop).Send(sel_mainRunLoop)}
|
||||
}
|
||||
|
||||
func NSRunLoop_currentRunLoop() NSRunLoop {
|
||||
return NSRunLoop{objc.ID(classNSRunLoop).Send(selCurrentRunLoop)}
|
||||
return NSRunLoop{objc.ID(classNSRunLoop).Send(sel_currentRunLoop)}
|
||||
}
|
||||
|
||||
func (r NSRunLoop) AddPort(port NSMachPort, mode NSRunLoopMode) {
|
||||
r.Send(selAddPort, port.ID, mode)
|
||||
r.Send(sel_addPort_forMode, port.ID, mode)
|
||||
}
|
||||
|
||||
func (r NSRunLoop) Run() {
|
||||
r.Send(selRun)
|
||||
r.Send(sel_run)
|
||||
}
|
||||
|
||||
func (r NSRunLoop) PerformBlock(block objc.Block) {
|
||||
r.Send(selPerformBlock, block)
|
||||
r.Send(sel_performBlock, block)
|
||||
}
|
||||
|
||||
type NSRunLoopMode NSString
|
||||
@@ -369,7 +369,7 @@ type NSMachPort struct {
|
||||
}
|
||||
|
||||
func NSMachPort_port() NSMachPort {
|
||||
return NSMachPort{objc.ID(classNSMachPort).Send(selPort)}
|
||||
return NSMachPort{objc.ID(classNSMachPort).Send(sel_port)}
|
||||
}
|
||||
|
||||
type NSWorkspace struct {
|
||||
@@ -377,11 +377,11 @@ type NSWorkspace struct {
|
||||
}
|
||||
|
||||
func NSWorkspace_sharedWorkspace() NSWorkspace {
|
||||
return NSWorkspace{objc.ID(classNSWorkspace).Send(selSharedWorkspace)}
|
||||
return NSWorkspace{objc.ID(classNSWorkspace).Send(sel_sharedWorkspace)}
|
||||
}
|
||||
|
||||
func (w NSWorkspace) NotificationCenter() NSNotificationCenter {
|
||||
return NSNotificationCenter{w.Send(selNotificationCenter)}
|
||||
return NSNotificationCenter{w.Send(sel_notificationCenter)}
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -394,7 +394,7 @@ type NSNotificationCenter struct {
|
||||
}
|
||||
|
||||
func (n NSNotificationCenter) AddObserverForName(name NSString, object objc.ID, queue NSOperationQueue, usingBlock objc.Block) objc.ID {
|
||||
return n.Send(selAddObserverForName, name.ID, object, queue.ID, usingBlock)
|
||||
return n.Send(sel_addObserverForName_object_queue_usingBlock, name.ID, object, queue.ID, usingBlock)
|
||||
}
|
||||
|
||||
type NSOperationQueue struct {
|
||||
@@ -402,5 +402,5 @@ type NSOperationQueue struct {
|
||||
}
|
||||
|
||||
func NSOperationQueue_mainQueue() NSOperationQueue {
|
||||
return NSOperationQueue{objc.ID(classNSOperationQueue).Send(selMainQueue)}
|
||||
return NSOperationQueue{objc.ID(classNSOperationQueue).Send(sel_mainQueue)}
|
||||
}
|
||||
|
||||
@@ -26,11 +26,11 @@ import (
|
||||
var (
|
||||
idNSApplication = objc.ID(objc.GetClass("NSApplication"))
|
||||
|
||||
selEffectiveAppearance = objc.RegisterName("effectiveAppearance")
|
||||
selLengthOfBytesUsingEncoding = objc.RegisterName("lengthOfBytesUsingEncoding:")
|
||||
selName = objc.RegisterName("name")
|
||||
selSharedApplication = objc.RegisterName("sharedApplication")
|
||||
selUTF8String = objc.RegisterName("UTF8String")
|
||||
sel_effectiveAppearance = objc.RegisterName("effectiveAppearance")
|
||||
sel_lengthOfBytesUsingEncoding = objc.RegisterName("lengthOfBytesUsingEncoding:")
|
||||
sel_name = objc.RegisterName("name")
|
||||
sel_sharedApplication = objc.RegisterName("sharedApplication")
|
||||
sel_UTF8String = objc.RegisterName("UTF8String")
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -47,8 +47,8 @@ func systemColorMode() ColorMode {
|
||||
// See also:
|
||||
// * https://developer.apple.com/documentation/appkit/nsapplication/effectiveappearance?language=objc
|
||||
// * https://go.dev/wiki/MinimumRequirements
|
||||
objcName := idNSApplication.Send(selSharedApplication).Send(selEffectiveAppearance).Send(selName)
|
||||
name := unsafe.Slice((*byte)(unsafe.Pointer(objcName.Send(selUTF8String))), objcName.Send(selLengthOfBytesUsingEncoding, nsUTF8StringEncoding))
|
||||
objcName := idNSApplication.Send(sel_sharedApplication).Send(sel_effectiveAppearance).Send(sel_name)
|
||||
name := unsafe.Slice((*byte)(unsafe.Pointer(objcName.Send(sel_UTF8String))), objcName.Send(sel_lengthOfBytesUsingEncoding, nsUTF8StringEncoding))
|
||||
// https://developer.apple.com/documentation/appkit/nsappearance/name-swift.struct?language=objc
|
||||
if bytes.Contains(name, bytesDark) {
|
||||
return Dark
|
||||
|
||||
+153
-153
@@ -108,48 +108,48 @@ var (
|
||||
|
||||
// ObjC selectors for GameController framework.
|
||||
var (
|
||||
selControllers objc.SEL
|
||||
selExtendedGamepad objc.SEL
|
||||
selMicroGamepad objc.SEL
|
||||
selProductCategory objc.SEL
|
||||
selVendorName objc.SEL
|
||||
selPhysicalInputProfile objc.SEL
|
||||
selRespondsToSelector objc.SEL
|
||||
selIsEqualToString objc.SEL
|
||||
selUTF8String objc.SEL
|
||||
selLeftThumbstick objc.SEL
|
||||
selRightThumbstick objc.SEL
|
||||
selLeftThumbstickButton objc.SEL
|
||||
selRightThumbstickButton objc.SEL
|
||||
selButtonA objc.SEL
|
||||
selButtonB objc.SEL
|
||||
selButtonX objc.SEL
|
||||
selButtonY objc.SEL
|
||||
selLeftShoulder objc.SEL
|
||||
selRightShoulder objc.SEL
|
||||
selButtonOptions objc.SEL
|
||||
selButtonHome objc.SEL
|
||||
selButtonMenu objc.SEL
|
||||
selLeftTrigger objc.SEL
|
||||
selRightTrigger objc.SEL
|
||||
selDpad objc.SEL
|
||||
selXAxis objc.SEL
|
||||
selYAxis objc.SEL
|
||||
selValue objc.SEL
|
||||
selIsPressed objc.SEL
|
||||
selUp objc.SEL
|
||||
selDown objc.SEL
|
||||
selLeft objc.SEL
|
||||
selRight objc.SEL
|
||||
selButtons objc.SEL
|
||||
selObjectForKeyedSubscript objc.SEL
|
||||
selObject objc.SEL
|
||||
selDefaultCenter objc.SEL
|
||||
selAddObserver objc.SEL
|
||||
selAlloc objc.SEL
|
||||
selInitWithUTF8String objc.SEL
|
||||
selCount objc.SEL
|
||||
selObjectAtIndex objc.SEL
|
||||
sel_controllers objc.SEL
|
||||
sel_extendedGamepad objc.SEL
|
||||
sel_microGamepad objc.SEL
|
||||
sel_productCategory objc.SEL
|
||||
sel_vendorName objc.SEL
|
||||
sel_physicalInputProfile objc.SEL
|
||||
sel_respondsToSelector objc.SEL
|
||||
sel_isEqualToString objc.SEL
|
||||
sel_UTF8String objc.SEL
|
||||
sel_leftThumbstick objc.SEL
|
||||
sel_rightThumbstick objc.SEL
|
||||
sel_leftThumbstickButton objc.SEL
|
||||
sel_rightThumbstickButton objc.SEL
|
||||
sel_buttonA objc.SEL
|
||||
sel_buttonB objc.SEL
|
||||
sel_buttonX objc.SEL
|
||||
sel_buttonY objc.SEL
|
||||
sel_leftShoulder objc.SEL
|
||||
sel_rightShoulder objc.SEL
|
||||
sel_buttonOptions objc.SEL
|
||||
sel_buttonHome objc.SEL
|
||||
sel_buttonMenu objc.SEL
|
||||
sel_leftTrigger objc.SEL
|
||||
sel_rightTrigger objc.SEL
|
||||
sel_dpad objc.SEL
|
||||
sel_xAxis objc.SEL
|
||||
sel_yAxis objc.SEL
|
||||
sel_value objc.SEL
|
||||
sel_isPressed objc.SEL
|
||||
sel_up objc.SEL
|
||||
sel_down objc.SEL
|
||||
sel_left objc.SEL
|
||||
sel_right objc.SEL
|
||||
sel_buttons objc.SEL
|
||||
sel_objectForKeyedSubscript objc.SEL
|
||||
sel_object objc.SEL
|
||||
sel_defaultCenter objc.SEL
|
||||
sel_addObserverForName_object_queue_usingBlock objc.SEL
|
||||
sel_alloc objc.SEL
|
||||
sel_initWithUTF8String objc.SEL
|
||||
sel_count objc.SEL
|
||||
sel_objectAtIndex objc.SEL
|
||||
)
|
||||
|
||||
// GC notification and input string constants (loaded from framework symbols).
|
||||
@@ -175,48 +175,48 @@ func init() {
|
||||
classGCController = objc.GetClass("GCController")
|
||||
classNSNotificationCtr = objc.GetClass("NSNotificationCenter")
|
||||
|
||||
selControllers = objc.RegisterName("controllers")
|
||||
selExtendedGamepad = objc.RegisterName("extendedGamepad")
|
||||
selMicroGamepad = objc.RegisterName("microGamepad")
|
||||
selProductCategory = objc.RegisterName("productCategory")
|
||||
selVendorName = objc.RegisterName("vendorName")
|
||||
selPhysicalInputProfile = objc.RegisterName("physicalInputProfile")
|
||||
selRespondsToSelector = objc.RegisterName("respondsToSelector:")
|
||||
selIsEqualToString = objc.RegisterName("isEqualToString:")
|
||||
selUTF8String = objc.RegisterName("UTF8String")
|
||||
selLeftThumbstick = objc.RegisterName("leftThumbstick")
|
||||
selRightThumbstick = objc.RegisterName("rightThumbstick")
|
||||
selLeftThumbstickButton = objc.RegisterName("leftThumbstickButton")
|
||||
selRightThumbstickButton = objc.RegisterName("rightThumbstickButton")
|
||||
selButtonA = objc.RegisterName("buttonA")
|
||||
selButtonB = objc.RegisterName("buttonB")
|
||||
selButtonX = objc.RegisterName("buttonX")
|
||||
selButtonY = objc.RegisterName("buttonY")
|
||||
selLeftShoulder = objc.RegisterName("leftShoulder")
|
||||
selRightShoulder = objc.RegisterName("rightShoulder")
|
||||
selButtonOptions = objc.RegisterName("buttonOptions")
|
||||
selButtonHome = objc.RegisterName("buttonHome")
|
||||
selButtonMenu = objc.RegisterName("buttonMenu")
|
||||
selLeftTrigger = objc.RegisterName("leftTrigger")
|
||||
selRightTrigger = objc.RegisterName("rightTrigger")
|
||||
selDpad = objc.RegisterName("dpad")
|
||||
selXAxis = objc.RegisterName("xAxis")
|
||||
selYAxis = objc.RegisterName("yAxis")
|
||||
selValue = objc.RegisterName("value")
|
||||
selIsPressed = objc.RegisterName("isPressed")
|
||||
selUp = objc.RegisterName("up")
|
||||
selDown = objc.RegisterName("down")
|
||||
selLeft = objc.RegisterName("left")
|
||||
selRight = objc.RegisterName("right")
|
||||
selButtons = objc.RegisterName("buttons")
|
||||
selObjectForKeyedSubscript = objc.RegisterName("objectForKeyedSubscript:")
|
||||
selObject = objc.RegisterName("object")
|
||||
selDefaultCenter = objc.RegisterName("defaultCenter")
|
||||
selAddObserver = objc.RegisterName("addObserverForName:object:queue:usingBlock:")
|
||||
selAlloc = objc.RegisterName("alloc")
|
||||
selInitWithUTF8String = objc.RegisterName("initWithUTF8String:")
|
||||
selCount = objc.RegisterName("count")
|
||||
selObjectAtIndex = objc.RegisterName("objectAtIndex:")
|
||||
sel_controllers = objc.RegisterName("controllers")
|
||||
sel_extendedGamepad = objc.RegisterName("extendedGamepad")
|
||||
sel_microGamepad = objc.RegisterName("microGamepad")
|
||||
sel_productCategory = objc.RegisterName("productCategory")
|
||||
sel_vendorName = objc.RegisterName("vendorName")
|
||||
sel_physicalInputProfile = objc.RegisterName("physicalInputProfile")
|
||||
sel_respondsToSelector = objc.RegisterName("respondsToSelector:")
|
||||
sel_isEqualToString = objc.RegisterName("isEqualToString:")
|
||||
sel_UTF8String = objc.RegisterName("UTF8String")
|
||||
sel_leftThumbstick = objc.RegisterName("leftThumbstick")
|
||||
sel_rightThumbstick = objc.RegisterName("rightThumbstick")
|
||||
sel_leftThumbstickButton = objc.RegisterName("leftThumbstickButton")
|
||||
sel_rightThumbstickButton = objc.RegisterName("rightThumbstickButton")
|
||||
sel_buttonA = objc.RegisterName("buttonA")
|
||||
sel_buttonB = objc.RegisterName("buttonB")
|
||||
sel_buttonX = objc.RegisterName("buttonX")
|
||||
sel_buttonY = objc.RegisterName("buttonY")
|
||||
sel_leftShoulder = objc.RegisterName("leftShoulder")
|
||||
sel_rightShoulder = objc.RegisterName("rightShoulder")
|
||||
sel_buttonOptions = objc.RegisterName("buttonOptions")
|
||||
sel_buttonHome = objc.RegisterName("buttonHome")
|
||||
sel_buttonMenu = objc.RegisterName("buttonMenu")
|
||||
sel_leftTrigger = objc.RegisterName("leftTrigger")
|
||||
sel_rightTrigger = objc.RegisterName("rightTrigger")
|
||||
sel_dpad = objc.RegisterName("dpad")
|
||||
sel_xAxis = objc.RegisterName("xAxis")
|
||||
sel_yAxis = objc.RegisterName("yAxis")
|
||||
sel_value = objc.RegisterName("value")
|
||||
sel_isPressed = objc.RegisterName("isPressed")
|
||||
sel_up = objc.RegisterName("up")
|
||||
sel_down = objc.RegisterName("down")
|
||||
sel_left = objc.RegisterName("left")
|
||||
sel_right = objc.RegisterName("right")
|
||||
sel_buttons = objc.RegisterName("buttons")
|
||||
sel_objectForKeyedSubscript = objc.RegisterName("objectForKeyedSubscript:")
|
||||
sel_object = objc.RegisterName("object")
|
||||
sel_defaultCenter = objc.RegisterName("defaultCenter")
|
||||
sel_addObserverForName_object_queue_usingBlock = objc.RegisterName("addObserverForName:object:queue:usingBlock:")
|
||||
sel_alloc = objc.RegisterName("alloc")
|
||||
sel_initWithUTF8String = objc.RegisterName("initWithUTF8String:")
|
||||
sel_count = objc.RegisterName("count")
|
||||
sel_objectAtIndex = objc.RegisterName("objectAtIndex:")
|
||||
|
||||
// Load notification name symbols (NSString* globals).
|
||||
connectPtr, err := purego.Dlsym(gc, "GCControllerDidConnectNotification")
|
||||
@@ -246,7 +246,7 @@ func init() {
|
||||
|
||||
// GCInputXboxShareButton is not an official constant; use "Button Share".
|
||||
classNSString := objc.GetClass("NSString")
|
||||
gcInputXboxShareButton = objc.ID(classNSString).Send(selAlloc).Send(selInitWithUTF8String, "Button Share\x00")
|
||||
gcInputXboxShareButton = objc.ID(classNSString).Send(sel_alloc).Send(sel_initWithUTF8String, "Button Share\x00")
|
||||
}
|
||||
|
||||
// nsStringToGoString converts an ObjC NSString to a Go string.
|
||||
@@ -254,7 +254,7 @@ func nsStringToGoString(nsStr objc.ID) string {
|
||||
if nsStr == 0 {
|
||||
return ""
|
||||
}
|
||||
ptr := nsStr.Send(selUTF8String)
|
||||
ptr := nsStr.Send(sel_UTF8String)
|
||||
if ptr == 0 {
|
||||
return ""
|
||||
}
|
||||
@@ -273,9 +273,9 @@ func nsStringEquals(nsStr objc.ID, s string) bool {
|
||||
return false
|
||||
}
|
||||
classNSString := objc.GetClass("NSString")
|
||||
goNSStr := objc.ID(classNSString).Send(selAlloc).Send(selInitWithUTF8String, s+"\x00")
|
||||
goNSStr := objc.ID(classNSString).Send(sel_alloc).Send(sel_initWithUTF8String, s+"\x00")
|
||||
defer goNSStr.Send(objc.RegisterName("release"))
|
||||
return nsStr.Send(selIsEqualToString, goNSStr) != 0
|
||||
return nsStr.Send(sel_isEqualToString, goNSStr) != 0
|
||||
}
|
||||
|
||||
// getControllerPropertyFromController extracts controller properties via ObjC.
|
||||
@@ -283,7 +283,7 @@ func getControllerPropertyFromController(controller objc.ID) controllerProperty
|
||||
var prop controllerProperty
|
||||
|
||||
// Get controller name.
|
||||
vendorNameStr := controller.Send(selVendorName)
|
||||
vendorNameStr := controller.Send(sel_vendorName)
|
||||
if vendorNameStr != 0 {
|
||||
prop.name = nsStringToGoString(vendorNameStr)
|
||||
}
|
||||
@@ -293,14 +293,14 @@ func getControllerPropertyFromController(controller objc.ID) controllerProperty
|
||||
|
||||
var vendor, product, subtype uint16
|
||||
|
||||
extGamepad := controller.Send(selExtendedGamepad)
|
||||
extGamepad := controller.Send(sel_extendedGamepad)
|
||||
if extGamepad != 0 {
|
||||
// Detect controller type via productCategory (macOS 10.15+) or vendorName.
|
||||
isXbox := false
|
||||
isPS4 := false
|
||||
isPS5 := false
|
||||
|
||||
productCategory := controller.Send(selProductCategory)
|
||||
productCategory := controller.Send(sel_productCategory)
|
||||
if productCategory != 0 {
|
||||
if nsStringEquals(productCategory, "DualShock 4") {
|
||||
isPS4 = true
|
||||
@@ -311,7 +311,7 @@ func getControllerPropertyFromController(controller objc.ID) controllerProperty
|
||||
}
|
||||
}
|
||||
if !isXbox && !isPS4 && !isPS5 {
|
||||
vendorName := controller.Send(selVendorName)
|
||||
vendorName := controller.Send(sel_vendorName)
|
||||
if vendorName != 0 {
|
||||
if nsStringEquals(vendorName, "DUALSHOCK") {
|
||||
isPS4 = true
|
||||
@@ -333,19 +333,19 @@ func getControllerPropertyFromController(controller objc.ID) controllerProperty
|
||||
prop.nButtons += 6
|
||||
|
||||
// Optional buttons (check availability via respondsToSelector:).
|
||||
if extGamepad.Send(selRespondsToSelector, selLeftThumbstickButton) != 0 && extGamepad.Send(selLeftThumbstickButton) != 0 {
|
||||
if extGamepad.Send(sel_respondsToSelector, sel_leftThumbstickButton) != 0 && extGamepad.Send(sel_leftThumbstickButton) != 0 {
|
||||
prop.buttonMask |= (1 << kControllerButtonLeftStick)
|
||||
prop.nButtons++
|
||||
}
|
||||
if extGamepad.Send(selRespondsToSelector, selRightThumbstickButton) != 0 && extGamepad.Send(selRightThumbstickButton) != 0 {
|
||||
if extGamepad.Send(sel_respondsToSelector, sel_rightThumbstickButton) != 0 && extGamepad.Send(sel_rightThumbstickButton) != 0 {
|
||||
prop.buttonMask |= (1 << kControllerButtonRightStick)
|
||||
prop.nButtons++
|
||||
}
|
||||
if extGamepad.Send(selRespondsToSelector, selButtonOptions) != 0 && extGamepad.Send(selButtonOptions) != 0 {
|
||||
if extGamepad.Send(sel_respondsToSelector, sel_buttonOptions) != 0 && extGamepad.Send(sel_buttonOptions) != 0 {
|
||||
prop.buttonMask |= (1 << kControllerButtonBack)
|
||||
prop.nButtons++
|
||||
}
|
||||
if extGamepad.Send(selRespondsToSelector, selButtonHome) != 0 && extGamepad.Send(selButtonHome) != 0 {
|
||||
if extGamepad.Send(sel_respondsToSelector, sel_buttonHome) != 0 && extGamepad.Send(sel_buttonHome) != 0 {
|
||||
prop.buttonMask |= (1 << kControllerButtonGuide)
|
||||
prop.nButtons++
|
||||
}
|
||||
@@ -354,37 +354,37 @@ func getControllerPropertyFromController(controller objc.ID) controllerProperty
|
||||
prop.nButtons++
|
||||
|
||||
// Physical input profile buttons (GCInputDualShockTouchpad, Xbox paddles, etc.).
|
||||
if controller.Send(selRespondsToSelector, selPhysicalInputProfile) != 0 {
|
||||
profile := controller.Send(selPhysicalInputProfile)
|
||||
if controller.Send(sel_respondsToSelector, sel_physicalInputProfile) != 0 {
|
||||
profile := controller.Send(sel_physicalInputProfile)
|
||||
if profile != 0 {
|
||||
profileButtons := profile.Send(selButtons)
|
||||
profileButtons := profile.Send(sel_buttons)
|
||||
if profileButtons != 0 {
|
||||
if gcInputDualShockTouchpadButton != 0 && profileButtons.Send(selObjectForKeyedSubscript, gcInputDualShockTouchpadButton) != 0 {
|
||||
if gcInputDualShockTouchpadButton != 0 && profileButtons.Send(sel_objectForKeyedSubscript, gcInputDualShockTouchpadButton) != 0 {
|
||||
prop.hasDualshockTouchpad = true
|
||||
prop.buttonMask |= (1 << kControllerButtonMisc1)
|
||||
prop.nButtons++
|
||||
}
|
||||
if gcInputXboxPaddleOne != 0 && profileButtons.Send(selObjectForKeyedSubscript, gcInputXboxPaddleOne) != 0 {
|
||||
if gcInputXboxPaddleOne != 0 && profileButtons.Send(sel_objectForKeyedSubscript, gcInputXboxPaddleOne) != 0 {
|
||||
prop.hasXboxPaddles = true
|
||||
prop.buttonMask |= (1 << kControllerButtonPaddle1)
|
||||
prop.nButtons++
|
||||
}
|
||||
if gcInputXboxPaddleTwo != 0 && profileButtons.Send(selObjectForKeyedSubscript, gcInputXboxPaddleTwo) != 0 {
|
||||
if gcInputXboxPaddleTwo != 0 && profileButtons.Send(sel_objectForKeyedSubscript, gcInputXboxPaddleTwo) != 0 {
|
||||
prop.hasXboxPaddles = true
|
||||
prop.buttonMask |= (1 << kControllerButtonPaddle2)
|
||||
prop.nButtons++
|
||||
}
|
||||
if gcInputXboxPaddleThree != 0 && profileButtons.Send(selObjectForKeyedSubscript, gcInputXboxPaddleThree) != 0 {
|
||||
if gcInputXboxPaddleThree != 0 && profileButtons.Send(sel_objectForKeyedSubscript, gcInputXboxPaddleThree) != 0 {
|
||||
prop.hasXboxPaddles = true
|
||||
prop.buttonMask |= (1 << kControllerButtonPaddle3)
|
||||
prop.nButtons++
|
||||
}
|
||||
if gcInputXboxPaddleFour != 0 && profileButtons.Send(selObjectForKeyedSubscript, gcInputXboxPaddleFour) != 0 {
|
||||
if gcInputXboxPaddleFour != 0 && profileButtons.Send(sel_objectForKeyedSubscript, gcInputXboxPaddleFour) != 0 {
|
||||
prop.hasXboxPaddles = true
|
||||
prop.buttonMask |= (1 << kControllerButtonPaddle4)
|
||||
prop.nButtons++
|
||||
}
|
||||
if gcInputXboxShareButton != 0 && profileButtons.Send(selObjectForKeyedSubscript, gcInputXboxShareButton) != 0 {
|
||||
if gcInputXboxShareButton != 0 && profileButtons.Send(sel_objectForKeyedSubscript, gcInputXboxShareButton) != 0 {
|
||||
prop.hasXboxShareButton = true
|
||||
prop.buttonMask |= (1 << kControllerButtonMisc1)
|
||||
prop.nButtons++
|
||||
@@ -445,25 +445,25 @@ func getControllerPropertyFromController(controller objc.ID) controllerProperty
|
||||
|
||||
// getAxisValue reads a float value from an ObjC axis element (returns the raw float32 value from the `value` property).
|
||||
func getAxisValue(element objc.ID) float32 {
|
||||
return objc.Send[float32](element, selValue)
|
||||
return objc.Send[float32](element, sel_value)
|
||||
}
|
||||
|
||||
// getIsPressed reads the boolean isPressed property from an ObjC button element.
|
||||
func getIsPressed(element objc.ID) bool {
|
||||
return element.Send(selIsPressed) != 0
|
||||
return element.Send(sel_isPressed) != 0
|
||||
}
|
||||
|
||||
// getHatState reads the hat state from a GCControllerDirectionPad.
|
||||
func getHatState(dpad objc.ID) uint8 {
|
||||
var hat uint8
|
||||
if getIsPressed(dpad.Send(selUp)) {
|
||||
if getIsPressed(dpad.Send(sel_up)) {
|
||||
hat |= kHatUp
|
||||
} else if getIsPressed(dpad.Send(selDown)) {
|
||||
} else if getIsPressed(dpad.Send(sel_down)) {
|
||||
hat |= kHatDown
|
||||
}
|
||||
if getIsPressed(dpad.Send(selLeft)) {
|
||||
if getIsPressed(dpad.Send(sel_left)) {
|
||||
hat |= kHatLeft
|
||||
} else if getIsPressed(dpad.Send(selRight)) {
|
||||
} else if getIsPressed(dpad.Send(sel_right)) {
|
||||
hat |= kHatRight
|
||||
}
|
||||
return hat
|
||||
@@ -476,20 +476,20 @@ func getControllerStateGC(controllerPtr uintptr, buttonMask uint32, nHats int,
|
||||
controller := objc.ID(controllerPtr)
|
||||
var state controllerState
|
||||
|
||||
extGamepad := controller.Send(selExtendedGamepad)
|
||||
extGamepad := controller.Send(sel_extendedGamepad)
|
||||
if extGamepad == 0 {
|
||||
return state
|
||||
}
|
||||
|
||||
// Axes.
|
||||
leftStick := extGamepad.Send(selLeftThumbstick)
|
||||
rightStick := extGamepad.Send(selRightThumbstick)
|
||||
state.axes[0] = getAxisValue(leftStick.Send(selXAxis))
|
||||
state.axes[1] = -getAxisValue(leftStick.Send(selYAxis))
|
||||
state.axes[2] = getAxisValue(extGamepad.Send(selLeftTrigger))*2 - 1
|
||||
state.axes[3] = getAxisValue(rightStick.Send(selXAxis))
|
||||
state.axes[4] = -getAxisValue(rightStick.Send(selYAxis))
|
||||
state.axes[5] = getAxisValue(extGamepad.Send(selRightTrigger))*2 - 1
|
||||
leftStick := extGamepad.Send(sel_leftThumbstick)
|
||||
rightStick := extGamepad.Send(sel_rightThumbstick)
|
||||
state.axes[0] = getAxisValue(leftStick.Send(sel_xAxis))
|
||||
state.axes[1] = -getAxisValue(leftStick.Send(sel_yAxis))
|
||||
state.axes[2] = getAxisValue(extGamepad.Send(sel_leftTrigger))*2 - 1
|
||||
state.axes[3] = getAxisValue(rightStick.Send(sel_xAxis))
|
||||
state.axes[4] = -getAxisValue(rightStick.Send(sel_yAxis))
|
||||
state.axes[5] = getAxisValue(extGamepad.Send(sel_rightTrigger))*2 - 1
|
||||
|
||||
// Buttons.
|
||||
buttonCount := 0
|
||||
@@ -499,60 +499,60 @@ func getControllerStateGC(controllerPtr uintptr, buttonMask uint32, nHats int,
|
||||
}
|
||||
buttonCount++
|
||||
}
|
||||
setButton(getIsPressed(extGamepad.Send(selButtonA)))
|
||||
setButton(getIsPressed(extGamepad.Send(selButtonB)))
|
||||
setButton(getIsPressed(extGamepad.Send(selButtonX)))
|
||||
setButton(getIsPressed(extGamepad.Send(selButtonY)))
|
||||
setButton(getIsPressed(extGamepad.Send(selLeftShoulder)))
|
||||
setButton(getIsPressed(extGamepad.Send(selRightShoulder)))
|
||||
setButton(getIsPressed(extGamepad.Send(sel_buttonA)))
|
||||
setButton(getIsPressed(extGamepad.Send(sel_buttonB)))
|
||||
setButton(getIsPressed(extGamepad.Send(sel_buttonX)))
|
||||
setButton(getIsPressed(extGamepad.Send(sel_buttonY)))
|
||||
setButton(getIsPressed(extGamepad.Send(sel_leftShoulder)))
|
||||
setButton(getIsPressed(extGamepad.Send(sel_rightShoulder)))
|
||||
|
||||
if buttonMask&(1<<kControllerButtonLeftStick) != 0 {
|
||||
setButton(getIsPressed(extGamepad.Send(selLeftThumbstickButton)))
|
||||
setButton(getIsPressed(extGamepad.Send(sel_leftThumbstickButton)))
|
||||
}
|
||||
if buttonMask&(1<<kControllerButtonRightStick) != 0 {
|
||||
setButton(getIsPressed(extGamepad.Send(selRightThumbstickButton)))
|
||||
setButton(getIsPressed(extGamepad.Send(sel_rightThumbstickButton)))
|
||||
}
|
||||
if buttonMask&(1<<kControllerButtonBack) != 0 {
|
||||
setButton(getIsPressed(extGamepad.Send(selButtonOptions)))
|
||||
setButton(getIsPressed(extGamepad.Send(sel_buttonOptions)))
|
||||
}
|
||||
if buttonMask&(1<<kControllerButtonGuide) != 0 {
|
||||
setButton(getIsPressed(extGamepad.Send(selButtonHome)))
|
||||
setButton(getIsPressed(extGamepad.Send(sel_buttonHome)))
|
||||
}
|
||||
if buttonMask&(1<<kControllerButtonStart) != 0 {
|
||||
setButton(getIsPressed(extGamepad.Send(selButtonMenu)))
|
||||
setButton(getIsPressed(extGamepad.Send(sel_buttonMenu)))
|
||||
}
|
||||
|
||||
if hasDualshockTouchpad {
|
||||
profile := controller.Send(selPhysicalInputProfile)
|
||||
profileButtons := profile.Send(selButtons)
|
||||
btn := profileButtons.Send(selObjectForKeyedSubscript, gcInputDualShockTouchpadButton)
|
||||
profile := controller.Send(sel_physicalInputProfile)
|
||||
profileButtons := profile.Send(sel_buttons)
|
||||
btn := profileButtons.Send(sel_objectForKeyedSubscript, gcInputDualShockTouchpadButton)
|
||||
setButton(getIsPressed(btn))
|
||||
}
|
||||
if hasXboxPaddles {
|
||||
profile := controller.Send(selPhysicalInputProfile)
|
||||
profileButtons := profile.Send(selButtons)
|
||||
profile := controller.Send(sel_physicalInputProfile)
|
||||
profileButtons := profile.Send(sel_buttons)
|
||||
if buttonMask&(1<<kControllerButtonPaddle1) != 0 {
|
||||
setButton(getIsPressed(profileButtons.Send(selObjectForKeyedSubscript, gcInputXboxPaddleOne)))
|
||||
setButton(getIsPressed(profileButtons.Send(sel_objectForKeyedSubscript, gcInputXboxPaddleOne)))
|
||||
}
|
||||
if buttonMask&(1<<kControllerButtonPaddle2) != 0 {
|
||||
setButton(getIsPressed(profileButtons.Send(selObjectForKeyedSubscript, gcInputXboxPaddleTwo)))
|
||||
setButton(getIsPressed(profileButtons.Send(sel_objectForKeyedSubscript, gcInputXboxPaddleTwo)))
|
||||
}
|
||||
if buttonMask&(1<<kControllerButtonPaddle3) != 0 {
|
||||
setButton(getIsPressed(profileButtons.Send(selObjectForKeyedSubscript, gcInputXboxPaddleThree)))
|
||||
setButton(getIsPressed(profileButtons.Send(sel_objectForKeyedSubscript, gcInputXboxPaddleThree)))
|
||||
}
|
||||
if buttonMask&(1<<kControllerButtonPaddle4) != 0 {
|
||||
setButton(getIsPressed(profileButtons.Send(selObjectForKeyedSubscript, gcInputXboxPaddleFour)))
|
||||
setButton(getIsPressed(profileButtons.Send(sel_objectForKeyedSubscript, gcInputXboxPaddleFour)))
|
||||
}
|
||||
}
|
||||
if hasXboxShareButton {
|
||||
profile := controller.Send(selPhysicalInputProfile)
|
||||
profileButtons := profile.Send(selButtons)
|
||||
setButton(getIsPressed(profileButtons.Send(selObjectForKeyedSubscript, gcInputXboxShareButton)))
|
||||
profile := controller.Send(sel_physicalInputProfile)
|
||||
profileButtons := profile.Send(sel_buttons)
|
||||
setButton(getIsPressed(profileButtons.Send(sel_objectForKeyedSubscript, gcInputXboxShareButton)))
|
||||
}
|
||||
|
||||
// Hat.
|
||||
if nHats > 0 {
|
||||
state.hat = getHatState(extGamepad.Send(selDpad))
|
||||
state.hat = getHatState(extGamepad.Send(sel_dpad))
|
||||
}
|
||||
|
||||
return state
|
||||
@@ -561,7 +561,7 @@ func getControllerStateGC(controllerPtr uintptr, buttonMask uint32, nHats int,
|
||||
// addController adds a GCController to the gamepad list.
|
||||
func addController(controller objc.ID) {
|
||||
// Ignore if the controller is not an actual controller (e.g., Siri Remote).
|
||||
if controller.Send(selExtendedGamepad) == 0 && controller.Send(selMicroGamepad) != 0 {
|
||||
if controller.Send(sel_extendedGamepad) == 0 && controller.Send(sel_microGamepad) != 0 {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -615,34 +615,34 @@ func initializeGCGamepads() {
|
||||
}
|
||||
|
||||
// Add all currently connected controllers.
|
||||
controllers := objc.ID(classGCController).Send(selControllers)
|
||||
count := int(controllers.Send(selCount))
|
||||
controllers := objc.ID(classGCController).Send(sel_controllers)
|
||||
count := int(controllers.Send(sel_count))
|
||||
for i := range count {
|
||||
controller := controllers.Send(selObjectAtIndex, i)
|
||||
controller := controllers.Send(sel_objectAtIndex, i)
|
||||
addController(controller)
|
||||
}
|
||||
|
||||
// Register for connect/disconnect notifications.
|
||||
center := objc.ID(classNSNotificationCtr).Send(selDefaultCenter)
|
||||
center := objc.ID(classNSNotificationCtr).Send(sel_defaultCenter)
|
||||
|
||||
connectBlock := objc.NewBlock(func(_ objc.Block, notification objc.ID) {
|
||||
controller := notification.Send(selObject)
|
||||
controller := notification.Send(sel_object)
|
||||
addController(controller)
|
||||
})
|
||||
|
||||
disconnectBlock := objc.NewBlock(func(_ objc.Block, notification objc.ID) {
|
||||
controller := notification.Send(selObject)
|
||||
controller := notification.Send(sel_object)
|
||||
removeController(controller)
|
||||
})
|
||||
|
||||
// The notification name symbols are pointers to NSString* — dereference them.
|
||||
if gcControllerDidConnectNotification != 0 {
|
||||
connectName := *(*objc.ID)(unsafe.Pointer(gcControllerDidConnectNotification))
|
||||
center.Send(selAddObserver, connectName, uintptr(0), uintptr(0), connectBlock)
|
||||
center.Send(sel_addObserverForName_object_queue_usingBlock, connectName, uintptr(0), uintptr(0), connectBlock)
|
||||
}
|
||||
if gcControllerDidDisconnectNotification != 0 {
|
||||
disconnectName := *(*objc.ID)(unsafe.Pointer(gcControllerDidDisconnectNotification))
|
||||
center.Send(selAddObserver, disconnectName, uintptr(0), uintptr(0), disconnectBlock)
|
||||
center.Send(sel_addObserverForName_object_queue_usingBlock, disconnectName, uintptr(0), uintptr(0), disconnectBlock)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -41,26 +41,25 @@ var (
|
||||
|
||||
// ObjC selectors for CoreHaptics.
|
||||
var (
|
||||
selCHHaptics objc.SEL
|
||||
selCHCreateEngineWithLocality objc.SEL
|
||||
selCHStartAndReturnError objc.SEL
|
||||
selCHStopWithCompletionHandler objc.SEL
|
||||
selCHCreatePlayerWithPattern objc.SEL
|
||||
selCHSendParameters objc.SEL
|
||||
selCHStartAtTime objc.SEL
|
||||
selCHStopAtTime objc.SEL
|
||||
selCHSupportedLocalities objc.SEL
|
||||
selCHContainsObject objc.SEL
|
||||
selCHInitWithParameterID objc.SEL
|
||||
selCHInitWithEventType objc.SEL
|
||||
selCHInitWithEvents objc.SEL
|
||||
selCHInitDynParam objc.SEL
|
||||
selCHAlloc objc.SEL
|
||||
selCHRelease objc.SEL
|
||||
selCHRetain objc.SEL
|
||||
selCHInit objc.SEL
|
||||
selCHArrayWithObjects objc.SEL
|
||||
selCHArray objc.SEL
|
||||
sel_haptics objc.SEL
|
||||
sel_createEngineWithLocality objc.SEL
|
||||
sel_startAndReturnError objc.SEL
|
||||
sel_stopWithCompletionHandler objc.SEL
|
||||
sel_createPlayerWithPattern_error objc.SEL
|
||||
sel_sendParameters_atTime_error objc.SEL
|
||||
sel_startAtTime_error objc.SEL
|
||||
sel_stopAtTime_error objc.SEL
|
||||
sel_supportedLocalities objc.SEL
|
||||
sel_containsObject objc.SEL
|
||||
sel_initWithParameterID_value objc.SEL
|
||||
sel_initWithEventType_parameters_relativeTime_duration objc.SEL
|
||||
sel_initWithEvents_parameters_error objc.SEL
|
||||
sel_initWithParameterID_value_relativeTime objc.SEL
|
||||
sel_release objc.SEL
|
||||
sel_retain objc.SEL
|
||||
sel_init objc.SEL
|
||||
sel_arrayWithObjects_count objc.SEL
|
||||
sel_array objc.SEL
|
||||
)
|
||||
|
||||
// CoreHaptics string/float constants (loaded from framework symbols).
|
||||
@@ -97,26 +96,25 @@ func init() {
|
||||
classCHHapticDynamicParam = objc.GetClass("CHHapticDynamicParameter")
|
||||
classNSArrayCH = objc.GetClass("NSArray")
|
||||
|
||||
selCHHaptics = objc.RegisterName("haptics")
|
||||
selCHCreateEngineWithLocality = objc.RegisterName("createEngineWithLocality:")
|
||||
selCHStartAndReturnError = objc.RegisterName("startAndReturnError:")
|
||||
selCHStopWithCompletionHandler = objc.RegisterName("stopWithCompletionHandler:")
|
||||
selCHCreatePlayerWithPattern = objc.RegisterName("createPlayerWithPattern:error:")
|
||||
selCHSendParameters = objc.RegisterName("sendParameters:atTime:error:")
|
||||
selCHStartAtTime = objc.RegisterName("startAtTime:error:")
|
||||
selCHStopAtTime = objc.RegisterName("stopAtTime:error:")
|
||||
selCHSupportedLocalities = objc.RegisterName("supportedLocalities")
|
||||
selCHContainsObject = objc.RegisterName("containsObject:")
|
||||
selCHInitWithParameterID = objc.RegisterName("initWithParameterID:value:")
|
||||
selCHInitWithEventType = objc.RegisterName("initWithEventType:parameters:relativeTime:duration:")
|
||||
selCHInitWithEvents = objc.RegisterName("initWithEvents:parameters:error:")
|
||||
selCHInitDynParam = objc.RegisterName("initWithParameterID:value:relativeTime:")
|
||||
selCHAlloc = objc.RegisterName("alloc")
|
||||
selCHRelease = objc.RegisterName("release")
|
||||
selCHRetain = objc.RegisterName("retain")
|
||||
selCHInit = objc.RegisterName("init")
|
||||
selCHArrayWithObjects = objc.RegisterName("arrayWithObjects:count:")
|
||||
selCHArray = objc.RegisterName("array")
|
||||
sel_haptics = objc.RegisterName("haptics")
|
||||
sel_createEngineWithLocality = objc.RegisterName("createEngineWithLocality:")
|
||||
sel_startAndReturnError = objc.RegisterName("startAndReturnError:")
|
||||
sel_stopWithCompletionHandler = objc.RegisterName("stopWithCompletionHandler:")
|
||||
sel_createPlayerWithPattern_error = objc.RegisterName("createPlayerWithPattern:error:")
|
||||
sel_sendParameters_atTime_error = objc.RegisterName("sendParameters:atTime:error:")
|
||||
sel_startAtTime_error = objc.RegisterName("startAtTime:error:")
|
||||
sel_stopAtTime_error = objc.RegisterName("stopAtTime:error:")
|
||||
sel_supportedLocalities = objc.RegisterName("supportedLocalities")
|
||||
sel_containsObject = objc.RegisterName("containsObject:")
|
||||
sel_initWithParameterID_value = objc.RegisterName("initWithParameterID:value:")
|
||||
sel_initWithEventType_parameters_relativeTime_duration = objc.RegisterName("initWithEventType:parameters:relativeTime:duration:")
|
||||
sel_initWithEvents_parameters_error = objc.RegisterName("initWithEvents:parameters:error:")
|
||||
sel_initWithParameterID_value_relativeTime = objc.RegisterName("initWithParameterID:value:relativeTime:")
|
||||
sel_release = objc.RegisterName("release")
|
||||
sel_retain = objc.RegisterName("retain")
|
||||
sel_init = objc.RegisterName("init")
|
||||
sel_arrayWithObjects_count = objc.RegisterName("arrayWithObjects:count:")
|
||||
sel_array = objc.RegisterName("array")
|
||||
|
||||
// Load string constants from GameController framework.
|
||||
gc, err := purego.Dlopen("/System/Library/Frameworks/GameController.framework/GameController", purego.RTLD_LAZY|purego.RTLD_GLOBAL)
|
||||
@@ -157,16 +155,16 @@ func createGCRumbleMotor(controller uintptr, which int) uintptr {
|
||||
}
|
||||
|
||||
controllerObj := objc.ID(controller)
|
||||
haptics := controllerObj.Send(selCHHaptics)
|
||||
haptics := controllerObj.Send(sel_haptics)
|
||||
if haptics == 0 {
|
||||
return 0
|
||||
}
|
||||
|
||||
supportedLocalities := haptics.Send(selCHSupportedLocalities)
|
||||
supportedLocalities := haptics.Send(sel_supportedLocalities)
|
||||
if supportedLocalities == 0 || chHapticsLocalityHandles == 0 {
|
||||
return 0
|
||||
}
|
||||
if supportedLocalities.Send(selCHContainsObject, chHapticsLocalityHandles) == 0 {
|
||||
if supportedLocalities.Send(sel_containsObject, chHapticsLocalityHandles) == 0 {
|
||||
return 0
|
||||
}
|
||||
|
||||
@@ -177,21 +175,21 @@ func createGCRumbleMotor(controller uintptr, which int) uintptr {
|
||||
locality = chHapticsLocalityRightHandle
|
||||
}
|
||||
|
||||
engine := haptics.Send(selCHCreateEngineWithLocality, locality)
|
||||
engine := haptics.Send(sel_createEngineWithLocality, locality)
|
||||
if engine == 0 {
|
||||
return 0
|
||||
}
|
||||
|
||||
// Start the engine.
|
||||
var nsError objc.ID
|
||||
engine.Send(selCHStartAndReturnError, uintptr(unsafe.Pointer(&nsError)))
|
||||
engine.Send(sel_startAndReturnError, uintptr(unsafe.Pointer(&nsError)))
|
||||
if nsError != 0 {
|
||||
return 0
|
||||
}
|
||||
|
||||
// Create a continuous haptic event with intensity 1.0.
|
||||
intensityParam := objc.ID(classCHHapticEventParameter).Send(selCHAlloc).Send(
|
||||
selCHInitWithParameterID,
|
||||
intensityParam := objc.ID(classCHHapticEventParameter).Send(sel_alloc).Send(
|
||||
sel_initWithParameterID_value,
|
||||
chHapticEventParameterIDHapticIntensity,
|
||||
float32(1.0),
|
||||
)
|
||||
@@ -199,47 +197,47 @@ func createGCRumbleMotor(controller uintptr, which int) uintptr {
|
||||
// Create an NSArray with the parameter.
|
||||
paramArray := makeNSArray(intensityParam)
|
||||
|
||||
event := objc.ID(classCHHapticEvent).Send(selCHAlloc).Send(
|
||||
selCHInitWithEventType,
|
||||
event := objc.ID(classCHHapticEvent).Send(sel_alloc).Send(
|
||||
sel_initWithEventType_parameters_relativeTime_duration,
|
||||
chHapticEventTypeHapticContinuous,
|
||||
paramArray,
|
||||
float64(0), // relativeTime
|
||||
float64(gcHapticDurationInfinite), // duration (NSTimeInterval)
|
||||
)
|
||||
intensityParam.Send(selCHRelease)
|
||||
intensityParam.Send(sel_release)
|
||||
|
||||
// Create pattern.
|
||||
eventArray := makeNSArray(event)
|
||||
emptyArray := objc.ID(classNSArrayCH).Send(selCHArray)
|
||||
emptyArray := objc.ID(classNSArrayCH).Send(sel_array)
|
||||
|
||||
nsError = 0
|
||||
pattern := objc.ID(classCHHapticPattern).Send(selCHAlloc).Send(
|
||||
selCHInitWithEvents,
|
||||
pattern := objc.ID(classCHHapticPattern).Send(sel_alloc).Send(
|
||||
sel_initWithEvents_parameters_error,
|
||||
eventArray,
|
||||
emptyArray,
|
||||
uintptr(unsafe.Pointer(&nsError)),
|
||||
)
|
||||
event.Send(selCHRelease)
|
||||
event.Send(sel_release)
|
||||
if nsError != 0 {
|
||||
if pattern != 0 {
|
||||
pattern.Send(selCHRelease)
|
||||
pattern.Send(sel_release)
|
||||
}
|
||||
engine.Send(selCHStopWithCompletionHandler, uintptr(0))
|
||||
engine.Send(sel_stopWithCompletionHandler, uintptr(0))
|
||||
return 0
|
||||
}
|
||||
|
||||
// Create player.
|
||||
nsError = 0
|
||||
player := engine.Send(selCHCreatePlayerWithPattern, pattern, uintptr(unsafe.Pointer(&nsError)))
|
||||
pattern.Send(selCHRelease)
|
||||
player := engine.Send(sel_createPlayerWithPattern_error, pattern, uintptr(unsafe.Pointer(&nsError)))
|
||||
pattern.Send(sel_release)
|
||||
if nsError != 0 {
|
||||
engine.Send(selCHStopWithCompletionHandler, uintptr(0))
|
||||
engine.Send(sel_stopWithCompletionHandler, uintptr(0))
|
||||
return 0
|
||||
}
|
||||
|
||||
motor := &rumbleMotor{
|
||||
engine: engine.Send(selCHRetain),
|
||||
player: player.Send(selCHRetain),
|
||||
engine: engine.Send(sel_retain),
|
||||
player: player.Send(sel_retain),
|
||||
active: false,
|
||||
}
|
||||
|
||||
@@ -249,7 +247,7 @@ func createGCRumbleMotor(controller uintptr, which int) uintptr {
|
||||
// makeNSArray creates an NSArray containing a single object.
|
||||
func makeNSArray(obj objc.ID) objc.ID {
|
||||
objects := [1]uintptr{uintptr(obj)}
|
||||
return objc.ID(classNSArrayCH).Send(selCHArrayWithObjects, uintptr(unsafe.Pointer(&objects[0])), 1)
|
||||
return objc.ID(classNSArrayCH).Send(sel_arrayWithObjects_count, uintptr(unsafe.Pointer(&objects[0])), 1)
|
||||
}
|
||||
|
||||
func releaseGCRumbleMotor(motorPtr uintptr) {
|
||||
@@ -263,11 +261,11 @@ func releaseGCRumbleMotor(motorPtr uintptr) {
|
||||
motor := (*rumbleMotor)(unsafe.Pointer(motorPtr))
|
||||
if motor.active {
|
||||
var nsError objc.ID
|
||||
motor.player.Send(selCHStopAtTime, float64(0), uintptr(unsafe.Pointer(&nsError)))
|
||||
motor.player.Send(sel_stopAtTime_error, float64(0), uintptr(unsafe.Pointer(&nsError)))
|
||||
}
|
||||
motor.engine.Send(selCHStopWithCompletionHandler, uintptr(0))
|
||||
motor.player.Send(selCHRelease)
|
||||
motor.engine.Send(selCHRelease)
|
||||
motor.engine.Send(sel_stopWithCompletionHandler, uintptr(0))
|
||||
motor.player.Send(sel_release)
|
||||
motor.engine.Send(sel_release)
|
||||
}
|
||||
|
||||
func vibrateGCGamepad(left, right uintptr, strong, weak float64) {
|
||||
@@ -289,22 +287,22 @@ func vibrateMotor(motorPtr uintptr, intensity float64) {
|
||||
|
||||
if intensity <= 0 {
|
||||
if motor.active {
|
||||
motor.player.Send(selCHStopAtTime, float64(0), uintptr(unsafe.Pointer(&nsError)))
|
||||
motor.player.Send(sel_stopAtTime_error, float64(0), uintptr(unsafe.Pointer(&nsError)))
|
||||
motor.active = false
|
||||
}
|
||||
} else {
|
||||
// Create a dynamic parameter to control intensity.
|
||||
param := objc.ID(classCHHapticDynamicParam).Send(selCHAlloc).Send(
|
||||
selCHInitDynParam,
|
||||
param := objc.ID(classCHHapticDynamicParam).Send(sel_alloc).Send(
|
||||
sel_initWithParameterID_value_relativeTime,
|
||||
chHapticDynamicParameterIDHapticIntensityCtrl,
|
||||
float32(intensity),
|
||||
float64(0), // relativeTime
|
||||
)
|
||||
paramArray := makeNSArray(param)
|
||||
motor.player.Send(selCHSendParameters, paramArray, float64(0), uintptr(unsafe.Pointer(&nsError)))
|
||||
param.Send(selCHRelease)
|
||||
motor.player.Send(sel_sendParameters_atTime_error, paramArray, float64(0), uintptr(unsafe.Pointer(&nsError)))
|
||||
param.Send(sel_release)
|
||||
if !motor.active {
|
||||
motor.player.Send(selCHStartAtTime, float64(0), uintptr(unsafe.Pointer(&nsError)))
|
||||
motor.player.Send(sel_startAtTime_error, float64(0), uintptr(unsafe.Pointer(&nsError)))
|
||||
motor.active = true
|
||||
}
|
||||
}
|
||||
|
||||
+197
-199
@@ -276,245 +276,243 @@ var (
|
||||
// ObjC selectors.
|
||||
var (
|
||||
// General
|
||||
selAlloc = objc.RegisterName("alloc")
|
||||
selInit = objc.RegisterName("init")
|
||||
selRelease = objc.RegisterName("release")
|
||||
selRetain = objc.RegisterName("retain")
|
||||
sel_alloc = objc.RegisterName("alloc")
|
||||
sel_init = objc.RegisterName("init")
|
||||
sel_release = objc.RegisterName("release")
|
||||
sel_retain = objc.RegisterName("retain")
|
||||
|
||||
// NSApplication
|
||||
selNSApp = objc.RegisterName("sharedApplication")
|
||||
selSharedApplication = objc.RegisterName("sharedApplication")
|
||||
selSetActivationPolicy = objc.RegisterName("setActivationPolicy:")
|
||||
selSetMainMenu = objc.RegisterName("setMainMenu:")
|
||||
selMainMenu = objc.RegisterName("mainMenu")
|
||||
selSetWindowsMenu = objc.RegisterName("setWindowsMenu:")
|
||||
selSetServicesMenu = objc.RegisterName("setServicesMenu:")
|
||||
selRun = objc.RegisterName("run")
|
||||
selStop = objc.RegisterName("stop:")
|
||||
selNextEventMatchingMask = objc.RegisterName("nextEventMatchingMask:untilDate:inMode:dequeue:")
|
||||
selSendEvent = objc.RegisterName("sendEvent:")
|
||||
selActivateIgnoringOtherApps = objc.RegisterName("activateIgnoringOtherApps:")
|
||||
selKeyWindow = objc.RegisterName("keyWindow")
|
||||
selPostEventAtStart = objc.RegisterName("postEvent:atStart:")
|
||||
selHide = objc.RegisterName("hide:")
|
||||
selUnhideAllApplications = objc.RegisterName("unhideAllApplications:")
|
||||
selHideOtherApplications = objc.RegisterName("hideOtherApplications:")
|
||||
selTerminate = objc.RegisterName("terminate:")
|
||||
selOrderFrontStandardAboutPanel = objc.RegisterName("orderFrontStandardAboutPanel:")
|
||||
selAddLocalMonitorForEventsMatchingMask = objc.RegisterName("addLocalMonitorForEventsMatchingMask:handler:")
|
||||
selAddGlobalMonitorForEventsMatchingMask = objc.RegisterName("addGlobalMonitorForEventsMatchingMask:handler:")
|
||||
sel_sharedApplication = objc.RegisterName("sharedApplication")
|
||||
sel_setActivationPolicy = objc.RegisterName("setActivationPolicy:")
|
||||
sel_setMainMenu = objc.RegisterName("setMainMenu:")
|
||||
sel_mainMenu = objc.RegisterName("mainMenu")
|
||||
sel_setWindowsMenu = objc.RegisterName("setWindowsMenu:")
|
||||
sel_setServicesMenu = objc.RegisterName("setServicesMenu:")
|
||||
sel_run = objc.RegisterName("run")
|
||||
sel_stop = objc.RegisterName("stop:")
|
||||
sel_nextEventMatchingMask_untilDate_inMode_dequeue = objc.RegisterName("nextEventMatchingMask:untilDate:inMode:dequeue:")
|
||||
sel_sendEvent = objc.RegisterName("sendEvent:")
|
||||
sel_activateIgnoringOtherApps = objc.RegisterName("activateIgnoringOtherApps:")
|
||||
sel_keyWindow = objc.RegisterName("keyWindow")
|
||||
sel_postEvent_atStart = objc.RegisterName("postEvent:atStart:")
|
||||
sel_hide = objc.RegisterName("hide:")
|
||||
sel_unhideAllApplications = objc.RegisterName("unhideAllApplications:")
|
||||
sel_hideOtherApplications = objc.RegisterName("hideOtherApplications:")
|
||||
sel_terminate = objc.RegisterName("terminate:")
|
||||
sel_orderFrontStandardAboutPanel = objc.RegisterName("orderFrontStandardAboutPanel:")
|
||||
sel_addLocalMonitorForEventsMatchingMask_handler = objc.RegisterName("addLocalMonitorForEventsMatchingMask:handler:")
|
||||
sel_addGlobalMonitorForEventsMatchingMask_handler = objc.RegisterName("addGlobalMonitorForEventsMatchingMask:handler:")
|
||||
|
||||
// NSProcessInfo
|
||||
selProcessInfo = objc.RegisterName("processInfo")
|
||||
selProcessName = objc.RegisterName("processName")
|
||||
sel_processInfo = objc.RegisterName("processInfo")
|
||||
sel_processName = objc.RegisterName("processName")
|
||||
|
||||
// NSBundle
|
||||
selBundleIdentifier = objc.RegisterName("bundleIdentifier")
|
||||
selMainBundle = objc.RegisterName("mainBundle")
|
||||
selInfoDictionary = objc.RegisterName("infoDictionary")
|
||||
sel_bundleIdentifier = objc.RegisterName("bundleIdentifier")
|
||||
sel_mainBundle = objc.RegisterName("mainBundle")
|
||||
sel_infoDictionary = objc.RegisterName("infoDictionary")
|
||||
|
||||
// NSNotificationCenter
|
||||
selDefaultCenter = objc.RegisterName("defaultCenter")
|
||||
selAddObserverSelectorNameObject = objc.RegisterName("addObserver:selector:name:object:")
|
||||
sel_defaultCenter = objc.RegisterName("defaultCenter")
|
||||
sel_addObserver_selector_name_object = objc.RegisterName("addObserver:selector:name:object:")
|
||||
|
||||
// NSMenu / NSMenuItem
|
||||
selInitWithTitle = objc.RegisterName("initWithTitle:")
|
||||
selAddItem = objc.RegisterName("addItem:")
|
||||
selAddItemWithTitle = objc.RegisterName("addItemWithTitle:action:keyEquivalent:")
|
||||
selSetSubmenu = objc.RegisterName("setSubmenu:")
|
||||
selSeparatorItem = objc.RegisterName("separatorItem")
|
||||
selSetKeyEquivalentModifierMask = objc.RegisterName("setKeyEquivalentModifierMask:")
|
||||
sel_initWithTitle = objc.RegisterName("initWithTitle:")
|
||||
sel_addItem = objc.RegisterName("addItem:")
|
||||
sel_addItemWithTitle_action_keyEquivalent = objc.RegisterName("addItemWithTitle:action:keyEquivalent:")
|
||||
sel_setSubmenu = objc.RegisterName("setSubmenu:")
|
||||
sel_separatorItem = objc.RegisterName("separatorItem")
|
||||
sel_setKeyEquivalentModifierMask = objc.RegisterName("setKeyEquivalentModifierMask:")
|
||||
|
||||
// NSEvent type/modifier selectors
|
||||
selCurrentEvent = objc.RegisterName("currentEvent")
|
||||
selOtherEventWithType = objc.RegisterName("otherEventWithType:location:modifierFlags:timestamp:windowNumber:context:subtype:data1:data2:")
|
||||
selType = objc.RegisterName("type")
|
||||
selModifierFlags = objc.RegisterName("modifierFlags")
|
||||
selKeyCode = objc.RegisterName("keyCode")
|
||||
selCharacters = objc.RegisterName("characters")
|
||||
selCharactersIgnoringModifiers = objc.RegisterName("charactersIgnoringModifiers")
|
||||
selLocationInWindow = objc.RegisterName("locationInWindow")
|
||||
selScrollingDeltaX = objc.RegisterName("scrollingDeltaX")
|
||||
selScrollingDeltaY = objc.RegisterName("scrollingDeltaY")
|
||||
selHasPreciseScrollingDeltas = objc.RegisterName("hasPreciseScrollingDeltas")
|
||||
selButtonNumber = objc.RegisterName("buttonNumber")
|
||||
selDeltaX = objc.RegisterName("deltaX")
|
||||
selDeltaY = objc.RegisterName("deltaY")
|
||||
sel_currentEvent = objc.RegisterName("currentEvent")
|
||||
sel_otherEventWithType_location_modifierFlags_timestamp_windowNumber_context_subtype_data1_data2 = objc.RegisterName("otherEventWithType:location:modifierFlags:timestamp:windowNumber:context:subtype:data1:data2:")
|
||||
sel_type = objc.RegisterName("type")
|
||||
sel_modifierFlags = objc.RegisterName("modifierFlags")
|
||||
sel_keyCode = objc.RegisterName("keyCode")
|
||||
sel_characters = objc.RegisterName("characters")
|
||||
sel_charactersIgnoringModifiers = objc.RegisterName("charactersIgnoringModifiers")
|
||||
sel_locationInWindow = objc.RegisterName("locationInWindow")
|
||||
sel_scrollingDeltaX = objc.RegisterName("scrollingDeltaX")
|
||||
sel_scrollingDeltaY = objc.RegisterName("scrollingDeltaY")
|
||||
sel_hasPreciseScrollingDeltas = objc.RegisterName("hasPreciseScrollingDeltas")
|
||||
sel_buttonNumber = objc.RegisterName("buttonNumber")
|
||||
sel_deltaX = objc.RegisterName("deltaX")
|
||||
sel_deltaY = objc.RegisterName("deltaY")
|
||||
|
||||
// NSWindow selectors
|
||||
selSetTitle = objc.RegisterName("setTitle:")
|
||||
selSetFrameAutosaveName = objc.RegisterName("setFrameAutosaveName:")
|
||||
selSetContentSize = objc.RegisterName("setContentSize:")
|
||||
selSetFrameOrigin = objc.RegisterName("setFrameOrigin:")
|
||||
selMakeKeyAndOrderFront = objc.RegisterName("makeKeyAndOrderFront:")
|
||||
selOrderOut = objc.RegisterName("orderOut:")
|
||||
selMiniaturize = objc.RegisterName("miniaturize:")
|
||||
selDeminiaturize = objc.RegisterName("deminiaturize:")
|
||||
selZoom = objc.RegisterName("zoom:")
|
||||
selToggleFullScreen = objc.RegisterName("toggleFullScreen:")
|
||||
selSetOpaque = objc.RegisterName("setOpaque:")
|
||||
selSetHasShadow = objc.RegisterName("setHasShadow:")
|
||||
selSetBackgroundColor = objc.RegisterName("setBackgroundColor:")
|
||||
selSetLevel = objc.RegisterName("setLevel:")
|
||||
selLevel = objc.RegisterName("level")
|
||||
selSetContentView = objc.RegisterName("setContentView:")
|
||||
selContentView = objc.RegisterName("contentView")
|
||||
selSetDelegate = objc.RegisterName("setDelegate:")
|
||||
selDelegate = objc.RegisterName("delegate")
|
||||
selIsKeyWindow = objc.RegisterName("isKeyWindow")
|
||||
selIsMiniaturized = objc.RegisterName("isMiniaturized")
|
||||
selIsVisible = objc.RegisterName("isVisible")
|
||||
selIsZoomed = objc.RegisterName("isZoomed")
|
||||
selSetMinSize = objc.RegisterName("setMinSize:")
|
||||
selSetMaxSize = objc.RegisterName("setMaxSize:")
|
||||
selSetContentMinSize = objc.RegisterName("setContentMinSize:")
|
||||
selSetContentMaxSize = objc.RegisterName("setContentMaxSize:")
|
||||
selSetContentAspectRatio = objc.RegisterName("setContentAspectRatio:")
|
||||
selSetResizeIncrements = objc.RegisterName("setResizeIncrements:")
|
||||
selOrderFront = objc.RegisterName("orderFront:")
|
||||
selStyleMask = objc.RegisterName("styleMask")
|
||||
selSetStyleMask = objc.RegisterName("setStyleMask:")
|
||||
selMiniwindowTitle = objc.RegisterName("miniwindowTitle")
|
||||
selSetMiniwindowTitle = objc.RegisterName("setMiniwindowTitle:")
|
||||
selMakeFirstResponder = objc.RegisterName("makeFirstResponder:")
|
||||
selSetRestorable = objc.RegisterName("setRestorable:")
|
||||
selSetCollectionBehavior = objc.RegisterName("setCollectionBehavior:")
|
||||
selSetIgnoresMouseEvents = objc.RegisterName("setIgnoresMouseEvents:")
|
||||
selAlphaValue = objc.RegisterName("alphaValue")
|
||||
selSetAlphaValue = objc.RegisterName("setAlphaValue:")
|
||||
selOcclusionState = objc.RegisterName("occlusionState")
|
||||
selWindowNumber = objc.RegisterName("windowNumber")
|
||||
selConvertRectToBacking = objc.RegisterName("convertRectToBacking:")
|
||||
selConvertRectFromBacking = objc.RegisterName("convertRectFromBacking:")
|
||||
selConvertPointToBacking = objc.RegisterName("convertPointToBacking:")
|
||||
selConvertPointFromBacking = objc.RegisterName("convertPointFromBacking:")
|
||||
selInitWithContentRect = objc.RegisterName("initWithContentRect:styleMask:backing:defer:")
|
||||
selContentRectForFrameRect = objc.RegisterName("contentRectForFrameRect:")
|
||||
selFrameRectForContentRect = objc.RegisterName("frameRectForContentRect:")
|
||||
selFrameRectForContentRectStyleMask = objc.RegisterName("frameRectForContentRect:styleMask:")
|
||||
selRequestUserAttention = objc.RegisterName("requestUserAttention:")
|
||||
selArrangeInFront = objc.RegisterName("arrangeInFront:")
|
||||
selConvertRectToScreen = objc.RegisterName("convertRectToScreen:")
|
||||
selMouseLocationOutsideOfEventStream = objc.RegisterName("mouseLocationOutsideOfEventStream")
|
||||
sel_setTitle = objc.RegisterName("setTitle:")
|
||||
sel_setFrameAutosaveName = objc.RegisterName("setFrameAutosaveName:")
|
||||
sel_setContentSize = objc.RegisterName("setContentSize:")
|
||||
sel_setFrameOrigin = objc.RegisterName("setFrameOrigin:")
|
||||
sel_makeKeyAndOrderFront = objc.RegisterName("makeKeyAndOrderFront:")
|
||||
sel_orderOut = objc.RegisterName("orderOut:")
|
||||
sel_miniaturize = objc.RegisterName("miniaturize:")
|
||||
sel_deminiaturize = objc.RegisterName("deminiaturize:")
|
||||
sel_zoom = objc.RegisterName("zoom:")
|
||||
sel_toggleFullScreen = objc.RegisterName("toggleFullScreen:")
|
||||
sel_setOpaque = objc.RegisterName("setOpaque:")
|
||||
sel_setHasShadow = objc.RegisterName("setHasShadow:")
|
||||
sel_setBackgroundColor = objc.RegisterName("setBackgroundColor:")
|
||||
sel_setLevel = objc.RegisterName("setLevel:")
|
||||
sel_level = objc.RegisterName("level")
|
||||
sel_setContentView = objc.RegisterName("setContentView:")
|
||||
sel_contentView = objc.RegisterName("contentView")
|
||||
sel_setDelegate = objc.RegisterName("setDelegate:")
|
||||
sel_delegate = objc.RegisterName("delegate")
|
||||
sel_isKeyWindow = objc.RegisterName("isKeyWindow")
|
||||
sel_isMiniaturized = objc.RegisterName("isMiniaturized")
|
||||
sel_isVisible = objc.RegisterName("isVisible")
|
||||
sel_isZoomed = objc.RegisterName("isZoomed")
|
||||
sel_setMinSize = objc.RegisterName("setMinSize:")
|
||||
sel_setMaxSize = objc.RegisterName("setMaxSize:")
|
||||
sel_setContentMinSize = objc.RegisterName("setContentMinSize:")
|
||||
sel_setContentMaxSize = objc.RegisterName("setContentMaxSize:")
|
||||
sel_setContentAspectRatio = objc.RegisterName("setContentAspectRatio:")
|
||||
sel_setResizeIncrements = objc.RegisterName("setResizeIncrements:")
|
||||
sel_orderFront = objc.RegisterName("orderFront:")
|
||||
sel_styleMask = objc.RegisterName("styleMask")
|
||||
sel_setStyleMask = objc.RegisterName("setStyleMask:")
|
||||
sel_miniwindowTitle = objc.RegisterName("miniwindowTitle")
|
||||
sel_setMiniwindowTitle = objc.RegisterName("setMiniwindowTitle:")
|
||||
sel_makeFirstResponder = objc.RegisterName("makeFirstResponder:")
|
||||
sel_setRestorable = objc.RegisterName("setRestorable:")
|
||||
sel_setCollectionBehavior = objc.RegisterName("setCollectionBehavior:")
|
||||
sel_setIgnoresMouseEvents = objc.RegisterName("setIgnoresMouseEvents:")
|
||||
sel_alphaValue = objc.RegisterName("alphaValue")
|
||||
sel_setAlphaValue = objc.RegisterName("setAlphaValue:")
|
||||
sel_occlusionState = objc.RegisterName("occlusionState")
|
||||
sel_windowNumber = objc.RegisterName("windowNumber")
|
||||
sel_convertRectToBacking = objc.RegisterName("convertRectToBacking:")
|
||||
sel_convertRectFromBacking = objc.RegisterName("convertRectFromBacking:")
|
||||
sel_convertPointToBacking = objc.RegisterName("convertPointToBacking:")
|
||||
sel_convertPointFromBacking = objc.RegisterName("convertPointFromBacking:")
|
||||
sel_initWithContentRect_styleMask_backing_defer = objc.RegisterName("initWithContentRect:styleMask:backing:defer:")
|
||||
sel_contentRectForFrameRect = objc.RegisterName("contentRectForFrameRect:")
|
||||
sel_frameRectForContentRect = objc.RegisterName("frameRectForContentRect:")
|
||||
sel_frameRectForContentRect_styleMask = objc.RegisterName("frameRectForContentRect:styleMask:")
|
||||
sel_requestUserAttention = objc.RegisterName("requestUserAttention:")
|
||||
sel_arrangeInFront = objc.RegisterName("arrangeInFront:")
|
||||
sel_convertRectToScreen = objc.RegisterName("convertRectToScreen:")
|
||||
sel_mouseLocationOutsideOfEventStream = objc.RegisterName("mouseLocationOutsideOfEventStream")
|
||||
|
||||
// NSView selectors
|
||||
selFrame = objc.RegisterName("frame")
|
||||
selBounds = objc.RegisterName("bounds")
|
||||
selWindow = objc.RegisterName("window")
|
||||
selAddTrackingArea = objc.RegisterName("addTrackingArea:")
|
||||
selRemoveTrackingArea = objc.RegisterName("removeTrackingArea:")
|
||||
selTrackingAreas = objc.RegisterName("trackingAreas")
|
||||
selSetNeedsDisplay = objc.RegisterName("setNeedsDisplay:")
|
||||
selMouseInRect = objc.RegisterName("mouse:inRect:")
|
||||
sel_frame = objc.RegisterName("frame")
|
||||
sel_bounds = objc.RegisterName("bounds")
|
||||
sel_window = objc.RegisterName("window")
|
||||
sel_addTrackingArea = objc.RegisterName("addTrackingArea:")
|
||||
sel_removeTrackingArea = objc.RegisterName("removeTrackingArea:")
|
||||
sel_trackingAreas = objc.RegisterName("trackingAreas")
|
||||
sel_setNeedsDisplay = objc.RegisterName("setNeedsDisplay:")
|
||||
sel_mouse_inRect = objc.RegisterName("mouse:inRect:")
|
||||
|
||||
// NSScreen selectors
|
||||
selScreens = objc.RegisterName("screens")
|
||||
selMainScreen = objc.RegisterName("mainScreen")
|
||||
selScreen = objc.RegisterName("screen")
|
||||
selDeviceDescription = objc.RegisterName("deviceDescription")
|
||||
selBackingScaleFactor = objc.RegisterName("backingScaleFactor")
|
||||
selVisibleFrame = objc.RegisterName("visibleFrame")
|
||||
sel_screens = objc.RegisterName("screens")
|
||||
sel_mainScreen = objc.RegisterName("mainScreen")
|
||||
sel_screen = objc.RegisterName("screen")
|
||||
sel_deviceDescription = objc.RegisterName("deviceDescription")
|
||||
sel_backingScaleFactor = objc.RegisterName("backingScaleFactor")
|
||||
sel_visibleFrame = objc.RegisterName("visibleFrame")
|
||||
|
||||
// NSPasteboard selectors
|
||||
selGeneralPasteboard = objc.RegisterName("generalPasteboard")
|
||||
selDeclareTypes = objc.RegisterName("declareTypes:owner:")
|
||||
selSetStringForType = objc.RegisterName("setString:forType:")
|
||||
selStringForType = objc.RegisterName("stringForType:")
|
||||
selTypes = objc.RegisterName("types")
|
||||
selContainsObject = objc.RegisterName("containsObject:")
|
||||
sel_generalPasteboard = objc.RegisterName("generalPasteboard")
|
||||
sel_declareTypes_owner = objc.RegisterName("declareTypes:owner:")
|
||||
sel_setString_forType = objc.RegisterName("setString:forType:")
|
||||
sel_stringForType = objc.RegisterName("stringForType:")
|
||||
sel_types = objc.RegisterName("types")
|
||||
sel_containsObject = objc.RegisterName("containsObject:")
|
||||
|
||||
// NSCursor selectors
|
||||
selArrowCursor = objc.RegisterName("arrowCursor")
|
||||
selIBeamCursor = objc.RegisterName("IBeamCursor")
|
||||
selCrosshairCursor = objc.RegisterName("crosshairCursor")
|
||||
selClosedHandCursor = objc.RegisterName("closedHandCursor")
|
||||
selOpenHandCursor = objc.RegisterName("openHandCursor")
|
||||
selPointingHandCursor = objc.RegisterName("pointingHandCursor")
|
||||
selResizeLeftCursor = objc.RegisterName("resizeLeftCursor")
|
||||
selResizeRightCursor = objc.RegisterName("resizeRightCursor")
|
||||
selResizeUpCursor = objc.RegisterName("resizeUpCursor")
|
||||
selResizeDownCursor = objc.RegisterName("resizeDownCursor")
|
||||
selOperationNotAllowedCursor = objc.RegisterName("operationNotAllowedCursor")
|
||||
selRespondsToSelector = objc.RegisterName("respondsToSelector:")
|
||||
selPerformSelector = objc.RegisterName("performSelector:")
|
||||
selSetCursor = objc.RegisterName("set")
|
||||
selHideCursor = objc.RegisterName("hide")
|
||||
selUnhideCursor = objc.RegisterName("unhide")
|
||||
sel_arrowCursor = objc.RegisterName("arrowCursor")
|
||||
sel_IBeamCursor = objc.RegisterName("IBeamCursor")
|
||||
sel_crosshairCursor = objc.RegisterName("crosshairCursor")
|
||||
sel_closedHandCursor = objc.RegisterName("closedHandCursor")
|
||||
sel_openHandCursor = objc.RegisterName("openHandCursor")
|
||||
sel_pointingHandCursor = objc.RegisterName("pointingHandCursor")
|
||||
sel_resizeLeftCursor = objc.RegisterName("resizeLeftCursor")
|
||||
sel_resizeRightCursor = objc.RegisterName("resizeRightCursor")
|
||||
sel_resizeUpCursor = objc.RegisterName("resizeUpCursor")
|
||||
sel_resizeDownCursor = objc.RegisterName("resizeDownCursor")
|
||||
sel_operationNotAllowedCursor = objc.RegisterName("operationNotAllowedCursor")
|
||||
sel_respondsToSelector = objc.RegisterName("respondsToSelector:")
|
||||
sel_performSelector = objc.RegisterName("performSelector:")
|
||||
sel_set = objc.RegisterName("set")
|
||||
sel_unhide = objc.RegisterName("unhide")
|
||||
|
||||
// NSImage / NSBitmapImageRep selectors
|
||||
selInitWithSize = objc.RegisterName("initWithSize:")
|
||||
selAddRepresentation = objc.RegisterName("addRepresentation:")
|
||||
selInitWithBitmapDataPlanes = objc.RegisterName("initWithBitmapDataPlanes:pixelsWide:pixelsHigh:bitsPerSample:samplesPerPixel:hasAlpha:isPlanar:colorSpaceName:bitmapFormat:bytesPerRow:bitsPerPixel:")
|
||||
selBitmapData = objc.RegisterName("bitmapData")
|
||||
selInitByReferencingFile = objc.RegisterName("initByReferencingFile:")
|
||||
selInitWithImageHotSpot = objc.RegisterName("initWithImage:hotSpot:")
|
||||
selStringByAppendingPathComponent = objc.RegisterName("stringByAppendingPathComponent:")
|
||||
selDictionaryWithContentsOfFile = objc.RegisterName("dictionaryWithContentsOfFile:")
|
||||
selValueForKey = objc.RegisterName("valueForKey:")
|
||||
selDoubleValue = objc.RegisterName("doubleValue")
|
||||
sel_initWithSize = objc.RegisterName("initWithSize:")
|
||||
sel_addRepresentation = objc.RegisterName("addRepresentation:")
|
||||
sel_initWithBitmapDataPlanes_pixelsWide_pixelsHigh_bitsPerSample_samplesPerPixel_hasAlpha_isPlanar_colorSpaceName_bitmapFormat_bytesPerRow_bitsPerPixel = objc.RegisterName("initWithBitmapDataPlanes:pixelsWide:pixelsHigh:bitsPerSample:samplesPerPixel:hasAlpha:isPlanar:colorSpaceName:bitmapFormat:bytesPerRow:bitsPerPixel:")
|
||||
sel_bitmapData = objc.RegisterName("bitmapData")
|
||||
sel_initByReferencingFile = objc.RegisterName("initByReferencingFile:")
|
||||
sel_initWithImage_hotSpot = objc.RegisterName("initWithImage:hotSpot:")
|
||||
sel_stringByAppendingPathComponent = objc.RegisterName("stringByAppendingPathComponent:")
|
||||
sel_dictionaryWithContentsOfFile = objc.RegisterName("dictionaryWithContentsOfFile:")
|
||||
sel_valueForKey = objc.RegisterName("valueForKey:")
|
||||
sel_doubleValue = objc.RegisterName("doubleValue")
|
||||
|
||||
// NSTrackingArea selectors
|
||||
selInitWithRectOptionsOwnerUserInfo = objc.RegisterName("initWithRect:options:owner:userInfo:")
|
||||
sel_initWithRect_options_owner_userInfo = objc.RegisterName("initWithRect:options:owner:userInfo:")
|
||||
|
||||
// NSColor selectors
|
||||
selClearColor = objc.RegisterName("clearColor")
|
||||
sel_clearColor = objc.RegisterName("clearColor")
|
||||
|
||||
// NSArray selectors
|
||||
selArrayWithObject = objc.RegisterName("arrayWithObject:")
|
||||
selCount = objc.RegisterName("count")
|
||||
selObjectAtIndex = objc.RegisterName("objectAtIndex:")
|
||||
selObjectForKey = objc.RegisterName("objectForKey:")
|
||||
selUnsignedIntValue = objc.RegisterName("unsignedIntValue")
|
||||
selLocalizedName = objc.RegisterName("localizedName")
|
||||
selUTF8String = objc.RegisterName("UTF8String")
|
||||
selLength = objc.RegisterName("length")
|
||||
selLengthOfBytesUsingEncoding = objc.RegisterName("lengthOfBytesUsingEncoding:")
|
||||
sel_arrayWithObject = objc.RegisterName("arrayWithObject:")
|
||||
sel_count = objc.RegisterName("count")
|
||||
sel_objectAtIndex = objc.RegisterName("objectAtIndex:")
|
||||
sel_objectForKey = objc.RegisterName("objectForKey:")
|
||||
sel_unsignedIntValue = objc.RegisterName("unsignedIntValue")
|
||||
sel_localizedName = objc.RegisterName("localizedName")
|
||||
sel_UTF8String = objc.RegisterName("UTF8String")
|
||||
sel_length = objc.RegisterName("length")
|
||||
sel_lengthOfBytesUsingEncoding = objc.RegisterName("lengthOfBytesUsingEncoding:")
|
||||
|
||||
// Drag and drop selectors
|
||||
selDraggingPasteboard = objc.RegisterName("draggingPasteboard")
|
||||
selReadObjectsForClasses = objc.RegisterName("readObjectsForClasses:options:")
|
||||
selRegisterForDraggedTypes = objc.RegisterName("registerForDraggedTypes:")
|
||||
sel_draggingPasteboard = objc.RegisterName("draggingPasteboard")
|
||||
sel_readObjectsForClasses_options = objc.RegisterName("readObjectsForClasses:options:")
|
||||
sel_registerForDraggedTypes = objc.RegisterName("registerForDraggedTypes:")
|
||||
|
||||
// Text input selectors
|
||||
selInterpretKeyEvents = objc.RegisterName("interpretKeyEvents:")
|
||||
selHasMarkedText = objc.RegisterName("hasMarkedText")
|
||||
selMarkedRange = objc.RegisterName("markedRange")
|
||||
selSelectedRange = objc.RegisterName("selectedRange")
|
||||
selSetMarkedText = objc.RegisterName("setMarkedText:selectedRange:replacementRange:")
|
||||
selUnmarkText = objc.RegisterName("unmarkText")
|
||||
selValidAttributesForMarkedText = objc.RegisterName("validAttributesForMarkedText")
|
||||
selAttributedSubstringForProposedRange = objc.RegisterName("attributedSubstringForProposedRange:actualRange:")
|
||||
selInsertText = objc.RegisterName("insertText:replacementRange:")
|
||||
selCharacterIndexForPoint = objc.RegisterName("characterIndexForPoint:")
|
||||
selFirstRectForCharacterRange = objc.RegisterName("firstRectForCharacterRange:actualRange:")
|
||||
selDoCommandBySelector = objc.RegisterName("doCommandBySelector:")
|
||||
sel_interpretKeyEvents = objc.RegisterName("interpretKeyEvents:")
|
||||
sel_hasMarkedText = objc.RegisterName("hasMarkedText")
|
||||
sel_markedRange = objc.RegisterName("markedRange")
|
||||
sel_selectedRange = objc.RegisterName("selectedRange")
|
||||
sel_setMarkedText_selectedRange_replacementRange = objc.RegisterName("setMarkedText:selectedRange:replacementRange:")
|
||||
sel_unmarkText = objc.RegisterName("unmarkText")
|
||||
sel_validAttributesForMarkedText = objc.RegisterName("validAttributesForMarkedText")
|
||||
sel_attributedSubstringForProposedRange_actualRange = objc.RegisterName("attributedSubstringForProposedRange:actualRange:")
|
||||
sel_insertText_replacementRange = objc.RegisterName("insertText:replacementRange:")
|
||||
sel_characterIndexForPoint = objc.RegisterName("characterIndexForPoint:")
|
||||
sel_firstRectForCharacterRange_actualRange = objc.RegisterName("firstRectForCharacterRange:actualRange:")
|
||||
sel_doCommandBySelector = objc.RegisterName("doCommandBySelector:")
|
||||
|
||||
// GLFWApplicationDelegate selectors
|
||||
selSelectedKeyboardInputSourceChanged = objc.RegisterName("selectedKeyboardInputSourceChanged:")
|
||||
selApplicationShouldTerminate = objc.RegisterName("applicationShouldTerminate:")
|
||||
selApplicationDidChangeScreenParameters = objc.RegisterName("applicationDidChangeScreenParameters:")
|
||||
selApplicationWillFinishLaunching = objc.RegisterName("applicationWillFinishLaunching:")
|
||||
selApplicationDidFinishLaunching = objc.RegisterName("applicationDidFinishLaunching:")
|
||||
selApplicationDidHide = objc.RegisterName("applicationDidHide:")
|
||||
sel_selectedKeyboardInputSourceChanged = objc.RegisterName("selectedKeyboardInputSourceChanged:")
|
||||
sel_applicationShouldTerminate = objc.RegisterName("applicationShouldTerminate:")
|
||||
sel_applicationDidChangeScreenParameters = objc.RegisterName("applicationDidChangeScreenParameters:")
|
||||
sel_applicationWillFinishLaunching = objc.RegisterName("applicationWillFinishLaunching:")
|
||||
sel_applicationDidFinishLaunching = objc.RegisterName("applicationDidFinishLaunching:")
|
||||
sel_applicationDidHide = objc.RegisterName("applicationDidHide:")
|
||||
|
||||
// NSOpenGL selectors
|
||||
selInitWithAttributes = objc.RegisterName("initWithAttributes:")
|
||||
selInitWithFormatShareContext = objc.RegisterName("initWithFormat:shareContext:")
|
||||
selMakeCurrentContext = objc.RegisterName("makeCurrentContext")
|
||||
selClearCurrentContext = objc.RegisterName("clearCurrentContext")
|
||||
selFlushBuffer = objc.RegisterName("flushBuffer")
|
||||
selSetValuesForParameter = objc.RegisterName("setValues:forParameter:")
|
||||
selGetValuesForParameter = objc.RegisterName("getValues:forParameter:")
|
||||
selSetView = objc.RegisterName("setView:")
|
||||
selSetWantsBestResolutionOpenGLSurface = objc.RegisterName("setWantsBestResolutionOpenGLSurface:")
|
||||
sel_initWithAttributes = objc.RegisterName("initWithAttributes:")
|
||||
sel_initWithFormat_shareContext = objc.RegisterName("initWithFormat:shareContext:")
|
||||
sel_makeCurrentContext = objc.RegisterName("makeCurrentContext")
|
||||
sel_clearCurrentContext = objc.RegisterName("clearCurrentContext")
|
||||
sel_flushBuffer = objc.RegisterName("flushBuffer")
|
||||
sel_setValues_forParameter = objc.RegisterName("setValues:forParameter:")
|
||||
sel_getValues_forParameter = objc.RegisterName("getValues:forParameter:")
|
||||
sel_setView = objc.RegisterName("setView:")
|
||||
sel_setWantsBestResolutionOpenGLSurface = objc.RegisterName("setWantsBestResolutionOpenGLSurface:")
|
||||
|
||||
// NSAttributedString / NSMutableAttributedString selectors
|
||||
selIsKindOfClass = objc.RegisterName("isKindOfClass:")
|
||||
selString = objc.RegisterName("string")
|
||||
selInitWithAttributedString = objc.RegisterName("initWithAttributedString:")
|
||||
selInitWithString = objc.RegisterName("initWithString:")
|
||||
selMutableString = objc.RegisterName("mutableString")
|
||||
selSetStringValue = objc.RegisterName("setString:")
|
||||
sel_isKindOfClass = objc.RegisterName("isKindOfClass:")
|
||||
sel_string = objc.RegisterName("string")
|
||||
sel_initWithAttributedString = objc.RegisterName("initWithAttributedString:")
|
||||
sel_initWithString = objc.RegisterName("initWithString:")
|
||||
sel_mutableString = objc.RegisterName("mutableString")
|
||||
sel_setString = objc.RegisterName("setString:")
|
||||
)
|
||||
|
||||
func mustDlsym(handle uintptr, name string) uintptr {
|
||||
|
||||
@@ -150,9 +150,9 @@ func createKeyTables() {
|
||||
// getAppName returns the application name from NSProcessInfo or the bundle.
|
||||
func getAppName() string {
|
||||
// Try to figure out what the calling application is called.
|
||||
bundle := objc.ID(classNSBundle).Send(selMainBundle)
|
||||
bundle := objc.ID(classNSBundle).Send(sel_mainBundle)
|
||||
if bundle != 0 {
|
||||
info := bundle.Send(selInfoDictionary)
|
||||
info := bundle.Send(sel_infoDictionary)
|
||||
if info != 0 {
|
||||
nameKeys := []string{
|
||||
"CFBundleDisplayName",
|
||||
@@ -161,8 +161,8 @@ func getAppName() string {
|
||||
}
|
||||
for _, key := range nameKeys {
|
||||
nsKey := cocoa.NSString_alloc().InitWithUTF8String(key)
|
||||
name := info.Send(selObjectForKey, nsKey.ID)
|
||||
nsKey.ID.Send(selRelease)
|
||||
name := info.Send(sel_objectForKey, nsKey.ID)
|
||||
nsKey.ID.Send(sel_release)
|
||||
if name != 0 && objc.Send[bool](name, objc.RegisterName("isKindOfClass:"), objc.ID(objc.GetClass("NSString"))) {
|
||||
s := cocoa.NSString{ID: name}.String()
|
||||
if len(s) > 0 {
|
||||
@@ -174,8 +174,8 @@ func getAppName() string {
|
||||
}
|
||||
|
||||
// Fall back to process name.
|
||||
pi := objc.ID(classNSProcessInfo).Send(selProcessInfo)
|
||||
name := cocoa.NSString{ID: pi.Send(selProcessName)}
|
||||
pi := objc.ID(classNSProcessInfo).Send(sel_processInfo)
|
||||
name := cocoa.NSString{ID: pi.Send(sel_processName)}
|
||||
if s := name.String(); len(s) > 0 {
|
||||
return s
|
||||
}
|
||||
@@ -188,8 +188,8 @@ func createMenuBar() {
|
||||
appName := getAppName()
|
||||
|
||||
menubar := objc.ID(classNSMenu).Send(objc.RegisterName("alloc")).Send(objc.RegisterName("init"))
|
||||
nsApp := objc.ID(classNSApplication).Send(selNSApp)
|
||||
nsApp.Send(selSetMainMenu, menubar)
|
||||
nsApp := objc.ID(classNSApplication).Send(sel_sharedApplication)
|
||||
nsApp.Send(sel_setMainMenu, menubar)
|
||||
|
||||
// nsStr creates an NSString and schedules it for release.
|
||||
// This mirrors the behavior of @"..." literals in Objective-C which are
|
||||
@@ -202,100 +202,100 @@ func createMenuBar() {
|
||||
}
|
||||
defer func() {
|
||||
for _, s := range nsStrings {
|
||||
s.ID.Send(selRelease)
|
||||
s.ID.Send(sel_release)
|
||||
}
|
||||
}()
|
||||
|
||||
// Create the application menu.
|
||||
appMenuItem := menubar.Send(selAddItemWithTitle, nsStr(""), objc.SEL(0), nsStr(""))
|
||||
appMenuItem := menubar.Send(sel_addItemWithTitle_action_keyEquivalent, nsStr(""), objc.SEL(0), nsStr(""))
|
||||
appMenu := objc.ID(classNSMenu).Send(objc.RegisterName("alloc")).Send(objc.RegisterName("init"))
|
||||
appMenuItem.Send(selSetSubmenu, appMenu)
|
||||
appMenuItem.Send(sel_setSubmenu, appMenu)
|
||||
|
||||
// About <AppName>
|
||||
appMenu.Send(selAddItemWithTitle,
|
||||
appMenu.Send(sel_addItemWithTitle_action_keyEquivalent,
|
||||
nsStr("About "+appName),
|
||||
selOrderFrontStandardAboutPanel,
|
||||
sel_orderFrontStandardAboutPanel,
|
||||
nsStr(""))
|
||||
|
||||
appMenu.Send(selAddItem, objc.ID(classNSMenuItem).Send(selSeparatorItem))
|
||||
appMenu.Send(sel_addItem, objc.ID(classNSMenuItem).Send(sel_separatorItem))
|
||||
|
||||
// Services submenu
|
||||
servicesMenu := objc.ID(classNSMenu).Send(objc.RegisterName("alloc")).Send(objc.RegisterName("init"))
|
||||
nsApp.Send(selSetServicesMenu, servicesMenu)
|
||||
servicesMenuItem := appMenu.Send(selAddItemWithTitle,
|
||||
nsApp.Send(sel_setServicesMenu, servicesMenu)
|
||||
servicesMenuItem := appMenu.Send(sel_addItemWithTitle_action_keyEquivalent,
|
||||
nsStr("Services"),
|
||||
objc.SEL(0),
|
||||
nsStr(""))
|
||||
servicesMenuItem.Send(selSetSubmenu, servicesMenu)
|
||||
servicesMenu.Send(selRelease)
|
||||
servicesMenuItem.Send(sel_setSubmenu, servicesMenu)
|
||||
servicesMenu.Send(sel_release)
|
||||
|
||||
appMenu.Send(selAddItem, objc.ID(classNSMenuItem).Send(selSeparatorItem))
|
||||
appMenu.Send(sel_addItem, objc.ID(classNSMenuItem).Send(sel_separatorItem))
|
||||
|
||||
// Hide <AppName>
|
||||
appMenu.Send(selAddItemWithTitle,
|
||||
appMenu.Send(sel_addItemWithTitle_action_keyEquivalent,
|
||||
nsStr("Hide "+appName),
|
||||
selHide,
|
||||
sel_hide,
|
||||
nsStr("h"))
|
||||
|
||||
// Hide Others
|
||||
hideOthersItem := appMenu.Send(selAddItemWithTitle,
|
||||
hideOthersItem := appMenu.Send(sel_addItemWithTitle_action_keyEquivalent,
|
||||
nsStr("Hide Others"),
|
||||
selHideOtherApplications,
|
||||
sel_hideOtherApplications,
|
||||
nsStr("h"))
|
||||
// NSEventModifierFlagOption | NSEventModifierFlagCommand
|
||||
hideOthersItem.Send(selSetKeyEquivalentModifierMask, uintptr(1<<19|1<<20))
|
||||
hideOthersItem.Send(sel_setKeyEquivalentModifierMask, uintptr(1<<19|1<<20))
|
||||
|
||||
// Show All
|
||||
appMenu.Send(selAddItemWithTitle,
|
||||
appMenu.Send(sel_addItemWithTitle_action_keyEquivalent,
|
||||
nsStr("Show All"),
|
||||
selUnhideAllApplications,
|
||||
sel_unhideAllApplications,
|
||||
nsStr(""))
|
||||
|
||||
appMenu.Send(selAddItem, objc.ID(classNSMenuItem).Send(selSeparatorItem))
|
||||
appMenu.Send(sel_addItem, objc.ID(classNSMenuItem).Send(sel_separatorItem))
|
||||
|
||||
// Quit <AppName>
|
||||
appMenu.Send(selAddItemWithTitle,
|
||||
appMenu.Send(sel_addItemWithTitle_action_keyEquivalent,
|
||||
nsStr("Quit "+appName),
|
||||
selTerminate,
|
||||
sel_terminate,
|
||||
nsStr("q"))
|
||||
|
||||
// Create the Window menu.
|
||||
windowMenuItem := menubar.Send(selAddItemWithTitle, nsStr(""), objc.SEL(0), nsStr(""))
|
||||
menubar.Send(selRelease)
|
||||
windowMenuItem := menubar.Send(sel_addItemWithTitle_action_keyEquivalent, nsStr(""), objc.SEL(0), nsStr(""))
|
||||
menubar.Send(sel_release)
|
||||
|
||||
windowMenu := objc.ID(classNSMenu).Send(objc.RegisterName("alloc")).Send(
|
||||
selInitWithTitle, nsStr("Window"))
|
||||
nsApp.Send(selSetWindowsMenu, windowMenu)
|
||||
windowMenuItem.Send(selSetSubmenu, windowMenu)
|
||||
sel_initWithTitle, nsStr("Window"))
|
||||
nsApp.Send(sel_setWindowsMenu, windowMenu)
|
||||
windowMenuItem.Send(sel_setSubmenu, windowMenu)
|
||||
|
||||
// Minimize
|
||||
windowMenu.Send(selAddItemWithTitle,
|
||||
windowMenu.Send(sel_addItemWithTitle_action_keyEquivalent,
|
||||
nsStr("Minimize"),
|
||||
objc.RegisterName("performMiniaturize:"),
|
||||
nsStr("m"))
|
||||
|
||||
// Zoom
|
||||
windowMenu.Send(selAddItemWithTitle,
|
||||
windowMenu.Send(sel_addItemWithTitle_action_keyEquivalent,
|
||||
nsStr("Zoom"),
|
||||
objc.RegisterName("performZoom:"),
|
||||
nsStr(""))
|
||||
|
||||
windowMenu.Send(selAddItem, objc.ID(classNSMenuItem).Send(selSeparatorItem))
|
||||
windowMenu.Send(sel_addItem, objc.ID(classNSMenuItem).Send(sel_separatorItem))
|
||||
|
||||
// Bring All to Front
|
||||
windowMenu.Send(selAddItemWithTitle,
|
||||
windowMenu.Send(sel_addItemWithTitle_action_keyEquivalent,
|
||||
nsStr("Bring All to Front"),
|
||||
selArrangeInFront,
|
||||
sel_arrangeInFront,
|
||||
nsStr(""))
|
||||
|
||||
// Enter Full Screen
|
||||
windowMenu.Send(selAddItem, objc.ID(classNSMenuItem).Send(selSeparatorItem))
|
||||
fullScreenItem := windowMenu.Send(selAddItemWithTitle,
|
||||
windowMenu.Send(sel_addItem, objc.ID(classNSMenuItem).Send(sel_separatorItem))
|
||||
fullScreenItem := windowMenu.Send(sel_addItemWithTitle_action_keyEquivalent,
|
||||
nsStr("Enter Full Screen"),
|
||||
selToggleFullScreen,
|
||||
sel_toggleFullScreen,
|
||||
nsStr("f"))
|
||||
// NSEventModifierFlagControl | NSEventModifierFlagCommand
|
||||
fullScreenItem.Send(selSetKeyEquivalentModifierMask, uintptr(NSEventModifierFlagControl|NSEventModifierFlagCommand))
|
||||
fullScreenItem.Send(sel_setKeyEquivalentModifierMask, uintptr(NSEventModifierFlagControl|NSEventModifierFlagCommand))
|
||||
|
||||
// Prior to Snow Leopard, we need to use this oddly-named semi-private API
|
||||
// to get the application menu working properly.
|
||||
@@ -425,7 +425,7 @@ func platformInit() error {
|
||||
nil,
|
||||
[]objc.MethodDef{
|
||||
{
|
||||
Cmd: selSelectedKeyboardInputSourceChanged,
|
||||
Cmd: sel_selectedKeyboardInputSourceChanged,
|
||||
Fn: func(_ objc.ID, _ objc.SEL, _ objc.ID) {
|
||||
_ = updateUnicodeDataNS()
|
||||
},
|
||||
@@ -450,7 +450,7 @@ func platformInit() error {
|
||||
nil,
|
||||
[]objc.MethodDef{
|
||||
{
|
||||
Cmd: selApplicationShouldTerminate,
|
||||
Cmd: sel_applicationShouldTerminate,
|
||||
Fn: func(_ objc.ID, _ objc.SEL, sender objc.ID) uintptr {
|
||||
// Post close events to all windows.
|
||||
for _, window := range _glfw.windows {
|
||||
@@ -460,7 +460,7 @@ func platformInit() error {
|
||||
},
|
||||
},
|
||||
{
|
||||
Cmd: selApplicationDidChangeScreenParameters,
|
||||
Cmd: sel_applicationDidChangeScreenParameters,
|
||||
Fn: func(_ objc.ID, _ objc.SEL, _ objc.ID) {
|
||||
for _, window := range _glfw.windows {
|
||||
if window.context.client != NoAPI {
|
||||
@@ -471,41 +471,41 @@ func platformInit() error {
|
||||
},
|
||||
},
|
||||
{
|
||||
Cmd: selApplicationWillFinishLaunching,
|
||||
Cmd: sel_applicationWillFinishLaunching,
|
||||
Fn: func(_ objc.ID, _ objc.SEL, _ objc.ID) {
|
||||
// In the C original, this first tries to load MainMenu.nib from
|
||||
// the bundle, and only falls back to createMenuBar() if no nib exists.
|
||||
bundle := objc.ID(classNSBundle).Send(selMainBundle)
|
||||
bundle := objc.ID(classNSBundle).Send(sel_mainBundle)
|
||||
mainMenuNib := cocoa.NSString_alloc().InitWithUTF8String("MainMenu")
|
||||
nibType := cocoa.NSString_alloc().InitWithUTF8String("nib")
|
||||
nibPath := bundle.Send(objc.RegisterName("pathForResource:ofType:"), mainMenuNib.ID, nibType.ID)
|
||||
nibType.ID.Send(selRelease)
|
||||
nibType.ID.Send(sel_release)
|
||||
if nibPath != 0 {
|
||||
bundle.Send(objc.RegisterName("loadNibNamed:owner:topLevelObjects:"),
|
||||
mainMenuNib.ID,
|
||||
objc.ID(classNSApplication).Send(selNSApp),
|
||||
objc.ID(classNSApplication).Send(sel_sharedApplication),
|
||||
uintptr(unsafe.Pointer(&_glfw.platformWindow.nibObjects)))
|
||||
} else {
|
||||
createMenuBar()
|
||||
}
|
||||
mainMenuNib.ID.Send(selRelease)
|
||||
mainMenuNib.ID.Send(sel_release)
|
||||
},
|
||||
},
|
||||
{
|
||||
Cmd: selApplicationDidFinishLaunching,
|
||||
Cmd: sel_applicationDidFinishLaunching,
|
||||
Fn: func(_ objc.ID, _ objc.SEL, _ objc.ID) {
|
||||
nsApp := objc.ID(classNSApplication).Send(selNSApp)
|
||||
nsApp := objc.ID(classNSApplication).Send(sel_sharedApplication)
|
||||
postEmptyEvent()
|
||||
// In case we are unbundled, make us a proper UI application.
|
||||
// The C code gates this on _glfw.hints.init.ns.menubar which
|
||||
// defaults to true. Since Ebitengine always wants a menubar,
|
||||
// this is called unconditionally.
|
||||
nsApp.Send(selSetActivationPolicy, _NSApplicationActivationPolicyRegular)
|
||||
nsApp.Send(selStop, 0)
|
||||
nsApp.Send(sel_setActivationPolicy, _NSApplicationActivationPolicyRegular)
|
||||
nsApp.Send(sel_stop, 0)
|
||||
},
|
||||
},
|
||||
{
|
||||
Cmd: selApplicationDidHide,
|
||||
Cmd: sel_applicationDidHide,
|
||||
Fn: func(_ objc.ID, _ objc.SEL, _ objc.ID) {
|
||||
for _, monitor := range _glfw.monitors {
|
||||
monitor.restoreVideoModeNS()
|
||||
@@ -520,7 +520,7 @@ func platformInit() error {
|
||||
classGLFWApplicationDelegate = delegate
|
||||
|
||||
// Create the shared NSApplication instance.
|
||||
nsApp := objc.ID(classNSApplication).Send(selNSApp)
|
||||
nsApp := objc.ID(classNSApplication).Send(sel_sharedApplication)
|
||||
|
||||
// Create and set the application delegate.
|
||||
_glfw.platformWindow.delegate = objc.ID(classGLFWApplicationDelegate).Send(
|
||||
@@ -531,27 +531,27 @@ func platformInit() error {
|
||||
_glfw.platformWindow.helper = objc.ID(classGLFWHelper).Send(
|
||||
objc.RegisterName("alloc")).Send(objc.RegisterName("init"))
|
||||
|
||||
notificationCenter := objc.ID(classNSNotificationCenter).Send(selDefaultCenter)
|
||||
notificationCenter := objc.ID(classNSNotificationCenter).Send(sel_defaultCenter)
|
||||
nsTextInputContextKeyboardSelectionDidChangeNotification := cocoa.NSString_alloc().InitWithUTF8String(
|
||||
"NSTextInputContextKeyboardSelectionDidChangeNotification")
|
||||
notificationCenter.Send(selAddObserverSelectorNameObject,
|
||||
notificationCenter.Send(sel_addObserver_selector_name_object,
|
||||
_glfw.platformWindow.helper,
|
||||
selSelectedKeyboardInputSourceChanged,
|
||||
sel_selectedKeyboardInputSourceChanged,
|
||||
nsTextInputContextKeyboardSelectionDidChangeNotification.ID,
|
||||
0)
|
||||
nsTextInputContextKeyboardSelectionDidChangeNotification.ID.Send(selRelease)
|
||||
nsTextInputContextKeyboardSelectionDidChangeNotification.ID.Send(sel_release)
|
||||
|
||||
// Add a local monitor for keyUp events to work around Cocoa swallowing
|
||||
// key-up events when the menu bar is active.
|
||||
keyUpBlock := objc.NewBlock(func(_ objc.Block, event objc.ID) objc.ID {
|
||||
if uintptr(event.Send(selModifierFlags))&NSEventModifierFlagCommand != 0 {
|
||||
app := objc.ID(classNSApplication).Send(selNSApp)
|
||||
app.Send(selKeyWindow).Send(selSendEvent, event)
|
||||
if uintptr(event.Send(sel_modifierFlags))&NSEventModifierFlagCommand != 0 {
|
||||
app := objc.ID(classNSApplication).Send(sel_sharedApplication)
|
||||
app.Send(sel_keyWindow).Send(sel_sendEvent, event)
|
||||
}
|
||||
return event
|
||||
})
|
||||
_glfw.platformWindow.keyUpMonitor = objc.ID(classNSEvent).Send(
|
||||
selAddLocalMonitorForEventsMatchingMask,
|
||||
sel_addLocalMonitorForEventsMatchingMask_handler,
|
||||
_NSEventMaskKeyUp,
|
||||
keyUpBlock)
|
||||
|
||||
@@ -591,7 +591,7 @@ func platformInit() error {
|
||||
// calls stop: and posts an empty event, so this returns quickly.
|
||||
currentApp := objc.ID(classNSRunningApplication).Send(objc.RegisterName("currentApplication"))
|
||||
if !objc.Send[bool](currentApp, objc.RegisterName("isFinishedLaunching")) {
|
||||
nsApp.Send(selRun)
|
||||
nsApp.Send(sel_run)
|
||||
}
|
||||
|
||||
// Initialize NSGL (OpenGL context support).
|
||||
@@ -604,9 +604,9 @@ func platformInit() error {
|
||||
|
||||
// postEmptyEvent posts a no-op application-defined event to wake the run loop.
|
||||
func postEmptyEvent() {
|
||||
nsApp := objc.ID(classNSApplication).Send(selNSApp)
|
||||
nsApp := objc.ID(classNSApplication).Send(sel_sharedApplication)
|
||||
// NSApplicationDefined = 15
|
||||
event := objc.Send[objc.ID](objc.ID(classNSEvent), selOtherEventWithType,
|
||||
event := objc.Send[objc.ID](objc.ID(classNSEvent), sel_otherEventWithType_location_modifierFlags_timestamp_windowNumber_context_subtype_data1_data2,
|
||||
uintptr(15), // NSApplicationDefined
|
||||
cocoa.CGPoint{0, 0}, // location (NSPoint)
|
||||
uintptr(0), // modifierFlags
|
||||
@@ -617,7 +617,7 @@ func postEmptyEvent() {
|
||||
uintptr(0), // data1
|
||||
uintptr(0), // data2
|
||||
)
|
||||
nsApp.Send(selPostEventAtStart, event, true)
|
||||
nsApp.Send(sel_postEvent_atStart, event, true)
|
||||
}
|
||||
|
||||
// platformTerminate cleans up macOS platform resources.
|
||||
@@ -640,7 +640,7 @@ func platformTerminate() error {
|
||||
|
||||
// Release the application delegate.
|
||||
if _glfw.platformWindow.delegate != 0 {
|
||||
nsApp := objc.ID(classNSApplication).Send(selNSApp)
|
||||
nsApp := objc.ID(classNSApplication).Send(sel_sharedApplication)
|
||||
nsApp.Send(objc.RegisterName("setDelegate:"), 0)
|
||||
_glfw.platformWindow.delegate.Send(objc.RegisterName("release"))
|
||||
_glfw.platformWindow.delegate = 0
|
||||
|
||||
@@ -21,7 +21,7 @@ var nsScreenNumberKey objc.ID
|
||||
|
||||
func init() {
|
||||
classNSString := objc.GetClass("NSString")
|
||||
nsScreenNumberKey = objc.ID(classNSString).Send(selAlloc)
|
||||
nsScreenNumberKey = objc.ID(classNSString).Send(sel_alloc)
|
||||
nsScreenNumberKey = nsScreenNumberKey.Send(objc.RegisterName("initWithUTF8String:"), "NSScreenNumber\x00")
|
||||
}
|
||||
|
||||
@@ -419,27 +419,27 @@ func endFadeReservation(token uint32) {
|
||||
// getMonitorNameNS retrieves the name of a monitor.
|
||||
// It tries NSScreen.localizedName first (macOS 10.15+), then falls back to IOKit.
|
||||
func getMonitorNameNS(displayID uint32) string {
|
||||
screens := objc.ID(classNSScreen).Send(selScreens)
|
||||
count := int(screens.Send(selCount))
|
||||
screens := objc.ID(classNSScreen).Send(sel_screens)
|
||||
count := int(screens.Send(sel_count))
|
||||
for i := range count {
|
||||
screen := screens.Send(selObjectAtIndex, i)
|
||||
dict := screen.Send(selDeviceDescription)
|
||||
screenNum := dict.Send(selObjectForKey, nsScreenNumberKey)
|
||||
screen := screens.Send(sel_objectAtIndex, i)
|
||||
dict := screen.Send(sel_deviceDescription)
|
||||
screenNum := dict.Send(sel_objectForKey, nsScreenNumberKey)
|
||||
if screenNum == 0 {
|
||||
continue
|
||||
}
|
||||
sid := uint32(screenNum.Send(selUnsignedIntValue))
|
||||
sid := uint32(screenNum.Send(sel_unsignedIntValue))
|
||||
// HACK: Compare unit numbers instead of display IDs to work around
|
||||
// display replacement on machines with automatic graphics switching
|
||||
if cgDisplayUnitNumber(sid) == cgDisplayUnitNumber(displayID) {
|
||||
if screen.Send(objc.RegisterName("respondsToSelector:"), selLocalizedName) != 0 {
|
||||
nameID := screen.Send(selLocalizedName)
|
||||
if screen.Send(objc.RegisterName("respondsToSelector:"), sel_localizedName) != 0 {
|
||||
nameID := screen.Send(sel_localizedName)
|
||||
if nameID != 0 {
|
||||
utf8Ptr := nameID.Send(selUTF8String)
|
||||
utf8Ptr := nameID.Send(sel_UTF8String)
|
||||
if utf8Ptr != 0 {
|
||||
// Use lengthOfBytesUsingEncoding: to get the UTF-8 byte count.
|
||||
// NSString.length returns UTF-16 code units which differs for non-ASCII.
|
||||
length := int(nameID.Send(selLengthOfBytesUsingEncoding, NSUTF8StringEncoding))
|
||||
length := int(nameID.Send(sel_lengthOfBytesUsingEncoding, NSUTF8StringEncoding))
|
||||
if length > 0 {
|
||||
// Copy the string to avoid dangling pointer
|
||||
// when the NSString is released.
|
||||
@@ -546,16 +546,16 @@ func cStringToGoString(b []byte) string {
|
||||
// on machines with automatic graphics switching.
|
||||
func nsScreenForDisplayID(displayID uint32) objc.ID {
|
||||
unitNumber := cgDisplayUnitNumber(displayID)
|
||||
screens := objc.ID(classNSScreen).Send(selScreens)
|
||||
count := int(screens.Send(selCount))
|
||||
screens := objc.ID(classNSScreen).Send(sel_screens)
|
||||
count := int(screens.Send(sel_count))
|
||||
for i := range count {
|
||||
screen := screens.Send(selObjectAtIndex, i)
|
||||
dict := screen.Send(selDeviceDescription)
|
||||
screenNum := dict.Send(selObjectForKey, nsScreenNumberKey)
|
||||
screen := screens.Send(sel_objectAtIndex, i)
|
||||
dict := screen.Send(sel_deviceDescription)
|
||||
screenNum := dict.Send(sel_objectForKey, nsScreenNumberKey)
|
||||
if screenNum == 0 {
|
||||
continue
|
||||
}
|
||||
sid := uint32(screenNum.Send(selUnsignedIntValue))
|
||||
sid := uint32(screenNum.Send(sel_unsignedIntValue))
|
||||
if cgDisplayUnitNumber(sid) == unitNumber {
|
||||
return screen
|
||||
}
|
||||
@@ -732,8 +732,8 @@ func (m *Monitor) platformGetMonitorContentScale() (xscale, yscale float32, err
|
||||
return 0, 0, fmt.Errorf("glfw: cannot query content scale without screen: %w", PlatformError)
|
||||
}
|
||||
|
||||
points := objc.Send[cocoa.NSRect](m.platform.screen, selFrame)
|
||||
pixels := objc.Send[cocoa.NSRect](m.platform.screen, selConvertRectToBacking, points)
|
||||
points := objc.Send[cocoa.NSRect](m.platform.screen, sel_frame)
|
||||
pixels := objc.Send[cocoa.NSRect](m.platform.screen, sel_convertRectToBacking, points)
|
||||
|
||||
return float32(pixels.Size.Width / points.Size.Width),
|
||||
float32(pixels.Size.Height / points.Size.Height), nil
|
||||
@@ -749,7 +749,7 @@ func (m *Monitor) platformGetMonitorWorkarea() (xpos, ypos, width, height int) {
|
||||
return int(bounds.X), int(bounds.Y), int(bounds.Width), int(bounds.Height)
|
||||
}
|
||||
|
||||
visibleFrame := objc.Send[cgRect](screen, selVisibleFrame)
|
||||
visibleFrame := objc.Send[cgRect](screen, sel_visibleFrame)
|
||||
primaryBounds := cgDisplayBounds(cgMainDisplayID())
|
||||
|
||||
xpos = int(visibleFrame.X)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -135,7 +135,7 @@ func (w *Window) createContextNSGL(ctxconfig *ctxconfig, fbconfig_ *fbconfig) er
|
||||
addAttrib(0)
|
||||
|
||||
// Create the pixel format.
|
||||
pixelFormat := objc.ID(classNSOpenGLPixelFormat).Send(selAlloc).Send(selInitWithAttributes, uintptr(unsafe.Pointer(&attribs[0])))
|
||||
pixelFormat := objc.ID(classNSOpenGLPixelFormat).Send(sel_alloc).Send(sel_initWithAttributes, uintptr(unsafe.Pointer(&attribs[0])))
|
||||
if pixelFormat == 0 {
|
||||
return fmt.Errorf("glfw: NSGL: failed to find a suitable pixel format: %w", FormatUnavailable)
|
||||
}
|
||||
@@ -146,9 +146,9 @@ func (w *Window) createContextNSGL(ctxconfig *ctxconfig, fbconfig_ *fbconfig) er
|
||||
share = ctxconfig.share.context.platform.object
|
||||
}
|
||||
|
||||
context := objc.ID(classNSOpenGLContext).Send(selAlloc).Send(selInitWithFormatShareContext, uintptr(pixelFormat), uintptr(share))
|
||||
context := objc.ID(classNSOpenGLContext).Send(sel_alloc).Send(sel_initWithFormat_shareContext, uintptr(pixelFormat), uintptr(share))
|
||||
if context == 0 {
|
||||
pixelFormat.Send(selRelease)
|
||||
pixelFormat.Send(sel_release)
|
||||
return fmt.Errorf("glfw: NSGL: failed to create OpenGL context: %w", VersionUnavailable)
|
||||
}
|
||||
|
||||
@@ -158,14 +158,14 @@ func (w *Window) createContextNSGL(ctxconfig *ctxconfig, fbconfig_ *fbconfig) er
|
||||
// Set surface opacity for transparent windows.
|
||||
if fbconfig_.transparent {
|
||||
var opacity int32 = 0
|
||||
context.Send(selSetValuesForParameter, uintptr(unsafe.Pointer(&opacity)), uintptr(NSOpenGLCPSurfaceOpacity))
|
||||
context.Send(sel_setValues_forParameter, uintptr(unsafe.Pointer(&opacity)), uintptr(NSOpenGLCPSurfaceOpacity))
|
||||
}
|
||||
|
||||
// Set retina support. Always call this to explicitly enable or disable.
|
||||
w.platform.view.Send(selSetWantsBestResolutionOpenGLSurface, w.platform.retina)
|
||||
w.platform.view.Send(sel_setWantsBestResolutionOpenGLSurface, w.platform.retina)
|
||||
|
||||
// Set the view on the context.
|
||||
context.Send(selSetView, uintptr(w.platform.view))
|
||||
context.Send(sel_setView, uintptr(w.platform.view))
|
||||
|
||||
w.context.makeCurrent = makeContextCurrentNSGL
|
||||
w.context.swapBuffers = swapBuffersNSGL
|
||||
@@ -182,12 +182,12 @@ func makeContextCurrentNSGL(window *Window) error {
|
||||
defer pool.Release()
|
||||
|
||||
if window != nil {
|
||||
window.context.platform.object.Send(selMakeCurrentContext)
|
||||
window.context.platform.object.Send(sel_makeCurrentContext)
|
||||
if err := _glfw.contextSlot.set(uintptr(unsafe.Pointer(window))); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
objc.ID(classNSOpenGLContext).Send(selClearCurrentContext)
|
||||
objc.ID(classNSOpenGLContext).Send(sel_clearCurrentContext)
|
||||
if err := _glfw.contextSlot.set(0); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -203,7 +203,7 @@ func swapBuffersNSGL(window *Window) error {
|
||||
// windows with a non-visible occlusion state.
|
||||
if window.platform.occluded {
|
||||
var interval int32
|
||||
window.context.platform.object.Send(selGetValuesForParameter, uintptr(unsafe.Pointer(&interval)), uintptr(NSOpenGLCPSwapInterval))
|
||||
window.context.platform.object.Send(sel_getValues_forParameter, uintptr(unsafe.Pointer(&interval)), uintptr(NSOpenGLCPSwapInterval))
|
||||
if interval > 0 {
|
||||
const framerate = 60.0
|
||||
elapsed := float64(time.Now().UnixNano()) / float64(time.Second)
|
||||
@@ -214,7 +214,7 @@ func swapBuffersNSGL(window *Window) error {
|
||||
}
|
||||
}
|
||||
|
||||
window.context.platform.object.Send(selFlushBuffer)
|
||||
window.context.platform.object.Send(sel_flushBuffer)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -223,7 +223,7 @@ func swapIntervalNSGL(window *Window, interval int) error {
|
||||
defer pool.Release()
|
||||
|
||||
value := int32(interval)
|
||||
window.context.platform.object.Send(selSetValuesForParameter, uintptr(unsafe.Pointer(&value)), uintptr(NSOpenGLCPSwapInterval))
|
||||
window.context.platform.object.Send(sel_setValues_forParameter, uintptr(unsafe.Pointer(&value)), uintptr(NSOpenGLCPSwapInterval))
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -244,12 +244,12 @@ func destroyContextNSGL(window *Window) error {
|
||||
defer pool.Release()
|
||||
|
||||
if window.context.platform.pixelFormat != 0 {
|
||||
window.context.platform.pixelFormat.Send(selRelease)
|
||||
window.context.platform.pixelFormat.Send(sel_release)
|
||||
window.context.platform.pixelFormat = 0
|
||||
}
|
||||
|
||||
if window.context.platform.object != 0 {
|
||||
window.context.platform.object.Send(selRelease)
|
||||
window.context.platform.object.Send(sel_release)
|
||||
window.context.platform.object = 0
|
||||
}
|
||||
|
||||
|
||||
@@ -40,29 +40,29 @@ var (
|
||||
)
|
||||
|
||||
var (
|
||||
selPixelFormat = objc.RegisterName("pixelFormat")
|
||||
selSetDevice = objc.RegisterName("setDevice:")
|
||||
selSetOpaque = objc.RegisterName("setOpaque:")
|
||||
selSetPixelFormat = objc.RegisterName("setPixelFormat:")
|
||||
selNew = objc.RegisterName("new")
|
||||
selSetColorspace = objc.RegisterName("setColorspace:")
|
||||
selSetMaximumDrawableCount = objc.RegisterName("setMaximumDrawableCount:")
|
||||
selSetDisplaySyncEnabled = objc.RegisterName("setDisplaySyncEnabled:")
|
||||
selSetDrawableSize = objc.RegisterName("setDrawableSize:")
|
||||
selNextDrawable = objc.RegisterName("nextDrawable")
|
||||
selPresentsWithTransaction = objc.RegisterName("presentsWithTransaction")
|
||||
selSetPresentsWithTransaction = objc.RegisterName("setPresentsWithTransaction:")
|
||||
selSetFramebufferOnly = objc.RegisterName("setFramebufferOnly:")
|
||||
selTexture = objc.RegisterName("texture")
|
||||
selPresent = objc.RegisterName("present")
|
||||
selAlloc = objc.RegisterName("alloc")
|
||||
selInitWithMetalLayer = objc.RegisterName("initWithMetalLayer:")
|
||||
selSetDelegate = objc.RegisterName("setDelegate:")
|
||||
selAddToOneLoopForMode = objc.RegisterName("addToRunLoop:forMode:")
|
||||
selRemoveFromRunLoopForMode = objc.RegisterName("removeFromRunLoop:forMode:")
|
||||
selSetPaused = objc.RegisterName("setPaused:")
|
||||
selDrawable = objc.RegisterName("drawable")
|
||||
selRelease = objc.RegisterName("release")
|
||||
sel_pixelFormat = objc.RegisterName("pixelFormat")
|
||||
sel_setDevice = objc.RegisterName("setDevice:")
|
||||
sel_setOpaque = objc.RegisterName("setOpaque:")
|
||||
sel_setPixelFormat = objc.RegisterName("setPixelFormat:")
|
||||
sel_new = objc.RegisterName("new")
|
||||
sel_setColorspace = objc.RegisterName("setColorspace:")
|
||||
sel_setMaximumDrawableCount = objc.RegisterName("setMaximumDrawableCount:")
|
||||
sel_setDisplaySyncEnabled = objc.RegisterName("setDisplaySyncEnabled:")
|
||||
sel_setDrawableSize = objc.RegisterName("setDrawableSize:")
|
||||
sel_nextDrawable = objc.RegisterName("nextDrawable")
|
||||
sel_presentsWithTransaction = objc.RegisterName("presentsWithTransaction")
|
||||
sel_setPresentsWithTransaction = objc.RegisterName("setPresentsWithTransaction:")
|
||||
sel_setFramebufferOnly = objc.RegisterName("setFramebufferOnly:")
|
||||
sel_texture = objc.RegisterName("texture")
|
||||
sel_present = objc.RegisterName("present")
|
||||
sel_alloc = objc.RegisterName("alloc")
|
||||
sel_initWithMetalLayer = objc.RegisterName("initWithMetalLayer:")
|
||||
sel_setDelegate = objc.RegisterName("setDelegate:")
|
||||
sel_addToRunLoop_forMode = objc.RegisterName("addToRunLoop:forMode:")
|
||||
sel_removeFromRunLoop_forMode = objc.RegisterName("removeFromRunLoop:forMode:")
|
||||
sel_setPaused = objc.RegisterName("setPaused:")
|
||||
sel_drawable = objc.RegisterName("drawable")
|
||||
sel_release = objc.RegisterName("release")
|
||||
)
|
||||
|
||||
// Layer is an object that manages image-based content and
|
||||
@@ -118,14 +118,14 @@ func NewMetalLayer(colorSpace color.ColorSpace) (MetalLayer, error) {
|
||||
return MetalLayer{}, fmt.Errorf("ca: unsupported color space: %d", colorSpace)
|
||||
}
|
||||
|
||||
layer := objc.ID(classCAMetalLayer).Send(selNew)
|
||||
layer := objc.ID(classCAMetalLayer).Send(sel_new)
|
||||
// setColorspace: is available from iOS 13.0?
|
||||
// https://github.com/hajimehoshi/ebiten/commit/3af351a2aa31e30affd433429c42130015b302f3
|
||||
// TODO: Enable this on iOS as well.
|
||||
if runtime.GOOS != "ios" {
|
||||
// Dlsym returns pointer to symbol so dereference it.
|
||||
colorspace, _, _ := purego.SyscallN(cgColorSpaceCreateWithName, **(**uintptr)(unsafe.Pointer(&colorSpaceSym)))
|
||||
layer.Send(selSetColorspace, colorspace)
|
||||
layer.Send(sel_setColorspace, colorspace)
|
||||
purego.SyscallN(cgColorSpaceRelease, colorspace)
|
||||
}
|
||||
return MetalLayer{layer}, nil
|
||||
@@ -140,19 +140,19 @@ func (ml MetalLayer) Layer() unsafe.Pointer {
|
||||
//
|
||||
// Reference: https://developer.apple.com/documentation/quartzcore/cametallayer/1478155-pixelformat?language=objc.
|
||||
func (ml MetalLayer) PixelFormat() mtl.PixelFormat {
|
||||
return mtl.PixelFormat(ml.metalLayer.Send(selPixelFormat))
|
||||
return mtl.PixelFormat(ml.metalLayer.Send(sel_pixelFormat))
|
||||
}
|
||||
|
||||
// SetDevice sets the Metal device responsible for the layer's drawable resources.
|
||||
//
|
||||
// Reference: https://developer.apple.com/documentation/quartzcore/cametallayer/1478163-device?language=objc.
|
||||
func (ml MetalLayer) SetDevice(device mtl.Device) {
|
||||
ml.metalLayer.Send(selSetDevice, uintptr(device.Device()))
|
||||
ml.metalLayer.Send(sel_setDevice, uintptr(device.Device()))
|
||||
}
|
||||
|
||||
// SetOpaque a Boolean value indicating whether the layer contains completely opaque content.
|
||||
func (ml MetalLayer) SetOpaque(opaque bool) {
|
||||
ml.metalLayer.Send(selSetOpaque, opaque)
|
||||
ml.metalLayer.Send(sel_setOpaque, opaque)
|
||||
}
|
||||
|
||||
// SetPixelFormat controls the pixel format of textures for rendering layer content.
|
||||
@@ -168,7 +168,7 @@ func (ml MetalLayer) SetPixelFormat(pf mtl.PixelFormat) {
|
||||
default:
|
||||
panic(fmt.Sprintf("ca: invalid pixel format %d", pf))
|
||||
}
|
||||
ml.metalLayer.Send(selSetPixelFormat, uint(pf))
|
||||
ml.metalLayer.Send(sel_setPixelFormat, uint(pf))
|
||||
}
|
||||
|
||||
// SetMaximumDrawableCount controls the number of Metal drawables in the resource pool
|
||||
@@ -181,7 +181,7 @@ func (ml MetalLayer) SetMaximumDrawableCount(count int) {
|
||||
if count < 2 || count > 3 {
|
||||
panic(fmt.Sprintf("ca: failed trying to set maximumDrawableCount to %d outside of the valid range of [2, 3]", count))
|
||||
}
|
||||
ml.metalLayer.Send(selSetMaximumDrawableCount, count)
|
||||
ml.metalLayer.Send(sel_setMaximumDrawableCount, count)
|
||||
}
|
||||
|
||||
// SetDisplaySyncEnabled controls whether the Metal layer and its drawables
|
||||
@@ -192,21 +192,21 @@ func (ml MetalLayer) SetDisplaySyncEnabled(enabled bool) {
|
||||
if runtime.GOOS == "ios" {
|
||||
return
|
||||
}
|
||||
ml.metalLayer.Send(selSetDisplaySyncEnabled, enabled)
|
||||
ml.metalLayer.Send(sel_setDisplaySyncEnabled, enabled)
|
||||
}
|
||||
|
||||
// SetDrawableSize sets the size, in pixels, of textures for rendering layer content.
|
||||
//
|
||||
// Reference: https://developer.apple.com/documentation/quartzcore/cametallayer/1478174-drawablesize?language=objc.
|
||||
func (ml MetalLayer) SetDrawableSize(width, height int) {
|
||||
ml.metalLayer.Send(selSetDrawableSize, cocoa.CGSize{Width: cocoa.CGFloat(width), Height: cocoa.CGFloat(height)})
|
||||
ml.metalLayer.Send(sel_setDrawableSize, cocoa.CGSize{Width: cocoa.CGFloat(width), Height: cocoa.CGFloat(height)})
|
||||
}
|
||||
|
||||
// NextDrawable returns a Metal drawable.
|
||||
//
|
||||
// Reference: https://developer.apple.com/documentation/quartzcore/cametallayer/1478172-nextdrawable?language=objc.
|
||||
func (ml MetalLayer) NextDrawable() (MetalDrawable, error) {
|
||||
md := ml.metalLayer.Send(selNextDrawable)
|
||||
md := ml.metalLayer.Send(sel_nextDrawable)
|
||||
if md == 0 {
|
||||
return MetalDrawable{}, errors.New("nextDrawable returned nil")
|
||||
}
|
||||
@@ -217,21 +217,21 @@ func (ml MetalLayer) NextDrawable() (MetalDrawable, error) {
|
||||
//
|
||||
// Reference: https://developer.apple.com/documentation/quartzcore/cametallayer/1478157-presentswithtransaction?language=objc
|
||||
func (ml MetalLayer) PresentsWithTransaction() bool {
|
||||
return ml.metalLayer.Send(selPresentsWithTransaction) != 0
|
||||
return ml.metalLayer.Send(sel_presentsWithTransaction) != 0
|
||||
}
|
||||
|
||||
// SetPresentsWithTransaction sets a Boolean value that determines whether the layer presents its content using a Core Animation transaction.
|
||||
//
|
||||
// Reference: https://developer.apple.com/documentation/quartzcore/cametallayer/1478157-presentswithtransaction?language=objc
|
||||
func (ml MetalLayer) SetPresentsWithTransaction(presentsWithTransaction bool) {
|
||||
ml.metalLayer.Send(selSetPresentsWithTransaction, presentsWithTransaction)
|
||||
ml.metalLayer.Send(sel_setPresentsWithTransaction, presentsWithTransaction)
|
||||
}
|
||||
|
||||
// SetFramebufferOnly sets a Boolean value that determines whether the layer’s textures are used only for rendering.
|
||||
//
|
||||
// Reference: https://developer.apple.com/documentation/quartzcore/cametallayer/1478168-framebufferonly?language=objc
|
||||
func (ml MetalLayer) SetFramebufferOnly(framebufferOnly bool) {
|
||||
ml.metalLayer.Send(selSetFramebufferOnly, framebufferOnly)
|
||||
ml.metalLayer.Send(sel_setFramebufferOnly, framebufferOnly)
|
||||
}
|
||||
|
||||
// MetalDrawable is a displayable resource that can be rendered or written to by Metal.
|
||||
@@ -250,14 +250,14 @@ func (md MetalDrawable) Drawable() unsafe.Pointer {
|
||||
//
|
||||
// Reference: https://developer.apple.com/documentation/quartzcore/cametaldrawable/1478159-texture?language=objc.
|
||||
func (md MetalDrawable) Texture() mtl.Texture {
|
||||
return mtl.NewTexture(md.metalDrawable.Send(selTexture))
|
||||
return mtl.NewTexture(md.metalDrawable.Send(sel_texture))
|
||||
}
|
||||
|
||||
// Present presents the drawable onscreen as soon as possible.
|
||||
//
|
||||
// Reference: https://developer.apple.com/documentation/metal/mtldrawable/1470284-present?language=objc.
|
||||
func (md MetalDrawable) Present() {
|
||||
md.metalDrawable.Send(selPresent)
|
||||
md.metalDrawable.Send(sel_present)
|
||||
}
|
||||
|
||||
// MetalDisplayLink is a class your Metal app uses to register for callbacks to synchronize its animations for a display.
|
||||
@@ -271,39 +271,39 @@ type MetalDisplayLink struct {
|
||||
//
|
||||
// Reference: https://developer.apple.com/documentation/quartzcore/cametaldisplaylink/delegate?language=objc
|
||||
func (m MetalDisplayLink) SetDelegate(delegate objc.ID) {
|
||||
m.Send(selSetDelegate, delegate)
|
||||
m.Send(sel_setDelegate, delegate)
|
||||
}
|
||||
|
||||
// AddToRunLoop registers the display link with a run loop.
|
||||
//
|
||||
// Reference: https://developer.apple.com/documentation/quartzcore/cametaldisplaylink/add(to:formode:)?language=objc
|
||||
func (m MetalDisplayLink) AddToRunLoop(runLoop cocoa.NSRunLoop, mode cocoa.NSRunLoopMode) {
|
||||
m.Send(selAddToOneLoopForMode, runLoop, mode)
|
||||
m.Send(sel_addToRunLoop_forMode, runLoop, mode)
|
||||
}
|
||||
|
||||
// RemoveFromRunLoop removes a mode’s display link from a run loop.
|
||||
//
|
||||
// Reference: https://developer.apple.com/documentation/quartzcore/cametaldisplaylink/remove(from:formode:)?language=objc
|
||||
func (m MetalDisplayLink) RemoveFromRunLoop(runLoop cocoa.NSRunLoop, mode cocoa.NSRunLoopMode) {
|
||||
m.Send(selRemoveFromRunLoopForMode, runLoop, mode)
|
||||
m.Send(sel_removeFromRunLoop_forMode, runLoop, mode)
|
||||
}
|
||||
|
||||
// SetPaused sets a Boolean value that indicates whether the system suspends the display link’s notifications to the target.
|
||||
//
|
||||
// https://developer.apple.com/documentation/quartzcore/cametaldisplaylink/ispaused?language=objc
|
||||
func (m MetalDisplayLink) SetPaused(paused bool) {
|
||||
m.Send(selSetPaused, paused)
|
||||
m.Send(sel_setPaused, paused)
|
||||
}
|
||||
|
||||
func (m MetalDisplayLink) Release() {
|
||||
m.Send(selRelease)
|
||||
m.Send(sel_release)
|
||||
}
|
||||
|
||||
// NewMetalDisplayLink creates a display link for Metal from a Core Animation layer.
|
||||
//
|
||||
// Reference: https://developer.apple.com/documentation/quartzcore/cametaldisplaylink/init(metallayer:)?language=objc
|
||||
func NewMetalDisplayLink(metalLayer MetalLayer) MetalDisplayLink {
|
||||
displayLink := objc.ID(classCAMetalDisplayLink).Send(selAlloc).Send(selInitWithMetalLayer, metalLayer.metalLayer)
|
||||
displayLink := objc.ID(classCAMetalDisplayLink).Send(sel_alloc).Send(sel_initWithMetalLayer, metalLayer.metalLayer)
|
||||
return MetalDisplayLink{displayLink}
|
||||
}
|
||||
|
||||
@@ -318,5 +318,5 @@ type MetalDisplayLinkUpdate struct {
|
||||
//
|
||||
// https://developer.apple.com/documentation/quartzcore/cametaldisplaylink/update/drawable?language=objc
|
||||
func (m MetalDisplayLinkUpdate) Drawable() MetalDrawable {
|
||||
return MetalDrawable{m.Send(selDrawable)}
|
||||
return MetalDrawable{m.Send(sel_drawable)}
|
||||
}
|
||||
|
||||
@@ -43,8 +43,8 @@ func (v *view) initDisplayLink() error {
|
||||
}
|
||||
|
||||
var (
|
||||
selProcessInfo = objc.RegisterName("processInfo")
|
||||
selOperatingSystemVersion = objc.RegisterName("operatingSystemVersion")
|
||||
sel_processInfo = objc.RegisterName("processInfo")
|
||||
sel_operatingSystemVersion = objc.RegisterName("operatingSystemVersion")
|
||||
|
||||
classNSProcessInfo = objc.GetClass("NSProcessInfo")
|
||||
)
|
||||
@@ -80,7 +80,7 @@ func init() {
|
||||
}
|
||||
|
||||
func isCAMetalDisplayLinkAvailable() bool {
|
||||
version := objc.Send[nsOperatingSystemVersion](objc.ID(classNSProcessInfo).Send(selProcessInfo), selOperatingSystemVersion)
|
||||
version := objc.Send[nsOperatingSystemVersion](objc.ID(classNSProcessInfo).Send(sel_processInfo), sel_operatingSystemVersion)
|
||||
if version.majorVersion >= 14 {
|
||||
return nsClassFromString(cocoa.NSString_alloc().InitWithUTF8String("CAMetalDisplayLink")) != 0
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ import (
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/shaderir"
|
||||
)
|
||||
|
||||
var selSupportsFamily = objc.RegisterName("supportsFamily:")
|
||||
var sel_supportsFamily = objc.RegisterName("supportsFamily:")
|
||||
|
||||
type Graphics struct {
|
||||
view view
|
||||
@@ -568,7 +568,7 @@ func (g *Graphics) MaxImageSize() int {
|
||||
|
||||
// supportsFamily is available as of macOS 10.15+ and iOS 13.0+.
|
||||
// https://developer.apple.com/documentation/metal/mtldevice/3143473-supportsfamily
|
||||
if d.RespondsToSelector(selSupportsFamily) {
|
||||
if d.RespondsToSelector(sel_supportsFamily) {
|
||||
// https://developer.apple.com/metal/Metal-Feature-Set-Tables.pdf
|
||||
g.maxImageSize = 8192
|
||||
switch {
|
||||
|
||||
@@ -484,85 +484,85 @@ var (
|
||||
)
|
||||
|
||||
var (
|
||||
selLength = objc.RegisterName("length")
|
||||
selIsHeadless = objc.RegisterName("isHeadless")
|
||||
selIsLowPower = objc.RegisterName("isLowPower")
|
||||
selName = objc.RegisterName("name")
|
||||
selSupportsFamily = objc.RegisterName("supportsFamily:")
|
||||
selSupportsFeatureSet = objc.RegisterName("supportsFeatureSet:")
|
||||
selNewCommandQueue = objc.RegisterName("newCommandQueue")
|
||||
selNewLibraryWithSource_options_error = objc.RegisterName("newLibraryWithSource:options:error:")
|
||||
selNewLibraryWithData_error = objc.RegisterName("newLibraryWithData:error:")
|
||||
selRelease = objc.RegisterName("release")
|
||||
selRetain = objc.RegisterName("retain")
|
||||
selNew = objc.RegisterName("new")
|
||||
selLocalizedDescription = objc.RegisterName("localizedDescription")
|
||||
selSetVertexFunction = objc.RegisterName("setVertexFunction:")
|
||||
selSetFragmentFunction = objc.RegisterName("setFragmentFunction:")
|
||||
selColorAttachments = objc.RegisterName("colorAttachments")
|
||||
selObjectAtIndexedSubscript = objc.RegisterName("objectAtIndexedSubscript:")
|
||||
selSetPixelFormat = objc.RegisterName("setPixelFormat:")
|
||||
selSetBlendingEnabled = objc.RegisterName("setBlendingEnabled:")
|
||||
selSetDestinationAlphaBlendFactor = objc.RegisterName("setDestinationAlphaBlendFactor:")
|
||||
selSetDestinationRGBBlendFactor = objc.RegisterName("setDestinationRGBBlendFactor:")
|
||||
selSetSourceAlphaBlendFactor = objc.RegisterName("setSourceAlphaBlendFactor:")
|
||||
selSetSourceRGBBlendFactor = objc.RegisterName("setSourceRGBBlendFactor:")
|
||||
selSetAlphaBlendOperation = objc.RegisterName("setAlphaBlendOperation:")
|
||||
selSetRgbBlendOperation = objc.RegisterName("setRgbBlendOperation:")
|
||||
selSetWriteMask = objc.RegisterName("setWriteMask:")
|
||||
selSetStencilAttachmentPixelFormat = objc.RegisterName("setStencilAttachmentPixelFormat:")
|
||||
selNewRenderPipelineStateWithDescriptor_error = objc.RegisterName("newRenderPipelineStateWithDescriptor:error:")
|
||||
selNewBufferWithBytes_length_options = objc.RegisterName("newBufferWithBytes:length:options:")
|
||||
selNewBufferWithLength_options = objc.RegisterName("newBufferWithLength:options:")
|
||||
selSetTextureType = objc.RegisterName("setTextureType:")
|
||||
selDidModifyRange = objc.RegisterName("didModifyRange:")
|
||||
selSetWidth = objc.RegisterName("setWidth:")
|
||||
selSetHeight = objc.RegisterName("setHeight:")
|
||||
selWidth = objc.RegisterName("width")
|
||||
selHeight = objc.RegisterName("height")
|
||||
selContents = objc.RegisterName("contents")
|
||||
selSetStorageMode = objc.RegisterName("setStorageMode:")
|
||||
selSetUsage = objc.RegisterName("setUsage:")
|
||||
selNewTextureWithDescriptor = objc.RegisterName("newTextureWithDescriptor:")
|
||||
selCommandBuffer = objc.RegisterName("commandBuffer")
|
||||
selStatus = objc.RegisterName("status")
|
||||
selPresentDrawable = objc.RegisterName("presentDrawable:")
|
||||
selCommit = objc.RegisterName("commit")
|
||||
selWaitUntilCompleted = objc.RegisterName("waitUntilCompleted")
|
||||
selWaitUntilScheduled = objc.RegisterName("waitUntilScheduled")
|
||||
selRenderCommandEncoderWithDescriptor = objc.RegisterName("renderCommandEncoderWithDescriptor:")
|
||||
selStencilAttachment = objc.RegisterName("stencilAttachment")
|
||||
selSetLoadAction = objc.RegisterName("setLoadAction:")
|
||||
selSetStoreAction = objc.RegisterName("setStoreAction:")
|
||||
selSetTexture = objc.RegisterName("setTexture:")
|
||||
selSetClearColor = objc.RegisterName("setClearColor:")
|
||||
selBlitCommandEncoder = objc.RegisterName("blitCommandEncoder")
|
||||
selEndEncoding = objc.RegisterName("endEncoding")
|
||||
selSetRenderPipelineState = objc.RegisterName("setRenderPipelineState:")
|
||||
selSetViewport = objc.RegisterName("setViewport:")
|
||||
selSetScissorRect = objc.RegisterName("setScissorRect:")
|
||||
selSetVertexBuffer_offset_atIndex = objc.RegisterName("setVertexBuffer:offset:atIndex:")
|
||||
selSetVertexBytes_length_atIndex = objc.RegisterName("setVertexBytes:length:atIndex:")
|
||||
selSetFragmentBytes_length_atIndex = objc.RegisterName("setFragmentBytes:length:atIndex:")
|
||||
selSetFragmentTexture_atIndex = objc.RegisterName("setFragmentTexture:atIndex:")
|
||||
selSetBlendColorRedGreenBlueAlpha = objc.RegisterName("setBlendColorRed:green:blue:alpha:")
|
||||
selSetDepthStencilState = objc.RegisterName("setDepthStencilState:")
|
||||
selDrawPrimitives_vertexStart_vertexCount = objc.RegisterName("drawPrimitives:vertexStart:vertexCount:")
|
||||
selDrawIndexedPrimitives_indexCount_indexType_indexBuffer_indexBufferOffset = objc.RegisterName("drawIndexedPrimitives:indexCount:indexType:indexBuffer:indexBufferOffset:")
|
||||
selSynchronizeResource = objc.RegisterName("synchronizeResource:")
|
||||
selSynchronizeTexture_slice_level = objc.RegisterName("synchronizeTexture:slice:level:")
|
||||
selCopyFromTexture_sourceSlice_sourceLevel_sourceOrigin_sourceSize_toTexture_destinationSlice_destinationLevel_destinationOrigin = objc.RegisterName("copyFromTexture:sourceSlice:sourceLevel:sourceOrigin:sourceSize:toTexture:destinationSlice:destinationLevel:destinationOrigin:")
|
||||
selNewFunctionWithName = objc.RegisterName("newFunctionWithName:")
|
||||
selBackFaceStencil = objc.RegisterName("backFaceStencil")
|
||||
selFrontFaceStencil = objc.RegisterName("frontFaceStencil")
|
||||
selSetStencilFailureOperation = objc.RegisterName("setStencilFailureOperation:")
|
||||
selSetDepthFailureOperation = objc.RegisterName("setDepthFailureOperation:")
|
||||
selSetDepthStencilPassOperation = objc.RegisterName("setDepthStencilPassOperation:")
|
||||
selSetStencilCompareFunction = objc.RegisterName("setStencilCompareFunction:")
|
||||
selNewDepthStencilStateWithDescriptor = objc.RegisterName("newDepthStencilStateWithDescriptor:")
|
||||
selReplaceRegion_mipmapLevel_withBytes_bytesPerRow = objc.RegisterName("replaceRegion:mipmapLevel:withBytes:bytesPerRow:")
|
||||
selGetBytes_bytesPerRow_fromRegion_mipmapLevel = objc.RegisterName("getBytes:bytesPerRow:fromRegion:mipmapLevel:")
|
||||
selRespondsToSelector = objc.RegisterName("respondsToSelector:")
|
||||
sel_length = objc.RegisterName("length")
|
||||
sel_isHeadless = objc.RegisterName("isHeadless")
|
||||
sel_isLowPower = objc.RegisterName("isLowPower")
|
||||
sel_name = objc.RegisterName("name")
|
||||
sel_supportsFamily = objc.RegisterName("supportsFamily:")
|
||||
sel_supportsFeatureSet = objc.RegisterName("supportsFeatureSet:")
|
||||
sel_newCommandQueue = objc.RegisterName("newCommandQueue")
|
||||
sel_newLibraryWithSource_options_error = objc.RegisterName("newLibraryWithSource:options:error:")
|
||||
sel_newLibraryWithData_error = objc.RegisterName("newLibraryWithData:error:")
|
||||
sel_release = objc.RegisterName("release")
|
||||
sel_retain = objc.RegisterName("retain")
|
||||
sel_new = objc.RegisterName("new")
|
||||
sel_localizedDescription = objc.RegisterName("localizedDescription")
|
||||
sel_setVertexFunction = objc.RegisterName("setVertexFunction:")
|
||||
sel_setFragmentFunction = objc.RegisterName("setFragmentFunction:")
|
||||
sel_colorAttachments = objc.RegisterName("colorAttachments")
|
||||
sel_objectAtIndexedSubscript = objc.RegisterName("objectAtIndexedSubscript:")
|
||||
sel_setPixelFormat = objc.RegisterName("setPixelFormat:")
|
||||
sel_setBlendingEnabled = objc.RegisterName("setBlendingEnabled:")
|
||||
sel_setDestinationAlphaBlendFactor = objc.RegisterName("setDestinationAlphaBlendFactor:")
|
||||
sel_setDestinationRGBBlendFactor = objc.RegisterName("setDestinationRGBBlendFactor:")
|
||||
sel_setSourceAlphaBlendFactor = objc.RegisterName("setSourceAlphaBlendFactor:")
|
||||
sel_setSourceRGBBlendFactor = objc.RegisterName("setSourceRGBBlendFactor:")
|
||||
sel_setAlphaBlendOperation = objc.RegisterName("setAlphaBlendOperation:")
|
||||
sel_setRgbBlendOperation = objc.RegisterName("setRgbBlendOperation:")
|
||||
sel_setWriteMask = objc.RegisterName("setWriteMask:")
|
||||
sel_setStencilAttachmentPixelFormat = objc.RegisterName("setStencilAttachmentPixelFormat:")
|
||||
sel_newRenderPipelineStateWithDescriptor_error = objc.RegisterName("newRenderPipelineStateWithDescriptor:error:")
|
||||
sel_newBufferWithBytes_length_options = objc.RegisterName("newBufferWithBytes:length:options:")
|
||||
sel_newBufferWithLength_options = objc.RegisterName("newBufferWithLength:options:")
|
||||
sel_setTextureType = objc.RegisterName("setTextureType:")
|
||||
sel_didModifyRange = objc.RegisterName("didModifyRange:")
|
||||
sel_setWidth = objc.RegisterName("setWidth:")
|
||||
sel_setHeight = objc.RegisterName("setHeight:")
|
||||
sel_width = objc.RegisterName("width")
|
||||
sel_height = objc.RegisterName("height")
|
||||
sel_contents = objc.RegisterName("contents")
|
||||
sel_setStorageMode = objc.RegisterName("setStorageMode:")
|
||||
sel_setUsage = objc.RegisterName("setUsage:")
|
||||
sel_newTextureWithDescriptor = objc.RegisterName("newTextureWithDescriptor:")
|
||||
sel_commandBuffer = objc.RegisterName("commandBuffer")
|
||||
sel_status = objc.RegisterName("status")
|
||||
sel_presentDrawable = objc.RegisterName("presentDrawable:")
|
||||
sel_commit = objc.RegisterName("commit")
|
||||
sel_waitUntilCompleted = objc.RegisterName("waitUntilCompleted")
|
||||
sel_waitUntilScheduled = objc.RegisterName("waitUntilScheduled")
|
||||
sel_renderCommandEncoderWithDescriptor = objc.RegisterName("renderCommandEncoderWithDescriptor:")
|
||||
sel_stencilAttachment = objc.RegisterName("stencilAttachment")
|
||||
sel_setLoadAction = objc.RegisterName("setLoadAction:")
|
||||
sel_setStoreAction = objc.RegisterName("setStoreAction:")
|
||||
sel_setTexture = objc.RegisterName("setTexture:")
|
||||
sel_setClearColor = objc.RegisterName("setClearColor:")
|
||||
sel_blitCommandEncoder = objc.RegisterName("blitCommandEncoder")
|
||||
sel_endEncoding = objc.RegisterName("endEncoding")
|
||||
sel_setRenderPipelineState = objc.RegisterName("setRenderPipelineState:")
|
||||
sel_setViewport = objc.RegisterName("setViewport:")
|
||||
sel_setScissorRect = objc.RegisterName("setScissorRect:")
|
||||
sel_setVertexBuffer_offset_atIndex = objc.RegisterName("setVertexBuffer:offset:atIndex:")
|
||||
sel_setVertexBytes_length_atIndex = objc.RegisterName("setVertexBytes:length:atIndex:")
|
||||
sel_setFragmentBytes_length_atIndex = objc.RegisterName("setFragmentBytes:length:atIndex:")
|
||||
sel_setFragmentTexture_atIndex = objc.RegisterName("setFragmentTexture:atIndex:")
|
||||
sel_setBlendColorRed_green_blue_alpha = objc.RegisterName("setBlendColorRed:green:blue:alpha:")
|
||||
sel_setDepthStencilState = objc.RegisterName("setDepthStencilState:")
|
||||
sel_drawPrimitives_vertexStart_vertexCount = objc.RegisterName("drawPrimitives:vertexStart:vertexCount:")
|
||||
sel_drawIndexedPrimitives_indexCount_indexType_indexBuffer_indexBufferOffset = objc.RegisterName("drawIndexedPrimitives:indexCount:indexType:indexBuffer:indexBufferOffset:")
|
||||
sel_synchronizeResource = objc.RegisterName("synchronizeResource:")
|
||||
sel_synchronizeTexture_slice_level = objc.RegisterName("synchronizeTexture:slice:level:")
|
||||
sel_copyFromTexture_sourceSlice_sourceLevel_sourceOrigin_sourceSize_toTexture_destinationSlice_destinationLevel_destinationOrigin = objc.RegisterName("copyFromTexture:sourceSlice:sourceLevel:sourceOrigin:sourceSize:toTexture:destinationSlice:destinationLevel:destinationOrigin:")
|
||||
sel_newFunctionWithName = objc.RegisterName("newFunctionWithName:")
|
||||
sel_backFaceStencil = objc.RegisterName("backFaceStencil")
|
||||
sel_frontFaceStencil = objc.RegisterName("frontFaceStencil")
|
||||
sel_setStencilFailureOperation = objc.RegisterName("setStencilFailureOperation:")
|
||||
sel_setDepthFailureOperation = objc.RegisterName("setDepthFailureOperation:")
|
||||
sel_setDepthStencilPassOperation = objc.RegisterName("setDepthStencilPassOperation:")
|
||||
sel_setStencilCompareFunction = objc.RegisterName("setStencilCompareFunction:")
|
||||
sel_newDepthStencilStateWithDescriptor = objc.RegisterName("newDepthStencilStateWithDescriptor:")
|
||||
sel_replaceRegion_mipmapLevel_withBytes_bytesPerRow = objc.RegisterName("replaceRegion:mipmapLevel:withBytes:bytesPerRow:")
|
||||
sel_getBytes_bytesPerRow_fromRegion_mipmapLevel = objc.RegisterName("getBytes:bytesPerRow:fromRegion:mipmapLevel:")
|
||||
sel_respondsToSelector = objc.RegisterName("respondsToSelector:")
|
||||
)
|
||||
|
||||
// CreateSystemDefaultDevice returns the preferred system default Metal device.
|
||||
@@ -589,10 +589,10 @@ func CreateSystemDefaultDevice() (Device, error) {
|
||||
name string
|
||||
)
|
||||
if runtime.GOOS != "ios" {
|
||||
headless = int(objc.ID(d).Send(selIsHeadless)) != 0
|
||||
lowPower = int(objc.ID(d).Send(selIsLowPower)) != 0
|
||||
headless = int(objc.ID(d).Send(sel_isHeadless)) != 0
|
||||
lowPower = int(objc.ID(d).Send(sel_isLowPower)) != 0
|
||||
}
|
||||
name = cocoa.NSString{ID: objc.ID(d).Send(selName)}.String()
|
||||
name = cocoa.NSString{ID: objc.ID(d).Send(sel_name)}.String()
|
||||
|
||||
return Device{
|
||||
device: objc.ID(d),
|
||||
@@ -609,28 +609,28 @@ func (d Device) Device() unsafe.Pointer { return *(*unsafe.Pointer)(unsafe.Point
|
||||
//
|
||||
// Reference: https://developer.apple.com/documentation/objectivec/1418956-nsobject/1418583-respondstoselector?language=objc.
|
||||
func (d Device) RespondsToSelector(sel objc.SEL) bool {
|
||||
return d.device.Send(selRespondsToSelector, sel) != 0
|
||||
return d.device.Send(sel_respondsToSelector, sel) != 0
|
||||
}
|
||||
|
||||
// SupportsFamily returns a Boolean value that indicates whether the GPU device supports the feature set of a specific GPU family.
|
||||
//
|
||||
// Reference: https://developer.apple.com/documentation/metal/mtldevice/3143473-supportsfamily?language=objc.
|
||||
func (d Device) SupportsFamily(gpuFamily GPUFamily) bool {
|
||||
return d.device.Send(selSupportsFamily, uintptr(gpuFamily)) != 0
|
||||
return d.device.Send(sel_supportsFamily, uintptr(gpuFamily)) != 0
|
||||
}
|
||||
|
||||
// SupportsFeatureSet reports whether device d supports feature set fs.
|
||||
//
|
||||
// Reference: https://developer.apple.com/documentation/metal/mtldevice/1433418-supportsfeatureset?language=objc.
|
||||
func (d Device) SupportsFeatureSet(fs FeatureSet) bool {
|
||||
return d.device.Send(selSupportsFeatureSet, uintptr(fs)) != 0
|
||||
return d.device.Send(sel_supportsFeatureSet, uintptr(fs)) != 0
|
||||
}
|
||||
|
||||
// NewCommandQueue creates a queue you use to submit rendering and computation commands to a GPU.
|
||||
//
|
||||
// Reference: https://developer.apple.com/documentation/metal/mtldevice/1433388-newcommandqueue?language=objc.
|
||||
func (d Device) NewCommandQueue() CommandQueue {
|
||||
return CommandQueue{d.device.Send(selNewCommandQueue)}
|
||||
return CommandQueue{d.device.Send(sel_newCommandQueue)}
|
||||
}
|
||||
|
||||
// NewLibraryWithSource synchronously creates a Metal library instance by compiling the functions in a source string.
|
||||
@@ -639,13 +639,13 @@ func (d Device) NewCommandQueue() CommandQueue {
|
||||
func (d Device) NewLibraryWithSource(source string, opt CompileOptions) (Library, error) {
|
||||
var err cocoa.NSError
|
||||
l := d.device.Send(
|
||||
selNewLibraryWithSource_options_error,
|
||||
sel_newLibraryWithSource_options_error,
|
||||
cocoa.NSString_alloc().InitWithUTF8String(source).ID,
|
||||
0,
|
||||
unsafe.Pointer(&err),
|
||||
)
|
||||
if l == 0 {
|
||||
return Library{}, errors.New(cocoa.NSString{ID: err.Send(selLocalizedDescription)}.String())
|
||||
return Library{}, errors.New(cocoa.NSString{ID: err.Send(sel_localizedDescription)}.String())
|
||||
}
|
||||
|
||||
return Library{l}, nil
|
||||
@@ -662,12 +662,12 @@ func (d Device) NewLibraryWithData(buffer []byte) (Library, error) {
|
||||
|
||||
var err cocoa.NSError
|
||||
l := d.device.Send(
|
||||
selNewLibraryWithData_error,
|
||||
sel_newLibraryWithData_error,
|
||||
data,
|
||||
unsafe.Pointer(&err),
|
||||
)
|
||||
if l == 0 {
|
||||
return Library{}, errors.New(cocoa.NSString{ID: err.Send(selLocalizedDescription)}.String())
|
||||
return Library{}, errors.New(cocoa.NSString{ID: err.Send(sel_localizedDescription)}.String())
|
||||
}
|
||||
return Library{l}, nil
|
||||
}
|
||||
@@ -676,28 +676,28 @@ func (d Device) NewLibraryWithData(buffer []byte) (Library, error) {
|
||||
//
|
||||
// Reference: https://developer.apple.com/documentation/metal/mtldevice/1433369-newrenderpipelinestatewithdescri?language=objc.
|
||||
func (d Device) NewRenderPipelineStateWithDescriptor(rpd RenderPipelineDescriptor) (RenderPipelineState, error) {
|
||||
renderPipelineDescriptor := objc.ID(classMTLRenderPipelineDescriptor).Send(selNew)
|
||||
renderPipelineDescriptor.Send(selSetVertexFunction, rpd.VertexFunction.function)
|
||||
renderPipelineDescriptor.Send(selSetFragmentFunction, rpd.FragmentFunction.function)
|
||||
colorAttachments0 := renderPipelineDescriptor.Send(selColorAttachments).Send(selObjectAtIndexedSubscript, 0)
|
||||
colorAttachments0.Send(selSetPixelFormat, uintptr(rpd.ColorAttachments[0].PixelFormat))
|
||||
colorAttachments0.Send(selSetBlendingEnabled, rpd.ColorAttachments[0].BlendingEnabled)
|
||||
colorAttachments0.Send(selSetDestinationAlphaBlendFactor, uintptr(rpd.ColorAttachments[0].DestinationAlphaBlendFactor))
|
||||
colorAttachments0.Send(selSetDestinationRGBBlendFactor, uintptr(rpd.ColorAttachments[0].DestinationRGBBlendFactor))
|
||||
colorAttachments0.Send(selSetSourceAlphaBlendFactor, uintptr(rpd.ColorAttachments[0].SourceAlphaBlendFactor))
|
||||
colorAttachments0.Send(selSetSourceRGBBlendFactor, uintptr(rpd.ColorAttachments[0].SourceRGBBlendFactor))
|
||||
colorAttachments0.Send(selSetAlphaBlendOperation, uintptr(rpd.ColorAttachments[0].AlphaBlendOperation))
|
||||
colorAttachments0.Send(selSetRgbBlendOperation, uintptr(rpd.ColorAttachments[0].RGBBlendOperation))
|
||||
colorAttachments0.Send(selSetWriteMask, uintptr(rpd.ColorAttachments[0].WriteMask))
|
||||
renderPipelineDescriptor.Send(selSetStencilAttachmentPixelFormat, uintptr(rpd.StencilAttachmentPixelFormat))
|
||||
renderPipelineDescriptor := objc.ID(classMTLRenderPipelineDescriptor).Send(sel_new)
|
||||
renderPipelineDescriptor.Send(sel_setVertexFunction, rpd.VertexFunction.function)
|
||||
renderPipelineDescriptor.Send(sel_setFragmentFunction, rpd.FragmentFunction.function)
|
||||
colorAttachments0 := renderPipelineDescriptor.Send(sel_colorAttachments).Send(sel_objectAtIndexedSubscript, 0)
|
||||
colorAttachments0.Send(sel_setPixelFormat, uintptr(rpd.ColorAttachments[0].PixelFormat))
|
||||
colorAttachments0.Send(sel_setBlendingEnabled, rpd.ColorAttachments[0].BlendingEnabled)
|
||||
colorAttachments0.Send(sel_setDestinationAlphaBlendFactor, uintptr(rpd.ColorAttachments[0].DestinationAlphaBlendFactor))
|
||||
colorAttachments0.Send(sel_setDestinationRGBBlendFactor, uintptr(rpd.ColorAttachments[0].DestinationRGBBlendFactor))
|
||||
colorAttachments0.Send(sel_setSourceAlphaBlendFactor, uintptr(rpd.ColorAttachments[0].SourceAlphaBlendFactor))
|
||||
colorAttachments0.Send(sel_setSourceRGBBlendFactor, uintptr(rpd.ColorAttachments[0].SourceRGBBlendFactor))
|
||||
colorAttachments0.Send(sel_setAlphaBlendOperation, uintptr(rpd.ColorAttachments[0].AlphaBlendOperation))
|
||||
colorAttachments0.Send(sel_setRgbBlendOperation, uintptr(rpd.ColorAttachments[0].RGBBlendOperation))
|
||||
colorAttachments0.Send(sel_setWriteMask, uintptr(rpd.ColorAttachments[0].WriteMask))
|
||||
renderPipelineDescriptor.Send(sel_setStencilAttachmentPixelFormat, uintptr(rpd.StencilAttachmentPixelFormat))
|
||||
var err cocoa.NSError
|
||||
renderPipelineState := d.device.Send(selNewRenderPipelineStateWithDescriptor_error,
|
||||
renderPipelineState := d.device.Send(sel_newRenderPipelineStateWithDescriptor_error,
|
||||
renderPipelineDescriptor,
|
||||
unsafe.Pointer(&err),
|
||||
)
|
||||
renderPipelineDescriptor.Send(selRelease)
|
||||
renderPipelineDescriptor.Send(sel_release)
|
||||
if renderPipelineState == 0 {
|
||||
return RenderPipelineState{}, errors.New(cocoa.NSString{ID: err.Send(selLocalizedDescription)}.String())
|
||||
return RenderPipelineState{}, errors.New(cocoa.NSString{ID: err.Send(sel_localizedDescription)}.String())
|
||||
}
|
||||
|
||||
return RenderPipelineState{renderPipelineState}, nil
|
||||
@@ -707,29 +707,29 @@ func (d Device) NewRenderPipelineStateWithDescriptor(rpd RenderPipelineDescripto
|
||||
//
|
||||
// Reference: https://developer.apple.com/documentation/metal/mtldevice/1433429-newbufferwithbytes?language=objc.
|
||||
func (d Device) NewBufferWithBytes(bytes unsafe.Pointer, length uintptr, opt ResourceOptions) Buffer {
|
||||
return Buffer{d.device.Send(selNewBufferWithBytes_length_options, bytes, length, uintptr(opt))}
|
||||
return Buffer{d.device.Send(sel_newBufferWithBytes_length_options, bytes, length, uintptr(opt))}
|
||||
}
|
||||
|
||||
// NewBufferWithLength allocates a new zero-filled buffer of a given length.
|
||||
//
|
||||
// Reference: https://developer.apple.com/documentation/metal/mtldevice/1433375-newbufferwithlength?language=objc.
|
||||
func (d Device) NewBufferWithLength(length uintptr, opt ResourceOptions) Buffer {
|
||||
return Buffer{d.device.Send(selNewBufferWithLength_options, length, uintptr(opt))}
|
||||
return Buffer{d.device.Send(sel_newBufferWithLength_options, length, uintptr(opt))}
|
||||
}
|
||||
|
||||
// NewTextureWithDescriptor creates a new texture instance.
|
||||
//
|
||||
// Reference: https://developer.apple.com/documentation/metal/mtldevice/1433425-newtexturewithdescriptor?language=objc.
|
||||
func (d Device) NewTextureWithDescriptor(td TextureDescriptor) Texture {
|
||||
textureDescriptor := objc.ID(classMTLTextureDescriptor).Send(selNew)
|
||||
textureDescriptor.Send(selSetTextureType, uintptr(td.TextureType))
|
||||
textureDescriptor.Send(selSetPixelFormat, uintptr(td.PixelFormat))
|
||||
textureDescriptor.Send(selSetWidth, uintptr(td.Width))
|
||||
textureDescriptor.Send(selSetHeight, uintptr(td.Height))
|
||||
textureDescriptor.Send(selSetStorageMode, uintptr(td.StorageMode))
|
||||
textureDescriptor.Send(selSetUsage, uintptr(td.Usage))
|
||||
texture := d.device.Send(selNewTextureWithDescriptor, textureDescriptor)
|
||||
textureDescriptor.Send(selRelease)
|
||||
textureDescriptor := objc.ID(classMTLTextureDescriptor).Send(sel_new)
|
||||
textureDescriptor.Send(sel_setTextureType, uintptr(td.TextureType))
|
||||
textureDescriptor.Send(sel_setPixelFormat, uintptr(td.PixelFormat))
|
||||
textureDescriptor.Send(sel_setWidth, uintptr(td.Width))
|
||||
textureDescriptor.Send(sel_setHeight, uintptr(td.Height))
|
||||
textureDescriptor.Send(sel_setStorageMode, uintptr(td.StorageMode))
|
||||
textureDescriptor.Send(sel_setUsage, uintptr(td.Usage))
|
||||
texture := d.device.Send(sel_newTextureWithDescriptor, textureDescriptor)
|
||||
textureDescriptor.Send(sel_release)
|
||||
return Texture{
|
||||
texture: texture,
|
||||
}
|
||||
@@ -739,19 +739,19 @@ func (d Device) NewTextureWithDescriptor(td TextureDescriptor) Texture {
|
||||
//
|
||||
// Reference: https://developer.apple.com/documentation/metal/mtldevice/1433412-newdepthstencilstatewithdescript?language=objc.
|
||||
func (d Device) NewDepthStencilStateWithDescriptor(dsd DepthStencilDescriptor) DepthStencilState {
|
||||
depthStencilDescriptor := objc.ID(classMTLDepthStencilDescriptor).Send(selNew)
|
||||
backFaceStencil := depthStencilDescriptor.Send(selBackFaceStencil)
|
||||
backFaceStencil.Send(selSetStencilFailureOperation, uintptr(dsd.BackFaceStencil.StencilFailureOperation))
|
||||
backFaceStencil.Send(selSetDepthFailureOperation, uintptr(dsd.BackFaceStencil.DepthFailureOperation))
|
||||
backFaceStencil.Send(selSetDepthStencilPassOperation, uintptr(dsd.BackFaceStencil.DepthStencilPassOperation))
|
||||
backFaceStencil.Send(selSetStencilCompareFunction, uintptr(dsd.BackFaceStencil.StencilCompareFunction))
|
||||
frontFaceStencil := depthStencilDescriptor.Send(selFrontFaceStencil)
|
||||
frontFaceStencil.Send(selSetStencilFailureOperation, uintptr(dsd.FrontFaceStencil.StencilFailureOperation))
|
||||
frontFaceStencil.Send(selSetDepthFailureOperation, uintptr(dsd.FrontFaceStencil.DepthFailureOperation))
|
||||
frontFaceStencil.Send(selSetDepthStencilPassOperation, uintptr(dsd.FrontFaceStencil.DepthStencilPassOperation))
|
||||
frontFaceStencil.Send(selSetStencilCompareFunction, uintptr(dsd.FrontFaceStencil.StencilCompareFunction))
|
||||
depthStencilState := d.device.Send(selNewDepthStencilStateWithDescriptor, depthStencilDescriptor)
|
||||
depthStencilDescriptor.Send(selRelease)
|
||||
depthStencilDescriptor := objc.ID(classMTLDepthStencilDescriptor).Send(sel_new)
|
||||
backFaceStencil := depthStencilDescriptor.Send(sel_backFaceStencil)
|
||||
backFaceStencil.Send(sel_setStencilFailureOperation, uintptr(dsd.BackFaceStencil.StencilFailureOperation))
|
||||
backFaceStencil.Send(sel_setDepthFailureOperation, uintptr(dsd.BackFaceStencil.DepthFailureOperation))
|
||||
backFaceStencil.Send(sel_setDepthStencilPassOperation, uintptr(dsd.BackFaceStencil.DepthStencilPassOperation))
|
||||
backFaceStencil.Send(sel_setStencilCompareFunction, uintptr(dsd.BackFaceStencil.StencilCompareFunction))
|
||||
frontFaceStencil := depthStencilDescriptor.Send(sel_frontFaceStencil)
|
||||
frontFaceStencil.Send(sel_setStencilFailureOperation, uintptr(dsd.FrontFaceStencil.StencilFailureOperation))
|
||||
frontFaceStencil.Send(sel_setDepthFailureOperation, uintptr(dsd.FrontFaceStencil.DepthFailureOperation))
|
||||
frontFaceStencil.Send(sel_setDepthStencilPassOperation, uintptr(dsd.FrontFaceStencil.DepthStencilPassOperation))
|
||||
frontFaceStencil.Send(sel_setStencilCompareFunction, uintptr(dsd.FrontFaceStencil.StencilCompareFunction))
|
||||
depthStencilState := d.device.Send(sel_newDepthStencilStateWithDescriptor, depthStencilDescriptor)
|
||||
depthStencilDescriptor.Send(sel_release)
|
||||
return DepthStencilState{
|
||||
depthStencilState: depthStencilState,
|
||||
}
|
||||
@@ -782,14 +782,14 @@ type CommandQueue struct {
|
||||
}
|
||||
|
||||
func (cq CommandQueue) Release() {
|
||||
cq.commandQueue.Send(selRelease)
|
||||
cq.commandQueue.Send(sel_release)
|
||||
}
|
||||
|
||||
// CommandBuffer returns a command buffer from the command queue that maintains strong references to resources.
|
||||
//
|
||||
// Reference: https://developer.apple.com/documentation/metal/mtlcommandqueue/1508686-commandbuffer?language=objc.
|
||||
func (cq CommandQueue) CommandBuffer() CommandBuffer {
|
||||
return CommandBuffer{cq.commandQueue.Send(selCommandBuffer)}
|
||||
return CommandBuffer{cq.commandQueue.Send(sel_commandBuffer)}
|
||||
}
|
||||
|
||||
// CommandBuffer is a container that stores encoded commands
|
||||
@@ -801,64 +801,64 @@ type CommandBuffer struct {
|
||||
}
|
||||
|
||||
func (cb CommandBuffer) Retain() {
|
||||
cb.commandBuffer.Send(selRetain)
|
||||
cb.commandBuffer.Send(sel_retain)
|
||||
}
|
||||
|
||||
func (cb CommandBuffer) Release() {
|
||||
cb.commandBuffer.Send(selRelease)
|
||||
cb.commandBuffer.Send(sel_release)
|
||||
}
|
||||
|
||||
// Status returns the current stage in the lifetime of the command buffer.
|
||||
//
|
||||
// Reference: https://developer.apple.com/documentation/metal/mtlcommandbuffer/1443048-status?language=objc.
|
||||
func (cb CommandBuffer) Status() CommandBufferStatus {
|
||||
return CommandBufferStatus(cb.commandBuffer.Send(selStatus))
|
||||
return CommandBufferStatus(cb.commandBuffer.Send(sel_status))
|
||||
}
|
||||
|
||||
// PresentDrawable registers a drawable presentation to occur as soon as possible.
|
||||
//
|
||||
// Reference: https://developer.apple.com/documentation/metal/mtlcommandbuffer/1443029-presentdrawable?language=objc.
|
||||
func (cb CommandBuffer) PresentDrawable(d Drawable) {
|
||||
cb.commandBuffer.Send(selPresentDrawable, d.Drawable())
|
||||
cb.commandBuffer.Send(sel_presentDrawable, d.Drawable())
|
||||
}
|
||||
|
||||
// Commit commits this command buffer for execution as soon as possible.
|
||||
//
|
||||
// Reference: https://developer.apple.com/documentation/metal/mtlcommandbuffer/1443003-commit?language=objc.
|
||||
func (cb CommandBuffer) Commit() {
|
||||
cb.commandBuffer.Send(selCommit)
|
||||
cb.commandBuffer.Send(sel_commit)
|
||||
}
|
||||
|
||||
// WaitUntilCompleted waits for the execution of this command buffer to complete.
|
||||
//
|
||||
// Reference: https://developer.apple.com/documentation/metal/mtlcommandbuffer/1443039-waituntilcompleted?language=objc.
|
||||
func (cb CommandBuffer) WaitUntilCompleted() {
|
||||
cb.commandBuffer.Send(selWaitUntilCompleted)
|
||||
cb.commandBuffer.Send(sel_waitUntilCompleted)
|
||||
}
|
||||
|
||||
// WaitUntilScheduled blocks execution of the current thread until the command buffer is scheduled.
|
||||
//
|
||||
// Reference: https://developer.apple.com/documentation/metal/mtlcommandbuffer/1443036-waituntilscheduled?language=objc.
|
||||
func (cb CommandBuffer) WaitUntilScheduled() {
|
||||
cb.commandBuffer.Send(selWaitUntilScheduled)
|
||||
cb.commandBuffer.Send(sel_waitUntilScheduled)
|
||||
}
|
||||
|
||||
// RenderCommandEncoderWithDescriptor creates a render command encoder from a descriptor.
|
||||
//
|
||||
// Reference: https://developer.apple.com/documentation/metal/mtlcommandbuffer/1442999-rendercommandencoderwithdescript?language=objc.
|
||||
func (cb CommandBuffer) RenderCommandEncoderWithDescriptor(rpd RenderPassDescriptor) RenderCommandEncoder {
|
||||
var renderPassDescriptor = objc.ID(classMTLRenderPassDescriptor).Send(selNew)
|
||||
var colorAttachments0 = renderPassDescriptor.Send(selColorAttachments).Send(selObjectAtIndexedSubscript, 0)
|
||||
colorAttachments0.Send(selSetLoadAction, int(rpd.ColorAttachments[0].LoadAction))
|
||||
colorAttachments0.Send(selSetStoreAction, int(rpd.ColorAttachments[0].StoreAction))
|
||||
colorAttachments0.Send(selSetTexture, rpd.ColorAttachments[0].Texture.texture)
|
||||
colorAttachments0.Send(selSetClearColor, rpd.ColorAttachments[0].ClearColor)
|
||||
var stencilAttachment = renderPassDescriptor.Send(selStencilAttachment)
|
||||
stencilAttachment.Send(selSetLoadAction, int(rpd.StencilAttachment.LoadAction))
|
||||
stencilAttachment.Send(selSetStoreAction, int(rpd.StencilAttachment.StoreAction))
|
||||
stencilAttachment.Send(selSetTexture, rpd.StencilAttachment.Texture.texture)
|
||||
var rce = cb.commandBuffer.Send(selRenderCommandEncoderWithDescriptor, renderPassDescriptor)
|
||||
renderPassDescriptor.Send(selRelease)
|
||||
var renderPassDescriptor = objc.ID(classMTLRenderPassDescriptor).Send(sel_new)
|
||||
var colorAttachments0 = renderPassDescriptor.Send(sel_colorAttachments).Send(sel_objectAtIndexedSubscript, 0)
|
||||
colorAttachments0.Send(sel_setLoadAction, int(rpd.ColorAttachments[0].LoadAction))
|
||||
colorAttachments0.Send(sel_setStoreAction, int(rpd.ColorAttachments[0].StoreAction))
|
||||
colorAttachments0.Send(sel_setTexture, rpd.ColorAttachments[0].Texture.texture)
|
||||
colorAttachments0.Send(sel_setClearColor, rpd.ColorAttachments[0].ClearColor)
|
||||
var stencilAttachment = renderPassDescriptor.Send(sel_stencilAttachment)
|
||||
stencilAttachment.Send(sel_setLoadAction, int(rpd.StencilAttachment.LoadAction))
|
||||
stencilAttachment.Send(sel_setStoreAction, int(rpd.StencilAttachment.StoreAction))
|
||||
stencilAttachment.Send(sel_setTexture, rpd.StencilAttachment.Texture.texture)
|
||||
var rce = cb.commandBuffer.Send(sel_renderCommandEncoderWithDescriptor, renderPassDescriptor)
|
||||
renderPassDescriptor.Send(sel_release)
|
||||
return RenderCommandEncoder{CommandEncoder{rce}}
|
||||
}
|
||||
|
||||
@@ -867,7 +867,7 @@ func (cb CommandBuffer) RenderCommandEncoderWithDescriptor(rpd RenderPassDescrip
|
||||
//
|
||||
// Reference: https://developer.apple.com/documentation/metal/mtlcommandbuffer/1443001-makeblitcommandencoder?language=objc.
|
||||
func (cb CommandBuffer) BlitCommandEncoder() BlitCommandEncoder {
|
||||
ce := cb.commandBuffer.Send(selBlitCommandEncoder)
|
||||
ce := cb.commandBuffer.Send(sel_blitCommandEncoder)
|
||||
return BlitCommandEncoder{CommandEncoder{ce}}
|
||||
}
|
||||
|
||||
@@ -883,7 +883,7 @@ type CommandEncoder struct {
|
||||
//
|
||||
// Reference: https://developer.apple.com/documentation/metal/mtlcommandencoder/1458038-endencoding?language=objc.
|
||||
func (ce CommandEncoder) EndEncoding() {
|
||||
ce.commandEncoder.Send(selEndEncoding)
|
||||
ce.commandEncoder.Send(sel_endEncoding)
|
||||
}
|
||||
|
||||
// RenderCommandEncoder is an encoder that specifies graphics-rendering commands
|
||||
@@ -895,25 +895,25 @@ type RenderCommandEncoder struct {
|
||||
}
|
||||
|
||||
func (rce RenderCommandEncoder) Release() {
|
||||
rce.commandEncoder.Send(selRelease)
|
||||
rce.commandEncoder.Send(sel_release)
|
||||
}
|
||||
|
||||
// SetRenderPipelineState sets the current render pipeline state object.
|
||||
//
|
||||
// Reference: https://developer.apple.com/documentation/metal/mtlrendercommandencoder/1515811-setrenderpipelinestate?language=objc.
|
||||
func (rce RenderCommandEncoder) SetRenderPipelineState(rps RenderPipelineState) {
|
||||
rce.commandEncoder.Send(selSetRenderPipelineState, rps.renderPipelineState)
|
||||
rce.commandEncoder.Send(sel_setRenderPipelineState, rps.renderPipelineState)
|
||||
}
|
||||
|
||||
func (rce RenderCommandEncoder) SetViewport(viewport Viewport) {
|
||||
rce.commandEncoder.Send(selSetViewport, viewport)
|
||||
rce.commandEncoder.Send(sel_setViewport, viewport)
|
||||
}
|
||||
|
||||
// SetScissorRect sets the scissor rectangle for a fragment scissor test.
|
||||
//
|
||||
// Reference: https://developer.apple.com/documentation/metal/mtlrendercommandencoder/1515583-setscissorrect?language=objc.
|
||||
func (rce RenderCommandEncoder) SetScissorRect(scissorRect ScissorRect) {
|
||||
rce.commandEncoder.Send(selSetScissorRect, scissorRect)
|
||||
rce.commandEncoder.Send(sel_setScissorRect, scissorRect)
|
||||
}
|
||||
|
||||
// SetVertexBuffer sets a buffer for the vertex shader function at an index
|
||||
@@ -921,36 +921,36 @@ func (rce RenderCommandEncoder) SetScissorRect(scissorRect ScissorRect) {
|
||||
//
|
||||
// Reference: https://developer.apple.com/documentation/metal/mtlrendercommandencoder/1515829-setvertexbuffer?language=objc.
|
||||
func (rce RenderCommandEncoder) SetVertexBuffer(buf Buffer, offset, index int) {
|
||||
rce.commandEncoder.Send(selSetVertexBuffer_offset_atIndex, buf.buffer, offset, index)
|
||||
rce.commandEncoder.Send(sel_setVertexBuffer_offset_atIndex, buf.buffer, offset, index)
|
||||
}
|
||||
|
||||
// SetVertexBytes sets a block of data for the vertex function.
|
||||
//
|
||||
// Reference: https://developer.apple.com/documentation/metal/mtlrendercommandencoder/1515846-setvertexbytes?language=objc.
|
||||
func (rce RenderCommandEncoder) SetVertexBytes(bytes unsafe.Pointer, length uintptr, index int) {
|
||||
rce.commandEncoder.Send(selSetVertexBytes_length_atIndex, bytes, length, index)
|
||||
rce.commandEncoder.Send(sel_setVertexBytes_length_atIndex, bytes, length, index)
|
||||
}
|
||||
|
||||
func (rce RenderCommandEncoder) SetFragmentBytes(bytes unsafe.Pointer, length uintptr, index int) {
|
||||
rce.commandEncoder.Send(selSetFragmentBytes_length_atIndex, bytes, length, index)
|
||||
rce.commandEncoder.Send(sel_setFragmentBytes_length_atIndex, bytes, length, index)
|
||||
}
|
||||
|
||||
// SetFragmentTexture sets a texture for the fragment function at an index in the texture argument table.
|
||||
//
|
||||
// Reference: https://developer.apple.com/documentation/metal/mtlrendercommandencoder/1515390-setfragmenttexture?language=objc.
|
||||
func (rce RenderCommandEncoder) SetFragmentTexture(texture Texture, index int) {
|
||||
rce.commandEncoder.Send(selSetFragmentTexture_atIndex, texture.texture, index)
|
||||
rce.commandEncoder.Send(sel_setFragmentTexture_atIndex, texture.texture, index)
|
||||
}
|
||||
|
||||
func (rce RenderCommandEncoder) SetBlendColor(red, green, blue, alpha float32) {
|
||||
rce.commandEncoder.Send(selSetBlendColorRedGreenBlueAlpha, red, green, blue, alpha)
|
||||
rce.commandEncoder.Send(sel_setBlendColorRed_green_blue_alpha, red, green, blue, alpha)
|
||||
}
|
||||
|
||||
// SetDepthStencilState sets the depth and stencil test state.
|
||||
//
|
||||
// Reference: https://developer.apple.com/documentation/metal/mtlrendercommandencoder/1516119-setdepthstencilstate?language=objc.
|
||||
func (rce RenderCommandEncoder) SetDepthStencilState(depthStencilState DepthStencilState) {
|
||||
rce.commandEncoder.Send(selSetDepthStencilState, depthStencilState.depthStencilState)
|
||||
rce.commandEncoder.Send(sel_setDepthStencilState, depthStencilState.depthStencilState)
|
||||
}
|
||||
|
||||
// DrawPrimitives renders one instance of primitives using vertex data
|
||||
@@ -958,7 +958,7 @@ func (rce RenderCommandEncoder) SetDepthStencilState(depthStencilState DepthSten
|
||||
//
|
||||
// Reference: https://developer.apple.com/documentation/metal/mtlrendercommandencoder/1516326-drawprimitives?language=objc.
|
||||
func (rce RenderCommandEncoder) DrawPrimitives(typ PrimitiveType, vertexStart, vertexCount int) {
|
||||
rce.commandEncoder.Send(selDrawPrimitives_vertexStart_vertexCount, uintptr(typ), vertexStart, vertexCount)
|
||||
rce.commandEncoder.Send(sel_drawPrimitives_vertexStart_vertexCount, uintptr(typ), vertexStart, vertexCount)
|
||||
}
|
||||
|
||||
// DrawIndexedPrimitives encodes a command to render one instance of primitives using an index list specified in a buffer.
|
||||
@@ -966,7 +966,7 @@ func (rce RenderCommandEncoder) DrawPrimitives(typ PrimitiveType, vertexStart, v
|
||||
// Reference: https://developer.apple.com/documentation/metal/mtlrendercommandencoder/1515542-drawindexedprimitives
|
||||
func (rce RenderCommandEncoder) DrawIndexedPrimitives(typ PrimitiveType, indexCount int, indexType IndexType, indexBuffer Buffer, indexBufferOffset int) {
|
||||
rce.commandEncoder.Send(
|
||||
selDrawIndexedPrimitives_indexCount_indexType_indexBuffer_indexBufferOffset,
|
||||
sel_drawIndexedPrimitives_indexCount_indexType_indexBuffer_indexBufferOffset,
|
||||
uintptr(typ), indexCount, uintptr(indexType), indexBuffer.buffer, indexBufferOffset)
|
||||
}
|
||||
|
||||
@@ -986,7 +986,7 @@ func (bce BlitCommandEncoder) Synchronize(resource Resource) {
|
||||
if runtime.GOOS == "ios" {
|
||||
return
|
||||
}
|
||||
bce.commandEncoder.Send(selSynchronizeResource, resource.resource())
|
||||
bce.commandEncoder.Send(sel_synchronizeResource, resource.resource())
|
||||
}
|
||||
|
||||
// SynchronizeTexture encodes a command that synchronizes a part of the CPU’s copy of a texture so that it matches the GPU’s copy.
|
||||
@@ -996,7 +996,7 @@ func (bce BlitCommandEncoder) SynchronizeTexture(texture Texture, slice int, lev
|
||||
if runtime.GOOS == "ios" {
|
||||
return
|
||||
}
|
||||
bce.commandEncoder.Send(selSynchronizeTexture_slice_level, texture.texture, slice, level)
|
||||
bce.commandEncoder.Send(sel_synchronizeTexture_slice_level, texture.texture, slice, level)
|
||||
}
|
||||
|
||||
// CopyFromTexture encodes a command that copies image data from a texture’s slice into another slice.
|
||||
@@ -1006,7 +1006,7 @@ func (bce BlitCommandEncoder) CopyFromTexture(sourceTexture Texture, sourceSlice
|
||||
// copyFromTexture requires so many arguments that Send doesn't work (#3135).
|
||||
inv := cocoa.NSInvocation_invocationWithMethodSignature(cocoa.NSMethodSignature_signatureWithObjCTypes("v@:@QQ{MTLOrigin=qqq}{MTLSize=qqq}@QQ{MTLOrigin=qqq}"))
|
||||
inv.SetTarget(bce.commandEncoder)
|
||||
inv.SetSelector(selCopyFromTexture_sourceSlice_sourceLevel_sourceOrigin_sourceSize_toTexture_destinationSlice_destinationLevel_destinationOrigin)
|
||||
inv.SetSelector(sel_copyFromTexture_sourceSlice_sourceLevel_sourceOrigin_sourceSize_toTexture_destinationSlice_destinationLevel_destinationOrigin)
|
||||
inv.SetArgumentAtIndex(unsafe.Pointer(&sourceTexture), 2)
|
||||
inv.SetArgumentAtIndex(unsafe.Pointer(&sourceSlice), 3)
|
||||
inv.SetArgumentAtIndex(unsafe.Pointer(&sourceLevel), 4)
|
||||
@@ -1030,7 +1030,7 @@ type Library struct {
|
||||
//
|
||||
// Reference: https://developer.apple.com/documentation/metal/mtllibrary/1515524-newfunctionwithname?language=objc.
|
||||
func (l Library) NewFunctionWithName(name string) (Function, error) {
|
||||
f := l.library.Send(selNewFunctionWithName,
|
||||
f := l.library.Send(sel_newFunctionWithName,
|
||||
cocoa.NSString_alloc().InitWithUTF8String(name).ID,
|
||||
)
|
||||
if f == 0 {
|
||||
@@ -1040,7 +1040,7 @@ func (l Library) NewFunctionWithName(name string) (Function, error) {
|
||||
}
|
||||
|
||||
func (l Library) Release() {
|
||||
l.library.Send(selRelease)
|
||||
l.library.Send(sel_release)
|
||||
}
|
||||
|
||||
// Texture is a memory allocation for storing formatted
|
||||
@@ -1062,7 +1062,7 @@ func (t Texture) resource() unsafe.Pointer {
|
||||
}
|
||||
|
||||
func (t Texture) Release() {
|
||||
t.texture.Send(selRelease)
|
||||
t.texture.Send(sel_release)
|
||||
}
|
||||
|
||||
// GetBytes copies a block of pixels from the storage allocation of texture
|
||||
@@ -1070,28 +1070,28 @@ func (t Texture) Release() {
|
||||
//
|
||||
// Reference: https://developer.apple.com/documentation/metal/mtltexture/1515751-getbytes?language=objc.
|
||||
func (t Texture) GetBytes(pixelBytes *byte, bytesPerRow uintptr, region Region, level int) {
|
||||
t.texture.Send(selGetBytes_bytesPerRow_fromRegion_mipmapLevel, pixelBytes, bytesPerRow, region, level)
|
||||
t.texture.Send(sel_getBytes_bytesPerRow_fromRegion_mipmapLevel, pixelBytes, bytesPerRow, region, level)
|
||||
}
|
||||
|
||||
// ReplaceRegion copies a block of pixels from the caller's pointer into the storage allocation for slice 0 of a texture.
|
||||
//
|
||||
// Reference: https://developer.apple.com/documentation/metal/mtltexture/1515464-replaceregion?language=objc.
|
||||
func (t Texture) ReplaceRegion(region Region, level int, pixelBytes unsafe.Pointer, bytesPerRow int) {
|
||||
t.texture.Send(selReplaceRegion_mipmapLevel_withBytes_bytesPerRow, region, level, pixelBytes, bytesPerRow)
|
||||
t.texture.Send(sel_replaceRegion_mipmapLevel_withBytes_bytesPerRow, region, level, pixelBytes, bytesPerRow)
|
||||
}
|
||||
|
||||
// Width is the width of the texture image for the base level mipmap, in pixels.
|
||||
//
|
||||
// Reference: https://developer.apple.com/documentation/metal/mtltexture/1515339-width?language=objc.
|
||||
func (t Texture) Width() int {
|
||||
return int(t.texture.Send(selWidth))
|
||||
return int(t.texture.Send(sel_width))
|
||||
}
|
||||
|
||||
// Height is the height of the texture image for the base level mipmap, in pixels.
|
||||
//
|
||||
// Reference: https://developer.apple.com/documentation/metal/mtltexture/1515938-height?language=objc.
|
||||
func (t Texture) Height() int {
|
||||
return int(t.texture.Send(selHeight))
|
||||
return int(t.texture.Send(sel_height))
|
||||
}
|
||||
|
||||
// Buffer is a memory allocation for storing unformatted data
|
||||
@@ -1111,23 +1111,23 @@ func (b Buffer) resource() unsafe.Pointer {
|
||||
//
|
||||
// Reference: https://developer.apple.com/documentation/metal/mtlbuffer/1515373-length?language=objc.
|
||||
func (b Buffer) Length() uintptr {
|
||||
return uintptr(b.buffer.Send(selLength))
|
||||
return uintptr(b.buffer.Send(sel_length))
|
||||
}
|
||||
|
||||
func (b Buffer) CopyToContents(data unsafe.Pointer, lengthInBytes uintptr) {
|
||||
contents := b.buffer.Send(selContents)
|
||||
contents := b.buffer.Send(sel_contents)
|
||||
copy(unsafe.Slice((*byte)(unsafe.Pointer(contents)), lengthInBytes), unsafe.Slice((*byte)(data), lengthInBytes))
|
||||
if runtime.GOOS != "ios" {
|
||||
b.buffer.Send(selDidModifyRange, 0, lengthInBytes)
|
||||
b.buffer.Send(sel_didModifyRange, 0, lengthInBytes)
|
||||
}
|
||||
}
|
||||
|
||||
func (b Buffer) Retain() {
|
||||
b.buffer.Send(selRetain)
|
||||
b.buffer.Send(sel_retain)
|
||||
}
|
||||
|
||||
func (b Buffer) Release() {
|
||||
b.buffer.Send(selRelease)
|
||||
b.buffer.Send(sel_release)
|
||||
}
|
||||
|
||||
// Function represents a programmable graphics or compute function executed by the GPU.
|
||||
@@ -1138,7 +1138,7 @@ type Function struct {
|
||||
}
|
||||
|
||||
func (f Function) Release() {
|
||||
f.function.Send(selRelease)
|
||||
f.function.Send(sel_release)
|
||||
}
|
||||
|
||||
// RenderPipelineState contains the graphics functions
|
||||
@@ -1150,7 +1150,7 @@ type RenderPipelineState struct {
|
||||
}
|
||||
|
||||
func (r RenderPipelineState) Release() {
|
||||
r.renderPipelineState.Send(selRelease)
|
||||
r.renderPipelineState.Send(sel_release)
|
||||
}
|
||||
|
||||
// Region is a rectangular block of pixels in an image or texture,
|
||||
@@ -1222,7 +1222,7 @@ type DepthStencilState struct {
|
||||
}
|
||||
|
||||
func (d DepthStencilState) Release() {
|
||||
d.depthStencilState.Send(selRelease)
|
||||
d.depthStencilState.Send(sel_release)
|
||||
}
|
||||
|
||||
// DepthStencilDescriptor is an object that configures new MTLDepthStencilState objects.
|
||||
|
||||
+73
-73
@@ -37,17 +37,17 @@ var classEbitengineWindowDelegate objc.Class
|
||||
func (u *UserInterface) initializePlatform() error {
|
||||
pushResizableState := func(id, win objc.ID) {
|
||||
window := cocoa.NSWindow{ID: win}
|
||||
id.Send(selSetOrigResizable, window.StyleMask()&cocoa.NSWindowStyleMaskResizable != 0)
|
||||
if !objc.Send[bool](id, selOrigResizable) {
|
||||
id.Send(sel_setOrigResizable, window.StyleMask()&cocoa.NSWindowStyleMaskResizable != 0)
|
||||
if !objc.Send[bool](id, sel_isOrigResizable) {
|
||||
window.SetStyleMask(window.StyleMask() | cocoa.NSWindowStyleMaskResizable)
|
||||
}
|
||||
}
|
||||
popResizableState := func(id, win objc.ID) {
|
||||
if !objc.Send[bool](id, selOrigResizable) {
|
||||
if !objc.Send[bool](id, sel_isOrigResizable) {
|
||||
window := cocoa.NSWindow{ID: win}
|
||||
window.SetStyleMask(window.StyleMask() & ^uint(cocoa.NSWindowStyleMaskResizable))
|
||||
}
|
||||
id.Send(selSetOrigResizable, false)
|
||||
id.Send(sel_setOrigResizable, false)
|
||||
}
|
||||
d, err := objc.RegisterClass(
|
||||
"EbitengineWindowDelegate",
|
||||
@@ -67,11 +67,11 @@ func (u *UserInterface) initializePlatform() error {
|
||||
},
|
||||
[]objc.MethodDef{
|
||||
{
|
||||
Cmd: selInitWithOrigDelegate,
|
||||
Cmd: sel_initWithOrigDelegate,
|
||||
Fn: func(id objc.ID, cmd objc.SEL, origDelegate objc.ID) objc.ID {
|
||||
self := id.SendSuper(selInit)
|
||||
self := id.SendSuper(sel_init)
|
||||
if self != 0 {
|
||||
id.Send(selSetOrigDelegate, origDelegate)
|
||||
id.Send(sel_setOrigDelegate, origDelegate)
|
||||
}
|
||||
return self
|
||||
},
|
||||
@@ -79,49 +79,49 @@ func (u *UserInterface) initializePlatform() error {
|
||||
// The method set of origDelegate must sync with GLFWWindowDelegate's implementation.
|
||||
// See cocoa_window.m in GLFW.
|
||||
{
|
||||
Cmd: selWindowShouldClose,
|
||||
Cmd: sel_windowShouldClose,
|
||||
Fn: func(id objc.ID, cmd objc.SEL, sender objc.ID) bool {
|
||||
return id.Send(selOrigDelegate).Send(cmd, sender) != 0
|
||||
return id.Send(sel_origDelegate).Send(cmd, sender) != 0
|
||||
},
|
||||
},
|
||||
{
|
||||
Cmd: selWindowDidResize,
|
||||
Cmd: sel_windowDidResize,
|
||||
Fn: func(id objc.ID, cmd objc.SEL, notification objc.ID) {
|
||||
id.Send(selOrigDelegate).Send(cmd, notification)
|
||||
id.Send(sel_origDelegate).Send(cmd, notification)
|
||||
},
|
||||
},
|
||||
{
|
||||
Cmd: selWindowDidMove,
|
||||
Cmd: sel_windowDidMove,
|
||||
Fn: func(id objc.ID, cmd objc.SEL, notification objc.ID) {
|
||||
id.Send(selOrigDelegate).Send(cmd, notification)
|
||||
id.Send(sel_origDelegate).Send(cmd, notification)
|
||||
},
|
||||
},
|
||||
{
|
||||
Cmd: selWindowDidMiniaturize,
|
||||
Cmd: sel_windowDidMiniaturize,
|
||||
Fn: func(id objc.ID, cmd objc.SEL, notification objc.ID) {
|
||||
id.Send(selOrigDelegate).Send(cmd, notification)
|
||||
id.Send(sel_origDelegate).Send(cmd, notification)
|
||||
},
|
||||
},
|
||||
{
|
||||
Cmd: selWindowDidBecomeKey,
|
||||
Cmd: sel_windowDidBecomeKey,
|
||||
Fn: func(id objc.ID, cmd objc.SEL, notification objc.ID) {
|
||||
id.Send(selOrigDelegate).Send(cmd, notification)
|
||||
id.Send(sel_origDelegate).Send(cmd, notification)
|
||||
},
|
||||
},
|
||||
{
|
||||
Cmd: selWindowDidResignKey,
|
||||
Cmd: sel_windowDidResignKey,
|
||||
Fn: func(id objc.ID, cmd objc.SEL, notification objc.ID) {
|
||||
id.Send(selOrigDelegate).Send(cmd, notification)
|
||||
id.Send(sel_origDelegate).Send(cmd, notification)
|
||||
},
|
||||
},
|
||||
{
|
||||
Cmd: selWindowDidChangeOcclusionState,
|
||||
Cmd: sel_windowDidChangeOcclusionState,
|
||||
Fn: func(id objc.ID, cmd objc.SEL, notification objc.ID) {
|
||||
id.Send(selOrigDelegate).Send(cmd, notification)
|
||||
id.Send(sel_origDelegate).Send(cmd, notification)
|
||||
},
|
||||
},
|
||||
{
|
||||
Cmd: selWindowWillEnterFullScreen,
|
||||
Cmd: sel_windowWillEnterFullScreen,
|
||||
Fn: func(id objc.ID, cmd objc.SEL, notification objc.ID) {
|
||||
if err := u.setOrigWindowPosWithCurrentPos(); err != nil {
|
||||
u.setError(err)
|
||||
@@ -131,13 +131,13 @@ func (u *UserInterface) initializePlatform() error {
|
||||
},
|
||||
},
|
||||
{
|
||||
Cmd: selWindowDidEnterFullScreen,
|
||||
Cmd: sel_windowDidEnterFullScreen,
|
||||
Fn: func(id objc.ID, cmd objc.SEL, notification objc.ID) {
|
||||
popResizableState(id, cocoa.NSNotification{ID: notification}.Object())
|
||||
},
|
||||
},
|
||||
{
|
||||
Cmd: selWindowWillExitFullScreen,
|
||||
Cmd: sel_windowWillExitFullScreen,
|
||||
Fn: func(id objc.ID, cmd objc.SEL, notification objc.ID) {
|
||||
pushResizableState(id, cocoa.NSNotification{ID: notification}.Object())
|
||||
// Even a window has a size limitation, a window can be fullscreen by calling SetFullscreen(true).
|
||||
@@ -150,7 +150,7 @@ func (u *UserInterface) initializePlatform() error {
|
||||
},
|
||||
},
|
||||
{
|
||||
Cmd: selWindowDidExitFullScreen,
|
||||
Cmd: sel_windowDidExitFullScreen,
|
||||
Fn: func(id objc.ID, cmd objc.SEL, notification objc.ID) {
|
||||
popResizableState(id, cocoa.NSNotification{ID: notification}.Object())
|
||||
// Do not call setFrame here (#2295). setFrame here causes unexpected results.
|
||||
@@ -171,12 +171,12 @@ func (u *UserInterface) setApplePressAndHoldEnabled(enabled bool) {
|
||||
if enabled {
|
||||
val = 1
|
||||
}
|
||||
defaults := objc.ID(classNSMutableDictionary).Send(selAlloc).Send(selInit)
|
||||
defaults.Send(selSetObjectForKey,
|
||||
objc.ID(classNSNumber).Send(selAlloc).Send(selInitWithBool, val),
|
||||
defaults := objc.ID(classNSMutableDictionary).Send(sel_alloc).Send(sel_init)
|
||||
defaults.Send(sel_setObject_forKey,
|
||||
objc.ID(classNSNumber).Send(sel_alloc).Send(sel_initWithBool, val),
|
||||
cocoa.NSString_alloc().InitWithUTF8String("ApplePressAndHoldEnabled").ID)
|
||||
ud := objc.ID(classNSUserDefaults).Send(selStandardUserDefaults)
|
||||
ud.Send(selRegisterDefaults, defaults)
|
||||
ud := objc.ID(classNSUserDefaults).Send(sel_standardUserDefaults)
|
||||
ud.Send(sel_registerDefaults, defaults)
|
||||
}
|
||||
|
||||
type graphicsDriverCreatorImpl struct {
|
||||
@@ -247,41 +247,41 @@ var (
|
||||
)
|
||||
|
||||
var (
|
||||
selAlloc = objc.RegisterName("alloc")
|
||||
selAppearanceNamed = objc.RegisterName("appearanceNamed:")
|
||||
selCollectionBehavior = objc.RegisterName("collectionBehavior")
|
||||
selDelegate = objc.RegisterName("delegate")
|
||||
selInit = objc.RegisterName("init")
|
||||
selInitWithBool = objc.RegisterName("initWithBool:")
|
||||
selInitWithOrigDelegate = objc.RegisterName("initWithOrigDelegate:")
|
||||
selMouseLocation = objc.RegisterName("mouseLocation")
|
||||
selOrigDelegate = objc.RegisterName("origDelegate")
|
||||
selOrigResizable = objc.RegisterName("isOrigResizable")
|
||||
selRegisterDefaults = objc.RegisterName("registerDefaults:")
|
||||
selSetAppearance = objc.RegisterName("setAppearance:")
|
||||
selSetCollectionBehavior = objc.RegisterName("setCollectionBehavior:")
|
||||
selSetDelegate = objc.RegisterName("setDelegate:")
|
||||
selSetDocumentEdited = objc.RegisterName("setDocumentEdited:")
|
||||
selSetObjectForKey = objc.RegisterName("setObject:forKey:")
|
||||
selSetOrigDelegate = objc.RegisterName("setOrigDelegate:")
|
||||
selSetOrigResizable = objc.RegisterName("setOrigResizable:")
|
||||
selStandardUserDefaults = objc.RegisterName("standardUserDefaults")
|
||||
selToggleFullScreen = objc.RegisterName("toggleFullScreen:")
|
||||
selWindowDidBecomeKey = objc.RegisterName("windowDidBecomeKey:")
|
||||
selWindowDidEnterFullScreen = objc.RegisterName("windowDidEnterFullScreen:")
|
||||
selWindowDidExitFullScreen = objc.RegisterName("windowDidExitFullScreen:")
|
||||
selWindowDidMiniaturize = objc.RegisterName("windowDidMiniaturize:")
|
||||
selWindowDidMove = objc.RegisterName("windowDidMove:")
|
||||
selWindowDidResignKey = objc.RegisterName("windowDidResignKey:")
|
||||
selWindowDidResize = objc.RegisterName("windowDidResize:")
|
||||
selWindowDidChangeOcclusionState = objc.RegisterName("windowDidChangeOcclusionState:")
|
||||
selWindowShouldClose = objc.RegisterName("windowShouldClose:")
|
||||
selWindowWillEnterFullScreen = objc.RegisterName("windowWillEnterFullScreen:")
|
||||
selWindowWillExitFullScreen = objc.RegisterName("windowWillExitFullScreen:")
|
||||
sel_alloc = objc.RegisterName("alloc")
|
||||
sel_appearanceNamed = objc.RegisterName("appearanceNamed:")
|
||||
sel_collectionBehavior = objc.RegisterName("collectionBehavior")
|
||||
sel_delegate = objc.RegisterName("delegate")
|
||||
sel_init = objc.RegisterName("init")
|
||||
sel_initWithBool = objc.RegisterName("initWithBool:")
|
||||
sel_initWithOrigDelegate = objc.RegisterName("initWithOrigDelegate:")
|
||||
sel_mouseLocation = objc.RegisterName("mouseLocation")
|
||||
sel_origDelegate = objc.RegisterName("origDelegate")
|
||||
sel_isOrigResizable = objc.RegisterName("isOrigResizable")
|
||||
sel_registerDefaults = objc.RegisterName("registerDefaults:")
|
||||
sel_setAppearance = objc.RegisterName("setAppearance:")
|
||||
sel_setCollectionBehavior = objc.RegisterName("setCollectionBehavior:")
|
||||
sel_setDelegate = objc.RegisterName("setDelegate:")
|
||||
sel_setDocumentEdited = objc.RegisterName("setDocumentEdited:")
|
||||
sel_setObject_forKey = objc.RegisterName("setObject:forKey:")
|
||||
sel_setOrigDelegate = objc.RegisterName("setOrigDelegate:")
|
||||
sel_setOrigResizable = objc.RegisterName("setOrigResizable:")
|
||||
sel_standardUserDefaults = objc.RegisterName("standardUserDefaults")
|
||||
sel_toggleFullScreen = objc.RegisterName("toggleFullScreen:")
|
||||
sel_windowDidBecomeKey = objc.RegisterName("windowDidBecomeKey:")
|
||||
sel_windowDidEnterFullScreen = objc.RegisterName("windowDidEnterFullScreen:")
|
||||
sel_windowDidExitFullScreen = objc.RegisterName("windowDidExitFullScreen:")
|
||||
sel_windowDidMiniaturize = objc.RegisterName("windowDidMiniaturize:")
|
||||
sel_windowDidMove = objc.RegisterName("windowDidMove:")
|
||||
sel_windowDidResignKey = objc.RegisterName("windowDidResignKey:")
|
||||
sel_windowDidResize = objc.RegisterName("windowDidResize:")
|
||||
sel_windowDidChangeOcclusionState = objc.RegisterName("windowDidChangeOcclusionState:")
|
||||
sel_windowShouldClose = objc.RegisterName("windowShouldClose:")
|
||||
sel_windowWillEnterFullScreen = objc.RegisterName("windowWillEnterFullScreen:")
|
||||
sel_windowWillExitFullScreen = objc.RegisterName("windowWillExitFullScreen:")
|
||||
)
|
||||
|
||||
func currentMouseLocation() (x, y int) {
|
||||
point := objc.Send[cocoa.NSPoint](objc.ID(classNSEvent), selMouseLocation)
|
||||
point := objc.Send[cocoa.NSPoint](objc.ID(classNSEvent), sel_mouseLocation)
|
||||
|
||||
x, y = int(point.X), int(point.Y)
|
||||
|
||||
@@ -361,17 +361,17 @@ func (u *UserInterface) setNativeFullscreen(fullscreen bool) error {
|
||||
}
|
||||
// Even though EbitengineWindowDelegate is used, this hack is still required.
|
||||
// toggleFullscreen doesn't work when the window is not resizable.
|
||||
origCollectionBehavior := window.Send(selCollectionBehavior)
|
||||
origCollectionBehavior := window.Send(sel_collectionBehavior)
|
||||
origFullScreen := origCollectionBehavior&cocoa.NSWindowCollectionBehaviorFullScreenPrimary != 0
|
||||
if !origFullScreen {
|
||||
collectionBehavior := origCollectionBehavior
|
||||
collectionBehavior |= cocoa.NSWindowCollectionBehaviorFullScreenPrimary
|
||||
collectionBehavior &^= cocoa.NSWindowCollectionBehaviorFullScreenNone
|
||||
window.Send(selSetCollectionBehavior, cocoa.NSUInteger(collectionBehavior))
|
||||
window.Send(sel_setCollectionBehavior, cocoa.NSUInteger(collectionBehavior))
|
||||
}
|
||||
window.Send(selToggleFullScreen, 0)
|
||||
window.Send(sel_toggleFullScreen, 0)
|
||||
if !origFullScreen {
|
||||
window.Send(selSetCollectionBehavior, cocoa.NSUInteger(cocoa.NSUInteger(origCollectionBehavior)))
|
||||
window.Send(sel_setCollectionBehavior, cocoa.NSUInteger(cocoa.NSUInteger(origCollectionBehavior)))
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -434,7 +434,7 @@ func (u *UserInterface) setWindowResizingModeForOS(mode WindowResizingMode) erro
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
objc.ID(w).Send(selSetCollectionBehavior, collectionBehavior)
|
||||
objc.ID(w).Send(sel_setCollectionBehavior, collectionBehavior)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -446,8 +446,8 @@ func initializeWindowAfterCreation(w *glfw.Window) error {
|
||||
return err
|
||||
}
|
||||
nswindow := objc.ID(cocoaWindow)
|
||||
delegate := objc.ID(classEbitengineWindowDelegate).Send(selAlloc).Send(selInitWithOrigDelegate, nswindow.Send(selDelegate))
|
||||
nswindow.Send(selSetDelegate, delegate)
|
||||
delegate := objc.ID(classEbitengineWindowDelegate).Send(sel_alloc).Send(sel_initWithOrigDelegate, nswindow.Send(sel_delegate))
|
||||
nswindow.Send(sel_setDelegate, delegate)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -461,7 +461,7 @@ func (u *UserInterface) setDocumentEdited(edited bool) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
objc.ID(w).Send(selSetDocumentEdited, edited)
|
||||
objc.ID(w).Send(sel_setDocumentEdited, edited)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -484,13 +484,13 @@ func (u *UserInterface) setWindowColorModeImpl(mode colormode.ColorMode) error {
|
||||
var appearance objc.ID
|
||||
switch mode {
|
||||
case colormode.Light:
|
||||
appearance = objc.ID(classNSAppearance).Send(selAppearanceNamed, nsStringAqua.ID)
|
||||
appearance = objc.ID(classNSAppearance).Send(sel_appearanceNamed, nsStringAqua.ID)
|
||||
case colormode.Dark:
|
||||
appearance = objc.ID(classNSAppearance).Send(selAppearanceNamed, nsStringDarkAqua.ID)
|
||||
appearance = objc.ID(classNSAppearance).Send(sel_appearanceNamed, nsStringDarkAqua.ID)
|
||||
case colormode.Unknown:
|
||||
appearance = 0
|
||||
}
|
||||
|
||||
objc.ID(w).Send(selSetAppearance, appearance)
|
||||
objc.ID(w).Send(sel_setAppearance, appearance)
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user