wwine 0.5.0 → 0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +4 -3
- data/wwine +236 -56
- data/wwine.1 +21 -14
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3dc80c72bd69e1e4dfb94f59970ac9a0d13e33dae01aaf045e78bb3aa5d0b7b5
|
4
|
+
data.tar.gz: 7782fb91245eee5dc068c890326e538b8707a9cdedede3e3ae22e7b3236f3264
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a69c8a650eb88a1815a3c6e08915a762036d85618b14a2eb82290396abe08d4cb9f50c60485f350e2191279933ba96b6e1b17722e043660021c7457cdf99f609
|
7
|
+
data.tar.gz: 31b4af75ed1a7fc8cd251271d78e4f6b3ed5ee2c76000c0570088c2f3d77345b888399c74b208e0ba56b736c989d4b0150825d00e3cde92ee51b2d5fb37d39fa
|
data/README.md
CHANGED
@@ -5,16 +5,17 @@ wwine (wrapped wine) is a wrapper for the Windows compatibility layer
|
|
5
5
|
single unified interface, complete with full bottle support for all of them.
|
6
6
|
|
7
7
|
It integrates well with how the various flavours mange their bottles, so for
|
8
|
-
instance applications
|
8
|
+
instance applications installed using crossover will be manageable through the
|
9
9
|
usual crossover interface.
|
10
10
|
|
11
|
-
For vanilla wine, lutris and
|
12
|
-
support, creating bottles as ~/.wwinebottles/[BOTTLE NAME]
|
11
|
+
For vanilla wine, lutris, PlayOnLinux and Proton it uses variants of WINEPREFIX
|
12
|
+
to achieve bottle support, creating bottles as ~/.wwinebottles/[BOTTLE NAME]
|
13
13
|
|
14
14
|
It supports the following flavours of wine:
|
15
15
|
|
16
16
|
- [vanilla wine (winehq)](http://www.winehq.com/)
|
17
17
|
- [wine-staging](https://github.com/wine-staging/wine-staging)
|
18
|
+
- [Proton (Steam Play)](https://github.com/ValveSoftware/Proton)
|
18
19
|
- [Crossover](https://codeweavers.com/)
|
19
20
|
- [wine from lutris](https://lutris.net/)
|
20
21
|
- [wine from PlayOnLinux](https://www.playonlinux.com/en/)
|
data/wwine
CHANGED
@@ -22,7 +22,7 @@ require 'open3'
|
|
22
22
|
# Needed to make symlinks
|
23
23
|
require 'fileutils'
|
24
24
|
# Application version
|
25
|
-
$version = '0.
|
25
|
+
$version = '0.6'
|
26
26
|
# The wine flavour to use
|
27
27
|
$wine = nil
|
28
28
|
# The bottle to use
|
@@ -212,9 +212,27 @@ def getFromEnviron(path)
|
|
212
212
|
elsif info['bottle'] == '.wine-pipelight'
|
213
213
|
info['wine'] = 'pipelight'
|
214
214
|
info['bottle'] = '(pipelight)'
|
215
|
+
elsif env['WINEDLLPATH'] =~ /Proton/
|
216
|
+
proton = env['WINEDLLPATH'].sub(/.*Proton\s+([^\/]+).*/,'proton-\1')
|
217
|
+
if proton !~ /\//
|
218
|
+
info['wine'] = proton.downcase.sub(/\s/,'')
|
219
|
+
end
|
215
220
|
end
|
216
221
|
if env['CX_BOTTLE']
|
217
222
|
info['bottle'] = env['CX_BOTTLE']
|
223
|
+
elsif info['wine'] =~ /proton/i
|
224
|
+
bottle = env['__WWINE_INT_XBOTTLE'] || env['WINEPREFIX'] || env['STEAM_COMPAT_DATA_PATH']
|
225
|
+
if bottle
|
226
|
+
if File.basename(bottle) == 'pfx'
|
227
|
+
bottle = File.realpath(bottle+'/../')
|
228
|
+
end
|
229
|
+
bottleId = File.basename(bottle)
|
230
|
+
if bottleId =~ /\D/
|
231
|
+
info['bottle'] = '(?)'
|
232
|
+
else
|
233
|
+
info['bottle'] = 'steam:'+bottleId
|
234
|
+
end
|
235
|
+
end
|
218
236
|
elsif env['__WWINE_INT_XBOTTLE']
|
219
237
|
info['bottle'] = env['__WWINE_INT_XBOTTLE']
|
220
238
|
elsif env['WINEPREFIX']
|
@@ -234,7 +252,7 @@ end
|
|
234
252
|
# Description will be reformatted to fit within a normal terminal
|
235
253
|
def printHelp (short,long,description)
|
236
254
|
maxlen = 80
|
237
|
-
optionlen =
|
255
|
+
optionlen = 26
|
238
256
|
# Check if the short/long are LONGER than optionlen, if so, we need
|
239
257
|
# to do some additional magic to take up only $maxlen.
|
240
258
|
# The +1 here is because we always add a space between them, no matter what
|
@@ -247,7 +265,7 @@ def printHelp (short,long,description)
|
|
247
265
|
|
248
266
|
description.split(/ /).each do |part|
|
249
267
|
if(generatedDesc.length > 0)
|
250
|
-
if (currdesc.length + part.length + 1 +
|
268
|
+
if (currdesc.length + part.length + 1 + 26) > maxlen
|
251
269
|
generatedDesc.concat("\n")
|
252
270
|
currdesc = ''
|
253
271
|
else
|
@@ -262,7 +280,7 @@ def printHelp (short,long,description)
|
|
262
280
|
raise("Option mismatch")
|
263
281
|
end
|
264
282
|
generatedDesc.split(/\n/).each do |descr|
|
265
|
-
printf("%-4s %-
|
283
|
+
printf("%-4s %-21s %s\n",short,long,descr)
|
266
284
|
short = ''; long = ''
|
267
285
|
end
|
268
286
|
end
|
@@ -477,6 +495,28 @@ def generateWrapper (wine,bottle,targetFile,wineCommand,args,type = nil)
|
|
477
495
|
writeWrapper(targetFile ,wwineCmd, wineCommand, $wrapperCwd, wwineInfo, args, wineprefix)
|
478
496
|
end
|
479
497
|
|
498
|
+
# Purpose: Emulate --version for nonstandard wine
|
499
|
+
def emulateVersionOutput(wine)
|
500
|
+
# For CX* we can actually output a useful version number, namely the
|
501
|
+
# wine version that CX* release was based on
|
502
|
+
if wine == 'cxgames' || wine == 'cxoffice' || wine == 'crossover'
|
503
|
+
cxgBin = getCXwithParams(wine,nil,false)
|
504
|
+
cxVer, cxwVer = getCXVersionsFrom( cxgBin )
|
505
|
+
# CX* wine --versions often contain git revisions and other additional
|
506
|
+
# information in the version number, this strips that out.
|
507
|
+
cxwVer.sub!(/-.*/,'')
|
508
|
+
puts 'wine-'+cxwVer
|
509
|
+
# For proton we use the proton version number
|
510
|
+
elsif wine =~ /^proton-/
|
511
|
+
version = wine.sub(/^proton-(\d+.\d+)\D*/,'\1')
|
512
|
+
puts 'wine-'+version
|
513
|
+
# For cedega we just output an invalid version number in the same syntax
|
514
|
+
# as vanilla wine would have done
|
515
|
+
elsif resolveWine(wine) == 'gametree'
|
516
|
+
puts 'wine-0.0.0'
|
517
|
+
end
|
518
|
+
end
|
519
|
+
|
480
520
|
# Purpose: Sets WINE and WINEPREFIX, and then either outputs them to STDOUT, or
|
481
521
|
# executes whatever native command was supplied (the logic that handles --env)
|
482
522
|
def setEnvAndExec (wine,bottle,cmd,args,type)
|
@@ -505,6 +545,12 @@ def setEnvAndExec (wine,bottle,cmd,args,type)
|
|
505
545
|
if type == 'wine' || wine == 'wine' || (File.exists?(wine) && !File.directory?(wine)) || wine =~ /^(pol|lutris)[-:]?/i
|
506
546
|
vputs(V_DBG,"Used ENV/WINEPREFIX method to get bottle")
|
507
547
|
bottlePath = ENV['WINEPREFIX']
|
548
|
+
elsif type == 'proton' || wine =~ /^proton-/
|
549
|
+
vputs(V_DBG,"Used STEAM_COMPAT_DATA_PATH method to get bottle")
|
550
|
+
bottlePath = ENV['STEAM_COMPAT_DATA_PATH']
|
551
|
+
if File.exists?(bottlePath+'/pfx')
|
552
|
+
bottlePath = bottlePath+'/pfx'
|
553
|
+
end
|
508
554
|
elsif resolveWine(wine) == 'gametree'
|
509
555
|
vputs(V_DBG,"Used ENV/cedega method to get bottle")
|
510
556
|
bottlePath = ENV['HOME']+'/.cedega/'+bottle
|
@@ -746,6 +792,12 @@ def vputs (level,str)
|
|
746
792
|
str = 'Debug: '+str
|
747
793
|
end
|
748
794
|
if $verbosity >= level
|
795
|
+
# Don't enable debugging output at all if STDOUT is not a tty and we're
|
796
|
+
# running in env mode. In these cases the caller might rely upon parsing
|
797
|
+
# specific output, and including debugging info can cause the caller to fail.
|
798
|
+
if !STDOUT.isatty && ENV['__WWINE_INT_ENVMODE'] == $version
|
799
|
+
return
|
800
|
+
end
|
749
801
|
puts(str)
|
750
802
|
end
|
751
803
|
end
|
@@ -769,12 +821,15 @@ def Help ()
|
|
769
821
|
printHelp('-h','--help','Display this help text')
|
770
822
|
printHelp('-w','--wine','Select the wine to use. Any wine listed in "wwine --list" or the path to a wine binary or crossover installation directory.')
|
771
823
|
printHelp('-b','--bottle','Use the selected bottle (~/.wwinebottles/[NAME] for wine, CX bottle or cedega folder, depending on the --wine in use). The bottle will be created if it does not exist.')
|
824
|
+
printHelp('','--list-proton-bottles','Output a list of all available Proton/Steam game bottles')
|
772
825
|
printHelp('','--debug','Enable wine debugging output with the supplied levels (using the format of the WINEDEBUG environment variable)')
|
773
826
|
printHelp('','--env','Set the WINE and WINEPREFIX environment variables to match the parameters provided to wwine and optionally run a program with those variables set.')
|
774
827
|
printHelp('','--arch','Set the wine architecture. Accepts win32 and win64. The default is win32 if --wine does not end with "64"')
|
775
828
|
printHelp('-l','--list','List all available wine versions')
|
776
829
|
printHelp('-k','--kill','Attempt to kill all running wine processes')
|
777
830
|
printHelp('','--drykill','Print what --kill would have done, but don\'t actually do anything')
|
831
|
+
printHelp('','--gamemode','Enable Feral GameMode')
|
832
|
+
printHelp('','--no-gamemode','Disable Feral GameMode')
|
778
833
|
printHelp('','--wrap','Write a wrapper script of your current wwine command to the path supplied')
|
779
834
|
printHelp('','--wrapdir','Use the supplied directory as the working directory for the script created by --wrap (default: current directory)')
|
780
835
|
printHelp('-s','--from','Load parameters and program from the wrapper script supplied. Command-line arguments overrides settings from wrapper script.')
|
@@ -1255,6 +1310,11 @@ def getCXwithParams (wine,bottle, missingIsFatal = true, getBottleDir = false, g
|
|
1255
1310
|
return cxdir
|
1256
1311
|
end
|
1257
1312
|
|
1313
|
+
if bottle =~ /\//
|
1314
|
+
puts wine+' (cx) does not support bottles that exist outside of ~/'+bottleDir
|
1315
|
+
exit 1
|
1316
|
+
end
|
1317
|
+
|
1258
1318
|
final.push(cxdir+'/bin/cxstart')
|
1259
1319
|
if(bottle != nil && bottle.length > 0)
|
1260
1320
|
final.push('--bottle',bottle)
|
@@ -1359,9 +1419,11 @@ def getCustomwithParams(wine,bottle, type = 'POL', missingIsFatal = true, return
|
|
1359
1419
|
end
|
1360
1420
|
|
1361
1421
|
# Purpose: Get parameters for Proton
|
1362
|
-
|
1422
|
+
# if multiReturn is true it will return cmd,bottle
|
1423
|
+
def getProtonWithParams(wine,bottle, missingIsFatal = true, multiReturn = false)
|
1363
1424
|
command = []
|
1364
1425
|
protons = getProtons()
|
1426
|
+
wine = wine.downcase
|
1365
1427
|
if !protons[wine]
|
1366
1428
|
if missingIsFatal
|
1367
1429
|
puts("Could not find a proton version matching \""+wine+"\"")
|
@@ -1387,64 +1449,157 @@ def getProtonWithParams(wine,bottle, missingIsFatal = true)
|
|
1387
1449
|
|
1388
1450
|
command.push( protons[wine]+'/proton','run')
|
1389
1451
|
|
1452
|
+
if File.exists?(bottle) && File.basename(bottle) == 'pfx'
|
1453
|
+
bottle = File.realpath(bottle+'/../')
|
1454
|
+
end
|
1455
|
+
|
1390
1456
|
bottleRoot = ENV['HOME']+'/.wwinebottles/'
|
1391
|
-
if
|
1392
|
-
|
1393
|
-
|
1394
|
-
|
1395
|
-
|
1396
|
-
|
1397
|
-
|
1398
|
-
|
1457
|
+
if bottle =~ /^\// && File.exists?(bottle+'/pfx')
|
1458
|
+
# Proton uses STEAM_COMPAT_DATA_PATH to point to the bottle location
|
1459
|
+
envPut('STEAM_COMPAT_DATA_PATH',bottle)
|
1460
|
+
else
|
1461
|
+
if !Dir.exists?(bottleRoot)
|
1462
|
+
vputs(V_INFO,bottleRoot+': does not exist, creating')
|
1463
|
+
begin
|
1464
|
+
Dir.mkdir(bottleRoot)
|
1465
|
+
rescue SystemCallError
|
1466
|
+
puts('Failed to create directory "'+bottleRoot+": "+$!.message)
|
1467
|
+
puts('Unable to continue.')
|
1468
|
+
exit(1)
|
1469
|
+
end
|
1399
1470
|
end
|
1400
|
-
|
1401
|
-
|
1402
|
-
|
1403
|
-
|
1404
|
-
|
1405
|
-
|
1406
|
-
|
1407
|
-
|
1408
|
-
|
1471
|
+
if !Dir.exists?(bottleRoot+bottle)
|
1472
|
+
vputs(V_INFO,bottleRoot+bottle+': does not exist, creating')
|
1473
|
+
begin
|
1474
|
+
Dir.mkdir(bottleRoot+bottle)
|
1475
|
+
rescue SystemCallError
|
1476
|
+
puts('Failed to create directory "'+bottleRoot+": "+$!.message)
|
1477
|
+
puts('Unable to continue.')
|
1478
|
+
exit(1)
|
1479
|
+
end
|
1409
1480
|
end
|
1481
|
+
# Proton always uses /pfx, we make that a symlink to the base bottle
|
1482
|
+
if !File.exists?(bottleRoot+bottle+'/pfx')
|
1483
|
+
begin
|
1484
|
+
FileUtils.ln_s(bottleRoot+bottle,bottleRoot+bottle+'/pfx')
|
1485
|
+
rescue SystemCallError
|
1486
|
+
puts('Failed to create pfx symlink in '+bottleRoot+bottle+': '+$!.message)
|
1487
|
+
puts('Unable to continue')
|
1488
|
+
exit(1)
|
1489
|
+
end
|
1490
|
+
end
|
1491
|
+
# Proton uses STEAM_COMPAT_DATA_PATH to point to the bottle location
|
1492
|
+
envPut('STEAM_COMPAT_DATA_PATH',bottleRoot+bottle)
|
1410
1493
|
end
|
1411
|
-
# Proton always uses /pfx, we make that a symlink to the base bottle
|
1412
|
-
if !File.exists?(bottleRoot+bottle+'/pfx')
|
1413
|
-
FileUtils.ln_s(bottleRoot+bottle,bottleRoot+bottle+'/pfx')
|
1414
|
-
end
|
1415
|
-
# Proton uses STEAM_COMPAT_DATA_PATH to point to the bottle location
|
1416
|
-
envPut('STEAM_COMPAT_DATA_PATH',bottleRoot+bottle)
|
1417
1494
|
|
1418
1495
|
# Disable wineArch support. Proton uses its own.
|
1419
|
-
$wineArch
|
1496
|
+
if $wineArch
|
1497
|
+
puts "Warning: proton does not support --arch, ignoring."
|
1498
|
+
$wineArch = nil
|
1499
|
+
end
|
1500
|
+
|
1501
|
+
# Enable debugging if requested
|
1502
|
+
if $wineDebug
|
1503
|
+
puts "Notice: proton does not support --debug, ignoring."
|
1504
|
+
end
|
1420
1505
|
|
1421
1506
|
vputs(V_DBG,'Detected proton: '+command.join(' '))
|
1422
|
-
|
1507
|
+
if multiReturn
|
1508
|
+
return command,bottleRoot+bottle
|
1509
|
+
else
|
1510
|
+
return command
|
1511
|
+
end
|
1423
1512
|
end
|
1424
1513
|
|
1425
|
-
# Purpose: Get a list of
|
1426
|
-
def
|
1427
|
-
|
1428
|
-
# that used said version of Proton is installed to. Thus we need to parse out where
|
1429
|
-
# all of Steam's library directories are to be able to produce a complete list.
|
1430
|
-
dirs = [ ENV['HOME']+'/.steam/root/SteamApps/common' ]
|
1514
|
+
# Purpose: Get a list of Proton base directory locations
|
1515
|
+
def getProtonBaseDirs ()
|
1516
|
+
dirs = [ ENV['HOME']+'/.steam/root/SteamApps/', ENV['HOME']+'/.steam/root/steamapps/' ]
|
1431
1517
|
steamConfigFile = ENV['HOME']+'/.steam/root/config/config.vdf'
|
1432
1518
|
if File.exists?(steamConfigFile)
|
1433
1519
|
source = File.open(steamConfigFile)
|
1434
1520
|
source.each("\n") do |entry|
|
1435
1521
|
if entry =~ /\s*\"BaseInstallFolder_\d+\"\s*/
|
1436
1522
|
dir = entry.sub(/^\s*\"BaseInstallFolder_\d+\"\s*\"(.*)\"/,'\1').chomp
|
1437
|
-
dirs.push(dir+'/steamapps/
|
1523
|
+
dirs.push(dir+'/steamapps/')
|
1438
1524
|
end
|
1439
1525
|
end
|
1440
1526
|
end
|
1527
|
+
return dirs
|
1528
|
+
end
|
1529
|
+
|
1530
|
+
# Purpose: Get the name of the game that owns a Proton bottle
|
1531
|
+
# (converts ID to name)
|
1532
|
+
def getProtonBottleName (id)
|
1533
|
+
dirs = getProtonBaseDirs()
|
1534
|
+
dirs.each do |entry|
|
1535
|
+
manifestFile = entry+'/appmanifest_'+id+'.acf';
|
1536
|
+
if File.exists?(manifestFile)
|
1537
|
+
manifest = File.open(manifestFile)
|
1538
|
+
manifest.each("\n") do |entry|
|
1539
|
+
if entry =~ /\s*\"(name|installdir)\"\s*/
|
1540
|
+
return entry.sub(/^\s*\"(name|installdir)\"\s*\"(.*)\"/,'\2').chomp
|
1541
|
+
end
|
1542
|
+
end
|
1543
|
+
end
|
1544
|
+
end
|
1545
|
+
return nil
|
1546
|
+
end
|
1547
|
+
|
1548
|
+
# Purpose: Get a list of Proton bottles
|
1549
|
+
# Returns a hash, mapping the key (ID) to another hash. The inner hash kontains
|
1550
|
+
# the keys "directory" (path to the bottle) and "name" (name of the game owning
|
1551
|
+
# the bottle)
|
1552
|
+
def getProtonBottles ()
|
1553
|
+
dirs = getProtonBaseDirs()
|
1554
|
+
|
1555
|
+
bottles = {}
|
1556
|
+
dirs.each do |entry|
|
1557
|
+
Dir.glob(entry+'/compatdata/*') do |bottle|
|
1558
|
+
if Dir.exists?(bottle+'/pfx')
|
1559
|
+
bottle = File.realpath(bottle)
|
1560
|
+
id = File.basename(bottle)
|
1561
|
+
name = getProtonBottleName(id)
|
1562
|
+
if name == nil
|
1563
|
+
name = 'uninstalled game ('+bottle+')'
|
1564
|
+
end
|
1565
|
+
bottles[id] = {
|
1566
|
+
"name" => name,
|
1567
|
+
"directory" => bottle+'/pfx'
|
1568
|
+
}
|
1569
|
+
end
|
1570
|
+
end
|
1571
|
+
end
|
1572
|
+
return bottles
|
1573
|
+
end
|
1574
|
+
|
1575
|
+
# Purpose: Output a list of Proton bottles
|
1576
|
+
def listProtonBottles ()
|
1577
|
+
outFormat = '%-15s: %s'+"\n"
|
1578
|
+
bottles = getProtonBottles()
|
1579
|
+
begin
|
1580
|
+
printf(outFormat,'Bottle','Description')
|
1581
|
+
bottles.each do |bottle,meta|
|
1582
|
+
printf(outFormat,'steam:'+bottle,meta['name'])
|
1583
|
+
vputs(V_DBG,'steam:'+bottle+' is at '+meta['directory'])
|
1584
|
+
end
|
1585
|
+
rescue => ex
|
1586
|
+
handleException(ex)
|
1587
|
+
end
|
1588
|
+
end
|
1589
|
+
|
1590
|
+
# Purpose: Get a list of installed proton versions
|
1591
|
+
def getProtons ()
|
1592
|
+
dirs = getProtonBaseDirs()
|
1593
|
+
# Proton gets installed in the same "steam library" directory that the first game
|
1594
|
+
# that used said version of Proton is installed to. Thus we need to parse out where
|
1595
|
+
# all of Steam's library directories are to be able to produce a complete list.
|
1441
1596
|
protons = {}
|
1442
1597
|
# Note: In the case of several identical proton versions we'll just use the last one
|
1443
1598
|
# we find
|
1444
1599
|
dirs.each do |entry|
|
1445
|
-
Dir.glob(entry+'/Proton*') do |instance|
|
1600
|
+
Dir.glob(entry+'/common/Proton*') do |instance|
|
1446
1601
|
if File.executable?(instance+'/proton')
|
1447
|
-
version = instance.sub(/.*Proton\s+(\d+\.\d+)
|
1602
|
+
version = instance.sub(/.*Proton\s+(\d+\.\d+)\s*(.*)?/,'\1\2').sub(/\s/,'').downcase
|
1448
1603
|
protons['proton-'+version] = instance
|
1449
1604
|
end
|
1450
1605
|
end
|
@@ -1487,6 +1642,19 @@ def runWine (wine,bottle,args)
|
|
1487
1642
|
cmd = nil
|
1488
1643
|
type = nil
|
1489
1644
|
|
1645
|
+
if bottle =~ /^steam:/
|
1646
|
+
bottleID = bottle.sub(/^steam:(\d+)/,'\1')
|
1647
|
+
|
1648
|
+
protonBottles = getProtonBottles()
|
1649
|
+
|
1650
|
+
if protonBottles[bottleID]
|
1651
|
+
bottle = protonBottles[bottleID]['directory']
|
1652
|
+
else
|
1653
|
+
puts "Unable to find a steam bottle with the ID \""+bottleID+"\""
|
1654
|
+
exit 1
|
1655
|
+
end
|
1656
|
+
end
|
1657
|
+
|
1490
1658
|
if wine == nil
|
1491
1659
|
type,cmd = getAutoWithParams(bottle)
|
1492
1660
|
wine = type
|
@@ -1524,7 +1692,7 @@ def runWine (wine,bottle,args)
|
|
1524
1692
|
realWine = wine.sub(/^(pol|lutris)[-:]?/i,'')
|
1525
1693
|
cmd = getCustomwithParams(realWine,bottle,wine)
|
1526
1694
|
elsif wine =~ /^proton-/
|
1527
|
-
cmd = getProtonWithParams(wine,bottle)
|
1695
|
+
cmd,bottle = getProtonWithParams(wine,bottle,true,true)
|
1528
1696
|
else
|
1529
1697
|
puts('Unknown --wine: '+wine)
|
1530
1698
|
if File.directory?(wine)
|
@@ -1540,28 +1708,36 @@ def runWine (wine,bottle,args)
|
|
1540
1708
|
puts('Command detection failed. This is a bug')
|
1541
1709
|
exit(1)
|
1542
1710
|
end
|
1711
|
+
|
1712
|
+
if wine =~ /^proton-/ && args[0] !~ /(\/|\\)/ && !File.exists?(args[0])
|
1713
|
+
orig = args[0]
|
1714
|
+
['syswow64','system32'].each do |subdir|
|
1715
|
+
if File.exists?(bottle+'/drive_c/windows/'+subdir+'/'+args[0]+'.exe')
|
1716
|
+
orig = args[0]
|
1717
|
+
args[0] = bottle+'/drive_c/windows/'+subdir+'/'+args[0]+'.exe'
|
1718
|
+
vputs(V_DBG,'Resolving for Proton: '+orig+' -> '+orig+'.exe'+' -> '+args[0])
|
1719
|
+
break
|
1720
|
+
elsif File.exists?(bottle+'/drive_c/windows/'+subdir+'/'+args[0])
|
1721
|
+
orig = args[0]
|
1722
|
+
args[0] = bottle+'/drive_c/windows/'+subdir+'/'+args[0]
|
1723
|
+
vputs(V_DBG,'Resolving for Proton: '+orig+' -> '+args[0])
|
1724
|
+
break
|
1725
|
+
end
|
1726
|
+
end
|
1727
|
+
if args[0] != orig
|
1728
|
+
vputs(V_INFO,'Proton can\'t find Wine commands, therefore '+orig+' is converted to '+args[0])
|
1729
|
+
puts 'wwine: Resolved '+orig+' to '+args[0]
|
1730
|
+
end
|
1731
|
+
end
|
1732
|
+
|
1543
1733
|
cmd.concat(args)
|
1544
1734
|
|
1545
1735
|
# If args is a single parameter, that parameter is --version, and we're not using
|
1546
1736
|
# vanilla wine, then we emulate vanilla wine's --version output. This helps
|
1547
1737
|
# utilities like winetricks when it is running under "wwine --env"
|
1548
1738
|
if args.length == 1 && args[0] == '--version'
|
1549
|
-
|
1550
|
-
|
1551
|
-
if wine == 'cxgames' || wine == 'cxoffice' || wine == 'crossover'
|
1552
|
-
cxgBin = getCXwithParams(wine,nil,false)
|
1553
|
-
cxVer, cxwVer = getCXVersionsFrom( cxgBin )
|
1554
|
-
# CX* wine --versions often contain git revisions and other additional
|
1555
|
-
# information in the version number, this strips that out.
|
1556
|
-
cxwVer.sub!(/-.*/,'')
|
1557
|
-
puts 'wine-'+cxwVer
|
1558
|
-
exit
|
1559
|
-
# For cedega we just output an invalid version number in the same syntax
|
1560
|
-
# as vanilla wine would have done
|
1561
|
-
elsif resolveWine(wine) == 'gametree'
|
1562
|
-
puts 'wine-0.0.0'
|
1563
|
-
exit
|
1564
|
-
end
|
1739
|
+
emulateVersionOutput(wine)
|
1740
|
+
exit
|
1565
1741
|
end
|
1566
1742
|
|
1567
1743
|
# If we're in envMode, then we let setEnvAndExec handle the rest
|
@@ -1619,6 +1795,7 @@ else
|
|
1619
1795
|
[ '--debug',GetoptLong::REQUIRED_ARGUMENT ],
|
1620
1796
|
[ '--cxinstalldir','-c',GetoptLong::REQUIRED_ARGUMENT ],
|
1621
1797
|
[ '--cxg-installdir','--cxgamesinstalldir','-C',GetoptLong::REQUIRED_ARGUMENT ],
|
1798
|
+
[ '--list-proton-bottles',GetoptLong::NO_ARGUMENT ],
|
1622
1799
|
[ '--version',GetoptLong::NO_ARGUMENT ],
|
1623
1800
|
[ '--wrap', GetoptLong::REQUIRED_ARGUMENT ],
|
1624
1801
|
[ '--wrapdir', GetoptLong::REQUIRED_ARGUMENT ],
|
@@ -1690,6 +1867,9 @@ begin
|
|
1690
1867
|
when '--list-wines'
|
1691
1868
|
listWines()
|
1692
1869
|
exit(0)
|
1870
|
+
when '--list-proton-bottles'
|
1871
|
+
listProtonBottles()
|
1872
|
+
exit(0)
|
1693
1873
|
when '--kill'
|
1694
1874
|
if arg == nil
|
1695
1875
|
arg = 15
|
data/wwine.1
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
.IX Title "WWINE 1"
|
2
|
-
.TH WWINE 1 "2018-
|
2
|
+
.TH WWINE 1 "2018-11-12" "wwine 0.6" ""
|
3
3
|
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
|
4
4
|
.\" way too many mistakes in technical documents.
|
5
5
|
.if n .ad l
|
@@ -33,14 +33,9 @@ for \-\-wine for more information.
|
|
33
33
|
Display the help screen
|
34
34
|
.IP "\fB\-w, \-\-wine\fR \fI\s-1FLAVOUR\s0\fR" 4
|
35
35
|
.IX Item "-w, --wine FLAVOUR"
|
36
|
-
Use the supplied flavour of wine. The default is to use vanilla wine.
|
37
|
-
|
38
|
-
|
39
|
-
cxgames, cxoffice, cedega, cx (alias for crossover), cxg (alias for cxgames),
|
40
|
-
cxo (alias for cxoffice), /path/to/a/wine.binary or
|
41
|
-
/path/to/a/crossover\-installation. Note that if you have crossover, but not
|
42
|
-
cxgames installed, wwine will alias cxgames to crossover, to provide a simple
|
43
|
-
upgrade path where wrapper scripts 'just work'.
|
36
|
+
Use the supplied flavour of wine. The default is to use vanilla wine. To get a
|
37
|
+
list of detected wine flavours you can provide to \fI\-\-wine\fR, run \fIwwine
|
38
|
+
\&\-\-list\fR.
|
44
39
|
|
45
40
|
If this parameter is not supplied, wwine will attempt to autodetect which wine
|
46
41
|
to use, checking for the existance of flavours in the following order, using
|
@@ -61,6 +56,10 @@ case vanilla wine will use ~/.wine, crossover/cxoffice/cxgames will use the
|
|
61
56
|
bottle defined as default and for cedega a bottle named 'wwineFolder' will be
|
62
57
|
used.
|
63
58
|
|
59
|
+
The exception to the above are bottles that Steam makes for use with Proton.
|
60
|
+
You can use those bottles by specifying \*(L"steam:ID\*(R". To get a list of those
|
61
|
+
bottles, run \fIwwine \-\-list\-proton\-bottles\fR.
|
62
|
+
|
64
63
|
PlayOnLinux wines are a special case. If a bottle with the name supplied exists
|
65
64
|
in ~/.PlayOnLinux/wineprefixes/ then wwine will use that bottle (ie. the existing
|
66
65
|
PlayOnLinux bottle), otherwise it will use a bottle in ~/.wwinebottles.
|
@@ -83,6 +82,9 @@ Disable GameMode if enabled.
|
|
83
82
|
.IX Item "-l, --list"
|
84
83
|
List all available wine versions. This will list the names that can be supplied
|
85
84
|
to \fI\-\-wine\fR as well as the actual wine version in question.
|
85
|
+
.IP "\fB\-\-list\-proton\-bottles\fR" 4
|
86
|
+
.IX Item "--list-proton-bottles"
|
87
|
+
List all proton bottles.
|
86
88
|
.IP "\fB\-k, \-\-kill\fR" 4
|
87
89
|
.IX Item "-k, --kill"
|
88
90
|
Attempt to kill running wine processes. See also \fI\-\-drykill\fR.
|
@@ -103,8 +105,8 @@ Print what \fI\-\-kill\fR would have done, without actually doing anything.
|
|
103
105
|
variables, and (optionally) run a native program with those variables
|
104
106
|
set. This lets you run any program that uses the \s-1WINE\s0 and \s-1WINEPREFIX\s0
|
105
107
|
variables with wwine instead of wine (effectively giving you bottle
|
106
|
-
support, as well as support for using crossover/cxgames/cxoffice/..
|
107
|
-
of wine).
|
108
|
+
support, as well as support for using crossover/cxgames/cxoffice/proton/..
|
109
|
+
instead of wine).
|
108
110
|
|
109
111
|
When you use \-\-env, wwine will obey \-\-bottle and \-\-wine (or \-\-from) and set
|
110
112
|
\&\s-1WINE\s0 and \s-1WINEPREFIX\s0 accordingly. If you supply additional parameters, then
|
@@ -237,6 +239,9 @@ sending them the \s-1KILL\s0 signal. Should only be used if \*(L"wwine \-k\*(R"
|
|
237
239
|
.IP "\fIwwine \-\-bottle test \-\-wine cx \-\-kill\fR" 4
|
238
240
|
.IX Item "wwine --bottle test --wine cx --kill"
|
239
241
|
Kill any crossover processes running in the bottle \*(L"test\*(R".
|
242
|
+
.IP "\fIwwine \-b steam:201230 \-w proton\-3.16 winecfg\fR" 4
|
243
|
+
.IX Item "wwine -b steam:201230 -w proton-3.16 winecfg"
|
244
|
+
Runs winecfg in the Steam/Proton bottle for game \s-1ID 201230\s0 using Proton 3.16.
|
240
245
|
.SH "SUPPORTED WINE FLAVOURS"
|
241
246
|
.IX Header "SUPPORTED WINE FLAVOURS"
|
242
247
|
The following flavours of wine are supported:
|
@@ -251,8 +256,10 @@ versions \*(L"Crossover Office\*(R" and \*(L"Crossover Games\*(R". <http://www.c
|
|
251
256
|
.IX Item "Proton (Steam Play)"
|
252
257
|
The wine version used by Steam Play to run Windows games in the native Steam
|
253
258
|
client. Note that this does not obey \-\-winearch or \-\-debug, since proton uses
|
254
|
-
its own builtin arch detection and debug method.
|
255
|
-
|
259
|
+
its own builtin arch detection and debug method. When using proton, wwine will
|
260
|
+
add support for builtin wine commands, like winecfg, which proton can't handle
|
261
|
+
by default. <https://steampowered.com> and
|
262
|
+
<https://github.com/ValveSoftware/Proton>.
|
256
263
|
.IP "\fBLutris\fR" 4
|
257
264
|
.IX Item "Lutris"
|
258
265
|
Wine packages installed via Lutris. <https://lutris.net/>
|
@@ -295,7 +302,7 @@ submit feature requests there as well.
|
|
295
302
|
\&\fBwwine\fR is written by Eskild Hustvedt <\fIcode at zerodogg dot org\fR>
|
296
303
|
.SH "LICENSE AND COPYRIGHT"
|
297
304
|
.IX Header "LICENSE AND COPYRIGHT"
|
298
|
-
Copyright (C) Eskild Hustvedt 2009
|
305
|
+
Copyright (C) Eskild Hustvedt 2009\-2018
|
299
306
|
.PP
|
300
307
|
This is free software; see the source for copying conditions. There is \s-1NO\s0
|
301
308
|
warranty; not even for \s-1MERCHANTABILITY\s0 or \s-1FITNESS FOR A PARTICULAR PURPOSE.\s0
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: wwine
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: '0.6'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Eskild Hustvedt
|
8
8
|
autorequire:
|
9
9
|
bindir: "."
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-11-12 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: wwine is a a wine(1) wrapper. It wraps various flavours of wine (including
|
14
14
|
vanilla wine and crossover) into a single unified interface, complete with full
|
@@ -26,7 +26,7 @@ files:
|
|
26
26
|
- wwine.1
|
27
27
|
homepage: http://random.zerodogg.org/wwine
|
28
28
|
licenses:
|
29
|
-
-
|
29
|
+
- GPL-3.0
|
30
30
|
metadata: {}
|
31
31
|
post_install_message:
|
32
32
|
rdoc_options: []
|