mirror of
https://github.com/ZuneDev/MicrosoftIris.git
synced 2026-07-27 13:13:29 -07:00
Prepare for UIXrender and UIXsup stage 1 & 2
This commit is contained in:
+23
-3
@@ -23,10 +23,30 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<Choose>
|
<Choose>
|
||||||
<When Condition=" $(TargetFramework.StartsWith('net6.0-windows')) ">
|
<When Condition=" $([MSBuild]::GetTargetPlatformIdentifier($(TargetFramework))) == 'windows' ">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<DefineConstants Condition="$(TargetFramework.StartsWith('net6.0-windows10'))">$(DefineConstants);WINDOWS10</DefineConstants>
|
<DefineConstants>$(DefineConstants);WINDOWS</DefineConstants>
|
||||||
<DefineConstants Condition="$(TargetFramework.StartsWith('net6.0-windows8'))">$(DefineConstants);WINDOWS8</DefineConstants>
|
<TargetWindowsVersion>$([MSBuild]::GetTargetPlatformVersion($(TargetFramework)))</TargetWindowsVersion>
|
||||||
|
|
||||||
|
<DefineConstants Condition="$([MSBuild]::VersionGreaterThanOrEquals($(TargetWindowsVersion), '7.0'))">
|
||||||
|
$(DefineConstants);WINDOWS7
|
||||||
|
</DefineConstants>
|
||||||
|
<DefineConstants Condition="$([MSBuild]::VersionGreaterThanOrEquals($(TargetWindowsVersion), '8.0'))">
|
||||||
|
$(DefineConstants);WINDOWS8
|
||||||
|
</DefineConstants>
|
||||||
|
<DefineConstants Condition="$([MSBuild]::VersionGreaterThanOrEquals($(TargetWindowsVersion), '10.0'))">
|
||||||
|
$(DefineConstants);WINDOWS10
|
||||||
|
</DefineConstants>
|
||||||
|
</PropertyGroup>
|
||||||
|
</When>
|
||||||
|
|
||||||
|
<When Condition=" $(TargetFramework.StartsWith('net4')) ">
|
||||||
|
<PropertyGroup>
|
||||||
|
<DefineConstants>$(DefineConstants);WINDOWS</DefineConstants>
|
||||||
|
|
||||||
|
<DefineConstants Condition=" !$(TargetFramework.StartsWith('net40')) ">
|
||||||
|
$(DefineConstants);NETSTANDARD1_0_OR_GREATER;NETSTANDARD2_0_OR_GREATER
|
||||||
|
</DefineConstants>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
</When>
|
</When>
|
||||||
</Choose>
|
</Choose>
|
||||||
|
|||||||
@@ -18,6 +18,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
|
|||||||
Directory.Build.props = Directory.Build.props
|
Directory.Build.props = Directory.Build.props
|
||||||
EndProjectSection
|
EndProjectSection
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UIXrender", "UIXrender\UIXrender.csproj", "{1EFC7739-215B-45DA-852B-3B02C79749BE}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UIXsup", "UIXsup\UIXsup.csproj", "{9428B81F-24D7-4EB4-B5EC-9780321A8D90}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
@@ -76,6 +80,30 @@ Global
|
|||||||
{96FB9772-5619-47AD-93FC-F26319EC6BB1}.Release|x64.Build.0 = Release|Any CPU
|
{96FB9772-5619-47AD-93FC-F26319EC6BB1}.Release|x64.Build.0 = Release|Any CPU
|
||||||
{96FB9772-5619-47AD-93FC-F26319EC6BB1}.Release|x86.ActiveCfg = Release|Any CPU
|
{96FB9772-5619-47AD-93FC-F26319EC6BB1}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
{96FB9772-5619-47AD-93FC-F26319EC6BB1}.Release|x86.Build.0 = Release|Any CPU
|
{96FB9772-5619-47AD-93FC-F26319EC6BB1}.Release|x86.Build.0 = Release|Any CPU
|
||||||
|
{1EFC7739-215B-45DA-852B-3B02C79749BE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{1EFC7739-215B-45DA-852B-3B02C79749BE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{1EFC7739-215B-45DA-852B-3B02C79749BE}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{1EFC7739-215B-45DA-852B-3B02C79749BE}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{1EFC7739-215B-45DA-852B-3B02C79749BE}.Debug|x86.ActiveCfg = Debug|x86
|
||||||
|
{1EFC7739-215B-45DA-852B-3B02C79749BE}.Debug|x86.Build.0 = Debug|x86
|
||||||
|
{1EFC7739-215B-45DA-852B-3B02C79749BE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{1EFC7739-215B-45DA-852B-3B02C79749BE}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{1EFC7739-215B-45DA-852B-3B02C79749BE}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{1EFC7739-215B-45DA-852B-3B02C79749BE}.Release|x64.Build.0 = Release|x64
|
||||||
|
{1EFC7739-215B-45DA-852B-3B02C79749BE}.Release|x86.ActiveCfg = Release|x86
|
||||||
|
{1EFC7739-215B-45DA-852B-3B02C79749BE}.Release|x86.Build.0 = Release|x86
|
||||||
|
{9428B81F-24D7-4EB4-B5EC-9780321A8D90}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{9428B81F-24D7-4EB4-B5EC-9780321A8D90}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{9428B81F-24D7-4EB4-B5EC-9780321A8D90}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{9428B81F-24D7-4EB4-B5EC-9780321A8D90}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{9428B81F-24D7-4EB4-B5EC-9780321A8D90}.Debug|x86.ActiveCfg = Debug|x86
|
||||||
|
{9428B81F-24D7-4EB4-B5EC-9780321A8D90}.Debug|x86.Build.0 = Debug|x86
|
||||||
|
{9428B81F-24D7-4EB4-B5EC-9780321A8D90}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{9428B81F-24D7-4EB4-B5EC-9780321A8D90}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{9428B81F-24D7-4EB4-B5EC-9780321A8D90}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{9428B81F-24D7-4EB4-B5EC-9780321A8D90}.Release|x64.Build.0 = Release|x64
|
||||||
|
{9428B81F-24D7-4EB4-B5EC-9780321A8D90}.Release|x86.ActiveCfg = Release|x86
|
||||||
|
{9428B81F-24D7-4EB4-B5EC-9780321A8D90}.Release|x86.Build.0 = Release|x86
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|||||||
@@ -0,0 +1,149 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Extracts a machine-readable schema of the Splash wire protocol from the
|
||||||
|
decompiled Microsoft.Iris.Render.Protocols.Splash.* proxy classes, so the
|
||||||
|
native UIXrender.dll message structs and msgid dispatch tables can be
|
||||||
|
generated instead of hand-transcribed.
|
||||||
|
|
||||||
|
Source of truth: UIX.RenderApi/Microsoft/Iris/Render/Protocols/Splash/**/*.cs
|
||||||
|
(decompiled from the original UIX.RenderApi.dll; not hand-written, so its
|
||||||
|
Msg*_Name structs and _priv_msgid values are exactly what shipped).
|
||||||
|
|
||||||
|
See logs/UIXrender/Architecture.md for the reasoning behind this approach.
|
||||||
|
"""
|
||||||
|
import json
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
ROOT = Path(__file__).resolve().parent.parent
|
||||||
|
SPLASH_DIR = ROOT / "UIX.RenderApi/Microsoft/Iris/Render/Protocols/Splash"
|
||||||
|
|
||||||
|
RE_NAMESPACE = re.compile(r"^namespace\s+([\w.]+)", re.MULTILINE)
|
||||||
|
RE_CLASS = re.compile(
|
||||||
|
r"^\s*(?:internal|public)\s+(?:sealed\s+)?class\s+(\w+)\s*(?::\s*([\w<>,.\s]+?))?\s*$",
|
||||||
|
re.MULTILINE,
|
||||||
|
)
|
||||||
|
RE_MSG_STRUCT = re.compile(
|
||||||
|
r"private struct (Msg(\d+)_(\w+))\s*\{(.*?)\}", re.DOTALL
|
||||||
|
)
|
||||||
|
RE_FIELD = re.compile(r"public\s+([\w.<>\[\]*]+)\s+(\w+);")
|
||||||
|
RE_INIT_REMOTE_CLASS = re.compile(r'InitRemoteClass\("([^"]+)"\)')
|
||||||
|
RE_BIND_ASSIGN = re.compile(
|
||||||
|
r"_priv_remoteClass_(\w+)\s*=\s*port\.InitRemoteClass\(\"([^\"]+)\"\)"
|
||||||
|
)
|
||||||
|
RE_MSGID_ASSIGN = re.compile(r"->_priv_msgid\s*=\s*(\d+)U;")
|
||||||
|
RE_INSTANCE_SCOPED = re.compile(r"this\.m_renderHandle")
|
||||||
|
|
||||||
|
FIXED_HEADER_FIELDS = {"_priv_size", "_priv_msgid", "_priv_idObjectSubject"}
|
||||||
|
|
||||||
|
|
||||||
|
def parse_file(path: Path):
|
||||||
|
text = path.read_text(encoding="utf-8-sig")
|
||||||
|
ns_match = RE_NAMESPACE.search(text)
|
||||||
|
namespace = ns_match.group(1) if ns_match else None
|
||||||
|
|
||||||
|
classes = []
|
||||||
|
for cls_match in RE_CLASS.finditer(text):
|
||||||
|
cls_name = cls_match.group(1)
|
||||||
|
base = cls_match.group(2)
|
||||||
|
base = base.strip() if base else None
|
||||||
|
|
||||||
|
# Slice out this class's body (up to the next top-level class or EOF)
|
||||||
|
start = cls_match.end()
|
||||||
|
next_match = RE_CLASS.search(text, start)
|
||||||
|
body = text[start : next_match.start() if next_match else len(text)]
|
||||||
|
|
||||||
|
messages = []
|
||||||
|
for msg_match in RE_MSG_STRUCT.finditer(body):
|
||||||
|
struct_name, msgid, msg_name, field_block = msg_match.groups()
|
||||||
|
fields = [
|
||||||
|
{"type": ftype, "name": fname}
|
||||||
|
for ftype, fname in RE_FIELD.findall(field_block)
|
||||||
|
if fname not in FIXED_HEADER_FIELDS
|
||||||
|
]
|
||||||
|
# Find the Build* method for this message to see whether it's
|
||||||
|
# instance-scoped (uses this.m_renderHandle as the subject) or
|
||||||
|
# class/static-scoped (uses a resolved *_ClassHandle field).
|
||||||
|
build_method_match = re.search(
|
||||||
|
r"Build" + re.escape(msg_name) + r"\s*\((.*?)\)\s*\{(.*?)\n \}",
|
||||||
|
body,
|
||||||
|
re.DOTALL,
|
||||||
|
)
|
||||||
|
instance_scoped = bool(
|
||||||
|
build_method_match
|
||||||
|
and RE_INSTANCE_SCOPED.search(build_method_match.group(2))
|
||||||
|
)
|
||||||
|
has_blob = any(f["type"] == "BLOBREF" for f in fields)
|
||||||
|
messages.append(
|
||||||
|
{
|
||||||
|
"msgid": int(msgid),
|
||||||
|
"name": msg_name,
|
||||||
|
"fields": fields,
|
||||||
|
"instanceScoped": instance_scoped,
|
||||||
|
"hasVariableLengthData": has_blob,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
messages.sort(key=lambda m: m["msgid"])
|
||||||
|
|
||||||
|
# Class-name -> wire-name bindings only appear in the owning
|
||||||
|
# ProtocolInstance's Init() (e.g. ProtocolSplashMessaging.Init()),
|
||||||
|
# not in the Remote* file itself, so this stays empty here and is
|
||||||
|
# cross-referenced in a second pass (see collect_wire_names).
|
||||||
|
if messages or cls_name.startswith(("Remote", "Local")):
|
||||||
|
classes.append(
|
||||||
|
{
|
||||||
|
"namespace": namespace,
|
||||||
|
"class": cls_name,
|
||||||
|
"baseClass": base,
|
||||||
|
"sourceFile": str(path.relative_to(ROOT)),
|
||||||
|
"messages": messages,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return classes
|
||||||
|
|
||||||
|
|
||||||
|
def collect_wire_names(all_text: str):
|
||||||
|
"""Map short binding name (e.g. 'Broker') -> wire class name string,
|
||||||
|
from every '_priv_remoteClass_X = port.InitRemoteClass("Wire::Name")'
|
||||||
|
assignment found across all ProtocolInstance-derived binder classes."""
|
||||||
|
return {m.group(1): m.group(2) for m in RE_BIND_ASSIGN.finditer(all_text)}
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
if not SPLASH_DIR.is_dir():
|
||||||
|
print(f"error: {SPLASH_DIR} not found", file=sys.stderr)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
all_classes = []
|
||||||
|
all_text_parts = []
|
||||||
|
cs_files = sorted(SPLASH_DIR.rglob("*.cs"))
|
||||||
|
for path in cs_files:
|
||||||
|
text = path.read_text(encoding="utf-8-sig")
|
||||||
|
all_text_parts.append(text)
|
||||||
|
all_classes.extend(parse_file(path))
|
||||||
|
|
||||||
|
wire_names = collect_wire_names("\n".join(all_text_parts))
|
||||||
|
|
||||||
|
total_messages = sum(len(c["messages"]) for c in all_classes)
|
||||||
|
classes_with_messages = [c for c in all_classes if c["messages"]]
|
||||||
|
|
||||||
|
schema = {
|
||||||
|
"generatedFrom": str(SPLASH_DIR.relative_to(ROOT)),
|
||||||
|
"sourceFileCount": len(cs_files),
|
||||||
|
"wireClassNameBindings": wire_names,
|
||||||
|
"classes": classes_with_messages,
|
||||||
|
}
|
||||||
|
|
||||||
|
out_path = ROOT / "Tools" / "splash-schema.json"
|
||||||
|
out_path.write_text(json.dumps(schema, indent=2), encoding="utf-8")
|
||||||
|
|
||||||
|
print(f"Parsed {len(cs_files)} source files")
|
||||||
|
print(f"Found {len(classes_with_messages)} classes with message structs")
|
||||||
|
print(f"Found {total_messages} total messages")
|
||||||
|
print(f"Resolved {len(wire_names)} wire class-name bindings")
|
||||||
|
print(f"Wrote {out_path.relative_to(ROOT)}")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Library</OutputType>
|
||||||
|
<AssemblyName>UIXrender</AssemblyName>
|
||||||
|
<RootNamespace>Microsoft.Iris.Render</RootNamespace>
|
||||||
|
<GenerateAssemblyInfo>true</GenerateAssemblyInfo>
|
||||||
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
|
</PropertyGroup>
|
||||||
|
</Project>
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Library</OutputType>
|
||||||
|
<AssemblyName>UIXsup</AssemblyName>
|
||||||
|
<RootNamespace>Microsoft.Iris.Support</RootNamespace>
|
||||||
|
<GenerateAssemblyInfo>true</GenerateAssemblyInfo>
|
||||||
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
|
</PropertyGroup>
|
||||||
|
</Project>
|
||||||
Reference in New Issue
Block a user