update wine to wine-1.1.7
[sugaredwine.git] / wineactivity.py
blob208d6e2229d6669dc503d0a3998c452160cddb41
1 from sugar.activity import activity
2 import sys
3 import os
4 import gobject
5 import gtk
6 import shutil
7 import tempfile
8 import logging
9 import atexit
11 def mime_to_extension(mimetype):
12 # Sugar's metadata does not typically provide a file extension, and the
13 # filename tends to be unusable. Windows depends on extensions so we need
14 # a conversion function. This one is pretty lame but should work for now.
15 if mimetype == 'application/x-msi':
16 return '.msi'
17 else:
18 return '.exe'
20 class WineActivity(activity.Activity):
21 def __init__(self, handle):
22 activity.Activity.__init__(self, handle)
24 self.bundle_path = activity.get_bundle_path()
26 try:
27 activity_root = activity.get_activity_root()
28 wine_prefix = os.path.join(activity_root, 'data', 'wine')
29 except AttributeError:
30 try:
31 activity_root = os.environ['SUGAR_ACTIVITY_ROOT']
32 wine_prefix = os.path.join(activity_root, 'data', 'wine')
33 except KeyError:
34 activity_root = None
35 wine_prefix = os.path.expanduser('~/.wine')
37 try:
38 self.desktop_parent = gtk.EventBox()
39 self.desktop_parent.show()
40 self.set_canvas(self.desktop_parent)
41 except AttributeError:
42 # remove any children of the window that Sugar may have added
43 for widget in self.get_children():
44 self.remove(widget)
46 self.desktop_parent = self
48 os.environ['LD_LIBRARY_PATH'] = "%s:%s" % (os.path.join(self.bundle_path, 'lib'), os.environ.get('LD_LIBRARY_PATH', ''))
49 os.environ['PATH'] = "%s:%s" % (os.path.join(self.bundle_path, 'bin'), os.environ.get('PATH', ''))
50 os.environ['WINEPREFIX'] = wine_prefix
51 os.environ['WINELOADER'] = os.path.join(self.bundle_path, 'bin/wine')
52 os.environ['WINESERVER'] = os.path.join(self.bundle_path, 'bin/wineserver')
53 os.environ['WINEDLLPATH'] = os.path.join(self.bundle_path, 'lib/wine')
55 self.desktop_name = os.getpid()
57 firstrun = not os.path.exists(wine_prefix)
59 self.setup_prefix(firstrun)
61 self.desktop_parent.connect('map', self.on_parent_map)
63 self.wine_pid = None
65 self.to_run = []
66 self.tempfiles = []
68 self.set_title("Wine")
70 def on_parent_map(self, widget):
71 os.environ['WINE_DESKTOP_PARENT'] = str(self.desktop_parent.window.xid)
73 gtk.gdk.flush()
75 os.chdir(self.get_unix_path('c:\\'))
77 width = gtk.gdk.screen_width()
78 height = gtk.gdk.screen_height()
80 self.wine_pid, stdin, stdout, stderr = gobject.spawn_async(
81 ('wine', 'explorer', '/desktop=%s,%sx%s' % (self.desktop_name, width, height)),
82 flags=gobject.SPAWN_SEARCH_PATH|gobject.SPAWN_DO_NOT_REAP_CHILD)
83 gobject.child_watch_add(self.wine_pid, self.on_wine_quit, None)
85 for cmdline in self.to_run:
86 self.start_wine(*cmdline)
88 def start_wine(self, *args):
89 if self.wine_pid:
90 logging.info("running command line: %s" % ' '.join(str(x) for x in args))
91 gobject.spawn_async(
92 ['wine', 'explorer', '/desktop=%s' % self.desktop_name] + [str(x) for x in args],
93 flags=gobject.SPAWN_SEARCH_PATH)
94 else:
95 self.to_run.append(args)
97 def get_unix_path(self, windowspath):
98 pid, stdin, stdout, stderr = gobject.spawn_async(
99 ('winepath', '--unix', windowspath),
100 flags=gobject.SPAWN_SEARCH_PATH,
101 standard_output=True)
103 result = []
104 s = os.read(stdout, 4096)
105 while s:
106 result.append(s)
107 s = os.read(stdout, 4096)
109 result = ''.join(result).rstrip('\n')
111 return result
113 def setup_prefix(self, firstrun):
114 os.system('wineboot --init')
116 if firstrun:
117 #set up desktop background
118 winini = self.get_unix_path(r'c:\windows\win.ini')
120 f = open(winini, 'w')
121 f.write("\r\n\r\n[desktop]\r\nWallPaper=c:\\windows\\landscape.bmp")
122 f.close()
124 import shutil
125 landscapebmp = self.get_unix_path(r'c:\windows\landscape.bmp')
126 shutil.copyfile(os.path.join(self.bundle_path, 'background', 'landscape.bmp'), landscapebmp)
128 def on_wine_quit(self, pid, condition, data):
129 sys.exit()
131 def read_file(self, file_path):
132 #the file is read-only and will be deleted so make a copy
133 try:
134 fd, filename = tempfile.mkstemp(suffix=mime_to_extension(self.metadata['mime_type']))
135 except (AttributeError, KeyError):
136 logging.error("can't start file without a mime type")
137 os.chmod(filename, int('0770', 8))
138 shutil.copyfile(file_path, filename)
139 os.close(fd)
140 atexit.register(os.unlink, filename)
141 self.start_wine('start', '/unix', filename)