mirror of
https://github.com/Ed94/Odin.git
synced 2026-07-17 00:11:25 -07:00
Merge branch 'master' into macharena
This commit is contained in:
@@ -1,7 +1,5 @@
|
||||
package CoreFoundation
|
||||
|
||||
import "base:runtime"
|
||||
|
||||
foreign import CoreFoundation "system:CoreFoundation.framework"
|
||||
|
||||
String :: distinct TypeRef // same as CFStringRef
|
||||
@@ -9,157 +7,157 @@ String :: distinct TypeRef // same as CFStringRef
|
||||
StringEncoding :: distinct u32
|
||||
|
||||
StringBuiltInEncodings :: enum StringEncoding {
|
||||
MacRoman = 0,
|
||||
MacRoman = 0,
|
||||
WindowsLatin1 = 0x0500,
|
||||
ISOLatin1 = 0x0201,
|
||||
ISOLatin1 = 0x0201,
|
||||
NextStepLatin = 0x0B01,
|
||||
ASCII = 0x0600,
|
||||
Unicode = 0x0100,
|
||||
UTF8 = 0x08000100,
|
||||
ASCII = 0x0600,
|
||||
Unicode = 0x0100,
|
||||
UTF8 = 0x08000100,
|
||||
NonLossyASCII = 0x0BFF,
|
||||
|
||||
UTF16 = 0x0100,
|
||||
UTF16 = 0x0100,
|
||||
UTF16BE = 0x10000100,
|
||||
UTF16LE = 0x14000100,
|
||||
|
||||
UTF32 = 0x0c000100,
|
||||
UTF32BE = 0x18000100,
|
||||
UTF32LE = 0x1c000100,
|
||||
UTF32 = 0x0c000100,
|
||||
UTF32BE = 0x18000100,
|
||||
UTF32LE = 0x1c000100,
|
||||
}
|
||||
|
||||
StringEncodings :: enum Index {
|
||||
MacJapanese = 1,
|
||||
MacChineseTrad = 2,
|
||||
MacKorean = 3,
|
||||
MacArabic = 4,
|
||||
MacHebrew = 5,
|
||||
MacGreek = 6,
|
||||
MacCyrillic = 7,
|
||||
MacDevanagari = 9,
|
||||
MacGurmukhi = 10,
|
||||
MacGujarati = 11,
|
||||
MacOriya = 12,
|
||||
MacBengali = 13,
|
||||
MacTamil = 14,
|
||||
MacTelugu = 15,
|
||||
MacKannada = 16,
|
||||
MacMalayalam = 17,
|
||||
MacSinhalese = 18,
|
||||
MacBurmese = 19,
|
||||
MacKhmer = 20,
|
||||
MacThai = 21,
|
||||
MacLaotian = 22,
|
||||
MacGeorgian = 23,
|
||||
MacArmenian = 24,
|
||||
MacChineseSimp = 25,
|
||||
MacTibetan = 26,
|
||||
MacMongolian = 27,
|
||||
MacEthiopic = 28,
|
||||
MacCentralEurRoman = 29,
|
||||
MacVietnamese = 30,
|
||||
MacExtArabic = 31,
|
||||
MacSymbol = 33,
|
||||
MacDingbats = 34,
|
||||
MacTurkish = 35,
|
||||
MacCroatian = 36,
|
||||
MacIcelandic = 37,
|
||||
MacRomanian = 38,
|
||||
MacCeltic = 39,
|
||||
MacGaelic = 40,
|
||||
MacFarsi = 0x8C,
|
||||
MacUkrainian = 0x98,
|
||||
MacInuit = 0xEC,
|
||||
MacVT100 = 0xFC,
|
||||
MacHFS = 0xFF,
|
||||
ISOLatin2 = 0x0202,
|
||||
ISOLatin3 = 0x0203,
|
||||
ISOLatin4 = 0x0204,
|
||||
ISOLatinCyrillic = 0x0205,
|
||||
ISOLatinArabic = 0x0206,
|
||||
ISOLatinGreek = 0x0207,
|
||||
ISOLatinHebrew = 0x0208,
|
||||
ISOLatin5 = 0x0209,
|
||||
ISOLatin6 = 0x020A,
|
||||
ISOLatinThai = 0x020B,
|
||||
ISOLatin7 = 0x020D,
|
||||
ISOLatin8 = 0x020E,
|
||||
ISOLatin9 = 0x020F,
|
||||
ISOLatin10 = 0x0210,
|
||||
DOSLatinUS = 0x0400,
|
||||
DOSGreek = 0x0405,
|
||||
DOSBalticRim = 0x0406,
|
||||
DOSLatin1 = 0x0410,
|
||||
DOSGreek1 = 0x0411,
|
||||
DOSLatin2 = 0x0412,
|
||||
DOSCyrillic = 0x0413,
|
||||
DOSTurkish = 0x0414,
|
||||
DOSPortuguese = 0x0415,
|
||||
DOSIcelandic = 0x0416,
|
||||
DOSHebrew = 0x0417,
|
||||
DOSCanadianFrench = 0x0418,
|
||||
DOSArabic = 0x0419,
|
||||
DOSNordic = 0x041A,
|
||||
DOSRussian = 0x041B,
|
||||
DOSGreek2 = 0x041C,
|
||||
DOSThai = 0x041D,
|
||||
DOSJapanese = 0x0420,
|
||||
DOSChineseSimplif = 0x0421,
|
||||
DOSKorean = 0x0422,
|
||||
DOSChineseTrad = 0x0423,
|
||||
WindowsLatin2 = 0x0501,
|
||||
WindowsCyrillic = 0x0502,
|
||||
WindowsGreek = 0x0503,
|
||||
WindowsLatin5 = 0x0504,
|
||||
WindowsHebrew = 0x0505,
|
||||
WindowsArabic = 0x0506,
|
||||
WindowsBalticRim = 0x0507,
|
||||
WindowsVietnamese = 0x0508,
|
||||
WindowsKoreanJohab = 0x0510,
|
||||
ANSEL = 0x0601,
|
||||
JIS_X0201_76 = 0x0620,
|
||||
JIS_X0208_83 = 0x0621,
|
||||
JIS_X0208_90 = 0x0622,
|
||||
JIS_X0212_90 = 0x0623,
|
||||
JIS_C6226_78 = 0x0624,
|
||||
ShiftJIS_X0213 = 0x0628,
|
||||
ShiftJIS_X0213_MenKuTen = 0x0629,
|
||||
GB_2312_80 = 0x0630,
|
||||
GBK_95 = 0x0631,
|
||||
GB_18030_2000 = 0x0632,
|
||||
KSC_5601_87 = 0x0640,
|
||||
KSC_5601_92_Johab = 0x0641,
|
||||
CNS_11643_92_P1 = 0x0651,
|
||||
CNS_11643_92_P2 = 0x0652,
|
||||
CNS_11643_92_P3 = 0x0653,
|
||||
ISO_2022_JP = 0x0820,
|
||||
ISO_2022_JP_2 = 0x0821,
|
||||
ISO_2022_JP_1 = 0x0822,
|
||||
ISO_2022_JP_3 = 0x0823,
|
||||
ISO_2022_CN = 0x0830,
|
||||
ISO_2022_CN_EXT = 0x0831,
|
||||
ISO_2022_KR = 0x0840,
|
||||
EUC_JP = 0x0920,
|
||||
EUC_CN = 0x0930,
|
||||
EUC_TW = 0x0931,
|
||||
EUC_KR = 0x0940,
|
||||
ShiftJIS = 0x0A01,
|
||||
KOI8_R = 0x0A02,
|
||||
Big5 = 0x0A03,
|
||||
MacRomanLatin1 = 0x0A04,
|
||||
HZ_GB_2312 = 0x0A05,
|
||||
Big5_HKSCS_1999 = 0x0A06,
|
||||
VISCII = 0x0A07,
|
||||
KOI8_U = 0x0A08,
|
||||
Big5_E = 0x0A09,
|
||||
NextStepJapanese = 0x0B02,
|
||||
EBCDIC_US = 0x0C01,
|
||||
EBCDIC_CP037 = 0x0C02,
|
||||
UTF7 = 0x04000100,
|
||||
UTF7_IMAP = 0x0A10,
|
||||
ShiftJIS_X0213_00 = 0x0628, // Deprecated. Use `ShiftJIS_X0213` instead.
|
||||
MacJapanese = 1,
|
||||
MacChineseTrad = 2,
|
||||
MacKorean = 3,
|
||||
MacArabic = 4,
|
||||
MacHebrew = 5,
|
||||
MacGreek = 6,
|
||||
MacCyrillic = 7,
|
||||
MacDevanagari = 9,
|
||||
MacGurmukhi = 10,
|
||||
MacGujarati = 11,
|
||||
MacOriya = 12,
|
||||
MacBengali = 13,
|
||||
MacTamil = 14,
|
||||
MacTelugu = 15,
|
||||
MacKannada = 16,
|
||||
MacMalayalam = 17,
|
||||
MacSinhalese = 18,
|
||||
MacBurmese = 19,
|
||||
MacKhmer = 20,
|
||||
MacThai = 21,
|
||||
MacLaotian = 22,
|
||||
MacGeorgian = 23,
|
||||
MacArmenian = 24,
|
||||
MacChineseSimp = 25,
|
||||
MacTibetan = 26,
|
||||
MacMongolian = 27,
|
||||
MacEthiopic = 28,
|
||||
MacCentralEurRoman = 29,
|
||||
MacVietnamese = 30,
|
||||
MacExtArabic = 31,
|
||||
MacSymbol = 33,
|
||||
MacDingbats = 34,
|
||||
MacTurkish = 35,
|
||||
MacCroatian = 36,
|
||||
MacIcelandic = 37,
|
||||
MacRomanian = 38,
|
||||
MacCeltic = 39,
|
||||
MacGaelic = 40,
|
||||
MacFarsi = 0x8C,
|
||||
MacUkrainian = 0x98,
|
||||
MacInuit = 0xEC,
|
||||
MacVT100 = 0xFC,
|
||||
MacHFS = 0xFF,
|
||||
ISOLatin2 = 0x0202,
|
||||
ISOLatin3 = 0x0203,
|
||||
ISOLatin4 = 0x0204,
|
||||
ISOLatinCyrillic = 0x0205,
|
||||
ISOLatinArabic = 0x0206,
|
||||
ISOLatinGreek = 0x0207,
|
||||
ISOLatinHebrew = 0x0208,
|
||||
ISOLatin5 = 0x0209,
|
||||
ISOLatin6 = 0x020A,
|
||||
ISOLatinThai = 0x020B,
|
||||
ISOLatin7 = 0x020D,
|
||||
ISOLatin8 = 0x020E,
|
||||
ISOLatin9 = 0x020F,
|
||||
ISOLatin10 = 0x0210,
|
||||
DOSLatinUS = 0x0400,
|
||||
DOSGreek = 0x0405,
|
||||
DOSBalticRim = 0x0406,
|
||||
DOSLatin1 = 0x0410,
|
||||
DOSGreek1 = 0x0411,
|
||||
DOSLatin2 = 0x0412,
|
||||
DOSCyrillic = 0x0413,
|
||||
DOSTurkish = 0x0414,
|
||||
DOSPortuguese = 0x0415,
|
||||
DOSIcelandic = 0x0416,
|
||||
DOSHebrew = 0x0417,
|
||||
DOSCanadianFrench = 0x0418,
|
||||
DOSArabic = 0x0419,
|
||||
DOSNordic = 0x041A,
|
||||
DOSRussian = 0x041B,
|
||||
DOSGreek2 = 0x041C,
|
||||
DOSThai = 0x041D,
|
||||
DOSJapanese = 0x0420,
|
||||
DOSChineseSimplif = 0x0421,
|
||||
DOSKorean = 0x0422,
|
||||
DOSChineseTrad = 0x0423,
|
||||
WindowsLatin2 = 0x0501,
|
||||
WindowsCyrillic = 0x0502,
|
||||
WindowsGreek = 0x0503,
|
||||
WindowsLatin5 = 0x0504,
|
||||
WindowsHebrew = 0x0505,
|
||||
WindowsArabic = 0x0506,
|
||||
WindowsBalticRim = 0x0507,
|
||||
WindowsVietnamese = 0x0508,
|
||||
WindowsKoreanJohab = 0x0510,
|
||||
ANSEL = 0x0601,
|
||||
JIS_X0201_76 = 0x0620,
|
||||
JIS_X0208_83 = 0x0621,
|
||||
JIS_X0208_90 = 0x0622,
|
||||
JIS_X0212_90 = 0x0623,
|
||||
JIS_C6226_78 = 0x0624,
|
||||
ShiftJIS_X0213 = 0x0628,
|
||||
ShiftJIS_X0213_MenKuTen = 0x0629,
|
||||
GB_2312_80 = 0x0630,
|
||||
GBK_95 = 0x0631,
|
||||
GB_18030_2000 = 0x0632,
|
||||
KSC_5601_87 = 0x0640,
|
||||
KSC_5601_92_Johab = 0x0641,
|
||||
CNS_11643_92_P1 = 0x0651,
|
||||
CNS_11643_92_P2 = 0x0652,
|
||||
CNS_11643_92_P3 = 0x0653,
|
||||
ISO_2022_JP = 0x0820,
|
||||
ISO_2022_JP_2 = 0x0821,
|
||||
ISO_2022_JP_1 = 0x0822,
|
||||
ISO_2022_JP_3 = 0x0823,
|
||||
ISO_2022_CN = 0x0830,
|
||||
ISO_2022_CN_EXT = 0x0831,
|
||||
ISO_2022_KR = 0x0840,
|
||||
EUC_JP = 0x0920,
|
||||
EUC_CN = 0x0930,
|
||||
EUC_TW = 0x0931,
|
||||
EUC_KR = 0x0940,
|
||||
ShiftJIS = 0x0A01,
|
||||
KOI8_R = 0x0A02,
|
||||
Big5 = 0x0A03,
|
||||
MacRomanLatin1 = 0x0A04,
|
||||
HZ_GB_2312 = 0x0A05,
|
||||
Big5_HKSCS_1999 = 0x0A06,
|
||||
VISCII = 0x0A07,
|
||||
KOI8_U = 0x0A08,
|
||||
Big5_E = 0x0A09,
|
||||
NextStepJapanese = 0x0B02,
|
||||
EBCDIC_US = 0x0C01,
|
||||
EBCDIC_CP037 = 0x0C02,
|
||||
UTF7 = 0x04000100,
|
||||
UTF7_IMAP = 0x0A10,
|
||||
ShiftJIS_X0213_00 = 0x0628, // Deprecated. Use `ShiftJIS_X0213` instead.
|
||||
}
|
||||
|
||||
@(link_prefix = "CF", default_calling_convention = "c")
|
||||
@(link_prefix="CF", default_calling_convention="c")
|
||||
foreign CoreFoundation {
|
||||
// Copies the character contents of a string to a local C string buffer after converting the characters to a given encoding.
|
||||
StringGetCString :: proc(theString: String, buffer: [^]byte, bufferSize: Index, encoding: StringEncoding) -> b8 ---
|
||||
@@ -181,23 +179,16 @@ foreign CoreFoundation {
|
||||
|
||||
STR :: StringMakeConstantString
|
||||
|
||||
StringCopyToOdinString :: proc(
|
||||
theString: String,
|
||||
allocator := context.allocator,
|
||||
) -> (
|
||||
str: string,
|
||||
ok: bool,
|
||||
) #optional_ok {
|
||||
StringCopyToOdinString :: proc(theString: String, allocator := context.allocator) -> (str: string, ok: bool) #optional_ok {
|
||||
length := StringGetLength(theString)
|
||||
max := StringGetMaximumSizeForEncoding(length, StringEncoding(StringBuiltInEncodings.UTF8))
|
||||
|
||||
buf, err := make([]byte, max, allocator)
|
||||
if err != nil { return }
|
||||
|
||||
raw_str := runtime.Raw_String {
|
||||
data = raw_data(buf),
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
StringGetBytes(theString, {0, length}, StringEncoding(StringBuiltInEncodings.UTF8), 0, false, raw_data(buf), max, (^Index)(&raw_str.len))
|
||||
|
||||
return transmute(string)raw_str, true
|
||||
n: Index
|
||||
StringGetBytes(theString, {0, length}, StringEncoding(StringBuiltInEncodings.UTF8), 0, false, raw_data(buf), Index(len(buf)), &n)
|
||||
return string(buf[:n]), true
|
||||
}
|
||||
|
||||
@@ -79,7 +79,10 @@ Application_setActivationPolicy :: proc "c" (self: ^Application, activationPolic
|
||||
return msgSend(BOOL, self, "setActivationPolicy:", activationPolicy)
|
||||
}
|
||||
|
||||
@(deprecated="Use NSApplication method activate instead.")
|
||||
// NOTE: this is technically deprecated but still actively used (Sokol, glfw, SDL, etc.)
|
||||
// and has no clear alternative although `activate` is what Apple tells you to use,
|
||||
// that does not work the same way.
|
||||
// @(deprecated="Use NSApplication method activate instead.")
|
||||
@(objc_type=Application, objc_name="activateIgnoringOtherApps")
|
||||
Application_activateIgnoringOtherApps :: proc "c" (self: ^Application, ignoreOtherApps: BOOL) {
|
||||
msgSend(nil, self, "activateIgnoringOtherApps:", ignoreOtherApps)
|
||||
|
||||
@@ -5,8 +5,8 @@ Event :: struct {using _: Object}
|
||||
|
||||
|
||||
|
||||
EventMask :: distinct bit_set[EventType; UInteger]
|
||||
EventMaskAny :: ~EventMask{}
|
||||
EventMask :: distinct bit_set[EventType; UInteger]
|
||||
EventMaskAny :: transmute(EventMask)(max(UInteger))
|
||||
|
||||
when size_of(UInteger) == 4 {
|
||||
// We don't support a 32-bit darwin system but this is mostly to shut up the type checker for the time being
|
||||
|
||||
@@ -58,7 +58,10 @@ MakeConstantString :: proc "c" (#const c: cstring) -> ^String {
|
||||
|
||||
@(link_prefix="NS", default_calling_convention="c")
|
||||
foreign Foundation {
|
||||
StringFromClass :: proc(cls: Class) -> ^String ---
|
||||
StringFromClass :: proc(cls: Class) -> ^String ---
|
||||
ClassFromString :: proc(str: ^String) -> Class ---
|
||||
StringFromSelector :: proc(selector: SEL) -> ^String ---
|
||||
SelectorFromString :: proc(str: ^String) -> SEL ---
|
||||
}
|
||||
|
||||
@(objc_type=String, objc_name="alloc", objc_is_class_method=true)
|
||||
|
||||
@@ -9,24 +9,85 @@ import "core:c"
|
||||
|
||||
IMP :: proc "c" (object: id, sel: SEL, #c_vararg args: ..any) -> id
|
||||
|
||||
@(default_calling_convention="c")
|
||||
foreign Foundation {
|
||||
objc_getMetaClass :: proc "c" (name: cstring) -> id ---
|
||||
objc_lookUpClass :: proc "c" (name: cstring) -> Class ---
|
||||
objc_allocateClassPair :: proc "c" (superclass : Class, name : cstring, extraBytes : c.size_t) -> Class ---
|
||||
objc_registerClassPair :: proc "c" (cls : Class) ---
|
||||
objc_getMetaClass :: proc(name: cstring) -> id ---
|
||||
objc_lookUpClass :: proc(name: cstring) -> Class ---
|
||||
objc_allocateClassPair :: proc(superclass: Class, name: cstring, extraBytes: c.size_t) -> Class ---
|
||||
objc_registerClassPair :: proc(cls: Class) ---
|
||||
objc_disposeClassPair :: proc(cls: Class) ---
|
||||
objc_duplicateClass :: proc(original: Class, name: cstring, extraBytes: c.size_t) -> Class ---
|
||||
objc_getProtocol :: proc(name: cstring) -> ^Protocol ---
|
||||
objc_copyProtocolList :: proc(outCount: ^uint) -> [^]^Protocol ---
|
||||
objc_constructInstance :: proc(cls: Class, bytes: rawptr) -> id ---
|
||||
objc_destructInstance :: proc(obj: id) -> rawptr ---
|
||||
objc_getClassList :: proc(buffer: [^]Class, bufferCount: int) -> int ---
|
||||
objc_copyClassList :: proc(outCount: ^uint) -> [^]Class ---
|
||||
objc_getRequiredClass :: proc(name: cstring) -> Class ---
|
||||
objc_setAssociatedObject :: proc(object: id, key: rawptr, value: id, policy: objc_AssociationPolicy) ---
|
||||
objc_getAssociatedObject :: proc(object: id, key: rawptr) -> id ---
|
||||
objc_removeAssociatedObjects :: proc(object: id) ---
|
||||
|
||||
sel_registerName :: proc "c" (name: cstring) -> SEL ---
|
||||
sel_registerName :: proc(name: cstring) -> SEL ---
|
||||
sel_getName :: proc(sel: SEL) -> cstring ---
|
||||
sel_isEqual :: proc(lhs, rhs: SEL) -> BOOL ---
|
||||
|
||||
class_addMethod :: proc "c" (cls: Class, name: SEL, imp: IMP, types: cstring) -> BOOL ---
|
||||
class_getInstanceMethod :: proc "c" (cls: Class, name: SEL) -> Method ---
|
||||
class_createInstance :: proc "c" (cls: Class, extraBytes: c.size_t) -> id ---
|
||||
class_addMethod :: proc(cls: Class, name: SEL, imp: IMP, types: cstring) -> BOOL ---
|
||||
class_getInstanceMethod :: proc(cls: Class, name: SEL) -> Method ---
|
||||
class_getClassMethod :: proc(cls: Class, name: SEL) -> Method ---
|
||||
class_copyMethodList :: proc(cls: Class, outCount: ^uint) -> [^]Method ---
|
||||
class_createInstance :: proc(cls: Class, extraBytes: c.size_t) -> id ---
|
||||
class_replaceMethod :: proc(cls: Class, name: SEL, imp: IMP, types: cstring) -> IMP ---
|
||||
class_getMethodImplementation :: proc(cls: Class, name: SEL) -> IMP ---
|
||||
class_getSuperclass :: proc(cls: Class) -> Class ---
|
||||
class_getName :: proc(cls: Class) -> cstring ---
|
||||
class_isMetaClass :: proc(cls: Class) -> BOOL ---
|
||||
class_addProtocol :: proc(cls: Class, protocol: ^Protocol) -> BOOL ---
|
||||
class_getVersion :: proc(cls: Class) -> c.int ---
|
||||
class_setVersion :: proc(cls: Class, version: c.int) ---
|
||||
class_getProperty :: proc(cls: Class, name: cstring) -> objc_property_t ---
|
||||
class_addProperty :: proc(cls: Class, name: cstring, attributes: [^]objc_property_attribute_t, attributeCount: uint) -> BOOL ---
|
||||
class_replaceProperty :: proc(cls: Class, name: cstring, attributes: [^]objc_property_attribute_t, attributeCount: uint) ---
|
||||
class_copyPropertyList :: proc(cls: Class, outCount: ^uint) -> [^]objc_property_t ---
|
||||
class_conformsToProtocol :: proc(cls: Class, protocol: ^Protocol) -> BOOL ---
|
||||
class_copyProtocolList :: proc(cls: Class, outCount: ^uint) -> [^]^Protocol ---
|
||||
class_respondsToSelector :: proc(cls: Class, sel: SEL) -> BOOL ---
|
||||
class_getClassVariable :: proc(cls: Class, name: cstring) -> Ivar ---
|
||||
class_getInstanceVariable :: proc(cls: Class, name: cstring) -> Ivar ---
|
||||
class_addIvar :: proc(cls: Class, name: cstring, size: c.size_t, alignment: u8, types: cstring) -> BOOL ---
|
||||
class_copyIvarList :: proc(cls: Class, outCount: ^uint) -> [^]Ivar ---
|
||||
class_getInstanceSize :: proc(cls: Class) -> c.size_t ---
|
||||
|
||||
method_setImplementation :: proc "c" (method: Method, imp: IMP) ---
|
||||
property_getName :: proc(property: objc_property_t) -> cstring ---
|
||||
property_getAttributes :: proc(property: objc_property_t) -> cstring ---
|
||||
property_copyAttributeList :: proc(property: objc_property_t, outCount: ^uint) -> [^]objc_property_attribute_t ---
|
||||
property_copyAttributeValue :: proc(property: objc_property_t, attributeName: cstring) -> cstring ---
|
||||
|
||||
object_getClass :: proc "c" (obj: id) -> Class ---
|
||||
object_setClass :: proc "c" (obj: id, cls: Class) -> Class ---
|
||||
object_getClassName :: proc "c" (obj: id) -> cstring ---
|
||||
object_getIndexedIvars :: proc "c" (obj: id) -> rawptr ---
|
||||
protocol_conformsToProtocol :: proc(proto: ^Protocol, other: ^Protocol) -> BOOL ---
|
||||
protocol_isEqual :: proc(proto: ^Protocol, other: ^Protocol) -> BOOL ---
|
||||
protocol_getName :: proc(proto: ^Protocol) -> cstring ---
|
||||
|
||||
method_getImplementation :: proc(m: Method) -> IMP ---
|
||||
method_setImplementation :: proc(m: Method, imp: IMP) ---
|
||||
method_copyArgumentType :: proc(m: Method, index: uint) -> cstring ---
|
||||
method_getReturnType :: proc(m: Method, dst: cstring, dst_len: c.size_t) ---
|
||||
method_getNumberOfArguments :: proc(m: Method) -> uint ---
|
||||
method_getArgumentType :: proc(m: Method, index: uint, dst: cstring, dst_len: c.size_t) ---
|
||||
|
||||
object_getClass :: proc(obj: id) -> Class ---
|
||||
object_setClass :: proc(obj: id, cls: Class) -> Class ---
|
||||
object_copy :: proc(obj: id, size: c.size_t) -> id ---
|
||||
object_dispose :: proc(obj: id) -> id ---
|
||||
object_getClassName :: proc(obj: id) -> cstring ---
|
||||
object_getIndexedIvars :: proc(obj: id) -> rawptr ---
|
||||
object_getInstanceVariable :: proc(obj: id, name: cstring, outValue: rawptr) -> Ivar ---
|
||||
object_setInstanceVariable :: proc(obj: id, name: cstring, value: rawptr) -> Ivar ---
|
||||
object_getIvar :: proc(obj: id, ivar: Ivar) -> id ---
|
||||
object_setIvar :: proc(obj: id, ivar: Ivar, value: id) ---
|
||||
|
||||
ivar_getName :: proc(v: Ivar) -> cstring ---
|
||||
ivar_getTypeEncoding :: proc(v: Ivar) -> cstring ---
|
||||
ivar_getOffset :: proc(v: Ivar) -> c.ptrdiff_t ---
|
||||
}
|
||||
|
||||
|
||||
@@ -47,7 +108,17 @@ objc_method :: struct {
|
||||
}
|
||||
objc_method_list :: struct {}
|
||||
|
||||
objc_property :: struct{}
|
||||
objc_property_t :: ^objc_property
|
||||
|
||||
objc_property_attribute_t :: struct {
|
||||
name: cstring,
|
||||
value: cstring,
|
||||
}
|
||||
|
||||
objc_ivar :: struct {}
|
||||
Ivar :: ^objc_ivar
|
||||
|
||||
objc_ivar_list :: struct {}
|
||||
|
||||
objc_cache :: struct {
|
||||
@@ -85,3 +156,11 @@ objc_class_internals :: struct {
|
||||
protocols: rawptr,
|
||||
|
||||
}
|
||||
|
||||
objc_AssociationPolicy :: enum c.uintptr_t {
|
||||
Assign = 0,
|
||||
Retain_Nonatomic = 1,
|
||||
Copy_Nonatomic = 3,
|
||||
Retain = 01401,
|
||||
Copy = 01403,
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//+build darwin
|
||||
#+build darwin
|
||||
package darwin
|
||||
|
||||
import "core:c"
|
||||
|
||||
@@ -5,6 +5,7 @@ foreign import system "system:System.framework"
|
||||
// #define OS_WAIT_ON_ADDR_AVAILABILITY \
|
||||
// __API_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
|
||||
when ODIN_OS == .Darwin {
|
||||
|
||||
when ODIN_PLATFORM_SUBTARGET == .iOS && ODIN_MINIMUM_OS_VERSION >= 17_04_00 {
|
||||
WAIT_ON_ADDRESS_AVAILABLE :: true
|
||||
} else when ODIN_MINIMUM_OS_VERSION >= 14_04_00 {
|
||||
@@ -12,8 +13,18 @@ when ODIN_OS == .Darwin {
|
||||
} else {
|
||||
WAIT_ON_ADDRESS_AVAILABLE :: false
|
||||
}
|
||||
|
||||
when ODIN_PLATFORM_SUBTARGET == .iOS && ODIN_MINIMUM_OS_VERSION >= 14_00_00 {
|
||||
ULOCK_WAIT_2_AVAILABLE :: true
|
||||
} else when ODIN_MINIMUM_OS_VERSION >= 11_00_00 {
|
||||
ULOCK_WAIT_2_AVAILABLE :: true
|
||||
} else {
|
||||
ULOCK_WAIT_2_AVAILABLE :: false
|
||||
}
|
||||
|
||||
} else {
|
||||
WAIT_ON_ADDRESS_AVAILABLE :: false
|
||||
ULOCK_WAIT_2_AVAILABLE :: false
|
||||
}
|
||||
|
||||
os_sync_wait_on_address_flag :: enum u32 {
|
||||
|
||||
@@ -15,9 +15,9 @@ sys_write_string :: proc (fd: c.int, message: string) -> bool {
|
||||
Offset_From :: enum c.int {
|
||||
SEEK_SET = 0, // the offset is set to offset bytes.
|
||||
SEEK_CUR = 1, // the offset is set to its current location plus offset bytes.
|
||||
SEEK_END = 2, // the offset is set to the size of the file plus offset bytes.
|
||||
SEEK_HOLE = 3, // the offset is set to the start of the next hole greater than or equal to the supplied offset.
|
||||
SEEK_DATA = 4, // the offset is set to the start of the next non-hole file region greater than or equal to the supplied offset.
|
||||
SEEK_END = 2, // the offset is set to the size of the file plus offset bytes.
|
||||
SEEK_HOLE = 3, // the offset is set to the start of the next hole greater than or equal to the supplied offset.
|
||||
SEEK_DATA = 4, // the offset is set to the start of the next non-hole file region greater than or equal to the supplied offset.
|
||||
}
|
||||
|
||||
Open_Flags_Enum :: enum u8 {
|
||||
|
||||
@@ -192,43 +192,43 @@ _STRUCT_TIMEVAL :: struct {
|
||||
|
||||
/* pwd.h */
|
||||
_Password_Entry :: struct {
|
||||
pw_name: cstring, /* username */
|
||||
pw_passwd: cstring, /* user password */
|
||||
pw_uid: i32, /* user ID */
|
||||
pw_gid: i32, /* group ID */
|
||||
pw_name: cstring, /* username */
|
||||
pw_passwd: cstring, /* user password */
|
||||
pw_uid: i32, /* user ID */
|
||||
pw_gid: i32, /* group ID */
|
||||
pw_change: u64, /* password change time */
|
||||
pw_class: cstring, /* user access class */
|
||||
pw_gecos: cstring, /* full user name */
|
||||
pw_dir: cstring, /* home directory */
|
||||
pw_shell: cstring, /* shell program */
|
||||
pw_gecos: cstring, /* full user name */
|
||||
pw_dir: cstring, /* home directory */
|
||||
pw_shell: cstring, /* shell program */
|
||||
pw_expire: u64, /* account expiration */
|
||||
pw_fields: i32, /* filled fields */
|
||||
}
|
||||
|
||||
/* processinfo.h */
|
||||
_Proc_Bsdinfo :: struct {
|
||||
pbi_flags: u32, /* if is 64bit; emulated etc */
|
||||
pbi_status: u32,
|
||||
pbi_xstatus: u32,
|
||||
pbi_pid: u32,
|
||||
pbi_ppid: u32,
|
||||
pbi_uid: u32,
|
||||
pbi_gid: u32,
|
||||
pbi_ruid: u32,
|
||||
pbi_rgid: u32,
|
||||
pbi_svuid: u32,
|
||||
pbi_svgid: u32,
|
||||
res: u32,
|
||||
pbi_comm: [DARWIN_MAXCOMLEN]u8,
|
||||
pbi_name: [2 * DARWIN_MAXCOMLEN]u8, /* empty if no name is registered */
|
||||
pbi_nfiles: u32,
|
||||
pbi_pgid: u32,
|
||||
pbi_pjobc: u32,
|
||||
e_tdev: u32, /* controlling tty dev */
|
||||
e_tpgid: u32, /* tty process group id */
|
||||
pbi_nice: i32,
|
||||
pbi_start_tvsec: u64,
|
||||
pbi_start_tvusec: u64,
|
||||
pbi_flags: u32, /* if is 64bit; emulated etc */
|
||||
pbi_status: u32,
|
||||
pbi_xstatus: u32,
|
||||
pbi_pid: u32,
|
||||
pbi_ppid: u32,
|
||||
pbi_uid: u32,
|
||||
pbi_gid: u32,
|
||||
pbi_ruid: u32,
|
||||
pbi_rgid: u32,
|
||||
pbi_svuid: u32,
|
||||
pbi_svgid: u32,
|
||||
res: u32,
|
||||
pbi_comm: [DARWIN_MAXCOMLEN]u8,
|
||||
pbi_name: [2 * DARWIN_MAXCOMLEN]u8, /* empty if no name is registered */
|
||||
pbi_nfiles: u32,
|
||||
pbi_pgid: u32,
|
||||
pbi_pjobc: u32,
|
||||
e_tdev: u32, /* controlling tty dev */
|
||||
e_tpgid: u32, /* tty process group id */
|
||||
pbi_nice: i32,
|
||||
pbi_start_tvsec: u64,
|
||||
pbi_start_tvusec: u64,
|
||||
}
|
||||
|
||||
/*--==========================================================================--*/
|
||||
|
||||
@@ -14,12 +14,16 @@ import "core:c"
|
||||
// FreeBSD 15 syscall numbers
|
||||
// See: https://alfonsosiciliano.gitlab.io/posts/2023-08-28-freebsd-15-system-calls.html
|
||||
|
||||
SYS_read : uintptr : 3
|
||||
SYS_write : uintptr : 4
|
||||
SYS_open : uintptr : 5
|
||||
SYS_close : uintptr : 6
|
||||
SYS_getpid : uintptr : 20
|
||||
SYS_recvfrom : uintptr : 29
|
||||
SYS_accept : uintptr : 30
|
||||
SYS_getsockname: uintptr : 32
|
||||
SYS_fcntl : uintptr : 92
|
||||
SYS_fsync : uintptr : 95
|
||||
SYS_socket : uintptr : 97
|
||||
SYS_connect : uintptr : 98
|
||||
SYS_bind : uintptr : 104
|
||||
@@ -29,12 +33,46 @@ SYS_shutdown : uintptr : 134
|
||||
SYS_setsockopt : uintptr : 105
|
||||
SYS_sysctl : uintptr : 202
|
||||
SYS__umtx_op : uintptr : 454
|
||||
SYS_pread : uintptr : 475
|
||||
SYS_pwrite : uintptr : 476
|
||||
SYS_accept4 : uintptr : 541
|
||||
|
||||
//
|
||||
// Odin syscall wrappers
|
||||
//
|
||||
|
||||
// Read input.
|
||||
//
|
||||
// The read() function appeared in Version 1 AT&T UNIX.
|
||||
read :: proc "contextless" (fd: Fd, buf: []u8) -> (int, Errno) {
|
||||
result, ok := intrinsics.syscall_bsd(SYS_read,
|
||||
cast(uintptr)fd,
|
||||
cast(uintptr)raw_data(buf),
|
||||
cast(uintptr)len(buf))
|
||||
|
||||
if !ok {
|
||||
return 0, cast(Errno)result
|
||||
}
|
||||
|
||||
return cast(int)result, nil
|
||||
}
|
||||
|
||||
// Write output.
|
||||
//
|
||||
// The write() function appeared in Version 1 AT&T UNIX.
|
||||
write :: proc "contextless" (fd: Fd, buf: []u8) -> (int, Errno) {
|
||||
result, ok := intrinsics.syscall_bsd(SYS_pwrite,
|
||||
cast(uintptr)fd,
|
||||
cast(uintptr)raw_data(buf),
|
||||
cast(uintptr)len(buf))
|
||||
|
||||
if !ok {
|
||||
return 0, cast(Errno)result
|
||||
}
|
||||
|
||||
return cast(int)result, nil
|
||||
}
|
||||
|
||||
// Open or create a file for reading, writing or executing.
|
||||
//
|
||||
// The open() function appeared in Version 1 AT&T UNIX.
|
||||
@@ -164,6 +202,36 @@ accept_nil :: proc "contextless" (s: Fd) -> (Fd, Errno) {
|
||||
|
||||
accept :: proc { accept_T, accept_nil }
|
||||
|
||||
// Get socket name.
|
||||
//
|
||||
// The getsockname() system call appeared in 4.2BSD.
|
||||
getsockname :: proc "contextless" (s: Fd, sockaddr: ^$T) -> Errno {
|
||||
// sockaddr must contain a valid pointer, or this will segfault because
|
||||
// we're telling the syscall that there's memory available to write to.
|
||||
addrlen: socklen_t = size_of(T)
|
||||
|
||||
result, ok := intrinsics.syscall_bsd(SYS_getsockname,
|
||||
cast(uintptr)s,
|
||||
cast(uintptr)sockaddr,
|
||||
cast(uintptr)&addrlen)
|
||||
|
||||
if !ok {
|
||||
return cast(Errno)result
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Synchronize changes to a file.
|
||||
//
|
||||
// The fsync() system call appeared in 4.2BSD.
|
||||
fsync :: proc "contextless" (fd: Fd) -> Errno {
|
||||
result, _ := intrinsics.syscall_bsd(SYS_fsync,
|
||||
cast(uintptr)fd)
|
||||
|
||||
return cast(Errno)result
|
||||
}
|
||||
|
||||
// File control.
|
||||
//
|
||||
// The fcntl() system call appeared in 4.2BSD.
|
||||
@@ -469,6 +537,46 @@ _umtx_op :: proc "contextless" (obj: rawptr, op: Userland_Mutex_Operation, val:
|
||||
return cast(Errno)result
|
||||
}
|
||||
|
||||
// Read input without modifying the file pointer.
|
||||
//
|
||||
// The pread() function appeared in AT&T System V Release 4 UNIX.
|
||||
pread :: proc "contextless" (fd: Fd, buf: []u8, offset: off_t) -> (int, Errno) {
|
||||
result, ok := intrinsics.syscall_bsd(SYS_pread,
|
||||
cast(uintptr)fd,
|
||||
cast(uintptr)raw_data(buf),
|
||||
cast(uintptr)len(buf),
|
||||
cast(uintptr)offset)
|
||||
|
||||
if !ok {
|
||||
return 0, cast(Errno)result
|
||||
}
|
||||
|
||||
return cast(int)result, nil
|
||||
}
|
||||
|
||||
// Write output without modifying the file pointer.
|
||||
//
|
||||
// The pwrite() function appeared in AT&T System V Release 4 UNIX.
|
||||
//
|
||||
// BUGS
|
||||
//
|
||||
// The pwrite() system call appends the file without changing the file
|
||||
// offset if O_APPEND is set, contrary to IEEE Std 1003.1-2008 (“POSIX.1”)
|
||||
// where pwrite() writes into offset regardless of whether O_APPEND is set.
|
||||
pwrite :: proc "contextless" (fd: Fd, buf: []u8, offset: off_t) -> (int, Errno) {
|
||||
result, ok := intrinsics.syscall_bsd(SYS_pwrite,
|
||||
cast(uintptr)fd,
|
||||
cast(uintptr)raw_data(buf),
|
||||
cast(uintptr)len(buf),
|
||||
cast(uintptr)offset)
|
||||
|
||||
if !ok {
|
||||
return 0, cast(Errno)result
|
||||
}
|
||||
|
||||
return cast(int)result, nil
|
||||
}
|
||||
|
||||
// Accept a connection on a socket.
|
||||
//
|
||||
// The accept4() system call appeared in FreeBSD 10.0.
|
||||
|
||||
@@ -695,12 +695,12 @@ Record_Lock_Flag :: enum c.int {
|
||||
|
||||
// struct flock
|
||||
File_Lock :: struct {
|
||||
start: off_t, /* starting offset */
|
||||
len: off_t, /* len = 0 means until end of file */
|
||||
pid: pid_t, /* lock owner */
|
||||
type: Record_Lock_Flag, /* lock type: read/write, etc. */
|
||||
whence: c.short, /* type of l_start */
|
||||
sysid: c.int, /* remote system id or zero for local */
|
||||
start: off_t, /* starting offset */
|
||||
len: off_t, /* len = 0 means until end of file */
|
||||
pid: pid_t, /* lock owner */
|
||||
type: Record_Lock_Flag, /* lock type: read/write, etc. */
|
||||
whence: c.short, /* type of l_start */
|
||||
sysid: c.int, /* remote system id or zero for local */
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//+build haiku
|
||||
#+build haiku
|
||||
package sys_haiku
|
||||
|
||||
import "core:c"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//+build haiku
|
||||
#+build haiku
|
||||
package sys_haiku
|
||||
|
||||
import "core:c"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//+build haiku
|
||||
#+build haiku
|
||||
package sys_haiku
|
||||
|
||||
import "core:c"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//+build haiku
|
||||
#+build haiku
|
||||
package sys_haiku
|
||||
|
||||
import "core:c"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//+build arm32, arm64
|
||||
#+build arm32, arm64
|
||||
package sysinfo
|
||||
|
||||
import "core:sys/unix"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//+build i386, amd64
|
||||
#+build i386, amd64
|
||||
package sysinfo
|
||||
|
||||
import "base:intrinsics"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//+build arm32, arm64
|
||||
//+build linux
|
||||
#+build arm32, arm64
|
||||
#+build linux
|
||||
package sysinfo
|
||||
|
||||
import "core:sys/linux"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//+build riscv64
|
||||
//+build linux
|
||||
#+build riscv64
|
||||
#+build linux
|
||||
package sysinfo
|
||||
|
||||
import "base:intrinsics"
|
||||
@@ -8,35 +8,102 @@ import "core:sys/linux"
|
||||
|
||||
@(init, private)
|
||||
init_cpu_features :: proc() {
|
||||
fd, err := linux.open("/proc/self/auxv", {})
|
||||
if err != .NONE { return }
|
||||
defer linux.close(fd)
|
||||
_features: CPU_Features
|
||||
defer cpu_features = _features
|
||||
|
||||
// This is probably enough right?
|
||||
buf: [4096]byte
|
||||
n, rerr := linux.read(fd, buf[:])
|
||||
if rerr != .NONE || n == 0 { return }
|
||||
HWCAP_Bits :: enum u64 {
|
||||
I = 'I' - 'A',
|
||||
M = 'M' - 'A',
|
||||
A = 'A' - 'A',
|
||||
F = 'F' - 'A',
|
||||
D = 'D' - 'A',
|
||||
C = 'C' - 'A',
|
||||
V = 'V' - 'A',
|
||||
}
|
||||
HWCAP :: bit_set[HWCAP_Bits; u64]
|
||||
|
||||
ulong :: u64
|
||||
AT_HWCAP :: 16
|
||||
// Read HWCAP for base extensions, we can get this info through hwprobe too but that is Linux 6.4+ only.
|
||||
{
|
||||
fd, err := linux.open("/proc/self/auxv", {})
|
||||
if err != .NONE { return }
|
||||
defer linux.close(fd)
|
||||
|
||||
// TODO: using these we could get more information than just the basics.
|
||||
// AT_HWCAP2 :: 26
|
||||
// AT_HWCAP3 :: 29
|
||||
// AT_HWCAP4 :: 30
|
||||
// This is probably enough right?
|
||||
buf: [4096]byte
|
||||
n, rerr := linux.read(fd, buf[:])
|
||||
if rerr != .NONE || n == 0 { return }
|
||||
|
||||
auxv := buf[:n]
|
||||
for len(auxv) >= size_of(ulong)*2 {
|
||||
key := intrinsics.unaligned_load((^ulong)(&auxv[0]))
|
||||
val := intrinsics.unaligned_load((^ulong)(&auxv[size_of(ulong)]))
|
||||
auxv = auxv[2*size_of(ulong):]
|
||||
ulong :: u64
|
||||
AT_HWCAP :: 16
|
||||
|
||||
if key != AT_HWCAP {
|
||||
continue
|
||||
auxv := buf[:n]
|
||||
for len(auxv) >= size_of(ulong)*2 {
|
||||
key := intrinsics.unaligned_load((^ulong)(&auxv[0]))
|
||||
val := intrinsics.unaligned_load((^ulong)(&auxv[size_of(ulong)]))
|
||||
auxv = auxv[2*size_of(ulong):]
|
||||
|
||||
if key != AT_HWCAP {
|
||||
continue
|
||||
}
|
||||
|
||||
cap := transmute(HWCAP)(val)
|
||||
if .I in cap {
|
||||
_features += { .I }
|
||||
}
|
||||
if .M in cap {
|
||||
_features += { .M }
|
||||
}
|
||||
if .A in cap {
|
||||
_features += { .A }
|
||||
}
|
||||
if .F in cap {
|
||||
_features += { .F }
|
||||
}
|
||||
if .D in cap {
|
||||
_features += { .D }
|
||||
}
|
||||
if .C in cap {
|
||||
_features += { .C }
|
||||
}
|
||||
if .V in cap {
|
||||
_features += { .V }
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// hwprobe for other features.
|
||||
{
|
||||
pairs := []linux.RISCV_HWProbe{
|
||||
{ key = .IMA_EXT_0 },
|
||||
{ key = .CPUPERF_0 },
|
||||
{ key = .MISALIGNED_SCALAR_PERF },
|
||||
}
|
||||
err := linux.riscv_hwprobe(raw_data(pairs), len(pairs), 0, nil, {})
|
||||
if err != nil {
|
||||
assert(err == .ENOSYS, "unexpected error from riscv_hwprobe()")
|
||||
return
|
||||
}
|
||||
|
||||
cpu_features = transmute(CPU_Features)(val)
|
||||
break
|
||||
assert(pairs[0].key == .IMA_EXT_0)
|
||||
exts := pairs[0].value.ima_ext_0
|
||||
exts -= { .FD, .C, .V }
|
||||
_features += transmute(CPU_Features)exts
|
||||
|
||||
if pairs[2].key == .MISALIGNED_SCALAR_PERF {
|
||||
if pairs[2].value.misaligned_scalar_perf == .FAST {
|
||||
_features += { .Misaligned_Supported, .Misaligned_Fast }
|
||||
} else if pairs[2].value.misaligned_scalar_perf != .UNSUPPORTED {
|
||||
_features += { .Misaligned_Supported }
|
||||
}
|
||||
} else {
|
||||
assert(pairs[1].key == .CPUPERF_0)
|
||||
if .FAST in pairs[1].value.cpu_perf_0 {
|
||||
_features += { .Misaligned_Supported, .Misaligned_Fast }
|
||||
} else if .UNSUPPORTED not_in pairs[1].value.cpu_perf_0 {
|
||||
_features += { .Misaligned_Supported }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,13 +1,97 @@
|
||||
package sysinfo
|
||||
|
||||
CPU_Feature :: enum u64 {
|
||||
I = 'I' - 'A', // Base features, don't think this is ever not here.
|
||||
M = 'M' - 'A', // Integer multiplication and division, currently required by Odin.
|
||||
A = 'A' - 'A', // Atomics.
|
||||
F = 'F' - 'A', // Single precision floating point, currently required by Odin.
|
||||
D = 'D' - 'A', // Double precision floating point, currently required by Odin.
|
||||
C = 'C' - 'A', // Compressed instructions.
|
||||
V = 'V' - 'A', // Vector operations.
|
||||
// Bit-Manipulation ISA Extensions v1.
|
||||
Zba = 3,
|
||||
Zbb,
|
||||
Zbs,
|
||||
|
||||
// CMOs (ratified).
|
||||
Zicboz,
|
||||
|
||||
// Bit-Manipulation ISA Extensions v1.
|
||||
Zbc,
|
||||
|
||||
// Scalar Crypto ISA extensions v1.
|
||||
Zbkb,
|
||||
Zbkc,
|
||||
Zbkx,
|
||||
Zknd,
|
||||
Zkne,
|
||||
Zknh,
|
||||
Zksed,
|
||||
Zksh,
|
||||
Zkt,
|
||||
|
||||
// Cryptography Extensions Volume II v1.
|
||||
Zvbb,
|
||||
Zvbc,
|
||||
Zvkb,
|
||||
Zvkg,
|
||||
Zvkned,
|
||||
Zvknha,
|
||||
Zvknhb,
|
||||
Zvksed,
|
||||
Zvksh,
|
||||
Zvkt,
|
||||
|
||||
// ISA Manual v1.
|
||||
Zfh,
|
||||
Zfhmin,
|
||||
Zihintntl,
|
||||
|
||||
// ISA manual (ratified).
|
||||
Zvfh,
|
||||
Zvfhmin,
|
||||
Zfa,
|
||||
Ztso,
|
||||
|
||||
// Atomic Compare-and-Swap Instructions Manual (ratified).
|
||||
Zacas,
|
||||
Zicond,
|
||||
|
||||
// ISA manual (ratified).
|
||||
Zihintpause,
|
||||
|
||||
// Vector Extensions Manual v1.
|
||||
Zve32x,
|
||||
Zve32f,
|
||||
Zve64x,
|
||||
Zve64f,
|
||||
Zve64d,
|
||||
|
||||
// ISA manual (ratified).
|
||||
Zimop,
|
||||
|
||||
// Code Size Reduction (ratified).
|
||||
Zca,
|
||||
Zcb,
|
||||
Zcd,
|
||||
Zcf,
|
||||
|
||||
// ISA manual (ratified).
|
||||
Zcmop,
|
||||
Zawrs,
|
||||
|
||||
// Base features, don't think this is ever not here.
|
||||
I,
|
||||
// Integer multiplication and division, currently required by Odin.
|
||||
M,
|
||||
// Atomics.
|
||||
A,
|
||||
// Single precision floating point, currently required by Odin.
|
||||
F,
|
||||
// Double precision floating point, currently required by Odin.
|
||||
D,
|
||||
// Compressed instructions.
|
||||
C,
|
||||
// Vector operations.
|
||||
V,
|
||||
|
||||
// Indicates Misaligned Scalar Loads will not trap the program.
|
||||
Misaligned_Supported,
|
||||
// Indicates Hardware Support for Misaligned Scalar Loads.
|
||||
Misaligned_Fast,
|
||||
}
|
||||
|
||||
CPU_Features :: distinct bit_set[CPU_Feature; u64]
|
||||
|
||||
@@ -2,6 +2,12 @@
|
||||
Copyright 2022 Jeroen van Rijn <nom@duclavier.com>.
|
||||
Made available under Odin's BSD-3 license.
|
||||
|
||||
List of contributors:
|
||||
Jeroen van Rijn: Initial implementation.
|
||||
Laytan: ARM and RISC-V CPU feature detection.
|
||||
*/
|
||||
|
||||
/*
|
||||
Package `core:sys/info` gathers system information on:
|
||||
Windows, Linux, macOS, FreeBSD & OpenBSD.
|
||||
|
||||
@@ -11,9 +17,10 @@ and CPU information.
|
||||
On Windows, GPUs will also be enumerated using the registry.
|
||||
|
||||
CPU feature flags can be tested against `cpu_features`, where applicable, e.g.
|
||||
`if .aes in si.aes { ... }`
|
||||
`if .aes in info.cpu_features.? { ... }`
|
||||
|
||||
Example:
|
||||
package main
|
||||
|
||||
import "core:fmt"
|
||||
import si "core:sys/info"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//+build openbsd, netbsd
|
||||
#+build openbsd, netbsd
|
||||
package sysinfo
|
||||
|
||||
import sys "core:sys/unix"
|
||||
|
||||
@@ -530,6 +530,10 @@ macos_release_map: map[string]Darwin_To_Release = {
|
||||
"23F79" = {{23, 5, 0}, "macOS", {"Sonoma", {14, 5, 0}}},
|
||||
"23G80" = {{23, 6, 0}, "macOS", {"Sonoma", {14, 6, 0}}},
|
||||
"23G93" = {{23, 6, 0}, "macOS", {"Sonoma", {14, 6, 1}}},
|
||||
"23H124" = {{23, 6, 0}, "macOS", {"Sonoma", {14, 7, 0}}},
|
||||
|
||||
// MacOS Sequoia
|
||||
"24A335" = {{24, 0, 0}, "macOS", {"Sequoia", {15, 0, 0}}},
|
||||
}
|
||||
|
||||
@(private)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//+build darwin, netbsd, openbsd, freebsd
|
||||
#+build darwin, netbsd, openbsd, freebsd
|
||||
package kqueue
|
||||
|
||||
when ODIN_OS == .Darwin {
|
||||
|
||||
@@ -1839,3 +1839,87 @@ Execveat_Flags_Bits :: enum {
|
||||
AT_SYMLINK_NOFOLLOW = 8,
|
||||
AT_EMPTY_PATH = 12,
|
||||
}
|
||||
|
||||
RISCV_HWProbe_Key :: enum i64 {
|
||||
UNSUPPORTED = -1,
|
||||
MVENDORID = 0,
|
||||
MARCHID = 1,
|
||||
MIMPID = 2,
|
||||
BASE_BEHAVIOR = 3,
|
||||
IMA_EXT_0 = 4,
|
||||
// Deprecated, try `.MISALIGNED_SCALAR_PERF` first, if that is `.UNSUPPORTED`, use this.
|
||||
CPUPERF_0 = 5,
|
||||
ZICBOZ_BLOCK_SIZE = 6,
|
||||
HIGHEST_VIRT_ADDRESS = 7,
|
||||
TIME_CSR_FREQ = 8,
|
||||
MISALIGNED_SCALAR_PERF = 9,
|
||||
}
|
||||
|
||||
RISCV_HWProbe_Flags_Bits :: enum {
|
||||
WHICH_CPUS,
|
||||
}
|
||||
|
||||
RISCV_HWProbe_Base_Behavior_Bits :: enum {
|
||||
IMA,
|
||||
}
|
||||
|
||||
RISCV_HWProbe_IMA_Ext_0_Bits :: enum {
|
||||
FD,
|
||||
C,
|
||||
V,
|
||||
EXT_ZBA,
|
||||
EXT_ZBB,
|
||||
EXT_ZBS,
|
||||
EXT_ZICBOZ,
|
||||
EXT_ZBC,
|
||||
EXT_ZBKB,
|
||||
EXT_ZBKC,
|
||||
EXT_ZBKX,
|
||||
EXT_ZKND,
|
||||
EXT_ZKNE,
|
||||
EXT_ZKNH,
|
||||
EXT_ZKSED,
|
||||
EXT_ZKSH,
|
||||
EXT_ZKT,
|
||||
EXT_ZVBB,
|
||||
EXT_ZVBC,
|
||||
EXT_ZVKB,
|
||||
EXT_ZVKG,
|
||||
EXT_ZVKNED,
|
||||
EXT_ZVKNHA,
|
||||
EXT_ZVKNHB,
|
||||
EXT_ZVKSED,
|
||||
EXT_ZVKSH,
|
||||
EXT_ZVKT,
|
||||
EXT_ZFH,
|
||||
EXT_ZFHMIN,
|
||||
EXT_ZIHINTNTL,
|
||||
EXT_ZVFH,
|
||||
EXT_ZVFHMIN,
|
||||
EXT_ZFA,
|
||||
EXT_ZTSO,
|
||||
EXT_ZACAS,
|
||||
EXT_ZICOND,
|
||||
EXT_ZIHINTPAUSE,
|
||||
EXT_ZVE32X,
|
||||
EXT_ZVE32F,
|
||||
EXT_ZVE64X,
|
||||
EXT_ZVE64F,
|
||||
EXT_ZVE64D,
|
||||
EXT_ZIMOP,
|
||||
EXT_ZCA,
|
||||
EXT_ZCB,
|
||||
EXT_ZCD,
|
||||
EXT_ZCF,
|
||||
EXT_ZCMOP,
|
||||
EXT_ZAWRS,
|
||||
}
|
||||
|
||||
RISCV_HWProbe_Misaligned_Scalar_Perf :: enum {
|
||||
UNKNOWN,
|
||||
EMULATED,
|
||||
SLOW,
|
||||
FAST,
|
||||
UNSUPPORTED,
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//+build linux
|
||||
//+no-instrumentation
|
||||
#+build linux
|
||||
#+no-instrumentation
|
||||
package linux
|
||||
|
||||
import "base:intrinsics"
|
||||
|
||||
+31
-15
@@ -1,4 +1,4 @@
|
||||
//+no-instrumentation
|
||||
#+no-instrumentation
|
||||
package linux
|
||||
|
||||
import "base:intrinsics"
|
||||
@@ -1443,8 +1443,9 @@ ptrace_traceme :: proc "contextless" (rq: PTrace_Traceme_Type) -> (Errno) {
|
||||
}
|
||||
|
||||
ptrace_peek :: proc "contextless" (rq: PTrace_Peek_Type, pid: Pid, addr: uintptr) -> (uint, Errno) {
|
||||
ret := syscall(SYS_ptrace, rq, pid, addr)
|
||||
return errno_unwrap(ret, uint)
|
||||
res: uint = ---
|
||||
ret := syscall(SYS_ptrace, rq, pid, addr, &res)
|
||||
return res, Errno(-ret)
|
||||
}
|
||||
|
||||
ptrace_poke :: proc "contextless" (rq: PTrace_Poke_Type, pid: Pid, addr: uintptr, data: uint) -> (Errno) {
|
||||
@@ -1493,12 +1494,12 @@ ptrace_setregset :: proc "contextless" (rq: PTrace_Setregset_Type, pid: Pid, not
|
||||
}
|
||||
|
||||
ptrace_getsiginfo :: proc "contextless" (rq: PTrace_Getsiginfo_Type, pid: Pid, si: ^Sig_Info) -> (Errno) {
|
||||
ret := syscall(SYS_ptrace, rq, pid, si)
|
||||
ret := syscall(SYS_ptrace, rq, pid, si, rawptr(nil))
|
||||
return Errno(-ret)
|
||||
}
|
||||
|
||||
ptrace_peeksiginfo :: proc "contextless" (rq: PTrace_Peeksiginfo_Type, pid: Pid, si: ^Sig_Info) -> (Errno) {
|
||||
ret := syscall(SYS_ptrace, rq, pid, si)
|
||||
ret := syscall(SYS_ptrace, rq, pid, si, rawptr(nil))
|
||||
return Errno(-ret)
|
||||
}
|
||||
|
||||
@@ -1518,52 +1519,52 @@ ptrace_setoptions :: proc "contextless" (rq: PTrace_Setoptions_Type, pid: Pid, o
|
||||
}
|
||||
|
||||
ptrace_geteventmsg :: proc "contextless" (rq: PTrace_Geteventmsg_Type, pid: Pid, msg: ^uint) -> (Errno) {
|
||||
ret := syscall(SYS_ptrace, rq, pid, msg)
|
||||
ret := syscall(SYS_ptrace, rq, pid, msg, rawptr(nil))
|
||||
return Errno(-ret)
|
||||
}
|
||||
|
||||
ptrace_cont :: proc "contextless" (rq: PTrace_Cont_Type, pid: Pid, sig: Signal) -> (Errno) {
|
||||
ret := syscall(SYS_ptrace, rq, pid, sig)
|
||||
ret := syscall(SYS_ptrace, rq, pid, rawptr(nil), sig)
|
||||
return Errno(-ret)
|
||||
}
|
||||
|
||||
ptrace_singlestep :: proc "contextless" (rq: PTrace_Singlestep_Type, pid: Pid, sig: Signal) -> (Errno) {
|
||||
ret := syscall(SYS_ptrace, rq, pid, sig)
|
||||
ret := syscall(SYS_ptrace, rq, pid, rawptr(nil), sig)
|
||||
return Errno(-ret)
|
||||
}
|
||||
|
||||
ptrace_syscall :: proc "contextless" (rq: PTrace_Syscall_Type, pid: Pid, sig: Signal) -> (Errno) {
|
||||
ret := syscall(SYS_ptrace, rq, pid, sig)
|
||||
ret := syscall(SYS_ptrace, rq, pid, rawptr(nil), sig)
|
||||
return Errno(-ret)
|
||||
}
|
||||
|
||||
ptrace_sysemu :: proc "contextless" (rq: PTrace_Sysemu_Type, pid: Pid, sig: Signal) -> (Errno) {
|
||||
ret := syscall(SYS_ptrace, rq, pid, sig)
|
||||
ret := syscall(SYS_ptrace, rq, pid, rawptr(nil), sig)
|
||||
return Errno(-ret)
|
||||
}
|
||||
|
||||
ptrace_sysemu_singlestep :: proc "contextless" (rq: PTrace_Sysemu_Singlestep_Type, pid: Pid, sig: Signal) -> (Errno) {
|
||||
ret := syscall(SYS_ptrace, rq, pid, sig)
|
||||
ret := syscall(SYS_ptrace, rq, pid, rawptr(nil), sig)
|
||||
return Errno(-ret)
|
||||
}
|
||||
|
||||
ptrace_listen :: proc "contextless" (rq: PTrace_Listen_Type, pid: Pid) -> (Errno) {
|
||||
ret := syscall(SYS_ptrace, rq, pid)
|
||||
ret := syscall(SYS_ptrace, rq, pid, 0, rawptr(nil))
|
||||
return Errno(-ret)
|
||||
}
|
||||
|
||||
ptrace_interrupt :: proc "contextless" (rq: PTrace_Interrupt_Type, pid: Pid) -> (Errno) {
|
||||
ret := syscall(SYS_ptrace, rq, pid)
|
||||
ret := syscall(SYS_ptrace, rq, pid, 0, rawptr(nil))
|
||||
return Errno(-ret)
|
||||
}
|
||||
|
||||
ptrace_attach :: proc "contextless" (rq: PTrace_Attach_Type, pid: Pid) -> (Errno) {
|
||||
ret := syscall(SYS_ptrace, rq, pid)
|
||||
ret := syscall(SYS_ptrace, rq, pid, 0, rawptr(nil))
|
||||
return Errno(-ret)
|
||||
}
|
||||
|
||||
ptrace_seize :: proc "contextless" (rq: PTrace_Seize_Type, pid: Pid, opt: PTrace_Options) -> (Errno) {
|
||||
ret := syscall(SYS_ptrace, rq, pid, 0, transmute(u32) opt)
|
||||
ret := syscall(SYS_ptrace, rq, pid, 0, transmute(u32) opt, rawptr(nil))
|
||||
return Errno(-ret)
|
||||
}
|
||||
|
||||
@@ -2993,3 +2994,18 @@ epoll_pwait2 :: proc(epfd: Fd, events: [^]EPoll_Event, count: i32, timeout: ^Tim
|
||||
// TODO(flysand): fchmodat2
|
||||
|
||||
// TODO(flysand): map_shadow_stack
|
||||
|
||||
when ODIN_ARCH == .riscv64 {
|
||||
/*
|
||||
Probe for RISC-V Hardware Support.
|
||||
Available since Linux 6.4.
|
||||
|
||||
TODO: cpu_set_t
|
||||
|
||||
See: https://docs.kernel.org/arch/riscv/hwprobe.html
|
||||
*/
|
||||
riscv_hwprobe :: proc "contextless" (pairs: [^]RISCV_HWProbe, pair_count: uint, cpu_count: uint, cpus: rawptr /* cpu_set_t */, flags: RISCV_HWProbe_Flags) -> Errno {
|
||||
ret := syscall(SYS_riscv_hwprobe, pairs, pair_count, cpu_count, cpus, transmute(u32)flags)
|
||||
return Errno(-ret)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//+build amd64
|
||||
#+build amd64
|
||||
package linux
|
||||
|
||||
// AMD64 uses the new way to define syscalls, i.e. one that
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//+build arm32
|
||||
#+build arm32
|
||||
package linux
|
||||
|
||||
// This file was taken and transformed from
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//+build arm64
|
||||
#+build arm64
|
||||
package linux
|
||||
|
||||
// Syscalls for arm64 are defined using the new way, i.e. differently from
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//+build i386
|
||||
#+build i386
|
||||
package linux
|
||||
|
||||
// The numbers are taken from
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//+build riscv64
|
||||
#+build riscv64
|
||||
package linux
|
||||
|
||||
// https://github.com/riscv-collab/riscv-gnu-toolchain/blob/master/linux-headers/include/asm-generic/unistd.h
|
||||
@@ -248,6 +248,7 @@ SYS_rt_tgsigqueueinfo :: uintptr(240)
|
||||
SYS_perf_event_open :: uintptr(241)
|
||||
SYS_accept4 :: uintptr(242)
|
||||
SYS_recvmmsg :: uintptr(243)
|
||||
SYS_riscv_hwprobe :: uintptr(258)
|
||||
SYS_wait4 :: uintptr(260)
|
||||
SYS_prlimit64 :: uintptr(261)
|
||||
SYS_fanotify_init :: uintptr(262)
|
||||
|
||||
@@ -1335,3 +1335,20 @@ EPoll_Event :: struct #packed {
|
||||
Flags for execveat(2) syscall.
|
||||
*/
|
||||
Execveat_Flags :: bit_set[Execveat_Flags_Bits; i32]
|
||||
|
||||
RISCV_HWProbe_Flags :: bit_set[RISCV_HWProbe_Flags_Bits; u32]
|
||||
RISCV_HWProbe_CPU_Perf_0 :: bit_set[RISCV_HWProbe_Misaligned_Scalar_Perf; u64]
|
||||
RISCV_HWProbe_Base_Behavior :: bit_set[RISCV_HWProbe_Base_Behavior_Bits; u64]
|
||||
RISCV_HWProbe_IMA_Ext_0 :: bit_set[RISCV_HWProbe_IMA_Ext_0_Bits; u64]
|
||||
|
||||
RISCV_HWProbe :: struct {
|
||||
// set to `.UNSUPPORTED` by the kernel if that is the case.
|
||||
key: RISCV_HWProbe_Key,
|
||||
value: struct #raw_union {
|
||||
base_behavior: RISCV_HWProbe_Base_Behavior,
|
||||
ima_ext_0: RISCV_HWProbe_IMA_Ext_0,
|
||||
cpu_perf_0: RISCV_HWProbe_CPU_Perf_0,
|
||||
misaligned_scalar_perf: RISCV_HWProbe_Misaligned_Scalar_Perf,
|
||||
raw: u64,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//+build linux
|
||||
#+build linux
|
||||
package linux
|
||||
|
||||
/// Low 8 bits of the exit code
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// Bit Manipulation Intrinsics
|
||||
|
||||
package sys_llvm
|
||||
|
||||
/*
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// Code Generator Intrinsics
|
||||
|
||||
package sys_llvm
|
||||
|
||||
@(default_calling_convention="none")
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// Standard C Library Intrinsics
|
||||
|
||||
package sys_llvm
|
||||
|
||||
@(default_calling_convention="none")
|
||||
|
||||
@@ -13,7 +13,7 @@ when ODIN_OS == .Darwin {
|
||||
|
||||
foreign lib {
|
||||
/*
|
||||
Convert the broken down time in the structure to a string form: Sun Sep 16 01:03:52 1973\n\0
|
||||
Convert the broken down time in the structure to a string form: Sun Sep 16 01:03:52 1973.
|
||||
|
||||
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/asctime_r.html ]]
|
||||
*/
|
||||
|
||||
@@ -112,7 +112,7 @@ foreign lib {
|
||||
Return configuration-defined string values.
|
||||
Its use and purpose are similar to sysconf(), but it is used where string values rather than numeric values are returned.
|
||||
|
||||
Returns: 0 (setting errno) if `name` is invalid, need `buf` `len` if buf is `nil`, amount of bytes added to buf otherwise
|
||||
Returns: 0 (setting errno) if `name` is invalid, need `buf` of `len` bytes if `buf` is `nil`, amount of bytes added to buf otherwise
|
||||
|
||||
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/confstr.html ]]
|
||||
*/
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//+build darwin
|
||||
#+build darwin
|
||||
package unix
|
||||
|
||||
import "core:c"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//+build freebsd
|
||||
#+build freebsd
|
||||
package unix
|
||||
|
||||
import "core:c"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//+build linux
|
||||
#+build linux
|
||||
package unix
|
||||
|
||||
import "core:c"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//+build openbsd
|
||||
#+build openbsd
|
||||
package unix
|
||||
|
||||
import "core:c"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//+build linux, darwin, freebsd, openbsd, netbsd, haiku
|
||||
#+build linux, darwin, freebsd, openbsd, netbsd, haiku
|
||||
package unix
|
||||
|
||||
foreign import "system:pthread"
|
||||
@@ -27,6 +27,8 @@ foreign pthread {
|
||||
|
||||
pthread_equal :: proc(a, b: pthread_t) -> b32 ---
|
||||
|
||||
pthread_detach :: proc(t: pthread_t) -> c.int ---
|
||||
|
||||
sched_get_priority_min :: proc(policy: c.int) -> c.int ---
|
||||
sched_get_priority_max :: proc(policy: c.int) -> c.int ---
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//+build darwin
|
||||
#+build darwin
|
||||
package unix
|
||||
|
||||
import "base:intrinsics"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//+build freebsd
|
||||
#+build freebsd
|
||||
package unix
|
||||
|
||||
import "base:intrinsics"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//+build openbsd
|
||||
#+build openbsd
|
||||
package unix
|
||||
|
||||
import "core:c"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//+build amd64
|
||||
#+build amd64
|
||||
package sys_valgrind
|
||||
|
||||
import "base:intrinsics"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//+build amd64
|
||||
#+build amd64
|
||||
package sys_valgrind
|
||||
|
||||
import "base:intrinsics"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//+build amd64
|
||||
#+build amd64
|
||||
package sys_valgrind
|
||||
|
||||
import "base:intrinsics"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//+build amd64
|
||||
#+build amd64
|
||||
package sys_valgrind
|
||||
|
||||
import "base:intrinsics"
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
# WASM on the Web
|
||||
|
||||
This directory is for use when targeting the `js_wasm32` target and the packages that rely on it.
|
||||
|
||||
The `js_wasm32` target assumes that the WASM output will be ran within a web browser rather than a standalone VM. In the VM cases, either `wasi_wasm32` or `freestanding_wasm32` should be used accordingly.
|
||||
|
||||
## Example for `js_wasm32`
|
||||
|
||||
```html
|
||||
<!-- Copy `core:sys/wasm/js/odin.js` into your web server -->
|
||||
<script type="text/javascript" src="odin.js"></script>
|
||||
<script type="text/javascript">
|
||||
odin.runWasm(pathToWasm, consolePreElement);
|
||||
</script>
|
||||
```
|
||||
@@ -0,0 +1,93 @@
|
||||
#+build js wasm32, js wasm64p32
|
||||
package wasm_js_interface
|
||||
|
||||
foreign import dom_lib "odin_dom"
|
||||
|
||||
@(default_calling_convention="contextless")
|
||||
foreign dom_lib {
|
||||
get_element_value_f64 :: proc(id: string) -> f64 ---
|
||||
set_element_value_f64 :: proc(id: string, value: f64) ---
|
||||
|
||||
get_element_key_f64 :: proc(id: string, key: string) -> f64 ---
|
||||
set_element_key_f64 :: proc(id: string, key: string, value: f64) ---
|
||||
|
||||
set_element_value_string :: proc(id: string, value: string) ---
|
||||
get_element_value_string_length :: proc(id: string) -> int ---
|
||||
|
||||
set_element_key_string :: proc(id: string, key: string, value: string) ---
|
||||
get_element_key_string_length :: proc(id: string, key: string, ) -> int ---
|
||||
|
||||
device_pixel_ratio :: proc() -> f64 ---
|
||||
|
||||
window_set_scroll :: proc(x, y: f64) ---
|
||||
}
|
||||
|
||||
get_element_value_string :: proc "contextless" (id: string, buf: []byte) -> string {
|
||||
@(default_calling_convention="contextless")
|
||||
foreign dom_lib {
|
||||
@(link_name="get_element_value_string")
|
||||
_get_element_value_string :: proc(id: string, buf: []byte) -> int ---
|
||||
}
|
||||
n := _get_element_value_string(id, buf)
|
||||
return string(buf[:n])
|
||||
}
|
||||
|
||||
get_element_key_string :: proc "contextless" (id: string, key: string, buf: []byte) -> string {
|
||||
@(default_calling_convention="contextless")
|
||||
foreign dom_lib {
|
||||
@(link_name="get_element_key_string")
|
||||
_get_element_key_string :: proc(id: string, key: string, buf: []byte) -> int ---
|
||||
}
|
||||
n := _get_element_key_string(id, key, buf)
|
||||
return string(buf[:n])
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
get_element_min_max :: proc "contextless" (id: string) -> (min, max: f64) {
|
||||
@(default_calling_convention="contextless")
|
||||
foreign dom_lib {
|
||||
@(link_name="get_element_min_max")
|
||||
_get_element_min_max :: proc(min_max: ^[2]f64, id: string) ---
|
||||
}
|
||||
min_max: [2]f64
|
||||
_get_element_min_max(&min_max, id)
|
||||
return min_max[0], min_max[1]
|
||||
}
|
||||
|
||||
|
||||
Rect :: struct {
|
||||
x, y, width, height: f64,
|
||||
}
|
||||
|
||||
get_bounding_client_rect :: proc "contextless" (id: string) -> (rect: Rect) {
|
||||
@(default_calling_convention="contextless")
|
||||
foreign dom_lib {
|
||||
@(link_name="get_bounding_client_rect")
|
||||
_get_bounding_client_rect :: proc(rect: ^Rect, id: string) ---
|
||||
}
|
||||
_get_bounding_client_rect(&rect, id)
|
||||
return
|
||||
}
|
||||
|
||||
window_get_rect :: proc "contextless" () -> (rect: Rect) {
|
||||
@(default_calling_convention="contextless")
|
||||
foreign dom_lib {
|
||||
@(link_name="window_get_rect")
|
||||
_window_get_rect :: proc(rect: ^Rect) ---
|
||||
}
|
||||
_window_get_rect(&rect)
|
||||
return
|
||||
}
|
||||
|
||||
window_get_scroll :: proc "contextless" () -> (x, y: f64) {
|
||||
@(default_calling_convention="contextless")
|
||||
foreign dom_lib {
|
||||
@(link_name="window_get_scroll")
|
||||
_window_get_scroll :: proc(scroll: ^[2]f64) ---
|
||||
}
|
||||
scroll: [2]f64
|
||||
_window_get_scroll(&scroll)
|
||||
return scroll.x, scroll.y
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
#+build !js
|
||||
package wasm_js_interface
|
||||
|
||||
import "base:runtime"
|
||||
|
||||
|
||||
get_element_value_string :: proc "contextless" (id: string, buf: []byte) -> string {
|
||||
context = runtime.default_context()
|
||||
panic("vendor:wasm/js not supported on non JS targets")
|
||||
}
|
||||
|
||||
|
||||
get_element_min_max :: proc "contextless" (id: string) -> (min, max: f64) {
|
||||
context = runtime.default_context()
|
||||
panic("vendor:wasm/js not supported on non JS targets")
|
||||
}
|
||||
|
||||
|
||||
Rect :: struct {
|
||||
x, y, width, height: f64,
|
||||
}
|
||||
|
||||
get_bounding_client_rect :: proc "contextless" (id: string) -> (rect: Rect) {
|
||||
context = runtime.default_context()
|
||||
panic("vendor:wasm/js not supported on non JS targets")
|
||||
}
|
||||
|
||||
window_get_rect :: proc "contextless" () -> (rect: Rect) {
|
||||
context = runtime.default_context()
|
||||
panic("vendor:wasm/js not supported on non JS targets")
|
||||
}
|
||||
|
||||
window_get_scroll :: proc "contextless" () -> (x, y: f64) {
|
||||
context = runtime.default_context()
|
||||
panic("vendor:wasm/js not supported on non JS targets")
|
||||
}
|
||||
@@ -0,0 +1,418 @@
|
||||
#+build js wasm32, js wasm64p32
|
||||
package wasm_js_interface
|
||||
|
||||
foreign import dom_lib "odin_dom"
|
||||
|
||||
Event_Kind :: enum u32 {
|
||||
Invalid,
|
||||
|
||||
Load,
|
||||
Unload,
|
||||
Error,
|
||||
Resize,
|
||||
Visibility_Change,
|
||||
Fullscreen_Change,
|
||||
Fullscreen_Error,
|
||||
|
||||
Click,
|
||||
Double_Click,
|
||||
Mouse_Move,
|
||||
Mouse_Over,
|
||||
Mouse_Out,
|
||||
Mouse_Up,
|
||||
Mouse_Down,
|
||||
|
||||
Key_Up,
|
||||
Key_Down,
|
||||
Key_Press,
|
||||
|
||||
Scroll,
|
||||
Wheel,
|
||||
|
||||
Focus,
|
||||
Focus_In,
|
||||
Focus_Out,
|
||||
Submit,
|
||||
Blur,
|
||||
Change,
|
||||
Hash_Change,
|
||||
Select,
|
||||
|
||||
Animation_Start,
|
||||
Animation_End,
|
||||
Animation_Iteration,
|
||||
Animation_Cancel,
|
||||
|
||||
Copy,
|
||||
Cut,
|
||||
Paste,
|
||||
|
||||
// Drag,
|
||||
// Drag_Start,
|
||||
// Drag_End,
|
||||
// Drag_Enter,
|
||||
// Drag_Leave,
|
||||
// Drag_Over,
|
||||
// Drop,
|
||||
|
||||
Pointer_Cancel,
|
||||
Pointer_Down,
|
||||
Pointer_Enter,
|
||||
Pointer_Leave,
|
||||
Pointer_Move,
|
||||
Pointer_Over,
|
||||
Pointer_Up,
|
||||
Got_Pointer_Capture,
|
||||
Lost_Pointer_Capture,
|
||||
Pointer_Lock_Change,
|
||||
Pointer_Lock_Error,
|
||||
|
||||
Selection_Change,
|
||||
Selection_Start,
|
||||
|
||||
Touch_Cancel,
|
||||
Touch_End,
|
||||
Touch_Move,
|
||||
Touch_Start,
|
||||
|
||||
Transition_Start,
|
||||
Transition_End,
|
||||
Transition_Run,
|
||||
Transition_Cancel,
|
||||
|
||||
Context_Menu,
|
||||
|
||||
Gamepad_Connected,
|
||||
Gamepad_Disconnected,
|
||||
|
||||
Custom,
|
||||
|
||||
}
|
||||
event_kind_string := [Event_Kind]string{
|
||||
.Invalid = "",
|
||||
|
||||
.Load = "load",
|
||||
.Unload = "unload",
|
||||
.Error = "error",
|
||||
.Resize = "resize",
|
||||
.Visibility_Change = "visibilitychange",
|
||||
.Fullscreen_Change = "fullscreenchange",
|
||||
.Fullscreen_Error = "fullscreenerror",
|
||||
|
||||
.Click = "click",
|
||||
.Double_Click = "dblclick",
|
||||
.Mouse_Move = "mousemove",
|
||||
.Mouse_Over = "mouseover",
|
||||
.Mouse_Out = "mouseout",
|
||||
.Mouse_Up = "mouseup",
|
||||
.Mouse_Down = "mousedown",
|
||||
|
||||
.Key_Up = "keyup",
|
||||
.Key_Down = "keydown",
|
||||
.Key_Press = "keypress",
|
||||
|
||||
.Scroll = "scroll",
|
||||
.Wheel = "wheel",
|
||||
|
||||
.Focus = "focus",
|
||||
.Focus_In = "focusin",
|
||||
.Focus_Out = "focusout",
|
||||
.Submit = "submit",
|
||||
.Blur = "blur",
|
||||
.Change = "change",
|
||||
.Hash_Change = "hashchange",
|
||||
.Select = "select",
|
||||
|
||||
.Animation_Start = "animationstart",
|
||||
.Animation_End = "animationend",
|
||||
.Animation_Iteration = "animationiteration",
|
||||
.Animation_Cancel = "animationcancel",
|
||||
|
||||
.Copy = "copy",
|
||||
.Cut = "cut",
|
||||
.Paste = "paste",
|
||||
|
||||
// .Drag, = "drag",
|
||||
// .Drag_Start, = "dragstart",
|
||||
// .Drag_End, = "dragend",
|
||||
// .Drag_Enter, = "dragenter",
|
||||
// .Drag_Leave, = "dragleave",
|
||||
// .Drag_Over, = "dragover",
|
||||
// .Drop, = "drop",
|
||||
|
||||
.Pointer_Cancel = "pointercancel",
|
||||
.Pointer_Down = "pointerdown",
|
||||
.Pointer_Enter = "pointerenter",
|
||||
.Pointer_Leave = "pointerleave",
|
||||
.Pointer_Move = "pointermove",
|
||||
.Pointer_Over = "pointerover",
|
||||
.Pointer_Up = "pointerup",
|
||||
.Got_Pointer_Capture = "gotpointercapture",
|
||||
.Lost_Pointer_Capture = "lostpointercapture",
|
||||
.Pointer_Lock_Change = "pointerlockchange",
|
||||
.Pointer_Lock_Error = "pointerlockerror",
|
||||
|
||||
.Selection_Change = "selectionchange",
|
||||
.Selection_Start = "selectionstart",
|
||||
|
||||
.Transition_Start = "transitionstart",
|
||||
.Transition_End = "transitionend",
|
||||
.Transition_Run = "transitionrun",
|
||||
.Transition_Cancel = "transitioncancel",
|
||||
|
||||
.Touch_Cancel = "touchcancel",
|
||||
.Touch_End = "touchend",
|
||||
.Touch_Move = "touchmove",
|
||||
.Touch_Start = "touchstart",
|
||||
|
||||
.Context_Menu = "contextmenu",
|
||||
|
||||
.Gamepad_Connected = "gamepadconnected",
|
||||
.Gamepad_Disconnected = "gamepaddisconnected",
|
||||
|
||||
.Custom = "?custom?",
|
||||
}
|
||||
|
||||
Delta_Mode :: enum u32 {
|
||||
Pixel = 0,
|
||||
Line = 1,
|
||||
Page = 2,
|
||||
}
|
||||
|
||||
Key_Location :: enum u8 {
|
||||
Standard = 0,
|
||||
Left = 1,
|
||||
Right = 2,
|
||||
Numpad = 3,
|
||||
}
|
||||
|
||||
KEYBOARD_MAX_KEY_SIZE :: 16
|
||||
KEYBOARD_MAX_CODE_SIZE :: 16
|
||||
|
||||
GAMEPAD_MAX_ID_SIZE :: 64
|
||||
GAMEPAD_MAX_MAPPING_SIZE :: 64
|
||||
|
||||
GAMEPAD_MAX_BUTTONS :: 64
|
||||
GAMEPAD_MAX_AXES :: 16
|
||||
|
||||
Event_Target_Kind :: enum u32 {
|
||||
Element = 0,
|
||||
Document = 1,
|
||||
Window = 2,
|
||||
}
|
||||
|
||||
Event_Phase :: enum u8 {
|
||||
None = 0,
|
||||
Capturing_Phase = 1,
|
||||
At_Target = 2,
|
||||
Bubbling_Phase = 3,
|
||||
}
|
||||
|
||||
Event_Option :: enum u8 {
|
||||
Bubbles = 0,
|
||||
Cancelable = 1,
|
||||
Composed = 2,
|
||||
}
|
||||
Event_Options :: distinct bit_set[Event_Option; u8]
|
||||
|
||||
Gamepad_Button :: struct {
|
||||
value: f64,
|
||||
pressed: bool,
|
||||
touched: bool,
|
||||
}
|
||||
|
||||
Gamepad_State :: struct {
|
||||
id: string,
|
||||
mapping: string,
|
||||
index: int,
|
||||
connected: bool,
|
||||
timestamp: f64,
|
||||
|
||||
button_count: int,
|
||||
axis_count: int,
|
||||
buttons: [GAMEPAD_MAX_BUTTONS]Gamepad_Button `fmt:"v,button_count"`,
|
||||
axes: [GAMEPAD_MAX_AXES]f64 `fmt:"v,axes_count"`,
|
||||
|
||||
_id_len: int `fmt:"-"`,
|
||||
_mapping_len: int `fmt:"-"`,
|
||||
_id_buf: [GAMEPAD_MAX_ID_SIZE]byte `fmt:"-"`,
|
||||
_mapping_buf: [GAMEPAD_MAX_MAPPING_SIZE]byte `fmt:"-"`,
|
||||
}
|
||||
|
||||
Event :: struct {
|
||||
kind: Event_Kind,
|
||||
target_kind: Event_Target_Kind,
|
||||
current_target_kind: Event_Target_Kind,
|
||||
id: string,
|
||||
timestamp: f64,
|
||||
|
||||
phase: Event_Phase,
|
||||
options: Event_Options,
|
||||
is_composing: bool,
|
||||
is_trusted: bool,
|
||||
|
||||
using data: struct #raw_union #align(8) {
|
||||
scroll: struct {
|
||||
delta: [2]f64,
|
||||
},
|
||||
visibility_change: struct {
|
||||
is_visible: bool,
|
||||
},
|
||||
wheel: struct {
|
||||
delta: [3]f64,
|
||||
delta_mode: Delta_Mode,
|
||||
},
|
||||
|
||||
key: struct {
|
||||
key: string,
|
||||
code: string,
|
||||
location: Key_Location,
|
||||
|
||||
ctrl: bool,
|
||||
shift: bool,
|
||||
alt: bool,
|
||||
meta: bool,
|
||||
|
||||
repeat: bool,
|
||||
|
||||
_key_len: int `fmt:"-"`,
|
||||
_code_len: int `fmt:"-"`,
|
||||
_key_buf: [KEYBOARD_MAX_KEY_SIZE]byte `fmt:"-"`,
|
||||
_code_buf: [KEYBOARD_MAX_KEY_SIZE]byte `fmt:"-"`,
|
||||
},
|
||||
|
||||
mouse: struct {
|
||||
screen: [2]i64,
|
||||
client: [2]i64,
|
||||
offset: [2]i64,
|
||||
page: [2]i64,
|
||||
movement: [2]i64,
|
||||
|
||||
ctrl: bool,
|
||||
shift: bool,
|
||||
alt: bool,
|
||||
meta: bool,
|
||||
|
||||
button: i16,
|
||||
buttons: bit_set[0..<16; u16],
|
||||
},
|
||||
|
||||
gamepad: Gamepad_State,
|
||||
},
|
||||
|
||||
|
||||
user_data: rawptr,
|
||||
callback: proc(e: Event),
|
||||
}
|
||||
|
||||
@(default_calling_convention="contextless")
|
||||
foreign dom_lib {
|
||||
event_stop_propagation :: proc() ---
|
||||
event_stop_immediate_propagation :: proc() ---
|
||||
event_prevent_default :: proc() ---
|
||||
dispatch_custom_event :: proc(id: string, name: string, options := Event_Options{}) -> bool ---
|
||||
}
|
||||
|
||||
add_event_listener :: proc(id: string, kind: Event_Kind, user_data: rawptr, callback: proc(e: Event), use_capture := false) -> bool {
|
||||
@(default_calling_convention="contextless")
|
||||
foreign dom_lib {
|
||||
@(link_name="add_event_listener")
|
||||
_add_event_listener :: proc(id: string, name: string, name_code: Event_Kind, user_data: rawptr, callback: proc "odin" (Event), use_capture: bool) -> bool ---
|
||||
}
|
||||
// TODO: Pointer_Lock_Change etc related stuff for all different browsers
|
||||
return _add_event_listener(id, event_kind_string[kind], kind, user_data, callback, use_capture)
|
||||
}
|
||||
|
||||
remove_event_listener :: proc(id: string, kind: Event_Kind, user_data: rawptr, callback: proc(e: Event)) -> bool {
|
||||
@(default_calling_convention="contextless")
|
||||
foreign dom_lib {
|
||||
@(link_name="remove_event_listener")
|
||||
_remove_event_listener :: proc(id: string, name: string, user_data: rawptr, callback: proc "odin" (Event)) -> bool ---
|
||||
}
|
||||
return _remove_event_listener(id, event_kind_string[kind], user_data, callback)
|
||||
}
|
||||
|
||||
add_window_event_listener :: proc(kind: Event_Kind, user_data: rawptr, callback: proc(e: Event), use_capture := false) -> bool {
|
||||
@(default_calling_convention="contextless")
|
||||
foreign dom_lib {
|
||||
@(link_name="add_window_event_listener")
|
||||
_add_window_event_listener :: proc(name: string, name_code: Event_Kind, user_data: rawptr, callback: proc "odin" (Event), use_capture: bool) -> bool ---
|
||||
}
|
||||
return _add_window_event_listener(event_kind_string[kind], kind, user_data, callback, use_capture)
|
||||
}
|
||||
|
||||
remove_window_event_listener :: proc(kind: Event_Kind, user_data: rawptr, callback: proc(e: Event)) -> bool {
|
||||
@(default_calling_convention="contextless")
|
||||
foreign dom_lib {
|
||||
@(link_name="remove_window_event_listener")
|
||||
_remove_window_event_listener :: proc(name: string, user_data: rawptr, callback: proc "odin" (Event)) -> bool ---
|
||||
}
|
||||
return _remove_window_event_listener(event_kind_string[kind], user_data, callback)
|
||||
}
|
||||
|
||||
remove_event_listener_from_event :: proc(e: Event) -> bool {
|
||||
if e.id == "" {
|
||||
return remove_window_event_listener(e.kind, e.user_data, e.callback)
|
||||
}
|
||||
return remove_event_listener(e.id, e.kind, e.user_data, e.callback)
|
||||
}
|
||||
|
||||
add_custom_event_listener :: proc(id: string, name: string, user_data: rawptr, callback: proc(e: Event), use_capture := false) -> bool {
|
||||
@(default_calling_convention="contextless")
|
||||
foreign dom_lib {
|
||||
@(link_name="add_event_listener")
|
||||
_add_event_listener :: proc(id: string, name: string, name_code: Event_Kind, user_data: rawptr, callback: proc "odin" (Event), use_capture: bool) -> bool ---
|
||||
}
|
||||
return _add_event_listener(id, name, .Custom, user_data, callback, use_capture)
|
||||
}
|
||||
remove_custom_event_listener :: proc(id: string, name: string, user_data: rawptr, callback: proc(e: Event)) -> bool {
|
||||
@(default_calling_convention="contextless")
|
||||
foreign dom_lib {
|
||||
@(link_name="remove_event_listener")
|
||||
_remove_event_listener :: proc(id: string, name: string, user_data: rawptr, callback: proc "odin" (Event)) -> bool ---
|
||||
}
|
||||
return _remove_event_listener(id, name, user_data, callback)
|
||||
}
|
||||
|
||||
get_gamepad_state :: proc "contextless" (index: int, s: ^Gamepad_State) -> bool {
|
||||
@(default_calling_convention="contextless")
|
||||
foreign dom_lib {
|
||||
@(link_name="get_gamepad_state")
|
||||
_get_gamepad_state :: proc(index: int, s: ^Gamepad_State) -> bool ---
|
||||
}
|
||||
|
||||
if s == nil {
|
||||
return false
|
||||
}
|
||||
return _get_gamepad_state(index, s)
|
||||
}
|
||||
|
||||
|
||||
@(export, link_name="odin_dom_do_event_callback")
|
||||
do_event_callback :: proc(user_data: rawptr, callback: proc(e: Event)) {
|
||||
@(default_calling_convention="contextless")
|
||||
foreign dom_lib {
|
||||
init_event_raw :: proc(e: ^Event) ---
|
||||
}
|
||||
|
||||
if callback != nil {
|
||||
event := Event{
|
||||
user_data = user_data,
|
||||
callback = callback,
|
||||
}
|
||||
|
||||
|
||||
init_event_raw(&event)
|
||||
|
||||
#partial switch event.kind {
|
||||
case .Key_Up, .Key_Down, .Key_Press:
|
||||
event.key.key = string(event.key._key_buf[:event.key._key_len])
|
||||
event.key.code = string(event.key._code_buf[:event.key._code_len])
|
||||
case .Gamepad_Connected, .Gamepad_Disconnected:
|
||||
event.gamepad.id = string(event.gamepad._id_buf[:event.gamepad._id_len])
|
||||
event.gamepad.mapping = string(event.gamepad._mapping_buf[:event.gamepad._mapping_len])
|
||||
}
|
||||
|
||||
callback(event)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,287 @@
|
||||
#+build !js
|
||||
package wasm_js_interface
|
||||
|
||||
|
||||
Event_Kind :: enum u32 {
|
||||
Invalid,
|
||||
|
||||
Load,
|
||||
Unload,
|
||||
Error,
|
||||
Resize,
|
||||
Visibility_Change,
|
||||
Fullscreen_Change,
|
||||
Fullscreen_Error,
|
||||
|
||||
Click,
|
||||
Double_Click,
|
||||
Mouse_Move,
|
||||
Mouse_Over,
|
||||
Mouse_Out,
|
||||
Mouse_Up,
|
||||
Mouse_Down,
|
||||
|
||||
Key_Up,
|
||||
Key_Down,
|
||||
Key_Press,
|
||||
|
||||
Scroll,
|
||||
Wheel,
|
||||
|
||||
Focus,
|
||||
Submit,
|
||||
Blur,
|
||||
Change,
|
||||
Select,
|
||||
|
||||
Animation_Start,
|
||||
Animation_End,
|
||||
Animation_Iteration,
|
||||
Animation_Cancel,
|
||||
|
||||
Copy,
|
||||
Cut,
|
||||
Paste,
|
||||
|
||||
// Drag,
|
||||
// Drag_Start,
|
||||
// Drag_End,
|
||||
// Drag_Enter,
|
||||
// Drag_Leave,
|
||||
// Drag_Over,
|
||||
// Drop,
|
||||
|
||||
Pointer_Cancel,
|
||||
Pointer_Down,
|
||||
Pointer_Enter,
|
||||
Pointer_Leave,
|
||||
Pointer_Move,
|
||||
Pointer_Over,
|
||||
Pointer_Up,
|
||||
Got_Pointer_Capture,
|
||||
Lost_Pointer_Capture,
|
||||
Pointer_Lock_Change,
|
||||
Pointer_Lock_Error,
|
||||
|
||||
Selection_Change,
|
||||
Selection_Start,
|
||||
|
||||
Touch_Cancel,
|
||||
Touch_End,
|
||||
Touch_Move,
|
||||
Touch_Start,
|
||||
|
||||
Transition_Start,
|
||||
Transition_End,
|
||||
Transition_Run,
|
||||
Transition_Cancel,
|
||||
|
||||
Context_Menu,
|
||||
|
||||
Custom,
|
||||
|
||||
}
|
||||
event_kind_string := [Event_Kind]string{
|
||||
.Invalid = "",
|
||||
|
||||
.Load = "load",
|
||||
.Unload = "unload",
|
||||
.Error = "error",
|
||||
.Resize = "resize",
|
||||
.Visibility_Change = "visibilitychange",
|
||||
.Fullscreen_Change = "fullscreenchange",
|
||||
.Fullscreen_Error = "fullscreenerror",
|
||||
|
||||
.Click = "click",
|
||||
.Double_Click = "dblclick",
|
||||
.Mouse_Move = "mousemove",
|
||||
.Mouse_Over = "mouseover",
|
||||
.Mouse_Out = "mouseout",
|
||||
.Mouse_Up = "mouseup",
|
||||
.Mouse_Down = "mousedown",
|
||||
|
||||
.Key_Up = "keyup",
|
||||
.Key_Down = "keydown",
|
||||
.Key_Press = "keypress",
|
||||
|
||||
.Scroll = "scroll",
|
||||
.Wheel = "wheel",
|
||||
|
||||
.Focus = "focus",
|
||||
.Submit = "submit",
|
||||
.Blur = "blur",
|
||||
.Change = "change",
|
||||
.Select = "select",
|
||||
|
||||
.Animation_Start = "animationstart",
|
||||
.Animation_End = "animationend",
|
||||
.Animation_Iteration = "animationiteration",
|
||||
.Animation_Cancel = "animationcancel",
|
||||
|
||||
.Copy = "copy",
|
||||
.Cut = "cut",
|
||||
.Paste = "paste",
|
||||
|
||||
// .Drag, = "drag",
|
||||
// .Drag_Start, = "dragstart",
|
||||
// .Drag_End, = "dragend",
|
||||
// .Drag_Enter, = "dragenter",
|
||||
// .Drag_Leave, = "dragleave",
|
||||
// .Drag_Over, = "dragover",
|
||||
// .Drop, = "drop",
|
||||
|
||||
.Pointer_Cancel = "pointercancel",
|
||||
.Pointer_Down = "pointerdown",
|
||||
.Pointer_Enter = "pointerenter",
|
||||
.Pointer_Leave = "pointerleave",
|
||||
.Pointer_Move = "pointermove",
|
||||
.Pointer_Over = "pointerover",
|
||||
.Pointer_Up = "pointerup",
|
||||
.Got_Pointer_Capture = "gotpointercapture",
|
||||
.Lost_Pointer_Capture = "lostpointercapture",
|
||||
.Pointer_Lock_Change = "pointerlockchange",
|
||||
.Pointer_Lock_Error = "pointerlockerror",
|
||||
|
||||
.Selection_Change = "selectionchange",
|
||||
.Selection_Start = "selectionstart",
|
||||
|
||||
.Transition_Start = "transitionstart",
|
||||
.Transition_End = "transitionend",
|
||||
.Transition_Run = "transitionrun",
|
||||
.Transition_Cancel = "transitioncancel",
|
||||
|
||||
.Touch_Cancel = "touchcancel",
|
||||
.Touch_End = "touchend",
|
||||
.Touch_Move = "touchmove",
|
||||
.Touch_Start = "touchstart",
|
||||
|
||||
.Context_Menu = "contextmenu",
|
||||
|
||||
.Custom = "?custom?",
|
||||
}
|
||||
|
||||
Delta_Mode :: enum u32 {
|
||||
Pixel = 0,
|
||||
Line = 1,
|
||||
Page = 2,
|
||||
}
|
||||
|
||||
Key_Location :: enum u8 {
|
||||
Standard = 0,
|
||||
Left = 1,
|
||||
Right = 2,
|
||||
Numpad = 3,
|
||||
}
|
||||
|
||||
KEYBOARD_MAX_KEY_SIZE :: 16
|
||||
KEYBOARD_MAX_CODE_SIZE :: 16
|
||||
|
||||
Event_Target_Kind :: enum u32 {
|
||||
Element = 0,
|
||||
Document = 1,
|
||||
Window = 2,
|
||||
}
|
||||
|
||||
Event_Phase :: enum u8 {
|
||||
None = 0,
|
||||
Capturing_Phase = 1,
|
||||
At_Target = 2,
|
||||
Bubbling_Phase = 3,
|
||||
}
|
||||
|
||||
Event_Option :: enum u8 {
|
||||
Bubbles = 0,
|
||||
Cancelable = 1,
|
||||
Composed = 2,
|
||||
}
|
||||
Event_Options :: distinct bit_set[Event_Option; u8]
|
||||
|
||||
Event :: struct {
|
||||
kind: Event_Kind,
|
||||
target_kind: Event_Target_Kind,
|
||||
current_target_kind: Event_Target_Kind,
|
||||
id: string,
|
||||
timestamp: f64,
|
||||
|
||||
phase: Event_Phase,
|
||||
options: Event_Options,
|
||||
is_composing: bool,
|
||||
is_trusted: bool,
|
||||
|
||||
using data: struct #raw_union #align(8) {
|
||||
scroll: struct {
|
||||
delta: [2]f64,
|
||||
},
|
||||
visibility_change: struct {
|
||||
is_visible: bool,
|
||||
},
|
||||
wheel: struct {
|
||||
delta: [3]f64,
|
||||
delta_mode: Delta_Mode,
|
||||
},
|
||||
|
||||
key: struct {
|
||||
key: string,
|
||||
code: string,
|
||||
location: Key_Location,
|
||||
|
||||
ctrl: bool,
|
||||
shift: bool,
|
||||
alt: bool,
|
||||
meta: bool,
|
||||
|
||||
repeat: bool,
|
||||
|
||||
_key_buf: [KEYBOARD_MAX_KEY_SIZE]byte,
|
||||
_code_buf: [KEYBOARD_MAX_KEY_SIZE]byte,
|
||||
},
|
||||
|
||||
mouse: struct {
|
||||
screen: [2]i64,
|
||||
client: [2]i64,
|
||||
offset: [2]i64,
|
||||
page: [2]i64,
|
||||
movement: [2]i64,
|
||||
|
||||
ctrl: bool,
|
||||
shift: bool,
|
||||
alt: bool,
|
||||
meta: bool,
|
||||
|
||||
button: i16,
|
||||
buttons: bit_set[0..<16; u16],
|
||||
},
|
||||
},
|
||||
|
||||
|
||||
user_data: rawptr,
|
||||
callback: proc(e: Event),
|
||||
}
|
||||
|
||||
|
||||
add_event_listener :: proc(id: string, kind: Event_Kind, user_data: rawptr, callback: proc(e: Event), use_capture := false) -> bool {
|
||||
panic("vendor:wasm/js not supported on non JS targets")
|
||||
}
|
||||
|
||||
remove_event_listener :: proc(id: string, kind: Event_Kind, user_data: rawptr, callback: proc(e: Event)) -> bool {
|
||||
panic("vendor:wasm/js not supported on non JS targets")
|
||||
}
|
||||
|
||||
add_window_event_listener :: proc(kind: Event_Kind, user_data: rawptr, callback: proc(e: Event), use_capture := false) -> bool {
|
||||
panic("vendor:wasm/js not supported on non JS targets")
|
||||
}
|
||||
|
||||
remove_window_event_listener :: proc(kind: Event_Kind, user_data: rawptr, callback: proc(e: Event)) -> bool {
|
||||
panic("vendor:wasm/js not supported on non JS targets")
|
||||
}
|
||||
|
||||
remove_event_listener_from_event :: proc(e: Event) -> bool {
|
||||
panic("vendor:wasm/js not supported on non JS targets")
|
||||
}
|
||||
|
||||
add_custom_event_listener :: proc(id: string, name: string, user_data: rawptr, callback: proc(e: Event), use_capture := false) -> bool {
|
||||
panic("vendor:wasm/js not supported on non JS targets")
|
||||
}
|
||||
remove_custom_event_listener :: proc(id: string, name: string, user_data: rawptr, callback: proc(e: Event)) -> bool {
|
||||
panic("vendor:wasm/js not supported on non JS targets")
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
#+build js wasm32, js wasm64p32
|
||||
package wasm_js_interface
|
||||
|
||||
foreign import "odin_env"
|
||||
|
||||
@(default_calling_convention="contextless")
|
||||
foreign odin_env {
|
||||
trap :: proc() -> ! ---
|
||||
abort :: proc() -> ! ---
|
||||
alert :: proc(msg: string) ---
|
||||
evaluate :: proc(str: string) ---
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
#+build !js
|
||||
package wasm_js_interface
|
||||
|
||||
import "core:mem"
|
||||
|
||||
PAGE_SIZE :: 64 * 1024
|
||||
page_alloc :: proc(page_count: int) -> (data: []byte, err: mem.Allocator_Error) {
|
||||
panic("vendor:wasm/js not supported on non-js targets")
|
||||
}
|
||||
|
||||
page_allocator :: proc() -> mem.Allocator {
|
||||
panic("vendor:wasm/js not supported on non-js targets")
|
||||
}
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
#+build js wasm32, js wasm64p32
|
||||
package wasm_js_interface
|
||||
|
||||
import "core:mem"
|
||||
import "base:intrinsics"
|
||||
|
||||
PAGE_SIZE :: 64 * 1024
|
||||
page_alloc :: proc(page_count: int) -> (data: []byte, err: mem.Allocator_Error) {
|
||||
prev_page_count := intrinsics.wasm_memory_grow(0, uintptr(page_count))
|
||||
if prev_page_count < 0 {
|
||||
return nil, .Out_Of_Memory
|
||||
}
|
||||
|
||||
ptr := ([^]u8)(uintptr(prev_page_count) * PAGE_SIZE)
|
||||
return ptr[:page_count * PAGE_SIZE], nil
|
||||
}
|
||||
|
||||
page_allocator :: proc() -> mem.Allocator {
|
||||
procedure :: proc(allocator_data: rawptr, mode: mem.Allocator_Mode,
|
||||
size, alignment: int,
|
||||
old_memory: rawptr, old_size: int,
|
||||
location := #caller_location) -> ([]byte, mem.Allocator_Error) {
|
||||
switch mode {
|
||||
case .Alloc, .Alloc_Non_Zeroed:
|
||||
assert(size % PAGE_SIZE == 0)
|
||||
return page_alloc(size/PAGE_SIZE)
|
||||
case .Resize, .Free, .Free_All, .Query_Info, .Resize_Non_Zeroed:
|
||||
return nil, .Mode_Not_Implemented
|
||||
case .Query_Features:
|
||||
set := (^mem.Allocator_Mode_Set)(old_memory)
|
||||
if set != nil {
|
||||
set^ = {.Alloc, .Query_Features}
|
||||
}
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return {
|
||||
procedure = procedure,
|
||||
data = nil,
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,4 @@
|
||||
//+build wasm32
|
||||
#+build wasm32
|
||||
package sys_wasi
|
||||
|
||||
foreign import wasi "wasi_snapshot_preview1"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// +build windows
|
||||
#+build windows
|
||||
package sys_windows
|
||||
|
||||
foreign import advapi32 "system:Advapi32.lib"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// +build windows
|
||||
#+build windows
|
||||
package sys_windows
|
||||
|
||||
foreign import bcrypt "system:Bcrypt.lib"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// +build windows
|
||||
#+build windows
|
||||
package sys_windows
|
||||
|
||||
foreign import "system:bthprops.lib"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// +build windows
|
||||
#+build windows
|
||||
package sys_windows
|
||||
|
||||
// https://learn.microsoft.com/en-us/windows/win32/intl/code-page-identifiers
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// +build windows
|
||||
#+build windows
|
||||
package sys_windows
|
||||
|
||||
foreign import "system:Comctl32.lib"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// +build windows
|
||||
#+build windows
|
||||
package sys_windows
|
||||
|
||||
foreign import "system:Comdlg32.lib"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// +build windows
|
||||
#+build windows
|
||||
package sys_windows
|
||||
|
||||
foreign import "system:Dbghelp.lib"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// +build windows
|
||||
#+build windows
|
||||
package sys_windows
|
||||
|
||||
foreign import "system:Dnsapi.lib"
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
// +build windows
|
||||
#+build windows
|
||||
package sys_windows
|
||||
|
||||
foreign import dwmapi "system:Dwmapi.lib"
|
||||
|
||||
DWMWINDOWATTRIBUTE :: enum {
|
||||
DWMWA_NCRENDERING_ENABLED,
|
||||
DWMWA_NCRENDERING_ENABLED = 1,
|
||||
DWMWA_NCRENDERING_POLICY,
|
||||
DWMWA_TRANSITIONS_FORCEDISABLED,
|
||||
DWMWA_ALLOW_NCPAINT,
|
||||
@@ -28,7 +28,7 @@ DWMWINDOWATTRIBUTE :: enum {
|
||||
DWMWA_TEXT_COLOR,
|
||||
DWMWA_VISIBLE_FRAME_BORDER_THICKNESS,
|
||||
DWMWA_SYSTEMBACKDROP_TYPE,
|
||||
DWMWA_LAST,
|
||||
DWMWA_LAST,
|
||||
}
|
||||
|
||||
DWMNCRENDERINGPOLICY :: enum {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// +build windows
|
||||
#+build windows
|
||||
package sys_windows
|
||||
|
||||
import "core:math/fixed"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// +build windows
|
||||
#+build windows
|
||||
package sys_windows
|
||||
import "core:c"
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// +build windows
|
||||
#+build windows
|
||||
package sys_windows
|
||||
|
||||
USAGE :: distinct USHORT
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// +build windows
|
||||
#+build windows
|
||||
package sys_windows
|
||||
|
||||
foreign import "system:iphlpapi.lib"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// +build windows
|
||||
#+build windows
|
||||
package sys_windows
|
||||
|
||||
foreign import kernel32 "system:Kernel32.lib"
|
||||
@@ -400,6 +400,9 @@ foreign kernel32 {
|
||||
GlobalAlloc :: proc(flags: UINT, bytes: SIZE_T) -> LPVOID ---
|
||||
GlobalReAlloc :: proc(mem: LPVOID, bytes: SIZE_T, flags: UINT) -> LPVOID ---
|
||||
GlobalFree :: proc(mem: LPVOID) -> LPVOID ---
|
||||
|
||||
GlobalLock :: proc(hMem: HGLOBAL) -> LPVOID ---
|
||||
GlobalUnlock :: proc(hMem: HGLOBAL) -> BOOL ---
|
||||
|
||||
ReadDirectoryChangesW :: proc(
|
||||
hDirectory: HANDLE,
|
||||
@@ -1175,17 +1178,17 @@ SYSTEM_POWER_STATUS :: struct {
|
||||
}
|
||||
|
||||
AC_Line_Status :: enum BYTE {
|
||||
Offline = 0,
|
||||
Online = 1,
|
||||
Unknown = 255,
|
||||
Offline = 0,
|
||||
Online = 1,
|
||||
Unknown = 255,
|
||||
}
|
||||
|
||||
Battery_Flag :: enum BYTE {
|
||||
High = 0,
|
||||
Low = 1,
|
||||
Critical = 2,
|
||||
Charging = 3,
|
||||
No_Battery = 7,
|
||||
High = 0,
|
||||
Low = 1,
|
||||
Critical = 2,
|
||||
Charging = 3,
|
||||
No_Battery = 7,
|
||||
}
|
||||
Battery_Flags :: bit_set[Battery_Flag; BYTE]
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// +build windows
|
||||
#+build windows
|
||||
package sys_windows
|
||||
|
||||
// https://docs.microsoft.com/en-us/windows/win32/inputdev/about-keyboard-input
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// +build windows
|
||||
#+build windows
|
||||
package sys_windows
|
||||
|
||||
FOLDERID_NetworkFolder :: GUID {0xD20BEEC4, 0x5CA8, 0x4905, {0xAE, 0x3B, 0xBF, 0x25, 0x1E, 0xA0, 0x9B, 0x53}}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// +build windows
|
||||
#+build windows
|
||||
package sys_windows
|
||||
|
||||
foreign import netapi32 "system:Netapi32.lib"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// +build windows
|
||||
#+build windows
|
||||
package sys_windows
|
||||
|
||||
foreign import ntdll_lib "system:ntdll.lib"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// +build windows
|
||||
#+build windows
|
||||
|
||||
package sys_windows
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// +build windows
|
||||
#+build windows
|
||||
package sys_windows
|
||||
|
||||
foreign import shell32 "system:Shell32.lib"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// +build windows
|
||||
#+build windows
|
||||
package sys_windows
|
||||
|
||||
foreign import shlwapi "system:shlwapi.lib"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// +build windows
|
||||
#+build windows
|
||||
package sys_windows
|
||||
|
||||
foreign import Synchronization "system:Synchronization.lib"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// +build windows
|
||||
#+build windows
|
||||
package sys_windows
|
||||
|
||||
// Parameter for SystemParametersInfo.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//+build windows
|
||||
#+build windows
|
||||
package sys_windows
|
||||
|
||||
foreign import kernel32 "system:Kernel32.lib"
|
||||
|
||||
+26
-26
@@ -3546,11 +3546,11 @@ SIGDN :: enum c_int {
|
||||
}
|
||||
|
||||
SIATTRIBFLAGS :: enum c_int {
|
||||
AND = 0x1,
|
||||
OR = 0x2,
|
||||
APPCOMPAT = 0x3,
|
||||
MASK = 0x3,
|
||||
ALLITEMS = 0x4000,
|
||||
AND = 0x1,
|
||||
OR = 0x2,
|
||||
APPCOMPAT = 0x3,
|
||||
MASK = 0x3,
|
||||
ALLITEMS = 0x4000,
|
||||
}
|
||||
|
||||
FDAP :: enum c_int {
|
||||
@@ -4503,35 +4503,35 @@ DNS_INFO_NO_RECORDS :: 9501
|
||||
DNS_QUERY_NO_RECURSION :: 0x00000004
|
||||
|
||||
DNS_RECORD :: struct { // aka DNS_RECORDA
|
||||
pNext: ^DNS_RECORD,
|
||||
pName: cstring,
|
||||
wType: WORD,
|
||||
wDataLength: USHORT,
|
||||
Flags: DWORD,
|
||||
dwTtl: DWORD,
|
||||
_: DWORD,
|
||||
Data: struct #raw_union {
|
||||
CNAME: DNS_PTR_DATAA,
|
||||
A: u32be, // Ipv4 Address
|
||||
AAAA: u128be, // Ipv6 Address
|
||||
TXT: DNS_TXT_DATAA,
|
||||
NS: DNS_PTR_DATAA,
|
||||
MX: DNS_MX_DATAA,
|
||||
SRV: DNS_SRV_DATAA,
|
||||
},
|
||||
pNext: ^DNS_RECORD,
|
||||
pName: cstring,
|
||||
wType: WORD,
|
||||
wDataLength: USHORT,
|
||||
Flags: DWORD,
|
||||
dwTtl: DWORD,
|
||||
_: DWORD,
|
||||
Data: struct #raw_union {
|
||||
CNAME: DNS_PTR_DATAA,
|
||||
A: u32be, // Ipv4 Address
|
||||
AAAA: u128be, // Ipv6 Address
|
||||
TXT: DNS_TXT_DATAA,
|
||||
NS: DNS_PTR_DATAA,
|
||||
MX: DNS_MX_DATAA,
|
||||
SRV: DNS_SRV_DATAA,
|
||||
},
|
||||
}
|
||||
|
||||
DNS_TXT_DATAA :: struct {
|
||||
dwStringCount: DWORD,
|
||||
pStringArray: cstring,
|
||||
dwStringCount: DWORD,
|
||||
pStringArray: cstring,
|
||||
}
|
||||
|
||||
DNS_PTR_DATAA :: cstring
|
||||
|
||||
DNS_MX_DATAA :: struct {
|
||||
pNameExchange: cstring, // the hostname
|
||||
wPreference: WORD, // lower values preferred
|
||||
_: WORD, // padding.
|
||||
pNameExchange: cstring, // the hostname
|
||||
wPreference: WORD, // lower values preferred
|
||||
_: WORD, // padding.
|
||||
}
|
||||
DNS_SRV_DATAA :: struct {
|
||||
pNameTarget: cstring,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// +build windows
|
||||
#+build windows
|
||||
package sys_windows
|
||||
|
||||
import "base:intrinsics"
|
||||
@@ -66,7 +66,7 @@ foreign user32 {
|
||||
RemovePropW :: proc(hWnd: HWND, lpString: LPCWSTR) -> HANDLE ---
|
||||
EnumPropsW :: proc(hWnd: HWND, lpEnumFunc: PROPENUMPROCW) -> INT ---
|
||||
EnumPropsExW :: proc(hWnd: HWND, lpEnumFunc: PROPENUMPROCW, lParam: LPARAM) -> INT ---
|
||||
GetMessageW :: proc(lpMsg: ^MSG, hWnd: HWND, wMsgFilterMin: UINT, wMsgFilterMax: UINT) -> BOOL ---
|
||||
GetMessageW :: proc(lpMsg: ^MSG, hWnd: HWND, wMsgFilterMin: UINT, wMsgFilterMax: UINT) -> INT ---
|
||||
|
||||
TranslateMessage :: proc(lpMsg: ^MSG) -> BOOL ---
|
||||
DispatchMessageW :: proc(lpMsg: ^MSG) -> LRESULT ---
|
||||
@@ -142,7 +142,7 @@ foreign user32 {
|
||||
AppendMenuW :: proc(hMenu: HMENU, uFlags: UINT, uIDNewItem: UINT_PTR, lpNewItem: LPCWSTR) -> BOOL ---
|
||||
GetMenu :: proc(hWnd: HWND) -> HMENU ---
|
||||
SetMenu :: proc(hWnd: HWND, hMenu: HMENU) -> BOOL ---
|
||||
TrackPopupMenu :: proc(hMenu: HMENU, uFlags: UINT, x, y: INT, nReserved: INT, hWnd: HWND, prcRect: ^RECT) -> BOOL ---
|
||||
TrackPopupMenu :: proc(hMenu: HMENU, uFlags: UINT, x, y: INT, nReserved: INT, hWnd: HWND, prcRect: ^RECT) -> INT ---
|
||||
RegisterWindowMessageW :: proc(lpString: LPCWSTR) -> UINT ---
|
||||
|
||||
CreateAcceleratorTableW :: proc(paccel: LPACCEL, cAccel: INT) -> HACCEL ---
|
||||
@@ -305,6 +305,13 @@ foreign user32 {
|
||||
|
||||
GetProcessWindowStation :: proc() -> HWINSTA ---
|
||||
GetUserObjectInformationW :: proc(hObj: HANDLE, nIndex: GetUserObjectInformationFlags, pvInfo: PVOID, nLength: DWORD, lpnLengthNeeded: LPDWORD) -> BOOL ---
|
||||
|
||||
OpenClipboard :: proc(hWndNewOwner: HWND) -> BOOL ---
|
||||
CloseClipboard :: proc() -> BOOL ---
|
||||
GetClipboardData :: proc(uFormat: UINT) -> HANDLE ---
|
||||
SetClipboardData :: proc(uFormat: UINT, hMem: HANDLE) -> HANDLE ---
|
||||
IsClipboardFormatAvailable :: proc(format: UINT) -> BOOL ---
|
||||
EmptyClipboard :: proc() -> BOOL ---
|
||||
}
|
||||
|
||||
CreateWindowW :: #force_inline proc "system" (
|
||||
@@ -746,3 +753,31 @@ WinEventFlag :: enum DWORD {
|
||||
SKIPOWNPROCESS = 1,
|
||||
INCONTEXT = 2,
|
||||
}
|
||||
|
||||
// Standard Clipboard Formats
|
||||
CF_TEXT :: 1
|
||||
CF_BITMAP :: 2
|
||||
CF_METAFILEPICT :: 3
|
||||
CF_SYLK :: 4
|
||||
CF_DIF :: 5
|
||||
CF_TIFF :: 6
|
||||
CF_OEMTEXT :: 7
|
||||
CF_DIB :: 8
|
||||
CF_PALETTE :: 9
|
||||
CF_PENDATA :: 10
|
||||
CF_RIFF :: 11
|
||||
CF_WAVE :: 12
|
||||
CF_UNICODETEXT :: 13
|
||||
CF_ENHMETAFILE :: 14
|
||||
CF_HDROP :: 15
|
||||
CF_LOCALE :: 16
|
||||
CF_DIBV5 :: 17
|
||||
CF_DSPBITMAP :: 0x0082
|
||||
CF_DSPENHMETAFILE :: 0x008E
|
||||
CF_DSPMETAFILEPICT :: 0x0083
|
||||
CF_DSPTEXT :: 0x0081
|
||||
CF_GDIOBJFIRST :: 0x0300
|
||||
CF_GDIOBJLAST :: 0x03FF
|
||||
CF_OWNERDISPLAY :: 0x0080
|
||||
CF_PRIVATEFIRST :: 0x0200
|
||||
CF_PRIVATELAST :: 0x02FF
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// +build windows
|
||||
#+build windows
|
||||
package sys_windows
|
||||
|
||||
foreign import userenv "system:Userenv.lib"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// +build windows
|
||||
#+build windows
|
||||
package sys_windows
|
||||
|
||||
import "base:runtime"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// +build windows
|
||||
#+build windows
|
||||
package sys_windows
|
||||
|
||||
foreign import uxtheme "system:UxTheme.lib"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// +build windows
|
||||
#+build windows
|
||||
package sys_windows
|
||||
|
||||
import "core:c"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// +build windows
|
||||
#+build windows
|
||||
package sys_windows
|
||||
|
||||
// WGL_ARB_buffer_region
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// +build windows
|
||||
#+build windows
|
||||
package sys_windows
|
||||
|
||||
WM_NULL :: 0x0000
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// +build windows
|
||||
#+build windows
|
||||
package sys_windows
|
||||
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/winerror/
|
||||
@@ -213,6 +213,7 @@ ERROR_BROKEN_PIPE : DWORD : 109
|
||||
ERROR_CALL_NOT_IMPLEMENTED : DWORD : 120
|
||||
ERROR_INSUFFICIENT_BUFFER : DWORD : 122
|
||||
ERROR_INVALID_NAME : DWORD : 123
|
||||
ERROR_NEGATIVE_SEEK : DWORD : 131
|
||||
ERROR_BAD_ARGUMENTS : DWORD : 160
|
||||
ERROR_LOCK_FAILED : DWORD : 167
|
||||
ERROR_ALREADY_EXISTS : DWORD : 183
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// +build windows
|
||||
#+build windows
|
||||
package sys_windows
|
||||
|
||||
foreign import winmm "system:Winmm.lib"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// +build windows
|
||||
#+build windows
|
||||
package sys_windows
|
||||
|
||||
LCTYPE :: distinct DWORD
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// +build windows
|
||||
#+build windows
|
||||
package sys_windows
|
||||
|
||||
foreign import version "system:version.lib"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//+build windows
|
||||
#+build windows
|
||||
package sys_windows
|
||||
|
||||
foreign import kernel32 "system:Kernel32.lib"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// +build windows
|
||||
#+build windows
|
||||
package sys_windows
|
||||
|
||||
// Define flags to be used with the WSAAsyncSelect() call.
|
||||
|
||||
Reference in New Issue
Block a user