wwine 0.5.0 → 0.6
Sign up to get free protection for your applications and to get access to all the features.
- 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: []
|