mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 10:26:02 +00:00 
			
		
		
		
	 7bc817d5ba
			
		
	
	
		7bc817d5ba
		
	
	
	
	
		
			
			constructors.  There is no backward compatibility.  Not everything has
  been tested.
* aiff.{py,doc}: deleted in favor of aifc.py (which contains its docs as
  comments)
		
	
			
		
			
				
	
	
		
			256 lines
		
	
	
	
		
			6.1 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			256 lines
		
	
	
	
		
			6.1 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| # Standard main loop for *all* STDWIN applications.
 | |
| # This requires that applications:
 | |
| # - register their windows on creation and unregister them when closed
 | |
| # - have a 'dispatch' function as a window member
 | |
| 
 | |
| 
 | |
| import stdwin, stdwinq
 | |
| from stdwinevents import *
 | |
| 
 | |
| 
 | |
| # List of windows known to the main loop.
 | |
| #
 | |
| windows = []
 | |
| 
 | |
| 
 | |
| # Last window that ever received an event
 | |
| #
 | |
| last_window = None
 | |
| 
 | |
| 
 | |
| # Function to register a window.
 | |
| #
 | |
| def register(win):
 | |
| 	# First test the dispatch function by passing it a null event --
 | |
| 	# this catches registration of unconforming windows.
 | |
| 	win.dispatch((WE_NULL, win, None))
 | |
| 	if win not in windows:
 | |
| 		windows.append(win)
 | |
| 
 | |
| 
 | |
| # Function to unregister a window.
 | |
| # It is not an error to unregister an already unregistered window
 | |
| # (this is useful for cleanup actions).
 | |
| #
 | |
| def unregister(win):
 | |
| 	global last_window
 | |
| 	if win == last_window:
 | |
| 		last_window = None
 | |
| 	if win in windows:
 | |
| 		windows.remove(win) # Not in 0.9.1
 | |
| 		# 0.9.1 solution:
 | |
| 		#for i in range(len(windows)):
 | |
| 		#	if windows[i] = win:
 | |
| 		#		del windows[i]
 | |
| 		#		break
 | |
| 
 | |
| 
 | |
| # Interfaces used by WindowSched.
 | |
| #
 | |
| def countwindows():
 | |
| 	return len(windows)
 | |
| #
 | |
| def anywindow():
 | |
| 	if windows:
 | |
| 		return windows[0]
 | |
| 	else:
 | |
| 		return None
 | |
| 
 | |
| 
 | |
| # NEW: register any number of file descriptors
 | |
| #
 | |
| fdlist = []
 | |
| select_args = None
 | |
| select_handlers = None
 | |
| #
 | |
| def registerfd(fd, mode, handler):
 | |
| 	if mode not in ('r', 'w', 'x'):
 | |
| 		raise ValueError, 'mode must be r, w or x'
 | |
| 	if type(fd) <> type(0):
 | |
| 		fd = fd.fileno() # If this fails it's not a proper select arg
 | |
| 	for i in range(len(fdlist)):
 | |
| 		if fdlist[i][:2] == (fd, mode):
 | |
| 			raise ValueError, \
 | |
| 				'(fd, mode) combination already registered'
 | |
| 	fdlist.append((fd, mode, handler))
 | |
| 	make_select_args()
 | |
| #
 | |
| def unregisterfd(fd, *args):
 | |
| 	if type(fd) <> type(0):
 | |
| 		fd = fd.fileno() # If this fails it's not a proper select arg
 | |
| 	args = (fd,) + args
 | |
| 	n = len(args)
 | |
| 	for i in range(len(fdlist)):
 | |
| 		if fdlist[i][:n] == args:
 | |
| 			del fdlist[i]
 | |
| 	make_select_args()
 | |
| #
 | |
| def make_select_args():
 | |
| 	global select_args, select_handlers
 | |
| 	rlist, wlist, xlist = [], [], []
 | |
| 	rhandlers, whandlers, xhandlers = {}, {}, {}
 | |
| 	for fd, mode, handler in fdlist:
 | |
| 		if mode == 'r':
 | |
| 			rlist.append(fd)
 | |
| 			rhandlers[`fd`] = handler
 | |
| 		if mode == 'w':
 | |
| 			wlist.append(fd)
 | |
| 			whandlers[`fd`] = handler
 | |
| 		if mode == 'x':
 | |
| 			xlist.append(fd)
 | |
| 			xhandlers[`fd`] = handler
 | |
| 	if rlist or wlist or xlist:
 | |
| 		select_args = rlist, wlist, xlist
 | |
| 		select_handlers = rhandlers, whandlers, xhandlers
 | |
| 	else:
 | |
| 		select_args = None
 | |
| 		select_handlers = None
 | |
| #
 | |
| def do_select():
 | |
| 	import select
 | |
| 	reply = apply(select.select, select_args)
 | |
| 	for mode in 0, 1, 2:
 | |
| 		list = reply[mode]
 | |
| 		for fd in list:
 | |
| 			handler = select_handlers[mode][`fd`]
 | |
| 			handler(fd, 'rwx'[mode])
 | |
| 
 | |
| 
 | |
| # Event processing main loop.
 | |
| # Return when there are no windows left, or when an unhandled
 | |
| # exception occurs.  (It is safe to restart the main loop after
 | |
| # an unsuccessful exit.)
 | |
| # Python's stdwin.getevent() turns WE_COMMAND/WC_CANCEL events
 | |
| # into KeyboardInterrupt exceptions; these are turned back in events.
 | |
| #
 | |
| recursion_level = 0 # Hack to make it reentrant
 | |
| def mainloop():
 | |
| 	global recursion_level
 | |
| 	recursion_level = recursion_level + 1
 | |
| 	try:
 | |
| 		stdwin_select_handler() # Process events already in queue
 | |
| 		while 1:
 | |
| 			if windows and not fdlist:
 | |
| 				while windows and not fdlist:
 | |
| 					try:
 | |
| 						event = stdwinq.getevent()
 | |
| 					except KeyboardInterrupt:
 | |
| 						event = (WE_COMMAND, \
 | |
| 							 None, WC_CANCEL)
 | |
| 					dispatch(event)
 | |
| 			elif windows and fdlist:
 | |
| 				fd = stdwin.fileno()
 | |
| 				if recursion_level == 1:
 | |
| 				    registerfd(fd, 'r', stdwin_select_handler)
 | |
| 				try:
 | |
| 					while windows:
 | |
| 						do_select()
 | |
| 						stdwin_select_handler()
 | |
| 				finally:
 | |
| 					if recursion_level == 1:
 | |
| 						unregisterfd(fd)
 | |
| 			elif fdlist:
 | |
| 				while fdlist and not windows:
 | |
| 					do_select()
 | |
| 			else:
 | |
| 				break
 | |
| 	finally:
 | |
| 		recursion_level = recursion_level - 1
 | |
| 
 | |
| 
 | |
| # Check for events without ever blocking
 | |
| #
 | |
| def check():
 | |
| 	stdwin_select_handler()
 | |
| 	# XXX Should check for socket stuff as well
 | |
| 
 | |
| 
 | |
| # Handle stdwin events until none are left
 | |
| #
 | |
| def stdwin_select_handler(*args):
 | |
| 	while 1:
 | |
| 		try:
 | |
| 			event = stdwinq.pollevent()
 | |
| 		except KeyboardInterrupt:
 | |
| 			event = (WE_COMMAND, None, WC_CANCEL)
 | |
| 		if event is None:
 | |
| 			break
 | |
| 		dispatch(event)
 | |
| 
 | |
| 
 | |
| # Run a modal dialog loop for a window.  The dialog window must have
 | |
| # been registered first.  This prohibits most events (except size/draw
 | |
| # events) to other windows.  The modal dialog loop ends when the
 | |
| # dialog window unregisters itself.
 | |
| #
 | |
| passthrough = WE_SIZE, WE_DRAW
 | |
| beeping = WE_MOUSE_DOWN, WE_COMMAND, WE_CHAR, WE_KEY, WE_CLOSE, WE_MENU
 | |
| #
 | |
| def modaldialog(window):
 | |
| 	if window not in windows:
 | |
| 		raise ValueError, 'modaldialog window not registered'
 | |
| 	while window in windows:
 | |
| 		try:
 | |
| 			event = stdwinq.getevent()
 | |
| 		except KeyboardInterrupt:
 | |
| 			event = WE_COMMAND, None, WC_CANCEL
 | |
| 		etype, ewindow, edetail = event
 | |
| 		if etype not in passthrough and ewindow <> window:
 | |
| 			if etype in beeping:
 | |
| 				stdwin.fleep()
 | |
| 			continue
 | |
| 		dispatch(event)
 | |
| 
 | |
| 
 | |
| # Dispatch a single event.
 | |
| # Events for the no window in particular are sent to the active window
 | |
| # or to the last window that received an event (these hacks are for the
 | |
| # WE_LOST_SEL event, which is directed to no particular window).
 | |
| # Windows not in the windows list don't get their events:
 | |
| # events for such windows are silently ignored.
 | |
| #
 | |
| def dispatch(event):
 | |
| 	global last_window
 | |
| 	if event[1] == None:
 | |
| 		active = stdwin.getactive()
 | |
| 		if active: last_window = active
 | |
| 	else:
 | |
| 		last_window = event[1]
 | |
| 	if last_window in windows:
 | |
| 		last_window.dispatch(event)
 | |
| 
 | |
| 
 | |
| # Dialog base class
 | |
| #
 | |
| class Dialog:
 | |
| 	#
 | |
| 	def __init__(self, title):
 | |
| 		self.window = stdwin.open(title)
 | |
| 		self.window.dispatch = self.dispatch
 | |
| 		register(self.window)
 | |
| 	#
 | |
| 	def close(self):
 | |
| 		unregister(self.window)
 | |
| 		del self.window.dispatch
 | |
| 		self.window.close()
 | |
| 	#
 | |
| 	def dispatch(self, event):
 | |
| 		etype, ewindow, edetail = event
 | |
| 		if etype == WE_CLOSE:
 | |
| 			self.close()
 | |
| 
 | |
| 
 | |
| # Standard modal dialogs
 | |
| # XXX implemented using stdwin dialogs for now
 | |
| #
 | |
| def askstr(prompt, default):
 | |
| 	return stdwin.askstr(prompt, default)
 | |
| #
 | |
| def askync(prompt, yesorno):
 | |
| 	return stdwin.askync(prompt, yesorno)
 | |
| #
 | |
| def askfile(prompt, default, new):
 | |
| 	return stdwin.askfile(prompt, default, new)
 | |
| #
 | |
| def message(msg):
 | |
| 	stdwin.message(msg)
 |