Compare commits

...

32 Commits

Author SHA1 Message Date
Proton Merge Bot
dde78c6dc0 update submodules 2022-05-27 15:03:55 +00:00
Paul Gofman
7421ad04b8 fixup! lsteamclient: Execute SteamNetworkingSocketsDebugOutput callback from a Wine thread. 2022-05-25 14:38:16 -05:00
Proton Merge Bot
e25a701aba update submodules 2022-05-25 13:24:12 +00:00
Arkadiusz Hiler
083544dfa5 proton: Add Outward to MFDXGI hack.
CW-Bug-Id: #19126
2022-05-25 16:10:30 +03:00
Paul Gofman
be938daacd proton: Add V Rising to MFDXGI hack.
CW-Bug-Id: #19126
2022-05-25 16:10:19 +03:00
Paul Gofman
e3a485eef7 lsteamclient: Execute SteamNetworkingSocketsDebugOutput callback from a Wine thread.
CW-Bug-Id: #20684

The callback is called from a native Unix thread which is not initialized with Wine,
meaning it, e. g., has a leftover TEB from another thread. Only native Unix functions
may be called from such a thread.
2022-05-25 16:10:01 +03:00
Arkadiusz Hiler
8856c4de3f Add two more games to MFDXGI manager hack.
CW-Bug-Id: #19126
CW-Bug-Id: #20655
2022-05-25 16:09:59 +03:00
Arkadiusz Hiler
910cbd320c Add three more games to MFDXGI manager hack.
CW-Bug-Id: #19126
2022-05-25 16:09:20 +03:00
Anna Lasky
68d2cf5aa3 Add Ember Knights to IMFDXGIDeviceManager hack
CW-Bug-Id: #19126
2022-05-25 16:09:20 +03:00
Esme Povirk
819acd8503 Accept EINVAL result from copy_file_range.
Apparently, ecryptfs can give this result for regular files.

For #5769.
2022-05-25 16:09:20 +03:00
Esme Povirk
1c683ef8b1 Fix getting errno in copy_file_range_ctypes.
For #5769.
2022-05-25 16:09:20 +03:00
Esme Povirk
b605161f57 Update Wine Mono to 7.2.0. 2022-05-25 16:09:20 +03:00
Arkadiusz Hiler
33401e6571 update dxvk-nvapi to v0.5.4 2022-05-25 16:09:20 +03:00
Paul Gofman
72b0647e00 lsteamclient: HACK: Skip spurious overlay deactivation event.
CW-Bug-Id: #20169
2022-05-25 16:09:20 +03:00
Esme Povirk
8950a3051f proton: Make reflinks for file copies when possible. 2022-05-25 16:09:20 +03:00
Georg Lehmann
7dfcee6d38 Set VKD3D_SHADER_DEBUG=none by default.
Link: https://github.com/ValveSoftware/Proton/pull/5326
2022-05-25 16:09:20 +03:00
Andrew Eikum
5715495f62 Handle steampipe quirks in deploy builds 2022-05-25 16:09:20 +03:00
Andrew Eikum
d38ef96d81 Don't ship filenames with colons in them 2022-05-25 16:09:20 +03:00
Andrew Eikum
9ad0d1349b Don't ship proton dist files in a tarball anymore 2022-05-25 16:09:20 +03:00
Anna Lasky
71cf5a0767 Add El Hijo - A Wild West Tale to MFDXGI manager hack
CW-Bug-ID: #19126
2022-05-23 17:24:26 -05:00
Anna Lasky
124fbe2213 Add EZ2ON REBOOT : R to MFDXGI manager hack
CW-Bug-ID: #19126
2022-05-19 16:56:03 -05:00
Rémi Bernon
588b7dad67
lsteamclient: Turn overlay input filtering traces to FIXME. 2022-05-13 12:32:14 +02:00
Paul Gofman
dc84edec19 Add POSTAL4: No Regrets to MFDXGI manager hack.
CW-Bug-Id: #20611
2022-05-10 17:03:26 -05:00
Andrew Eikum
c970152c97 Add Disintegration to MFDXGI manager hack
CW-Bug-Id: #20592
2022-05-09 10:31:38 -05:00
Andrew Eikum
8edd5b697a Ship libgstvpx
For VP8 and VP9 support.

CW-Bug-Id: #20379
2022-04-25 11:24:41 -05:00
Andrew Eikum
873d276b93 Makefile: Fix SDK build 2022-04-25 10:36:53 -05:00
Andrew Eikum
cec88433ae docker: Use full URLs for base images
podman doesn't automatically use the docker.io registry.
2022-04-25 10:36:53 -05:00
Arkadiusz Hiler
918535cbfd configure.sh: Update default Proton SDK image to 0.20220329.0-0 2022-04-25 10:36:53 -05:00
Arkadiusz Hiler
4f35cbba13 docker: Bump steamrt version to 0.20220329.0. 2022-04-25 10:36:53 -05:00
Arkadiusz Hiler
952a238106 Makefile: Stop mentioning VMs. 2022-04-22 18:55:49 +03:00
Arkadiusz Hiler
b1225b9f24 Makefile: Get rid of install-internal target.
Since the migration off Vagrant we no longer need to copy Proton
installation from the VM to the host. This was replaced with a `make
install` invoked using the new build system which already puts things in
the right place. This render install-internal an unnecessary no-op.
2022-04-22 18:51:48 +03:00
Paul Gofman
9defdf97b8 Revert "lsteamclient: HACK Do not unset SteamAppId for 'Splitgate: Arena Warfare'."
This reverts commit 57dc9d706222ee68e502fcc53b2ff04427983a05.
2022-04-21 20:23:27 +03:00
15 changed files with 453 additions and 90 deletions

View File

@ -110,7 +110,7 @@ clean:
rm -rf $(BUILD_DIR)
protonsdk:
$(MAKE) $(MFLAGS) $(MAKEOVERRIDES) -C proton/docker $(UNSTRIPPED) PROTONSDK_VERSION=$(protonsdk_version) proton
$(MAKE) $(MFLAGS) $(MAKEOVERRIDES) -C docker $(UNSTRIPPED) PROTONSDK_VERSION=$(protonsdk_version) proton
configure: | $(BUILD_DIR)
if [ ! -e $(BUILD_DIR)/Makefile ]; then \
@ -126,15 +126,11 @@ downloads: configure
proton: downloads
$(MAKE) $(MFLAGS) $(MAKEOVERRIDES) -C $(BUILD_DIR)/ $(UNSTRIPPED) dist && \
echo "Proton built in VM. Use 'install' or 'deploy' targets to retrieve the build."
echo "Proton built locally. Use 'install', 'deploy' or 'redist' targets."
install-internal: | $(BUILD_ROOT)/compatibilitytools.d/$(_build_name)
install-internal: downloads
install: downloads
rm -rf $(STEAM_DIR)/compatibilitytools.d/$(_build_name)/files/ #remove proton's internal files, but preserve user_settings etc from top-level
$(MAKE) $(MFLAGS) $(MAKEOVERRIDES) -C $(BUILD_DIR)/ $(UNSTRIPPED) install
install: install-internal
mkdir -p $(STEAM_DIR)/compatibilitytools.d/
cp -Rf --no-dereference --preserve=mode,links $(BUILD_ROOT)/compatibilitytools.d/$(_build_name) $(STEAM_DIR)/compatibilitytools.d/
echo "Proton installed to your local Steam installation"
redist: | $(BUILD_ROOT)/$(DEPLOY_DIR)
@ -172,8 +168,8 @@ dxvk: | $(BUILD_ROOT)/dxvk/lib/wine/dxvk
dxvk: | $(BUILD_ROOT)/dxvk/lib64/wine/dxvk
dxvk: downloads
$(MAKE) $(MFLAGS) $(MAKEOVERRIDES) -C $(BUILD_DIR)/ $(UNSTRIPPED) dxvk && \
cp -f $(BUILD_DIR)/dist/dist/lib/wine/dxvk/*.dll $(BUILD_ROOT)/dxvk/lib/wine/dxvk/ && \
cp -f $(BUILD_DIR)/dist/dist/lib64/wine/dxvk/*.dll $(BUILD_ROOT)/dxvk/lib64/wine/dxvk/
cp -f $(BUILD_DIR)/dist/files/lib/wine/dxvk/*.dll $(BUILD_ROOT)/dxvk/lib/wine/dxvk/ && \
cp -f $(BUILD_DIR)/dist/files/lib64/wine/dxvk/*.dll $(BUILD_ROOT)/dxvk/lib64/wine/dxvk/
dxvk-nvapi: | $(BUILD_ROOT)/dxvk-nvapi/lib/wine/nvapi
dxvk-nvapi: | $(BUILD_ROOT)/dxvk-nvapi/lib64/wine/nvapi
@ -186,8 +182,8 @@ vkd3d-proton: | $(BUILD_ROOT)/vkd3d-proton/lib/wine/vkd3d-proton
vkd3d-proton: | $(BUILD_ROOT)/vkd3d-proton/lib64/wine/vkd3d-proton
vkd3d-proton: downloads
$(MAKE) $(MFLAGS) $(MAKEOVERRIDES) -C $(BUILD_DIR)/ $(UNSTRIPPED) vkd3d-proton && \
cp -f $(BUILD_DIR)/dist/dist/lib/wine/vkd3d-proton/*.dll $(BUILD_ROOT)/vkd3d-proton/lib/wine/vkd3d-proton/ && \
cp -f $(BUILD_DIR)/dist/dist/lib64/wine/vkd3d-proton/*.dll $(BUILD_ROOT)/vkd3d-proton/lib64/wine/vkd3d-proton/
cp -f $(BUILD_DIR)/dist/files/lib/wine/vkd3d-proton/*.dll $(BUILD_ROOT)/vkd3d-proton/lib/wine/vkd3d-proton/ && \
cp -f $(BUILD_DIR)/dist/files/lib64/wine/vkd3d-proton/*.dll $(BUILD_ROOT)/vkd3d-proton/lib64/wine/vkd3d-proton/
lsteamclient: | $(BUILD_ROOT)/lsteamclient/lib/wine/i386-windows
lsteamclient: | $(BUILD_ROOT)/lsteamclient/lib/wine/i386-unix
@ -195,10 +191,10 @@ lsteamclient: | $(BUILD_ROOT)/lsteamclient/lib64/wine/x86_64-windows
lsteamclient: | $(BUILD_ROOT)/lsteamclient/lib64/wine/x86_64-unix
lsteamclient: downloads
$(MAKE) $(MFLAGS) $(MAKEOVERRIDES) -C $(BUILD_DIR)/ $(UNSTRIPPED) lsteamclient && \
cp -f $(BUILD_DIR)/dist/dist/lib/wine/i386-windows/lsteamclient.dll $(BUILD_ROOT)/lsteamclient/lib/wine/i386-windows/ && \
cp -f $(BUILD_DIR)/dist/dist/lib/wine/i386-unix/lsteamclient.dll.so $(BUILD_ROOT)/lsteamclient/lib/wine/i386-unix/ && \
cp -f $(BUILD_DIR)/dist/dist/lib64/wine/x86_64-windows/lsteamclient.dll $(BUILD_ROOT)/lsteamclient/lib64/wine/x86_64-windows/ && \
cp -f $(BUILD_DIR)/dist/dist/lib64/wine/x86_64-unix/lsteamclient.dll.so $(BUILD_ROOT)/lsteamclient/lib64/wine/x86_64-unix/
cp -f $(BUILD_DIR)/dist/files/lib/wine/i386-windows/lsteamclient.dll $(BUILD_ROOT)/lsteamclient/lib/wine/i386-windows/ && \
cp -f $(BUILD_DIR)/dist/files/lib/wine/i386-unix/lsteamclient.dll.so $(BUILD_ROOT)/lsteamclient/lib/wine/i386-unix/ && \
cp -f $(BUILD_DIR)/dist/files/lib64/wine/x86_64-windows/lsteamclient.dll $(BUILD_ROOT)/lsteamclient/lib64/wine/x86_64-windows/ && \
cp -f $(BUILD_DIR)/dist/files/lib64/wine/x86_64-unix/lsteamclient.dll.so $(BUILD_ROOT)/lsteamclient/lib64/wine/x86_64-unix/
vrclient: | $(BUILD_ROOT)/vrclient/lib/wine/i386-windows
vrclient: | $(BUILD_ROOT)/vrclient/lib/wine/i386-unix
@ -206,17 +202,17 @@ vrclient: | $(BUILD_ROOT)/vrclient/lib64/wine/x86_64-windows
vrclient: | $(BUILD_ROOT)/vrclient/lib64/wine/x86_64-unix
vrclient: downloads
$(MAKE) $(MFLAGS) $(MAKEOVERRIDES) -C $(BUILD_DIR)/ $(UNSTRIPPED) vrclient && \
cp -f $(BUILD_DIR)/dist/dist/lib/wine/i386-windows/vrclient.dll $(BUILD_ROOT)/vrclient/lib/wine/i386-windows/ && \
cp -f $(BUILD_DIR)/dist/dist/lib/wine/i386-unix/vrclient.dll.so $(BUILD_ROOT)/vrclient/lib/wine/i386-unix/ && \
cp -f $(BUILD_DIR)/dist/dist/lib64/wine/x86_64-windows/vrclient_x64.dll $(BUILD_ROOT)/vrclient/lib64/wine/x86_64-windows/ && \
cp -f $(BUILD_DIR)/dist/dist/lib64/wine/x86_64-unix/vrclient_x64.dll.so $(BUILD_ROOT)/vrclient/lib64/wine/x86_64-unix/
cp -f $(BUILD_DIR)/dist/files/lib/wine/i386-windows/vrclient.dll $(BUILD_ROOT)/vrclient/lib/wine/i386-windows/ && \
cp -f $(BUILD_DIR)/dist/files/lib/wine/i386-unix/vrclient.dll.so $(BUILD_ROOT)/vrclient/lib/wine/i386-unix/ && \
cp -f $(BUILD_DIR)/dist/files/lib64/wine/x86_64-windows/vrclient_x64.dll $(BUILD_ROOT)/vrclient/lib64/wine/x86_64-windows/ && \
cp -f $(BUILD_DIR)/dist/files/lib64/wine/x86_64-unix/vrclient_x64.dll.so $(BUILD_ROOT)/vrclient/lib64/wine/x86_64-unix/
wineopenxr: | $(BUILD_ROOT)/wineopenxr/lib64/wine/x86_64-windows
wineopenxr: | $(BUILD_ROOT)/wineopenxr/lib64/wine/x86_64-unix
wineopenxr: downloads
$(MAKE) $(MFLAGS) $(MAKEOVERRIDES) -C $(BUILD_DIR)/ $(UNSTRIPPED) wineopenxr && \
cp -f $(BUILD_DIR)/dist/dist/lib64/wine/x86_64-windows/wineopenxr.dll $(BUILD_ROOT)/wineopenxr/lib64/wine/x86_64-windows/ && \
cp -f $(BUILD_DIR)/dist/dist/lib64/wine/x86_64-unix/wineopenxr.dll.so $(BUILD_ROOT)/wineopenxr/lib64/wine/x86_64-unix/
cp -f $(BUILD_DIR)/dist/files/lib64/wine/x86_64-windows/wineopenxr.dll $(BUILD_ROOT)/wineopenxr/lib64/wine/x86_64-windows/ && \
cp -f $(BUILD_DIR)/dist/files/lib64/wine/x86_64-unix/wineopenxr.dll.so $(BUILD_ROOT)/wineopenxr/lib64/wine/x86_64-unix/
battleye: | $(BUILD_ROOT)/battleye/v1/lib/wine/i386-windows
battleye: | $(BUILD_ROOT)/battleye/v1/lib/wine/i386-unix

View File

@ -147,7 +147,7 @@ endif
##
DST_BASE := $(OBJ)/dist
DST_DIR := $(DST_BASE)/dist
DST_DIR := $(DST_BASE)/files
DST_LIBDIR32 := $(DST_DIR)/lib
DST_LIBDIR64 := $(DST_DIR)/lib64
DEPLOY_DIR := ./deploy
@ -190,12 +190,13 @@ COMPAT_MANIFEST_TEMPLATE := $(SRCDIR)/compatibilitytool.vdf.template
LICENSE := $(SRCDIR)/dist.LICENSE
OFL_LICENSE := $(SRCDIR)/fonts/liberation-fonts/LICENSE
AV1_PATENTS := $(SRCDIR)/dav1d/doc/PATENTS
STEAMPIPE_FIXUPS_PY := $(SRCDIR)/steampipe_fixups.py
GECKO_VER := 2.47.2
GECKO32_TARBALL := wine-gecko-$(GECKO_VER)-x86.tar.xz
GECKO64_TARBALL := wine-gecko-$(GECKO_VER)-x86_64.tar.xz
WINEMONO_VER := 7.1.2
WINEMONO_VER := 7.2.0
WINEMONO_TARBALL := wine-mono-$(WINEMONO_VER)-x86.tar.xz
FONTS := $(SRCDIR)/fonts
@ -278,9 +279,10 @@ DIST_TARGETS := $(DIST_COPY_TARGETS) $(DIST_OVR32) $(DIST_OVR64) \
$(DIST_COMPAT_MANIFEST) $(DIST_LICENSE) $(DIST_TOOLMANIFEST) \
$(DIST_OFL_LICENSE) $(DIST_AV1_PATENTS) $(DIST_FONTS)
DEPLOY_COPY_TARGETS := $(DIST_COPY_TARGETS) $(DIST_VERSION) $(DIST_LICENSE) \
$(DIST_TOOLMANIFEST) $(DIST_OFL_LICENSE) $(DIST_AV1_PATENTS)
REDIST_COPY_TARGETS := $(DEPLOY_COPY_TARGETS) $(DIST_COMPAT_MANIFEST)
BASE_COPY_TARGETS := $(DIST_COPY_TARGETS) $(DIST_VERSION) $(DIST_LICENSE) \
$(DIST_TOOLMANIFEST) $(DIST_OFL_LICENSE) $(DIST_AV1_PATENTS) $(DST_DIR)
DEPLOY_COPY_TARGETS := $(BASE_COPY_TARGETS) $(STEAMPIPE_FIXUPS_PY)
REDIST_COPY_TARGETS := $(BASE_COPY_TARGETS) $(DIST_COMPAT_MANIFEST)
$(DIST_LICENSE): $(LICENSE)
cp -a $< $@
@ -375,24 +377,21 @@ dist: $(DIST_TARGETS) all-dist dist_wineopenxr | $(DST_DIR)
echo `date '+%s'` `GIT_DIR=$(abspath $(SRCDIR)/.git) git describe --tags` > $(DIST_VERSION)
deploy: dist | $(filter-out dist deploy install redist,$(MAKECMDGOALS))
mkdir -p $(DEPLOY_DIR) && \
cp -a $(DEPLOY_COPY_TARGETS) $(DEPLOY_DIR) && \
tar -C $(DST_DIR) -c . > $(DEPLOY_DIR)/proton_dist.tar
@echo "Created deployment archive at "$(DEPLOY_DIR)"/proton_dist.tar"
mkdir -p $(DEPLOY_DIR)
cp -af --no-dereference --preserve=mode,links $(DEPLOY_COPY_TARGETS) $(DEPLOY_DIR)
python3 $(STEAMPIPE_FIXUPS_PY) process $(DEPLOY_DIR)
install: dist | $(filter-out dist deploy install redist,$(MAKECMDGOALS))
if [ ! -d $(STEAM_DIR) ]; then echo >&2 "!! "$(STEAM_DIR)" does not exist, cannot install"; return 1; fi
mkdir -p $(STEAM_DIR)/compatibilitytools.d/$(BUILD_NAME)
# Use -r instead of -a for sshfs
cp -rf --no-dereference --preserve=mode,links $(DST_BASE)/* $(STEAM_DIR)/compatibilitytools.d/$(BUILD_NAME)
cp -f $(DIST_VERSION) $(STEAM_DIR)/compatibilitytools.d/$(BUILD_NAME)/dist/
@echo "Installed Proton to "$(STEAM_DIR)/compatibilitytools.d/$(BUILD_NAME)
@echo "You may need to restart Steam to select this tool"
redist: dist | $(filter-out dist deploy install redist,$(MAKECMDGOALS))
mkdir -p $(REDIST_DIR)
cp -a $(REDIST_COPY_TARGETS) $(REDIST_DIR)
tar -C $(DST_DIR) -c . | gzip -c -1 > $(REDIST_DIR)/proton_dist.tar.gz
@echo "Created redistribution tarball at "$(REDIST_DIR)"/proton_dist.tar.gz"
cp -af --no-dereference --preserve=mode,links $(REDIST_COPY_TARGETS) $(REDIST_DIR)
.PHONY: module32 module64 module
@ -504,6 +503,7 @@ GST_GOOD_MESON_ARGS := \
-Dmpg123=enabled \
-Dvideobox=enabled \
-Dvideofilter=enabled \
-Dvpx=enabled \
-Dwavparse=enabled \
$(GST_COMMON_MESON_ARGS)

View File

@ -182,7 +182,7 @@ function configure() {
#
arg_steamrt="soldier"
arg_protonsdk_image="registry.gitlab.steamos.cloud/proton/soldier/sdk:0.20220119.0-1"
arg_protonsdk_image="registry.gitlab.steamos.cloud/proton/soldier/sdk:0.20220329.0-0"
arg_no_protonsdk=""
arg_build_name=""
arg_container_engine=""

View File

@ -71,6 +71,14 @@ def setup_dll_symlinks(default_pfx_dir, dist_dir):
os.unlink(filename)
make_relative_symlink(target, filename)
#steampipe can't handle filenames with colons, so we remove them here
#and restore them in the proton script
def fixup_drive_links(default_pfx_dir):
for walk_dir, dirs, files in os.walk(os.path.join(default_pfx_dir, "dosdevices")):
for dir_ in dirs:
if ":" in dir_:
os.remove(os.path.join(walk_dir, dir_))
def make_default_pfx(default_pfx_dir, dist_dir, runtime):
local_env = dict(os.environ)
@ -94,6 +102,7 @@ def make_default_pfx(default_pfx_dir, dist_dir, runtime):
env=local_env, check=True)
setup_dll_symlinks(default_pfx_dir, dist_dir)
fixup_drive_links(default_pfx_dir)
if __name__ == '__main__':
import sys

View File

@ -1,4 +1,4 @@
STEAMRT_VERSION = 0.20220119.0
STEAMRT_VERSION = 0.20220329.0
STEAMRT_URLBASE = registry.gitlab.steamos.cloud
PROTONSDK_URLBASE = $(STEAMRT_URLBASE)/proton/soldier/sdk
@ -7,8 +7,8 @@ PROTONSDK_VERSION = $(STEAMRT_VERSION)-0-dev
# this is just for building toolchain, as we do static builds it should
# not have any impact on the end result, but changing it will invalidate
# docker caches, so we need something that don't change much
BASE_IMAGE_i686 = i386/ubuntu:18.04
BASE_IMAGE_x86_64 = ubuntu:18.04
BASE_IMAGE_i686 = docker.io/i386/ubuntu:18.04
BASE_IMAGE_x86_64 = docker.io/amd64/ubuntu:18.04
BINUTILS_VERSION = 2.37
GCC_VERSION = 10.3.0

2
dxvk

@ -1 +1 @@
Subproject commit a72463c5afcb41d0b2f6459c87d396543053b983
Subproject commit 0678d80e897e0b60f3424a22912c69f439233c53

@ -1 +1 @@
Subproject commit 87c043d7205b29cbba7610f0d88c7532ae32d736
Subproject commit ac312ac21bb1ca108a149849adba9fd1c77e3a9d

View File

@ -4,6 +4,8 @@
#include <dlfcn.h>
#include <limits.h>
#include <stdint.h>
#include <pthread.h>
#include <assert.h>
#include "windef.h"
#include "winbase.h"
@ -28,6 +30,17 @@ char g_tmppath[PATH_MAX];
static CRITICAL_SECTION steamclient_cs = { NULL, -1, 0, 0, 0, 0 };
static HANDLE steam_overlay_event;
static HANDLE callback_thread_handle;
#define MAX_CALLBACK_QUEUE_SIZE 4
struct callback_data *callback_queue[MAX_CALLBACK_QUEUE_SIZE];
static unsigned int callback_queue_size;
static BOOL callback_queue_done;
static UINT64 callback_queue_current_seq_number;
static pthread_mutex_t callback_queue_mutex;
static pthread_cond_t callback_queue_callback_event;
static pthread_cond_t callback_queue_ready_event;
static pthread_cond_t callback_queue_complete_event;
BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, void *reserved)
{
@ -40,6 +53,22 @@ BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, void *reserved)
steam_overlay_event = CreateEventA(NULL, TRUE, FALSE, "__wine_steamclient_GameOverlayActivated");
break;
case DLL_PROCESS_DETACH:
if (callback_thread_handle)
{
/* Unfortunately we don't have a clear place to shutdown the thread so just kill it. */
/* An explicit sync events and handle cleanup is to protect from unloading and loading
* .so again which may end up not actually reloading anyting and leaving the values of our static
* variables. */
TerminateThread(callback_thread_handle, -1);
WaitForSingleObject(callback_thread_handle, INFINITE);
pthread_mutex_destroy(&callback_queue_mutex);
pthread_cond_destroy(&callback_queue_callback_event);
pthread_cond_destroy(&callback_queue_ready_event);
pthread_cond_destroy(&callback_queue_complete_event);
CloseHandle(callback_thread_handle);
callback_thread_handle = NULL;
TRACE("Terminated callback thread.\n");
}
CloseHandle(steam_overlay_event);
break;
}
@ -59,12 +88,9 @@ void sync_environment(void)
for (unsigned int i = 0; i < ARRAY_SIZE(steamapi_envs); i++)
{
const char *env_str;
if (!GetEnvironmentVariableA(steamapi_envs[i], value, ARRAY_SIZE(value)))
{
if (GetLastError() == ERROR_ENVVAR_NOT_FOUND
&& !((env_str = getenv("SteamAppId")) && !strcmp(env_str, "677620")))
if (GetLastError() == ERROR_ENVVAR_NOT_FOUND)
{
TRACE("unsetenv(\"%s\")\n", steamapi_envs[i]);
unsetenv(steamapi_envs[i]);
@ -576,6 +602,84 @@ done:
return ret;
}
void execute_callback(struct callback_data *cb_data)
{
/* No TRACEs or other Wine calls here, this is executed from Unix native thread
* which is not initialized by Wine. */
cb_data->complete = FALSE;
pthread_mutex_lock(&callback_queue_mutex);
while (!callback_queue_done && callback_queue_size == MAX_CALLBACK_QUEUE_SIZE)
pthread_cond_wait(&callback_queue_ready_event, &callback_queue_mutex);
if (callback_queue_done)
{
pthread_mutex_unlock(&callback_queue_mutex);
return;
}
callback_queue[callback_queue_size++] = cb_data;
pthread_cond_broadcast(&callback_queue_callback_event);
while (!callback_queue_done && !cb_data->complete)
pthread_cond_wait(&callback_queue_complete_event, &callback_queue_mutex);
pthread_mutex_unlock(&callback_queue_mutex);
}
static BOOL get_next_callback(struct callback_data *cb_data, UINT64 *cookie)
{
BOOL ret;
pthread_mutex_lock(&callback_queue_mutex);
while (!callback_queue_done && !callback_queue_size)
pthread_cond_wait(&callback_queue_callback_event, &callback_queue_mutex);
if ((ret = !callback_queue_done))
{
assert(callback_queue_size);
--callback_queue_size;
*cookie = (UINT64)(ULONG_PTR)callback_queue[callback_queue_size];
*cb_data = *callback_queue[callback_queue_size];
}
pthread_cond_broadcast(&callback_queue_ready_event);
pthread_mutex_unlock(&callback_queue_mutex);
return ret;
}
static void callback_complete(UINT64 cookie)
{
struct callback_data *cb_data = (struct callback_data *)(ULONG_PTR)cookie;
pthread_mutex_lock(&callback_queue_mutex);
cb_data->complete = TRUE;
pthread_cond_broadcast(&callback_queue_complete_event);
pthread_mutex_unlock(&callback_queue_mutex);
}
typedef void (WINAPI *win_FSteamNetworkingSocketsDebugOutput)(ESteamNetworkingSocketsDebugOutputType nType,
const char *pszMsg);
static DWORD WINAPI callback_thread(void *dummy)
{
struct callback_data cb_data;
UINT64 cookie;
while (get_next_callback( &cb_data, &cookie))
{
switch (cb_data.type)
{
case SOCKET_DEBUG_OUTPUT:
TRACE("SOCKET_DEBUG_OUTPUT func %p, type %u, msg %s.\n",
cb_data.func, cb_data.sockets_debug_output.type,
wine_dbgstr_a(cb_data.sockets_debug_output.msg));
((win_FSteamNetworkingSocketsDebugOutput)cb_data.func)(cb_data.sockets_debug_output.type,
cb_data.sockets_debug_output.msg);
callback_complete(cookie);
break;
default:
ERR("Unexpected callback type %u.\n", cb_data.type);
break;
}
}
return 0;
}
static void *steamclient_lib;
static void *(*steamclient_CreateInterface)(const char *name, int *return_code);
static bool (*steamclient_BGetCallback)(HSteamPipe a, CallbackMsg_t *b, int32 *c);
@ -586,6 +690,7 @@ static void (*steamclient_ReleaseThreadLocalMemory)(int);
static int load_steamclient(void)
{
char path[PATH_MAX], resolved_path[PATH_MAX];
DWORD callback_thread_id;
if(steamclient_lib)
return 1;
@ -646,6 +751,14 @@ static int load_steamclient(void)
return 0;
}
pthread_mutex_init(&callback_queue_mutex, NULL);
pthread_cond_init(&callback_queue_callback_event, NULL);
pthread_cond_init(&callback_queue_ready_event, NULL);
pthread_cond_init(&callback_queue_complete_event, NULL);
callback_thread_handle = CreateThread(NULL, 0, callback_thread, NULL, 0, &callback_thread_id);
TRACE("Created callback thread 0x%04x.\n", callback_thread_id);
return 1;
}
@ -683,6 +796,7 @@ bool CDECL Steam_BGetCallback(HSteamPipe pipe, struct winCallbackMsg_t *win_msg,
if(!load_steamclient())
return 0;
next_event:
ret = steamclient_BGetCallback(pipe, &lin_msg, ignored);
if(ret){
@ -693,7 +807,7 @@ bool CDECL Steam_BGetCallback(HSteamPipe pipe, struct winCallbackMsg_t *win_msg,
if (win_msg->m_iCallback == 0x14b) /* GameOverlayActivated_t::k_iCallback */
{
uint8 activated = *(uint8 *)lin_msg.m_pubParam;
TRACE("steam overlay %sactivated, %sabling all X11 events.\n", activated ? "" : "de", activated ? "dis" : "en");
FIXME("HACK: Steam overlay %sactivated, %sabling all input events.\n", activated ? "" : "de", activated ? "dis" : "en");
if (activated)
{
SetEvent(steam_overlay_event);
@ -701,7 +815,16 @@ bool CDECL Steam_BGetCallback(HSteamPipe pipe, struct winCallbackMsg_t *win_msg,
keybd_event(VK_RSHIFT, 0x36 /* rshift scancode */, KEYEVENTF_KEYUP, 0);
keybd_event(VK_TAB, 0x0f /* tab scancode */, KEYEVENTF_KEYUP, 0);
}
else ResetEvent(steam_overlay_event);
else
{
if (WaitForSingleObject(steam_overlay_event, 0) == WAIT_TIMEOUT)
{
FIXME("Spurious steam overlay deactivate event, skipping.\n");
steamclient_FreeLastCallback(pipe);
goto next_event;
}
ResetEvent(steam_overlay_event);
}
}
switch(win_msg->m_iCallback | (lin_msg.m_cubParam << 16)){

View File

@ -61,6 +61,29 @@ bool do_cb_wrap(HSteamPipe pipe, void *linux_side, bool (*cpp_func)(void *, Stea
void *alloc_mem_for_iface(size_t size, const char *iface_version);
enum callback_type
{
SOCKET_DEBUG_OUTPUT = 1,
};
struct callback_data
{
enum callback_type type;
void *func;
int complete;
union
{
struct
{
unsigned int type;
const char *msg;
}
sockets_debug_output;
};
};
void execute_callback(struct callback_data *cb_data);
#ifdef __cplusplus
}
#endif

View File

@ -293,13 +293,19 @@ void *create_LinuxISteamMatchmakingRulesResponse(void *win, const char *version)
return ret;
}
/***** FSteamNetworkingSocketsDebugOutput *****/
static void (__attribute__((ms_abi)) *stored_FSteamNetworkingSocketsDebugOutput)(ESteamNetworkingSocketsDebugOutputType nType, const char *pszMsg);
static void lin_FSteamNetworkingSocketsDebugOutput(ESteamNetworkingSocketsDebugOutputType nType, const char *pszMsg)
{
stored_FSteamNetworkingSocketsDebugOutput(nType, pszMsg);
struct callback_data cb_data = { 0 };
/* Only Unix native calls from here (not even TRACE):
* this is native Unix thread which is not initialized by Wine. */
cb_data.type = SOCKET_DEBUG_OUTPUT;
cb_data.func = stored_FSteamNetworkingSocketsDebugOutput;
cb_data.sockets_debug_output.type = nType;
cb_data.sockets_debug_output.msg = pszMsg;
execute_callback(&cb_data);
}
void *manual_convert_FSteamNetworkingSocketsDebugOutput(void *win_func)

165
proton
View File

@ -10,6 +10,7 @@ import json
import os
import shutil
import errno
import platform
import stat
import subprocess
import sys
@ -17,13 +18,21 @@ import tarfile
import shlex
from ctypes import CDLL
from ctypes import CFUNCTYPE
from ctypes import POINTER
from ctypes import Structure
from ctypes import addressof
from ctypes import cast
from ctypes import get_errno
from ctypes import sizeof
from ctypes import c_int
from ctypes import c_int64
from ctypes import c_uint
from ctypes import c_long
from ctypes import c_char_p
from ctypes import c_void_p
from ctypes import c_size_t
from ctypes import c_ssize_t
from filelock import FileLock
from random import randrange
@ -142,10 +151,15 @@ def try_copy(src, dst, prefix=None, add_write_perm=True, copy_metadata=False, op
elif track_file and prefix is not None:
track_file.write(os.path.relpath(dst, prefix) + '\n')
if copy_metadata:
shutil.copy2(src, dst, follow_symlinks=follow_symlinks)
if os.path.islink(src) and not follow_symlinks:
shutil.copyfile(src, dst, follow_symlinks=False)
else:
shutil.copy(src, dst, follow_symlinks=follow_symlinks)
copyfile(src, dst)
if copy_metadata:
shutil.copystat(src, dst, follow_symlinks=follow_symlinks)
else:
shutil.copymode(src, dst, follow_symlinks=follow_symlinks)
if add_write_perm:
new_mode = os.lstat(dst).st_mode | stat.S_IWUSR | stat.S_IWGRP
@ -175,15 +189,62 @@ def try_copy(src, dst, prefix=None, add_write_perm=True, copy_metadata=False, op
else:
raise
# copy_file_range implementation for old Python versions
__syscall__copy_file_range = None
def copy_file_range_ctypes(fd_in, fd_out, count):
"Copy data using the copy_file_range syscall through ctypes, assuming x86_64 Linux"
global __syscall__copy_file_range
__NR_copy_file_range = 326
if __syscall__copy_file_range is None:
c_int64_p = POINTER(c_int64)
prototype = CFUNCTYPE(c_ssize_t, c_long, c_int, c_int64_p,
c_int, c_int64_p, c_size_t, c_uint, use_errno=True)
__syscall__copy_file_range = prototype(('syscall', CDLL(None, use_errno=True)))
while True:
ret = __syscall__copy_file_range(__NR_copy_file_range, fd_in, None, fd_out, None, count, 0)
if ret >= 0 or get_errno() != errno.EINTR:
break
if ret < 0:
raise OSError(get_errno(), errno.errorcode.get(get_errno(), 'unknown'))
return ret
def copyfile_reflink(srcname, dstname):
"Copy srcname to dstname, making reflink if possible"
global copyfile
with open(srcname, 'rb', buffering=0) as src:
bytes_to_copy = os.fstat(src.fileno()).st_size
try:
with open(dstname, 'wb', buffering=0) as dst:
while bytes_to_copy > 0:
bytes_to_copy -= copy_file_range(src.fileno(), dst.fileno(), bytes_to_copy)
except OSError as e:
if e.errno not in (errno.EXDEV, errno.ENOSYS, errno.EINVAL):
raise e
if e.errno == errno.ENOSYS:
copyfile = shutil.copyfile
shutil.copyfile(srcname, dstname)
if hasattr(os, 'copy_file_range'):
copyfile = copyfile_reflink
copy_file_range = os.copy_file_range
elif sys.platform == 'linux' and platform.machine() == 'x86_64' and sizeof(c_void_p) == 8:
copyfile = copyfile_reflink
copy_file_range = copy_file_range_ctypes
else:
copyfile = shutil.copyfile
def try_copyfile(src, dst):
try:
if os.path.isdir(dst):
dstfile = dst + "/" + os.path.basename(src)
if file_exists(dstfile, follow_symlinks=False):
os.remove(dstfile)
elif file_exists(dst, follow_symlinks=False):
dst = dst + "/" + os.path.basename(src)
if file_exists(dst, follow_symlinks=False):
os.remove(dst)
shutil.copyfile(src, dst)
copyfile(src, dst)
except PermissionError as e:
if e.errno == errno.EPERM:
#be forgiving about permissions errors; if it's a real problem, things will explode later anyway
@ -343,15 +404,15 @@ def set_dir_casefold_bit(dir_path):
class Proton:
def __init__(self, base_dir):
self.base_dir = base_dir + "/"
self.dist_dir = self.path("dist/")
self.bin_dir = self.path("dist/bin/")
self.lib_dir = self.path("dist/lib/")
self.lib64_dir = self.path("dist/lib64/")
self.fonts_dir = self.path("dist/share/fonts/")
self.wine_fonts_dir = self.path("dist/share/wine/fonts/")
self.wine_inf = self.path("dist/share/wine/wine.inf")
self.dist_dir = self.path("files/")
self.bin_dir = self.path("files/bin/")
self.lib_dir = self.path("files/lib/")
self.lib64_dir = self.path("files/lib64/")
self.fonts_dir = self.path("files/share/fonts/")
self.wine_fonts_dir = self.path("files/share/wine/fonts/")
self.wine_inf = self.path("files/share/wine/wine.inf")
self.version_file = self.path("version")
self.default_pfx_dir = self.path("dist/share/default_pfx/")
self.default_pfx_dir = self.path("files/share/default_pfx/")
self.user_settings_file = self.path("user_settings.py")
self.wine_bin = self.bin_dir + "wine"
self.wine64_bin = self.bin_dir + "wine64"
@ -361,28 +422,34 @@ class Proton:
def path(self, d):
return self.base_dir + d
def need_tarball_extraction(self):
'''Checks if the proton_dist tarball archive must be extracted. Returns true if extraction is needed, false otherwise'''
return not file_exists(self.dist_dir, follow_symlinks=True) or \
not file_exists(self.path("dist/version"), follow_symlinks=True) or \
not filecmp.cmp(self.version_file, self.path("dist/version"))
def cleanup_legacy_dist(self):
old_dist_dir = self.path("dist/")
if file_exists(old_dist_dir, follow_symlinks=True):
with self.dist_lock:
if file_exists(old_dist_dir, follow_symlinks=True):
shutil.rmtree(old_dist_dir)
def extract_tarball(self):
with self.dist_lock:
if self.need_tarball_extraction():
if file_exists(self.dist_dir, follow_symlinks=True):
shutil.rmtree(self.dist_dir)
tar = None
for sf in ["", ".xz", ".bz2", ".gz"]:
if file_exists(self.path("proton_dist.tar" + sf), follow_symlinks=True):
tar = tarfile.open(self.path("proton_dist.tar" + sf), mode="r:*")
break
if not tar:
log("No proton_dist tarball??")
sys.exit(1)
tar.extractall(path=self.dist_dir)
tar.close()
try_copy(self.version_file, self.dist_dir)
def do_steampipe_fixups(self):
fixups_json = self.path("steampipe_fixups.json")
fixups_mtime = self.path("files/steampipe_fixups_mtime")
if file_exists(fixups_json, follow_symlinks=True):
with self.dist_lock:
import steampipe_fixups
current_fixup_mtime = None
if file_exists(fixups_mtime, follow_symlinks=True):
with open(fixups_mtime, "r") as f:
current_fixup_mtime = f.readline().strip()
new_fixup_mtime = getmtimestr(fixups_json)
if current_fixup_mtime != new_fixup_mtime:
result_code = steampipe_fixups.do_restore(self.base_dir, fixups_json)
if result_code == 0:
with open(fixups_mtime, "w") as f:
f.write(new_fixup_mtime + "\n")
def missing_default_prefix(self):
'''Check if the default prefix dir is missing. Returns true if missing, false if present'''
@ -719,6 +786,12 @@ class CompatData:
self.migrate_user_paths()
if not file_exists(self.prefix_dir + "/dosdevices/c:", follow_symlinks=False):
os.symlink("../drive_c", self.prefix_dir + "/dosdevices/c:")
if not file_exists(self.prefix_dir + "/dosdevices/z:", follow_symlinks=False):
os.symlink("/", self.prefix_dir + "/dosdevices/z:")
# collect configuration info
steamdir = os.environ["STEAM_COMPAT_CLIENT_INSTALL_PATH"]
@ -920,19 +993,31 @@ def default_compat_config():
#affected by CW bug 19126
"252490", #Rust
"305620", #The Long Dark
"536280", #Disintegration
"585420", #Trailmakers
"684450", #Surviving the Aftermath
"700580", #Rust Staging
"707030", #POSTAL 4: No Regerts
"780290", #Gloomhaven
"794260", #Outward: Definitive Edition
"844260", #Rustler
"853050", #El Hijo - A Wild West Tale
"960170", #DJMAX RESPECT V
"983970", #Haven
"1075200", #TOHU
"1096530", #Solasta: Crown of the Magister
"1102190", #Monster Train
"1107790", #The Complex
"1110100", #Power Rangers: Battle for the Grid
"1135230", #Ember Knights
"1161580", #Hardspace: Shipbreaker
"1190000", #Car Mechanic Simulator 2021
"1331440", #FUSER
"1341290", #We Were Here Forever
"1361320", #The Room 4: Old Sins
"1477590", #EZ2ON REBOOT : R
"1523720", #Cook-Out
"1604030", #V Rising
"1913910", #Nine Sols Demo
#affected by CW bug 19741
@ -1071,6 +1156,7 @@ class Session:
self.env.setdefault("WINEDEBUG", "+timestamp,+pid,+tid,+seh,+unwind,+debugstr,+loaddll,+mscoree")
self.env.setdefault("DXVK_LOG_LEVEL", "info")
self.env.setdefault("VKD3D_DEBUG", "warn")
self.env.setdefault("VKD3D_SHADER_DEBUG", "fixme")
self.env.setdefault("WINE_MONO_TRACE", "E:System.NotImplementedException")
if self.env["PROTON_LOG"] != "1":
@ -1080,6 +1166,7 @@ class Session:
self.env.setdefault("WINEDEBUG", "-all")
self.env.setdefault("DXVK_LOG_LEVEL", "none")
self.env.setdefault("VKD3D_DEBUG", "none")
self.env.setdefault("VKD3D_SHADER_DEBUG", "none")
#disable XIM support until libx11 >= 1.7 is widespread
self.env.setdefault("WINE_ALLOW_XIM", "0")
@ -1377,8 +1464,8 @@ if __name__ == "__main__":
g_proton = Proton(os.path.dirname(sys.argv[0]))
if g_proton.need_tarball_extraction():
g_proton.extract_tarball()
g_proton.cleanup_legacy_dist()
g_proton.do_steampipe_fixups()
g_compatdata = CompatData(os.environ["STEAM_COMPAT_DATA_PATH"])

116
steampipe_fixups.py Executable file
View File

@ -0,0 +1,116 @@
#!/usr/bin/env python3
#Steampipe doesn't support certain unix-y things which may be required by
#native Linux applications. This file will process a directory of Linux files
#and store the file properties into a manifest file. After a round trip through
#Steampipe, the original file properties can be restored using this same
#script.
import json
import os
import secrets
import stat
DEFAULT_MANIFEST_NAME = "steampipe_fixups.json"
def usage():
print("Usage:")
print("\t" + sys.argv[0] + "\tprepare\t<path to directory to process>\t[manifest output file]")
print("\t\tProcess the given path and output the manifest file to the given path, or <path/" + DEFAULT_MANIFEST_NAME + "> if unspecified.")
print("")
print("\t" + sys.argv[0] + "\trestore\t<path to directory to process>\t[manifest file]")
print("\t\tRestore the given path using the manifest file, or <path/" + DEFAULT_MANIFEST_NAME + "> if unspecified.")
empty_dirs = []
no_write_paths = []
def canonicalize(path, prefix):
return path.replace(prefix, "", 1).lstrip('/')
def process_dir(path):
for root, subdirs, files in os.walk(path):
if len(subdirs) == 0 and len(files) == 0:
empty_dirs.append(canonicalize(root, path))
for file_ in files:
this_file = os.path.join(root, file_)
stat_result = os.lstat(this_file)
if (stat_result.st_mode & stat.S_IWUSR) == 0:
no_write_paths.append(canonicalize(this_file, path))
return 0
def write_manifest(manifest):
out = open(manifest, "w")
json.dump(
{
"id": str(secrets.randbits(32)), #we need steampipe to update this file for every build
"empty_dirs": empty_dirs,
"no_write_paths": no_write_paths,
},
out,
indent = 4,
sort_keys = True
)
return 0
def do_process(path, manifest):
if os.path.exists(manifest):
os.remove(manifest)
ret = process_dir(path)
if ret != 0:
return ret
#output should be deterministic
empty_dirs.sort()
no_write_paths.sort()
ret = write_manifest(manifest)
if ret != 0:
return ret
return 0
def do_restore(path, manifest):
loaded = json.load(open(manifest, "r"))
empty_dirs = loaded["empty_dirs"]
no_write_paths = loaded["no_write_paths"]
for empty_dir in empty_dirs:
try:
os.makedirs(os.path.join(path, empty_dir))
except OSError:
#already exists
pass
for file_ in no_write_paths:
this_file = os.path.join(path, file_)
stat_result = os.lstat(this_file)
os.chmod(this_file,
stat_result.st_mode & ~(stat.S_IWUSR | stat.S_IWGRP | stat.S_IWOTH))
return 0
if __name__ == '__main__':
import sys
if len(sys.argv) < 3 or len(sys.argv) > 4:
usage()
sys.exit(1)
verb = sys.argv[1]
path = sys.argv[2]
if len(sys.argv) >= 4:
manifest = sys.argv[3]
else:
manifest = os.path.join(path, DEFAULT_MANIFEST_NAME)
if verb == "process":
sys.exit(do_process(path, manifest))
if verb == "restore":
sys.exit(do_restore(path, manifest))
usage()
sys.exit(1)

View File

@ -15,6 +15,9 @@ user_settings = {
#vkd3d debug logging
"VKD3D_DEBUG": "warn",
#vkd3d-shader debug logging
"VKD3D_SHADER_DEBUG": "fixme",
#wine-mono debug logging (Wine's .NET replacement)
"WINE_MONO_TRACE": "E:System.NotImplementedException",
#"MONO_LOG_LEVEL": "info",

@ -1 +1 @@
Subproject commit 3e5aab6fb3e18f81a71b339be4cb5cdf55140980
Subproject commit cca7613bcaa78bd2fbcbf9a9ed50dd639e9c5bb6

2
wine

@ -1 +1 @@
Subproject commit df982e6865c2041ae994ee20ed2a2075ae7ddfb7
Subproject commit 84daaac686abe36b9d0fd95a1dbe1743871f7f52