1 from sugar
.activity
import activity
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':
20 class WineActivity(activity
.Activity
):
21 def __init__(self
, handle
):
22 activity
.Activity
.__init
__(self
, handle
)
24 self
.bundle_path
= activity
.get_bundle_path()
27 activity_root
= activity
.get_activity_root()
28 wine_prefix
= os
.path
.join(activity_root
, 'data', 'wine')
29 except AttributeError:
31 activity_root
= os
.environ
['SUGAR_ACTIVITY_ROOT']
32 wine_prefix
= os
.path
.join(activity_root
, 'data', 'wine')
35 wine_prefix
= os
.path
.expanduser('~/.wine')
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():
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
)
68 self
.set_title("Wine")
70 def on_parent_map(self
, widget
):
71 os
.environ
['WINE_DESKTOP_PARENT'] = str(self
.desktop_parent
.window
.xid
)
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
):
90 logging
.info("running command line: %s" % ' '.join(str(x
) for x
in args
))
92 ['wine', 'explorer', '/desktop=%s' % self
.desktop_name
] + [str(x
) for x
in args
],
93 flags
=gobject
.SPAWN_SEARCH_PATH
)
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)
104 s
= os
.read(stdout
, 4096)
107 s
= os
.read(stdout
, 4096)
109 result
= ''.join(result
).rstrip('\n')
113 def setup_prefix(self
, firstrun
):
114 os
.system('wineboot --init')
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")
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
):
131 def read_file(self
, file_path
):
132 #the file is read-only and will be deleted so make a copy
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
)
140 atexit
.register(os
.unlink
, filename
)
141 self
.start_wine('start', '/unix', filename
)