summaryrefslogtreecommitdiffstats
path: root/Demo/sgi/gl/glstdwin/glstdwin.py
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>1992-03-30 13:18:37 (GMT)
committerGuido van Rossum <guido@python.org>1992-03-30 13:18:37 (GMT)
commit453bd408bdd9287bb020e6ec5411983c8d176c89 (patch)
treec92cf78d2e602855b408990ed510819657cab3fa /Demo/sgi/gl/glstdwin/glstdwin.py
parent6da6aebfdb680a5340deae59088f9e68525723b5 (diff)
downloadcpython-453bd408bdd9287bb020e6ec5411983c8d176c89.zip
cpython-453bd408bdd9287bb020e6ec5411983c8d176c89.tar.gz
cpython-453bd408bdd9287bb020e6ec5411983c8d176c89.tar.bz2
Initial revision
Diffstat (limited to 'Demo/sgi/gl/glstdwin/glstdwin.py')
-rw-r--r--Demo/sgi/gl/glstdwin/glstdwin.py400
1 files changed, 400 insertions, 0 deletions
diff --git a/Demo/sgi/gl/glstdwin/glstdwin.py b/Demo/sgi/gl/glstdwin/glstdwin.py
new file mode 100644
index 0000000..2228554
--- /dev/null
+++ b/Demo/sgi/gl/glstdwin/glstdwin.py
@@ -0,0 +1,400 @@
+# GL STDWIN
+#
+# See stdwingl for a convenient hack to use this instead of built-in stdwin
+# without modifying your application, except for one line in the main file.
+#
+# Intrinsic differences with built-in stdwin (hard or impossible to fix):
+# - Need to call w.close() to close a window !!!
+# - Need to call m.close() to remove a menu !!!
+# - Doesn't enforce the existence of at most one drawing object
+# - No textedit package
+# - No X11 selections
+#
+# Not yet implemented:
+# - shade drawing
+# - elliptical arc drawing (need to play with transformation)
+# - more than one mouse button
+# - scroll bars (need to redo viewport handling to get this)
+# - partial redraws
+# - dialog boxes
+# - timer events
+# - cursors
+#
+# Extra features:
+# - color (for now, you need to know the colormap index)
+
+
+import gl
+import fm
+from GL import *
+from DEVICE import *
+from stdwinevents import *
+
+
+# Customizable constants
+#
+DEF_FONT = 'Times-Roman' # Default font
+DEF_SIZE = 12 # Default font size (points)
+MASK = 20 # Viewport minus scrmask
+
+
+# A structure to hold global variables
+#
+class Struct: pass
+G = Struct()
+#
+G.queue = [] # Pending STDWIN events
+G.drawqueue = [] # Windows that need WE_REDRAW
+G.windowmap = {} # Map window id to window object
+G.windowmap['0'] = None # For convenience
+G.focus = None # Input focus
+G.fg = BLACK # Foreground color
+G.bg = WHITE # Background color
+G.def_size = 0, 0 # Default window size
+G.def_pos = 0, 0 # Default window position
+#
+G.size = DEF_SIZE
+G.font = fm.findfont(DEF_FONT).scalefont(G.size)
+
+
+# Initialize GL
+#
+gl.foreground()
+gl.noport()
+dummygid = gl.winopen('')
+
+# Ask for all sorts of events
+#
+# Both REDRAW (= resize and/or redraw!) and INPUTCHANGE are implicitly queued
+#qdevice(REDRAW)
+#qdevice(INPUTCHANGE)
+#
+# Keyboard
+gl.qdevice(KEYBD)
+gl.qdevice(LEFTARROWKEY)
+gl.qdevice(RIGHTARROWKEY)
+gl.qdevice(UPARROWKEY)
+gl.qdevice(DOWNARROWKEY)
+gl.qdevice(LEFTALTKEY)
+gl.qdevice(RIGHTALTKEY)
+#
+# Mouse
+gl.qdevice(LEFTMOUSE)
+#gl.qdevice(MIDDLEMOUSE)
+gl.qdevice(RIGHTMOUSE) # Menu button
+# NB MOUSEX, MOUSEY events are queued on button down
+#
+# Window close requests
+gl.qdevice(WINQUIT)
+gl.qdevice(WINSHUT)
+#
+# These aren't needed
+#gl.qdevice(TIMER0)
+#gl.qdevice(WINFREEZE)
+#gl.qdevice(WINTHAW)
+#gl.qdevice(REDRAWICONIC)
+
+
+# STDWIN: create a new window
+#
+def open(title):
+ h, v = G.def_pos
+ width, height = G.def_size
+ if h > 0 or v > 0:
+ # Choose arbitrary defaults
+ if h < 0: h = 10
+ if v < 0: v = 30
+ if width <= 0: width = 400
+ if height <= 0: height = 300
+ gl.prefposition(h, h+width, 1024-v, 1024-v-height)
+ elif width > 0 or height > 0:
+ if width <= 0: width = 400
+ if height <= 0: height = 300
+ gl.prefsize(width, height)
+ from glstdwwin import WindowObject
+ win = WindowObject()._init(title)
+ G.windowmap[`win._gid`] = win
+ return win
+
+
+# STDWIN: set default initial window position (0 means use default)
+#
+def setdefwinpos(h, v):
+ G.def_pos = h, v
+
+
+# STDWIN: set default window size (0 means use default)
+#
+def setdefwinsize(width, height):
+ G.def_size = width, height
+
+
+# STDWIN: beep or ring the bell
+#
+def fleep():
+ gl.ringbell()
+
+
+# STDWIN: set default foreground color
+#
+def setfgcolor(color):
+ G.fg = color
+
+
+# STDWIN: set default background color
+#
+def setbgcolor(color):
+ G.bg = color
+
+
+# STDWIN: get default foreground color
+#
+def getfgcolor():
+ return G.fgcolor
+
+
+# STDWIN: get default background color
+#
+def getbgcolor():
+ return G.bgcolor
+
+
+# Table mapping characters to key codes
+#
+key2code = key = {}
+key['A'] = AKEY
+key['B'] = BKEY
+key['C'] = CKEY
+key['D'] = DKEY
+key['E'] = EKEY
+key['F'] = FKEY
+key['G'] = GKEY
+key['H'] = HKEY
+key['I'] = IKEY
+key['J'] = JKEY
+key['K'] = KKEY
+key['L'] = LKEY
+key['M'] = MKEY
+key['N'] = NKEY
+key['O'] = OKEY
+key['P'] = PKEY
+key['Q'] = QKEY
+key['R'] = RKEY
+key['S'] = SKEY
+key['T'] = TKEY
+key['U'] = UKEY
+key['V'] = VKEY
+key['W'] = WKEY
+key['X'] = XKEY
+key['Y'] = YKEY
+key['Z'] = ZKEY
+key['0'] = ZEROKEY
+key['1'] = ONEKEY
+key['2'] = TWOKEY
+key['3'] = THREEKEY
+key['4'] = FOURKEY
+key['5'] = FIVEKEY
+key['6'] = SIXKEY
+key['7'] = SEVENKEY
+key['8'] = EIGHTKEY
+key['9'] = NINEKEY
+del key
+#
+code2key = {}
+codelist = []
+for key in key2code.keys():
+ code = key2code[key]
+ code2key[`code`] = key
+ codelist.append(code)
+del key
+
+
+# STDWIN: wait for the next event
+#
+commands = {}
+commands['\r'] = WC_RETURN
+commands['\b'] = WC_BACKSPACE
+commands['\t'] = WC_TAB
+#
+def getevent():
+ while 1:
+ #
+ # Get next event from the processed queue, if any
+ #
+ if G.queue:
+ event = G.queue[0]
+ del G.queue[0]
+ #print 'getevent from queue -->', event
+ return event
+ #
+ # Get next event from the draw queue, if any,
+ # but only if there is nothing in the system queue.
+ #
+ if G.drawqueue and not gl.qtest():
+ win = G.drawqueue[0]
+ del G.drawqueue[0]
+ gl.winset(win._gid)
+ gl.color(win._bg)
+ gl.clear()
+ event = WE_DRAW, win, win._area
+ #print 'getevent from drawqueue -->', event
+ return event
+ #
+ # Get next event from system queue, blocking if necessary
+ # until one is available.
+ # Some cases immediately return the event, others do nothing
+ # or append one or more events to the processed queue.
+ #
+ dev, val = gl.qread()
+ #
+ if dev == REDRAW:
+ win = G.windowmap[`val`]
+ old_area = win._area
+ win._fixviewport()
+ win._needredraw()
+ if old_area <> win._area:
+ #print 'getevent --> WE_SIZE'
+ return WE_SIZE, win, None
+ elif dev == KEYBD:
+ if val == 3:
+ raise KeyboardInterrupt # Control-C in window
+ character = chr(val)
+ if commands.has_key(character):
+ return WE_COMMAND, G.focus, commands[character]
+ return WE_CHAR, G.focus, character
+ elif dev == LEFTARROWKEY:
+ if val:
+ return WE_COMMAND, G.focus, WC_LEFT
+ elif dev == RIGHTARROWKEY:
+ if val:
+ return WE_COMMAND, G.focus, WC_RIGHT
+ elif dev == UPARROWKEY:
+ if val:
+ return WE_COMMAND, G.focus, WC_UP
+ elif dev == DOWNARROWKEY:
+ if val:
+ return WE_COMMAND, G.focus, WC_DOWN
+ elif dev in (LEFTALTKEY, RIGHTALTKEY):
+ if val:
+ for code in codelist:
+ gl.qdevice(code)
+ else:
+ for code in codelist:
+ gl.unqdevice(code)
+ elif dev in codelist:
+ if val:
+ event = G.focus._doshortcut(code2key[`dev`])
+ if event:
+ return event
+ elif dev == LEFTMOUSE:
+ G.mousex = gl.getvaluator(MOUSEX)
+ G.mousey = gl.getvaluator(MOUSEY)
+ if val:
+ type = WE_MOUSE_DOWN
+ gl.qdevice(MOUSEX)
+ gl.qdevice(MOUSEY)
+ else:
+ type = WE_MOUSE_UP
+ gl.unqdevice(MOUSEX)
+ gl.unqdevice(MOUSEY)
+ return _mouseevent(type)
+ elif dev == MOUSEX:
+ G.mousex = val
+ return _mouseevent(WE_MOUSE_MOVE)
+ elif dev == MOUSEY:
+ G.mousey = val
+ return _mouseevent(WE_MOUSE_MOVE)
+ elif dev == RIGHTMOUSE: # Menu button press/release
+ if val: # Press
+ event = G.focus._domenu()
+ if event:
+ return event
+ elif dev == INPUTCHANGE:
+ if G.focus:
+ G.queue.append(WE_DEACTIVATE, G.focus, None)
+ G.focus = G.windowmap[`val`]
+ if G.focus:
+ G.queue.append(WE_ACTIVATE, G.focus, None)
+ elif dev in (WINSHUT, WINQUIT):
+ return WE_CLOSE, G.windowmap[`val`], None
+ else:
+ print '*** qread() --> dev:', dev, 'val:', val
+
+# Helper routine to construct a mouse (up, move or down) event
+#
+def _mouseevent(type):
+ gl.winset(G.focus._gid)
+ orgx, orgy = gl.getorigin()
+ sizex, sizey = gl.getsize()
+ x = G.mousex - orgx
+ y = G.mousey - orgy
+ return type, G.focus, ((x, sizey-y), 1, 0, 0)
+
+
+
+
+# STDWIN: text measuring functions
+
+def baseline():
+ (printermatched, fixed_width, xorig, yorig, xsize, ysize, \
+ height, nglyphs) = G.font.getfontinfo()
+ return height - yorig
+
+def lineheight():
+ (printermatched, fixed_width, xorig, yorig, xsize, ysize, \
+ height, nglyphs) = G.font.getfontinfo()
+ return height
+
+def textbreak(string, width):
+ # XXX Slooooow!
+ n = len(string)
+ nwidth = textwidth(string[:n])
+ while nwidth > width:
+ n = n-1
+ nwidth = textwidth(string[:n])
+ return n
+
+def textwidth(string):
+ return G.font.getstrwidth(string)
+
+
+# STDWIN: set default font and size
+
+def setfont(fontname):
+ G.font = fm.findfont(fontname).scalefont(G.size)
+
+def setsize(size):
+ ratio = float(size) / float(G.size)
+ G.size = size
+ G.font = G.font.scalefont(ratio)
+
+
+# Utility functions
+
+# Exclusive-or of two BYTES
+#
+def xor(x, y):
+ a = bits(x)
+ b = bits(y)
+ c = [0, 0, 0, 0, 0, 0, 0, 0]
+ for i in range(8):
+ c[i] = (a[i] + b[i]) % 2
+ return stib(c)
+
+# Return the bits of a byte as a list of 8 integers
+#
+def bits(x):
+ b = [0, 0, 0, 0, 0, 0, 0, 0]
+ for i in range(8):
+ x, b[i] = divmod(x, 2)
+ return b
+
+# Convert a list of 8 integers (0|1) to a byte
+#
+def stib(b):
+ x = 0
+ shift = 1
+ for i in range(8):
+ x = x + b[i]*shift
+ shift = shift*2
+ return x