]>
cvs.zerfleddert.de Git - micropolis/blob - micropolisactivity.py
1 # -*- mode: python; tab-width: 4 -*-
3 # Micropolis, Unix Version. This game was released for the Unix platform
4 # in or about 1990 and has been modified for inclusion in the One Laptop
5 # Per Child program. Copyright (C) 1989 - 2007 Electronic Arts Inc. If
6 # you need assistance with this program, you may contact:
7 # http://wiki.laptop.org/go/Micropolis or email micropolis@laptop.org.
9 # This program is free software: you can redistribute it and/or modify
10 # it under the terms of the GNU General Public License as published by
11 # the Free Software Foundation, either version 3 of the License, or (at
12 # your option) any later version.
14 # This program is distributed in the hope that it will be useful, but
15 # WITHOUT ANY WARRANTY; without even the implied warranty of
16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 # General Public License for more details. You should have received a
18 # copy of the GNU General Public License along with this program. If
19 # not, see <http://www.gnu.org/licenses/>.
21 # ADDITIONAL TERMS per GNU GPL Section 7
23 # No trademark or publicity rights are granted. This license does NOT
24 # give you any right, title or interest in the trademark SimCity or any
25 # other Electronic Arts trademark. You may not distribute any
26 # modification of this program using the trademark SimCity or claim any
27 # affliation or association with Electronic Arts Inc. or its employees.
29 # Any propagation or conveyance of this program must include this
30 # copyright notice and these terms.
32 # If you convey this program (or any modifications of it) and assume
33 # contractual liability for the program to recipients of it, you agree
34 # to indemnify Electronic Arts for any liability that those contractual
35 # assumptions impose on Electronic Arts.
37 # You may not misrepresent the origins of this program; modified
38 # versions of the program must be marked as such and not identified as
39 # the original program.
41 # This disclaimer supplements the one included in the General Public
42 # License. TO THE FULLEST EXTENT PERMISSIBLE UNDER APPLICABLE LAW, THIS
43 # PROGRAM IS PROVIDED TO YOU "AS IS," WITH ALL FAULTS, WITHOUT WARRANTY
44 # OF ANY KIND, AND YOUR USE IS AT YOUR SOLE RISK. THE ENTIRE RISK OF
45 # SATISFACTORY QUALITY AND PERFORMANCE RESIDES WITH YOU. ELECTRONIC ARTS
46 # DISCLAIMS ANY AND ALL EXPRESS, IMPLIED OR STATUTORY WARRANTIES,
47 # INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY, SATISFACTORY QUALITY,
48 # FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT OF THIRD PARTY
49 # RIGHTS, AND WARRANTIES (IF ANY) ARISING FROM A COURSE OF DEALING,
50 # USAGE, OR TRADE PRACTICE. ELECTRONIC ARTS DOES NOT WARRANT AGAINST
51 # INTERFERENCE WITH YOUR ENJOYMENT OF THE PROGRAM; THAT THE PROGRAM WILL
52 # MEET YOUR REQUIREMENTS; THAT OPERATION OF THE PROGRAM WILL BE
53 # UNINTERRUPTED OR ERROR-FREE, OR THAT THE PROGRAM WILL BE COMPATIBLE
54 # WITH THIRD PARTY SOFTWARE OR THAT ANY ERRORS IN THE PROGRAM WILL BE
55 # CORRECTED. NO ORAL OR WRITTEN ADVICE PROVIDED BY ELECTRONIC ARTS OR
56 # ANY AUTHORIZED REPRESENTATIVE SHALL CREATE A WARRANTY. SOME
57 # JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF OR LIMITATIONS ON IMPLIED
58 # WARRANTIES OR THE LIMITATIONS ON THE APPLICABLE STATUTORY RIGHTS OF A
59 # CONSUMER, SO SOME OR ALL OF THE ABOVE EXCLUSIONS AND LIMITATIONS MAY
73 from sugar
.activity
import activity
74 from sugar
.activity
.activity
import get_bundle_path
75 from sugar
import profile
76 from gettext
import gettext
as _
85 from sugar
.presence
import presenceservice
87 from sugar
.presence
import PresenceService
as presenceservice
91 return s
.replace('"', '\\"')
94 class MicropolisActivity(activity
.Activity
):
96 def __init__(self
, handle
):
98 activity
.Activity
.__init
__(self
, handle
)
100 self
.set_title(_('Micropolis Activity'))
101 self
.connect('destroy', self
._destroy
_cb
)
102 self
.connect('focus-in-event', self
._focus
_in
_cb
)
103 self
.connect('focus-out-event', self
._focus
_out
_cb
)
105 signal
.signal(signal
.SIGCHLD
, self
._sigchild
_handler
)
107 self
._bundle
_path
= get_bundle_path()
110 # FIXME: Plug Micropolis's window into a gtk socket.
111 # Doesn't work yet, but it would be cool if it did.
112 socket
= gtk
.Socket()
114 self
.set_canvas(socket
)
115 except AttributeError:
118 socket
.connect('plug-added', self
._plug
_added
_cb
)
119 socket
.connect('plug-removed', self
._plug
_removed
_cb
)
121 win
= socket
.get_id()
123 command
= os
.path
.join(
129 #'-R', str(win), # Set root window to socket window id
130 '-t', # Interactive tty mode, so we can send it commands.
133 logging
.debug("CWD: " + self
._bundle
_path
)
134 logging
.debug("Micropolis ARGS: " + repr(args
))
136 self
._process
= subprocess
.Popen(
138 stdin
=subprocess
.PIPE
,
139 stdout
=subprocess
.PIPE
,
141 cwd
=self
._bundle
_path
,
142 preexec_fn
=lambda: os
.chdir(self
._bundle
_path
))
144 logging
.debug("STARTING THREAD... " + str(self
._stdout
_thread
_function
))
147 t
= thread
.start_new(
148 self
._stdout
_thread
_function
,
151 logging
.debug("EXCEPTION " + str(e
))
152 self
._stdout
_thread
= t
153 logging
.debug("STARTED THREAD. " + str(t
))
155 uri
= handle
.uri
or ''
156 logging
.debug("Micropolis SUGARSTARTUP URI " + repr(uri
))
158 'SugarStartUp "' + QuoteTCL(uri
) + '"\n')
160 nick
= profile
.get_nick_name() or ''
161 logging
.debug("Micropolis SUGARNICKNAME NICK " + repr(nick
))
163 'SugarNickName "' + QuoteTCL(nick
) + '"\n')
165 #logging.debug("started Micropolis, pid " + repr(self._pid))
167 ps
= presenceservice
.get_instance()
169 for buddy
in ps
.get_buddies():
170 self
._buddy
_appeared
_cb
(ps
, buddy
)
172 ps
.connect("buddy-appeared", self
._buddy
_appeared
_cb
)
173 ps
.connect("buddy-disappeared", self
._buddy
_disappeared
_cb
)
176 def _stdout_thread_function(self
, *args
, **keys
):
177 logging
.debug("_stdout_thread_function BEGIN " + repr(args
) + " " + repr(keys
))
178 f
= self
._process
.stdout
179 fcntl
.fcntl(f
.fileno(), fcntl
.F_SETFD
, 0)
185 logging
.debug("READLINE EXCEPTION " + str(e
))
187 logging
.debug("LINE: " + repr(line
))
191 words
= line
.strip().split(' ')
193 if command
== 'PlaySound':
194 logging
.debug("PLAYSOUND " + " ".join(words
[1:]))
195 self
.play_sound(words
[1])
197 pass # logging.debug(">>> " + line)
198 logging
.debug("_stdout_thread_function END")
201 def play_sound(self
, name
):
202 fileName
= os
.path
.join(
205 name
.lower() + '.wav')
206 print "PLAY_SOUND " + fileName
208 sound
= pygame
.mixer
.Sound(fileName
)
211 print "Can't play sound: " + fileName
+ " " + str(e
)
215 def send_process(self
, message
):
216 logging
.debug("SEND_PROCESS " + message
)
217 self
._process
.stdin
.write(message
)
221 logging
.debug("SHARE")
227 def quit_process(self
):
228 logging
.debug("QUIT_PROCESS")
234 def _plug_added_cb(self
, sock
):
235 logging
.debug("Micropolis window opened")
239 def _plug_removed_cb(self
, sock
):
240 logging
.debug("Micropolis window closed")
245 def _destroy_cb(self
, window
):
246 logging
.debug("Micropolis activity destroyed %r" % window
)
250 def _focus_in_cb(self
, window
, event
):
251 logging
.debug("Micropolis activated %r %r" % (window
, event
))
256 def _focus_out_cb(self
, window
, event
):
257 logging
.debug("Micropolis deactivated %r %r" % (window
, event
))
262 def _buddy_appeared_cb(self
, ps
, buddy
):
265 key
= buddy
.props
.key
or ''
266 nick
= buddy
.props
.nick
or ''
267 color
= buddy
.props
.color
or ''
268 address
= buddy
.props
.ip4_address
or ''
269 except AttributeError:
270 key
= buddy
.get_name() or ''
271 nick
= buddy
.get_name() or ''
272 color
= buddy
.get_color() or ''
273 address
= buddy
.get_ip4_address() or ''
275 logging
.debug("Micropolis _BUDDY_APPEARED_CB KEY " + repr(key
) + " NICK " + repr(nick
) + " COLOR " + repr(color
) + " ADDRESS " + repr(address
))
277 logging
.debug("Buddy appeared " + repr(buddy
.props
.nick
))
281 QuoteTCL(key
) + '" "' +
282 QuoteTCL(nick
) + '" "' +
283 QuoteTCL(color
) + '" "' +
284 QuoteTCL(address
) + '"\n')
286 def _buddy_disappeared_cb(self
, ps
, buddy
):
289 key
= buddy
.props
.key
or ''
290 nick
= buddy
.props
.nick
or ''
291 color
= buddy
.props
.color
or ''
292 address
= buddy
.props
.ip4_address
or ''
293 except AttributeError:
294 key
= buddy
.get_name() or ''
295 nick
= buddy
.get_name() or ''
296 color
= buddy
.get_color() or ''
297 address
= buddy
.get_ip4_address() or ''
299 logging
.debug("Micropolis _BUDDY_DISAPPEARED_CB KEY " + repr(key
) + " NICK " + repr(nick
) + " COLOR " + repr(color
) + " ADDRESS " + repr(address
))
301 logging
.debug("Buddy disappeared " + repr(buddy
.props
.nick
))
305 QuoteTCL(key
) + '" "' +
306 QuoteTCL(nick
) + '" "' +
307 QuoteTCL(color
) + '" "' +
308 QuoteTCL(address
) + '"\n')
310 def _sigchild_handler(self
, signum
, frame
):
311 logging
.debug("got signal %i %r %r" % (signum
, frame
, self
._process
))