setup.ahk: update download link to firefox version 3.0.5
[sugaredwine.git] / wineactivity.py
blobad20bbb701a9d209ff31f76594461030a2a22c50
1 # Copyright (C) 2008, Vincent Povirk for CodeWeavers
3 # This library is free software; you can redistribute it and/or
4 # modify it under the terms of the GNU Lesser General Public
5 # License as published by the Free Software Foundation; either
6 # version 2 of the License, or (at your option) any later version.
8 # This library is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 # Lesser General Public License for more details.
13 # You should have received a copy of the GNU Lesser General Public
14 # License along with this library; if not, write to the
15 # Free Software Foundation, Inc., 59 Temple Place - Suite 330,
16 # Boston, MA 02111-1307, USA.
18 from sugar.activity import activity
19 import sys
20 import os
21 import gobject
22 import gtk
23 import shutil
24 import tempfile
25 import logging
26 import atexit
28 def mime_to_extension(mimetype):
29 # Sugar's metadata does not typically provide a file extension, and the
30 # filename tends to be unusable. Windows depends on extensions so we need
31 # a conversion function. This one is pretty lame but should work for now.
32 if mimetype == 'application/x-msi':
33 return '.msi'
34 else:
35 return '.exe'
37 class WineActivity(activity.Activity):
38 def __init__(self, handle):
39 activity.Activity.__init__(self, handle)
41 self.bundle_path = activity.get_bundle_path()
43 try:
44 activity_root = activity.get_activity_root()
45 wine_prefix = os.path.join(activity_root, 'data', 'wine')
46 except AttributeError:
47 try:
48 activity_root = os.environ['SUGAR_ACTIVITY_ROOT']
49 wine_prefix = os.path.join(activity_root, 'data', 'wine')
50 except KeyError:
51 activity_root = None
52 wine_prefix = os.path.expanduser('~/.wine')
54 self.settings = {}
55 f = open(os.path.join(self.bundle_path, 'activity', 'wine.info'), 'U')
56 for line in f.readlines():
57 if '=' in line:
58 key, value = line.rstrip('\n').split('=')
59 self.settings[key] = value
60 f.close()
62 try:
63 self.desktop_parent = gtk.EventBox()
64 self.desktop_parent.show()
65 self.set_canvas(self.desktop_parent)
66 except AttributeError:
67 # remove any children of the window that Sugar may have added
68 for widget in self.get_children():
69 self.remove(widget)
71 self.desktop_parent = self
73 os.environ['LD_LIBRARY_PATH'] = "%s:%s" % (os.path.join(self.bundle_path, 'lib'), os.environ.get('LD_LIBRARY_PATH', ''))
74 os.environ['PATH'] = "%s:%s" % (os.path.join(self.bundle_path, 'bin'), os.environ.get('PATH', ''))
75 os.environ['WINEPREFIX'] = wine_prefix
76 os.environ['WINELOADER'] = os.path.join(self.bundle_path, 'bin/wine')
77 os.environ['WINESERVER'] = os.path.join(self.bundle_path, 'bin/wineserver')
78 os.environ['WINEDLLPATH'] = os.path.join(self.bundle_path, 'lib/wine')
80 self.desktop_name = str(os.getpid())
81 os.environ['WINE_DESKTOP_NAME'] = self.desktop_name
83 firstrun = not os.path.exists(wine_prefix)
85 self.setup_prefix(firstrun)
87 self.desktop_parent.connect('map', self.on_parent_map)
89 self.wine_pid = None
91 self.to_run = []
92 self.tempfiles = []
94 self.set_title("Wine")
96 def on_parent_map(self, widget):
97 os.environ['WINE_DESKTOP_PARENT'] = str(self.desktop_parent.window.xid)
98 os.environ['SUGARED_WINE_TOPLEVEL'] = str(self.window.xid)
100 gtk.gdk.flush()
102 os.chdir(self.get_unix_path('c:\\'))
104 width = gtk.gdk.screen_width()
105 height = gtk.gdk.screen_height()
107 cmdline = ('wine', 'explorer', '/desktop=%s,%sx%s' % (self.desktop_name, width, height))
108 try:
109 args = self.settings['exec'].split(' ')
110 except KeyError:
111 pass
112 else:
113 cmdline += ('start', '/unix')
114 cmdline += (os.path.join(self.bundle_path, args[0]),)
115 cmdline += tuple(args[1:])
117 self.wine_pid, stdin, stdout, stderr = gobject.spawn_async(cmdline,
118 flags=gobject.SPAWN_SEARCH_PATH|gobject.SPAWN_DO_NOT_REAP_CHILD)
119 gobject.child_watch_add(self.wine_pid, self.on_wine_quit, None)
121 for cmdline in self.to_run:
122 self.start_wine(*cmdline)
124 def start_wine(self, *args):
125 if self.wine_pid:
126 logging.info("running command line: %s" % ' '.join(str(x) for x in args))
127 gobject.spawn_async(
128 ['wine', 'explorer', '/desktop=%s' % self.desktop_name] + [str(x) for x in args],
129 flags=gobject.SPAWN_SEARCH_PATH)
130 else:
131 self.to_run.append(args)
133 def run_cmd(self, *args):
134 pid, stdin, stdout, stderr = gobject.spawn_async(
135 args,
136 flags=gobject.SPAWN_SEARCH_PATH,
137 standard_output=True)
139 result = []
140 s = os.read(stdout, 4096)
141 while s:
142 result.append(s)
143 s = os.read(stdout, 4096)
145 result = ''.join(result)
147 return result
149 def get_unix_path(self, windowspath):
150 return self.run_cmd('winepath', '--unix', windowspath).rstrip('\n')
152 def setup_prefix(self, firstrun):
153 try:
154 self.run_cmd('wine', 'start', '/unix', os.path.join(self.bundle_path, self.settings['init']))
155 except KeyError:
156 self.run_cmd('wineboot', '--update')
158 if firstrun:
159 try:
160 background_file = os.path.join(self.bundle_path, self.settings['background'])
161 except KeyError:
162 pass
163 else:
164 #set up desktop background
165 winini = self.get_unix_path(r'c:\windows\win.ini')
167 f = open(winini, 'w')
168 f.write("\r\n\r\n[desktop]\r\nWallPaper=c:\\windows\\background.bmp")
169 f.close()
171 landscapebmp = self.get_unix_path(r'c:\windows\background.bmp')
172 os.symlink(background_file, landscapebmp)
174 def on_wine_quit(self, pid, condition, data):
175 sys.exit()
177 def read_file(self, file_path):
178 #the file is read-only and will be deleted so make a copy
179 try:
180 fd, filename = tempfile.mkstemp(suffix=mime_to_extension(self.metadata['mime_type']))
181 except (AttributeError, KeyError):
182 logging.error("can't start file without a mime type")
183 os.chmod(filename, int('0770', 8))
184 shutil.copyfile(file_path, filename)
185 os.close(fd)
186 atexit.register(os.unlink, filename)
187 self.start_wine('start', '/unix', filename)