wwine 0.2.2 → 0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. checksums.yaml +7 -0
  2. data/wwine +353 -122
  3. metadata +12 -11
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: e0c1328444909d1ab568f2290bc792a4ed4a790f
4
+ data.tar.gz: 07934726e9f51a60865e240a0edab85f3b850b6f
5
+ SHA512:
6
+ metadata.gz: b6b535f272c338396857e9e619a258b3d668aacce073153b0ed0c06945e2b410f0e042bb79f92596ceeeb686a12dba384a2e87e4988d2388a3e511a7ad0dc51c
7
+ data.tar.gz: 9907eca8940177e1ff09500e2af83b06d91abcacbfecea8a3de0ed018ccd50026a2d8115f7fd63a2fff2e7bf2c49e5880afcc7ee802ccc333658678e908139a2
data/wwine CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/ruby
2
2
  # wwine
3
- # Copyright (C) Eskild Hustvedt 2009, 2010, 2011, 2012
3
+ # Copyright (C) Eskild Hustvedt 2009, 2010, 2011, 2012, 2013
4
4
  #
5
5
  # This program is free software: you can redistribute it and/or modify
6
6
  # it under the terms of the GNU General Public License as published by
@@ -20,13 +20,15 @@ require 'getoptlong'
20
20
  # To read info for --debuginfo
21
21
  require 'open3'
22
22
  # Application version
23
- $version = '0.2.2'
23
+ $version = '0.3'
24
24
  # The wine flavour to use
25
25
  $wine = nil
26
26
  # The bottle to use
27
27
  $bottle = nil
28
28
  # CX path
29
29
  $cxPath = nil
30
+ # CXG path
31
+ $cxgPath = nil
30
32
  # Path to write wrapper to
31
33
  $wrapperPath = nil
32
34
  # Directory to cd to in a wrapper
@@ -37,13 +39,21 @@ $wwineDataFrom = nil
37
39
  $envMode = false
38
40
  # true if we're in --tricks mode
39
41
  $tricksMode = false
42
+ # A positive integer if we're in --kill or --drykill mode
43
+ # (--drykill = 9999)
44
+ $killMode = nil
40
45
  # Verbosity level
41
46
  $verbosity = 0
42
47
  V_INFO=1
43
48
  V_DBG=2
44
49
 
45
50
  # Purpose: Attempt to kill all running wine processes
46
- def killWine (dryRun = false, signal = 15)
51
+ def killWine (signal)
52
+ dryRun = false
53
+ if signal == 9999
54
+ dryRun = true
55
+ signal = 15
56
+ end
47
57
  # Open a pipe to ps to read processes
48
58
  wines = IO.popen('ps uxw')
49
59
  # True if we have killed something
@@ -70,6 +80,13 @@ def killWine (dryRun = false, signal = 15)
70
80
  else
71
81
  sigName = 'signal '+signal
72
82
  end
83
+ if !dryRun
84
+ print 'Sending '+sigName+' to the following processes:'+"\n\n"
85
+ else
86
+ print 'Would send '+sigName+' to the following processes:'+"\n\n"
87
+ end
88
+ format = "%-10s %-12s %-8s %-20s\n"
89
+ printf(format,'Wine','Bottle','PID','Command')
73
90
  # Go through each line in the 'ps' output
74
91
  wines.each do |line|
75
92
  # True if we *require* /proc to be read for this process.
@@ -111,7 +128,6 @@ def killWine (dryRun = false, signal = 15)
111
128
 
112
129
  # /exe test
113
130
  if File.readable?('/proc/'+pid+'/exe') and File.symlink?('/proc/'+pid+'/exe')
114
- linkValue = File.readlink('/proc/'+pid+'/exe')
115
131
  if File.readlink('/proc/'+pid+'/exe') !~ /\/[^\/]*wine[^\/]*$/i
116
132
  next
117
133
  end
@@ -127,16 +143,21 @@ def killWine (dryRun = false, signal = 15)
127
143
  end
128
144
  # Clean up the name
129
145
  name.sub!(/\s*$/,'')
146
+ extra = getFromEnviron('/proc/'+pid+'/environ')
147
+ if $wine && resolveWine($wine) != extra['wine']
148
+ next
149
+ elsif $bottle && $bottle != extra['bottle']
150
+ next
151
+ end
152
+ # Output information
153
+ printf(format,extra['wine'],extra['bottle'],pid,name)
130
154
  # Send SIGTERM (or output information if in dryRun mode)
131
155
  if !dryRun
132
- puts 'Sending '+sigName+' to '+name+' (PID '+pid+')'
133
156
  begin
134
157
  Process.kill(signal,pid.to_i)
135
158
  rescue
136
159
  puts('Error while attempting to send signal to '+pid+': '+$!)
137
160
  end
138
- else
139
- puts 'Would send '+sigName+' to '+name+' (PID '+pid+')'
140
161
  end
141
162
  killed = true
142
163
  end
@@ -145,12 +166,50 @@ def killWine (dryRun = false, signal = 15)
145
166
  end
146
167
  end
147
168
 
169
+ # Purpose: Get information from /proc/PID/environ
170
+ def getFromEnviron(path)
171
+ info = Hash.new
172
+ info['bottle'] = '(?)'
173
+ info['wine'] = '(?)'
174
+ if File.readable?(path)
175
+ source = File.open(path)
176
+ env = Hash.new
177
+ source.each("\0") do |entry|
178
+ key = entry.sub(/^([^=]+)=.*$/,'\1').chomp
179
+ value = entry.sub(/^[^=]+=(.*)$/,'\1').chomp
180
+ env[key] = value
181
+ end
182
+
183
+ if env['CX_BOTTLE']
184
+ info['bottle'] = env['CX_BOTTLE']
185
+ elsif env['WINEPREFIX']
186
+ info['bottle'] = env['WINEPREFIX'].sub(/^.*\/([^\/]+)$/,'\1').chomp
187
+ elsif env['__WWINE_INT_XBOTTLE']
188
+ info['bottle'] = env['__WWINE_INT_XBOTTLE']
189
+ else
190
+ info['bottle'] = '(default)'
191
+ end
192
+ if env['CX_ROOT'] && env['CX_ROOT'].match(/cxoffice/)
193
+ info['wine'] = 'crossover'
194
+ elsif env['CX_ROOT'] && env['CX_ROOT'].match(/cxgames/)
195
+ info['wine'] = 'cxgames'
196
+ elsif env['__WWINE_INT_XWINE']
197
+ info['wine'] = env['__WWINE_INT_XWINE']
198
+ elsif env['WINELOADER']
199
+ info['wine'] = 'wine'
200
+ end
201
+ info['wine'].sub!(/\0/,'')
202
+ info['bottle'].sub!(/\0/,'')
203
+ end
204
+ return info
205
+ end
206
+
148
207
  # Purpose: Print formatted --help output
149
208
  # Usage: printHelp('-shortoption', '--longoption', 'description');
150
209
  # Description will be reformatted to fit within a normal terminal
151
210
  def printHelp (short,long,description)
152
211
  maxlen = 80
153
- optionlen = 20
212
+ optionlen = 21
154
213
  # Check if the short/long are LONGER than optionlen, if so, we need
155
214
  # to do some additional magic to take up only $maxlen.
156
215
  # The +1 here is because we always add a space between them, no matter what
@@ -178,7 +237,7 @@ def printHelp (short,long,description)
178
237
  raise("Option mismatch")
179
238
  end
180
239
  generatedDesc.split(/\n/).each do |descr|
181
- printf("%-4s %-15s %s\n",short,long,descr)
240
+ printf("%-4s %-16s %s\n",short,long,descr)
182
241
  short = ''; long = ''
183
242
  end
184
243
  end
@@ -233,6 +292,13 @@ def writeWrapper (targetFile, wwineCommand, otherCommand, cwd, wwineInfo, args,
233
292
  exit(1)
234
293
  end
235
294
 
295
+ # If CxGamesinstalldir is present, use format v3, otherwise
296
+ # v2 is fine.
297
+ metaFormat = 'v2'
298
+ if wwineInfo['CxGamesinstalldir']
299
+ metaFormat = 'v3'
300
+ end
301
+
236
302
  file.puts('#!/bin/sh')
237
303
  file.puts('# Script autogenerated by wwine '+$version+' (http://random.zerodogg.org/wwine)')
238
304
  file.puts('# Licensed under the GNU General Public License version 3 or later')
@@ -241,12 +307,11 @@ def writeWrapper (targetFile, wwineCommand, otherCommand, cwd, wwineInfo, args,
241
307
  file.puts('# along with wwine. If not, see <http://www.gnu.org/licenses/>.')
242
308
  file.puts('#')
243
309
  file.puts('# -- Begin wwine metadata --')
244
- file.puts('# wwineInfo: v2')
245
- file.puts('# wwineDir: '+wwineInfo[0])
246
- file.puts('# wwineWine: '+wwineInfo[1])
247
- file.puts('# wwineBottle: '+wwineInfo[2])
248
- file.puts('# wwineCxinstalldir: '+wwineInfo[3])
249
- # wwineCmd isn't used in v2, but v1 outputs an invalid message if it
310
+ file.puts('# wwineInfo: '+metaFormat)
311
+ wwineInfo.each do |key,value|
312
+ file.puts('# wwine'+key+': '+value)
313
+ end
314
+ # wwineCmd isn't used in v2 or v3, but v1 outputs an invalid message if it
250
315
  # doesn't exist. wwineCmd (unnumbered) will be dropped in a later version.
251
316
  file.puts('# wwineCmd: nil')
252
317
 
@@ -264,6 +329,11 @@ def writeWrapper (targetFile, wwineCommand, otherCommand, cwd, wwineInfo, args,
264
329
  file.puts("\t"+'wwine="`which wwine 2> /dev/null`"')
265
330
  file.puts('fi')
266
331
  file.puts('if [ "x$wwine" != "x" ]; then')
332
+ # _WWINE_SCRIPT is currently unused, but is present so that wwine can try
333
+ # to use '--from' automatically in the future if for some reason there are
334
+ # backwards-incompatible changes to one of the command-line parameters used
335
+ # by scripts.
336
+ file.puts("\t"+'export _WWINE_SCRIPT="$0"')
267
337
  file.puts("\t"+'exec "$wwine" '+shellQuote(wwineCommand).join(" ")+' "$@"')
268
338
  file.puts('else')
269
339
  # Add wineprefix if needed. This is used when --wine is wine because wine
@@ -271,7 +341,19 @@ def writeWrapper (targetFile, wwineCommand, otherCommand, cwd, wwineInfo, args,
271
341
  if wineprefix != nil
272
342
  wineprefix.sub!(/'/,'\\')
273
343
  file.puts("\t"+'export WINEPREFIX='+shellQuote(wineprefix))
274
- file.puts("\t"+"export WINEDEBUG='-all'");
344
+ end
345
+ if wwineInfo['Wine'] =~ /^pol/i
346
+ path = getPOLwithParams(wwineInfo['Wine'].sub(/^pol[-:]?/i,''),nil,false,true)
347
+ if ENV['WINEDEBUG'] != nil
348
+ file.puts("\t"+"export WINEDEBUG="+shellQuote(ENV['WINEDEBUG']))
349
+ end
350
+ file.puts("\t"+'export WINESERVER='+shellQuote(path+'/bin/wineserver'))
351
+ file.puts("\t"+'export WINELOADER='+shellQuote(path+'/bin/wine'))
352
+ file.puts("\t"+'export WINEDLLPATH='+shellQuote(path+'/lib/wine'))
353
+ elsif wwineInfo['Wine'] == 'wine' || wineprefix
354
+ if ENV['WINEDEBUG'] != nil
355
+ file.puts("\t"+"export WINEDEBUG="+shellQuote(ENV['WINEDEBUG']))
356
+ end
275
357
  end
276
358
  file.puts("\t"+"exec "+shellQuote(otherCommand).join(" ")+' "$@"')
277
359
  file.puts('fi')
@@ -287,7 +369,12 @@ end
287
369
  # Purpose: Generate a wwine command and wwineInfo array
288
370
  def generateWwineCmd (wine,bottle,wineCommand,type = nil)
289
371
  wwineCmd = []
290
- wwineInfo = ['nil','nil','nil','nil']
372
+ wwineInfo = {
373
+ 'Cxinstalldir' => 'nil',
374
+ 'Dir' => 'nil',
375
+ 'Bottle' => 'nil',
376
+ 'Wine' => 'nil'
377
+ }
291
378
 
292
379
  # Generate a wwine command-line
293
380
  if $verbosity > 0
@@ -295,15 +382,19 @@ def generateWwineCmd (wine,bottle,wineCommand,type = nil)
295
382
  end
296
383
  if $cxPath
297
384
  wwineCmd.push('--cxinstalldir',$cxPath)
298
- wwineInfo[3] = $cxPath
385
+ wwineInfo['Cxinstalldir'] = $cxPath
386
+ end
387
+ if $cxgPath
388
+ wwineCmd.push('--cxg-installdir',$cxgPath)
389
+ wwineInfo['CxGamesinstalldir'] = $cxgPath
299
390
  end
300
391
  if wine
301
392
  wwineCmd.push('--wine',wine)
302
- wwineInfo[1] = wine
393
+ wwineInfo['Wine'] = wine
303
394
  end
304
395
  if bottle
305
396
  wwineCmd.push('--bottle',bottle)
306
- wwineInfo[2] = bottle;
397
+ wwineInfo['Bottle'] = bottle;
307
398
  end
308
399
  return wwineCmd, wwineInfo
309
400
  end
@@ -330,13 +421,13 @@ def generateWrapper (wine,bottle,targetFile,wineCommand,args,type = nil)
330
421
  $wrapperCwd = Dir.pwd
331
422
  end
332
423
 
333
- wwineInfo[0] = $wrapperCwd
424
+ wwineInfo['Dir'] = $wrapperCwd
334
425
 
335
426
  wineprefix = nil
336
427
 
337
428
  # For wine there is no --bottle definition in the wine command itself,
338
429
  # so we need to export a wineprefix in the launch script
339
- if type == 'wine'
430
+ if (type == 'wine' || type =~ /^pol[-:]/) && ENV['WINEPREFIX']
340
431
  wineprefix = ENV['WINEPREFIX'].dup
341
432
  end
342
433
 
@@ -349,14 +440,12 @@ def setEnvAndExec (wine,bottle,cmd,args,type)
349
440
  if wine == nil
350
441
  type,cmd = getAutoWithParams(bottle)
351
442
  end
352
- ENV['__WWINE_INT_WINE'] = wine
353
- vputs(V_DBG,'Set __WWINE_INT_WINE='+wine)
443
+ envPut('_WWINE_INT_WINE',wine)
354
444
 
355
445
  if wine == 'cxoffice' || wine == 'cxgames' || wine == 'crossover'
356
446
  cxdir = getCXwithParams(wine,bottle,true,false,true)
357
447
  if File.executable?(cxdir+'/bin/wineserver')
358
- vputs(V_DBG,'Set WINESERVER='+cxdir+'/bin/wineserver')
359
- ENV['WINESERVER'] = cxdir+'/bin/wineserver'
448
+ envPut('WINESERVER',cxdir+'/bin/wineserver')
360
449
  end
361
450
  end
362
451
 
@@ -364,31 +453,28 @@ def setEnvAndExec (wine,bottle,cmd,args,type)
364
453
  puts("--env requires a --bottle")
365
454
  exit(1)
366
455
  end
367
- vputs(V_DBG,'Set __WWINE_INT_BOTTLE='+bottle)
368
- ENV['__WWINE_INT_BOTTLE'] = bottle
369
- vputs(V_DBG,'Set __WWINE_INT_ENVMODE='+$version)
370
- ENV['__WWINE_INT_ENVMODE'] = $version
456
+ envPut('__WWINE_INT_BOTTLE',bottle);
457
+ envPut('__WWINE_INT_ENVMODE',$version)
371
458
  if $verbosity > 0
372
- vputs(V_DBG,'Set __WWINE_INT_VERBOSITY='+$verbosity.to_s)
373
- ENV['__WWINE_INT_VERBOSITY'] = $verbosity.to_s
459
+ envPut('__WWINE_INT_VERBOSITY',$verbosity.to_s)
374
460
  end
375
461
  if $cxPath
376
- vputs(V_DBG,'Set __WWINE_INT_CXPATH='+$cxpath)
377
- ENV['__WWINE_INT_CXPATH'] = $cxPath
462
+ envPut('__WWINE_INT_CXPATH',$cxPath);
463
+ end
464
+ if $cxgPath
465
+ envPut('__WWINE_INT_CXGPATH',$cxgPath);
378
466
  end
379
467
 
380
468
  if wine == 'wine' || File.exists?(wine)
381
469
  bottlePath = ENV['WINEPREFIX']
382
- elsif wine == 'cedega'
470
+ elsif resolveWine(wine) == 'gametree'
383
471
  bottlePath = ENV['HOME']+'/.cedega/'+bottle
384
472
  else
385
473
  bottlePath = getCXwithParams(wine,bottle,true,true)
386
474
  end
387
475
 
388
- vputs(V_INFO,"Set WINEPREFIX="+bottlePath)
389
- vputs(V_INFO,"Set WINE="+File.expand_path($0))
390
- ENV['WINEPREFIX'] = bottlePath
391
- ENV['WINE'] = File.expand_path($0)
476
+ envPut('WINEPREFIX',bottlePath)
477
+ envPut('WINE',File.expand_path($0))
392
478
  if args.length > 0
393
479
  puts("Executing "+args.join(' '))
394
480
  exec *args
@@ -426,8 +512,9 @@ def loadWwineDataFromFile (file,dryRun = false)
426
512
  end
427
513
 
428
514
  info = Hash.new
429
- wwineInfo = ''
430
- wwineCmd = ''
515
+ # Default entries
516
+ info['CxGamesinstalldir'] = 'nil'
517
+ info['Cxinstalldir'] = 'nil'
431
518
 
432
519
  source.each do |line|
433
520
  if line.match(/^#\s+wwine/)
@@ -442,13 +529,22 @@ def loadWwineDataFromFile (file,dryRun = false)
442
529
  puts "Unable to continue."
443
530
  exit(0)
444
531
  end
445
- if info['Info'] == 'v2'
532
+ if info['Info'] == 'v2' || info['Info'] == 'v3'
446
533
  info = parseWwineDataV2(info);
447
534
  elsif info['Info'].match(/^v1/)
448
535
  info = parseWwineDataV1(info)
536
+ if ! $wrapperPath
537
+ puts "-- Note: --"
538
+ puts "This file is using the wwine metadata format v1."
539
+ puts "This format has been deprecated and support for it will be dropped in"
540
+ puts "a later version of wwine. You may upgrade it with this command:"
541
+ puts "wwine --from "+shellQuote(file)+" --wrap "+shellQuote(file+'.new')+" && mv "+shellQuote(file)+" "+shellQuote(file+'.old')+' && mv '+shellQuote(file+'.new')+' '+shellQuote(file)
542
+ puts "-- --"
543
+ puts ""
544
+ end
449
545
  else
450
546
  version = info['Info'].sub(/^(v\S+).+/,'\1').chomp
451
- puts "This version of wwine supports info format v1 and v2."
547
+ puts "This version of wwine supports info format v1, v2 and v3."
452
548
  puts "This file is version "+version
453
549
  puts "Unable to continue."
454
550
  exit(0)
@@ -497,9 +593,13 @@ def loadWwineDataFromFile (file,dryRun = false)
497
593
  $cxPath = info['Cxinstalldir']
498
594
  printf(outFormat,outMessage+'--cxinstalldir',$cxPath)
499
595
  end
596
+ if $cxgPath == nil && info['CxGamesinstalldir'] != 'nil'
597
+ $cxgPath = info['CxGamesinstalldir']
598
+ printf(outFormat,outMessage+'--cxg-installdir',$cxgPath)
599
+ end
500
600
 
501
601
  # Set the command to run
502
- if ! dryRun && !$envMode
602
+ if ! dryRun && !$envMode && !$killMode
503
603
  if $wrapperPath
504
604
  out = 'Program command'
505
605
  else
@@ -577,6 +677,12 @@ def vputs (level,str)
577
677
  end
578
678
  end
579
679
 
680
+ # Purpose: Set an environment variable
681
+ def envPut (name,value)
682
+ vputs(V_DBG,'Set '+name+'='+value)
683
+ ENV[name] = value;
684
+ end
685
+
580
686
  # Purpose: Print the help output
581
687
  def Help ()
582
688
  puts "wwine "+$version
@@ -584,12 +690,14 @@ def Help ()
584
690
  puts "Usage: wwine (WWINE PARAMETERS) PROGRAM -- [PROGRAM ARGUMENTS]"
585
691
  puts ""
586
692
  printHelp('-h','--help','Display this help text')
587
- printHelp('-w','--wine','Select the wine to use: wine, crossover, cxgames, cedega, or a path to a wine bin. Default: wine')
693
+ printHelp('-w','--wine','Select the wine to use. Any wine listed in "wwine --list" or the path to a wine binary.')
588
694
  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.')
589
695
  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.')
696
+ printHelp('-l','--list','List all available wine versions')
590
697
  printHelp('-k','--kill','Attempt to kill all running wine processes')
591
698
  printHelp('','--drykill','Print what --kill would have done, but don\'t actually do anything')
592
- printHelp('-c','--cxinstalldir','Use the supplied path as the install path for CXoffice/CXgames (default: autodetect).')
699
+ printHelp('-c','--cxinstalldir','Use the supplied path as the install path for Crossover (default: autodetect).')
700
+ printHelp('-C','--cxg-installdir','Use the supplied path as the install path for CXGames (default: autodetect)')
593
701
  printHelp('','--wrap','Write a wrapper script of your current wwine command to the path supplied')
594
702
  printHelp('','--wrapdir','Use the supplied directory as the working directory for the script created by --wrap (default: current directory)')
595
703
  printHelp('-s','--from','Load parameters and program from the wrapper script supplied. Command-line arguments overrides settings from wrapper script.')
@@ -658,10 +766,10 @@ def getWineVersion (source = 'wine', fromStderr = false, cmdOpt = '--version')
658
766
  end
659
767
 
660
768
  # Purpose: Get cedega version string
661
- def getCedegaVersionString ()
769
+ def getGameTreeVersionString ()
662
770
  cedegaVer = nil
663
771
 
664
- if inPath('cedega')
772
+ if inPath('cedega') || inPath('gametree')
665
773
  begin
666
774
  # We need the HOME variable
667
775
  if ENV.has_key?('HOME')
@@ -753,7 +861,7 @@ end
753
861
 
754
862
  # Purpose: Print debugging info
755
863
  def debugInfo ()
756
- outFormat = '%-20s: %s'+"\n"
864
+ outFormat = '%-30s: %s'+"\n"
757
865
  puts "wwine "+$version
758
866
  # Load a --from file if it is set
759
867
  if $wwineDataFrom
@@ -776,20 +884,37 @@ def debugInfo ()
776
884
  printf(outFormat,'wwine md5sum','(exception: '+$!+')');
777
885
  end
778
886
 
779
- begin
887
+ listWines(true)
888
+ exit(0)
889
+ end
780
890
 
891
+ # Purpose: List available wine versions
892
+ def listWines(debug = false)
893
+ outFormat = '%-30s: %s'+"\n"
894
+ begin
781
895
  defaultWine,defaultWCMD = getAutoWithParams(nil,false)
896
+ if !debug
897
+ puts('Available wine versions:')
898
+ end
782
899
  if defaultWine == nil
783
900
  defaultWine = '(no wine found)'
784
901
  end
785
- printf(outFormat,'Default flavour',defaultWine)
902
+ if defaultWine != 'wine'
903
+ printf(outFormat,'(default wine)',defaultWine)
904
+ end
786
905
 
787
906
  if inPath('wine')
788
907
  wineVer = getWineVersion()
789
- else
790
- wineVer = '(not present)'
908
+ printf(outFormat,'wine',wineVer)
909
+ if defaultWine == 'wine'
910
+ puts " (default when no --wine is specified)"
911
+ end
912
+ end
913
+
914
+ if $wine != nil and File.executable?($wine) and not File.directory?($wine)
915
+ otherWver = getWineVersion($wine)
916
+ printf(outFormat,'--wine',otherWver+' ('+$wine+')')
791
917
  end
792
- printf(outFormat,'Wine',wineVer)
793
918
 
794
919
  cxgBin = getCXwithParams('cxgames',nil,false)
795
920
  cxgVer = getCXVersionsFrom(cxgBin,true)
@@ -797,19 +922,33 @@ def debugInfo ()
797
922
  cxoBin = getCXwithParams('cxoffice',nil,false)
798
923
  cxoVer = getCXVersionsFrom(cxoBin,true)
799
924
 
800
- if(cxoBin && !cxgBin)
801
- cxgVer = '(not available - aliased to crossover)'
925
+ if (cxgBin || !cxoBin)
926
+ printf(outFormat,'cxgames',cxgVer)
927
+ puts " (aliases for cxgames: cxg, cxgames)"
802
928
  end
803
929
 
804
- printf(outFormat,'Crossover Games',cxgVer)
805
- printf(outFormat,'Crossover',cxoVer)
930
+ if cxoVer
931
+ printf(outFormat,'crossover',cxoVer)
932
+ if !cxgBin
933
+ puts " (aliases for crossover: cx, cxo, cxg, cxoffice, cxgames)"
934
+ else
935
+ puts " (aliases for crossover: cx, cxo, cxoffice)"
936
+ end
937
+ end
938
+
939
+ cedegaVer = getGameTreeVersionString()
940
+ if cedegaVer
941
+ printf(outFormat,'gametree',cedegaVer)
942
+ puts " (aliases for gametree: cedega)"
943
+ end
806
944
 
807
- cedegaVer = getCedegaVersionString()
808
- printf(outFormat,'Cedega',cedegaVer)
945
+ Dir.glob(ENV['HOME']+'/.PlayOnLinux/wine/linux-*/*') do |dir|
946
+ name = dir.sub(/^.*\/([^\/]+)/,'\1')
947
+ printf(outFormat,'pol-'+name,getWineVersion(dir+'/bin/wine'))
948
+ end
809
949
  rescue => ex
810
950
  handleException(ex)
811
951
  end
812
- exit(0)
813
952
  end
814
953
 
815
954
  # Purpose: Handle an exception
@@ -828,12 +967,12 @@ def handleException(ex)
828
967
  end
829
968
 
830
969
  # Purpose: Get parameters for wine
831
- def getWineWithParams (wine,bottle, missingIsFatal = true)
970
+ def getWineWithParams (wine,bottle, missingIsFatal = true, playOnLinux = false)
832
971
  final = []
833
- possibleWines = [ 'wine32','wine','wine64','wine.bin','wine.real' ]
972
+ possibleWines = [ 'wine32','wine','wine64','wine.bin','wine.real','wine-unstable','wine32-unstable' ]
834
973
  # Manual search path, in the odd case none of the above are in $PATH.
835
974
  # Ie. /usr/lib32/wine/wine.bin is the real wine binary on Debian
836
- searchPath = [ '/usr/lib32/wine/','/usr/bin' ]
975
+ searchPath = [ '/usr/lib32/wine/','/usr/bin','/usr/lib/i386-linux-gnu/wine-unstable','/usr/lib/i386-linux-gnu/wine', ]
837
976
  # If wine is not a path or does not exist, check for wine in the path
838
977
  if !File.exists?(wine)
839
978
  wine = nil
@@ -869,33 +1008,47 @@ def getWineWithParams (wine,bottle, missingIsFatal = true)
869
1008
  end
870
1009
  final.push(wine)
871
1010
 
1011
+ # wwine's bottle storage
1012
+ wwine_bottleRoot = ENV['HOME']+'/.wwinebottles/'
1013
+ # PlayOnLinux's bottle storage
1014
+ playOnLinux_bottleRoot = ENV['HOME']+'/.PlayOnLinux/wineprefix/'
1015
+ # wwine is the default
1016
+ bottleRoot = wwine_bottleRoot
1017
+ # If a POL bottle exists and we are using a POL wine, then use the
1018
+ # POL bottle, otherwise use the wwine bottle
1019
+ if playOnLinux && bottle != nil
1020
+ if File.exists?(playOnLinux_bottleRoot+bottle)
1021
+ bottleRoot = playOnLinux_bottleRoot
1022
+ vputs(V_INFO,'Using the PlayOnLinux bottle path since a POL bottle named "'+bottle+'" exists')
1023
+ else
1024
+ vputs(V_DBG,'Using the wwine bottle location for POL since no POL bottle named "'+bottle+'" exists')
1025
+ end
1026
+ end
1027
+
872
1028
  # Set WINEPREFIX for bottle support
873
1029
  if(bottle != nil && bottle.length > 0)
874
1030
  if ENV.has_key?('WINEPREFIX') && ENV['WINEPREFIX'].length > 0
875
1031
  warn 'WINEPREFIX= was already set, overriding it.'
876
1032
  end
877
1033
  if ! (bottle =~ /^\.?\//)
878
- bottle = ENV['HOME']+'/.wwinebottles/'+bottle
879
- if !File.exists?(ENV['HOME']+'/.wwinebottles/')
880
- vputs(V_INFO,ENV['HOME']+'/.wwinebottles/: does not exist, creating')
881
- vputs(V_DBG,ENV['HOME']+'/'+bottleDir+'/'+bottle+' did not exist')
1034
+ bottle = bottleRoot+bottle
1035
+ if !File.exists?(bottleRoot)
1036
+ vputs(V_INFO,bottleRoot+': does not exist, creating')
882
1037
  begin
883
- Dir.mkdir(ENV['HOME']+'/.wwinebottles/')
1038
+ Dir.mkdir(bottleRoot)
884
1039
  rescue SystemCallError
885
- puts('Failed to create directory "'+ENV['HOME']+'/.wwinebottles/'+": "+$!)
1040
+ puts('Failed to create directory "'+bottleRoot+": "+$!)
886
1041
  puts('Unable to continue.')
887
1042
  exit(1)
888
1043
  end
889
1044
  end
890
1045
  end
891
- ENV['WINEPREFIX'] = bottle
892
- vputs(V_INFO,'Set WINEPREFIX='+bottle)
1046
+ envPut('WINEPREFIX',bottle)
893
1047
  end
894
1048
 
895
1049
  # Default to no debugging output if WINEDEBUG is not set yet
896
1050
  if ! ENV.has_key?('WINEDEBUG')
897
- vputs(V_INFO,'Set WINEDEBUG=-all')
898
- ENV['WINEDEBUG'] = '-all'
1051
+ envPut('WINEDEBUG','-all')
899
1052
  end
900
1053
 
901
1054
  vputs(V_DBG,'Detected wine: '+final.join(' '))
@@ -917,8 +1070,13 @@ def getCXwithParams (wine,bottle, missingIsFatal = true, getBottleDir = false, g
917
1070
  # Various crossover install paths
918
1071
  wines = ['/opt/'+installName, ENV['HOME']+'/'+installName, ENV['HOME']+'/.local/'+installName, ENV['HOME']+'/games/'+installName]
919
1072
 
1073
+ pathMode = nil
920
1074
  # If cxpath is set then overwrite the default paths
921
- if $cxPath != nil
1075
+ if wine == 'cxgames' && $cxgPath != nil
1076
+ pathMode = $cxgPath
1077
+ wines = [ $cxgPath+'/'+installName, $cxgPath ]
1078
+ elsif $cxPath != nil
1079
+ pathMode = $cxPath
922
1080
  wines = [ $cxPath+'/'+installName, $cxPath ]
923
1081
  end
924
1082
 
@@ -940,10 +1098,10 @@ def getCXwithParams (wine,bottle, missingIsFatal = true, getBottleDir = false, g
940
1098
  end
941
1099
  end
942
1100
 
943
- # If we're using cxPath, perform some additional detection
944
- if $cxPath != nil and mode != 'crossover'
945
- if File.exists?($cxPath+'/etc/'+wine+'.conf')
946
- cxdir = $cxPath
1101
+ # If we're using $cx*Path, perform some additional detection
1102
+ if pathMode != nil and mode != 'crossover'
1103
+ if File.exists?(pathMode+'/etc/'+wine+'.conf')
1104
+ cxdir = pathMode
947
1105
  else
948
1106
  cxdir = nil
949
1107
  end
@@ -955,22 +1113,28 @@ def getCXwithParams (wine,bottle, missingIsFatal = true, getBottleDir = false, g
955
1113
  vputs(V_DBG,'Failed to detect cxdir')
956
1114
  return nil
957
1115
  end
958
- if $cxPath != nil
959
- puts('Could not find a directory named "'+installName+'" in '+$cxPath)
960
- puts('and '+$cxPath+' does not appear to be a '+installName+' install directory')
1116
+ if pathMode != nil
1117
+ puts('Could not find a directory named "'+installName+'" in '+pathMode)
1118
+ puts('and '+pathMode+' does not appear to be a '+installName+' install directory')
961
1119
  if installName == 'cxgames'
962
1120
  reverse = 'cxoffice'
963
1121
  else
964
1122
  reverse = 'cxgames'
965
1123
  end
966
- if File.exists?($cxPath+'/'+reverse) || File.exists?($cxPath+'/etc/'+reverse+'.conf')
967
- puts('The directory looks like a '+reverse+' directory. Maybe you wanted')
968
- puts('--wine '+reverse+' instead?')
1124
+ if $cxPath != nil && pathMode == $cxPath
1125
+ if File.exists?($cxPath+'/'+reverse) || File.exists?($cxPath+'/etc/'+reverse+'.conf')
1126
+ puts('The directory looks like a '+reverse+' directory. Maybe you wanted')
1127
+ puts('--wine '+reverse+' instead?')
1128
+ end
969
1129
  end
970
1130
  else
971
1131
  puts('Failed to locate '+wine)
972
1132
  puts('You could try to explicitly tell wwine where '+wine+' is installed')
973
- puts('by supplying --cxinstalldir')
1133
+ if wine == 'cxgames'
1134
+ puts('by supplying --cxg-installdir')
1135
+ else
1136
+ puts('by supplying --cxinstalldir')
1137
+ end
974
1138
  end
975
1139
  exit(1)
976
1140
  elsif getCXpath
@@ -1002,20 +1166,25 @@ def getCXwithParams (wine,bottle, missingIsFatal = true, getBottleDir = false, g
1002
1166
  end
1003
1167
  end
1004
1168
 
1005
- # Purpose: Get parameters for cedega
1006
- def getCedegaWithParams (wine,bottle, missingIsFatal = true)
1169
+ # Purpose: Get parameters for gametree
1170
+ def getGameTreeWithParams (wine,bottle, missingIsFatal = true)
1007
1171
  final = []
1172
+ gametreeBin = nil
1008
1173
 
1009
- if not inPath('cedega')
1174
+ if inPath('gametree')
1175
+ gametreeBin = 'gametree'
1176
+ elsif inPath('gametree')
1177
+ gametreeBin = 'cedega'
1178
+ else
1010
1179
  if missingIsFatal
1011
- puts('cedega does not appear to be installed')
1180
+ puts('gametree does not appear to be installed')
1012
1181
  exit(1)
1013
1182
  else
1014
1183
  return nil
1015
1184
  end
1016
1185
  end
1017
1186
 
1018
- final.push('cedega','--install')
1187
+ final.push(gametreeBin,'--install')
1019
1188
 
1020
1189
  # Use wwineFolder as the folder if no bottle was supplied
1021
1190
  if (bottle == nil || bottle.length == 0)
@@ -1023,10 +1192,44 @@ def getCedegaWithParams (wine,bottle, missingIsFatal = true)
1023
1192
  end
1024
1193
  final.push(bottle)
1025
1194
 
1026
- vputs(V_DBG,'Detected cedega: '+final.join(' '))
1195
+ vputs(V_DBG,'Detected gametree: '+final.join(' '))
1027
1196
  return final
1028
1197
  end
1029
1198
 
1199
+ # Purpose: Get parameters for PlayOnLinux
1200
+ def getPOLwithParams(wine,bottle, missingIsFatal = true, returnDetected = false)
1201
+ winePaths = [ ENV['HOME']+'/.PlayOnLinux/wine/linux-x86', ENV['HOME']+'/.PlayOnLinux/wine/linux-amd64' ]
1202
+ detectedWine = nil
1203
+ detectedWineDir = nil
1204
+ winePaths.each do |path|
1205
+ if File.exists?(path+'/'+wine+'/bin/wine')
1206
+ detectedWine = path+'/'+wine+'/bin/wine'
1207
+ detectedWineDir = path+'/'+wine
1208
+ end
1209
+ end
1210
+
1211
+ if returnDetected
1212
+ return detectedWine
1213
+ end
1214
+
1215
+ if not detectedWine
1216
+ if !missingIsFatal
1217
+ vputs(V_DBG,'Failed to locate wine '+wine)
1218
+ return nil
1219
+ end
1220
+ puts('There does not appear to be a wine named "'+wine+'"')
1221
+ puts('installed via PlayOnLinux. See "wwine --list" for a list of available wine versions.')
1222
+ exit(1)
1223
+ end
1224
+
1225
+ envPut('PATH',detectedWineDir+'/bin/:'+ENV['PATH'])
1226
+ envPut('WINESERVER',detectedWineDir+'/bin/wineserver')
1227
+ envPut('WINELOADER',detectedWine)
1228
+ envPut('WINEDLLPATH',detectedWineDir+'/lib/wine:'+ENV['WINEDLLPATH'].to_s)
1229
+ envPut('LD_LIBRARY_PATH',detectedWineDir+'/lib:'+ENV['LD_LIBRARY_PATH'].to_s)
1230
+ getWineWithParams(detectedWine,bottle,missingIsFatal,true)
1231
+ end
1232
+
1030
1233
  # Purpose: Detect which wine to use and get parameters for that one
1031
1234
  # Returns: type,cmd
1032
1235
  def getAutoWithParams (bottle, missingIsFatal = true, returnFlavour = false)
@@ -1041,8 +1244,8 @@ def getAutoWithParams (bottle, missingIsFatal = true, returnFlavour = false)
1041
1244
  type = 'cxoffice'
1042
1245
  end
1043
1246
  if cmd == nil
1044
- cmd = getCedegaWithParams('cedega',bottle,false)
1045
- type = 'cedega'
1247
+ cmd = getGameTreeWithParams('gametree',bottle,false)
1248
+ type = 'gametree'
1046
1249
  end
1047
1250
  if cmd == nil
1048
1251
  if missingIsFatal
@@ -1067,12 +1270,7 @@ def runWine (wine,bottle,args)
1067
1270
  wine = type
1068
1271
  else
1069
1272
  # Expand cx*
1070
- if wine == 'cxg'
1071
- wine = 'cxgames'
1072
- elsif wine == 'cxo' || wine == 'cx' || wine == 'cxoffice'
1073
- wine = 'crossover'
1074
- end
1075
-
1273
+ wine = resolveWine(wine)
1076
1274
  type = wine
1077
1275
 
1078
1276
  if wine == 'cxgames' || wine == 'cxoffice' || wine == 'crossover'
@@ -1090,8 +1288,11 @@ def runWine (wine,bottle,args)
1090
1288
  elsif wine == 'wine' || File.executable?(wine)
1091
1289
  type = 'wine'
1092
1290
  cmd = getWineWithParams(wine,bottle)
1093
- elsif wine == 'cedega'
1094
- cmd = getCedegaWithParams(wine,bottle)
1291
+ elsif resolveWine(wine) == 'gametree'
1292
+ cmd = getGameTreeWithParams(wine,bottle)
1293
+ elsif wine =~ /^pol[-:]?/i
1294
+ realWine = wine.sub(/^pol[-:]?/i,'')
1295
+ cmd = getPOLwithParams(realWine,bottle)
1095
1296
  else
1096
1297
  puts('Unknown --wine: '+wine)
1097
1298
  puts('Must be one of: wine, crossover, cxgames, cedega, or the path to a wine executable')
@@ -1120,7 +1321,7 @@ def runWine (wine,bottle,args)
1120
1321
  exit
1121
1322
  # For cedega we just output an invalid version number in the same syntax
1122
1323
  # as vanilla wine would have done
1123
- elsif wine == 'cedega'
1324
+ elsif resolveWine(wine) == 'gametree'
1124
1325
  puts 'wine-0.0.0'
1125
1326
  exit
1126
1327
  end
@@ -1134,6 +1335,11 @@ def runWine (wine,bottle,args)
1134
1335
  elsif $wrapperPath != nil
1135
1336
  generateWrapper(wine,bottle,$wrapperPath,cmd,args,type)
1136
1337
  else
1338
+ wine = resolveWine(wine)
1339
+ envPut('__WWINE_INT_XWINE',wine);
1340
+ if bottle
1341
+ envPut('__WWINE_INT_XBOTTLE',bottle);
1342
+ end
1137
1343
  runcmd(cmd)
1138
1344
  end
1139
1345
  end
@@ -1161,19 +1367,34 @@ else
1161
1367
  [ '--kill', '-k', GetoptLong::OPTIONAL_ARGUMENT ],
1162
1368
  [ '--drykill', GetoptLong::NO_ARGUMENT ],
1163
1369
  [ '--cxinstalldir','-c',GetoptLong::REQUIRED_ARGUMENT ],
1370
+ [ '--cxg-installdir','--cxgamesinstalldir','-C',GetoptLong::REQUIRED_ARGUMENT ],
1164
1371
  [ '--version',GetoptLong::NO_ARGUMENT ],
1165
1372
  [ '--wrap', GetoptLong::REQUIRED_ARGUMENT ],
1166
1373
  [ '--wrapdir', GetoptLong::REQUIRED_ARGUMENT ],
1167
1374
  [ '--debuginfo', GetoptLong::NO_ARGUMENT ],
1375
+ [ '--list-wines','--list','-l', GetoptLong::NO_ARGUMENT ],
1168
1376
  [ '--man', GetoptLong::NO_ARGUMENT ],
1169
1377
  [ '--env', GetoptLong::NO_ARGUMENT ],
1170
1378
  [ '--tricks', GetoptLong::NO_ARGUMENT ],
1171
- [ '--env-bottle', GetoptLong::NO_ARGUMENT ],
1172
1379
  [ '--from', '-s', GetoptLong::REQUIRED_ARGUMENT ],
1173
1380
  [ '--verbose', '-v', GetoptLong::NO_ARGUMENT ]
1174
1381
  )
1175
1382
  end
1176
1383
 
1384
+ # Purpose: Resolve a wine to its proper name
1385
+ def resolveWine(wine)
1386
+ map = Hash.new()
1387
+ map['cx'] = 'crossover'
1388
+ map['cxo'] = 'crossover'
1389
+ map['cxoffice'] = 'crossover'
1390
+ map['cxg'] = 'cxgames'
1391
+ map['cedega'] = 'gametree'
1392
+ if(map[wine])
1393
+ wine = map[wine]
1394
+ end
1395
+ return wine
1396
+ end
1397
+
1177
1398
  # Handle command-line arguments
1178
1399
  begin
1179
1400
  opts.each do |opt, arg|
@@ -1185,35 +1406,32 @@ begin
1185
1406
  $wine = arg
1186
1407
  when '--bottle'
1187
1408
  $bottle = arg
1188
- when '--env-bottle'
1189
- puts 'DEPRECATED: --env-bottle is deprecated as of wwine 0.2.2'
1190
- puts ' pending removal in 0.3'
1191
- if ENV['WINEPREFIX'] && ENV['WINEPREFIX'].length > 0
1192
- $bottle = File.basename(ENV['WINEPREFIX'])
1193
- else
1194
- puts 'wwine: --env-bottle supplied but WINEPREFIX is not set'
1195
- exit(1)
1196
- end
1197
1409
  when '--verbose'
1198
1410
  $verbosity = $verbosity+1
1199
1411
  when '--drykill'
1200
- killWine(true)
1201
- exit(0)
1412
+ $killMode = 9999
1202
1413
  when '--debuginfo'
1203
1414
  debugInfo()
1415
+ when '--list-wines'
1416
+ listWines()
1417
+ exit(0)
1204
1418
  when '--kill'
1205
- begin
1206
- killWine(false,arg)
1207
- rescue
1208
- puts "Error while attempting to kill processes: "+$!
1419
+ if arg == nil
1420
+ arg = 15
1209
1421
  end
1210
- exit(0)
1422
+ $killMode = arg
1211
1423
  when '--cxinstalldir'
1212
1424
  $cxPath = arg
1213
1425
  if ! File.exists?($cxPath)
1214
1426
  puts('The supplied --cxinstalldir "'+$cxPath+'" does not exist')
1215
1427
  exit(1)
1216
1428
  end
1429
+ when '--cxg-installdir'
1430
+ $cxgPath = arg
1431
+ if ! File.exists?($cxgPath)
1432
+ puts('The supplied --cxg-installdir "'+$cxgPath+'" does not exist')
1433
+ exit(1)
1434
+ end
1217
1435
  when '--version'
1218
1436
  puts('wwine version '+$version+' (for wine version info, run wwine --debuginfo)')
1219
1437
  exit(0)
@@ -1238,8 +1456,12 @@ begin
1238
1456
  puts('--verbose assumed because the environment variable WWINE_VERBOSE is set to 1')
1239
1457
  $verbosity = 1
1240
1458
  end
1241
- rescue
1242
- puts('See --help for more inforation')
1459
+ rescue => ex
1460
+ if opts.error?
1461
+ puts('See --help for more inforation')
1462
+ else
1463
+ handleException(ex)
1464
+ end
1243
1465
  exit(1)
1244
1466
  end
1245
1467
 
@@ -1247,6 +1469,15 @@ if $wwineDataFrom
1247
1469
  loadWwineDataFromFile($wwineDataFrom)
1248
1470
  end
1249
1471
 
1472
+ if $killMode != nil
1473
+ begin
1474
+ killWine($killMode)
1475
+ rescue
1476
+ puts "Error while attempting to kill processes: "+$!
1477
+ end
1478
+ exit(0)
1479
+ end
1480
+
1250
1481
  if ARGV.length == 0 && !$envMode
1251
1482
  Help()
1252
1483
  exit(1)
metadata CHANGED
@@ -1,17 +1,18 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wwine
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
5
- prerelease:
4
+ version: '0.3'
6
5
  platform: ruby
7
6
  authors:
8
7
  - Eskild Hustvedt
9
8
  autorequire:
10
9
  bindir: .
11
10
  cert_chain: []
12
- date: 2012-07-21 00:00:00.000000000 Z
11
+ date: 2013-10-14 00:00:00.000000000 Z
13
12
  dependencies: []
14
- description: wwine is a simple wine wrapper.
13
+ description: wwine is a a wine(1) wrapper. It wraps various flavours of wine (including
14
+ vanilla wine and crossover) into a single unified interface, complete with full
15
+ bottle support for all of them (including vanilla wine).
15
16
  email: code at zerodogg dot org
16
17
  executables:
17
18
  - wwine
@@ -24,27 +25,27 @@ files:
24
25
  - wwine.1
25
26
  - ./wwine
26
27
  homepage: http://random.zerodogg.org/wwine
27
- licenses: []
28
+ licenses:
29
+ - GPLv3
30
+ metadata: {}
28
31
  post_install_message:
29
32
  rdoc_options: []
30
33
  require_paths:
31
34
  - lib
32
35
  required_ruby_version: !ruby/object:Gem::Requirement
33
- none: false
34
36
  requirements:
35
- - - ! '>='
37
+ - - '>='
36
38
  - !ruby/object:Gem::Version
37
39
  version: '0'
38
40
  required_rubygems_version: !ruby/object:Gem::Requirement
39
- none: false
40
41
  requirements:
41
- - - ! '>='
42
+ - - '>='
42
43
  - !ruby/object:Gem::Version
43
44
  version: '0'
44
45
  requirements: []
45
46
  rubyforge_project:
46
- rubygems_version: 1.8.23
47
+ rubygems_version: 2.0.10
47
48
  signing_key:
48
- specification_version: 3
49
+ specification_version: 4
49
50
  summary: wwine is a simple wine wrapper.
50
51
  test_files: []