TerminalView.st
changeset 2778 796ab4177728
parent 2678 f475a905c54c
child 2810 d57cc02787de
equal deleted inserted replaced
2777:56bb352f6b91 2778:796ab4177728
   230 
   230 
   231     "Modified: / 5.5.1999 / 17:25:59 / cg"
   231     "Modified: / 5.5.1999 / 17:25:59 / cg"
   232 !
   232 !
   233 
   233 
   234 openOnInput:inStream output:outStream in:aView
   234 openOnInput:inStream output:outStream in:aView
   235     "open a terminalView on the given streams (which are typically some
   235     "open a terminalView on the given streams 
   236      kind of socket or pty). 
   236      (which are typically some kind of socket or pty). 
   237      Keys pressed are sent to inStream, text appearing
   237      Keys pressed are sent to inStream, text appearing
   238      from outStream is displayed in the terminal view.
   238      from outStream is displayed in the terminal view.
   239      This can be used to implement things like rlogin
   239      This can be used to implement things like rlogin
   240      or telnet views (if connected to a modem, a com-program can also be
   240      or telnet views (if connected to a modem, a com-program can also be
   241      implemented this way)."
   241      implemented this way)."
   246     scr origin:0.0@0.0 corner:1.0@1.0.
   246     scr origin:0.0@0.0 corner:1.0@1.0.
   247     vt := scr scrolledView.
   247     vt := scr scrolledView.
   248 
   248 
   249     vt inStream:inStream.
   249     vt inStream:inStream.
   250     vt outStream:outStream.
   250     vt outStream:outStream.
   251     vt startReaderProcess.
   251     vt startReaderProcessWhenVisible.
   252 
   252 
   253     ^ scr
   253     ^ scr
   254 
   254 
   255     "Modified: / 5.5.1999 / 17:25:59 / cg"
   255     "Modified: / 5.5.1999 / 17:25:59 / cg"
   256 !
   256 !
  1104     ^ kbdMap
  1104     ^ kbdMap
  1105 
  1105 
  1106     "Modified: / 10.6.1998 / 17:46:59 / cg"
  1106     "Modified: / 10.6.1998 / 17:46:59 / cg"
  1107 !
  1107 !
  1108 
  1108 
       
  1109 readerProcessLoop
       
  1110     "look for the commands output,
       
  1111      and send me #processInput:n: events whenever something arrives."
       
  1112 
       
  1113     StreamError handle:[:ex |
       
  1114         Transcript show:'Terminal(PTY-reader) [error]: '; showCR:ex description.
       
  1115     ] do:[
       
  1116         [true] whileTrue:[
       
  1117             Object abortSignal handle:[:ex |
       
  1118                 self showCursor.
       
  1119             ] do:[
       
  1120                 |n sensor|
       
  1121 
       
  1122                 outStream readWait.
       
  1123                 sensor := self sensor.
       
  1124                 (sensor notNil and:[sensor hasKeyPressEventFor:self]) ifTrue:[
       
  1125                     true "(sensor userEventCount > 10)" ifTrue:[
       
  1126                         "/ give terminalView a chance to
       
  1127                         "/ send out the character.
       
  1128                         Delay waitForSeconds:0.01.
       
  1129                     ]
       
  1130                 ] ifFalse:[
       
  1131                     n := self readAnyAvailableData.
       
  1132                     n > 0 ifTrue:[
       
  1133                         shellPid notNil ifTrue:[
       
  1134                             self waitForOutputToDrain.
       
  1135                         ]
       
  1136                     ] ifFalse:[
       
  1137                         n == 0 ifTrue:[
       
  1138                             "/ Windows IPC has a bug - it always
       
  1139                             "/ returns 0 (when the command is idle)
       
  1140                             "/ and says its at the end (sigh)
       
  1141 
       
  1142                             OperatingSystem isMSWINDOWSlike ifTrue:[
       
  1143                                 Delay waitForSeconds:0.01
       
  1144                             ] ifFalse:[
       
  1145                                 outStream atEnd ifTrue:[
       
  1146                                     outStream close. outStream := nil.
       
  1147                                     inStream close.  inStream := nil.
       
  1148                                     Processor activeProcess terminate.
       
  1149                                 ] ifFalse:[
       
  1150                                     "/ this should not happen.
       
  1151 
       
  1152                                     Delay waitForSeconds:0.05
       
  1153                                 ]
       
  1154                             ].
       
  1155                         ]
       
  1156                     ]
       
  1157                 ]
       
  1158             ]
       
  1159         ]
       
  1160     ]
       
  1161 !
       
  1162 
  1109 reinitialize
  1163 reinitialize
  1110     "reinit after a snapIn.
  1164     "reinit after a snapIn.
  1111      this is invoked (by the system thread) after a snapShot image restart"
  1165      this is invoked (by the system thread) after a snapShot image restart"
  1112 
  1166 
  1113     super reinitialize.
  1167     super reinitialize.
  1150 
  1204 
  1151 startReaderProcess
  1205 startReaderProcess
  1152     "Start a reader process, which looks for the commands output,
  1206     "Start a reader process, which looks for the commands output,
  1153      and sends me #processInput:n: events whenever something arrives."
  1207      and sends me #processInput:n: events whenever something arrives."
  1154 
  1208 
       
  1209     self obsoleteMethodWarning.    
       
  1210     self startReaderProcessWhenVisible.
       
  1211 
       
  1212     "
       
  1213      VT100TerminalView openShell
       
  1214     "
       
  1215 
       
  1216     "Modified: / 5.5.1999 / 17:58:02 / cg"
       
  1217     "Modified: / 28.1.2002 / 21:10:13 / micha"
       
  1218 !
       
  1219 
       
  1220 startReaderProcessNow
       
  1221     "Start a reader process, which looks for the commands output,
       
  1222      and sends me #processInput:n: events whenever something arrives."
       
  1223 
  1155     readerProcess isNil ifTrue:[
  1224     readerProcess isNil ifTrue:[
  1156         readerProcess := [
  1225         readerProcess := [
  1157             [
  1226             [
  1158                 self waitUntilVisible.
  1227                 self readerProcessLoop.
  1159 
       
  1160                 StreamError handle:[:ex |
       
  1161                     Transcript show:'Terminal(PTY-reader) [error]: '; showCR:ex description.
       
  1162                 ] do:[
       
  1163                     [true] whileTrue:[
       
  1164                         Object abortSignal handle:[:ex |
       
  1165                             self showCursor.
       
  1166                         ] do:[
       
  1167                             |n sensor|
       
  1168 
       
  1169                             outStream readWait.
       
  1170                             sensor := self sensor.
       
  1171                             (sensor notNil and:[sensor hasKeyPressEventFor:self]) ifTrue:[
       
  1172                                 true "(sensor userEventCount > 10)" ifTrue:[
       
  1173                                     "/ give terminalView a chance to
       
  1174                                     "/ send out the character.
       
  1175                                     Delay waitForSeconds:0.01.
       
  1176                                 ]
       
  1177                             ] ifFalse:[
       
  1178                                 n := self readAnyAvailableData.
       
  1179                                 n > 0 ifTrue:[
       
  1180                                     shellPid notNil ifTrue:[
       
  1181                                         self waitForOutputToDrain.
       
  1182                                     ]
       
  1183                                 ] ifFalse:[
       
  1184                                     n == 0 ifTrue:[
       
  1185                                         "/ Windows IPC has a bug - it always
       
  1186                                         "/ returns 0 (when the command is idle)
       
  1187                                         "/ and says its at the end (sigh)
       
  1188 
       
  1189                                         OperatingSystem isMSWINDOWSlike ifTrue:[
       
  1190                                             Delay waitForSeconds:0.01
       
  1191                                         ] ifFalse:[
       
  1192                                             outStream atEnd ifTrue:[
       
  1193                                                 outStream close. outStream := nil.
       
  1194                                                 inStream close.  inStream := nil.
       
  1195                                                 Processor activeProcess terminate.
       
  1196                                             ] ifFalse:[
       
  1197                                                 "/ this should not happen.
       
  1198 
       
  1199                                                 Delay waitForSeconds:0.05
       
  1200                                             ]
       
  1201                                         ].
       
  1202                                     ]
       
  1203                                 ]
       
  1204                             ]
       
  1205                         ]
       
  1206                     ]
       
  1207                 ]
       
  1208             ] ifCurtailed:[
  1228             ] ifCurtailed:[
  1209                 readerProcess := nil    
  1229                 readerProcess := nil    
  1210             ]
  1230             ]
  1211         ] fork. "/ forkAt:9.
  1231         ] fork. "/ forkAt:9.
  1212         readerProcess name:'pty reader'.
  1232         readerProcess name:'pty reader'.
  1218 
  1238 
  1219     "Modified: / 5.5.1999 / 17:58:02 / cg"
  1239     "Modified: / 5.5.1999 / 17:58:02 / cg"
  1220     "Modified: / 28.1.2002 / 21:10:13 / micha"
  1240     "Modified: / 28.1.2002 / 21:10:13 / micha"
  1221 !
  1241 !
  1222 
  1242 
       
  1243 startReaderProcessWhenVisible
       
  1244     "Start a reader process, which looks for the commands output,
       
  1245      and sends me #processInput:n: events whenever something arrives."
       
  1246 
       
  1247     readerProcess isNil ifTrue:[
       
  1248         readerProcess := [
       
  1249             [
       
  1250                 self waitUntilVisible.
       
  1251                 self readerProcessLoop.
       
  1252             ] ifCurtailed:[
       
  1253                 readerProcess := nil    
       
  1254             ]
       
  1255         ] fork. "/ forkAt:9.
       
  1256         readerProcess name:'pty reader'.
       
  1257     ]
       
  1258 
       
  1259     "
       
  1260      VT100TerminalView openShell
       
  1261     "
       
  1262 
       
  1263     "Modified: / 5.5.1999 / 17:58:02 / cg"
       
  1264     "Modified: / 28.1.2002 / 21:10:13 / micha"
       
  1265 !
       
  1266 
  1223 stopReaderProcess
  1267 stopReaderProcess
  1224     "stop the background reader thread"
  1268     "stop the background reader thread"
  1225 
  1269 
  1226     |sensor|
  1270     |sensor|
  1227 
  1271 
  1239     "Modified: / 21.7.1998 / 19:00:13 / cg"
  1283     "Modified: / 21.7.1998 / 19:00:13 / cg"
  1240 ! !
  1284 ! !
  1241 
  1285 
  1242 !TerminalView methodsFor:'initialization-shell'!
  1286 !TerminalView methodsFor:'initialization-shell'!
  1243 
  1287 
  1244 startCommand:aCommand
  1288 basicStartCommand:aCommand in:aDirectory
  1245     "start a command on a pseudo terminal. If the command arg is nil,
       
  1246      a shell is started. The command is started in the current directory.
       
  1247      Also fork a reader process, to read the shells output and
       
  1248      tell me, whenever something arrives"
       
  1249 
       
  1250     ^ self startCommand:aCommand in:nil
       
  1251 
       
  1252     "Modified: / 20.7.1998 / 18:30:24 / cg"
       
  1253 !
       
  1254 
       
  1255 startCommand:aCommand in:aDirectory
       
  1256     "start a command on a pseudo terminal. If the command arg is nil,
  1289     "start a command on a pseudo terminal. If the command arg is nil,
  1257      a shell is started. If aDirectory is not nil, the command is
  1290      a shell is started. If aDirectory is not nil, the command is
  1258      executed in that directory.
  1291      executed in that directory.
  1259      Also fork a reader process, to read the shells output and
  1292      Also fork a reader process, to read the shells output and
  1260      tell me, whenever something arrives"
  1293      tell me, whenever something arrives"
  1269 
  1302 
  1270     OperatingSystem isMSWINDOWSlike ifTrue:[
  1303     OperatingSystem isMSWINDOWSlike ifTrue:[
  1271         "use two pipes to COMMAND.COM"
  1304         "use two pipes to COMMAND.COM"
  1272         stxToCommandPipe := NonPositionableExternalStream makePipe.
  1305         stxToCommandPipe := NonPositionableExternalStream makePipe.
  1273         stxToCommandPipe isNil ifTrue:[
  1306         stxToCommandPipe isNil ifTrue:[
  1274             ^ self warn:'Could not create pipe to COMMAND.COM.'.
  1307             self warn:'Could not create pipe to COMMAND.COM.'. ^ self.
  1275         ].
  1308         ].
  1276 
  1309 
  1277         commandToStxPipe := NonPositionableExternalStream makePipe.
  1310         commandToStxPipe := NonPositionableExternalStream makePipe.
  1278         commandToStxPipe isNil ifTrue:[
  1311         commandToStxPipe isNil ifTrue:[
  1279             ^ self warn:'Could not create pipe from COMMAND.COM.'.
  1312             self warn:'Could not create pipe from COMMAND.COM.'. ^ self.
  1280         ].
  1313         ].
  1281 
  1314 
  1282         "/ pipe readSide is p at:1;
  1315         "/ pipe readSide is p at:1;
  1283         "/      writeSide is p at:2
  1316         "/      writeSide is p at:2
  1284 
  1317 
  1380         inStream close.
  1413         inStream close.
  1381         inStream := outStream := nil.
  1414         inStream := outStream := nil.
  1382         ^ self.
  1415         ^ self.
  1383     ].
  1416     ].
  1384 
  1417 
  1385     self startReaderProcess.
  1418     "Created: / 20.7.1998 / 18:19:32 / cg"
       
  1419     "Modified: / 5.5.1999 / 17:28:37 / cg"
       
  1420 !
       
  1421 
       
  1422 startCommand:aCommand
       
  1423     "start a command on a pseudo terminal. If the command arg is nil,
       
  1424      a shell is started. The command is started in the current directory.
       
  1425      Also fork a reader process, to read the shells output and
       
  1426      tell me, whenever something arrives"
       
  1427 
       
  1428     self startCommand:aCommand in:nil
       
  1429 
       
  1430     "Modified: / 20.7.1998 / 18:30:24 / cg"
       
  1431 !
       
  1432 
       
  1433 startCommand:aCommand in:aDirectory
       
  1434     "start a command on a pseudo terminal. If the command arg is nil,
       
  1435      a shell is started. If aDirectory is not nil, the command is
       
  1436      executed in that directory.
       
  1437      Also fork a reader process, to read the shells output and
       
  1438      tell me, whenever something arrives"
       
  1439 
       
  1440     self basicStartCommand:aCommand in:aDirectory.
       
  1441     self startReaderProcessWhenVisible.
  1386 
  1442 
  1387     "Created: / 20.7.1998 / 18:19:32 / cg"
  1443     "Created: / 20.7.1998 / 18:19:32 / cg"
  1388     "Modified: / 5.5.1999 / 17:28:37 / cg"
  1444     "Modified: / 5.5.1999 / 17:28:37 / cg"
  1389 !
  1445 !
  1390 
  1446 
  1405 startShellIn:aDirectory
  1461 startShellIn:aDirectory
  1406     "start a shell on a pseudo terminal in some directory.
  1462     "start a shell on a pseudo terminal in some directory.
  1407      Also fork a reader process, to read the shells output and
  1463      Also fork a reader process, to read the shells output and
  1408      tell me, whenever something arrives"
  1464      tell me, whenever something arrives"
  1409 
  1465 
  1410     ^ self startCommand:nil in:aDirectory
  1466     self startCommand:nil in:aDirectory
  1411 
  1467 
  1412     "
  1468     "
  1413      VT100TerminalView openShellIn:'/etc'
  1469      VT100TerminalView openShellIn:'/etc'
  1414     "
  1470     "
  1415 
  1471 
  1855 ! !
  1911 ! !
  1856 
  1912 
  1857 !TerminalView class methodsFor:'documentation'!
  1913 !TerminalView class methodsFor:'documentation'!
  1858 
  1914 
  1859 version
  1915 version
  1860     ^ '$Header: /cvs/stx/stx/libwidg2/TerminalView.st,v 1.123 2004-03-19 18:58:02 stefan Exp $'
  1916     ^ '$Header: /cvs/stx/stx/libwidg2/TerminalView.st,v 1.124 2004-11-24 11:10:29 cg Exp $'
  1861 ! !
  1917 ! !
  1862 
  1918 
  1863 TerminalView initialize!
  1919 TerminalView initialize!