Merge branch 'master' into macharena

This commit is contained in:
Colin Davidson
2024-09-24 02:32:06 -07:00
597 changed files with 17453 additions and 6717 deletions
+145 -154
View File
@@ -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)
+2 -2
View File
@@ -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
+4 -1
View File
@@ -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)
+92 -13
View File
@@ -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 -1
View File
@@ -1,4 +1,4 @@
//+build darwin
#+build darwin
package darwin
import "core:c"
+11
View File
@@ -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 {
+3 -3
View File
@@ -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 {
+29 -29
View File
@@ -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,
}
/*--==========================================================================--*/
+108
View File
@@ -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.
+6 -6
View File
@@ -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 -1
View File
@@ -1,4 +1,4 @@
//+build haiku
#+build haiku
package sys_haiku
import "core:c"
+1 -1
View File
@@ -1,4 +1,4 @@
//+build haiku
#+build haiku
package sys_haiku
import "core:c"
+1 -1
View File
@@ -1,4 +1,4 @@
//+build haiku
#+build haiku
package sys_haiku
import "core:c"
+1 -1
View File
@@ -1,4 +1,4 @@
//+build haiku
#+build haiku
package sys_haiku
import "core:c"
+1 -1
View File
@@ -1,4 +1,4 @@
//+build arm32, arm64
#+build arm32, arm64
package sysinfo
import "core:sys/unix"
+1 -1
View File
@@ -1,4 +1,4 @@
//+build i386, amd64
#+build i386, amd64
package sysinfo
import "base:intrinsics"
+2 -2
View File
@@ -1,5 +1,5 @@
//+build arm32, arm64
//+build linux
#+build arm32, arm64
#+build linux
package sysinfo
import "core:sys/linux"
+91 -24
View File
@@ -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 }
}
}
}
}
+91 -7
View File
@@ -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]
+8 -1
View File
@@ -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 -1
View File
@@ -1,4 +1,4 @@
//+build openbsd, netbsd
#+build openbsd, netbsd
package sysinfo
import sys "core:sys/unix"
+4
View File
@@ -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 -1
View File
@@ -1,4 +1,4 @@
//+build darwin, netbsd, openbsd, freebsd
#+build darwin, netbsd, openbsd, freebsd
package kqueue
when ODIN_OS == .Darwin {
+84
View File
@@ -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,
}
+2 -2
View File
@@ -1,5 +1,5 @@
//+build linux
//+no-instrumentation
#+build linux
#+no-instrumentation
package linux
import "base:intrinsics"
+31 -15
View File
@@ -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 -1
View File
@@ -1,4 +1,4 @@
//+build amd64
#+build amd64
package linux
// AMD64 uses the new way to define syscalls, i.e. one that
+1 -1
View File
@@ -1,4 +1,4 @@
//+build arm32
#+build arm32
package linux
// This file was taken and transformed from
+1 -1
View File
@@ -1,4 +1,4 @@
//+build arm64
#+build arm64
package linux
// Syscalls for arm64 are defined using the new way, i.e. differently from
+1 -1
View File
@@ -1,4 +1,4 @@
//+build i386
#+build i386
package linux
// The numbers are taken from
+2 -1
View File
@@ -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)
+17
View File
@@ -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 -1
View File
@@ -1,4 +1,4 @@
//+build linux
#+build linux
package linux
/// Low 8 bits of the exit code
+1
View File
@@ -1,4 +1,5 @@
// Bit Manipulation Intrinsics
package sys_llvm
/*
+1
View File
@@ -1,4 +1,5 @@
// Code Generator Intrinsics
package sys_llvm
@(default_calling_convention="none")
+1
View File
@@ -1,4 +1,5 @@
// Standard C Library Intrinsics
package sys_llvm
@(default_calling_convention="none")
+1 -1
View File
@@ -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 ]]
*/
+1 -1
View File
@@ -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 -1
View File
@@ -1,4 +1,4 @@
//+build darwin
#+build darwin
package unix
import "core:c"
+1 -1
View File
@@ -1,4 +1,4 @@
//+build freebsd
#+build freebsd
package unix
import "core:c"
+1 -1
View File
@@ -1,4 +1,4 @@
//+build linux
#+build linux
package unix
import "core:c"
+1 -1
View File
@@ -1,4 +1,4 @@
//+build openbsd
#+build openbsd
package unix
import "core:c"
+3 -1
View File
@@ -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 -1
View File
@@ -1,4 +1,4 @@
//+build darwin
#+build darwin
package unix
import "base:intrinsics"
+1 -1
View File
@@ -1,4 +1,4 @@
//+build freebsd
#+build freebsd
package unix
import "base:intrinsics"
+1 -1
View File
@@ -1,4 +1,4 @@
//+build openbsd
#+build openbsd
package unix
import "core:c"
+1 -1
View File
@@ -1,4 +1,4 @@
//+build amd64
#+build amd64
package sys_valgrind
import "base:intrinsics"
+1 -1
View File
@@ -1,4 +1,4 @@
//+build amd64
#+build amd64
package sys_valgrind
import "base:intrinsics"
+1 -1
View File
@@ -1,4 +1,4 @@
//+build amd64
#+build amd64
package sys_valgrind
import "base:intrinsics"
+1 -1
View File
@@ -1,4 +1,4 @@
//+build amd64
#+build amd64
package sys_valgrind
import "base:intrinsics"
+15
View File
@@ -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>
```
+93
View File
@@ -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
}
+36
View File
@@ -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")
}
+418
View File
@@ -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)
}
}
+287
View File
@@ -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")
}
+12
View File
@@ -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) ---
}
+14
View File
@@ -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")
}
+44
View File
@@ -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 -1
View File
@@ -1,4 +1,4 @@
//+build wasm32
#+build wasm32
package sys_wasi
foreign import wasi "wasi_snapshot_preview1"
+1 -1
View File
@@ -1,4 +1,4 @@
// +build windows
#+build windows
package sys_windows
foreign import advapi32 "system:Advapi32.lib"
+1 -1
View File
@@ -1,4 +1,4 @@
// +build windows
#+build windows
package sys_windows
foreign import bcrypt "system:Bcrypt.lib"
+1 -1
View File
@@ -1,4 +1,4 @@
// +build windows
#+build windows
package sys_windows
foreign import "system:bthprops.lib"
+1 -1
View File
@@ -1,4 +1,4 @@
// +build windows
#+build windows
package sys_windows
// https://learn.microsoft.com/en-us/windows/win32/intl/code-page-identifiers
+1 -1
View File
@@ -1,4 +1,4 @@
// +build windows
#+build windows
package sys_windows
foreign import "system:Comctl32.lib"
+1 -1
View File
@@ -1,4 +1,4 @@
// +build windows
#+build windows
package sys_windows
foreign import "system:Comdlg32.lib"
+1 -1
View File
@@ -1,4 +1,4 @@
// +build windows
#+build windows
package sys_windows
foreign import "system:Dbghelp.lib"
+1 -1
View File
@@ -1,4 +1,4 @@
// +build windows
#+build windows
package sys_windows
foreign import "system:Dnsapi.lib"
+3 -3
View File
@@ -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 -1
View File
@@ -1,4 +1,4 @@
// +build windows
#+build windows
package sys_windows
import "core:math/fixed"
+1 -1
View File
@@ -1,4 +1,4 @@
// +build windows
#+build windows
package sys_windows
import "core:c"
+1 -1
View File
@@ -1,4 +1,4 @@
// +build windows
#+build windows
package sys_windows
USAGE :: distinct USHORT
+1 -1
View File
@@ -1,4 +1,4 @@
// +build windows
#+build windows
package sys_windows
foreign import "system:iphlpapi.lib"
+12 -9
View File
@@ -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 -1
View File
@@ -1,4 +1,4 @@
// +build windows
#+build windows
package sys_windows
// https://docs.microsoft.com/en-us/windows/win32/inputdev/about-keyboard-input
+1 -1
View File
@@ -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 -1
View File
@@ -1,4 +1,4 @@
// +build windows
#+build windows
package sys_windows
foreign import netapi32 "system:Netapi32.lib"
+1 -1
View File
@@ -1,4 +1,4 @@
// +build windows
#+build windows
package sys_windows
foreign import ntdll_lib "system:ntdll.lib"
+1 -1
View File
@@ -1,4 +1,4 @@
// +build windows
#+build windows
package sys_windows
+1 -1
View File
@@ -1,4 +1,4 @@
// +build windows
#+build windows
package sys_windows
foreign import shell32 "system:Shell32.lib"
+1 -1
View File
@@ -1,4 +1,4 @@
// +build windows
#+build windows
package sys_windows
foreign import shlwapi "system:shlwapi.lib"
+1 -1
View File
@@ -1,4 +1,4 @@
// +build windows
#+build windows
package sys_windows
foreign import Synchronization "system:Synchronization.lib"
+1 -1
View File
@@ -1,4 +1,4 @@
// +build windows
#+build windows
package sys_windows
// Parameter for SystemParametersInfo.
+1 -1
View File
@@ -1,4 +1,4 @@
//+build windows
#+build windows
package sys_windows
foreign import kernel32 "system:Kernel32.lib"
+26 -26
View File
@@ -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,
+38 -3
View File
@@ -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 -1
View File
@@ -1,4 +1,4 @@
// +build windows
#+build windows
package sys_windows
foreign import userenv "system:Userenv.lib"
+1 -1
View File
@@ -1,4 +1,4 @@
// +build windows
#+build windows
package sys_windows
import "base:runtime"
+1 -1
View File
@@ -1,4 +1,4 @@
// +build windows
#+build windows
package sys_windows
foreign import uxtheme "system:UxTheme.lib"
+1 -1
View File
@@ -1,4 +1,4 @@
// +build windows
#+build windows
package sys_windows
import "core:c"
+1 -1
View File
@@ -1,4 +1,4 @@
// +build windows
#+build windows
package sys_windows
// WGL_ARB_buffer_region
+1 -1
View File
@@ -1,4 +1,4 @@
// +build windows
#+build windows
package sys_windows
WM_NULL :: 0x0000
+2 -1
View File
@@ -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 -1
View File
@@ -1,4 +1,4 @@
// +build windows
#+build windows
package sys_windows
foreign import winmm "system:Winmm.lib"
+1 -1
View File
@@ -1,4 +1,4 @@
// +build windows
#+build windows
package sys_windows
LCTYPE :: distinct DWORD
+1 -1
View File
@@ -1,4 +1,4 @@
// +build windows
#+build windows
package sys_windows
foreign import version "system:version.lib"
+1 -1
View File
@@ -1,4 +1,4 @@
//+build windows
#+build windows
package sys_windows
foreign import kernel32 "system:Kernel32.lib"
+1 -1
View File
@@ -1,4 +1,4 @@
// +build windows
#+build windows
package sys_windows
// Define flags to be used with the WSAAsyncSelect() call.