mirror of
https://github.com/clearlinux/linux-steam-integration.git
synced 2026-09-06 22:01:27 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
53fec0a8b6 | ||
|
|
41c117918c | ||
|
|
88792a27ea | ||
|
|
24c26aeab7 | ||
|
|
ed0153c825 | ||
|
|
7d5ff6a5d4 | ||
|
|
b1852cb803 | ||
|
|
c524679428 | ||
|
|
2388f6f693 | ||
|
|
8cdb63fd7e | ||
|
|
8591b35a8e | ||
|
|
950897ab0d | ||
|
|
45b5652109 | ||
|
|
329f8de9aa | ||
|
|
b001cbf750 | ||
|
|
ec78c17316 | ||
|
|
20db0cad18 | ||
|
|
446152e8ad | ||
|
|
65805e2d0a | ||
|
|
32326af2b3 | ||
|
|
8c304bcd16 | ||
|
|
893100c174 | ||
|
|
709f5cd1c2 | ||
|
|
8f531f3be8 | ||
|
|
e1e4c11b8d | ||
|
|
347b41f990 | ||
|
|
e7b2d6f70e | ||
|
|
5732bc2fca | ||
|
|
514a7fabb1 | ||
|
|
44a195274b | ||
|
|
212d938e25 | ||
|
|
db4c33fce1 | ||
|
|
3355bb7cff | ||
|
|
3b40061748 | ||
|
|
1edead3929 | ||
|
|
da439aa484 | ||
|
|
991e12d6cd | ||
|
|
87bf493350 | ||
|
|
22c9805c16 | ||
|
|
84a4dd59a9 | ||
|
|
8684a992b0 | ||
|
|
4303b14f45 | ||
|
|
7456c9c26a | ||
|
|
0a84ba7fc4 | ||
|
|
981fe43071 | ||
|
|
63aba59c27 | ||
|
|
3485ab87eb | ||
|
|
e2325befba | ||
|
|
a89de2bb58 | ||
|
|
ede4e130f4 | ||
|
|
d4eb0ca042 | ||
|
|
bfb703be68 | ||
|
|
d0708a2332 | ||
|
|
a7c59cacef | ||
|
|
799c4b1e48 | ||
|
|
ada9b92f53 | ||
|
|
60c3ddc6e9 | ||
|
|
c3a071e2a0 | ||
|
|
4001ffc814 | ||
|
|
e3a4640c04 | ||
|
|
bddeda6ef3 | ||
|
|
71322156e3 | ||
|
|
c5bb4ca040 | ||
|
|
a2502c1ec7 | ||
|
|
2b2e73b572 | ||
|
|
a98ebc3607 | ||
|
|
78fcdf6247 | ||
|
|
516823ae3c | ||
|
|
f2352546d4 | ||
|
|
b87210a253 | ||
|
|
2d6ab6d497 | ||
|
|
ffdc14c109 | ||
|
|
e45340973a | ||
|
|
1f73dd3e0b | ||
|
|
fb50dca553 | ||
|
|
edf3176c70 | ||
|
|
e73d384726 | ||
|
|
30152b9604 | ||
|
|
a83b1c24b2 | ||
|
|
0f33bb1fbd | ||
|
|
88550aeffc | ||
|
|
fe83d34984 | ||
|
|
9b4187ed27 | ||
|
|
b40eba8ad9 | ||
|
|
1179763531 | ||
|
|
627c7639cf | ||
|
|
290260c09e | ||
|
|
a691985541 | ||
|
|
1811ff5225 | ||
|
|
a932486826 | ||
|
|
3c69b6dc05 | ||
|
|
c8f0cecb15 | ||
|
|
3b01919148 | ||
|
|
474aca0b69 | ||
|
|
fa81893d41 | ||
|
|
f958b8ac3f | ||
|
|
971d0c280e | ||
|
|
4f6166bdce | ||
|
|
be98e146ed | ||
|
|
5c131f6b28 | ||
|
|
8768730414 | ||
|
|
68fe3c1c11 | ||
|
|
dc85a14bfb | ||
|
|
c646ee516e | ||
|
|
bb29a04078 | ||
|
|
0eb0d09119 | ||
|
|
5810e63576 | ||
|
|
01faa3754d | ||
|
|
b4e512b708 | ||
|
|
95613a45f8 | ||
|
|
312b7a888a | ||
|
|
071304d8bd | ||
|
|
36e6cf5455 | ||
|
|
26dc2503d2 | ||
|
|
1d81c2094f | ||
|
|
fe063b1624 | ||
|
|
fa41b2c572 | ||
|
|
feae99a359 | ||
|
|
34fe25a533 | ||
|
|
6349652740 | ||
|
|
665caee634 | ||
|
|
be3023263f | ||
|
|
27e5cd0ae0 | ||
|
|
79fece840c | ||
|
|
478a0f1810 | ||
|
|
2cf5db42b3 | ||
|
|
191ea02946 | ||
|
|
03dd537574 | ||
|
|
8ded405801 | ||
|
|
35b3f132fd | ||
|
|
4b718a4bc7 | ||
|
|
5ceacb27fb | ||
|
|
d1b7a86867 | ||
|
|
0c252321e3 | ||
|
|
b9d677dee1 | ||
|
|
86fbf11040 | ||
|
|
ec67c801ad | ||
|
|
0a02c111a0 | ||
|
|
48a9bac406 | ||
|
|
8de8962099 | ||
|
|
de9380dc8d | ||
|
|
9bd423fb34 | ||
|
|
75d2e9cc45 |
Binary file not shown.
|
After Width: | Height: | Size: 97 KiB |
+1
-1
@@ -1,3 +1,3 @@
|
||||
[submodule "src/libnica"]
|
||||
path = src/libnica
|
||||
url = git@github.com:intel/libnica.git
|
||||
url = https://github.com/intel/libnica.git
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
[main]
|
||||
host = https://www.transifex.com
|
||||
|
||||
[linux-steam-integration.linux-steam-integrationpot]
|
||||
file_filter = po/<lang>.po
|
||||
source_lang = en
|
||||
type = PO
|
||||
|
||||
@@ -1,161 +1,63 @@
|
||||
linux-steam-integration
|
||||
-----------------------
|
||||
|
||||
Linux Steam Integration attempts to improve the Steam* gaming experience for users on Linux. In the default mode, it will disable the Steam runtime, and facilitate usage of the distro's own runtime for improved integration and performance. The Steam Runtime is a very old set of Ubuntu libraries, and as such provides a suboptimial experience for many Linux users. A key example of this is broken fontconfig, C++ ABI issues preventing loading, or even the broken theming of GTK widgets on non-Ubuntu distros. These woes have been compounded for users of the open source drivers.
|
||||
Linux Steam* Integration is a helper system to make the Steam Client and Steam
|
||||
games run better on Linux. In a nutshell, LSI automatically applies various workarounds
|
||||
to get games working, and fixes long standing bugs in both games and the client.
|
||||
|
||||
The LSI tool also allows you to use Steam's runtime if you need to, as currently not all cases are covered. It will also take care to prepare the environment, ensuring that users can load Steam using it's own runtime without hitting any of the issues common to a modern distro, i.e. ABI issues and having to `LD_PRELOAD` libraries to even make Steam start.
|
||||

|
||||
|
||||
More importantly, LSI achieves all of this by not having to **butcher your existing Steam installation**, as is common in some new tools.
|
||||
In many cases this will involve controlling which libraries are allowed to be used
|
||||
at any given time, and these libraries may be overriden for any of the following
|
||||
reasons:
|
||||
|
||||
This project, and by extension Solus, is not officially endorsed by, or affiliated with, Steam*, or its parent company, Valve*.
|
||||
- Security
|
||||
- Compatibility
|
||||
- Performance
|
||||
|
||||
Additionally we apply dynamic workarounds to fix some filesystem path related bugs in Linux
|
||||
ports (or even shader workarounds for ARK*) through our redirect module.
|
||||
|
||||
With LSI, you don't need to worry any more about manually mangling your Steam installation
|
||||
just to make the open source drivers work, or manually creating links and installing
|
||||
unsupported libraries. LSI is designed to take care of all of this for you.
|
||||
|
||||
Note that LSI will not modify your Steam installation, and instead makes use of two
|
||||
modules, `liblsi-redirect.so` and `liblsi-intercept.so`, to dynamically apply all of the
|
||||
workarounds at runtime, which in turn is set up by the main LSI `shim` binary.
|
||||
|
||||
For a more in depth view of what LSI is, and how to integrate it into your distribution,
|
||||
please check the [technical README document](https://github.com/solus-project/linux-steam-integration/blob/master/TECHNICAL.md).
|
||||
|
||||
Do note that we intend to remove the need for distributions to integrate LSI in the near future, by providing
|
||||
the LSI system as a [snap](https://snapcraft.io/) package for all supported distributions.
|
||||
|
||||
This project, and by extension Solus, is not officially endorsed by, or affiliated with, Steam, or its parent company, Valve*.
|
||||
|
||||
Linux Steam Integration is a [Solus project](https://solus-project.com/)
|
||||
|
||||

|
||||
|
||||
## Getting LSI
|
||||
|
||||
Integrating LSI
|
||||
===============
|
||||
LSI may not yet be available for your distribution, however some community maintained repositories do exist.
|
||||
|
||||
To correctly integrate LSI, your Steam package will require modification. LSI must provide the /usr/bin/steam binary, so your Steam package must move the main launcher to a shadow location.
|
||||
- [Arch Linux](https://aur.archlinux.org/packages/linux-steam-integration/)
|
||||
- [Fedora](https://copr.fedorainfracloud.org/coprs/alunux/linux-steam-integration/)
|
||||
- Solus uses LSI by default, just install the `steam` package.
|
||||
|
||||
## License
|
||||
|
||||
For users who do not have access to LSI in their distribution, because it has not been integrated yet, please configure with `-Dwith-shim=co-exist` to preserve your existing Steam integrity. Then use the "LSI Steam" shortcut in your menu to launch Steam via LSI.
|
||||
Copyright © 2016-2017 Ikey Doherty
|
||||
|
||||
**Configuring LSI build**
|
||||
linux-steam-integration is available under the terms of the `LGPL-2.1` license.
|
||||
|
||||
There are a number of meson configure options you should be aware of when integrating LSI correctly. The prominent ones are explained here.
|
||||
See the accompanying `LICENSE.LGPL2.1` file for more details
|
||||
|
||||
`-Dwith-shim= none | co-exist | replacement`
|
||||
`--disable-replace-steam`
|
||||
|
||||
Control behaviour of the shim build. `none` will disable building the main
|
||||
shim, required for actually launching Steam in the first place.
|
||||
|
||||
`co-exist` will ensure this does not conflict with the `/usr/bin/steam`
|
||||
path, providing a new `lsi-steam` binary and desktop file.
|
||||
|
||||
`replacement` will provide a drop-in replacement `/usr/bin/steam` binary
|
||||
shim responsible for bootstrapping Steam via LSI. This will require you
|
||||
to mask the original steam binary to a new location.
|
||||
|
||||
The default value for this option is::
|
||||
|
||||
replacement
|
||||
|
||||
|
||||
`-Dwith-steam-binary=$PATH`
|
||||
|
||||
Set the absolute path for the shadowed Steam binary.
|
||||
LSI will execv Steam after it has initialised the environment.
|
||||
Note that execv, not execvp, is used, to mask programs that may be
|
||||
in the `$PATH`, hence requiring an absolute path.
|
||||
|
||||
The default value for this option is::
|
||||
|
||||
/usr/lib/steam/steam
|
||||
|
||||
This option is only applicable for distribution integrators, when
|
||||
Steam replacement is enabled.
|
||||
|
||||
|
||||
`-Dwith-preload-libs=$LIBS`
|
||||
|
||||
A colon separated list of libraries that are required to launch Steam
|
||||
when using its own runtime. LSI enables users to switch back to the Steam
|
||||
runtime, and in this instance we manage the LD_PRELOAD environmental variable.
|
||||
Ensure this is correct, and escape $LIB for correct Linux usage.
|
||||
|
||||
The default value for this option is::
|
||||
|
||||
/usr/\$LIB/libX11.so.6:/usr/\$LIB/libstdc++.so.6
|
||||
|
||||
`-Dwith-frontend=$boolean`
|
||||
|
||||
A small UI application is shipped to enable configuration of LSI, which presents
|
||||
a simple GTK3 Dialog to the user. It is not enabled by default, it is up
|
||||
to the integrator to decide if they wish to employ lsi-settings, or implement
|
||||
an alternative.
|
||||
|
||||
The lsi-settings application will only ever write new configurations to the
|
||||
**user** settings file, and requires no special permissions.
|
||||
|
||||
The default value for this option is::
|
||||
|
||||
false
|
||||
|
||||
|
||||
**How LSI Works**
|
||||
|
||||
LSI provides a /usr/bin/steam binary to be used in place of the existing Steam script, which will then correctly set up the environment before swapping the process for the Steam process.
|
||||
When using a full build of LSI, the bootstrap shim will force a correct environment, removing any issues that can cause various older SDL versions to kill Steam. Additionally it will then
|
||||
force `STEAM_RUNTIME=0` if this is set in the config (default behaviour).
|
||||
|
||||
When using the native runtime, and the `intercept` library is enabled, the LSI shim will also set up `LD_AUDIT` to use `liblsi-intercept`. This library will intercept all dynamic linking operations
|
||||
for the main Steam binaries and override their behaviour, allowing Steam to only load a handful of vendored libraries (`libav` fork) as well as its own private libraries. It is then forced to use
|
||||
system libraries for everything else. This means the Steam client, web helper, etc, will use the native SDL, X11, fixing many bugs with video playback, font rendering and such.
|
||||
|
||||
If you are packaging LSI for a distribution, please ensure you provide both a 32-bit and 64-bit build of the intercept library so that the entirety of Steam's library (`.so`) mechanism is tightly
|
||||
controlled by LSI. See the scripts in the root directory of this repository for examples of how to do this.
|
||||
|
||||
Configuration options can be placed in an INI-style configuration file in a series of locations, which are ordered by priority in a cascade::
|
||||
|
||||
~/.config/linux-steam-integration.conf
|
||||
/etc/linux-steam-integration.conf
|
||||
/usr/share/defaults/linux-steam-integration/linux-steam-integration.conf
|
||||
|
||||
The user configuration takes immediate priority. Secondly we have the system-wide configuration for affecting all accounts, and lastly the vendor configuration, which may be provided by the integrator.
|
||||
|
||||
Currently this INI file supports two options. The root section in this INI file must be `[Steam]`.
|
||||
|
||||
`use-native-runtime = $boolean`
|
||||
|
||||
If set to a true boolean value, (yes/true/on), the host OS's native runtime
|
||||
will be used instead of the Steam provided runtime. If this is set to
|
||||
a false boolean value (no/false/off), then the startup will be modified
|
||||
to export the relevant `LD_PRELOAD` and `STEAM_RUNTIME` settings.
|
||||
|
||||
The default value of this variable is true.
|
||||
|
||||
`force-32bit = $boolean`
|
||||
|
||||
If set to a true boolean value (yes/true/on), the shadowed Steam binary will
|
||||
be run via the `linux32` command. This will force the `steam` process
|
||||
and all children to believe they are running on a 32-bit system. This
|
||||
may be useful for 64-bit games that are buggy only on 64-bit.
|
||||
|
||||
If this is set to a false boolean value (no/false/off), then the
|
||||
shadowed Steam binary will be directly executed. Note that on 32-bit
|
||||
OSs this setting is ignored.
|
||||
|
||||
The default value of this variable is false.
|
||||
|
||||
|
||||
Common issues
|
||||
=============
|
||||
|
||||
**Missing tray icon for Steam client using native OS runtime**
|
||||
|
||||
Ensure you have the 32-bit version of libappindicator installed. This is required for the tray icon. libappindicator falls back to a standard X11 tray icon in the absence of desktop appindicator support.
|
||||
|
||||
Related issue: [Steam tray icon missing #2](https://github.com/solus-project/linux-steam-integration/issues/2)
|
||||
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
`src/shim src/frontend src/lsi src/intercept`:
|
||||
|
||||
Copyright © 2016-2017 Ikey Doherty
|
||||
|
||||
linux-steam-integration is available under the terms of the `LGPL-2.1`
|
||||
|
||||
`data/lsi-steam.desktop`:
|
||||
|
||||
This file borrows translations from the official `steam.desktop` launcher.
|
||||
These are copyright of Valve*.
|
||||
|
||||
See `LICENSE.LGPL2.1 <LICENSE.LGPL2.1>`_ for more details
|
||||
|
||||
|
||||
* Some names may be claimed as the property of others.
|
||||
`* Some names may be claimed as the property of others.`
|
||||
|
||||
+274
@@ -0,0 +1,274 @@
|
||||
linux-steam-integration
|
||||
-----------------------
|
||||
|
||||
Linux Steam Integration is a software package aimed squarely at Linux distribution developers.
|
||||
It is designed to offer a far better Steam* experience than the stock client, doing away with old
|
||||
integration issues and crashes.
|
||||
|
||||
### Native Libraries
|
||||
|
||||
LSI enforces the use of host-native libraries, both in the Steam Client (via `lsi-intercept`) and
|
||||
games themselves. This ensures Steam integrates properly, games run with the latest libraries
|
||||
and users get the best performance.
|
||||
|
||||
Currently the officially provided Steam runtime is based on very old Ubuntu 12.04 packages,
|
||||
and has some cherry-picked updates (SDL, for example). This causes lots of integration issues
|
||||
on most newer distributions, such as broken client behaviour with full screen videos, outright
|
||||
crashes on startup, mismatched C++ ABI, missing sound, ugly menus, broken font rendering,
|
||||
poor performance, etc.
|
||||
|
||||
In a nut shell, LSI will force most of Steam over to using native libraries. The intercept
|
||||
system is new as of 0.4, and will be extended in future to allow improving certain games
|
||||
on a process-name whitelisting basis.
|
||||
|
||||
### Configurable
|
||||
|
||||
You can easily toggle the use of the native runtime or the runtime provided with the official
|
||||
Steam package distribution. LSI doesn't butcher any files, so your local Steam directory does
|
||||
not need to be repaired or reinstalled. Just run `lsi-settings` and restart Steam.
|
||||
|
||||
Currently you can control whether the native runtime is used, force 32-bit mode for some troublesome
|
||||
ports, and control whether the intercept library is enabled (which will undo the various library
|
||||
mangling tricks of the Steam distribution to force the usage of the system libs via rtld-audit)
|
||||
|
||||
### Portable
|
||||
|
||||
You can (and should) stick this into any distro. Hit us up if you need help integrating, or need some
|
||||
portability changes made. We won't bite.
|
||||
|
||||
### Going beyond LSI
|
||||
|
||||
LSI solves a great many issues, however there is then still a responsibility for the integrating distribution
|
||||
to provide basic ABI compatibility, as well as being functionally comparable to the "stock" runtime.
|
||||
Our future plans will basically involve creating a project based around LSI and a specially produced,
|
||||
optimised Steam runtime, usable on all Linux distributions.
|
||||
|
||||
If you want to be part of that effort - and help bring a modern, optimised gaming experience to your Linux
|
||||
users, please get in contact. Let's do this once, and do it right.
|
||||
|
||||
|
||||
## Integrating LSI
|
||||
|
||||
To correctly integrate LSI, your Steam package will require modification. LSI must provide the `/usr/bin/steam binary`, so your Steam package must move the main launcher to a shadow location.
|
||||
|
||||
For users who do not have access to LSI in their distribution, because it has not been integrated yet, please configure with `-Dwith-shim=co-exist` to preserve your existing Steam integrity. Then use the "LSI Steam" shortcut in your menu to launch Steam via LSI.
|
||||
|
||||
**Configuring LSI build**
|
||||
|
||||
There are a number of meson configure options you should be aware of when integrating LSI correctly. The prominent ones are explained here.
|
||||
|
||||
`-Dwith-shim= none | co-exist | replacement`
|
||||
|
||||
Control behaviour of the shim build. `none` will disable building the main
|
||||
shim, required for actually launching Steam in the first place.
|
||||
|
||||
`co-exist` will ensure this does not conflict with the `/usr/bin/steam`
|
||||
path, providing a new `lsi-steam` binary and desktop file.
|
||||
|
||||
`replacement` will provide a drop-in replacement `/usr/bin/steam` binary
|
||||
shim responsible for bootstrapping Steam via LSI. This will require you
|
||||
to mask the original steam binary to a new location.
|
||||
|
||||
The default value for this option is:
|
||||
|
||||
`replacement`
|
||||
|
||||
|
||||
`-Dwith-steam-binary=$PATH`
|
||||
|
||||
Set the absolute path for the shadowed Steam binary.
|
||||
LSI will execv Steam after it has initialised the environment.
|
||||
Note that execv, not execvp, is used, to mask programs that may be
|
||||
in the `$PATH`, hence requiring an absolute path.
|
||||
|
||||
The default value for this option is:
|
||||
|
||||
`/usr/lib/steam/steam`
|
||||
|
||||
This option is only applicable for distribution integrators, when
|
||||
Steam replacement is enabled.
|
||||
|
||||
|
||||
`-Dwith-preload-libs=$LIBS`
|
||||
|
||||
A colon separated list of libraries that are required to launch Steam
|
||||
when using its own runtime. LSI enables users to switch back to the Steam
|
||||
runtime, and in this instance we manage the LD_PRELOAD environmental variable.
|
||||
Ensure this is correct, and escape $LIB for correct Linux usage.
|
||||
|
||||
The default value for this option is:
|
||||
|
||||
`/usr/\$LIB/libX11.so.6:/usr/\$LIB/libstdc++.so.6`
|
||||
|
||||
`-Dwith-new-libcxx-abi=$boolean`
|
||||
|
||||
Enable this if your distribution uses a recent libstdc++ build, from
|
||||
GCC 6 or higher.
|
||||
|
||||
`-Dwith-frontend=$boolean`
|
||||
|
||||
A small UI application is shipped to enable configuration of LSI, which presents
|
||||
a simple GTK3 Dialog to the user. It is not enabled by default, it is up
|
||||
to the integrator to decide if they wish to employ lsi-settings, or implement
|
||||
an alternative.
|
||||
|
||||
The lsi-settings application will only ever write new configurations to the
|
||||
**user** settings file, and requires no special permissions.
|
||||
|
||||
The default value for this option is:
|
||||
|
||||
`false`
|
||||
|
||||
`-Dwith-libressl-mode= none | native | shim`
|
||||
|
||||
Control how LSI's `liblsi-intercept.so` handles LibreSSL.
|
||||
|
||||
The intercept module can be configured to enhance security of Linux ports
|
||||
by ensuring they use up to date LibreSSL builds.
|
||||
|
||||
When set to `native`, it is assumed the distro is employing LibreSSL as the
|
||||
default libSSL ABI (i.e. `libssl.so.1.0.0`)
|
||||
|
||||
When set to `shim`, LSI will redirect name requests for the `libssl` and
|
||||
`libcrypto` libraries to a uniquely named LibreSSL build of libraries,
|
||||
allowing libressl + openssl to co-exist on disk.
|
||||
|
||||
The default value for this option is:
|
||||
|
||||
`none`
|
||||
|
||||
`-Dwith-libressl-suffix=$suffix`
|
||||
|
||||
This option is only used when `-Dwith-libressl-mode=shim`, and sets the
|
||||
suffix for the libraries that LSI will attempt to use when transforming
|
||||
requests for LibreSSL libraries.
|
||||
|
||||
This will transform `libssl.so.$VERSION` to `libssl-$suffix.so`, i.e.
|
||||
`libssl.so.37` would become `libssl-libressl.so`. This allows distros
|
||||
to provide up to date `libressl` and `openssl` builds in parallel to
|
||||
improve the security of games relying on LibreSSL.
|
||||
|
||||
The default value for this option is:
|
||||
|
||||
`-libressl`
|
||||
|
||||
## How LSI Works
|
||||
|
||||
LSI provides a /usr/bin/steam binary to be used in place of the existing Steam script, which will then correctly set up the environment before swapping the process for the Steam process.
|
||||
When using a full build of LSI, the bootstrap shim will force a correct environment, removing any issues that can cause various older SDL versions to kill Steam. Additionally it will then
|
||||
force `STEAM_RUNTIME=0` if this is set in the config (default behaviour).
|
||||
|
||||
When using the native runtime, and the `intercept` library is enabled, the LSI shim will also set up `LD_AUDIT` to use `liblsi-intercept.so`. This library will intercept all dynamic linking operations
|
||||
for the main Steam binaries and override their behaviour, allowing Steam to only load a handful of vendored libraries (`libav` fork) as well as its own private libraries. It is then forced to use
|
||||
system libraries for everything else. This means the Steam client, web helper, etc, will use the native SDL, X11, fixing many bugs with video playback, font rendering and such.
|
||||
|
||||
As of the `0.6` release of LSI, we now also support a `redirect` module. When enabled, the LSI shim will set `LD_PRELOAD` to use `liblsi-redirect.so`, which will conditionally enable it's own
|
||||
internal logic based on the game being played. This module currently overrides the `open()` and `fopen64()` system calls to apply dynamic bug fixes to games, and may be expanded in future to
|
||||
provide more fixes.
|
||||
|
||||
Currently the `redirect` module supports:
|
||||
|
||||
- ARK: Survival Evolved* (Use fixed shader asset from `TheCenter` DLC to fix invalid water appearance)
|
||||
- Project Highrise* (Fix crash where the game attempts to use a directory as a config file `prefs.txt`)
|
||||
|
||||
If you are packaging LSI for a distribution, please ensure you provide both a 32-bit and 64-bit build of the intercept library so that the entirety of Steam's library (`.so`) mechanism is tightly
|
||||
controlled by LSI. See the scripts in the root directory of this repository for examples of how to do this.
|
||||
|
||||
Configuration options can be placed in an INI-style configuration file in a series of locations, which are ordered by priority in a cascade:
|
||||
|
||||
~/.config/linux-steam-integration.conf
|
||||
/etc/linux-steam-integration.conf
|
||||
/usr/share/defaults/linux-steam-integration/linux-steam-integration.conf
|
||||
|
||||
The user configuration takes immediate priority. Secondly we have the system-wide configuration for affecting all accounts, and lastly the vendor configuration, which may be provided by the integrator.
|
||||
|
||||
Currently this INI file supports three options. The root section in this INI file must be `[Steam]`.
|
||||
|
||||
`use-native-runtime = $boolean`
|
||||
|
||||
If set to a true boolean value, (yes/true/on), the host OS's native runtime
|
||||
will be used instead of the Steam provided runtime. If this is set to
|
||||
a false boolean value (no/false/off), then the startup will be modified
|
||||
to export the relevant `LD_PRELOAD` and `STEAM_RUNTIME` settings.
|
||||
|
||||
The default value of this variable is `true`.
|
||||
|
||||
`force-32bit = $boolean`
|
||||
|
||||
If set to a true boolean value (yes/true/on), the shadowed Steam binary will
|
||||
be run via the `linux32` command. This will force the `steam` process
|
||||
and all children to believe they are running on a 32-bit system. This
|
||||
may be useful for 64-bit games that are buggy only on 64-bit.
|
||||
|
||||
If this is set to a false boolean value (no/false/off), then the
|
||||
shadowed Steam binary will be directly executed. Note that on 32-bit
|
||||
OSs this setting is ignored.
|
||||
|
||||
The default value of this variable is `false`.
|
||||
|
||||
`use-libintercept = $boolean`
|
||||
|
||||
If set to a true boolean value (yes/true/on), the `liblsi-intercept.so`
|
||||
library will be utilised to control dynamic linking within the Steam client
|
||||
and associated processes.
|
||||
|
||||
Note this requires `use-native-runtime` to be set.
|
||||
|
||||
The default value of this variable is `true`.
|
||||
|
||||
`use-libredirect = $boolean`
|
||||
|
||||
If set to a true boolean value (yes/true/on), the `liblsi-redirect.so`
|
||||
library will be utilised to apply "hot" workarounds to certain games to
|
||||
fix various runtime issues.
|
||||
|
||||
Note this requires `use-native-runtime` to be set.
|
||||
|
||||
The default value of this variable is `true`.
|
||||
|
||||
|
||||
## Common issues
|
||||
|
||||
Virtually all issues will come down to having the right dependencies. LSI puts an emphasis on
|
||||
host-first libraries, so make sure all the correct libraries are available for both 32-bit and
|
||||
64-bit.
|
||||
|
||||
Steam has both 32-bit and 64-bit processes/libraries, having the full dependency set for both
|
||||
the client and common games/engines is a must.
|
||||
|
||||
### Steam fails to launch with libintercept/native-runtime
|
||||
|
||||
Make sure you enable full debugging when first assigning dependencies to your runtime package:
|
||||
|
||||
```bash
|
||||
$ LSI_DEBUG=1 steam
|
||||
# If you use co-exist option:
|
||||
$ LSI_DEBUG=1 lsi-steam
|
||||
```
|
||||
|
||||
### liblsi-intercept regressing performance
|
||||
|
||||
There exists a bug in `glibc` which incorrectly configures profiling for all PLT calls when using `LD_AUDIT` (rtld-audit)
|
||||
even if the audit library doesn't implement `la_pltenter` or `la_pltexit`. This leads to a performance hit on every
|
||||
runtime call via PLT.
|
||||
|
||||
The issue was first reported to this project by @amonakov [here](https://github.com/solus-project/linux-steam-integration/issues/15).
|
||||
The upstream glibc issue is reported on the upstream glibc [bugzilla](https://sourceware.org/bugzilla/show_bug.cgi?id=15533).
|
||||
A patch to resolve the issue was submitted by @amonakov [here](https://sourceware.org/ml/libc-alpha/2013-05/msg00888.html).
|
||||
|
||||
If you are noticing performance regressions, you can:
|
||||
|
||||
- As a user: Disable `liblsi-intercept` via `lsi-settings`. This will hurt compatibility.
|
||||
- As a packager: Disable `liblsi-intercept` via build flags. This will hurt compatibility.
|
||||
- As a distribution integrator: Add weight to upstream issue and import patch into your distribution.
|
||||
This will retain LSI compatibility magic and mitigate performance issues.
|
||||
As an example, Solus has already [integrated the patch](https://dev.solus-project.com/R927:afa5b639e8a9b62618457a304d1e6fb42a9f2066).
|
||||
|
||||
The long term solution is to remove this burden from non-Solus Linux distributions, and for the Solus & LSI projects to
|
||||
provide a specialised runtime & strict LSI build via third party mechanisms so that all this work only needs doing once.
|
||||
This will help ensure the same gaming experience regardless of Linux distribution, remove all compatibility issues, and
|
||||
any pressures on distributions. Additionally this will allow even distributions not supporting multilib to provide a
|
||||
curated and well integrated gaming runtime.
|
||||
|
||||
|
||||
`* Some names may be claimed as the property of others.`
|
||||
+27
-2
@@ -1,12 +1,12 @@
|
||||
project(
|
||||
'linux-steam-integration',
|
||||
['c'],
|
||||
version: '0.4',
|
||||
version: '0.6',
|
||||
license: [
|
||||
'LGPL-2.1',
|
||||
],
|
||||
default_options: [
|
||||
'c_std=c99',
|
||||
'c_std=c11',
|
||||
],
|
||||
)
|
||||
|
||||
@@ -41,8 +41,11 @@ prefix = get_option('prefix')
|
||||
datadir = join_paths(prefix, get_option('datadir'))
|
||||
vendordir = join_paths(datadir, 'defaults', meson.project_name())
|
||||
sysconfdir = join_paths(prefix, get_option('sysconfdir'))
|
||||
localedir = join_paths(prefix, get_option('localedir'))
|
||||
cdata.set_quoted('SYSTEMCONFDIR', sysconfdir)
|
||||
cdata.set_quoted('VENDORDIR', vendordir)
|
||||
cdata.set_quoted('LOCALEDIR', localedir)
|
||||
cdata.set_quoted('GETTEXT_PACKAGE', meson.project_name())
|
||||
|
||||
# Configurables
|
||||
cdata.set_quoted('LSI_PRELOAD_LIBS', get_option('with-preload-libs'))
|
||||
@@ -58,8 +61,29 @@ if with_libintercept == true
|
||||
cdata.set('HAVE_LIBINTERCEPT', '1')
|
||||
endif
|
||||
|
||||
with_libredirect = get_option('with-libredirect')
|
||||
if with_libredirect == true
|
||||
cdata.set('HAVE_LIBREDIRECT', '1')
|
||||
endif
|
||||
|
||||
with_frontend = get_option('with-frontend')
|
||||
|
||||
if get_option('with-new-libcxx-abi') == true
|
||||
cdata.set('LSI_USE_NEW_ABI', '1')
|
||||
endif
|
||||
|
||||
with_libressl_mode = get_option('with-libressl-mode')
|
||||
if with_libressl_mode == 'native'
|
||||
cdata.set('LSI_LIBRESSL_MODE_NATIVE', '1')
|
||||
cdata.set('LSI_OVERRIDE_LIBRESSL', '1')
|
||||
elif with_libressl_mode == 'shim'
|
||||
cdata.set('LSI_LIBRESSL_MODE_SHIM', '1')
|
||||
cdata.set('LSI_OVERRIDE_LIBRESSL', '1')
|
||||
cdata.set_quoted('LSI_LIBRESSL_SUFFIX', get_option('with-libressl-suffix'))
|
||||
else
|
||||
message('LibreSSL mode isn\'t configured which may impact security')
|
||||
endif
|
||||
|
||||
config_h = configure_file(
|
||||
configuration: cdata,
|
||||
output: 'config.h',
|
||||
@@ -68,3 +92,4 @@ config_h_dir = include_directories('.')
|
||||
|
||||
subdir('data')
|
||||
subdir('src')
|
||||
subdir('po')
|
||||
|
||||
+8
-1
@@ -1,7 +1,14 @@
|
||||
option('with-shim', type : 'combo', choices : ['replacement', 'co-exist', 'none'], default: 'replacement',
|
||||
option('with-shim', type : 'combo', choices : ['replacement', 'co-exist', 'none'], value: 'replacement',
|
||||
description : 'control how the shim is deployed')
|
||||
option('with-steam-binary', type: 'string', description: 'Set the path to the Steam binary', value: '/usr/lib/steam/steam')
|
||||
option('with-frontend', type: 'boolean', description: 'Build the LSI Settings UI', value: false)
|
||||
option('with-preload-libs', type: 'string', description: 'Colon separated list of libraries required to launch Steam games',
|
||||
value: '/usr/\$LIB/libxcb.so.1:/usr/\$LIB/libX11.so.6:/usr/\$LIB/libstdc++.so.6')
|
||||
option('with-libintercept', type: 'boolean', description: 'Enable libintercept library for controlling Steam linking', value: true)
|
||||
option('with-libredirect', type: 'boolean', description: 'Enable libredirect library for fine-tuning Steam games', value: true)
|
||||
option('with-new-libcxx-abi', type: 'boolean', description: 'Enable when using the new libstdc++ ABI', value: false)
|
||||
|
||||
option('with-libressl-mode', type: 'combo', choices: ['native', 'shim', 'none'], value: 'none',
|
||||
description: 'Control how LibreSSL replacements are performed')
|
||||
option('with-libressl-suffix', type: 'string', value: '-libressl',
|
||||
description: 'Suffix for shim LibreSSL library when using --with-libressl-mode=shim')
|
||||
|
||||
+2
-2
@@ -2,11 +2,11 @@
|
||||
set -e
|
||||
|
||||
if [[ ! -d buildroot/build32 ]]; then
|
||||
CC="gcc -m32" linux32 meson buildroot/build32 --prefix=/usr --sysconfdir=/etc --datadir=/usr/share --libdir=/usr/lib32 -Dwith-shim=none
|
||||
CC="gcc -m32" linux32 meson buildroot/build32 -Dwith-libressl-mode=shim --prefix=/usr --sysconfdir=/etc --datadir=/usr/share --libdir=/usr/lib32 -Dwith-shim=none -Dwith-new-libcxx-abi=true --buildtype debugoptimized
|
||||
fi
|
||||
|
||||
if [[ ! -d buildroot/build64 ]]; then
|
||||
meson buildroot/build64 --prefix=/usr --sysconfdir=/etc --datadir=/usr/share --libdir=/usr/lib64 -Dwith-shim=replacement -Dwith-steam-binary=/usr/lib64/steam/steam -Dwith-frontend=true
|
||||
meson buildroot/build64 -Dwith-libressl-mode=shim --prefix=/usr --sysconfdir=/etc --datadir=/usr/share --libdir=/usr/lib64 -Dwith-shim=replacement -Dwith-steam-binary=/usr/lib64/steam/steam -Dwith-frontend=true -Dwith-new-libcxx-abi=true --buildtype debugoptimized
|
||||
fi
|
||||
|
||||
ninja -C buildroot/build32
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@ git submodule init
|
||||
git submodule update
|
||||
|
||||
# Script for ikey because he went with meson. *shrug*
|
||||
VERSION="0.4"
|
||||
VERSION="0.6"
|
||||
NAME="linux-steam-integration"
|
||||
git-archive-all.sh --format tar --prefix ${NAME}-${VERSION}/ --verbose -t HEAD ${NAME}-${VERSION}.tar
|
||||
xz -9 "${NAME}-${VERSION}.tar"
|
||||
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
ar
|
||||
ca_ES
|
||||
ca
|
||||
cs
|
||||
da_DK
|
||||
de
|
||||
en_GB
|
||||
es_419
|
||||
es_AR
|
||||
es_MX
|
||||
es_PE
|
||||
fi
|
||||
fr_FR
|
||||
he
|
||||
id_ID
|
||||
it_IT
|
||||
ne_NP
|
||||
nl_BE
|
||||
nl_NL
|
||||
pl_PL
|
||||
pl
|
||||
pt_BR
|
||||
pt_PT
|
||||
ro_RO
|
||||
sv_SE
|
||||
zh_CN
|
||||
@@ -0,0 +1 @@
|
||||
src/frontend/main-window.c
|
||||
@@ -0,0 +1,81 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the linux-steam-integration package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: linux-steam-integration\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2017-11-05 19:28+0000\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: Ahmed Lemine <aljakany@gmail.com>, 2017\n"
|
||||
"Language-Team: Arabic (https://www.transifex.com/solus-project/teams/68407/ar/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: ar\n"
|
||||
"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n"
|
||||
|
||||
#. Sort out window bits
|
||||
#. header label
|
||||
#: src/frontend/main-window.c:131 src/frontend/main-window.c:148
|
||||
msgid "Linux Steam® Integration"
|
||||
msgstr "دمج ستيم® ولينكس"
|
||||
|
||||
#: src/frontend/main-window.c:162
|
||||
msgid ""
|
||||
"Control the behaviour of the Steam client and games. Settings will not take "
|
||||
"effect until the Steam Client is restarted. Use the 'Exit Steam' option to "
|
||||
"ensure it closes."
|
||||
msgstr ""
|
||||
"التحكم في سلوك عميل ستيم والألعاب. لن تكون الإعدادات سارية المفعول ما لم يتم"
|
||||
" إعادة تشغيل عميل ستيم. استخدم خيار \"الخروج من ستيم\" للتأكد من إغلاقه."
|
||||
|
||||
#: src/frontend/main-window.c:191
|
||||
msgid "Use native runtime"
|
||||
msgstr "استخدم زمن تشغيل أصيل"
|
||||
|
||||
#: src/frontend/main-window.c:192
|
||||
msgid "Switch between the native runtime and the bundled Steam runtime."
|
||||
msgstr "بدّل بين زمن التشغيل الأصيل وزمن التشغيل المرفق مع ستيم."
|
||||
|
||||
#. Label is shown to indicate we can't enable 32-bit option
|
||||
#: src/frontend/main-window.c:201
|
||||
msgid "This option has been disabled as the system is already 32-bit"
|
||||
msgstr "تم تعطيل هذا الخيار لأن النظام أساساً ذو معمارية 32 بت"
|
||||
|
||||
#: src/frontend/main-window.c:205
|
||||
msgid ""
|
||||
"This may workaround some broken games, but will disable the Steam store "
|
||||
"browser."
|
||||
msgstr "قد يصلح هذا بعض الألعاب المعطلة، لكن سيعطل متصفح متجر ستيم."
|
||||
|
||||
#: src/frontend/main-window.c:210
|
||||
msgid "Force 32-bit mode for Steam"
|
||||
msgstr "افرض وضع 32 بت لستيم"
|
||||
|
||||
#: src/frontend/main-window.c:218
|
||||
msgid "Use the intercept library"
|
||||
msgstr "استخدم مكتبة الاعتراض"
|
||||
|
||||
#: src/frontend/main-window.c:219
|
||||
msgid ""
|
||||
"Force Steam applications to use more native libraries to maximise "
|
||||
"compatibility."
|
||||
msgstr ""
|
||||
"أجبر تطبيقات ستيم على استخدام مزيد من المكتبات الأصيلة لزيادة التوافق إلى "
|
||||
"أقصى درجة."
|
||||
|
||||
#: src/frontend/main-window.c:228
|
||||
msgid "Use the redirect library"
|
||||
msgstr "استخدم مكتبة إعادة التوجيه"
|
||||
|
||||
#: src/frontend/main-window.c:229
|
||||
msgid "Override system calls to fix known bugs in some Linux ports."
|
||||
msgstr "تجاوز استدعاءات النظام لإصلاح مشكلات معروفة في بعض نسخ لينكس."
|
||||
|
||||
#: src/frontend/main-window.c:383
|
||||
msgid "Failed to save configuration"
|
||||
msgstr "فشل في حفظ الإعدادات"
|
||||
@@ -0,0 +1,86 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the linux-steam-integration package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: linux-steam-integration\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2017-11-05 19:28+0000\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: Davidmp <medipas@gmail.com>, 2017\n"
|
||||
"Language-Team: Catalan (https://www.transifex.com/solus-project/teams/68407/ca/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: ca\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#. Sort out window bits
|
||||
#. header label
|
||||
#: src/frontend/main-window.c:131 src/frontend/main-window.c:148
|
||||
msgid "Linux Steam® Integration"
|
||||
msgstr "Integració de Linux Steam®"
|
||||
|
||||
#: src/frontend/main-window.c:162
|
||||
msgid ""
|
||||
"Control the behaviour of the Steam client and games. Settings will not take "
|
||||
"effect until the Steam Client is restarted. Use the 'Exit Steam' option to "
|
||||
"ensure it closes."
|
||||
msgstr ""
|
||||
"Controleu el comportament del client i dels jocs d'Steam. La configuració no"
|
||||
" tindrà efecte fins que no es reiniciï el client d'Steam. Useu l'opció "
|
||||
"\"Surt de l'Steam\" per assegurar-vos que es tanqui."
|
||||
|
||||
#: src/frontend/main-window.c:191
|
||||
msgid "Use native runtime"
|
||||
msgstr "Usa l'entorn d'execució natiu"
|
||||
|
||||
#: src/frontend/main-window.c:192
|
||||
msgid "Switch between the native runtime and the bundled Steam runtime."
|
||||
msgstr "Canvieu entre l'entorn natiu i l'entorn d'Steam agrupat."
|
||||
|
||||
#. Label is shown to indicate we can't enable 32-bit option
|
||||
#: src/frontend/main-window.c:201
|
||||
msgid "This option has been disabled as the system is already 32-bit"
|
||||
msgstr "Aquesta opció s'ha inhabilitat ja que el sistema ja és de 32 bits."
|
||||
|
||||
#: src/frontend/main-window.c:205
|
||||
msgid ""
|
||||
"This may workaround some broken games, but will disable the Steam store "
|
||||
"browser."
|
||||
msgstr ""
|
||||
"Això pot solucionar alguns jocs trencats, però inhabilitarà el navegador de "
|
||||
"la botiga d'Steam."
|
||||
|
||||
#: src/frontend/main-window.c:210
|
||||
msgid "Force 32-bit mode for Steam"
|
||||
msgstr "Força el mode de 32 bits per a l'Steam"
|
||||
|
||||
#: src/frontend/main-window.c:218
|
||||
msgid "Use the intercept library"
|
||||
msgstr "Usa la biblioteca d'intercepció"
|
||||
|
||||
#: src/frontend/main-window.c:219
|
||||
msgid ""
|
||||
"Force Steam applications to use more native libraries to maximise "
|
||||
"compatibility."
|
||||
msgstr ""
|
||||
"Força que les aplicacions de l'Steam usin més biblioteques natives per "
|
||||
"maximitzar la compatibilitat."
|
||||
|
||||
#: src/frontend/main-window.c:228
|
||||
msgid "Use the redirect library"
|
||||
msgstr "Usa la biblioteca de redirecció"
|
||||
|
||||
#: src/frontend/main-window.c:229
|
||||
msgid "Override system calls to fix known bugs in some Linux ports."
|
||||
msgstr ""
|
||||
"Anul·la les crides de sistema per corregir errors coneguts en algunes "
|
||||
"versions de Linux."
|
||||
|
||||
#: src/frontend/main-window.c:383
|
||||
msgid "Failed to save configuration"
|
||||
msgstr "Ha fallat desar la configuració"
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the linux-steam-integration package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: linux-steam-integration\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2017-11-05 19:28+0000\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: Davidmp <medipas@gmail.com>, 2017\n"
|
||||
"Language-Team: Catalan (Spain) (https://www.transifex.com/solus-project/teams/68407/ca_ES/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: ca_ES\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#. Sort out window bits
|
||||
#. header label
|
||||
#: src/frontend/main-window.c:131 src/frontend/main-window.c:148
|
||||
msgid "Linux Steam® Integration"
|
||||
msgstr "Integració de Linux Steam®"
|
||||
|
||||
#: src/frontend/main-window.c:162
|
||||
msgid ""
|
||||
"Control the behaviour of the Steam client and games. Settings will not take "
|
||||
"effect until the Steam Client is restarted. Use the 'Exit Steam' option to "
|
||||
"ensure it closes."
|
||||
msgstr ""
|
||||
"Controleu el comportament del client i dels jocs d'Steam. La configuració no"
|
||||
" tindrà efecte fins que no es reiniciï el client d'Steam. Useu l'opció "
|
||||
"\"Surt de l'Steam\" per assegurar-vos que es tanqui."
|
||||
|
||||
#: src/frontend/main-window.c:191
|
||||
msgid "Use native runtime"
|
||||
msgstr "Usa l'entorn d'execució natiu"
|
||||
|
||||
#: src/frontend/main-window.c:192
|
||||
msgid "Switch between the native runtime and the bundled Steam runtime."
|
||||
msgstr "Canvieu entre l'entorn natiu i l'entorn d'Steam agrupat."
|
||||
|
||||
#. Label is shown to indicate we can't enable 32-bit option
|
||||
#: src/frontend/main-window.c:201
|
||||
msgid "This option has been disabled as the system is already 32-bit"
|
||||
msgstr "Aquesta opció s'ha inhabilitat ja que el sistema ja és de 32 bits."
|
||||
|
||||
#: src/frontend/main-window.c:205
|
||||
msgid ""
|
||||
"This may workaround some broken games, but will disable the Steam store "
|
||||
"browser."
|
||||
msgstr ""
|
||||
"Això pot solucionar alguns jocs trencats, però inhabilitarà el navegador de "
|
||||
"la botiga d'Steam."
|
||||
|
||||
#: src/frontend/main-window.c:210
|
||||
msgid "Force 32-bit mode for Steam"
|
||||
msgstr "Força el mode de 32 bits per a l'Steam"
|
||||
|
||||
#: src/frontend/main-window.c:218
|
||||
msgid "Use the intercept library"
|
||||
msgstr "Usa la biblioteca d'intercepció"
|
||||
|
||||
#: src/frontend/main-window.c:219
|
||||
msgid ""
|
||||
"Force Steam applications to use more native libraries to maximise "
|
||||
"compatibility."
|
||||
msgstr ""
|
||||
"Força que les aplicacions de l'Steam usin més biblioteques natives per "
|
||||
"maximitzar la compatibilitat."
|
||||
|
||||
#: src/frontend/main-window.c:228
|
||||
msgid "Use the redirect library"
|
||||
msgstr "Usa la biblioteca de redirecció"
|
||||
|
||||
#: src/frontend/main-window.c:229
|
||||
msgid "Override system calls to fix known bugs in some Linux ports."
|
||||
msgstr ""
|
||||
"Anul·la les crides de sistema per corregir errors coneguts en algunes "
|
||||
"versions de Linux."
|
||||
|
||||
#: src/frontend/main-window.c:383
|
||||
msgid "Failed to save configuration"
|
||||
msgstr "Ha fallat desar la configuració"
|
||||
@@ -0,0 +1,85 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the linux-steam-integration package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: linux-steam-integration\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2017-11-05 19:28+0000\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: Ondřej Pucholt <o.pucholt@windowslive.com>, 2017\n"
|
||||
"Language-Team: Czech (https://www.transifex.com/solus-project/teams/68407/cs/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: cs\n"
|
||||
"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
|
||||
|
||||
#. Sort out window bits
|
||||
#. header label
|
||||
#: src/frontend/main-window.c:131 src/frontend/main-window.c:148
|
||||
msgid "Linux Steam® Integration"
|
||||
msgstr "Integrace služby Steam®"
|
||||
|
||||
#: src/frontend/main-window.c:162
|
||||
msgid ""
|
||||
"Control the behaviour of the Steam client and games. Settings will not take "
|
||||
"effect until the Steam Client is restarted. Use the 'Exit Steam' option to "
|
||||
"ensure it closes."
|
||||
msgstr ""
|
||||
"Ovládá chování her a klienta služby Steam. Změny nastavení se projeví až po "
|
||||
"restartování služby. Pro její zaručené ukončení zvolte možnost \"Ukončit "
|
||||
"službu Steam\"."
|
||||
|
||||
#: src/frontend/main-window.c:191
|
||||
msgid "Use native runtime"
|
||||
msgstr "Používat nativní běhové prostředí"
|
||||
|
||||
#: src/frontend/main-window.c:192
|
||||
msgid "Switch between the native runtime and the bundled Steam runtime."
|
||||
msgstr "Přepíná mezi nativním a přibaleným běhovým prostředím služby Steam."
|
||||
|
||||
#. Label is shown to indicate we can't enable 32-bit option
|
||||
#: src/frontend/main-window.c:201
|
||||
msgid "This option has been disabled as the system is already 32-bit"
|
||||
msgstr "Tato volba není dostupná, protože systém už je 32bitový"
|
||||
|
||||
#: src/frontend/main-window.c:205
|
||||
msgid ""
|
||||
"This may workaround some broken games, but will disable the Steam store "
|
||||
"browser."
|
||||
msgstr ""
|
||||
"Umožňuje obejít některé problémy se hrami, ale deaktivuje prohlížeč obchodu "
|
||||
"služby Steam."
|
||||
|
||||
#: src/frontend/main-window.c:210
|
||||
msgid "Force 32-bit mode for Steam"
|
||||
msgstr "Přinutit službu Steam používat 32bitový režim"
|
||||
|
||||
#: src/frontend/main-window.c:218
|
||||
msgid "Use the intercept library"
|
||||
msgstr "Používat knihovnu pro zachytávání"
|
||||
|
||||
#: src/frontend/main-window.c:219
|
||||
msgid ""
|
||||
"Force Steam applications to use more native libraries to maximise "
|
||||
"compatibility."
|
||||
msgstr ""
|
||||
"Přinutit programy ze služby Steam používat více nativních knihoven pro "
|
||||
"zajištění maximální kompatibility."
|
||||
|
||||
#: src/frontend/main-window.c:228
|
||||
msgid "Use the redirect library"
|
||||
msgstr "Používat knihovnu pro přesměrování"
|
||||
|
||||
#: src/frontend/main-window.c:229
|
||||
msgid "Override system calls to fix known bugs in some Linux ports."
|
||||
msgstr ""
|
||||
"Přepsáním systémových volání opravit známé chyby v linuxových portech her."
|
||||
|
||||
#: src/frontend/main-window.c:383
|
||||
msgid "Failed to save configuration"
|
||||
msgstr "Uložení konfigurace selhalo"
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the linux-steam-integration package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: linux-steam-integration\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2017-11-05 19:28+0000\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: Yavuznie <y.z@live.dk>, 2017\n"
|
||||
"Language-Team: Danish (Denmark) (https://www.transifex.com/solus-project/teams/68407/da_DK/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: da_DK\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#. Sort out window bits
|
||||
#. header label
|
||||
#: src/frontend/main-window.c:131 src/frontend/main-window.c:148
|
||||
msgid "Linux Steam® Integration"
|
||||
msgstr "Integration med Linux Steam®"
|
||||
|
||||
#: src/frontend/main-window.c:162
|
||||
msgid ""
|
||||
"Control the behaviour of the Steam client and games. Settings will not take "
|
||||
"effect until the Steam Client is restarted. Use the 'Exit Steam' option to "
|
||||
"ensure it closes."
|
||||
msgstr ""
|
||||
"Styr opførslen af Steam-klienten og spil. Indstillingerne vil ikke træde i "
|
||||
"kraft før Steam-klienten er blevet genstartet. Brug 'Afslut Steam' for af "
|
||||
"sikre at programmet lukkes."
|
||||
|
||||
#: src/frontend/main-window.c:191
|
||||
msgid "Use native runtime"
|
||||
msgstr "Brug nativ runtime"
|
||||
|
||||
#: src/frontend/main-window.c:192
|
||||
msgid "Switch between the native runtime and the bundled Steam runtime."
|
||||
msgstr "Skift mellem nativ runtime og den runtime som følger med Steam."
|
||||
|
||||
#. Label is shown to indicate we can't enable 32-bit option
|
||||
#: src/frontend/main-window.c:201
|
||||
msgid "This option has been disabled as the system is already 32-bit"
|
||||
msgstr ""
|
||||
"Denne mulighed er blevet deaktiveret eftersom systemet allerede er 32-bit"
|
||||
|
||||
#: src/frontend/main-window.c:205
|
||||
msgid ""
|
||||
"This may workaround some broken games, but will disable the Steam store "
|
||||
"browser."
|
||||
msgstr ""
|
||||
"Det løser muligvis problemer for nogle ødelagte spil, til gengæld "
|
||||
"deaktiveres Steam butik-browseren."
|
||||
|
||||
#: src/frontend/main-window.c:210
|
||||
msgid "Force 32-bit mode for Steam"
|
||||
msgstr "Tving 32-bit-tilstand for Steam"
|
||||
|
||||
#: src/frontend/main-window.c:218
|
||||
msgid "Use the intercept library"
|
||||
msgstr "Brug intercept-biblioteket"
|
||||
|
||||
#: src/frontend/main-window.c:219
|
||||
msgid ""
|
||||
"Force Steam applications to use more native libraries to maximise "
|
||||
"compatibility."
|
||||
msgstr ""
|
||||
"Tving Steam-programmer til at bruge flere native biblioteker for at "
|
||||
"maksimere kompatibilitet."
|
||||
|
||||
#: src/frontend/main-window.c:228
|
||||
msgid "Use the redirect library"
|
||||
msgstr "Brug redirect-biblioteket"
|
||||
|
||||
#: src/frontend/main-window.c:229
|
||||
msgid "Override system calls to fix known bugs in some Linux ports."
|
||||
msgstr "Tilsidesæt systemkald for at rette kendte fejl i nogle Linux-porte."
|
||||
|
||||
#: src/frontend/main-window.c:383
|
||||
msgid "Failed to save configuration"
|
||||
msgstr "Kunne ikke gemme konfiguration"
|
||||
@@ -0,0 +1,88 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the linux-steam-integration package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: linux-steam-integration\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2017-11-05 19:28+0000\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: Thomas Staudinger <staudi.kaos@gmail.com>, 2017\n"
|
||||
"Language-Team: German (https://www.transifex.com/solus-project/teams/68407/de/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: de\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#. Sort out window bits
|
||||
#. header label
|
||||
#: src/frontend/main-window.c:131 src/frontend/main-window.c:148
|
||||
msgid "Linux Steam® Integration"
|
||||
msgstr "Linux Steam® Integration"
|
||||
|
||||
#: src/frontend/main-window.c:162
|
||||
msgid ""
|
||||
"Control the behaviour of the Steam client and games. Settings will not take "
|
||||
"effect until the Steam Client is restarted. Use the 'Exit Steam' option to "
|
||||
"ensure it closes."
|
||||
msgstr ""
|
||||
"Beeinflusse das Verhalten des Steam-Clients und von Spielen. Die "
|
||||
"Einstellungen werden erst aktiv, nachdem der Steam-Client neu gestartet "
|
||||
"wurde. Nutze 'Steam beenden', um sicherzugehen, dass es beendet wird."
|
||||
|
||||
#: src/frontend/main-window.c:191
|
||||
msgid "Use native runtime"
|
||||
msgstr "Nutze native Laufzeitumgebung"
|
||||
|
||||
#: src/frontend/main-window.c:192
|
||||
msgid "Switch between the native runtime and the bundled Steam runtime."
|
||||
msgstr ""
|
||||
"Wechsle zwischen der nativen Laufzeitumgebung und der Steam-"
|
||||
"Laufzeitumgebung."
|
||||
|
||||
#. Label is shown to indicate we can't enable 32-bit option
|
||||
#: src/frontend/main-window.c:201
|
||||
msgid "This option has been disabled as the system is already 32-bit"
|
||||
msgstr "Diese Option ist deaktiviert, da dies bereits ein 32-bit System ist."
|
||||
|
||||
#: src/frontend/main-window.c:205
|
||||
msgid ""
|
||||
"This may workaround some broken games, but will disable the Steam store "
|
||||
"browser."
|
||||
msgstr ""
|
||||
"Dies behebt möglicherweise Fehler bei kaputten Steam-Spielen, wird aber den "
|
||||
"Steam Store Browser deaktivieren."
|
||||
|
||||
#: src/frontend/main-window.c:210
|
||||
msgid "Force 32-bit mode for Steam"
|
||||
msgstr "Erzwinge 32-bit-Modus für Steam"
|
||||
|
||||
#: src/frontend/main-window.c:218
|
||||
msgid "Use the intercept library"
|
||||
msgstr "Nutze die Intercept-Bibliothek"
|
||||
|
||||
#: src/frontend/main-window.c:219
|
||||
msgid ""
|
||||
"Force Steam applications to use more native libraries to maximise "
|
||||
"compatibility."
|
||||
msgstr ""
|
||||
"Zwinge Steam Anwendungen dazu, mehr native Bibliotheken zu nutzen, um die "
|
||||
"Kompatibilität zu maximieren."
|
||||
|
||||
#: src/frontend/main-window.c:228
|
||||
msgid "Use the redirect library"
|
||||
msgstr "Nutze die Redirect-Bibliothek"
|
||||
|
||||
#: src/frontend/main-window.c:229
|
||||
msgid "Override system calls to fix known bugs in some Linux ports."
|
||||
msgstr ""
|
||||
"Überschreibe Systemcalls, um bekannte Bugs in manchen Linux-Ports zu "
|
||||
"beheben."
|
||||
|
||||
#: src/frontend/main-window.c:383
|
||||
msgid "Failed to save configuration"
|
||||
msgstr "Konfiguration konnte nicht gespeichert werden"
|
||||
+83
@@ -0,0 +1,83 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the linux-steam-integration package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: linux-steam-integration\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2017-11-05 19:28+0000\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: \n"
|
||||
|
||||
#. Sort out window bits
|
||||
#. header label
|
||||
#: src/frontend/main-window.c:131 src/frontend/main-window.c:148
|
||||
msgid "Linux Steam® Integration"
|
||||
msgstr "Linux Steam® Integration"
|
||||
|
||||
#: src/frontend/main-window.c:162
|
||||
msgid ""
|
||||
"Control the behaviour of the Steam client and games. Settings will not take "
|
||||
"effect until the Steam Client is restarted. Use the 'Exit Steam' option to "
|
||||
"ensure it closes."
|
||||
msgstr ""
|
||||
"Control the behaviour of the Steam client and games. Settings will not take "
|
||||
"effect until the Steam Client is restarted. Use the 'Exit Steam' option to "
|
||||
"ensure it closes."
|
||||
|
||||
#: src/frontend/main-window.c:191
|
||||
msgid "Use native runtime"
|
||||
msgstr "Use native runtime"
|
||||
|
||||
#: src/frontend/main-window.c:192
|
||||
msgid "Switch between the native runtime and the bundled Steam runtime."
|
||||
msgstr "Switch between the native runtime and the bundled Steam runtime."
|
||||
|
||||
#. Label is shown to indicate we can't enable 32-bit option
|
||||
#: src/frontend/main-window.c:201
|
||||
msgid "This option has been disabled as the system is already 32-bit"
|
||||
msgstr "This option has been disabled as the system is already 32-bit"
|
||||
|
||||
#: src/frontend/main-window.c:205
|
||||
msgid ""
|
||||
"This may workaround some broken games, but will disable the Steam store "
|
||||
"browser."
|
||||
msgstr ""
|
||||
"This may workaround some broken games, but will disable the Steam store "
|
||||
"browser."
|
||||
|
||||
#: src/frontend/main-window.c:210
|
||||
msgid "Force 32-bit mode for Steam"
|
||||
msgstr "Force 32-bit mode for Steam"
|
||||
|
||||
#: src/frontend/main-window.c:218
|
||||
msgid "Use the intercept library"
|
||||
msgstr "Use the intercept library"
|
||||
|
||||
#: src/frontend/main-window.c:219
|
||||
msgid ""
|
||||
"Force Steam applications to use more native libraries to maximise "
|
||||
"compatibility."
|
||||
msgstr ""
|
||||
"Force Steam applications to use more native libraries to maximise "
|
||||
"compatibility."
|
||||
|
||||
#: src/frontend/main-window.c:228
|
||||
msgid "Use the redirect library"
|
||||
msgstr "Use the redirect library"
|
||||
|
||||
#: src/frontend/main-window.c:229
|
||||
msgid "Override system calls to fix known bugs in some Linux ports."
|
||||
msgstr "Override system calls to fix known bugs in some Linux ports."
|
||||
|
||||
#: src/frontend/main-window.c:383
|
||||
msgid "Failed to save configuration"
|
||||
msgstr "Failed to save configuration"
|
||||
@@ -0,0 +1,87 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the linux-steam-integration package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: linux-steam-integration\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2017-11-05 19:28+0000\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: Víctor Rodríguez <vhugo642@gmail.com>, 2017\n"
|
||||
"Language-Team: Spanish (Latin America) (https://www.transifex.com/solus-project/teams/68407/es_419/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: es_419\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#. Sort out window bits
|
||||
#. header label
|
||||
#: src/frontend/main-window.c:131 src/frontend/main-window.c:148
|
||||
msgid "Linux Steam® Integration"
|
||||
msgstr "Linux Steam® Integration"
|
||||
|
||||
#: src/frontend/main-window.c:162
|
||||
msgid ""
|
||||
"Control the behaviour of the Steam client and games. Settings will not take "
|
||||
"effect until the Steam Client is restarted. Use the 'Exit Steam' option to "
|
||||
"ensure it closes."
|
||||
msgstr ""
|
||||
"Controla el comportamiento del cliente y los juegos de Steam. La "
|
||||
"configuración no tendrá efecto hasta que el cliente de Steam se reinicie. "
|
||||
"Use la opción 'Salir de Steam' para asegurarse de que se cierre."
|
||||
|
||||
#: src/frontend/main-window.c:191
|
||||
msgid "Use native runtime"
|
||||
msgstr "Usar tiempo de ejecución del sistema"
|
||||
|
||||
#: src/frontend/main-window.c:192
|
||||
msgid "Switch between the native runtime and the bundled Steam runtime."
|
||||
msgstr ""
|
||||
"Cambie entre el tiempo de ejecución del sistema y el incluido por Steam"
|
||||
|
||||
#. Label is shown to indicate we can't enable 32-bit option
|
||||
#: src/frontend/main-window.c:201
|
||||
msgid "This option has been disabled as the system is already 32-bit"
|
||||
msgstr "Esta opción ha sido desactivada ya que el sistema ya es de 32-bit"
|
||||
|
||||
#: src/frontend/main-window.c:205
|
||||
msgid ""
|
||||
"This may workaround some broken games, but will disable the Steam store "
|
||||
"browser."
|
||||
msgstr ""
|
||||
"Esto puede mejorar algunos juegos rotos, pero desactivará el navegador de la"
|
||||
" tienda de Steam."
|
||||
|
||||
#: src/frontend/main-window.c:210
|
||||
msgid "Force 32-bit mode for Steam"
|
||||
msgstr "Forzar modo de 32-bit para Steam"
|
||||
|
||||
#: src/frontend/main-window.c:218
|
||||
msgid "Use the intercept library"
|
||||
msgstr "Utilizar la biblioteca de intercepción"
|
||||
|
||||
#: src/frontend/main-window.c:219
|
||||
msgid ""
|
||||
"Force Steam applications to use more native libraries to maximise "
|
||||
"compatibility."
|
||||
msgstr ""
|
||||
"Forzar a las aplicaciones de Steam a usar más librerías nativas para "
|
||||
"maximizar la compatibilidad."
|
||||
|
||||
#: src/frontend/main-window.c:228
|
||||
msgid "Use the redirect library"
|
||||
msgstr "Utilizar la biblioteca de redirección"
|
||||
|
||||
#: src/frontend/main-window.c:229
|
||||
msgid "Override system calls to fix known bugs in some Linux ports."
|
||||
msgstr ""
|
||||
"Anular las llamadas del sistema para solucionar algunos problemas conocidos "
|
||||
"en adaptaciones de Linux."
|
||||
|
||||
#: src/frontend/main-window.c:383
|
||||
msgid "Failed to save configuration"
|
||||
msgstr "Error al guardar la configuración"
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the linux-steam-integration package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: linux-steam-integration\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2017-11-05 19:28+0000\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: Abe Linux <m.delvalle01@gmail.com>, 2017\n"
|
||||
"Language-Team: Spanish (Argentina) (https://www.transifex.com/solus-project/teams/68407/es_AR/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: es_AR\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#. Sort out window bits
|
||||
#. header label
|
||||
#: src/frontend/main-window.c:131 src/frontend/main-window.c:148
|
||||
msgid "Linux Steam® Integration"
|
||||
msgstr "Integración Steam® para Linux"
|
||||
|
||||
#: src/frontend/main-window.c:162
|
||||
msgid ""
|
||||
"Control the behaviour of the Steam client and games. Settings will not take "
|
||||
"effect until the Steam Client is restarted. Use the 'Exit Steam' option to "
|
||||
"ensure it closes."
|
||||
msgstr ""
|
||||
"Controla el comportamiento del cliente y juegos de Steam. Las preferencias "
|
||||
"no tomarán efecto hasta que el cliente de Steam sea reiniciado. Usa la "
|
||||
"opción \"Salir de Steam\" para asegurarte de que se cierre."
|
||||
|
||||
#: src/frontend/main-window.c:191
|
||||
msgid "Use native runtime"
|
||||
msgstr "Usar el entorno nativo"
|
||||
|
||||
#: src/frontend/main-window.c:192
|
||||
msgid "Switch between the native runtime and the bundled Steam runtime."
|
||||
msgstr "Cambiar entre el entorno nativo y el incluido por Steam."
|
||||
|
||||
#. Label is shown to indicate we can't enable 32-bit option
|
||||
#: src/frontend/main-window.c:201
|
||||
msgid "This option has been disabled as the system is already 32-bit"
|
||||
msgstr "Esta opción ha sido deshabilitada dado que el sistema ya es de 32-bit"
|
||||
|
||||
#: src/frontend/main-window.c:205
|
||||
msgid ""
|
||||
"This may workaround some broken games, but will disable the Steam store "
|
||||
"browser."
|
||||
msgstr ""
|
||||
"Esto puede solucionar algunos juegos que no funcionen, pero deshabilitará la"
|
||||
" tienda Steam."
|
||||
|
||||
#: src/frontend/main-window.c:210
|
||||
msgid "Force 32-bit mode for Steam"
|
||||
msgstr "Forzar modo 32-bit para Steam"
|
||||
|
||||
#: src/frontend/main-window.c:218
|
||||
msgid "Use the intercept library"
|
||||
msgstr "Usar la librería intercept"
|
||||
|
||||
#: src/frontend/main-window.c:219
|
||||
msgid ""
|
||||
"Force Steam applications to use more native libraries to maximise "
|
||||
"compatibility."
|
||||
msgstr ""
|
||||
"Forzar a las aplicaciones de Steam a utilizar más librerías nativas para "
|
||||
"maximizar la compatibilidad."
|
||||
|
||||
#: src/frontend/main-window.c:228
|
||||
msgid "Use the redirect library"
|
||||
msgstr "Usar la librería intercept"
|
||||
|
||||
#: src/frontend/main-window.c:229
|
||||
msgid "Override system calls to fix known bugs in some Linux ports."
|
||||
msgstr ""
|
||||
"Sobrescribir llamadas de sistema para corregir problemas conocidos en "
|
||||
"algunas adaptaciones de juegos para Linux."
|
||||
|
||||
#: src/frontend/main-window.c:383
|
||||
msgid "Failed to save configuration"
|
||||
msgstr "Falló en guardar la configuración"
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the linux-steam-integration package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: linux-steam-integration\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2017-11-05 19:28+0000\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: Fernando Macias <FernandoMaciasR@yahoo.com.mx>, 2017\n"
|
||||
"Language-Team: Spanish (Mexico) (https://www.transifex.com/solus-project/teams/68407/es_MX/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: es_MX\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#. Sort out window bits
|
||||
#. header label
|
||||
#: src/frontend/main-window.c:131 src/frontend/main-window.c:148
|
||||
msgid "Linux Steam® Integration"
|
||||
msgstr "Integración de Steam® con Linux"
|
||||
|
||||
#: src/frontend/main-window.c:162
|
||||
msgid ""
|
||||
"Control the behaviour of the Steam client and games. Settings will not take "
|
||||
"effect until the Steam Client is restarted. Use the 'Exit Steam' option to "
|
||||
"ensure it closes."
|
||||
msgstr ""
|
||||
"Controla el comportamiento del cliente y los juegos de Steam. Los ajustes no"
|
||||
" tendrán efecto hasta que el cliente de Steam sea reiniciado. Use la opción "
|
||||
"de 'Salir de Steam' para asegurarse de que sea cerrado."
|
||||
|
||||
#: src/frontend/main-window.c:191
|
||||
msgid "Use native runtime"
|
||||
msgstr "Usar tiempo de ejecución nativo"
|
||||
|
||||
#: src/frontend/main-window.c:192
|
||||
msgid "Switch between the native runtime and the bundled Steam runtime."
|
||||
msgstr ""
|
||||
"Cambia entre el tiempo de ejecución nativo y el tiempo de ejecución incluido"
|
||||
" en Steam."
|
||||
|
||||
#. Label is shown to indicate we can't enable 32-bit option
|
||||
#: src/frontend/main-window.c:201
|
||||
msgid "This option has been disabled as the system is already 32-bit"
|
||||
msgstr ""
|
||||
"Esta opción ha sido deshabilitada debido a que el sistema ya es de 32 bits"
|
||||
|
||||
#: src/frontend/main-window.c:205
|
||||
msgid ""
|
||||
"This may workaround some broken games, but will disable the Steam store "
|
||||
"browser."
|
||||
msgstr ""
|
||||
"Esto puede solucionar algunos juegos que no funcionen, pero desactivará el "
|
||||
"navegador de la tienda de Steam."
|
||||
|
||||
#: src/frontend/main-window.c:210
|
||||
msgid "Force 32-bit mode for Steam"
|
||||
msgstr "Forzar modo de 32 bits para Steam"
|
||||
|
||||
#: src/frontend/main-window.c:218
|
||||
msgid "Use the intercept library"
|
||||
msgstr "Usar la librería de intercepción"
|
||||
|
||||
#: src/frontend/main-window.c:219
|
||||
msgid ""
|
||||
"Force Steam applications to use more native libraries to maximise "
|
||||
"compatibility."
|
||||
msgstr ""
|
||||
"Forzar a las aplicaciones de Steam a que utilizen más librerias nativas para"
|
||||
" maximizar la compatibilidad."
|
||||
|
||||
#: src/frontend/main-window.c:228
|
||||
msgid "Use the redirect library"
|
||||
msgstr "Usar la librería de redirección"
|
||||
|
||||
#: src/frontend/main-window.c:229
|
||||
msgid "Override system calls to fix known bugs in some Linux ports."
|
||||
msgstr ""
|
||||
"Anular las llamadas del sistema para corregir errores conocidos en algunos "
|
||||
"puertos Linux."
|
||||
|
||||
#: src/frontend/main-window.c:383
|
||||
msgid "Failed to save configuration"
|
||||
msgstr "No se pudo guardar la configuración"
|
||||
+87
@@ -0,0 +1,87 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the linux-steam-integration package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: linux-steam-integration\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2017-11-05 19:28+0000\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: Víctor Rodríguez <vhugo642@gmail.com>, 2017\n"
|
||||
"Language-Team: Spanish (Peru) (https://www.transifex.com/solus-project/teams/68407/es_PE/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: es_PE\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#. Sort out window bits
|
||||
#. header label
|
||||
#: src/frontend/main-window.c:131 src/frontend/main-window.c:148
|
||||
msgid "Linux Steam® Integration"
|
||||
msgstr "Linux Steam® Integration"
|
||||
|
||||
#: src/frontend/main-window.c:162
|
||||
msgid ""
|
||||
"Control the behaviour of the Steam client and games. Settings will not take "
|
||||
"effect until the Steam Client is restarted. Use the 'Exit Steam' option to "
|
||||
"ensure it closes."
|
||||
msgstr ""
|
||||
"Controla el comportamiento del cliente y los juegos de Steam. La "
|
||||
"configuración no tendrá efecto hasta que el cliente de Steam se reinicie. "
|
||||
"Use la opción 'Salir de Steam' para asegurarse de que se cierre."
|
||||
|
||||
#: src/frontend/main-window.c:191
|
||||
msgid "Use native runtime"
|
||||
msgstr "Usar tiempo de ejecución del sistema"
|
||||
|
||||
#: src/frontend/main-window.c:192
|
||||
msgid "Switch between the native runtime and the bundled Steam runtime."
|
||||
msgstr ""
|
||||
"Cambie entre el tiempo de ejecución del sistema y el incluido por Steam"
|
||||
|
||||
#. Label is shown to indicate we can't enable 32-bit option
|
||||
#: src/frontend/main-window.c:201
|
||||
msgid "This option has been disabled as the system is already 32-bit"
|
||||
msgstr "Esta opción ha sido desactivada ya que el sistema ya es de 32-bit"
|
||||
|
||||
#: src/frontend/main-window.c:205
|
||||
msgid ""
|
||||
"This may workaround some broken games, but will disable the Steam store "
|
||||
"browser."
|
||||
msgstr ""
|
||||
"Esto puede mejorar algunos juegos rotos, pero desactivará el navegador de la"
|
||||
" tienda de Steam."
|
||||
|
||||
#: src/frontend/main-window.c:210
|
||||
msgid "Force 32-bit mode for Steam"
|
||||
msgstr "Forzar modo de 32-bit para Steam"
|
||||
|
||||
#: src/frontend/main-window.c:218
|
||||
msgid "Use the intercept library"
|
||||
msgstr "Usar la librería de intercepción"
|
||||
|
||||
#: src/frontend/main-window.c:219
|
||||
msgid ""
|
||||
"Force Steam applications to use more native libraries to maximise "
|
||||
"compatibility."
|
||||
msgstr ""
|
||||
"Forzar a las aplicaciones de Steam a usar más librerías del sistema para "
|
||||
"maximizar la compatibilidad."
|
||||
|
||||
#: src/frontend/main-window.c:228
|
||||
msgid "Use the redirect library"
|
||||
msgstr "Usar la librería de intercepción"
|
||||
|
||||
#: src/frontend/main-window.c:229
|
||||
msgid "Override system calls to fix known bugs in some Linux ports."
|
||||
msgstr ""
|
||||
"Anular las llamadas del sistema para solucionar algunos problemas conocidos "
|
||||
"en adaptaciones de Linux."
|
||||
|
||||
#: src/frontend/main-window.c:383
|
||||
msgid "Failed to save configuration"
|
||||
msgstr "Error al guardar la configuración"
|
||||
@@ -0,0 +1,88 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the linux-steam-integration package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: linux-steam-integration\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2017-11-05 19:28+0000\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: Kim Kröger <kroger.kim@gmail.com>, 2017\n"
|
||||
"Language-Team: Finnish (https://www.transifex.com/solus-project/teams/68407/fi/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: fi\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#. Sort out window bits
|
||||
#. header label
|
||||
#: src/frontend/main-window.c:131 src/frontend/main-window.c:148
|
||||
msgid "Linux Steam® Integration"
|
||||
msgstr "Linux Steam® Integraatio"
|
||||
|
||||
#: src/frontend/main-window.c:162
|
||||
msgid ""
|
||||
"Control the behaviour of the Steam client and games. Settings will not take "
|
||||
"effect until the Steam Client is restarted. Use the 'Exit Steam' option to "
|
||||
"ensure it closes."
|
||||
msgstr ""
|
||||
"Ohjaa Steam-sovelluksen ja -pelien toimintaa. Asetukset tulevat voimaan "
|
||||
"vasta Steam-sovelluksen uudelleenkäynnistyksen myötä. Käytä \"Sulje Steam\" "
|
||||
"-toimintoa varmistaaksesi sen sulkeutumisen."
|
||||
|
||||
#: src/frontend/main-window.c:191
|
||||
msgid "Use native runtime"
|
||||
msgstr "Käytä paikallista ohjelmakirjastoa"
|
||||
|
||||
#: src/frontend/main-window.c:192
|
||||
msgid "Switch between the native runtime and the bundled Steam runtime."
|
||||
msgstr ""
|
||||
"Vaihda paikallisen ohjelmakirjaston ja Steamin mukana tulevan "
|
||||
"ohjelmakirjaston välillä."
|
||||
|
||||
#. Label is shown to indicate we can't enable 32-bit option
|
||||
#: src/frontend/main-window.c:201
|
||||
msgid "This option has been disabled as the system is already 32-bit"
|
||||
msgstr "Tämä asetus ei ole käytössä, koska järjestelmä on jo 32-bittinen"
|
||||
|
||||
#: src/frontend/main-window.c:205
|
||||
msgid ""
|
||||
"This may workaround some broken games, but will disable the Steam store "
|
||||
"browser."
|
||||
msgstr ""
|
||||
"Tämä voi väliaikaisesti korjata joidenkin pelien yhteensopivuusongelmat, "
|
||||
"mutta ottaa myös Steamin Kaupan pois käytöstä."
|
||||
|
||||
#: src/frontend/main-window.c:210
|
||||
msgid "Force 32-bit mode for Steam"
|
||||
msgstr "Pakottaa 32-bittisen tilan Steamille"
|
||||
|
||||
#: src/frontend/main-window.c:218
|
||||
msgid "Use the intercept library"
|
||||
msgstr "Käytä intercept-kirjastoa"
|
||||
|
||||
#: src/frontend/main-window.c:219
|
||||
msgid ""
|
||||
"Force Steam applications to use more native libraries to maximise "
|
||||
"compatibility."
|
||||
msgstr ""
|
||||
"Pakottaa Steamin sovellusten käyttämään enemmän paikallisia "
|
||||
"ohjelmakirjastoja yhteensopivuuden maksimoimiseksi."
|
||||
|
||||
#: src/frontend/main-window.c:228
|
||||
msgid "Use the redirect library"
|
||||
msgstr "Käytä redirect-kirjastoa"
|
||||
|
||||
#: src/frontend/main-window.c:229
|
||||
msgid "Override system calls to fix known bugs in some Linux ports."
|
||||
msgstr ""
|
||||
"Ohittaa järjestelmän kutsut tunnettujen ongelmien korjaamiseksi joissakin "
|
||||
"peleissä."
|
||||
|
||||
#: src/frontend/main-window.c:383
|
||||
msgid "Failed to save configuration"
|
||||
msgstr "Asetusten tallentaminen epäonnistui"
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the linux-steam-integration package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: linux-steam-integration\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2017-11-05 19:28+0000\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: Serge <vanmechelen.serge@gmail.com>, 2017\n"
|
||||
"Language-Team: French (France) (https://www.transifex.com/solus-project/teams/68407/fr_FR/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: fr_FR\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
|
||||
#. Sort out window bits
|
||||
#. header label
|
||||
#: src/frontend/main-window.c:131 src/frontend/main-window.c:148
|
||||
msgid "Linux Steam® Integration"
|
||||
msgstr "Intégration Steam® Linux"
|
||||
|
||||
#: src/frontend/main-window.c:162
|
||||
msgid ""
|
||||
"Control the behaviour of the Steam client and games. Settings will not take "
|
||||
"effect until the Steam Client is restarted. Use the 'Exit Steam' option to "
|
||||
"ensure it closes."
|
||||
msgstr ""
|
||||
"Contrôle le comportement du client et des jeux Steam. Les paramètres ne "
|
||||
"prendront effet qu'après le redémarrage du client Steam. Utilisez l'option "
|
||||
"'Quitter Steam' pour vous assurer que l'application a bien été arrêtée."
|
||||
|
||||
#: src/frontend/main-window.c:191
|
||||
msgid "Use native runtime"
|
||||
msgstr "Utiliser l'environnement d'exécution natif"
|
||||
|
||||
#: src/frontend/main-window.c:192
|
||||
msgid "Switch between the native runtime and the bundled Steam runtime."
|
||||
msgstr ""
|
||||
"Basculer entre l'environnement d'exécution natif et l'environnement "
|
||||
"d'exécution Steam."
|
||||
|
||||
#. Label is shown to indicate we can't enable 32-bit option
|
||||
#: src/frontend/main-window.c:201
|
||||
msgid "This option has been disabled as the system is already 32-bit"
|
||||
msgstr "Cette option a été désactivée car le système est déjà en 32-bit"
|
||||
|
||||
#: src/frontend/main-window.c:205
|
||||
msgid ""
|
||||
"This may workaround some broken games, but will disable the Steam store "
|
||||
"browser."
|
||||
msgstr ""
|
||||
"Ceci permet d'éviter des problèmes rencontrés avec certains jeux mais "
|
||||
"désactive le magasin Steam."
|
||||
|
||||
#: src/frontend/main-window.c:210
|
||||
msgid "Force 32-bit mode for Steam"
|
||||
msgstr "Forcer le mode 32-bit pour Steam"
|
||||
|
||||
#: src/frontend/main-window.c:218
|
||||
msgid "Use the intercept library"
|
||||
msgstr "Utiliser la bibliothèque d'interception"
|
||||
|
||||
#: src/frontend/main-window.c:219
|
||||
msgid ""
|
||||
"Force Steam applications to use more native libraries to maximise "
|
||||
"compatibility."
|
||||
msgstr ""
|
||||
"Obliger les applications Steam à utiliser davantage de bibliothèques natives"
|
||||
" pour maximiser la compatibilité."
|
||||
|
||||
#: src/frontend/main-window.c:228
|
||||
msgid "Use the redirect library"
|
||||
msgstr "Utiliser la bibliothèque de redirection"
|
||||
|
||||
#: src/frontend/main-window.c:229
|
||||
msgid "Override system calls to fix known bugs in some Linux ports."
|
||||
msgstr ""
|
||||
"Remplacer les appels système pour corriger les bogues connus pour certains "
|
||||
"ports sous Linux."
|
||||
|
||||
#: src/frontend/main-window.c:383
|
||||
msgid "Failed to save configuration"
|
||||
msgstr "Echec dans la sauvegarde de la configuration"
|
||||
@@ -0,0 +1,81 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the linux-steam-integration package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: linux-steam-integration\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2017-11-05 19:28+0000\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: Moshe Sh <7moshe7@gmail.com>, 2017\n"
|
||||
"Language-Team: Hebrew (https://www.transifex.com/solus-project/teams/68407/he/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: he\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#. Sort out window bits
|
||||
#. header label
|
||||
#: src/frontend/main-window.c:131 src/frontend/main-window.c:148
|
||||
msgid "Linux Steam® Integration"
|
||||
msgstr "שילוב לינוקס וסטים "
|
||||
|
||||
#: src/frontend/main-window.c:162
|
||||
msgid ""
|
||||
"Control the behaviour of the Steam client and games. Settings will not take "
|
||||
"effect until the Steam Client is restarted. Use the 'Exit Steam' option to "
|
||||
"ensure it closes."
|
||||
msgstr ""
|
||||
"שליטה על ההתנהגות של Steam Client ומשחקים. ההגדרות לא יכנסו לתוקף עד להפעלה "
|
||||
"מחדש של Steam Client. מומלץ להשתמש באופציה 'יציאה מסטים' על מנת לוודא שנסגר."
|
||||
|
||||
#: src/frontend/main-window.c:191
|
||||
msgid "Use native runtime"
|
||||
msgstr "שימוש בהרצה מקומית"
|
||||
|
||||
#: src/frontend/main-window.c:192
|
||||
msgid "Switch between the native runtime and the bundled Steam runtime."
|
||||
msgstr "החלפה בין הרצה מקומית להרצה של סטים."
|
||||
|
||||
#. Label is shown to indicate we can't enable 32-bit option
|
||||
#: src/frontend/main-window.c:201
|
||||
msgid "This option has been disabled as the system is already 32-bit"
|
||||
msgstr "אפשרות זו הושבתה מאחר שהמערכת כבר 32 סיביות"
|
||||
|
||||
#: src/frontend/main-window.c:205
|
||||
msgid ""
|
||||
"This may workaround some broken games, but will disable the Steam store "
|
||||
"browser."
|
||||
msgstr ""
|
||||
"פעולה זו עשויה לעקוף בעיה של כמה משחקים לא תקינים, אבל ישבית את הדפדפן של "
|
||||
"חנות סטים."
|
||||
|
||||
#: src/frontend/main-window.c:210
|
||||
msgid "Force 32-bit mode for Steam"
|
||||
msgstr "הכרח מצב 32 סיביות עבור סטים"
|
||||
|
||||
#: src/frontend/main-window.c:218
|
||||
msgid "Use the intercept library"
|
||||
msgstr "שימוש בספריית intercept"
|
||||
|
||||
#: src/frontend/main-window.c:219
|
||||
msgid ""
|
||||
"Force Steam applications to use more native libraries to maximise "
|
||||
"compatibility."
|
||||
msgstr "הכרח יישומי סטים להשתמש בספריות מקומיות כדי להגדיל את התאימות."
|
||||
|
||||
#: src/frontend/main-window.c:228
|
||||
msgid "Use the redirect library"
|
||||
msgstr "שימוש בספריית redirect"
|
||||
|
||||
#: src/frontend/main-window.c:229
|
||||
msgid "Override system calls to fix known bugs in some Linux ports."
|
||||
msgstr "מעקף לקריאות המערכת כדי לתקן באגים ידועים בכמה יציאות לינוקס."
|
||||
|
||||
#: src/frontend/main-window.c:383
|
||||
msgid "Failed to save configuration"
|
||||
msgstr "שמירת ההגדרות נכשלה"
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the linux-steam-integration package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: linux-steam-integration\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2017-11-05 19:28+0000\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: Yurizal Susanto <rizal.sagi@gmail.com>, 2017\n"
|
||||
"Language-Team: Indonesian (Indonesia) (https://www.transifex.com/solus-project/teams/68407/id_ID/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: id_ID\n"
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
|
||||
#. Sort out window bits
|
||||
#. header label
|
||||
#: src/frontend/main-window.c:131 src/frontend/main-window.c:148
|
||||
msgid "Linux Steam® Integration"
|
||||
msgstr "Integrasi Steam® Linux"
|
||||
|
||||
#: src/frontend/main-window.c:162
|
||||
msgid ""
|
||||
"Control the behaviour of the Steam client and games. Settings will not take "
|
||||
"effect until the Steam Client is restarted. Use the 'Exit Steam' option to "
|
||||
"ensure it closes."
|
||||
msgstr ""
|
||||
"Atur sifat klien Steam dan permainan. Pengaturan tidak akan berlaku sebelum "
|
||||
"klien Steam dimulai ulang. Gunakan pilihan 'Exit Steam' untuk memastikan "
|
||||
"klien tertutup."
|
||||
|
||||
#: src/frontend/main-window.c:191
|
||||
msgid "Use native runtime"
|
||||
msgstr "Gunakan runtime bawaan"
|
||||
|
||||
#: src/frontend/main-window.c:192
|
||||
msgid "Switch between the native runtime and the bundled Steam runtime."
|
||||
msgstr "Tukar antara runtime bawaan dan runtime yang dibundel Steam"
|
||||
|
||||
#. Label is shown to indicate we can't enable 32-bit option
|
||||
#: src/frontend/main-window.c:201
|
||||
msgid "This option has been disabled as the system is already 32-bit"
|
||||
msgstr "Pilihan ini dimatikan karena sistem sudah 32-bit"
|
||||
|
||||
#: src/frontend/main-window.c:205
|
||||
msgid ""
|
||||
"This may workaround some broken games, but will disable the Steam store "
|
||||
"browser."
|
||||
msgstr ""
|
||||
"Ini bisa menyelesaikan masalah pada beberapa permainan, tapi akan "
|
||||
"menonaktifkan penjelajahan toko Steam."
|
||||
|
||||
#: src/frontend/main-window.c:210
|
||||
msgid "Force 32-bit mode for Steam"
|
||||
msgstr "Paksa mode 32-bit untuk Steam"
|
||||
|
||||
#: src/frontend/main-window.c:218
|
||||
msgid "Use the intercept library"
|
||||
msgstr "Gunakan pustaka pencegat"
|
||||
|
||||
#: src/frontend/main-window.c:219
|
||||
msgid ""
|
||||
"Force Steam applications to use more native libraries to maximise "
|
||||
"compatibility."
|
||||
msgstr ""
|
||||
"Paksa aplikasi Steam untuk menggunakan lebih banyak pustaka bawaan untuk "
|
||||
"memaksimalkan kompabilitas."
|
||||
|
||||
#: src/frontend/main-window.c:228
|
||||
msgid "Use the redirect library"
|
||||
msgstr "Gunakan pustaka pengalihan"
|
||||
|
||||
#: src/frontend/main-window.c:229
|
||||
msgid "Override system calls to fix known bugs in some Linux ports."
|
||||
msgstr ""
|
||||
"Timpa panggilan sistem untuk memperbaiki bug yang diketahui di beberapa port"
|
||||
" Linux."
|
||||
|
||||
#: src/frontend/main-window.c:383
|
||||
msgid "Failed to save configuration"
|
||||
msgstr "Gagal menyimpan konfigurasi"
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the linux-steam-integration package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: linux-steam-integration\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2017-11-05 19:28+0000\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: Fabio Forni <fabio94xx@gmail.com>, 2017\n"
|
||||
"Language-Team: Italian (Italy) (https://www.transifex.com/solus-project/teams/68407/it_IT/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: it_IT\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#. Sort out window bits
|
||||
#. header label
|
||||
#: src/frontend/main-window.c:131 src/frontend/main-window.c:148
|
||||
msgid "Linux Steam® Integration"
|
||||
msgstr "Linux Steam® Integration"
|
||||
|
||||
#: src/frontend/main-window.c:162
|
||||
msgid ""
|
||||
"Control the behaviour of the Steam client and games. Settings will not take "
|
||||
"effect until the Steam Client is restarted. Use the 'Exit Steam' option to "
|
||||
"ensure it closes."
|
||||
msgstr ""
|
||||
"Controlla il comportamento dei giochi e del client Steam. Le impostazioni "
|
||||
"non avranno effetto finché il client Steam non sarà riavviato. Usa l'opzione"
|
||||
" \"Esci da Steam\" per assicurarti che venga davvero chiuso."
|
||||
|
||||
#: src/frontend/main-window.c:191
|
||||
msgid "Use native runtime"
|
||||
msgstr "Use ambiente di runtime nativo"
|
||||
|
||||
#: src/frontend/main-window.c:192
|
||||
msgid "Switch between the native runtime and the bundled Steam runtime."
|
||||
msgstr "Scegli tra l'ambiente di runtime nativo e quello integrato in Steam."
|
||||
|
||||
#. Label is shown to indicate we can't enable 32-bit option
|
||||
#: src/frontend/main-window.c:201
|
||||
msgid "This option has been disabled as the system is already 32-bit"
|
||||
msgstr "Questa opzione è disabilitata perché il sistema è già a 32-bit"
|
||||
|
||||
#: src/frontend/main-window.c:205
|
||||
msgid ""
|
||||
"This may workaround some broken games, but will disable the Steam store "
|
||||
"browser."
|
||||
msgstr ""
|
||||
"Può correggere alcuni giochi non funzionanti, ma disabiliterà la navigazione"
|
||||
" nel negozio Steam."
|
||||
|
||||
#: src/frontend/main-window.c:210
|
||||
msgid "Force 32-bit mode for Steam"
|
||||
msgstr "Forza Steam a 32-bit"
|
||||
|
||||
#: src/frontend/main-window.c:218
|
||||
msgid "Use the intercept library"
|
||||
msgstr "Usa la libreria di intercettazione"
|
||||
|
||||
#: src/frontend/main-window.c:219
|
||||
msgid ""
|
||||
"Force Steam applications to use more native libraries to maximise "
|
||||
"compatibility."
|
||||
msgstr ""
|
||||
"Forza le applicazioni di Steam a usare ancor più librerie native per "
|
||||
"massimizzare la compatibilità."
|
||||
|
||||
#: src/frontend/main-window.c:228
|
||||
msgid "Use the redirect library"
|
||||
msgstr "Usa la libreria di redirezione"
|
||||
|
||||
#: src/frontend/main-window.c:229
|
||||
msgid "Override system calls to fix known bugs in some Linux ports."
|
||||
msgstr ""
|
||||
"Sostituisce le chiamate di sistema per correggere i bug noti di alcuni "
|
||||
"porting su Linux."
|
||||
|
||||
#: src/frontend/main-window.c:383
|
||||
msgid "Failed to save configuration"
|
||||
msgstr "Errore durante il salvataggio della configurazione"
|
||||
@@ -0,0 +1,76 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the linux-steam-integration package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: linux-steam-integration\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2017-11-05 19:28+0000\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"Language: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#. Sort out window bits
|
||||
#. header label
|
||||
#: src/frontend/main-window.c:131 src/frontend/main-window.c:148
|
||||
msgid "Linux Steam® Integration"
|
||||
msgstr ""
|
||||
|
||||
#: src/frontend/main-window.c:162
|
||||
msgid ""
|
||||
"Control the behaviour of the Steam client and games. Settings will not take "
|
||||
"effect until the Steam Client is restarted. Use the 'Exit Steam' option to "
|
||||
"ensure it closes."
|
||||
msgstr ""
|
||||
|
||||
#: src/frontend/main-window.c:191
|
||||
msgid "Use native runtime"
|
||||
msgstr ""
|
||||
|
||||
#: src/frontend/main-window.c:192
|
||||
msgid "Switch between the native runtime and the bundled Steam runtime."
|
||||
msgstr ""
|
||||
|
||||
#. Label is shown to indicate we can't enable 32-bit option
|
||||
#: src/frontend/main-window.c:201
|
||||
msgid "This option has been disabled as the system is already 32-bit"
|
||||
msgstr ""
|
||||
|
||||
#: src/frontend/main-window.c:205
|
||||
msgid ""
|
||||
"This may workaround some broken games, but will disable the Steam store "
|
||||
"browser."
|
||||
msgstr ""
|
||||
|
||||
#: src/frontend/main-window.c:210
|
||||
msgid "Force 32-bit mode for Steam"
|
||||
msgstr ""
|
||||
|
||||
#: src/frontend/main-window.c:218
|
||||
msgid "Use the intercept library"
|
||||
msgstr ""
|
||||
|
||||
#: src/frontend/main-window.c:219
|
||||
msgid ""
|
||||
"Force Steam applications to use more native libraries to maximise "
|
||||
"compatibility."
|
||||
msgstr ""
|
||||
|
||||
#: src/frontend/main-window.c:228
|
||||
msgid "Use the redirect library"
|
||||
msgstr ""
|
||||
|
||||
#: src/frontend/main-window.c:229
|
||||
msgid "Override system calls to fix known bugs in some Linux ports."
|
||||
msgstr ""
|
||||
|
||||
#: src/frontend/main-window.c:383
|
||||
msgid "Failed to save configuration"
|
||||
msgstr ""
|
||||
@@ -0,0 +1,3 @@
|
||||
i18n = import('i18n')
|
||||
|
||||
i18n.gettext(meson.project_name(), preset: 'glib')
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the linux-steam-integration package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: linux-steam-integration\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2017-11-05 19:28+0000\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: Rabin Adhikari <rabin.adk1@gmail.com>, 2017\n"
|
||||
"Language-Team: Nepali (Nepal) (https://www.transifex.com/solus-project/teams/68407/ne_NP/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: ne_NP\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#. Sort out window bits
|
||||
#. header label
|
||||
#: src/frontend/main-window.c:131 src/frontend/main-window.c:148
|
||||
msgid "Linux Steam® Integration"
|
||||
msgstr "लिनक्स स्टिम® एकीकरण"
|
||||
|
||||
#: src/frontend/main-window.c:162
|
||||
msgid ""
|
||||
"Control the behaviour of the Steam client and games. Settings will not take "
|
||||
"effect until the Steam Client is restarted. Use the 'Exit Steam' option to "
|
||||
"ensure it closes."
|
||||
msgstr ""
|
||||
"स्टिम क्लाइन्ट र खेलहरूको व्यवहार नियन्त्रण गर्नुहोस्। स्टिम क्लाइन्ट पुन: "
|
||||
"सुरु नभएसम्म सेटिङहरूमा प्रभाव पर्ने छैन। यो बन्द गर्न सुनिश्चित गर्नको लागि"
|
||||
" 'बाहिर निस्कनुहोस्' विकल्प प्रयोग गर्नुहोस्।"
|
||||
|
||||
#: src/frontend/main-window.c:191
|
||||
msgid "Use native runtime"
|
||||
msgstr "मूल रनटाइम प्रयोग गर्नुहोस्"
|
||||
|
||||
#: src/frontend/main-window.c:192
|
||||
msgid "Switch between the native runtime and the bundled Steam runtime."
|
||||
msgstr "मूल रनटाइम र बन्डल स्टिम रनटाइम बीच स्विच गर्नुहोस्।"
|
||||
|
||||
#. Label is shown to indicate we can't enable 32-bit option
|
||||
#: src/frontend/main-window.c:201
|
||||
msgid "This option has been disabled as the system is already 32-bit"
|
||||
msgstr "यो विकल्प असक्षम गरिएको छ किनभने प्रणाली पहिले नै 32-बिट छ"
|
||||
|
||||
#: src/frontend/main-window.c:205
|
||||
msgid ""
|
||||
"This may workaround some broken games, but will disable the Steam store "
|
||||
"browser."
|
||||
msgstr ""
|
||||
"यसले केही बिच्छेद खेलहरूको गर्न वैकल्पिक समाधान गर्न सक्दछ, तर स्टिम भण्डार "
|
||||
"ब्राउजर असक्षम पार्नेछ।"
|
||||
|
||||
#: src/frontend/main-window.c:210
|
||||
msgid "Force 32-bit mode for Steam"
|
||||
msgstr "स्टिमको लागि 32-बिट मोड बल गर्नुहोस्"
|
||||
|
||||
#: src/frontend/main-window.c:218
|
||||
msgid "Use the intercept library"
|
||||
msgstr "इन्टरसेप्ट लाइब्रेरी प्रयोग गर्नुहोस्"
|
||||
|
||||
#: src/frontend/main-window.c:219
|
||||
msgid ""
|
||||
"Force Steam applications to use more native libraries to maximise "
|
||||
"compatibility."
|
||||
msgstr ""
|
||||
"अनुकूलता अधिकतम गर्नका लागी थप मूल पुस्तकालयहरू प्रयोग गर्न स्टिम "
|
||||
"एप्लिकेसनहरूलाई बल गर्नुहोस्।"
|
||||
|
||||
#: src/frontend/main-window.c:228
|
||||
msgid "Use the redirect library"
|
||||
msgstr "पुन: निर्देशित पुस्तकालय प्रयोग गर्नुहोस्"
|
||||
|
||||
#: src/frontend/main-window.c:229
|
||||
msgid "Override system calls to fix known bugs in some Linux ports."
|
||||
msgstr ""
|
||||
"केहि लिनक्स पोर्टहरूमा ज्ञात बगहरू ठीक गर्न प्रणाली कलहरू ओभरराइड गर्नुहोस्।"
|
||||
|
||||
#: src/frontend/main-window.c:383
|
||||
msgid "Failed to save configuration"
|
||||
msgstr "कन्फिगरेसन सुरक्षित गर्न असफल भयो"
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the linux-steam-integration package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: linux-steam-integration\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2017-11-05 19:28+0000\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: Geert Verheyde <geert.verheyde@gmail.com>, 2017\n"
|
||||
"Language-Team: Dutch (Belgium) (https://www.transifex.com/solus-project/teams/68407/nl_BE/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: nl_BE\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#. Sort out window bits
|
||||
#. header label
|
||||
#: src/frontend/main-window.c:131 src/frontend/main-window.c:148
|
||||
msgid "Linux Steam® Integration"
|
||||
msgstr "Linux Steam® Integration"
|
||||
|
||||
#: src/frontend/main-window.c:162
|
||||
msgid ""
|
||||
"Control the behaviour of the Steam client and games. Settings will not take "
|
||||
"effect until the Steam Client is restarted. Use the 'Exit Steam' option to "
|
||||
"ensure it closes."
|
||||
msgstr ""
|
||||
"Beheer het gedrag van de Steam Client en games. Wijzigingen zijn pas "
|
||||
"effectief na het herstarten van de Steam Client. Gebruik de \"Exit Steam\" "
|
||||
"optie om definitief af te sluiten."
|
||||
|
||||
#: src/frontend/main-window.c:191
|
||||
msgid "Use native runtime"
|
||||
msgstr "Gebruik de systeemeigen runtime"
|
||||
|
||||
#: src/frontend/main-window.c:192
|
||||
msgid "Switch between the native runtime and the bundled Steam runtime."
|
||||
msgstr "Wissel tussen de systeemeigen runtime en de gebundelde Steam runtime"
|
||||
|
||||
#. Label is shown to indicate we can't enable 32-bit option
|
||||
#: src/frontend/main-window.c:201
|
||||
msgid "This option has been disabled as the system is already 32-bit"
|
||||
msgstr "Deze optie werd uitgezet omdat het systeem reeds 32-bit is"
|
||||
|
||||
#: src/frontend/main-window.c:205
|
||||
msgid ""
|
||||
"This may workaround some broken games, but will disable the Steam store "
|
||||
"browser."
|
||||
msgstr ""
|
||||
"Dit kan gebroken games doen werken, maar zal de Steam store browser "
|
||||
"uitzetten."
|
||||
|
||||
#: src/frontend/main-window.c:210
|
||||
msgid "Force 32-bit mode for Steam"
|
||||
msgstr "Forceer 32-bit modus voor Steam."
|
||||
|
||||
#: src/frontend/main-window.c:218
|
||||
msgid "Use the intercept library"
|
||||
msgstr "Gebruik de opvangende bibliotheek"
|
||||
|
||||
#: src/frontend/main-window.c:219
|
||||
msgid ""
|
||||
"Force Steam applications to use more native libraries to maximise "
|
||||
"compatibility."
|
||||
msgstr ""
|
||||
"Forceer Steam toepassingen meer systeemeigen bibliotheken te gebruiken om de"
|
||||
" compatibiliteit te maximaliseren"
|
||||
|
||||
#: src/frontend/main-window.c:228
|
||||
msgid "Use the redirect library"
|
||||
msgstr "Gebruik de omleidende bibliotheek"
|
||||
|
||||
#: src/frontend/main-window.c:229
|
||||
msgid "Override system calls to fix known bugs in some Linux ports."
|
||||
msgstr ""
|
||||
"Negeer systeemoproepen om gekende fouten te herstellen in bepaalde Linux "
|
||||
"ports"
|
||||
|
||||
#: src/frontend/main-window.c:383
|
||||
msgid "Failed to save configuration"
|
||||
msgstr "Het opslaan van de configuratie is mislukt."
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the linux-steam-integration package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: linux-steam-integration\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2017-11-05 19:28+0000\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: Heimen Stoffels <vistausss@outlook.com>, 2017\n"
|
||||
"Language-Team: Dutch (Netherlands) (https://www.transifex.com/solus-project/teams/68407/nl_NL/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: nl_NL\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#. Sort out window bits
|
||||
#. header label
|
||||
#: src/frontend/main-window.c:131 src/frontend/main-window.c:148
|
||||
msgid "Linux Steam® Integration"
|
||||
msgstr "Linux Steam® Integration"
|
||||
|
||||
#: src/frontend/main-window.c:162
|
||||
msgid ""
|
||||
"Control the behaviour of the Steam client and games. Settings will not take "
|
||||
"effect until the Steam Client is restarted. Use the 'Exit Steam' option to "
|
||||
"ensure it closes."
|
||||
msgstr ""
|
||||
"Beheer het gedrag van de Steam-client en spellen. De wijzigingen zijn pas "
|
||||
"effectief na het herstarten van de Steam-client. Gebruik de \"Steam "
|
||||
"afsluiten\"-optie om Steam definitief af te sluiten."
|
||||
|
||||
#: src/frontend/main-window.c:191
|
||||
msgid "Use native runtime"
|
||||
msgstr "Gebruik de systeemeigen runtime"
|
||||
|
||||
#: src/frontend/main-window.c:192
|
||||
msgid "Switch between the native runtime and the bundled Steam runtime."
|
||||
msgstr "Wissel tussen de systeemeigen runtime en de gebundelde Steam runtime"
|
||||
|
||||
#. Label is shown to indicate we can't enable 32-bit option
|
||||
#: src/frontend/main-window.c:201
|
||||
msgid "This option has been disabled as the system is already 32-bit"
|
||||
msgstr "Deze optie is uitgeschakeld omdat het systeem reeds 32-bit is"
|
||||
|
||||
#: src/frontend/main-window.c:205
|
||||
msgid ""
|
||||
"This may workaround some broken games, but will disable the Steam store "
|
||||
"browser."
|
||||
msgstr ""
|
||||
"Dit kan gebroken spellen doen werken, maar zal de Steam store browser "
|
||||
"uitschakelen."
|
||||
|
||||
#: src/frontend/main-window.c:210
|
||||
msgid "Force 32-bit mode for Steam"
|
||||
msgstr "Forceer 32-bitmodus voor Steam"
|
||||
|
||||
#: src/frontend/main-window.c:218
|
||||
msgid "Use the intercept library"
|
||||
msgstr "Gebruik de opvangende bibliotheek"
|
||||
|
||||
#: src/frontend/main-window.c:219
|
||||
msgid ""
|
||||
"Force Steam applications to use more native libraries to maximise "
|
||||
"compatibility."
|
||||
msgstr ""
|
||||
"Forceer Steam-toepassingen meer systeemeigen bibliotheken te gebruiken om de"
|
||||
" compatibiliteit te maximaliseren."
|
||||
|
||||
#: src/frontend/main-window.c:228
|
||||
msgid "Use the redirect library"
|
||||
msgstr "Gebruik de omleidende bibliotheek"
|
||||
|
||||
#: src/frontend/main-window.c:229
|
||||
msgid "Override system calls to fix known bugs in some Linux ports."
|
||||
msgstr ""
|
||||
"Negeer systeemoproepen om bekende fouten te herstellen in bepaalde Linux-"
|
||||
"ports"
|
||||
|
||||
#: src/frontend/main-window.c:383
|
||||
msgid "Failed to save configuration"
|
||||
msgstr "Het opslaan van de configuratie is mislukt"
|
||||
@@ -0,0 +1,88 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the linux-steam-integration package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: linux-steam-integration\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2017-11-05 19:28+0000\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: Kacper Herchel <kacperski1@gmail.com>, 2017\n"
|
||||
"Language-Team: Polish (https://www.transifex.com/solus-project/teams/68407/pl/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: pl\n"
|
||||
"Plural-Forms: nplurals=4; plural=(n==1 ? 0 : (n%10>=2 && n%10<=4) && (n%100<12 || n%100>14) ? 1 : n!=1 && (n%10>=0 && n%10<=1) || (n%10>=5 && n%10<=9) || (n%100>=12 && n%100<=14) ? 2 : 3);\n"
|
||||
|
||||
#. Sort out window bits
|
||||
#. header label
|
||||
#: src/frontend/main-window.c:131 src/frontend/main-window.c:148
|
||||
msgid "Linux Steam® Integration"
|
||||
msgstr "Integracja Linuksa ze Steam®"
|
||||
|
||||
#: src/frontend/main-window.c:162
|
||||
msgid ""
|
||||
"Control the behaviour of the Steam client and games. Settings will not take "
|
||||
"effect until the Steam Client is restarted. Use the 'Exit Steam' option to "
|
||||
"ensure it closes."
|
||||
msgstr ""
|
||||
"Zarządzaj zachowaniem klienta Steam i gier. Ustawienia dadzą efekt dopiero "
|
||||
"po zrestartowaniu klienta Steam. Użyj opcji „Zamknij Steam” aby upewnić się,"
|
||||
" że klient został zamknięty."
|
||||
|
||||
#: src/frontend/main-window.c:191
|
||||
msgid "Use native runtime"
|
||||
msgstr "Używaj natywnego środowiska"
|
||||
|
||||
#: src/frontend/main-window.c:192
|
||||
msgid "Switch between the native runtime and the bundled Steam runtime."
|
||||
msgstr ""
|
||||
"Przełączaj się między natywnym środowiskiem uruchomieniowym i wersją "
|
||||
"dołączaną do klienta Steam."
|
||||
|
||||
#. Label is shown to indicate we can't enable 32-bit option
|
||||
#: src/frontend/main-window.c:201
|
||||
msgid "This option has been disabled as the system is already 32-bit"
|
||||
msgstr "Ta opcja została zablokowana, ponieważ używany system jest 32-bitowy"
|
||||
|
||||
#: src/frontend/main-window.c:205
|
||||
msgid ""
|
||||
"This may workaround some broken games, but will disable the Steam store "
|
||||
"browser."
|
||||
msgstr ""
|
||||
"To może naprawić działanie niektórych gier, ale wyłączy możliwość "
|
||||
"przeglądania sklepu Steam."
|
||||
|
||||
#: src/frontend/main-window.c:210
|
||||
msgid "Force 32-bit mode for Steam"
|
||||
msgstr "Wymuś tryb 32-bitowy dla Steam"
|
||||
|
||||
#: src/frontend/main-window.c:218
|
||||
msgid "Use the intercept library"
|
||||
msgstr "Używaj biblioteki przechwytującej"
|
||||
|
||||
#: src/frontend/main-window.c:219
|
||||
msgid ""
|
||||
"Force Steam applications to use more native libraries to maximise "
|
||||
"compatibility."
|
||||
msgstr ""
|
||||
"Wymusza na grach Steam używanie większej ilości natywnych bibliotek, co "
|
||||
"zwiększa kompatybilność."
|
||||
|
||||
#: src/frontend/main-window.c:228
|
||||
msgid "Use the redirect library"
|
||||
msgstr "Używaj biblioteki przekierowującej"
|
||||
|
||||
#: src/frontend/main-window.c:229
|
||||
msgid "Override system calls to fix known bugs in some Linux ports."
|
||||
msgstr ""
|
||||
"Nadpisuje wywołania systemowe, aby poprawić błędy w niektórych linuksowych "
|
||||
"portach."
|
||||
|
||||
#: src/frontend/main-window.c:383
|
||||
msgid "Failed to save configuration"
|
||||
msgstr "Nie udało się zapisać konfiguracji"
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the linux-steam-integration package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: linux-steam-integration\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2017-11-05 19:28+0000\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: Kacper Herchel <kacperski1@gmail.com>, 2017\n"
|
||||
"Language-Team: Polish (Poland) (https://www.transifex.com/solus-project/teams/68407/pl_PL/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: pl_PL\n"
|
||||
"Plural-Forms: nplurals=4; plural=(n==1 ? 0 : (n%10>=2 && n%10<=4) && (n%100<12 || n%100>14) ? 1 : n!=1 && (n%10>=0 && n%10<=1) || (n%10>=5 && n%10<=9) || (n%100>=12 && n%100<=14) ? 2 : 3);\n"
|
||||
|
||||
#. Sort out window bits
|
||||
#. header label
|
||||
#: src/frontend/main-window.c:131 src/frontend/main-window.c:148
|
||||
msgid "Linux Steam® Integration"
|
||||
msgstr "Integracja Linuksa ze Steam®"
|
||||
|
||||
#: src/frontend/main-window.c:162
|
||||
msgid ""
|
||||
"Control the behaviour of the Steam client and games. Settings will not take "
|
||||
"effect until the Steam Client is restarted. Use the 'Exit Steam' option to "
|
||||
"ensure it closes."
|
||||
msgstr ""
|
||||
"Zarządzaj zachowaniem klienta Steam i gier. Ustawienia dadzą efekt dopiero "
|
||||
"po zrestartowaniu klienta Steam. Użyj opcji „Opuść Steam” aby upewnić się, "
|
||||
"że klient został zamknięty."
|
||||
|
||||
#: src/frontend/main-window.c:191
|
||||
msgid "Use native runtime"
|
||||
msgstr "Używaj natywnego środowiska"
|
||||
|
||||
#: src/frontend/main-window.c:192
|
||||
msgid "Switch between the native runtime and the bundled Steam runtime."
|
||||
msgstr ""
|
||||
"Przełączaj się między natywnym środowiskiem uruchomieniowym i wersją "
|
||||
"dołączaną do klienta Steam."
|
||||
|
||||
#. Label is shown to indicate we can't enable 32-bit option
|
||||
#: src/frontend/main-window.c:201
|
||||
msgid "This option has been disabled as the system is already 32-bit"
|
||||
msgstr "Ta opcja została zablokowana, ponieważ używany system jest 32-bitowy"
|
||||
|
||||
#: src/frontend/main-window.c:205
|
||||
msgid ""
|
||||
"This may workaround some broken games, but will disable the Steam store "
|
||||
"browser."
|
||||
msgstr ""
|
||||
"To może naprawić działanie niektórych gier, ale wyłączy możliwość "
|
||||
"przeglądania sklepu Steam."
|
||||
|
||||
#: src/frontend/main-window.c:210
|
||||
msgid "Force 32-bit mode for Steam"
|
||||
msgstr "Wymuś tryb 32-bitowy dla Steam"
|
||||
|
||||
#: src/frontend/main-window.c:218
|
||||
msgid "Use the intercept library"
|
||||
msgstr "Używaj biblioteki przechwytującej"
|
||||
|
||||
#: src/frontend/main-window.c:219
|
||||
msgid ""
|
||||
"Force Steam applications to use more native libraries to maximise "
|
||||
"compatibility."
|
||||
msgstr ""
|
||||
"Wymusza na grach Steam używanie większej ilości natywnych bibliotek, co "
|
||||
"zwiększa kompatybilność."
|
||||
|
||||
#: src/frontend/main-window.c:228
|
||||
msgid "Use the redirect library"
|
||||
msgstr "Używaj biblioteki przekierowującej"
|
||||
|
||||
#: src/frontend/main-window.c:229
|
||||
msgid "Override system calls to fix known bugs in some Linux ports."
|
||||
msgstr ""
|
||||
"Nadpisuje wywołania systemowe, aby poprawić błędy w niektórych linuksowych "
|
||||
"portach."
|
||||
|
||||
#: src/frontend/main-window.c:383
|
||||
msgid "Failed to save configuration"
|
||||
msgstr "Nie udało się zapisać konfiguracji"
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the linux-steam-integration package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: linux-steam-integration\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2017-11-05 19:28+0000\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: Marcelo Ferreira <marceloffdeoliveira@gmail.com>, 2017\n"
|
||||
"Language-Team: Portuguese (Brazil) (https://www.transifex.com/solus-project/teams/68407/pt_BR/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: pt_BR\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
|
||||
#. Sort out window bits
|
||||
#. header label
|
||||
#: src/frontend/main-window.c:131 src/frontend/main-window.c:148
|
||||
msgid "Linux Steam® Integration"
|
||||
msgstr "Integração Steam® com Linux"
|
||||
|
||||
#: src/frontend/main-window.c:162
|
||||
msgid ""
|
||||
"Control the behaviour of the Steam client and games. Settings will not take "
|
||||
"effect until the Steam Client is restarted. Use the 'Exit Steam' option to "
|
||||
"ensure it closes."
|
||||
msgstr ""
|
||||
"Controla o comportamento dos jogos e do programa da Steam. As configurações "
|
||||
"não terão efeito até que o programa seja reiniciado. Utilize a opção \"Sair "
|
||||
"da Steam\" para garantir que ele seja fechado."
|
||||
|
||||
#: src/frontend/main-window.c:191
|
||||
msgid "Use native runtime"
|
||||
msgstr "Usar runtime nativo"
|
||||
|
||||
#: src/frontend/main-window.c:192
|
||||
msgid "Switch between the native runtime and the bundled Steam runtime."
|
||||
msgstr "Alternar entre o runtime nativo e o incluso da Steam."
|
||||
|
||||
#. Label is shown to indicate we can't enable 32-bit option
|
||||
#: src/frontend/main-window.c:201
|
||||
msgid "This option has been disabled as the system is already 32-bit"
|
||||
msgstr "Esta opção foi desativada, uma vez que o sistema já é de 32-bits"
|
||||
|
||||
#: src/frontend/main-window.c:205
|
||||
msgid ""
|
||||
"This may workaround some broken games, but will disable the Steam store "
|
||||
"browser."
|
||||
msgstr ""
|
||||
"Isto pode funcionar em alguns jogos defeituosos, mas irá desativar o "
|
||||
"navegador da loja da Steam."
|
||||
|
||||
#: src/frontend/main-window.c:210
|
||||
msgid "Force 32-bit mode for Steam"
|
||||
msgstr "Forçar modo 32-bits para a Steam"
|
||||
|
||||
#: src/frontend/main-window.c:218
|
||||
msgid "Use the intercept library"
|
||||
msgstr "Usar a biblioteca de interceptação"
|
||||
|
||||
#: src/frontend/main-window.c:219
|
||||
msgid ""
|
||||
"Force Steam applications to use more native libraries to maximise "
|
||||
"compatibility."
|
||||
msgstr ""
|
||||
"Forçar aplicativos da Steam a usar mais bibliotecas nativas para maximizar a"
|
||||
" compatibilidade."
|
||||
|
||||
#: src/frontend/main-window.c:228
|
||||
msgid "Use the redirect library"
|
||||
msgstr "Usar a biblioteca de redirecionamento"
|
||||
|
||||
#: src/frontend/main-window.c:229
|
||||
msgid "Override system calls to fix known bugs in some Linux ports."
|
||||
msgstr ""
|
||||
"Sobrescrever chamadas do sistema para corrigir bugs conhecidos em algumas "
|
||||
"adaptações para Linux."
|
||||
|
||||
#: src/frontend/main-window.c:383
|
||||
msgid "Failed to save configuration"
|
||||
msgstr "Falha ao salvar configuração"
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the linux-steam-integration package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: linux-steam-integration\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2017-11-05 19:28+0000\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: Christophe Silva <christophesilva80@gmail.com>, 2017\n"
|
||||
"Language-Team: Portuguese (Portugal) (https://www.transifex.com/solus-project/teams/68407/pt_PT/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: pt_PT\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#. Sort out window bits
|
||||
#. header label
|
||||
#: src/frontend/main-window.c:131 src/frontend/main-window.c:148
|
||||
msgid "Linux Steam® Integration"
|
||||
msgstr "Integração Linux Steam®"
|
||||
|
||||
#: src/frontend/main-window.c:162
|
||||
msgid ""
|
||||
"Control the behaviour of the Steam client and games. Settings will not take "
|
||||
"effect until the Steam Client is restarted. Use the 'Exit Steam' option to "
|
||||
"ensure it closes."
|
||||
msgstr ""
|
||||
"Controla o comportamento do cliente e jogos em Steam. As configurações não "
|
||||
"terão efeito antes de o Cliente de Steam ser reinicializado. Use a opção "
|
||||
"\"Sair do Steam\" para ter a certeza que o cliente fecha."
|
||||
|
||||
#: src/frontend/main-window.c:191
|
||||
msgid "Use native runtime"
|
||||
msgstr "Usar \"runtime\" nativo"
|
||||
|
||||
#: src/frontend/main-window.c:192
|
||||
msgid "Switch between the native runtime and the bundled Steam runtime."
|
||||
msgstr "Alternar entre o \"runtime\" nativo e o \"runtime\" Steam incluído."
|
||||
|
||||
#. Label is shown to indicate we can't enable 32-bit option
|
||||
#: src/frontend/main-window.c:201
|
||||
msgid "This option has been disabled as the system is already 32-bit"
|
||||
msgstr "Esta opção foi desativada, já que o sistema já possui 32 bits"
|
||||
|
||||
#: src/frontend/main-window.c:205
|
||||
msgid ""
|
||||
"This may workaround some broken games, but will disable the Steam store "
|
||||
"browser."
|
||||
msgstr ""
|
||||
"Isto pode resolver alguns jogos danificados, mas irá desativar o navegador "
|
||||
"da loja Steam."
|
||||
|
||||
#: src/frontend/main-window.c:210
|
||||
msgid "Force 32-bit mode for Steam"
|
||||
msgstr "Forçar o modo de 32 bits para Steam"
|
||||
|
||||
#: src/frontend/main-window.c:218
|
||||
msgid "Use the intercept library"
|
||||
msgstr "Use a biblioteca de intercetação"
|
||||
|
||||
#: src/frontend/main-window.c:219
|
||||
msgid ""
|
||||
"Force Steam applications to use more native libraries to maximise "
|
||||
"compatibility."
|
||||
msgstr ""
|
||||
"Força aplicativos do Steam para usar mais bibliotecas nativas para maximizar"
|
||||
" a compatibilidade."
|
||||
|
||||
#: src/frontend/main-window.c:228
|
||||
msgid "Use the redirect library"
|
||||
msgstr "Use a biblioteca de redirecionamento"
|
||||
|
||||
#: src/frontend/main-window.c:229
|
||||
msgid "Override system calls to fix known bugs in some Linux ports."
|
||||
msgstr ""
|
||||
"Substitua as chamadas do sistema para corrigir erros conhecidos em algumas "
|
||||
"portas Linux."
|
||||
|
||||
#: src/frontend/main-window.c:383
|
||||
msgid "Failed to save configuration"
|
||||
msgstr "Falha ao salvar a configuração"
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the linux-steam-integration package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: linux-steam-integration\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2017-11-05 19:28+0000\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: Andrei B <snoozeisdoze@gmail.com>, 2017\n"
|
||||
"Language-Team: Romanian (Romania) (https://www.transifex.com/solus-project/teams/68407/ro_RO/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: ro_RO\n"
|
||||
"Plural-Forms: nplurals=3; plural=(n==1?0:(((n%100>19)||((n%100==0)&&(n!=0)))?2:1));\n"
|
||||
|
||||
#. Sort out window bits
|
||||
#. header label
|
||||
#: src/frontend/main-window.c:131 src/frontend/main-window.c:148
|
||||
msgid "Linux Steam® Integration"
|
||||
msgstr "Integrare Steam® Linux"
|
||||
|
||||
#: src/frontend/main-window.c:162
|
||||
msgid ""
|
||||
"Control the behaviour of the Steam client and games. Settings will not take "
|
||||
"effect until the Steam Client is restarted. Use the 'Exit Steam' option to "
|
||||
"ensure it closes."
|
||||
msgstr ""
|
||||
"Controleaza comportamentul jocurilor si al clientului Steam. Setarile nu vor"
|
||||
" avea efect pana cand Clientul Steam nu este restartat. Utilizati optiunea "
|
||||
"\"Exit Steam\" pentru a va asigura ca se inchide."
|
||||
|
||||
#: src/frontend/main-window.c:191
|
||||
msgid "Use native runtime"
|
||||
msgstr "Utilizati runtime-ul nativ"
|
||||
|
||||
#: src/frontend/main-window.c:192
|
||||
msgid "Switch between the native runtime and the bundled Steam runtime."
|
||||
msgstr "Comuta intre runtime-ul nativ si cel inclus in Steam"
|
||||
|
||||
#. Label is shown to indicate we can't enable 32-bit option
|
||||
#: src/frontend/main-window.c:201
|
||||
msgid "This option has been disabled as the system is already 32-bit"
|
||||
msgstr "Aceasta optiune a fost dezactivata deoarece sistemul este deja 32-bit"
|
||||
|
||||
#: src/frontend/main-window.c:205
|
||||
msgid ""
|
||||
"This may workaround some broken games, but will disable the Steam store "
|
||||
"browser."
|
||||
msgstr ""
|
||||
"Aceasta poate fi o solutie pentru unele jocuri nefunctionale, dar va "
|
||||
"dezactiva navigatorul magazinul Steam."
|
||||
|
||||
#: src/frontend/main-window.c:210
|
||||
msgid "Force 32-bit mode for Steam"
|
||||
msgstr "Forteaza modul 32-bit pentru Steam"
|
||||
|
||||
#: src/frontend/main-window.c:218
|
||||
msgid "Use the intercept library"
|
||||
msgstr "Utilizati libraria de interceptare"
|
||||
|
||||
#: src/frontend/main-window.c:219
|
||||
msgid ""
|
||||
"Force Steam applications to use more native libraries to maximise "
|
||||
"compatibility."
|
||||
msgstr ""
|
||||
"Fortati aplicatiile Steam sa foloseasca mai multe librarii native pentru a "
|
||||
"maximiza compatibilitatea."
|
||||
|
||||
#: src/frontend/main-window.c:228
|
||||
msgid "Use the redirect library"
|
||||
msgstr "Utilizati libraria de redirectionare"
|
||||
|
||||
#: src/frontend/main-window.c:229
|
||||
msgid "Override system calls to fix known bugs in some Linux ports."
|
||||
msgstr ""
|
||||
"Suprascrie apelurile de sistem pentru a repara erori cunoscute in unele "
|
||||
"portari Linux."
|
||||
|
||||
#: src/frontend/main-window.c:383
|
||||
msgid "Failed to save configuration"
|
||||
msgstr "Nu s-a reusit salvarea configuratiei"
|
||||
+83
@@ -0,0 +1,83 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the linux-steam-integration package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: linux-steam-integration\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2017-11-05 19:28+0000\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: Puppelimies <max.haureus@gmail.com>, 2017\n"
|
||||
"Language-Team: Swedish (Sweden) (https://www.transifex.com/solus-project/teams/68407/sv_SE/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: sv_SE\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#. Sort out window bits
|
||||
#. header label
|
||||
#: src/frontend/main-window.c:131 src/frontend/main-window.c:148
|
||||
msgid "Linux Steam® Integration"
|
||||
msgstr "Linux Steam® Integration"
|
||||
|
||||
#: src/frontend/main-window.c:162
|
||||
msgid ""
|
||||
"Control the behaviour of the Steam client and games. Settings will not take "
|
||||
"effect until the Steam Client is restarted. Use the 'Exit Steam' option to "
|
||||
"ensure it closes."
|
||||
msgstr ""
|
||||
"Styr beteendet av Steam klienten och spel. Inställningarna kommer inte att "
|
||||
"träda i kraft förrän Steam klienten startas om. Använd 'Avsluta Steam' "
|
||||
"alternativet för att se till att den stängs."
|
||||
|
||||
#: src/frontend/main-window.c:191
|
||||
msgid "Use native runtime"
|
||||
msgstr "Använd inbyggd runtime"
|
||||
|
||||
#: src/frontend/main-window.c:192
|
||||
msgid "Switch between the native runtime and the bundled Steam runtime."
|
||||
msgstr "Växla mellan inbyggd runtime och inkluderad Steam runtime."
|
||||
|
||||
#. Label is shown to indicate we can't enable 32-bit option
|
||||
#: src/frontend/main-window.c:201
|
||||
msgid "This option has been disabled as the system is already 32-bit"
|
||||
msgstr "Detta alternativ är inaktiverat eftersom systemet redan är 32-bit"
|
||||
|
||||
#: src/frontend/main-window.c:205
|
||||
msgid ""
|
||||
"This may workaround some broken games, but will disable the Steam store "
|
||||
"browser."
|
||||
msgstr ""
|
||||
"Detta kan lösa endel trasiga spel, men inaktiverar Steam butik bläddraren."
|
||||
|
||||
#: src/frontend/main-window.c:210
|
||||
msgid "Force 32-bit mode for Steam"
|
||||
msgstr "Tvinga 32-bit läge för Steam"
|
||||
|
||||
#: src/frontend/main-window.c:218
|
||||
msgid "Use the intercept library"
|
||||
msgstr "Använd avledningsbiblioteket"
|
||||
|
||||
#: src/frontend/main-window.c:219
|
||||
msgid ""
|
||||
"Force Steam applications to use more native libraries to maximise "
|
||||
"compatibility."
|
||||
msgstr ""
|
||||
"Tvinga Steam applikationer att använda fler inbyggda bibliotek för att "
|
||||
"maximera kompatibilitet."
|
||||
|
||||
#: src/frontend/main-window.c:228
|
||||
msgid "Use the redirect library"
|
||||
msgstr "Använd omdirigeringsbiblioteket"
|
||||
|
||||
#: src/frontend/main-window.c:229
|
||||
msgid "Override system calls to fix known bugs in some Linux ports."
|
||||
msgstr "Åsidosätt systemanrop för att åtgärda kända fel i vissa Linux-portar."
|
||||
|
||||
#: src/frontend/main-window.c:383
|
||||
msgid "Failed to save configuration"
|
||||
msgstr "Spara konfiguration misslyckades"
|
||||
Executable
+9
@@ -0,0 +1,9 @@
|
||||
#!/bin/sh
|
||||
tx pull -a --minimum-perc=100
|
||||
|
||||
cd po
|
||||
rm LINGUAS
|
||||
|
||||
for i in *.po ; do
|
||||
echo `echo $i|sed 's/.po$//'` >> LINGUAS
|
||||
done
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the linux-steam-integration package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: linux-steam-integration\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2017-11-05 19:28+0000\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: plantman <weihanlin@live.com>, 2017\n"
|
||||
"Language-Team: Chinese (China) (https://www.transifex.com/solus-project/teams/68407/zh_CN/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: zh_CN\n"
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
|
||||
#. Sort out window bits
|
||||
#. header label
|
||||
#: src/frontend/main-window.c:131 src/frontend/main-window.c:148
|
||||
msgid "Linux Steam® Integration"
|
||||
msgstr "Steam® 的 Linux 系统整合"
|
||||
|
||||
#: src/frontend/main-window.c:162
|
||||
msgid ""
|
||||
"Control the behaviour of the Steam client and games. Settings will not take "
|
||||
"effect until the Steam Client is restarted. Use the 'Exit Steam' option to "
|
||||
"ensure it closes."
|
||||
msgstr "控制 Steam 客户端和游戏的运行方式。配置在重启后生效。使用“退出 Steam”选项来确保完全退出。"
|
||||
|
||||
#: src/frontend/main-window.c:191
|
||||
msgid "Use native runtime"
|
||||
msgstr "使用系统运行时"
|
||||
|
||||
#: src/frontend/main-window.c:192
|
||||
msgid "Switch between the native runtime and the bundled Steam runtime."
|
||||
msgstr "在系统运行时跟 Steam 自带运行时之间切换"
|
||||
|
||||
#. Label is shown to indicate we can't enable 32-bit option
|
||||
#: src/frontend/main-window.c:201
|
||||
msgid "This option has been disabled as the system is already 32-bit"
|
||||
msgstr "此选项已禁用,因为系统已经是 32 位了"
|
||||
|
||||
#: src/frontend/main-window.c:205
|
||||
msgid ""
|
||||
"This may workaround some broken games, but will disable the Steam store "
|
||||
"browser."
|
||||
msgstr "这个解决方法可能会修复某些运行不正常的游戏,但是会禁用 Steam 商店浏览器"
|
||||
|
||||
#: src/frontend/main-window.c:210
|
||||
msgid "Force 32-bit mode for Steam"
|
||||
msgstr "强制以 32 位模式运行 Steam"
|
||||
|
||||
#: src/frontend/main-window.c:218
|
||||
msgid "Use the intercept library"
|
||||
msgstr "使用 “Intercept” 库"
|
||||
|
||||
#: src/frontend/main-window.c:219
|
||||
msgid ""
|
||||
"Force Steam applications to use more native libraries to maximise "
|
||||
"compatibility."
|
||||
msgstr "强制让 Steam 尽可能使用系统自带库,以确保最好的兼容性"
|
||||
|
||||
#: src/frontend/main-window.c:228
|
||||
msgid "Use the redirect library"
|
||||
msgstr "使用 \"Redirect\" 库"
|
||||
|
||||
#: src/frontend/main-window.c:229
|
||||
msgid "Override system calls to fix known bugs in some Linux ports."
|
||||
msgstr "覆盖系统调用以修复某些已知的游戏运行问题"
|
||||
|
||||
#: src/frontend/main-window.c:383
|
||||
msgid "Failed to save configuration"
|
||||
msgstr "无法保存配置"
|
||||
@@ -0,0 +1,218 @@
|
||||
/*
|
||||
* This file is part of linux-steam-integration.
|
||||
*
|
||||
* Copyright © 2016-2017 Ikey Doherty <ikey@solus-project.com>
|
||||
*
|
||||
* linux-steam-integration is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1
|
||||
* of the License, or (at your option) any later version.
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include <ctype.h>
|
||||
#include <pwd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "files.h"
|
||||
#include "log.h"
|
||||
#include "nica/array.h"
|
||||
#include "nica/util.h"
|
||||
#include "vdf.h"
|
||||
|
||||
DEF_AUTOFREE(VdfFile, vdf_file_close)
|
||||
|
||||
bool lsi_file_exists(const char *path)
|
||||
{
|
||||
__lsi_unused__ struct stat st = { 0 };
|
||||
return lstat(path, &st) == 0;
|
||||
}
|
||||
|
||||
const char *lsi_get_home_dir()
|
||||
{
|
||||
char *c = NULL;
|
||||
struct passwd *p = NULL;
|
||||
|
||||
c = getenv("HOME");
|
||||
if (c) {
|
||||
return c;
|
||||
}
|
||||
p = getpwuid(getuid());
|
||||
if (!p) {
|
||||
return NULL;
|
||||
}
|
||||
return p->pw_dir;
|
||||
}
|
||||
|
||||
char *lsi_get_user_config_dir()
|
||||
{
|
||||
const char *home = lsi_get_home_dir();
|
||||
char *c = NULL;
|
||||
if (asprintf(&c, "%s/.config", home) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* Just use .local/share/Steam at this point..
|
||||
*/
|
||||
static inline char *lsi_get_fallback_steam_dir(const char *home)
|
||||
{
|
||||
char *p = NULL;
|
||||
if (asprintf(&p, "%s/.local/share/Steam", home) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
char *lsi_get_steam_dir()
|
||||
{
|
||||
const char *homedir = NULL;
|
||||
autofree(char) *candidate = NULL;
|
||||
autofree(char) *resolv = NULL;
|
||||
|
||||
homedir = lsi_get_home_dir();
|
||||
if (asprintf(&candidate, "%s/.steam/root", homedir) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
resolv = realpath(candidate, NULL);
|
||||
if (!resolv || !lsi_file_exists(resolv)) {
|
||||
return lsi_get_fallback_steam_dir(homedir);
|
||||
}
|
||||
return strdup(resolv);
|
||||
}
|
||||
|
||||
char *lsi_get_process_name(void)
|
||||
{
|
||||
char *realp = NULL;
|
||||
|
||||
realp = realpath("/proc/self/exe", NULL);
|
||||
if (!realp) {
|
||||
return NULL;
|
||||
}
|
||||
return realp;
|
||||
}
|
||||
|
||||
char *lsi_get_process_base_name(void)
|
||||
{
|
||||
autofree(char) *p = NULL;
|
||||
char *basep = NULL;
|
||||
|
||||
p = lsi_get_process_name();
|
||||
if (!p) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
basep = basename(p);
|
||||
return strdup(basep);
|
||||
}
|
||||
|
||||
/**
|
||||
* Quickly determine if a string is numeric..
|
||||
*/
|
||||
static inline bool lsi_is_string_numeric(char *p)
|
||||
{
|
||||
char *s;
|
||||
|
||||
for (s = p; *s; s++) {
|
||||
if (!isdigit(*s)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* Didn't wind, empty string */
|
||||
if (s == p) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
char **lsi_get_steam_paths(void)
|
||||
{
|
||||
autofree(char) *steam_root = NULL;
|
||||
autofree(char) *lib_conf = NULL;
|
||||
autofree(VdfFile) *vdf = NULL;
|
||||
VdfNode *root = NULL;
|
||||
VdfNode *node = NULL;
|
||||
NcArray *array = NULL;
|
||||
|
||||
steam_root = lsi_get_steam_dir();
|
||||
if (!steam_root) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
array = nc_array_new();
|
||||
if (!nc_array_add(array, strdup(steam_root))) {
|
||||
goto bail;
|
||||
}
|
||||
|
||||
if (asprintf(&lib_conf, "%s/steamapps/libraryfolders.vdf", steam_root) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
vdf = vdf_file_open(lib_conf);
|
||||
if (!vdf) {
|
||||
goto fallback;
|
||||
}
|
||||
|
||||
if (!vdf_file_parse(vdf)) {
|
||||
goto fallback;
|
||||
}
|
||||
|
||||
/* Look up LibraryFolders under root */
|
||||
root = vdf_file_get_root(vdf);
|
||||
node = vdf_node_get(root, "LibraryFolders", NULL);
|
||||
if (!node) {
|
||||
goto fallback;
|
||||
}
|
||||
|
||||
/* Walk all nodes immediately within LibraryFolders and ignore sections */
|
||||
for (VdfNode *n = node->child; n; n = n->sibling) {
|
||||
if (!n->value) {
|
||||
continue;
|
||||
}
|
||||
if (lsi_is_string_numeric(n->key)) {
|
||||
if (!nc_array_add(array, strdup(n->value))) {
|
||||
goto bail;
|
||||
}
|
||||
lsi_log_debug("vdf: discovered LibraryFolders: %s", n->value);
|
||||
}
|
||||
}
|
||||
|
||||
fallback:
|
||||
/* Trick nica into storing empty value to so we can terminate the array */
|
||||
if (!nc_array_add(array, (void *)(long)1)) {
|
||||
goto bail;
|
||||
}
|
||||
|
||||
/* Steal the blob straight out of the array */
|
||||
char **data = (char **)array->data;
|
||||
data[array->len - 1] = NULL;
|
||||
free(array);
|
||||
return data;
|
||||
|
||||
bail:
|
||||
nc_array_free(&array, free);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Editor modelines - https://www.wireshark.org/tools/modelines.html
|
||||
*
|
||||
* Local variables:
|
||||
* c-basic-offset: 8
|
||||
* tab-width: 8
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*
|
||||
* vi: set shiftwidth=8 tabstop=8 expandtab:
|
||||
* :indentSize=8:tabSize=8:noTabs=true:
|
||||
*/
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* This file is part of linux-steam-integration.
|
||||
*
|
||||
* Copyright © 2016-2017 Ikey Doherty <ikey@solus-project.com>
|
||||
*
|
||||
* linux-steam-integration is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1
|
||||
* of the License, or (at your option) any later version.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/**
|
||||
* Determine the home directory
|
||||
*/
|
||||
const char *lsi_get_home_dir(void);
|
||||
|
||||
/**
|
||||
* Determine the home config directory
|
||||
*/
|
||||
char *lsi_get_user_config_dir(void);
|
||||
|
||||
/**
|
||||
* Find out where Steam is installed
|
||||
*/
|
||||
char *lsi_get_steam_dir(void);
|
||||
|
||||
/**
|
||||
* Grab all the valid steam installation directories
|
||||
*/
|
||||
char **lsi_get_steam_paths(void);
|
||||
|
||||
/**
|
||||
* Quick helper to determine if the path exists
|
||||
*/
|
||||
bool lsi_file_exists(const char *path);
|
||||
|
||||
/**
|
||||
* Return the full process name
|
||||
*/
|
||||
char *lsi_get_process_name(void);
|
||||
|
||||
/**
|
||||
* Determine the basename'd process
|
||||
*/
|
||||
char *lsi_get_process_base_name(void);
|
||||
|
||||
/*
|
||||
* Editor modelines - https://www.wireshark.org/tools/modelines.html
|
||||
*
|
||||
* Local variables:
|
||||
* c-basic-offset: 8
|
||||
* tab-width: 8
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*
|
||||
* vi: set shiftwidth=8 tabstop=8 expandtab:
|
||||
* :indentSize=8:tabSize=8:noTabs=true:
|
||||
*/
|
||||
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* This file is part of linux-steam-integration.
|
||||
*
|
||||
* Copyright © 2016-2017 Ikey Doherty <ikey@solus-project.com>
|
||||
*
|
||||
* linux-steam-integration is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1
|
||||
* of the License, or (at your option) any later version.
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "log.h"
|
||||
#include "nica/util.h"
|
||||
|
||||
static const char *_log_id = "__init__";
|
||||
|
||||
void lsi_log_set_id(const char *id)
|
||||
{
|
||||
_log_id = id;
|
||||
}
|
||||
|
||||
void lsi_log_debug(const char *format, ...)
|
||||
{
|
||||
if (!getenv("LSI_DEBUG")) {
|
||||
return;
|
||||
}
|
||||
|
||||
autofree(char) *p = NULL;
|
||||
va_list va;
|
||||
va_start(va, format);
|
||||
|
||||
if (!vasprintf(&p, format, va)) {
|
||||
/* At least print *something */
|
||||
fprintf(stderr, "%s\n", format);
|
||||
goto end;
|
||||
}
|
||||
|
||||
fprintf(stderr, "\033[32;1m[lsi:%s]\033[0m %s\n", _log_id, p);
|
||||
|
||||
end:
|
||||
va_end(va);
|
||||
}
|
||||
|
||||
void lsi_log_info(const char *format, ...)
|
||||
{
|
||||
autofree(char) *p = NULL;
|
||||
va_list va;
|
||||
va_start(va, format);
|
||||
|
||||
if (!vasprintf(&p, format, va)) {
|
||||
/* At least print *something */
|
||||
fprintf(stderr, "%s\n", format);
|
||||
goto end;
|
||||
}
|
||||
|
||||
fprintf(stderr, "\033[34;1m[lsi:%s]\033[0m %s\n", _log_id, p);
|
||||
|
||||
end:
|
||||
va_end(va);
|
||||
}
|
||||
|
||||
void lsi_log_warn(const char *format, ...)
|
||||
{
|
||||
autofree(char) *p = NULL;
|
||||
va_list va;
|
||||
va_start(va, format);
|
||||
|
||||
if (!vasprintf(&p, format, va)) {
|
||||
/* At least print *something */
|
||||
fprintf(stderr, "%s\n", format);
|
||||
goto end;
|
||||
}
|
||||
|
||||
fprintf(stderr, "\033[33;1m[lsi:%s]\033[0m %s\n", _log_id, p);
|
||||
|
||||
end:
|
||||
va_end(va);
|
||||
}
|
||||
|
||||
void lsi_log_error(const char *format, ...)
|
||||
{
|
||||
autofree(char) *p = NULL;
|
||||
va_list va;
|
||||
va_start(va, format);
|
||||
|
||||
if (!vasprintf(&p, format, va)) {
|
||||
/* At least print *something */
|
||||
fprintf(stderr, "%s\n", format);
|
||||
goto end;
|
||||
}
|
||||
|
||||
fprintf(stderr, "\033[31;1m[lsi:%s]\033[0m %s\n", _log_id, p);
|
||||
|
||||
end:
|
||||
va_end(va);
|
||||
}
|
||||
|
||||
/*
|
||||
* Editor modelines - https://www.wireshark.org/tools/modelines.html
|
||||
*
|
||||
* Local variables:
|
||||
* c-basic-offset: 8
|
||||
* tab-width: 8
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*
|
||||
* vi: set shiftwidth=8 tabstop=8 expandtab:
|
||||
* :indentSize=8:tabSize=8:noTabs=true:
|
||||
*/
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* This file is part of linux-steam-integration.
|
||||
*
|
||||
* Copyright © 2016-2017 Ikey Doherty <ikey@solus-project.com>
|
||||
*
|
||||
* linux-steam-integration is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1
|
||||
* of the License, or (at your option) any later version.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
/**
|
||||
* Set the ID used in all log output
|
||||
*/
|
||||
void lsi_log_set_id(const char *id);
|
||||
|
||||
/**
|
||||
* Emit some debug information if LSI_DEBUG is set
|
||||
*/
|
||||
void lsi_log_debug(const char *format, ...) __attribute__((format(printf, 1, 2)));
|
||||
|
||||
/**
|
||||
* Emit information, always shown
|
||||
*/
|
||||
void lsi_log_info(const char *format, ...) __attribute__((format(printf, 1, 2)));
|
||||
|
||||
/**
|
||||
* Emit a warning, always shown
|
||||
*/
|
||||
void lsi_log_warn(const char *format, ...) __attribute__((format(printf, 1, 2)));
|
||||
|
||||
/**
|
||||
* Emit an error, always shown
|
||||
*/
|
||||
void lsi_log_error(const char *format, ...) __attribute__((format(printf, 1, 2)));
|
||||
|
||||
/*
|
||||
* Editor modelines - https://www.wireshark.org/tools/modelines.html
|
||||
*
|
||||
* Local variables:
|
||||
* c-basic-offset: 8
|
||||
* tab-width: 8
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*
|
||||
* vi: set shiftwidth=8 tabstop=8 expandtab:
|
||||
* :indentSize=8:tabSize=8:noTabs=true:
|
||||
*/
|
||||
@@ -0,0 +1,19 @@
|
||||
# Build the common library to share functionality between various components
|
||||
|
||||
lsi_common_sources = [
|
||||
'files.c',
|
||||
'log.c',
|
||||
'vdf.c',
|
||||
]
|
||||
|
||||
lib_lsi_common = static_library(
|
||||
'lsi-lsi-common',
|
||||
sources: lsi_common_sources + nica_sources,
|
||||
c_args: ['-fvisibility=hidden'],
|
||||
include_directories: nica_includes,
|
||||
)
|
||||
|
||||
link_lsi_common = declare_dependency(
|
||||
link_with: lib_lsi_common,
|
||||
include_directories: include_directories('.'),
|
||||
)
|
||||
@@ -0,0 +1,705 @@
|
||||
/*
|
||||
* This file is part of linux-steam-integration.
|
||||
*
|
||||
* Copyright © 2016-2017 Ikey Doherty <ikey@solus-project.com>
|
||||
*
|
||||
* linux-steam-integration is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1
|
||||
* of the License, or (at your option) any later version.
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "log.h"
|
||||
#include "vdf.h"
|
||||
|
||||
#define VDF_CHAR_QUOTE '"'
|
||||
#define VDF_CHAR_SLASH '\\'
|
||||
#define VDF_CHAR_OPEN '{'
|
||||
#define VDF_CHAR_CLOSE '}'
|
||||
|
||||
typedef enum {
|
||||
VDF_FLAG_MIN = 1 << 0,
|
||||
VDF_FLAG_QUOTED = 1 << 1, /**< Inside a quoted block */
|
||||
VDF_FLAG_COMMENT = 1 << 2, /**< Inside a comment block */
|
||||
VDF_FLAG_BLOCK_COMMENT = 1 << 3, /**< Inside a multiline comment block */
|
||||
VDF_FLAG_CHEW_WHITESPACE = 1 << 4,
|
||||
} VdfFlags;
|
||||
|
||||
/**
|
||||
* VdfFile is the main dude required for parsing a file
|
||||
*/
|
||||
struct VdfFile {
|
||||
/* Input */
|
||||
size_t buffer_len;
|
||||
char *buffer;
|
||||
|
||||
/* Output (memstream) */
|
||||
FILE *ring;
|
||||
char *out_buffer;
|
||||
size_t out_len;
|
||||
|
||||
/* Input file */
|
||||
int fd;
|
||||
|
||||
/* Tracking */
|
||||
size_t index;
|
||||
int flags;
|
||||
char *key_id;
|
||||
int n_quote; /**only allow 2 sets per "line" */
|
||||
VdfNode *section;
|
||||
VdfNode *root;
|
||||
|
||||
bool error; /**< Allow breaking. */
|
||||
};
|
||||
|
||||
/**
|
||||
* Function pointer to the generic handler functions.
|
||||
*/
|
||||
typedef bool (*vdf_handle_func)(VdfFile *file, char c);
|
||||
|
||||
/**
|
||||
* Free node
|
||||
*/
|
||||
static void vdf_node_free(VdfNode *node)
|
||||
{
|
||||
if (!node) {
|
||||
return;
|
||||
}
|
||||
if (node->key) {
|
||||
free(node->key);
|
||||
}
|
||||
if (node->value) {
|
||||
free(node->value);
|
||||
}
|
||||
|
||||
vdf_node_free(node->sibling);
|
||||
vdf_node_free(node->child);
|
||||
free(node);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocate a new VdfNode, copying the key and value if they exist.
|
||||
*/
|
||||
static VdfNode *vdf_node_new(const char *key, const char *value)
|
||||
{
|
||||
VdfNode *ret = NULL;
|
||||
|
||||
ret = calloc(1, sizeof(VdfNode));
|
||||
if (!ret) {
|
||||
return NULL;
|
||||
}
|
||||
if (key) {
|
||||
ret->key = strdup(key);
|
||||
if (!ret->key) {
|
||||
goto failed;
|
||||
}
|
||||
}
|
||||
if (value) {
|
||||
ret->value = strdup(value);
|
||||
if (!ret->value) {
|
||||
goto failed;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
failed:
|
||||
vdf_node_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void vdf_file_close(VdfFile *file)
|
||||
{
|
||||
if (!file) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (file->buffer) {
|
||||
munmap(file->buffer, file->buffer_len);
|
||||
}
|
||||
if (file->fd > -1) {
|
||||
close(file->fd);
|
||||
}
|
||||
if (file->ring) {
|
||||
fclose(file->ring);
|
||||
}
|
||||
if (file->out_buffer) {
|
||||
free(file->out_buffer);
|
||||
}
|
||||
if (file->key_id) {
|
||||
free(file->key_id);
|
||||
}
|
||||
/* TODO: Make free separate from close, so we can just keep the node */
|
||||
vdf_node_free(file->root);
|
||||
free(file);
|
||||
}
|
||||
|
||||
VdfFile *vdf_file_open(const char *path)
|
||||
{
|
||||
VdfFile *ret = NULL;
|
||||
struct stat st = { 0 };
|
||||
|
||||
ret = calloc(1, sizeof(VdfFile));
|
||||
if (!ret) {
|
||||
return NULL;
|
||||
}
|
||||
ret->fd = -1;
|
||||
|
||||
ret->fd = open(path, O_RDONLY);
|
||||
if (ret->fd < 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (fstat(ret->fd, &st) != 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret->buffer_len = (size_t)st.st_size;
|
||||
|
||||
ret->buffer = mmap(NULL, ret->buffer_len, PROT_READ, MAP_PRIVATE, ret->fd, 0);
|
||||
if (!ret->buffer) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Now we have input map, build output memstream */
|
||||
ret->ring = open_memstream(&ret->out_buffer, &ret->out_len);
|
||||
if (!ret->ring) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
return ret;
|
||||
fail:
|
||||
vdf_file_close(ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
VdfNode *vdf_file_get_root(VdfFile *file)
|
||||
{
|
||||
if (!file) {
|
||||
return NULL;
|
||||
}
|
||||
return file->root;
|
||||
}
|
||||
|
||||
/**
|
||||
* Advance the buffer pointer forward if possible.
|
||||
*/
|
||||
static char vdf_file_next(VdfFile *file)
|
||||
{
|
||||
file->index++;
|
||||
if (file->index > file->buffer_len) {
|
||||
file->index = file->buffer_len;
|
||||
return '\0';
|
||||
}
|
||||
return file->buffer[file->index];
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to peek at the next character in the buffer
|
||||
*/
|
||||
static char vdf_file_peek(VdfFile *file)
|
||||
{
|
||||
if (file->index + 1 > file->buffer_len) {
|
||||
return '\0';
|
||||
}
|
||||
return file->buffer[file->index + 1];
|
||||
}
|
||||
|
||||
/**
|
||||
* Skip a character in the stream
|
||||
*/
|
||||
static void vdf_file_skip(VdfFile *file)
|
||||
{
|
||||
if (++file->index > file->buffer_len) {
|
||||
file->index = file->buffer_len;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Push a char to the ring buffer
|
||||
*/
|
||||
static bool vdf_file_push_ring(VdfFile *file, char c)
|
||||
{
|
||||
if (fwrite(&c, 1, sizeof(c), file->ring) != 1) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* End the ring buffer by writing a NUL byte
|
||||
*/
|
||||
static bool vdf_file_end_ring(VdfFile *file)
|
||||
{
|
||||
if (!vdf_file_push_ring(file, '\0')) {
|
||||
return false;
|
||||
}
|
||||
if (fflush(file->ring) != 0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the ring once more to begin writing again.
|
||||
*/
|
||||
static bool vdf_file_reset_ring(VdfFile *file)
|
||||
{
|
||||
if (fflush(file->ring) != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fseek(file->ring, 0, SEEK_SET) != 0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle newlines
|
||||
*
|
||||
* When encountering a newline we need to do a bit of state cleanup
|
||||
*/
|
||||
static bool vdf_file_handle_newline(VdfFile *file, char c)
|
||||
{
|
||||
if (c != '\n') {
|
||||
return false;
|
||||
}
|
||||
file->flags &= ~VDF_FLAG_COMMENT;
|
||||
if (file->flags & VDF_FLAG_QUOTED) {
|
||||
file->flags |= VDF_FLAG_CHEW_WHITESPACE;
|
||||
} else {
|
||||
file->flags &= ~VDF_FLAG_CHEW_WHITESPACE;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle quote characters
|
||||
*
|
||||
* This function deals with the start/end quotes encountered in the stream
|
||||
* to set keys and values
|
||||
*/
|
||||
static bool vdf_file_handle_quote(VdfFile *file, char c)
|
||||
{
|
||||
if (c != VDF_CHAR_QUOTE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Start tracking quoting if necessary */
|
||||
if (!(file->flags & VDF_FLAG_QUOTED)) {
|
||||
/* Start tracking the quoted thing */
|
||||
if (file->n_quote > 2) {
|
||||
lsi_log_error("vdf: Cannot start a third section");
|
||||
goto bail;
|
||||
}
|
||||
file->flags |= VDF_FLAG_QUOTED;
|
||||
file->flags &= ~VDF_FLAG_CHEW_WHITESPACE;
|
||||
vdf_file_reset_ring(file);
|
||||
return true;
|
||||
}
|
||||
|
||||
++file->n_quote;
|
||||
|
||||
/* Stop tracking the quoted thing */
|
||||
file->flags ^= VDF_FLAG_QUOTED;
|
||||
vdf_file_end_ring(file);
|
||||
|
||||
/* Capture the ID */
|
||||
if (file->n_quote == 1) {
|
||||
if (file->key_id) {
|
||||
lsi_log_error("vdf: Key should not already be set!");
|
||||
goto bail;
|
||||
}
|
||||
file->key_id = strdup(file->out_buffer);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!file->key_id) {
|
||||
lsi_log_error("vdf: Missing key for value!");
|
||||
goto bail;
|
||||
}
|
||||
|
||||
if (file->n_quote != 2) {
|
||||
lsi_log_error("vdf: Invalid number of quotes on line");
|
||||
goto bail;
|
||||
}
|
||||
|
||||
/* Reset n_quote now */
|
||||
file->n_quote = 0;
|
||||
|
||||
/* Store the node now */
|
||||
VdfNode *t = vdf_node_new(file->key_id, file->out_buffer);
|
||||
if (!t) {
|
||||
fputs("OOM\n", stderr);
|
||||
goto bail;
|
||||
}
|
||||
|
||||
/* dispose of key ID now */
|
||||
free(file->key_id);
|
||||
file->key_id = NULL;
|
||||
file->flags &= ~VDF_FLAG_CHEW_WHITESPACE;
|
||||
|
||||
/* Store the new key->value mapping */
|
||||
t->parent = file->section->parent;
|
||||
t->sibling = file->section->child;
|
||||
file->section->child = t;
|
||||
|
||||
return true;
|
||||
|
||||
bail:
|
||||
file->error = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle opening of a section
|
||||
*
|
||||
* This will perform some basic validation, and when all conditions are satisfied
|
||||
* we'll attempt construction of a new section
|
||||
*/
|
||||
static bool vdf_file_handle_section_open(VdfFile *file)
|
||||
{
|
||||
VdfNode *node = NULL;
|
||||
vdf_file_reset_ring(file);
|
||||
|
||||
if (file->n_quote == 2) {
|
||||
lsi_log_error("vdf: section cannot have value!");
|
||||
goto bail;
|
||||
}
|
||||
|
||||
if (file->n_quote != 1) {
|
||||
lsi_log_error("vdf: Section is missing id!");
|
||||
goto bail;
|
||||
}
|
||||
|
||||
file->n_quote = 0;
|
||||
|
||||
if (!file->key_id) {
|
||||
lsi_log_error("vdf: key_id should not be NULL!");
|
||||
goto bail;
|
||||
}
|
||||
|
||||
node = vdf_node_new(file->out_buffer, NULL);
|
||||
if (!node) {
|
||||
goto bail;
|
||||
}
|
||||
free(file->key_id);
|
||||
file->key_id = NULL;
|
||||
|
||||
node->parent = file->section;
|
||||
node->sibling = file->section->child;
|
||||
file->section->child = node;
|
||||
|
||||
file->section = node;
|
||||
return true;
|
||||
|
||||
bail:
|
||||
file->error = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle closing of a section
|
||||
*
|
||||
* This will perform some basic error checking to ensure we're closing it
|
||||
* correctly. At this point we'll wind back to the nodes parent
|
||||
*/
|
||||
static bool vdf_file_handle_section_close(VdfFile *file)
|
||||
{
|
||||
if (file->n_quote != 0) {
|
||||
lsi_log_error("vdf: unterminated section!");
|
||||
goto bail;
|
||||
}
|
||||
|
||||
if (!file->section) {
|
||||
lsi_log_error("vdf: Closed section without creating one!");
|
||||
goto bail;
|
||||
}
|
||||
|
||||
/* Wind back */
|
||||
file->section = file->section->parent;
|
||||
if (!file->section) {
|
||||
goto bail;
|
||||
}
|
||||
return true;
|
||||
|
||||
bail:
|
||||
file->error = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle brace characters
|
||||
*
|
||||
* This function will proxy to the relevant handler function
|
||||
*/
|
||||
static bool vdf_file_handle_section(VdfFile *file, char c)
|
||||
{
|
||||
switch (c) {
|
||||
case VDF_CHAR_CLOSE:
|
||||
return vdf_file_handle_section_close(file);
|
||||
case VDF_CHAR_OPEN:
|
||||
return vdf_file_handle_section_open(file);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle normal text
|
||||
*
|
||||
* Whilst in QUOTED mode we'll keep pushing text to the buffer, which will
|
||||
* later become keys and values.
|
||||
*
|
||||
* We'll also do some sanity checks here to escape any common text sequences,
|
||||
* so as not to break the quotes
|
||||
*/
|
||||
static bool vdf_file_handle_text(VdfFile *file, char c)
|
||||
{
|
||||
char next = '\0';
|
||||
|
||||
/* Must be within quoting */
|
||||
if (!(file->flags & VDF_FLAG_QUOTED)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (file->flags & VDF_FLAG_CHEW_WHITESPACE && isspace(c)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
file->flags &= ~VDF_FLAG_CHEW_WHITESPACE;
|
||||
|
||||
/* Check if we need to do any escaping */
|
||||
if (c != VDF_CHAR_SLASH) {
|
||||
vdf_file_push_ring(file, c);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Perform text escaping */
|
||||
switch ((next = vdf_file_peek(file))) {
|
||||
case 'r':
|
||||
vdf_file_push_ring(file, '\r');
|
||||
vdf_file_skip(file);
|
||||
return true;
|
||||
case 'n':
|
||||
vdf_file_push_ring(file, '\n');
|
||||
vdf_file_skip(file);
|
||||
return true;
|
||||
case 't':
|
||||
vdf_file_push_ring(file, '\t');
|
||||
vdf_file_skip(file);
|
||||
return true;
|
||||
case '"':
|
||||
vdf_file_push_ring(file, '"');
|
||||
vdf_file_skip(file);
|
||||
return true;
|
||||
case '\'':
|
||||
vdf_file_push_ring(file, '\'');
|
||||
vdf_file_skip(file);
|
||||
return true;
|
||||
case '\\':
|
||||
vdf_file_push_ring(file, '\\');
|
||||
vdf_file_skip(file);
|
||||
return true;
|
||||
default:
|
||||
// TODO: Handle errors properly!
|
||||
lsi_log_error("vdf: Invalid escape sequence '\\%c'", next);
|
||||
file->error = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle multiline comments
|
||||
*
|
||||
* This method will attempt to look for the start and ends of multiline comment
|
||||
* blocks, which will result in all text from the start until the trailing
|
||||
* characters of the comment to be ignored.
|
||||
*/
|
||||
static bool vdf_file_handle_multiline_comment(VdfFile *file, char c)
|
||||
{
|
||||
if (c == '/' && vdf_file_peek(file) == '*') {
|
||||
vdf_file_skip(file);
|
||||
if (file->flags & VDF_FLAG_BLOCK_COMMENT) {
|
||||
lsi_log_error("vdf: Starting nested block comment");
|
||||
goto bail;
|
||||
}
|
||||
file->flags |= VDF_FLAG_BLOCK_COMMENT;
|
||||
} else if (c == '*' && vdf_file_peek(file) == '/') {
|
||||
vdf_file_skip(file);
|
||||
if (!(file->flags & VDF_FLAG_BLOCK_COMMENT)) {
|
||||
lsi_log_error("vdf: Ended comment without starting one");
|
||||
goto bail;
|
||||
}
|
||||
file->flags ^= VDF_FLAG_BLOCK_COMMENT;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
bail:
|
||||
file->error = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle single comments
|
||||
*
|
||||
* This will handle C++ style '//' comments and cause the remaining text on
|
||||
* the line to be ignored
|
||||
*/
|
||||
static bool vdf_file_handle_single_comment(VdfFile *file, char c)
|
||||
{
|
||||
/* Don't switch us on if we're inside a multiline comment! */
|
||||
if (file->flags & VDF_FLAG_BLOCK_COMMENT) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Must be a C++ style comment. */
|
||||
if (!(c == '/' && vdf_file_peek(file) == '/')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Skip the next character, and turn on comment mode */
|
||||
vdf_file_skip(file);
|
||||
file->flags |= VDF_FLAG_COMMENT;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle comment state
|
||||
*
|
||||
* If we're in a comment we might need to skip this line entirely, however
|
||||
* if its a multiline comment we need to preemptively evaluate the termination.
|
||||
*/
|
||||
static bool vdf_file_handle_commented(VdfFile *file, char c)
|
||||
{
|
||||
if (file->flags & VDF_FLAG_COMMENT) {
|
||||
return true;
|
||||
}
|
||||
if (file->flags & VDF_FLAG_BLOCK_COMMENT) {
|
||||
/* Always return true here, must ignore the line! */
|
||||
vdf_file_handle_multiline_comment(file, c);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool vdf_file_parse(VdfFile *file)
|
||||
{
|
||||
char c = file->buffer[0];
|
||||
bool ret = false;
|
||||
static vdf_handle_func funcs[] = {
|
||||
&vdf_file_handle_newline,
|
||||
&vdf_file_handle_commented,
|
||||
&vdf_file_handle_quote,
|
||||
&vdf_file_handle_text,
|
||||
&vdf_file_handle_section,
|
||||
&vdf_file_handle_single_comment,
|
||||
&vdf_file_handle_multiline_comment,
|
||||
};
|
||||
static size_t n_funcs = sizeof(funcs) / sizeof(funcs[0]);
|
||||
|
||||
file->flags = 0;
|
||||
file->key_id = NULL;
|
||||
file->section = file->root = vdf_node_new(NULL, NULL);
|
||||
if (!file->root) {
|
||||
goto bail;
|
||||
}
|
||||
|
||||
while (c != '\0') {
|
||||
/* Pass through all of our functions */
|
||||
for (size_t i = 0; i < n_funcs; i++) {
|
||||
if (funcs[i](file, c)) {
|
||||
goto next;
|
||||
}
|
||||
}
|
||||
if (file->error) {
|
||||
goto bail;
|
||||
}
|
||||
|
||||
/* Now the only thing left is to allow whitespace */
|
||||
if (!isspace(c)) {
|
||||
lsi_log_error("vdf: Illegal character in stream: '%c'", c);
|
||||
goto bail;
|
||||
}
|
||||
next:
|
||||
c = vdf_file_next(file);
|
||||
}
|
||||
|
||||
ret = true;
|
||||
|
||||
/* Check a comment actually ended .. */
|
||||
if (file->flags & VDF_FLAG_BLOCK_COMMENT) {
|
||||
lsi_log_error("vdf: Started block comment without ending one");
|
||||
ret = false;
|
||||
}
|
||||
|
||||
bail:
|
||||
if (file->key_id) {
|
||||
free(file->key_id);
|
||||
file->key_id = NULL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
VdfNode *vdf_node_get_child(VdfNode *node, const char *id)
|
||||
{
|
||||
if (!id || !node) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (VdfNode *tmp = node->child; tmp; tmp = tmp->sibling) {
|
||||
if (tmp->key && strcmp(tmp->key, id) == 0) {
|
||||
return tmp;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
VdfNode *vdf_node_get(VdfNode *node, ...)
|
||||
{
|
||||
va_list va;
|
||||
va_start(va, node);
|
||||
char *id = NULL;
|
||||
VdfNode *retr = node;
|
||||
|
||||
while ((id = va_arg(va, char *)) != NULL) {
|
||||
retr = vdf_node_get_child(retr, id);
|
||||
if (!retr) {
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
va_end(va);
|
||||
return retr;
|
||||
}
|
||||
|
||||
/*
|
||||
* Editor modelines - https://www.wireshark.org/tools/modelines.html
|
||||
*
|
||||
* Local variables:
|
||||
* c-basic-offset: 8
|
||||
* tab-width: 8
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*
|
||||
* vi: set shiftwidth=8 tabstop=8 expandtab:
|
||||
* :indentSize=8:tabSize=8:noTabs=true:
|
||||
*/
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* This file is part of linux-steam-integration.
|
||||
*
|
||||
* Copyright © 2016-2017 Ikey Doherty <ikey@solus-project.com>
|
||||
*
|
||||
* linux-steam-integration is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define _GNU_SOURCE
|
||||
|
||||
/**
|
||||
* VdfFile is an opaque type containing fields used primarily for parsing
|
||||
* a .vdf file
|
||||
*
|
||||
* A VdfFile is used to parse the Valve Data Format file, allowing LSI to
|
||||
* parse the users library paths, etc.
|
||||
*/
|
||||
typedef struct VdfFile VdfFile;
|
||||
|
||||
/**
|
||||
* A VdfNode may be any element in a VDF document, and has optional value,
|
||||
* children and parent.
|
||||
* The root node in a document has no parent
|
||||
*/
|
||||
typedef struct VdfNode {
|
||||
struct VdfNode *sibling; /**First sibling */
|
||||
struct VdfNode *child; /**<First child, may have siblings. */
|
||||
struct VdfNode *parent; /**<Parent if not the root */
|
||||
|
||||
char *key; /**<Only null for the root node */
|
||||
char *value; /**<Only exists for key-value nodes */
|
||||
} VdfNode;
|
||||
|
||||
/**
|
||||
* Close and free an existing VdfFile
|
||||
*/
|
||||
void vdf_file_close(VdfFile *file);
|
||||
|
||||
/**
|
||||
* Attempt to map the source path and open a .vdf file
|
||||
*/
|
||||
VdfFile *vdf_file_open(const char *path);
|
||||
|
||||
/**
|
||||
* Return the root node for this file, if it has been parsed
|
||||
*/
|
||||
VdfNode *vdf_file_get_root(VdfFile *file);
|
||||
|
||||
/**
|
||||
* Attempt to parse a file
|
||||
*
|
||||
* @file Pointer to a VdfFile instance
|
||||
* @returns true if parsing succeeds
|
||||
*/
|
||||
bool vdf_file_parse(VdfFile *file);
|
||||
|
||||
/**
|
||||
* Grab a child node by the given ID
|
||||
*
|
||||
* @node Parent node
|
||||
* @id Child ID
|
||||
*/
|
||||
VdfNode *vdf_node_get_child(VdfNode *node, const char *id);
|
||||
|
||||
/**
|
||||
* Variadic function to retrieve a child node
|
||||
*
|
||||
* This function will keep iterating the args passed until it hits NULL and
|
||||
* has a node, or no node can be found prior to this and it returns NULL.
|
||||
*/
|
||||
__attribute__((sentinel(0))) VdfNode *vdf_node_get(VdfNode *node, ...);
|
||||
|
||||
/*
|
||||
* Editor modelines - https://www.wireshark.org/tools/modelines.html
|
||||
*
|
||||
* Local variables:
|
||||
* c-basic-offset: 8
|
||||
* tab-width: 8
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*
|
||||
* vi: set shiftwidth=8 tabstop=8 expandtab:
|
||||
* :indentSize=8:tabSize=8:noTabs=true:
|
||||
*/
|
||||
@@ -0,0 +1,400 @@
|
||||
/*
|
||||
* This file is part of linux-steam-integration.
|
||||
*
|
||||
* Copyright © 2016-2017 Ikey Doherty <ikey@solus-project.com>
|
||||
*
|
||||
* linux-steam-integration is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1
|
||||
* of the License, or (at your option) any later version.
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include "main-window.h"
|
||||
#include "config.h"
|
||||
#include "lsi.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <glib/gi18n.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
struct _LsiSettingsWindow {
|
||||
GtkWindow parent;
|
||||
LsiConfig config; /**<Current LSI config */
|
||||
|
||||
/* Only when libintercept is enabled will we have this option */
|
||||
#ifdef HAVE_LIBINTERCEPT
|
||||
GtkWidget *check_intercept;
|
||||
#endif
|
||||
|
||||
/* Only when libredirect is enabled will we have this option */
|
||||
#ifdef HAVE_LIBREDIRECT
|
||||
GtkWidget *check_redirect;
|
||||
#endif
|
||||
|
||||
/* Always have these guys */
|
||||
GtkWidget *check_native;
|
||||
GtkWidget *check_emul32;
|
||||
};
|
||||
|
||||
struct _LsiSettingsWindowClass {
|
||||
GtkWindowClass parent_class;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE(LsiSettingsWindow, lsi_settings_window, GTK_TYPE_WINDOW)
|
||||
|
||||
static void _align_label(GtkWidget *label);
|
||||
static void insert_grid(GtkWidget *grid, int *row, const char *title, const char *description,
|
||||
GtkWidget *widget);
|
||||
static GtkWidget *insert_grid_toggle(GtkWidget *grid, int *row, const char *title,
|
||||
const char *description);
|
||||
static void set_row_sensitive(GtkWidget *toggle, gboolean sensitive);
|
||||
static void lsi_native_swapped(LsiSettingsWindow *window, gpointer v);
|
||||
static gboolean lsi_window_closed(LsiSettingsWindow *window, GdkEvent *event, gpointer v);
|
||||
|
||||
/**
|
||||
* lsi_settings_window_new:
|
||||
*
|
||||
* Construct a new LsiSettingsWindow object
|
||||
*/
|
||||
GtkWidget *lsi_settings_window_new()
|
||||
{
|
||||
return g_object_new(LSI_TYPE_SETTINGS_WINDOW, "type", GTK_WINDOW_TOPLEVEL, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* lsi_settings_window_dispose:
|
||||
*
|
||||
* Clean up a LsiSettingsWindow instance
|
||||
*/
|
||||
static void lsi_settings_window_dispose(GObject *obj)
|
||||
{
|
||||
G_OBJECT_CLASS(lsi_settings_window_parent_class)->dispose(obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* lsi_settings_window_class_init:
|
||||
*
|
||||
* Handle class initialisation
|
||||
*/
|
||||
static void lsi_settings_window_class_init(LsiSettingsWindowClass *klazz)
|
||||
{
|
||||
GObjectClass *obj_class = G_OBJECT_CLASS(klazz);
|
||||
|
||||
/* gobject vtable hookup */
|
||||
obj_class->dispose = lsi_settings_window_dispose;
|
||||
}
|
||||
|
||||
/**
|
||||
* lsi_settings_window_init:
|
||||
*
|
||||
* Handle construction of the LsiSettingsWindow
|
||||
*/
|
||||
static void lsi_settings_window_init(LsiSettingsWindow *self)
|
||||
{
|
||||
GtkWidget *grid = NULL;
|
||||
GtkWidget *layout = NULL;
|
||||
GtkWidget *header = NULL;
|
||||
GtkWidget *widget = NULL;
|
||||
GtkStyleContext *style = NULL;
|
||||
const gchar *xdg_desktop = NULL;
|
||||
const gchar *emul32_desc = NULL;
|
||||
bool is_64bit = false;
|
||||
gchar *label = NULL;
|
||||
int row = 0;
|
||||
|
||||
/* Ensure we correctly clean this up.. */
|
||||
memset(&self->config, 0, sizeof(LsiConfig));
|
||||
|
||||
/* Load the LSI configuration now */
|
||||
if (!lsi_config_load(&self->config)) {
|
||||
lsi_config_load_defaults(&self->config);
|
||||
}
|
||||
|
||||
/* Conditionally apply CSD */
|
||||
#if GTK_CHECK_VERSION(3, 12, 0)
|
||||
xdg_desktop = g_getenv("XDG_CURRENT_DESKTOP");
|
||||
if (xdg_desktop && (strstr(xdg_desktop, "GNOME:") || strstr(xdg_desktop, ":GNOME") ||
|
||||
g_str_equal(xdg_desktop, "GNOME"))) {
|
||||
widget = gtk_header_bar_new();
|
||||
gtk_header_bar_set_show_close_button(GTK_HEADER_BAR(widget), TRUE);
|
||||
gtk_window_set_titlebar(GTK_WINDOW(self), widget);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* For now we'll just exit on close */
|
||||
g_signal_connect(self, "delete-event", G_CALLBACK(lsi_window_closed), NULL);
|
||||
|
||||
/* Sort out window bits */
|
||||
gtk_window_set_title(GTK_WINDOW(self), _("Linux Steam® Integration"));
|
||||
gtk_window_set_icon_name(GTK_WINDOW(self), "steam");
|
||||
gtk_window_set_position(GTK_WINDOW(self), GTK_WIN_POS_CENTER);
|
||||
gtk_widget_set_size_request(GTK_WIDGET(self), 320, 500);
|
||||
gtk_window_set_resizable(GTK_WINDOW(self), FALSE);
|
||||
|
||||
/* Add main layout */
|
||||
layout = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
|
||||
gtk_container_add(GTK_CONTAINER(self), layout);
|
||||
gtk_container_set_border_width(GTK_CONTAINER(self), 12);
|
||||
gtk_widget_set_valign(GTK_WIDGET(layout), GTK_ALIGN_START);
|
||||
|
||||
/* Header box */
|
||||
header = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
|
||||
gtk_box_pack_start(GTK_BOX(layout), header, FALSE, FALSE, 0);
|
||||
|
||||
/* header label */
|
||||
label = g_strdup_printf("<big>%s</big>", _("Linux Steam® Integration"));
|
||||
widget = gtk_label_new(label);
|
||||
gtk_label_set_use_markup(GTK_LABEL(widget), TRUE);
|
||||
g_free(label);
|
||||
_align_label(widget);
|
||||
gtk_box_pack_start(GTK_BOX(header), widget, FALSE, FALSE, 0);
|
||||
|
||||
/* header image */
|
||||
widget = gtk_image_new_from_icon_name("steam", GTK_ICON_SIZE_DIALOG);
|
||||
gtk_widget_set_valign(widget, GTK_ALIGN_START);
|
||||
gtk_box_pack_end(GTK_BOX(header), widget, FALSE, FALSE, 0);
|
||||
|
||||
/* small label */
|
||||
widget = gtk_label_new(
|
||||
_("Control the behaviour of the Steam client and games. Settings will not take effect "
|
||||
"until the Steam Client is restarted. Use the 'Exit Steam' option to ensure it "
|
||||
"closes."));
|
||||
g_object_set(widget, "xalign", 0.0, NULL);
|
||||
gtk_label_set_max_width_chars(GTK_LABEL(widget), 80);
|
||||
gtk_label_set_line_wrap(GTK_LABEL(widget), TRUE);
|
||||
gtk_label_set_line_wrap_mode(GTK_LABEL(widget), PANGO_WRAP_WORD);
|
||||
_align_label(widget);
|
||||
gtk_box_pack_start(GTK_BOX(layout), widget, TRUE, TRUE, 0);
|
||||
style = gtk_widget_get_style_context(widget);
|
||||
gtk_style_context_add_class(style, GTK_STYLE_CLASS_DIM_LABEL);
|
||||
#if GTK_CHECK_VERSION(3, 12, 0)
|
||||
gtk_widget_set_margin_end(widget, 100);
|
||||
#else
|
||||
gtk_widget_set_margin_right(widget, 100);
|
||||
#endif
|
||||
/* add a separator now */
|
||||
widget = gtk_separator_new(GTK_ORIENTATION_HORIZONTAL);
|
||||
gtk_box_pack_start(GTK_BOX(layout), widget, FALSE, FALSE, 0);
|
||||
g_object_set(widget, "margin-top", 12, "margin-bottom", 4, NULL);
|
||||
|
||||
/* Start populating main grid with controls */
|
||||
grid = gtk_grid_new();
|
||||
gtk_box_pack_start(GTK_BOX(layout), grid, FALSE, FALSE, 0);
|
||||
|
||||
/* Start populating options into the UI */
|
||||
self->check_native = insert_grid_toggle(
|
||||
grid,
|
||||
&row,
|
||||
_("Use native runtime"),
|
||||
_("Switch between the native runtime and the bundled Steam runtime."));
|
||||
|
||||
/* Load in the existing configuration */
|
||||
gtk_switch_set_active(GTK_SWITCH(self->check_native), self->config.use_native_runtime);
|
||||
|
||||
is_64bit = lsi_system_is_64bit();
|
||||
/* Can only force on a 64-bit system. */
|
||||
if (!is_64bit) {
|
||||
/* Label is shown to indicate we can't enable 32-bit option */
|
||||
emul32_desc = _("This option has been disabled as the system is already 32-bit");
|
||||
} else {
|
||||
/* Label is shown on 64-bit systems only */
|
||||
emul32_desc =
|
||||
_("This may workaround some broken games, but will disable the Steam store "
|
||||
"browser.");
|
||||
}
|
||||
|
||||
self->check_emul32 =
|
||||
insert_grid_toggle(grid, &row, _("Force 32-bit mode for Steam"), emul32_desc);
|
||||
set_row_sensitive(self->check_emul32, is_64bit);
|
||||
gtk_switch_set_active(GTK_SWITCH(self->check_emul32), self->config.force_32);
|
||||
|
||||
#ifdef HAVE_LIBINTERCEPT
|
||||
self->check_intercept = insert_grid_toggle(
|
||||
grid,
|
||||
&row,
|
||||
_("Use the intercept library"),
|
||||
_("Force Steam applications to use more native libraries to maximise compatibility."));
|
||||
set_row_sensitive(self->check_intercept, FALSE);
|
||||
gtk_switch_set_active(GTK_SWITCH(self->check_intercept), self->config.use_libintercept);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIBREDIRECT
|
||||
self->check_redirect =
|
||||
insert_grid_toggle(grid,
|
||||
&row,
|
||||
_("Use the redirect library"),
|
||||
_("Override system calls to fix known bugs in some "
|
||||
"Linux ports."));
|
||||
set_row_sensitive(self->check_redirect, FALSE);
|
||||
gtk_switch_set_active(GTK_SWITCH(self->check_redirect), self->config.use_libredirect);
|
||||
#endif
|
||||
|
||||
/* Hook up our signals. Basically the "native runtime" option controls the two library
|
||||
* options, they must be used in conjunction.
|
||||
*/
|
||||
g_signal_connect_swapped(self->check_native,
|
||||
"notify::active",
|
||||
G_CALLBACK(lsi_native_swapped),
|
||||
self);
|
||||
|
||||
/* Ensure our properties are now in sync. */
|
||||
lsi_native_swapped(self, self->check_native);
|
||||
|
||||
/* Finally, make sure we're visible will we. */
|
||||
gtk_widget_show_all(GTK_WIDGET(self));
|
||||
}
|
||||
|
||||
static void _align_label(GtkWidget *label)
|
||||
{
|
||||
#if GTK_CHECK_VERSION(3, 12, 0)
|
||||
gtk_widget_set_halign(label, GTK_ALIGN_START);
|
||||
#else
|
||||
gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
|
||||
#endif
|
||||
gtk_widget_set_hexpand(label, FALSE);
|
||||
gtk_widget_set_valign(label, GTK_ALIGN_START);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic function to add titled description box with a custom widget into the grid.
|
||||
*/
|
||||
static void insert_grid(GtkWidget *grid, int *row, const char *title, const char *description,
|
||||
GtkWidget *widget)
|
||||
{
|
||||
GtkWidget *label = NULL;
|
||||
GtkWidget *desc = NULL;
|
||||
GtkStyleContext *style = NULL;
|
||||
|
||||
/* Sort out title label */
|
||||
label = gtk_label_new(title);
|
||||
_align_label(label);
|
||||
g_object_set(label, "margin-top", 12, "hexpand", TRUE, NULL);
|
||||
gtk_grid_attach(GTK_GRID(grid), label, 0, *row, 1, 1);
|
||||
|
||||
g_object_set(widget,
|
||||
"halign",
|
||||
GTK_ALIGN_END,
|
||||
"valign",
|
||||
GTK_ALIGN_END,
|
||||
"vexpand",
|
||||
FALSE,
|
||||
NULL);
|
||||
gtk_grid_attach(GTK_GRID(grid), widget, 1, *row, 1, 1);
|
||||
|
||||
*row += 1;
|
||||
|
||||
/* Sort out description label */
|
||||
desc = gtk_label_new(description);
|
||||
_align_label(desc);
|
||||
style = gtk_widget_get_style_context(desc);
|
||||
gtk_style_context_add_class(style, GTK_STYLE_CLASS_DIM_LABEL);
|
||||
#if GTK_CHECK_VERSION(3, 12, 0)
|
||||
gtk_widget_set_margin_end(desc, 12);
|
||||
#else
|
||||
gtk_widget_set_margin_right(desc, 12);
|
||||
#endif
|
||||
/* Deprecated but line wrap is busted without it.. */
|
||||
g_object_set(desc, "xalign", 0.0, NULL);
|
||||
gtk_label_set_line_wrap(GTK_LABEL(desc), TRUE);
|
||||
gtk_label_set_line_wrap_mode(GTK_LABEL(desc), PANGO_WRAP_WORD);
|
||||
gtk_label_set_max_width_chars(GTK_LABEL(desc), 90);
|
||||
|
||||
gtk_grid_attach(GTK_GRID(grid), desc, 0, *row, 1, 1);
|
||||
*row += 1;
|
||||
|
||||
/* Allow accessing these dynamic items again */
|
||||
g_object_set_data(G_OBJECT(widget), "lsi_title", label);
|
||||
g_object_set_data(G_OBJECT(widget), "lsi_desc", desc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the complete row within the grid to the given sensitivity state
|
||||
*/
|
||||
static void set_row_sensitive(GtkWidget *toggle, gboolean sensitive)
|
||||
{
|
||||
GtkWidget *title = NULL;
|
||||
GtkWidget *desc = NULL;
|
||||
|
||||
title = g_object_get_data(G_OBJECT(toggle), "lsi_title");
|
||||
desc = g_object_get_data(G_OBJECT(toggle), "lsi_desc");
|
||||
|
||||
gtk_widget_set_sensitive(toggle, sensitive);
|
||||
gtk_widget_set_sensitive(title, sensitive);
|
||||
gtk_widget_set_sensitive(desc, sensitive);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds on the insert_grid function to insert a GtkSwitch and return only the
|
||||
* switch widget.
|
||||
*/
|
||||
static GtkWidget *insert_grid_toggle(GtkWidget *grid, int *row, const char *title,
|
||||
const char *description)
|
||||
{
|
||||
GtkWidget *toggle = NULL;
|
||||
|
||||
/* Sort out widget */
|
||||
toggle = gtk_switch_new();
|
||||
insert_grid(grid, row, title, description, toggle);
|
||||
return toggle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the sensitivity of the UI controls based on whether or not we have
|
||||
* native runtime turned on
|
||||
*/
|
||||
static void lsi_native_swapped(LsiSettingsWindow *self, __lsi_unused__ gpointer v)
|
||||
{
|
||||
gboolean native_runtime;
|
||||
|
||||
native_runtime = gtk_switch_get_active(GTK_SWITCH(self->check_native));
|
||||
|
||||
#ifdef HAVE_LIBREDIRECT
|
||||
set_row_sensitive(self->check_redirect, native_runtime);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIBINTERCEPT
|
||||
set_row_sensitive(self->check_intercept, native_runtime);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Window is closed, so let's write our config out
|
||||
*/
|
||||
static gboolean lsi_window_closed(LsiSettingsWindow *self, __lsi_unused__ GdkEvent *event,
|
||||
__lsi_unused__ gpointer v)
|
||||
{
|
||||
/* Just pop the properties back into the struct */
|
||||
self->config.force_32 = gtk_switch_get_active(GTK_SWITCH(self->check_emul32));
|
||||
self->config.use_native_runtime = gtk_switch_get_active(GTK_SWITCH(self->check_native));
|
||||
|
||||
#ifdef HAVE_LIBREDIRECT
|
||||
self->config.use_libredirect = gtk_switch_get_active(GTK_SWITCH(self->check_redirect));
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIBINTERCEPT
|
||||
self->config.use_libredirect = gtk_switch_get_active(GTK_SWITCH(self->check_redirect));
|
||||
#endif
|
||||
|
||||
/* Try to write new config */
|
||||
if (!lsi_config_store(&self->config)) {
|
||||
lsi_report_failure("%s: %s", _("Failed to save configuration"), strerror(errno));
|
||||
}
|
||||
|
||||
gtk_main_quit();
|
||||
return FALSE;
|
||||
}
|
||||
/*
|
||||
* Editor modelines - https://www.wireshark.org/tools/modelines.html
|
||||
*
|
||||
* Local variables:
|
||||
* c-basic-offset: 8
|
||||
* tab-width: 8
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*
|
||||
* vi: set shiftwidth=8 tabstop=8 expandtab:
|
||||
* :indentSize=8:tabSize=8:noTabs=true:
|
||||
*/
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* This file is part of linux-steam-integration.
|
||||
*
|
||||
* Copyright © 2016-2017 Ikey Doherty <ikey@solus-project.com>
|
||||
*
|
||||
* linux-steam-integration is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1
|
||||
* of the License, or (at your option) any later version.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <glib-object.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _LsiSettingsWindow LsiSettingsWindow;
|
||||
typedef struct _LsiSettingsWindowClass LsiSettingsWindowClass;
|
||||
|
||||
#define LSI_TYPE_SETTINGS_WINDOW lsi_settings_window_get_type()
|
||||
#define LSI_SETTINGS_WINDOW(o) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST((o), LSI_TYPE_SETTINGS_WINDOW, LsiSettingsWindow))
|
||||
#define LSI_IS_SETTINGS_WINDOW(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), LSI_TYPE_SETTINGS_WINDOW))
|
||||
#define LSI_SETTINGS_WINDOW_CLASS(o) \
|
||||
(G_TYPE_CHECK_CLASS_CAST((o), LSI_TYPE_SETTINGS_WINDOW, LsiSettingsWindowClass))
|
||||
#define LSI_IS_SETTINGS_WINDOW_CLASS(o) (G_TYPE_CHECK_CLASS_TYPE((o), LSI_TYPE_SETTINGS_WINDOW))
|
||||
#define LSI_SETTINGS_WINDOW_GET_CLASS(o) \
|
||||
(G_TYPE_INSTANCE_GET_CLASS((o), LSI_TYPE_SETTINGS_WINDOW, LsiSettingsWindowClass))
|
||||
|
||||
GtkWidget *lsi_settings_window_new(void);
|
||||
|
||||
GType lsi_settings_window_get_type(void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
/*
|
||||
* Editor modelines - https://www.wireshark.org/tools/modelines.html
|
||||
*
|
||||
* Local variables:
|
||||
* c-basic-offset: 8
|
||||
* tab-width: 8
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*
|
||||
* vi: set shiftwidth=8 tabstop=8 expandtab:
|
||||
* :indentSize=8:tabSize=8:noTabs=true:
|
||||
*/
|
||||
+15
-144
@@ -11,160 +11,31 @@
|
||||
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include <errno.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <glib/gi18n.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "lsi.h"
|
||||
|
||||
static inline void _align_label(GtkWidget *label)
|
||||
{
|
||||
#if GTK_MINOR_VERSION <= 12
|
||||
gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
|
||||
#else
|
||||
gtk_widget_set_halign(label, GTK_ALIGN_START);
|
||||
#endif
|
||||
gtk_widget_set_hexpand(label, FALSE);
|
||||
gtk_widget_set_valign(label, GTK_ALIGN_START);
|
||||
}
|
||||
#include "main-window.h"
|
||||
|
||||
/**
|
||||
* Main application entry.
|
||||
*/
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
GtkWidget *window = NULL;
|
||||
|
||||
setlocale(LC_ALL, "");
|
||||
bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR);
|
||||
bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
|
||||
textdomain(GETTEXT_PACKAGE);
|
||||
|
||||
gtk_init(&argc, &argv);
|
||||
GtkWidget *dialog = NULL;
|
||||
GtkWidget *grid = NULL;
|
||||
GtkWidget *container = NULL;
|
||||
GtkWidget *button = NULL;
|
||||
GtkWidget *image = NULL;
|
||||
GtkWidget *check_native = NULL;
|
||||
GtkWidget *check_emul32 = NULL;
|
||||
#ifdef HAVE_LIBINTERCEPT
|
||||
GtkWidget *check_intercept = NULL;
|
||||
#endif
|
||||
GtkWidget *label = NULL;
|
||||
GtkSettings *settings = NULL;
|
||||
int response = 0;
|
||||
bool is_x86_64 = lsi_system_is_64bit();
|
||||
LsiConfig lconfig = { 0 };
|
||||
|
||||
dialog = gtk_dialog_new();
|
||||
g_object_set(G_OBJECT(dialog),
|
||||
"title",
|
||||
"Linux Steam® Integration",
|
||||
"icon-name",
|
||||
"steam",
|
||||
NULL);
|
||||
window = lsi_settings_window_new();
|
||||
gtk_widget_show(window);
|
||||
|
||||
settings = gtk_settings_get_default();
|
||||
g_object_set(settings, "gtk-application-prefer-dark-theme", TRUE, NULL);
|
||||
gtk_main();
|
||||
|
||||
/* Sort out the buttons */
|
||||
(void)gtk_dialog_add_button(GTK_DIALOG(dialog), "Cancel", GTK_RESPONSE_REJECT);
|
||||
button = gtk_dialog_add_button(GTK_DIALOG(dialog), "OK", GTK_RESPONSE_ACCEPT);
|
||||
gtk_style_context_add_class(gtk_widget_get_style_context(button), "suggested-action");
|
||||
|
||||
/* Pack the grid */
|
||||
grid = gtk_grid_new();
|
||||
gtk_grid_set_column_spacing(GTK_GRID(grid), 12);
|
||||
gtk_grid_set_row_spacing(GTK_GRID(grid), 12);
|
||||
|
||||
container = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
|
||||
gtk_container_add(GTK_CONTAINER(container), grid);
|
||||
gtk_container_set_border_width(GTK_CONTAINER(container), 6);
|
||||
|
||||
/* Add a splash of colour. */
|
||||
image = gtk_image_new_from_icon_name("steam", GTK_ICON_SIZE_DIALOG);
|
||||
gtk_image_set_pixel_size(GTK_IMAGE(image), 64);
|
||||
gtk_grid_attach(GTK_GRID(grid), image, 0, 0, 1, 1);
|
||||
|
||||
label = gtk_label_new(
|
||||
"<big>Linux Steam® Integration</big>\n"
|
||||
"Note that settings are not applied until the next time Steam® starts.\n"
|
||||
"Use the \'Exit Steam\' option on the Steam® tray icon to exit the application.");
|
||||
_align_label(label);
|
||||
gtk_grid_attach(GTK_GRID(grid), label, 1, 0, 2, 1);
|
||||
gtk_label_set_use_markup(GTK_LABEL(label), TRUE);
|
||||
gtk_widget_set_margin_bottom(label, 8);
|
||||
|
||||
label = gtk_label_new("Use the native runtime provided by the Operating System");
|
||||
_align_label(label);
|
||||
gtk_widget_set_tooltip_text(label,
|
||||
"Alternatively, the default Steam® runtime "
|
||||
"will be used, which may cause issues.");
|
||||
gtk_grid_attach(GTK_GRID(grid), label, 1, 1, 1, 1);
|
||||
check_native = gtk_switch_new();
|
||||
gtk_grid_attach(GTK_GRID(grid), check_native, 2, 1, 1, 1);
|
||||
|
||||
/* Handle the 32-bit cruft */
|
||||
label = gtk_label_new("Force 32-bit mode for Steam®");
|
||||
_align_label(label);
|
||||
if (is_x86_64) {
|
||||
gtk_widget_set_tooltip_text(label,
|
||||
"Some games may run better using 32-bit than 64-bit");
|
||||
} else {
|
||||
gtk_widget_set_tooltip_text(label, "You are using a 32-bit operating system");
|
||||
}
|
||||
|
||||
gtk_grid_attach(GTK_GRID(grid), label, 1, 2, 1, 1);
|
||||
check_emul32 = gtk_switch_new();
|
||||
gtk_grid_attach(GTK_GRID(grid), check_emul32, 2, 2, 1, 1);
|
||||
|
||||
gtk_widget_set_sensitive(label, is_x86_64);
|
||||
gtk_widget_set_sensitive(check_emul32, is_x86_64);
|
||||
|
||||
#ifdef HAVE_LIBINTERCEPT
|
||||
label = gtk_label_new("Use liblsi-intercept to override Steam's library loading mechanism");
|
||||
_align_label(label);
|
||||
gtk_widget_set_tooltip_text(label,
|
||||
"This can help with many library issues with the core client");
|
||||
gtk_grid_attach(GTK_GRID(grid), label, 1, 3, 1, 1);
|
||||
check_intercept = gtk_switch_new();
|
||||
gtk_grid_attach(GTK_GRID(grid), check_intercept, 2, 3, 1, 1);
|
||||
#endif
|
||||
|
||||
gtk_container_set_border_width(GTK_CONTAINER(grid), 6);
|
||||
gtk_widget_set_margin_bottom(grid, 18);
|
||||
|
||||
/* Load the config */
|
||||
if (!lsi_config_load(&lconfig)) {
|
||||
lsi_config_load_defaults(&lconfig);
|
||||
}
|
||||
|
||||
/* Adapt UI to match config */
|
||||
gtk_switch_set_active(GTK_SWITCH(check_native), lconfig.use_native_runtime);
|
||||
gtk_switch_set_active(GTK_SWITCH(check_emul32), lconfig.force_32);
|
||||
|
||||
#ifdef HAVE_LIBINTERCEPT
|
||||
gtk_switch_set_active(GTK_SWITCH(check_intercept), lconfig.use_libintercept);
|
||||
#endif
|
||||
|
||||
/* Run the dialog */
|
||||
gtk_widget_show_all(container);
|
||||
response = gtk_dialog_run(GTK_DIALOG(dialog));
|
||||
|
||||
if (response == GTK_RESPONSE_REJECT) {
|
||||
gtk_widget_destroy(dialog);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
/* Get the config from the UI */
|
||||
lconfig.use_native_runtime = gtk_switch_get_active(GTK_SWITCH(check_native));
|
||||
lconfig.force_32 = gtk_switch_get_active(GTK_SWITCH(check_emul32));
|
||||
#ifdef HAVE_LIBINTERCEPT
|
||||
lconfig.use_libintercept = gtk_switch_get_active(GTK_SWITCH(check_intercept));
|
||||
#endif
|
||||
|
||||
/* Cleanup */
|
||||
gtk_widget_destroy(dialog);
|
||||
|
||||
/* Try to write new config */
|
||||
if (!lsi_config_store(&lconfig)) {
|
||||
lsi_report_failure("Failed to save configuration: %s", strerror(errno));
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ if with_frontend == true
|
||||
|
||||
frontend_sources = [
|
||||
'main.c',
|
||||
'main-window.c',
|
||||
]
|
||||
|
||||
frontend = executable(
|
||||
|
||||
+456
-109
@@ -11,68 +11,168 @@
|
||||
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include <libgen.h>
|
||||
#include <link.h>
|
||||
#include <linux/limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "../common.h"
|
||||
#include "nica/nica.h"
|
||||
#include "../common/common.h"
|
||||
#include "../common/files.h"
|
||||
#include "../common/log.h"
|
||||
#include "config.h"
|
||||
#include "nica/util.h"
|
||||
|
||||
/**
|
||||
* Is this a process we're actually interested in?
|
||||
* What's the known process name?
|
||||
*/
|
||||
static bool process_supported = false;
|
||||
static const char *matched_process = NULL;
|
||||
|
||||
/**
|
||||
* Determine the basename'd process
|
||||
* We support a number of modes, but we mostly exist to make Steam behave
|
||||
*/
|
||||
static inline char *get_process_name(void)
|
||||
typedef enum {
|
||||
INTERCEPT_MODE_NONE = 0,
|
||||
INTERCEPT_MODE_STEAM,
|
||||
INTERCEPT_MODE_VENDOR_OFFENDER,
|
||||
} InterceptMode;
|
||||
|
||||
/**
|
||||
* by default, we're not "on"
|
||||
*/
|
||||
static InterceptMode work_mode = INTERCEPT_MODE_NONE;
|
||||
|
||||
/* Patterns we'll permit Steam to privately load */
|
||||
static const char *steam_allowed[] = {
|
||||
/* general */
|
||||
"libicui18n.so",
|
||||
"libicuuc.so",
|
||||
"libavcodec.so.",
|
||||
"libavformat.so.",
|
||||
"libavresample.so.",
|
||||
"libavutil.so.",
|
||||
"libswscale.so.",
|
||||
"libx264.so.",
|
||||
|
||||
/* core plugins */
|
||||
"chromehtml.so",
|
||||
"crashhandler.so",
|
||||
"filesystem_stdio.so",
|
||||
"friendsui.so",
|
||||
"gameoverlayrenderer.so",
|
||||
"gameoverlayui.so",
|
||||
"libaudio.so",
|
||||
"libmiles.so",
|
||||
"libopenvr_api.so",
|
||||
"liboverride.so",
|
||||
"libsteam.so",
|
||||
"libtier0_s.so",
|
||||
"libv8.so",
|
||||
"libvideo.so",
|
||||
"libvstdlib_s.so",
|
||||
"serverbrowser.so",
|
||||
"steamclient.so",
|
||||
"steamoverlayvulkanlayer.so",
|
||||
"steamservice.so",
|
||||
"steamui.so",
|
||||
"vgui2_s.so",
|
||||
|
||||
/* big picture mode */
|
||||
"panorama",
|
||||
"libpangoft2-1.0.so",
|
||||
"libpango-1.0.so",
|
||||
|
||||
/* steamwebhelper */
|
||||
"libcef.so",
|
||||
|
||||
/* Swift shader */
|
||||
"libGLESv2.so",
|
||||
};
|
||||
|
||||
static const char *wanted_steam_processes[] = {
|
||||
"html5app_steam",
|
||||
"opengl-program",
|
||||
"steam",
|
||||
"steamwebhelper",
|
||||
};
|
||||
|
||||
/**
|
||||
* Vendor offendors should not be allowed to load replacements for libraries
|
||||
* that are KNOWN to cause issues, i.e. SDL + libstdc++
|
||||
*/
|
||||
static const char *vendor_blacklist[] = {
|
||||
/* base libraries being replaced will cause a C++ ABI issue when
|
||||
* loading the mesalib drivers. */
|
||||
"libgcc_",
|
||||
"libstdc++",
|
||||
"libSDL",
|
||||
|
||||
/* general problem causer. */
|
||||
"libopenal.so.",
|
||||
|
||||
/* thou shalt not replace drivers (swiftshader) ! */
|
||||
"libGLESv2.so",
|
||||
"libGL.so",
|
||||
|
||||
/* glews (provide glew + glew110 in your distro for full compat) */
|
||||
"libGLEW.so.1.10",
|
||||
"libGLEW.so.1.12",
|
||||
|
||||
/* libglu has stable soname */
|
||||
"libGLU.so.",
|
||||
|
||||
/* Security sensitive libraries should not be replaced */
|
||||
"libcurl.so.",
|
||||
|
||||
#ifdef LSI_OVERRIDE_LIBRESSL
|
||||
/* Sometimes libressl but this is handled separately. */
|
||||
"libcrypto.so.",
|
||||
"libssl.so.",
|
||||
#else
|
||||
"libcrypto.so.1.0.0",
|
||||
"libssl.so.1.0.0",
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
* Determine if we're in a given process set, i.e. the process name matches
|
||||
* the given table
|
||||
*/
|
||||
static bool is_in_process_set(char *process_name, const char **processes, size_t n_processes)
|
||||
{
|
||||
autofree(char) *realp = NULL;
|
||||
char *basep = NULL;
|
||||
|
||||
realp = realpath("/proc/self/exe", NULL);
|
||||
if (!realp) {
|
||||
return false;
|
||||
/* Are we some portion of the process set? */
|
||||
for (size_t i = 0; i < n_processes; i++) {
|
||||
if (streq(processes[i], process_name)) {
|
||||
work_mode = INTERCEPT_MODE_STEAM;
|
||||
matched_process = processes[i];
|
||||
lsi_log_debug("loading libintercept for '%s'", matched_process);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
basep = basename(realp);
|
||||
return strdup(basep);
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find out if we're being executed by a process we actually need to override,
|
||||
* otherwise we'd not be loaded by rtld-audit
|
||||
*/
|
||||
static bool is_intercept_candidate(void)
|
||||
static void check_is_intercept_candidate(void)
|
||||
{
|
||||
static const char *wanted_processes[] = {
|
||||
"html5app_steam",
|
||||
"opengl-program",
|
||||
"steam",
|
||||
"steamwebhelper",
|
||||
};
|
||||
autofree(char) *nom = NULL;
|
||||
|
||||
nom = get_process_name();
|
||||
nom = lsi_get_process_base_name();
|
||||
if (!nom) {
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < ARRAY_SIZE(wanted_processes); i++) {
|
||||
if (streq(wanted_processes[i], nom)) {
|
||||
matched_process = wanted_processes[i];
|
||||
if (!getenv("LSI_DEBUG")) {
|
||||
return true;
|
||||
}
|
||||
fprintf(stderr,
|
||||
"\033[32;1m[LSI:%s]\033[0m: debug: loading libintercept from LSI\n",
|
||||
matched_process);
|
||||
return true;
|
||||
}
|
||||
if (is_in_process_set(nom, wanted_steam_processes, ARRAY_SIZE(wanted_steam_processes))) {
|
||||
work_mode = INTERCEPT_MODE_STEAM;
|
||||
} else {
|
||||
work_mode = INTERCEPT_MODE_VENDOR_OFFENDER;
|
||||
matched_process = "vendor_offender";
|
||||
}
|
||||
return false;
|
||||
lsi_log_set_id(matched_process);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -82,83 +182,17 @@ static bool is_intercept_candidate(void)
|
||||
_nica_public_ unsigned int la_version(unsigned int supported_version)
|
||||
{
|
||||
/* Unfortunately glibc will die if we tell it to skip us .. */
|
||||
process_supported = is_intercept_candidate();
|
||||
check_is_intercept_candidate();
|
||||
return supported_version;
|
||||
}
|
||||
|
||||
/**
|
||||
* emit_overriden lib is used to pretty-print the debug when we blacklist
|
||||
* a vendored library
|
||||
* lsi_search_steam handles whitelisting for the main Steam processes
|
||||
*/
|
||||
static void emit_overriden_lib(const char *lib_name)
|
||||
char *lsi_search_steam(const char *name)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"\033[32;1m[LSI:%s]\033[0m: debug: blacklisted loading of vendored library: "
|
||||
"\033[34;1m%s\033[0m\n",
|
||||
matched_process,
|
||||
lib_name);
|
||||
}
|
||||
|
||||
/**
|
||||
* la_objsearch will allow us to blacklist certain LD_LIBRARY_PATH duplicate
|
||||
* libraries being loaded by the Steam client, such as the broken libSDL shipped
|
||||
* as a private vendored lib
|
||||
*/
|
||||
_nica_public_ char *la_objsearch(const char *name, __lsi_unused__ uintptr_t *cookie,
|
||||
__lsi_unused__ unsigned int flag)
|
||||
{
|
||||
/* We don't know about this process, so have glibc do its thing as normal */
|
||||
if (!process_supported) {
|
||||
return (char *)name;
|
||||
}
|
||||
|
||||
// Patterns we'll permit Steam to privately load
|
||||
static const char *steam_allowed[] = {
|
||||
/* general */
|
||||
"libicui18n.so",
|
||||
"libicuuc.so",
|
||||
"libavcodec.so.",
|
||||
"libavformat.so.",
|
||||
"libavresample.so.",
|
||||
"libavutil.so.",
|
||||
"libswscale.so.",
|
||||
|
||||
/* core plugins */
|
||||
"chromehtml.so",
|
||||
"crashhandler.so",
|
||||
"filesystem_stdio.so",
|
||||
"friendsui.so",
|
||||
"gameoverlayrenderer.so",
|
||||
"gameoverlayui.so",
|
||||
"libaudio.so",
|
||||
"libicui18n.so",
|
||||
"libicuuc.so",
|
||||
"libmiles.so",
|
||||
"libopenvr_api.so",
|
||||
"liboverride.so",
|
||||
"libsteam.so",
|
||||
"libtier0_s.so",
|
||||
"libv8.so",
|
||||
"libvideo.so",
|
||||
"libvstdlib_s.so",
|
||||
"serverbrowser.so",
|
||||
"steamclient.so",
|
||||
"steamoverlayvulkanlayer.so",
|
||||
"steamservice.so",
|
||||
"steamui.so",
|
||||
"vgui2_s.so",
|
||||
|
||||
/* big picture mode */
|
||||
"panorama",
|
||||
"libpangoft2-1.0.so",
|
||||
"libpango-1.0.so",
|
||||
|
||||
/* steamwebhelper */
|
||||
"libcef.so",
|
||||
};
|
||||
|
||||
/* Find out if it exists */
|
||||
bool file_exists = nc_file_exists(name);
|
||||
bool file_exists = lsi_file_exists(name);
|
||||
|
||||
/* Find out if its a Steam private lib.. These are relative "./" files too! */
|
||||
if (name && (strstr(name, "/Steam/") || strncmp(name, "./", 2) == 0)) {
|
||||
@@ -167,9 +201,9 @@ _nica_public_ char *la_objsearch(const char *name, __lsi_unused__ uintptr_t *coo
|
||||
return (char *)name;
|
||||
}
|
||||
}
|
||||
/* If LSI_DEBUG is set, spam it. */
|
||||
if (getenv("LSI_DEBUG") && file_exists) {
|
||||
emit_overriden_lib(name);
|
||||
if (file_exists) {
|
||||
lsi_log_debug("blacklisted loading of vendor library: \033[34;1m%s\033[0m",
|
||||
name);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
@@ -178,6 +212,319 @@ _nica_public_ char *la_objsearch(const char *name, __lsi_unused__ uintptr_t *coo
|
||||
return (char *)name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Source identifier patterns that indicate a soname replacement is happening.
|
||||
* Note that this is a basic pattern match for the soname and just allows us
|
||||
* to lookup the transmute target
|
||||
*/
|
||||
static const char *vendor_transmute_source[] = {
|
||||
/* Common */
|
||||
"libSDL2-2.0.",
|
||||
"libSDL2_image-2.0.",
|
||||
|
||||
/* ".so" renames */
|
||||
"libSDL2_ttf.so",
|
||||
"libSDL2_image.so",
|
||||
"libSDL2_mixer.so",
|
||||
"libSDL2_net.so",
|
||||
"libSDL2_gfx.so",
|
||||
|
||||
/* libressl (security updates) */
|
||||
#ifdef LSI_OVERRIDE_LIBRESSL
|
||||
"libcrypto.so.36",
|
||||
"libssl.so.37",
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
* The transmute target is the intended replacement for any source name, assuming
|
||||
* that the soname doesn't identically match the currently requested soname.
|
||||
* This allows us to do on the fly replacements for re-soname'd libraries.
|
||||
*/
|
||||
static const char *vendor_transmute_target[] = {
|
||||
/* Common */
|
||||
"libSDL2-2.0.so.0",
|
||||
"libSDL2_image-2.0.so.0",
|
||||
|
||||
/* ".so" renames */
|
||||
"libSDL2_ttf-2.0.so.0",
|
||||
"libSDL2_image-2.0.so.0",
|
||||
"libSDL2_mixer-2.0.so.0",
|
||||
"libSDL2_net-2.0.so.0",
|
||||
"libSDL2_gfx-1.0.so.0",
|
||||
|
||||
/* libressl (security updates) */
|
||||
#if defined(LSI_LIBRESSL_MODE_SHIM)
|
||||
"libcrypto" LSI_LIBRESSL_SUFFIX ".so",
|
||||
"libssl" LSI_LIBRESSL_SUFFIX ".so",
|
||||
#elif defined(LSI_LIBRESSL_MODE_NATIVE)
|
||||
"libcrypto.so.1.0.0",
|
||||
"libssl.so.1.0.0",
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
* Every so often a game comes along that does the following:
|
||||
*
|
||||
* open("path") ? dlopen("path").
|
||||
* Except: path = "*.dll", dlopen() is transformed to ".dll.so"
|
||||
*
|
||||
* This is unrelated to the ".la" errors
|
||||
*/
|
||||
static bool lsi_override_dll_fail(const char *orig_name, const char **soname)
|
||||
{
|
||||
size_t len = strlen(orig_name);
|
||||
static char path_lookup[PATH_MAX];
|
||||
|
||||
if (len < 7) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (strncmp(orig_name + (len - 7), ".dll.so", 7) != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!strncpy(path_lookup, orig_name, len - 3)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!lsi_file_exists(path_lookup)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
*soname = path_lookup;
|
||||
lsi_log_debug("fixed invalid suffix dlopen() \033[31;1m%s\033[0m -> \033[34;1m%s\033[0m",
|
||||
orig_name,
|
||||
path_lookup);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mono games might try looking for /x86/ plugin directory for a 64-bit process,
|
||||
* as seen with testing with Project Highrise.
|
||||
*
|
||||
* This function simply redirects the dlopen to the file in the x86_64 directory,
|
||||
* if it actually exists.
|
||||
*
|
||||
* Typically this is for libCSteamWorks, libsteam_api, and Unity ScreenSelector.so
|
||||
*/
|
||||
#if UINTPTR_MAX == 0xffffffffffffffff
|
||||
static bool lsi_override_x86_derp(const char *orig_name, const char **soname)
|
||||
{
|
||||
static char path_copy[PATH_MAX];
|
||||
static char path_lookup[PATH_MAX];
|
||||
char *small_name = NULL;
|
||||
char *dir = NULL;
|
||||
|
||||
if (!(strstr(orig_name, "/Plugins/x86/") && strstr(orig_name, ".so"))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!strcpy(path_copy, orig_name)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
small_name = basename(path_copy);
|
||||
dir = dirname(path_copy);
|
||||
|
||||
if (snprintf(path_lookup, sizeof(path_lookup), "%s/../x86_64/%s", dir, small_name) < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!lsi_file_exists(path_lookup)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
*soname = path_lookup;
|
||||
lsi_log_debug(
|
||||
"fixed invalid architecture dlopen() \033[31;1m%s\033[0m -> \033[34;1m%s\033[0m",
|
||||
orig_name,
|
||||
path_lookup);
|
||||
return true;
|
||||
#else
|
||||
static bool lsi_override_x86_derp(__lsi_unused__ const char *orig_name,
|
||||
__lsi_unused__ const char **soname)
|
||||
{
|
||||
/* Don't perform x86 translation on 32-bit machines */
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* lsi_override_dlopen is used to override simple dlopen() requests typically
|
||||
* used by Mono games, i.e.:
|
||||
*
|
||||
* <dllmap dll="SDL2.dll" os="linux" cpu="x86-64" target="./lib64/libSDL2-2.0.so.0"/>
|
||||
*
|
||||
* We'll attempt to do a trivial lookup for "/usr/./lib64/libSDL2-2.0.so.0 in this
|
||||
* case.
|
||||
*/
|
||||
static bool lsi_override_dlopen(const char *orig_name, const char **soname)
|
||||
{
|
||||
static char path_lookup[PATH_MAX];
|
||||
static char path_copy[PATH_MAX];
|
||||
char *small_name = NULL;
|
||||
static const char *library_paths[] = {
|
||||
#if UINTPTR_MAX == 0xffffffffffffffff
|
||||
"/usr/lib64",
|
||||
"/usr/lib/x86_64-linux-gnu",
|
||||
"/usr/lib",
|
||||
#else
|
||||
"/usr/lib32",
|
||||
"/usr/lib/i386-linux-gnu",
|
||||
"/usr/lib",
|
||||
#endif
|
||||
};
|
||||
|
||||
if (lsi_override_dll_fail(orig_name, soname)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!lsi_file_exists(orig_name)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (lsi_override_x86_derp(orig_name, soname)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!strcpy(path_copy, orig_name)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
small_name = basename(path_copy);
|
||||
|
||||
/* Iterate all of the library paths for this process architecture and try
|
||||
* to find a system variant of the library instead of allowing the process
|
||||
* to dlopen() the vendored version.
|
||||
*/
|
||||
for (size_t i = 0; i < ARRAY_SIZE(library_paths); i++) {
|
||||
if (snprintf(path_lookup,
|
||||
sizeof(path_lookup),
|
||||
"%s/%s",
|
||||
library_paths[i],
|
||||
small_name) < 0) {
|
||||
return false;
|
||||
}
|
||||
if (!lsi_file_exists(path_lookup)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* We hit a match but it was identical to our expectation */
|
||||
if (strcmp(path_lookup, orig_name) == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
*soname = path_lookup;
|
||||
lsi_log_debug(
|
||||
"intercepting vendor dlopen() \033[31;1m%s\033[0m -> \033[34;1m%s\033[0m",
|
||||
orig_name,
|
||||
path_lookup);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* lsi_override_soname will deal with LA_SER_ORIG entries, i.e. the original
|
||||
* soname request when the linker tries to load a library.
|
||||
*
|
||||
* Certain Steam games (notably Feral Interactive ports) use their own vendored
|
||||
* SDL libraries with changed sonames, which are implicitly blacklisted by the
|
||||
* lsi_blacklist_vendor function.
|
||||
*
|
||||
* As such, we intercept those renamed libraries, and convert their names back
|
||||
* to the ABI stable system libraries on the fly.
|
||||
*/
|
||||
static bool lsi_override_soname(unsigned int flag, const char *orig_name, const char **soname)
|
||||
{
|
||||
*soname = NULL;
|
||||
|
||||
/* We only need to deal with LA_SER_ORIG */
|
||||
if ((flag & LA_SER_ORIG) != LA_SER_ORIG) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Don't transform dlopen */
|
||||
if (strstr(orig_name, "/")) {
|
||||
return lsi_override_dlopen(orig_name, soname);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < ARRAY_SIZE(vendor_transmute_source); i++) {
|
||||
if (!strstr(orig_name, vendor_transmute_source[i])) {
|
||||
continue;
|
||||
}
|
||||
/* Ensure we're not just replacing the same thing here as the
|
||||
* string would be identical, no real replacement would happen,
|
||||
* and ld will be confused about memory and die.
|
||||
*/
|
||||
if (streq(orig_name, vendor_transmute_target[i])) {
|
||||
continue;
|
||||
}
|
||||
*soname = vendor_transmute_target[i];
|
||||
lsi_log_debug(
|
||||
"transforming vendor soname: \033[31;1m%s\033[0m -> \033[34;1m%s\033[0m",
|
||||
orig_name,
|
||||
*soname);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
char *lsi_blacklist_vendor(unsigned int flag, const char *name)
|
||||
{
|
||||
/* Find out if it exists */
|
||||
bool file_exists = lsi_file_exists(name);
|
||||
const char *override_soname = NULL;
|
||||
|
||||
/* Find out if we have to rename some libraries on the fly */
|
||||
if (lsi_override_soname(flag, name, &override_soname)) {
|
||||
return (char *)override_soname;
|
||||
}
|
||||
|
||||
/* Find out if its a Steam private lib.. These are relative "./" files too! */
|
||||
if (name && (strstr(name, "/Steam/") || strncmp(name, "./", 2) == 0)) {
|
||||
for (size_t i = 0; i < ARRAY_SIZE(vendor_blacklist); i++) {
|
||||
if (!strstr(name, vendor_blacklist[i])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (file_exists) {
|
||||
lsi_log_debug(
|
||||
"blacklisted loading of vendor library: \033[34;1m%s\033[0m",
|
||||
name);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
/* Allowed to exist */
|
||||
return (char *)name;
|
||||
}
|
||||
|
||||
return (char *)name;
|
||||
}
|
||||
|
||||
/**
|
||||
* la_objsearch will allow us to blacklist certain LD_LIBRARY_PATH duplicate
|
||||
* libraries being loaded by the Steam client, such as the broken libSDL shipped
|
||||
* as a private vendored lib
|
||||
*/
|
||||
_nica_public_ char *la_objsearch(const char *name, __lsi_unused__ uintptr_t *cookie,
|
||||
unsigned int flag)
|
||||
{
|
||||
switch (work_mode) {
|
||||
case INTERCEPT_MODE_STEAM:
|
||||
return lsi_search_steam(name);
|
||||
case INTERCEPT_MODE_VENDOR_OFFENDER:
|
||||
return lsi_blacklist_vendor(flag, name);
|
||||
case INTERCEPT_MODE_NONE:
|
||||
default:
|
||||
return (char *)name;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Editor modelines - https://www.wireshark.org/tools/modelines.html
|
||||
*
|
||||
|
||||
@@ -6,10 +6,17 @@ if with_libintercept == true
|
||||
'main.c',
|
||||
]
|
||||
|
||||
sym_map = join_paths(meson.current_source_dir(), 'sym.map')
|
||||
|
||||
main_intercept = shared_library(
|
||||
'lsi-intercept',
|
||||
sources: intercept_sources + nica_sources,
|
||||
sources: intercept_sources,
|
||||
c_args: ['-fvisibility=hidden'],
|
||||
link_args: ['-Wl,--version-script=@0@'.format(sym_map)],
|
||||
include_directories: nica_includes,
|
||||
dependencies: [
|
||||
link_lsi_common,
|
||||
],
|
||||
install: true,
|
||||
)
|
||||
endif
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
global:
|
||||
la_objsearch;
|
||||
la_version;
|
||||
local:
|
||||
*;
|
||||
};
|
||||
+14
-34
@@ -26,6 +26,8 @@
|
||||
#include "nica/hashmap.h"
|
||||
#include "nica/inifile.h"
|
||||
|
||||
#include "../common/files.h"
|
||||
|
||||
/**
|
||||
* Configuration file suffix, i.e. ~/.config/linux-steam-integration.conf
|
||||
*/
|
||||
@@ -42,38 +44,6 @@
|
||||
*/
|
||||
#define LSI_VENDOR_CONFIG_FILE VENDORDIR "/ " LSI_CONFIG_FILE
|
||||
|
||||
/**
|
||||
* Determine the home directory
|
||||
*/
|
||||
static const char *lsi_get_home_dir(void)
|
||||
{
|
||||
char *c = NULL;
|
||||
struct passwd *p = NULL;
|
||||
|
||||
c = getenv("HOME");
|
||||
if (c) {
|
||||
return c;
|
||||
}
|
||||
p = getpwuid(getuid());
|
||||
if (!p) {
|
||||
return NULL;
|
||||
}
|
||||
return p->pw_dir;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the home config directory
|
||||
*/
|
||||
static char *lsi_get_user_config_dir(void)
|
||||
{
|
||||
const char *home = lsi_get_home_dir();
|
||||
char *c = NULL;
|
||||
if (asprintf(&c, "%s/.config", home) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the user config file path
|
||||
*/
|
||||
@@ -150,6 +120,13 @@ bool lsi_config_load(LsiConfig *config)
|
||||
map_val = NULL;
|
||||
}
|
||||
|
||||
/* Do we want libredirect? */
|
||||
map_val = nc_hashmap_get(nc_hashmap_get(mconfig, "Steam"), "use-libredirect");
|
||||
if (map_val) {
|
||||
config->use_libredirect = lsi_is_boolean_true(map_val);
|
||||
map_val = NULL;
|
||||
}
|
||||
|
||||
/* Check if 32-bit is being forced */
|
||||
map_val = nc_hashmap_get(nc_hashmap_get(mconfig, "Steam"), "force-32bit");
|
||||
if (map_val) {
|
||||
@@ -185,10 +162,12 @@ bool lsi_config_store(LsiConfig *config)
|
||||
return false;
|
||||
}
|
||||
if (fprintf(fp,
|
||||
"[Steam]\nuse-native-runtime = %s\nforce-32bit = %s\nuse-libintercept = %s\n",
|
||||
"[Steam]\nuse-native-runtime = %s\nforce-32bit = %s\nuse-libintercept = "
|
||||
"%s\nuse-libredirect = %s\n",
|
||||
lsi_bool_to_string(config->use_native_runtime),
|
||||
lsi_bool_to_string(config->force_32),
|
||||
lsi_bool_to_string(config->use_libintercept)) < 0) {
|
||||
lsi_bool_to_string(config->use_libintercept),
|
||||
lsi_bool_to_string(config->use_libredirect)) < 0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -203,6 +182,7 @@ void lsi_config_load_defaults(LsiConfig *config)
|
||||
config->force_32 = false;
|
||||
config->use_native_runtime = true;
|
||||
config->use_libintercept = true;
|
||||
config->use_libredirect = true;
|
||||
}
|
||||
|
||||
void lsi_report_failure(const char *s, ...)
|
||||
|
||||
+2
-11
@@ -17,10 +17,9 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "../common.h"
|
||||
#include "../common/common.h"
|
||||
#include "config.h"
|
||||
|
||||
/**
|
||||
@@ -30,6 +29,7 @@ typedef struct LsiConfig {
|
||||
bool force_32; /**<Do we force 32-bit? */
|
||||
bool use_native_runtime; /**<Do we force our native runtime? */
|
||||
bool use_libintercept; /**<Do we force libintercept? */
|
||||
bool use_libredirect; /**<Do we force libredirect? */
|
||||
} LsiConfig;
|
||||
|
||||
/**
|
||||
@@ -96,15 +96,6 @@ __lsi_inline__ static inline const char *lsi_preload_list(void)
|
||||
*/
|
||||
void lsi_report_failure(const char *s, ...);
|
||||
|
||||
/**
|
||||
* Quick helper to determine if the path exists
|
||||
*/
|
||||
__lsi_inline__ static inline bool lsi_file_exists(const char *path)
|
||||
{
|
||||
__lsi_unused__ struct stat st = { 0 };
|
||||
return lstat(path, &st) == 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Editor modelines - https://www.wireshark.org/tools/modelines.html
|
||||
*
|
||||
|
||||
+4
-1
@@ -8,7 +8,10 @@ if shim_behaviour != 'none' or with_frontend == true
|
||||
|
||||
lib_lsi = static_library(
|
||||
'lsi-lsi',
|
||||
sources: lsi_sources + nica_sources,
|
||||
sources: lsi_sources,
|
||||
dependencies: [
|
||||
link_lsi_common,
|
||||
],
|
||||
include_directories: nica_includes,
|
||||
)
|
||||
link_lsi = declare_dependency(
|
||||
|
||||
@@ -16,7 +16,9 @@ nica_includes = [
|
||||
config_h_dir,
|
||||
]
|
||||
|
||||
subdir('common')
|
||||
subdir('lsi')
|
||||
subdir('frontend')
|
||||
subdir('intercept')
|
||||
subdir('redirect')
|
||||
subdir('shim')
|
||||
|
||||
@@ -0,0 +1,353 @@
|
||||
/*
|
||||
* This file is part of linux-steam-integration.
|
||||
*
|
||||
* Copyright © 2017 Ikey Doherty <ikey@solus-project.com>
|
||||
*
|
||||
* linux-steam-integration is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1
|
||||
* of the License, or (at your option) any later version.
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <libgen.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "../common/common.h"
|
||||
#include "../common/files.h"
|
||||
#include "../common/log.h"
|
||||
#include "nica/util.h"
|
||||
|
||||
#include "profile.h"
|
||||
#include "redirect.h"
|
||||
|
||||
#define _STRINGIFY(x) #x
|
||||
|
||||
#define SYMBOL_BINDING(l, x) \
|
||||
{ \
|
||||
.handle = &lsi_table.handles.l, .name = _STRINGIFY(x), \
|
||||
.func = (void **)(&lsi_table.x), .func_size = sizeof(lsi_table.x) \
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether we've initialised yet or not.
|
||||
*/
|
||||
static volatile bool lsi_init = false;
|
||||
|
||||
/**
|
||||
* Whether we should actually perform overrides
|
||||
* This is determined by the process name
|
||||
*/
|
||||
static volatile bool lsi_override = false;
|
||||
|
||||
/**
|
||||
* Handle definitions
|
||||
*/
|
||||
typedef int (*lsi_open_file)(const char *p, int flags, mode_t mode);
|
||||
|
||||
typedef FILE *(*lsi_fopen64_file)(const char *p, const char *modes);
|
||||
|
||||
/**
|
||||
* Known profiles
|
||||
*/
|
||||
static lsi_profile_generator_func generators[] = {
|
||||
&lsi_redirect_profile_new_ark,
|
||||
&lsi_redirect_profile_new_project_highrise,
|
||||
};
|
||||
|
||||
/**
|
||||
* Global storage of handles for nicer organisation.
|
||||
*/
|
||||
typedef struct LsiRedirectTable {
|
||||
lsi_open_file open;
|
||||
lsi_fopen64_file fopen64;
|
||||
|
||||
/* Allow future handle opens.. */
|
||||
struct {
|
||||
void *libc;
|
||||
} handles;
|
||||
} LsiRedirectTable;
|
||||
|
||||
/**
|
||||
* Easy mapping to make it quick and easy to add new function overrides
|
||||
*/
|
||||
typedef struct LsiSymbolBinding {
|
||||
void **handle;
|
||||
char *name;
|
||||
void **func;
|
||||
size_t func_size;
|
||||
} LsiSymbolBinding;
|
||||
|
||||
/**
|
||||
* Our redirect instance, stack only.
|
||||
*/
|
||||
static LsiRedirectTable lsi_table = { 0 };
|
||||
|
||||
/**
|
||||
* Contains all of our replacement rules.
|
||||
*/
|
||||
static LsiRedirectProfile *lsi_profile = NULL;
|
||||
|
||||
/**
|
||||
* Our current set of libc bindings. This sets up the LsiRedirectTable with
|
||||
* all of our needed dlsym() functions from libc.so.6.
|
||||
*/
|
||||
static LsiSymbolBinding lsi_libc_bindings[] = {
|
||||
SYMBOL_BINDING(libc, open),
|
||||
SYMBOL_BINDING(libc, fopen64),
|
||||
};
|
||||
|
||||
/**
|
||||
* We'll only perform teardown code if the process doesn't `abort()` or `_exit()`
|
||||
*/
|
||||
__attribute__((destructor)) static void lsi_redirect_shutdown(void)
|
||||
{
|
||||
if (lsi_profile) {
|
||||
lsi_redirect_profile_free(lsi_profile);
|
||||
lsi_profile = NULL;
|
||||
}
|
||||
|
||||
if (!lsi_init) {
|
||||
return;
|
||||
}
|
||||
lsi_init = false;
|
||||
|
||||
if (lsi_table.handles.libc) {
|
||||
dlclose(lsi_table.handles.libc);
|
||||
lsi_table.handles.libc = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal helper to perform the symbol binding
|
||||
*/
|
||||
static bool lsi_redirect_bind_function(void *handle, const char *name, void **out_func,
|
||||
size_t func_size)
|
||||
{
|
||||
void *symbol_lookup = NULL;
|
||||
char *dl_error = NULL;
|
||||
|
||||
/* Safely look up the symbol */
|
||||
symbol_lookup = dlsym(handle, name);
|
||||
dl_error = dlerror();
|
||||
if (dl_error || !symbol_lookup) {
|
||||
fprintf(stderr, "Failed to bind '%s': %s\n", name, dl_error);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Have the symbol correctly, copy it to make it usable */
|
||||
memcpy(out_func, &symbol_lookup, func_size);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Responsible for setting up the vfunc redirect table so that we're able to
|
||||
* get `open` and such working before we've hit the constructor, and ensure
|
||||
* we only init once.
|
||||
*/
|
||||
static void lsi_redirect_init_tables(void)
|
||||
{
|
||||
if (lsi_init) {
|
||||
return;
|
||||
}
|
||||
|
||||
lsi_init = true;
|
||||
|
||||
/* Try to explicitly open libc. We can't safely rely on RTLD_NEXT
|
||||
* as we might be dealing with a strange link order
|
||||
*/
|
||||
lsi_table.handles.libc = dlopen("libc.so.6", RTLD_LAZY);
|
||||
if (!lsi_table.handles.libc) {
|
||||
fprintf(stderr, "Unable to grab libc.so.6 handle: %s\n", dlerror());
|
||||
goto failed;
|
||||
}
|
||||
|
||||
/* Hook up all necessary symbol binding */
|
||||
for (size_t i = 0; i < ARRAY_SIZE(lsi_libc_bindings); i++) {
|
||||
LsiSymbolBinding *binding = &lsi_libc_bindings[i];
|
||||
if (!lsi_redirect_bind_function(*(binding->handle),
|
||||
binding->name,
|
||||
binding->func,
|
||||
binding->func_size)) {
|
||||
goto failed;
|
||||
}
|
||||
}
|
||||
|
||||
/* We might not get an unload, so chain onto atexit */
|
||||
atexit(lsi_redirect_shutdown);
|
||||
return;
|
||||
|
||||
failed:
|
||||
/* Pretty damn fatal. */
|
||||
lsi_redirect_shutdown();
|
||||
abort();
|
||||
}
|
||||
|
||||
/**
|
||||
* Main entry point into this redirect module.
|
||||
*
|
||||
* We'll check the process name and determine if we're interested in installing
|
||||
* some redirect hooks into this library.
|
||||
* Otherwise we'll continue to operate in a pass-through mode
|
||||
*/
|
||||
__attribute__((constructor)) static void lsi_redirect_init(void)
|
||||
{
|
||||
/* Ensure we're open. */
|
||||
lsi_redirect_init_tables();
|
||||
autofree(char) *process_name = NULL;
|
||||
char **paths = NULL;
|
||||
char **orig = NULL;
|
||||
|
||||
/* Absolute path to the process for fine-grained matching */
|
||||
process_name = lsi_get_process_name();
|
||||
|
||||
if (!process_name) {
|
||||
fputs("Out of memory!\n", stderr);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Grab the stam installation directories */
|
||||
orig = paths = lsi_get_steam_paths();
|
||||
|
||||
/* For each path try to form a valid profile for the process name and Steam directory */
|
||||
while (*paths) {
|
||||
for (size_t i = 0; i < ARRAY_SIZE(generators); i++) {
|
||||
lsi_profile = generators[i](process_name, *paths);
|
||||
if (lsi_profile) {
|
||||
goto use_profile;
|
||||
}
|
||||
}
|
||||
++paths;
|
||||
}
|
||||
|
||||
use_profile:
|
||||
/* Rewind path set */
|
||||
paths = orig;
|
||||
|
||||
if (!lsi_profile) {
|
||||
goto clean_array;
|
||||
}
|
||||
|
||||
lsi_override = true;
|
||||
lsi_log_debug("Enable lsi_redirect for '%s'", lsi_profile->name);
|
||||
|
||||
clean_array:
|
||||
|
||||
/* Free them again */
|
||||
if (paths) {
|
||||
while (*paths) {
|
||||
free(*paths);
|
||||
++paths;
|
||||
}
|
||||
free(orig);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a redirect path from the table if it exists, otherwise return NULL
|
||||
*/
|
||||
static char *lsi_get_redirect_path(const char *syscall_id, LsiRedirectOperation op, const char *p)
|
||||
{
|
||||
autofree(char) *path = NULL;
|
||||
LsiRedirect *redirect = NULL;
|
||||
|
||||
/* Get the absolute path here */
|
||||
path = realpath(p, NULL);
|
||||
if (!path) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* find a valid replacement */
|
||||
for (redirect = lsi_profile->op_table[op]; redirect; redirect = redirect->next) {
|
||||
/* Currently we only known path replacements */
|
||||
if (redirect->type != LSI_REDIRECT_PATH) {
|
||||
continue;
|
||||
}
|
||||
if (strcmp(redirect->path_source, path) != 0) {
|
||||
continue;
|
||||
}
|
||||
if (!lsi_file_exists(redirect->path_target)) {
|
||||
lsi_log_warn("Replacement path does not exist: %s", redirect->path_target);
|
||||
return NULL;
|
||||
}
|
||||
lsi_log_info("%s(): Replaced '%s' with '%s'",
|
||||
syscall_id,
|
||||
path,
|
||||
redirect->path_target);
|
||||
return strdup(redirect->path_target);
|
||||
}
|
||||
|
||||
/* Got nothin' */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
_nica_public_ int open(const char *p, int flags, ...)
|
||||
{
|
||||
va_list va;
|
||||
mode_t mode;
|
||||
LsiRedirectOperation op = LSI_OPERATION_OPEN;
|
||||
autofree(char) *replacement = NULL;
|
||||
|
||||
/* Must ensure we're **really** initialised, as we might see open happen
|
||||
* before the constructor..
|
||||
*/
|
||||
lsi_redirect_init_tables();
|
||||
|
||||
/* Grab the mode_t */
|
||||
va_start(va, flags);
|
||||
mode = va_arg(va, mode_t);
|
||||
va_end(va);
|
||||
|
||||
/* Not interested in this guy apparently */
|
||||
if (!lsi_override) {
|
||||
return lsi_table.open(p, flags, mode);
|
||||
}
|
||||
|
||||
replacement = lsi_get_redirect_path("open", op, p);
|
||||
if (!replacement) {
|
||||
return lsi_table.open(p, flags, mode);
|
||||
}
|
||||
return lsi_table.open(replacement, flags, mode);
|
||||
}
|
||||
|
||||
_nica_public_ FILE *fopen64(const char *p, const char *modes)
|
||||
{
|
||||
LsiRedirectOperation op = LSI_OPERATION_OPEN;
|
||||
autofree(char) *replacement = NULL;
|
||||
|
||||
/* Must ensure we're **really** initialised, as we might see open happen
|
||||
* before the constructor..
|
||||
*/
|
||||
lsi_redirect_init_tables();
|
||||
|
||||
/* Not interested in this guy apparently */
|
||||
if (!lsi_override) {
|
||||
return lsi_table.fopen64(p, modes);
|
||||
}
|
||||
|
||||
replacement = lsi_get_redirect_path("fopen64", op, p);
|
||||
if (!replacement) {
|
||||
return lsi_table.fopen64(p, modes);
|
||||
}
|
||||
return lsi_table.fopen64(replacement, modes);
|
||||
}
|
||||
|
||||
/*
|
||||
* Editor modelines - https://www.wireshark.org/tools/modelines.html
|
||||
*
|
||||
* Local variables:
|
||||
* c-basic-offset: 8
|
||||
* tab-width: 8
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*
|
||||
* vi: set shiftwidth=8 tabstop=8 expandtab:
|
||||
* :indentSize=8:tabSize=8:noTabs=true:
|
||||
*/
|
||||
@@ -0,0 +1,29 @@
|
||||
# Only build libredirect if told to!
|
||||
|
||||
if with_libredirect == true
|
||||
|
||||
# Might not need libdl for alt libcs
|
||||
libdl = meson.get_compiler('c').find_library('dl', required : false)
|
||||
|
||||
redirect_sources = [
|
||||
'main.c',
|
||||
'profile.c',
|
||||
'profiles/ark.c',
|
||||
'profiles/project_highrise.c',
|
||||
]
|
||||
|
||||
sym_map = join_paths(meson.current_source_dir(), 'sym.map')
|
||||
|
||||
main_redirect = shared_library(
|
||||
'lsi-redirect',
|
||||
sources: redirect_sources,
|
||||
c_args: ['-fvisibility=hidden'],
|
||||
link_args: ['-Wl,--version-script=@0@'.format(sym_map)],
|
||||
include_directories: nica_includes,
|
||||
dependencies: [
|
||||
libdl,
|
||||
link_lsi_common,
|
||||
],
|
||||
install: true,
|
||||
)
|
||||
endif
|
||||
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
* This file is part of linux-steam-integration.
|
||||
*
|
||||
* Copyright © 2017 Ikey Doherty <ikey@solus-project.com>
|
||||
*
|
||||
* linux-steam-integration is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1
|
||||
* of the License, or (at your option) any later version.
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "../common/log.h"
|
||||
#include "redirect.h"
|
||||
|
||||
LsiRedirectProfile *lsi_redirect_profile_new(const char *name)
|
||||
{
|
||||
LsiRedirectProfile p = { .name = strdup(name), { 0 } };
|
||||
LsiRedirectProfile *ret = NULL;
|
||||
if (!p.name) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = calloc(1, sizeof(LsiRedirectProfile));
|
||||
if (!ret) {
|
||||
return NULL;
|
||||
}
|
||||
*ret = p;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void lsi_redirect_profile_free(LsiRedirectProfile *self)
|
||||
{
|
||||
if (!self) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Free all chains */
|
||||
for (unsigned int i = 0; i < LSI_NUM_OPERATIONS; i++) {
|
||||
LsiRedirect *r = self->op_table[i];
|
||||
if (!r) {
|
||||
continue;
|
||||
}
|
||||
lsi_redirect_free(r);
|
||||
}
|
||||
|
||||
free(self->name);
|
||||
free(self);
|
||||
}
|
||||
|
||||
void lsi_redirect_profile_insert_rule(LsiRedirectProfile *self, LsiRedirect *redirect)
|
||||
{
|
||||
LsiRedirectOperation op;
|
||||
|
||||
switch (redirect->type) {
|
||||
case LSI_REDIRECT_PATH:
|
||||
op = LSI_OPERATION_OPEN;
|
||||
break;
|
||||
default:
|
||||
lsi_log_error("Attempted insert of unknown rule into '%s'", self->name);
|
||||
lsi_redirect_free(redirect);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Set head or prepend the rule */
|
||||
if (self->op_table[op]) {
|
||||
redirect->next = self->op_table[op];
|
||||
self->op_table[op] = redirect;
|
||||
} else {
|
||||
self->op_table[op] = redirect;
|
||||
}
|
||||
}
|
||||
|
||||
LsiRedirect *lsi_redirect_new_path_replacement(const char *source_path, const char *target_path)
|
||||
{
|
||||
LsiRedirect *ret = NULL;
|
||||
|
||||
ret = calloc(1, sizeof(LsiRedirect));
|
||||
if (!ret) {
|
||||
return NULL;
|
||||
}
|
||||
ret->type = LSI_REDIRECT_PATH;
|
||||
ret->path_source = realpath(source_path, NULL);
|
||||
ret->path_target = realpath(target_path, NULL);
|
||||
|
||||
if (!ret->path_source || !ret->path_target) {
|
||||
lsi_redirect_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void lsi_redirect_free(LsiRedirect *self)
|
||||
{
|
||||
if (!self) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Pass it along */
|
||||
if (self->next) {
|
||||
lsi_redirect_free(self->next);
|
||||
}
|
||||
|
||||
switch (self->type) {
|
||||
case LSI_REDIRECT_PATH:
|
||||
default:
|
||||
free(self->path_source);
|
||||
free(self->path_target);
|
||||
break;
|
||||
}
|
||||
|
||||
free(self);
|
||||
}
|
||||
|
||||
/*
|
||||
* Editor modelines - https://www.wireshark.org/tools/modelines.html
|
||||
*
|
||||
* Local variables:
|
||||
* c-basic-offset: 8
|
||||
* tab-width: 8
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*
|
||||
* vi: set shiftwidth=8 tabstop=8 expandtab:
|
||||
* :indentSize=8:tabSize=8:noTabs=true:
|
||||
*/
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* This file is part of linux-steam-integration.
|
||||
*
|
||||
* Copyright © 2017 Ikey Doherty <ikey@solus-project.com>
|
||||
*
|
||||
* linux-steam-integration is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1
|
||||
* of the License, or (at your option) any later version.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "redirect.h"
|
||||
|
||||
/**
|
||||
* Generator function is used to attempt creation of profiles based on the
|
||||
* steam directory
|
||||
*/
|
||||
typedef LsiRedirectProfile *(*lsi_profile_generator_func)(char *process_name, char *steam_root);
|
||||
|
||||
/**
|
||||
* Profile generator for Ark survival evolved
|
||||
*/
|
||||
LsiRedirectProfile *lsi_redirect_profile_new_ark(char *process_name, char *steam_root);
|
||||
|
||||
/**
|
||||
* Profile generator for Project Highrise
|
||||
*/
|
||||
LsiRedirectProfile *lsi_redirect_profile_new_project_highrise(char *process_name, char *steam_root);
|
||||
|
||||
/*
|
||||
* Editor modelines - https://www.wireshark.org/tools/modelines.html
|
||||
*
|
||||
* Local variables:
|
||||
* c-basic-offset: 8
|
||||
* tab-width: 8
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*
|
||||
* vi: set shiftwidth=8 tabstop=8 expandtab:
|
||||
* :indentSize=8:tabSize=8:noTabs=true:
|
||||
*/
|
||||
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* This file is part of linux-steam-integration.
|
||||
*
|
||||
* Copyright © 2017 Ikey Doherty <ikey@solus-project.com>
|
||||
*
|
||||
* linux-steam-integration is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1
|
||||
* of the License, or (at your option) any later version.
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "../common/log.h"
|
||||
#include "nica/util.h"
|
||||
#include "profile.h"
|
||||
#include "redirect.h"
|
||||
|
||||
#define ARK_BASE "steamapps/common/ARK/ShooterGame"
|
||||
#define ARK_CONTENT ARK_BASE "/Content"
|
||||
#define ARK_BINARY ARK_BASE "/Binaries/Linux/ShooterGame"
|
||||
|
||||
/**
|
||||
* This generator function is responsible for supporting ARK: Survival Evolved
|
||||
*
|
||||
* Simply it redirects the executable to open the correct asset when TheCenter
|
||||
* DLC is installed.
|
||||
*/
|
||||
LsiRedirectProfile *lsi_redirect_profile_new_ark(char *process_name, char *steam_path)
|
||||
{
|
||||
LsiRedirectProfile *p = NULL;
|
||||
LsiRedirect *redirect = NULL;
|
||||
autofree(char) *mic_source = NULL;
|
||||
autofree(char) *mic_target = NULL;
|
||||
autofree(char) *match_process = NULL;
|
||||
autofree(char) *test_process = NULL;
|
||||
|
||||
if (asprintf(&match_process, "%s/%s", steam_path, ARK_BINARY) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Check it even exists */
|
||||
test_process = realpath(match_process, NULL);
|
||||
if (!test_process) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Check the process name now */
|
||||
if (strcmp(test_process, process_name) != 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char *def_mic_source =
|
||||
ARK_CONTENT "/PrimalEarth/Environment/Water/Water_DepthBlur_MIC.uasset";
|
||||
static const char *def_mic_target =
|
||||
ARK_CONTENT "/Mods/TheCenter/Assets/Mic/Water_DepthBlur_MIC.uasset";
|
||||
|
||||
p = lsi_redirect_profile_new("ARK: Survival Evolved");
|
||||
if (!p) {
|
||||
fputs("OUT OF MEMORY\n", stderr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (asprintf(&mic_source, "%s/%s", steam_path, def_mic_source) < 0) {
|
||||
goto failed;
|
||||
}
|
||||
if (asprintf(&mic_target, "%s/%s", steam_path, def_mic_target) < 0) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
/* Don't add a redirect if the paths don't exist. */
|
||||
redirect = lsi_redirect_new_path_replacement(mic_source, mic_target);
|
||||
if (!redirect) {
|
||||
goto unused;
|
||||
}
|
||||
|
||||
/* We're in, set our log ID now */
|
||||
lsi_log_set_id("ARK");
|
||||
|
||||
lsi_redirect_profile_insert_rule(p, redirect);
|
||||
|
||||
return p;
|
||||
|
||||
failed:
|
||||
/* Dead in the water.. */
|
||||
fputs("OUT OF MEMORY\n", stderr);
|
||||
unused:
|
||||
lsi_redirect_profile_free(p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Editor modelines - https://www.wireshark.org/tools/modelines.html
|
||||
*
|
||||
* Local variables:
|
||||
* c-basic-offset: 8
|
||||
* tab-width: 8
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*
|
||||
* vi: set shiftwidth=8 tabstop=8 expandtab:
|
||||
* :indentSize=8:tabSize=8:noTabs=true:
|
||||
*/
|
||||
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* This file is part of linux-steam-integration.
|
||||
*
|
||||
* Copyright © 2017 Ikey Doherty <ikey@solus-project.com>
|
||||
*
|
||||
* linux-steam-integration is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1
|
||||
* of the License, or (at your option) any later version.
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "../common/files.h"
|
||||
#include "../common/log.h"
|
||||
#include "nica/util.h"
|
||||
#include "profile.h"
|
||||
#include "redirect.h"
|
||||
|
||||
#define PHR_PREF_DIR "unity3d/SomaSim/Project Highrise/prefs"
|
||||
#define PHR_PREF_FILE "unity3d/SomaSim/Project Highrise/prefs/prefs.txt"
|
||||
|
||||
#if UINTPTR_MAX == 0xffffffffffffffff
|
||||
#define PHR_BINARY "steamapps/common/Project Highrise/Game.x86_64"
|
||||
#else
|
||||
#define PHR_BINARY "steamapps/common/Project Highrise/Game.x86"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* This generator function is responsible for supporting: Project Highrise
|
||||
*
|
||||
* Currently a bug exists in Projec Highrise, where on the second launch, i.e.
|
||||
* preferences tree exists, it will try to load/map the preferences directory
|
||||
* as a file, and fails to use the correct *file path*
|
||||
*
|
||||
* This is a temporary workaround and we'll let them know what we found.
|
||||
*/
|
||||
LsiRedirectProfile *lsi_redirect_profile_new_project_highrise(char *process_name, char *steam_path)
|
||||
{
|
||||
LsiRedirectProfile *p = NULL;
|
||||
LsiRedirect *redirect = NULL;
|
||||
autofree(char) *p_source = NULL;
|
||||
autofree(char) *p_target = NULL;
|
||||
autofree(char) *match_process = NULL;
|
||||
autofree(char) *test_process = NULL;
|
||||
autofree(char) *config_dir = NULL;
|
||||
|
||||
if (asprintf(&match_process, "%s/%s", steam_path, PHR_BINARY) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Check it even exists */
|
||||
test_process = realpath(match_process, NULL);
|
||||
if (!test_process) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Check the process name now */
|
||||
if (strcmp(test_process, process_name) != 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
config_dir = lsi_get_user_config_dir();
|
||||
if (!config_dir) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
p = lsi_redirect_profile_new("Project Highrise");
|
||||
if (!p) {
|
||||
fputs("OUT OF MEMORY\n", stderr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (asprintf(&p_source, "%s/%s", config_dir, PHR_PREF_DIR) < 0) {
|
||||
goto failed;
|
||||
}
|
||||
if (asprintf(&p_target, "%s/%s", config_dir, PHR_PREF_FILE) < 0) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
/* Don't add a redirect if the paths don't exist. */
|
||||
redirect = lsi_redirect_new_path_replacement(p_source, p_target);
|
||||
if (!redirect) {
|
||||
goto unused;
|
||||
}
|
||||
|
||||
/* We're in, set our log ID now */
|
||||
lsi_log_set_id("ProjectHighrise");
|
||||
|
||||
lsi_redirect_profile_insert_rule(p, redirect);
|
||||
|
||||
return p;
|
||||
|
||||
failed:
|
||||
/* Dead in the water.. */
|
||||
fputs("OUT OF MEMORY\n", stderr);
|
||||
unused:
|
||||
lsi_redirect_profile_free(p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Editor modelines - https://www.wireshark.org/tools/modelines.html
|
||||
*
|
||||
* Local variables:
|
||||
* c-basic-offset: 8
|
||||
* tab-width: 8
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*
|
||||
* vi: set shiftwidth=8 tabstop=8 expandtab:
|
||||
* :indentSize=8:tabSize=8:noTabs=true:
|
||||
*/
|
||||
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* This file is part of linux-steam-integration.
|
||||
*
|
||||
* Copyright © 2017 Ikey Doherty <ikey@solus-project.com>
|
||||
*
|
||||
* linux-steam-integration is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1
|
||||
* of the License, or (at your option) any later version.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/**
|
||||
* The type of redirect required
|
||||
*/
|
||||
typedef enum {
|
||||
LSI_REDIRECT_MIN = 1,
|
||||
LSI_REDIRECT_PATH,
|
||||
} LsiRedirectType;
|
||||
|
||||
/**
|
||||
* LsiRedirect describes the configuration required for each operation.
|
||||
*/
|
||||
typedef struct LsiRedirect {
|
||||
LsiRedirectType type;
|
||||
union {
|
||||
/* Path replacement */
|
||||
struct {
|
||||
char *path_source;
|
||||
char *path_target;
|
||||
};
|
||||
};
|
||||
struct LsiRedirect *next;
|
||||
} LsiRedirect;
|
||||
|
||||
/**
|
||||
* LsiRedirectOperation specifies the syscall we're intended for.
|
||||
*/
|
||||
typedef enum { LSI_OPERATION_OPEN = 0, LSI_NUM_OPERATIONS } LsiRedirectOperation;
|
||||
|
||||
/**
|
||||
* We build an LsiRedirectProfile to match the current process.
|
||||
* It contains a table of LsiRedirect members corresponding to a given
|
||||
* op, i.e:
|
||||
*
|
||||
* op_table[LSI_OPERATION_OPEN]
|
||||
*/
|
||||
typedef struct LsiRedirectProfile {
|
||||
char *name; /**< Name for this profile */
|
||||
|
||||
LsiRedirect *op_table[LSI_NUM_OPERATIONS]; /* vtable information */
|
||||
} LsiRedirectProfile;
|
||||
|
||||
/**
|
||||
* Construct a new LsiRedirectProfile
|
||||
*
|
||||
* @param name Profile name
|
||||
* @returns A newly allocated LsiRedirectProfile
|
||||
*/
|
||||
LsiRedirectProfile *lsi_redirect_profile_new(const char *name);
|
||||
|
||||
/**
|
||||
* Free a previously allocated LsiRedirectProfile
|
||||
*
|
||||
* @param profile Pointer to an allocated LsiRedirectProfile
|
||||
*/
|
||||
void lsi_redirect_profile_free(LsiRedirectProfile *profile);
|
||||
|
||||
/**
|
||||
* Attempt insert of a redirect rule into this profile
|
||||
*
|
||||
* @param profile Pointer to a valid LsiRedirectProfile
|
||||
* @param redirect Pointer to an allocated LsiRedirect
|
||||
*/
|
||||
void lsi_redirect_profile_insert_rule(LsiRedirectProfile *self, LsiRedirect *redirect);
|
||||
|
||||
/* LsiRedirect APIs follow */
|
||||
|
||||
/**
|
||||
* Construct a new LsiRedirect to perform path replacements
|
||||
*/
|
||||
LsiRedirect *lsi_redirect_new_path_replacement(const char *source_path, const char *target_path);
|
||||
|
||||
/**
|
||||
* Attempt to free this redirect
|
||||
*
|
||||
* @param redirect Pointer to allocated LsiRedirect
|
||||
*/
|
||||
void lsi_redirect_free(LsiRedirect *self);
|
||||
|
||||
/*
|
||||
* Editor modelines - https://www.wireshark.org/tools/modelines.html
|
||||
*
|
||||
* Local variables:
|
||||
* c-basic-offset: 8
|
||||
* tab-width: 8
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*
|
||||
* vi: set shiftwidth=8 tabstop=8 expandtab:
|
||||
* :indentSize=8:tabSize=8:noTabs=true:
|
||||
*/
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
global:
|
||||
fopen64;
|
||||
open;
|
||||
local:
|
||||
*;
|
||||
};
|
||||
+39
-4
@@ -12,11 +12,13 @@
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "../common/files.h"
|
||||
#include "config.h"
|
||||
#include "lsi.h"
|
||||
|
||||
@@ -32,6 +34,36 @@
|
||||
*/
|
||||
#define AUDIT_PATH "/usr/\$LIB/liblsi-intercept.so"
|
||||
|
||||
/**
|
||||
* Redirect path is used for the libredirect library to perform internal
|
||||
* redirections in functions like `open()` where needed to hotfix games
|
||||
* at runtime.
|
||||
*/
|
||||
#define REDIRECT_PATH "/usr/\$LIB/liblsi-redirect.so"
|
||||
|
||||
/**
|
||||
* Set up LD_PRELOAD, respecting an existing LD_PRELOAD and forcing ourselves
|
||||
* to be first in the list.
|
||||
*/
|
||||
static void shim_set_ld_preload(void)
|
||||
{
|
||||
const char *preload = NULL;
|
||||
static char tgt[PATH_MAX] = { 0 };
|
||||
|
||||
preload = getenv("LD_PRELOAD");
|
||||
if (!preload) {
|
||||
setenv("LD_PRELOAD", REDIRECT_PATH, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (snprintf(tgt, sizeof(tgt), "%s:%s", REDIRECT_PATH, preload) < 0) {
|
||||
setenv("LD_PRELOAD", REDIRECT_PATH, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
setenv("LD_PRELOAD", tgt, 1);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
LsiConfig config = { 0 };
|
||||
@@ -44,11 +76,8 @@ int main(int argc, char **argv)
|
||||
int8_t off = 0;
|
||||
int (*vfunc)(const char *, char *const argv[]) = NULL;
|
||||
|
||||
#ifdef REPLACE_STEAM
|
||||
lsi_exec_bin = STEAM_BINARY;
|
||||
#else
|
||||
lsi_exec_bin = "/usr/bin/steam";
|
||||
#endif
|
||||
|
||||
/* Initialise config */
|
||||
if (!lsi_config_load(&config)) {
|
||||
lsi_config_load_defaults(&config);
|
||||
@@ -70,6 +99,12 @@ int main(int argc, char **argv)
|
||||
if (config.use_libintercept) {
|
||||
setenv("LD_AUDIT", AUDIT_PATH, 1);
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_LIBREDIRECT
|
||||
/* Only use libredirect in combination with native runtime! */
|
||||
if (config.use_libredirect) {
|
||||
shim_set_ld_preload();
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
/* Only preload when needed. */
|
||||
|
||||
Reference in New Issue
Block a user