aboutsummaryrefslogtreecommitdiff
path: root/src/Ryujinx.UI.Common/Helper/ObjectiveC.cs
blob: 6aba377a349f9dce06a8a7fc14eb02416811a7cf (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
using System;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;

namespace Ryujinx.UI.Common.Helper
{
    [SupportedOSPlatform("macos")]
    public static partial class ObjectiveC
    {
        private const string ObjCRuntime = "/usr/lib/libobjc.A.dylib";

        [LibraryImport(ObjCRuntime, StringMarshalling = StringMarshalling.Utf8)]
        private static partial IntPtr sel_getUid(string name);

        [LibraryImport(ObjCRuntime, StringMarshalling = StringMarshalling.Utf8)]
        private static partial IntPtr objc_getClass(string name);

        [LibraryImport(ObjCRuntime)]
        private static partial void objc_msgSend(IntPtr receiver, Selector selector);

        [LibraryImport(ObjCRuntime)]
        private static partial void objc_msgSend(IntPtr receiver, Selector selector, byte value);

        [LibraryImport(ObjCRuntime)]
        private static partial void objc_msgSend(IntPtr receiver, Selector selector, IntPtr value);

        [LibraryImport(ObjCRuntime)]
        private static partial void objc_msgSend(IntPtr receiver, Selector selector, NSRect point);

        [LibraryImport(ObjCRuntime)]
        private static partial void objc_msgSend(IntPtr receiver, Selector selector, double value);

        [LibraryImport(ObjCRuntime, EntryPoint = "objc_msgSend")]
        private static partial IntPtr IntPtr_objc_msgSend(IntPtr receiver, Selector selector);

        [LibraryImport(ObjCRuntime, EntryPoint = "objc_msgSend")]
        private static partial IntPtr IntPtr_objc_msgSend(IntPtr receiver, Selector selector, IntPtr param);

        [LibraryImport(ObjCRuntime, EntryPoint = "objc_msgSend", StringMarshalling = StringMarshalling.Utf8)]
        private static partial IntPtr IntPtr_objc_msgSend(IntPtr receiver, Selector selector, string param);

        [LibraryImport(ObjCRuntime, EntryPoint = "objc_msgSend")]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static partial bool bool_objc_msgSend(IntPtr receiver, Selector selector, IntPtr param);

        public readonly struct Object
        {
            public readonly IntPtr ObjPtr;

            private Object(IntPtr pointer)
            {
                ObjPtr = pointer;
            }

            public Object(string name)
            {
                ObjPtr = objc_getClass(name);
            }

            public void SendMessage(Selector selector)
            {
                objc_msgSend(ObjPtr, selector);
            }

            public void SendMessage(Selector selector, byte value)
            {
                objc_msgSend(ObjPtr, selector, value);
            }

            public void SendMessage(Selector selector, Object obj)
            {
                objc_msgSend(ObjPtr, selector, obj.ObjPtr);
            }

            public void SendMessage(Selector selector, NSRect point)
            {
                objc_msgSend(ObjPtr, selector, point);
            }

            public void SendMessage(Selector selector, double value)
            {
                objc_msgSend(ObjPtr, selector, value);
            }

            public Object GetFromMessage(Selector selector)
            {
                return new Object(IntPtr_objc_msgSend(ObjPtr, selector));
            }

            public Object GetFromMessage(Selector selector, Object obj)
            {
                return new Object(IntPtr_objc_msgSend(ObjPtr, selector, obj.ObjPtr));
            }

            public Object GetFromMessage(Selector selector, NSString nsString)
            {
                return new Object(IntPtr_objc_msgSend(ObjPtr, selector, nsString.StrPtr));
            }

            public Object GetFromMessage(Selector selector, string param)
            {
                return new Object(IntPtr_objc_msgSend(ObjPtr, selector, param));
            }

            public bool GetBoolFromMessage(Selector selector, Object obj)
            {
                return bool_objc_msgSend(ObjPtr, selector, obj.ObjPtr);
            }
        }

        public readonly struct Selector
        {
            public readonly IntPtr SelPtr;

            private Selector(string name)
            {
                SelPtr = sel_getUid(name);
            }

            public static implicit operator Selector(string value) => new(value);
        }

        public readonly struct NSString
        {
            public readonly IntPtr StrPtr;

            public NSString(string aString)
            {
                IntPtr nsString = objc_getClass("NSString");
                StrPtr = IntPtr_objc_msgSend(nsString, "stringWithUTF8String:", aString);
            }

            public static implicit operator IntPtr(NSString nsString) => nsString.StrPtr;
        }

        public readonly struct NSPoint
        {
            public readonly double X;
            public readonly double Y;

            public NSPoint(double x, double y)
            {
                X = x;
                Y = y;
            }
        }

        public readonly struct NSRect
        {
            public readonly NSPoint Pos;
            public readonly NSPoint Size;

            public NSRect(double x, double y, double width, double height)
            {
                Pos = new NSPoint(x, y);
                Size = new NSPoint(width, height);
            }
        }
    }
}