wwine 0.2.2 → 0.3

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.
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: []