From 110c324373ceeceff5fb59467964e1e3b3b0185a Mon Sep 17 00:00:00 2001
From: castro-fidel <tergoevm@gmail.com>
Date: Wed, 28 Oct 2020 21:29:06 +0300
Subject: [PATCH] Update port_on file for wine-proton-5.13

---
 data_from_portwine/port_on | 145 ++++++++++++++++++++++++++++++++-----
 1 file changed, 126 insertions(+), 19 deletions(-)

diff --git a/data_from_portwine/port_on b/data_from_portwine/port_on
index 3b9e6f96..2f6ff89d 100755
--- a/data_from_portwine/port_on
+++ b/data_from_portwine/port_on
@@ -32,10 +32,6 @@ def log(msg):
     sys.stderr.write(PFX + msg + os.linesep)
     sys.stderr.flush()
 
-def log(msg):
-    sys.stderr.write(PFX + msg + os.linesep)
-    sys.stderr.flush()
-
 def file_is_wine_builtin_dll(path):
     if os.path.islink(path):
         contents = os.readlink(path)
@@ -120,7 +116,7 @@ def set_dir_casefold_bit(dir_path):
         if fcntl.ioctl(dr, EXT2_IOC_GETFLAGS, dat, True) >= 0:
             dat[0] = dat[0] | EXT4_CASEFOLD_FL
             fcntl.ioctl(dr, EXT2_IOC_SETFLAGS, dat, False)
-    except OSError:
+    except (OSError, IOError):
         #no problem
         pass
     os.close(dr)
@@ -144,10 +140,14 @@ class Proton:
     def path(self, d):
         return self.base_dir + d
 
+    def missing_default_prefix(self):
+        '''Check if the default prefix dir is missing. Returns true if missing, false if present'''
+        return not os.path.isdir(self.default_pfx_dir)
+
     def make_default_prefix(self):
         with self.dist_lock:
             local_env = dict(g_session.env)
-            if not os.path.isdir(self.default_pfx_dir):
+            if self.missing_default_prefix():
                 #make default prefix
                 local_env["WINEPREFIX"] = self.default_pfx_dir
                 local_env["WINEDEBUG"] = "-all"
@@ -160,7 +160,6 @@ class CompatData:
         self.prefix_dir = self.path("pfx/")
         self.version_file = self.path("version")
         self.tracked_files_file = self.path("tracked_files")
-#        if "PW_FILELOCK" in os.environ and nonzero(os.environ["PW_FILELOCK"]):
         self.prefix_lock = FileLock(self.path("pfx.lock"), timeout=-1)
 
     def path(self, d):
@@ -190,6 +189,82 @@ class CompatData:
         os.remove(self.tracked_files_file)
         os.remove(self.version_file)
 
+    def upgrade_pfx(self, old_ver):
+        if old_ver == CURRENT_PREFIX_VERSION:
+            return
+
+        log("Upgrading prefix from " + str(old_ver) + " to " + CURRENT_PREFIX_VERSION + " (" + self.base_dir + ")")
+
+        if old_ver is None:
+            return
+
+        if not '-' in old_ver:
+            #How can this happen??
+            log("Prefix has an invalid version?! You may want to back up user files and delete this prefix.")
+            #If it does, just let the Wine upgrade happen and hope it works...
+            return
+
+        try:
+            old_proton_ver, old_prefix_ver = old_ver.split('-')
+            old_proton_maj, old_proton_min = old_proton_ver.split('.')
+            new_proton_ver, new_prefix_ver = CURRENT_PREFIX_VERSION.split('-')
+            new_proton_maj, new_proton_min = new_proton_ver.split('.')
+
+            if int(new_proton_maj) < int(old_proton_maj) or \
+                    (int(new_proton_maj) == int(old_proton_maj) and \
+                     int(new_proton_min) < int(old_proton_min)):
+                log("Removing newer prefix")
+                if old_proton_ver == "3.7" and not os.path.exists(self.tracked_files_file):
+                    #proton 3.7 did not generate tracked_files, so copy it into place first
+                    try_copy(g_proton.path("proton_3.7_tracked_files"), self.tracked_files_file)
+                self.remove_tracked_files()
+                return
+
+            if old_proton_ver == "3.7" and old_prefix_ver == "1":
+                if not os.path.exists(self.prefix_dir + "/drive_c/windows/syswow64/kernel32.dll"):
+                    #shipped a busted 64-bit-only installation on 20180822. detect and wipe clean
+                    log("Detected broken 64-bit-only installation, re-creating prefix.")
+                    shutil.rmtree(self.prefix_dir)
+                    return
+
+            #replace broken .NET installations with wine-mono support
+            if os.path.exists(self.prefix_dir + "/drive_c/windows/Microsoft.NET/NETFXRepair.exe") and \
+                    file_is_wine_builtin_dll(self.prefix_dir + "/drive_c/windows/system32/mscoree.dll"):
+                log("Broken .NET installation detected, switching to wine-mono.")
+                #deleting this directory allows wine-mono to work
+                shutil.rmtree(self.prefix_dir + "/drive_c/windows/Microsoft.NET")
+
+            #prior to prefix version 4.11-2, all controllers were xbox controllers. wipe out the old registry entries.
+            if (int(old_proton_maj) < 4 or (int(old_proton_maj) == 4 and int(old_proton_min) == 11)) and \
+                    int(old_prefix_ver) < 2:
+                log("Removing old xinput registry entries.")
+                with open(self.prefix_dir + "system.reg", "r") as reg_in:
+                    with open(self.prefix_dir + "system.reg.new", "w") as reg_out:
+                        for line in reg_in:
+                            if line[0] == '[' and "CurrentControlSet" in line and "IG_" in line:
+                                if "DeviceClasses" in line:
+                                    reg_out.write(line.replace("DeviceClasses", "DeviceClasses_old"))
+                                elif "Enum" in line:
+                                    reg_out.write(line.replace("Enum", "Enum_old"))
+                            else:
+                                reg_out.write(line)
+                try:
+                    os.rename(self.prefix_dir + "system.reg", self.prefix_dir + "system.reg.old")
+                except OSError:
+                    os.remove(self.prefix_dir + "system.reg")
+                    pass
+
+                try:
+                    os.rename(self.prefix_dir + "system.reg.new", self.prefix_dir + "system.reg")
+                except OSError:
+                    log("Unable to write new registry file to " + self.prefix_dir + "system.reg")
+                    pass
+
+        except ValueError:
+            log("Prefix has an invalid version?! You may want to back up user files and delete this prefix.")
+            #Just let the Wine upgrade happen and hope it works...
+            return
+
     def pfx_copy(self, src, dst, dll_copy=False):
         if os.path.islink(src):
             contents = os.readlink(src)
@@ -283,6 +358,14 @@ class CompatData:
 
     def setup_prefix(self):
         with self.prefix_lock:
+            if os.path.exists(self.version_file):
+                with open(self.version_file, "r") as f:
+                    old_ver = f.readline().strip()
+            else:
+                old_ver = None
+
+            self.upgrade_pfx(old_ver)
+
             if not os.path.exists(self.prefix_dir):
                 makedirs(self.prefix_dir + "/drive_c")
                 set_dir_casefold_bit(self.prefix_dir + "/drive_c")
@@ -290,6 +373,9 @@ class CompatData:
             if not os.path.exists(self.prefix_dir + "/user.reg"):
                 self.copy_pfx()
 
+            use_wined3d = "wined3d" in g_session.compat_config
+            use_dxvk_dxgi = "WINEDLLOVERRIDES" in g_session.env and "dxgi=n" in g_session.env["WINEDLLOVERRIDES"]
+            
             builtin_dll_copy = os.environ.get("PROTON_DLL_COPY",
                     #dxsetup redist
                     "d3dcompiler_*.dll," +
@@ -318,13 +404,25 @@ class CompatData:
                     "vulkan-1.dll"
                     )
 
+            # update builtin dll symlinks or copies
+            self.update_builtin_libs(builtin_dll_copy)
+
             with open(self.version_file, "w") as f:
                 f.write(CURRENT_PREFIX_VERSION + "\n")
 
             #create font files symlinks
             self.create_fonts_symlinks()
 
-            if "wined3d" in g_session.compat_config:
+            #copy openvr files into place
+            dst = self.prefix_dir + "/drive_c/vrclient/bin/"
+            makedirs(dst)
+            try_copy(g_proton.lib_dir + "wine/fakedlls/vrclient.dll", dst)
+            try_copy(g_proton.lib64_dir + "wine/fakedlls/vrclient_x64.dll", dst)
+
+            try_copy(g_proton.lib_dir + "wine/dxvk/openvr_api_dxvk.dll", self.prefix_dir + "/drive_c/windows/syswow64/")
+            try_copy(g_proton.lib64_dir + "wine/dxvk/openvr_api_dxvk.dll", self.prefix_dir + "/drive_c/windows/system32/")
+
+            if use_wined3d:
                 dxvkfiles = ["dxvk_config"]
                 wined3dfiles = ["d3d11", "d3d10", "d3d10core", "d3d10_1", "d3d9"]
             else:
@@ -332,7 +430,7 @@ class CompatData:
                 wined3dfiles = []
 
             #if the user asked for dxvk's dxgi (dxgi=n), then copy it into place
-            if "PW_DXGI_NATIVE" in os.environ and "1" in os.environ["PW_DXGI_NATIVE"]:
+            if use_dxvk_dxgi:
                 dxvkfiles.append("dxgi")
             else:
                 wined3dfiles.append("dxgi")
@@ -349,11 +447,11 @@ class CompatData:
                 try_copy(g_proton.lib_dir + "wine/dxvk/" + f + ".dll",
                         self.prefix_dir + "drive_c/windows/syswow64/" + f + ".dll")
                 g_session.dlloverrides[f] = "n"
-            
+
             try_copy(g_proton.lib64_dir + "wine/vkd3d-proton/d3d12.dll",
-                self.prefix_dir + "drive_c/windows/system32/d3d12.dll")
+                    self.prefix_dir + "drive_c/windows/system32/d3d12.dll")
             try_copy(g_proton.lib_dir + "wine/vkd3d-proton/d3d12.dll",
-                self.prefix_dir + "drive_c/windows/syswow64/d3d12.dll")
+                    self.prefix_dir + "drive_c/windows/syswow64/d3d12.dll")
 
 def comma_escaped(s):
     escaped = False
@@ -408,6 +506,10 @@ class Session:
 
         self.env.pop("WINEARCH", "")
 
+        if 'ORIG_'+ld_path_var not in os.environ:
+            # Allow wine to restore this when calling an external app.
+            self.env['ORIG_'+ld_path_var] = os.environ.get(ld_path_var, '')
+
         if ld_path_var in os.environ:
             self.env[ld_path_var] = g_proton.lib64_dir + ":" + g_proton.lib_dir + ":" + os.environ[ld_path_var]
         else:
@@ -477,14 +579,18 @@ class Session:
         self.check_environment("PW_WINEDBG_DISABLE", "nowinedbg")
         self.check_environment("PW_PULSE_LOWLATENCY", "pulselowlat")
 
-        if not "noesync" in self.compat_config:
-            self.env["WINEESYNC"] = "1" 
+        if "noesync" in self.compat_config:
+            self.env.pop("WINEESYNC", "")
+        else:
+            self.env["WINEESYNC"] = "1"
 
-        if not "nofsync" in self.compat_config:
+        if "nofsync" in self.compat_config:
+            self.env.pop("WINEFSYNC", "")
+        else:
             self.env["WINEFSYNC"] = "1"
 
-        if "seccomp" in self.compat_config:
-            self.env["WINESECCOMP"] = "1"
+        if "nowritewatch" in self.compat_config:
+            self.env["WINE_DISABLE_WRITE_WATCH"] = "1"
 
         if "oldglstr" in self.compat_config:
             #mesa override
@@ -500,7 +606,7 @@ class Session:
 
         if "pulselowlat" in self.compat_config:
             self.env["PULSE_LATENCY_MSEC"] = "60"
-            
+
         g_compatdata.setup_prefix()
 
         if "nod3d12" in self.compat_config:
@@ -575,7 +681,8 @@ if __name__ == "__main__":
 
     g_session.init_wine()
 
-    g_proton.make_default_prefix()
+    if g_proton.missing_default_prefix():
+        g_proton.make_default_prefix()
 
     g_session.init_session()