1 # Copyright (c) Twisted Matrix Laboratories.
2 # See LICENSE for details.
7 You can run this .tac file directly with:
10 Demonstrates various widgets or buttons, such as scrollable regions,
13 This demo sets up two listening ports: one on 6022 which accepts ssh
14 connections; one on 6023 which accepts telnet connections. No login for the
15 telnet server is required; for the ssh server, "username" is the username and
16 "password" is the password.
19 from __future__ import division
23 from twisted.python import log
24 from twisted.internet import protocol, task
25 from twisted.application import internet, service
26 from twisted.cred import checkers, portal
28 from twisted.conch.insults import insults, window
29 from twisted.conch.telnet import TelnetTransport, TelnetBootstrapProtocol
30 from twisted.conch.manhole_ssh import ConchFactory, TerminalRealm
32 from twisted.internet import reactor
34 class DrawableCanvas(window.Canvas):
38 def func_LEFT_ARROW(self, modifier):
42 def func_RIGHT_ARROW(self, modifier):
46 def func_UP_ARROW(self, modifier):
50 def func_DOWN_ARROW(self, modifier):
54 def characterReceived(self, keyID, modifier):
55 self[self.x, self.y] = keyID
59 def keystrokeReceived(self, keyID, modifier):
60 if keyID == '\r' or keyID == '\v':
62 window.Canvas.keystrokeReceived(self, keyID, modifier)
63 if self.x >= self.width:
66 self.x = self.width - 1
68 if self.y >= self.height:
71 self.y = self.height - 1
74 def render(self, width, height, terminal):
75 window.Canvas.render(self, width, height, terminal)
77 terminal.cursorPosition(self.x, self.y)
78 window.cursor(terminal, self[self.x, self.y])
81 class ButtonDemo(insults.TerminalProtocol):
86 self.window.draw(self.width, self.height, self.terminal)
92 def _schedule(self, f):
93 reactor.callLater(0, f)
95 def connectionMade(self):
96 self.terminal.eraseDisplay()
97 self.terminal.resetPrivateModes([insults.privateModes.CURSOR_MODE])
99 self.window = window.TopWindow(self._draw, self._schedule)
100 self.output = window.TextOutput((15, 1))
101 self.input = window.TextInput(15, self._setText)
102 self.select1 = window.Selection(map(str, range(100)), self._setText, 10)
103 self.select2 = window.Selection(map(str, range(200, 300)), self._setText, 10)
104 self.button = window.Button("Clear", self._clear)
105 self.canvas = DrawableCanvas()
108 hbox.addChild(self.input)
109 hbox.addChild(self.output)
110 hbox.addChild(window.Border(self.button))
111 hbox.addChild(window.Border(self.select1))
112 hbox.addChild(window.Border(self.select2))
114 t1 = window.TextOutputArea(longLines=window.TextOutputArea.WRAP)
115 t2 = window.TextOutputArea(longLines=window.TextOutputArea.TRUNCATE)
116 t3 = window.TextOutputArea(longLines=window.TextOutputArea.TRUNCATE)
117 t4 = window.TextOutputArea(longLines=window.TextOutputArea.TRUNCATE)
118 for _t in t1, t2, t3, t4:
119 _t.setText((('This is a very long string. ' * 3) + '\n') * 3)
121 vp = window.Viewport(t3)
125 if vp.xOffset == 0 or vp.xOffset == 25:
127 self.call = task.LoopingCall(spin)
128 self.call.start(0.25, now=False)
129 hbox.addChild(window.Border(vp))
131 vp2 = window.ScrolledArea(t4)
134 texts = window.VBox()
135 texts.addChild(window.Border(t1))
136 texts.addChild(window.Border(t2))
138 areas = window.HBox()
139 areas.addChild(window.Border(self.canvas))
140 areas.addChild(texts)
145 self.window.addChild(vbox)
146 self.terminalSize(self.width, self.height)
148 def connectionLost(self, reason):
150 insults.TerminalProtocol.connectionLost(self, reason)
152 def terminalSize(self, width, height):
155 self.terminal.eraseDisplay()
159 def keystrokeReceived(self, keyID, modifier):
160 self.window.keystrokeReceived(keyID, modifier)
165 def _setText(self, text):
166 self.input.setText('')
167 self.output.setText(text)
170 def makeService(args):
171 checker = checkers.InMemoryUsernamePasswordDatabaseDontUse(username="password")
173 f = protocol.ServerFactory()
174 f.protocol = lambda: TelnetTransport(TelnetBootstrapProtocol,
175 insults.ServerProtocol,
176 args['protocolFactory'],
177 *args.get('protocolArgs', ()),
178 **args.get('protocolKwArgs', {}))
179 tsvc = internet.TCPServer(args['telnet'], f)
181 def chainProtocolFactory():
182 return insults.ServerProtocol(
183 args['protocolFactory'],
184 *args.get('protocolArgs', ()),
185 **args.get('protocolKwArgs', {}))
187 rlm = TerminalRealm()
188 rlm.chainedProtocolFactory = chainProtocolFactory
189 ptl = portal.Portal(rlm, [checker])
190 f = ConchFactory(ptl)
191 csvc = internet.TCPServer(args['ssh'], f)
193 m = service.MultiService()
194 tsvc.setServiceParent(m)
195 csvc.setServiceParent(m)
198 application = service.Application("Window Demo")
200 makeService({'protocolFactory': ButtonDemo,
202 'ssh': 6022}).setServiceParent(application)