// Text of project pseudoInspector written on 5/9/95 at 18:14 // Beginning of file baseView.t // Before Script for "baseView" // Copyright © 1993-1995 by Apple Computer, Inc. All Rights Reserved. baseView := {title: "PseudoInspector", viewBounds: {left: 0, top: 0, right: 240, bottom: 336}, viewSetupFormScript: func() begin // Justification of app base view constant kMaxWidth := 240; constant kMaxHeight := 336; local b := GetAppParams(); self.viewBounds := RelBounds(b.appAreaLeft, b.appAreaTop, Min(b.appAreaWidth, kMaxWidth), Min(b.appAreaHeight, kMaxHeight) ); end, debug: "baseView", _proto: @157 }; info := { text: "This simple application will dump Newton information via the serial port." , viewBounds: {left: 10, top: 18, right: 226, bottom: 66}, viewJustify: 0, debug: "info", _proto: @218 }; AddStepForm(baseView, info); DumpButton := {text: "Connect", buttonClickScript: // Make the initial connection, start listening to incoming messages. func() begin // instantiate the endpoint anErr := ep:Instantiate(ep, nil); if anErr then begin :Notify(kNotifyAlert, "DumpNames", "Sorry, serial port already in use!"); return; end; SetValue(result, 'text, "endpoint instantiated"); // do a connect local anErr := ep:Connect(nil,nil); if anErr then begin :Notify(kNotifyAlert, "DumpNames", "Check your cables and terminal emulator, couldn't connect"); return; end; // set the next input spec for listening mode ep:SetInputSpec(ep.waitforACK); // dump info to our info field SetValue(result,'text, "Connected, waiting for ACK?"); end;, viewBounds: {left: 52, top: 220, right: 156, bottom: 252}, viewSetupDoneScript: // Create the endpoint that we need later. func() begin local anErr := nil; // create an endpoint for our use, protoSerialProtocol is defined in this same frame ep := {_proto: protoSerialProtocol, _parent: self}; end, ep: nil, viewQuitScript: func() // release the endpoint (connection, memory) begin ep:FlushInput (); ep:FlushOutput (); ep:SetInputSpec (nil); ep:Abort(); AddDelayedAction(func() begin // let the endpoint clean up from the abort before disconnecting and disposing ep:Disconnect(); ep:Dispose(); end, [], 1000); print("Disposed the endpoint"); end, DumpResult: nil, protoSerialProtocol: // this is our special endpoint with the protocol built in. This works fine as long as you remember // that this entity is created in Read-only space. Stay tuned for a solution where this is created // in RAM (actually move this code so it executes during viewSetupDoneScript time and that's it) { _proto: protoEndpoint, // the basic serial endpoint with the serial port configuration configOptions: [ { label: kCMSAsyncSerial, type: 'service, opCode: opSetRequired }, { label: kCMOSerialIOParms, type: 'option, opCode: opSetNegotiate, data: { bps: k9600bps, dataBits: k8DataBits, stopBits: k1StopBits, parity: kNoParity } }, { label: kCMOInputFlowControlParms, type: 'option, opCode: opSetNegotiate, data: { xonChar: unicodeDC1, xoffChar: unicodeDC3, useSoftFlowControl: true, useHardFlowControl: nil } }, ], // the rest here is just code for the state machine, all the state frames are stored inside the // the endpoint itself, it's just a handy place to put them, those could be stored anywhere. // We need to catch the last abort exception, later this should be more uniform, check // out what the exception was and ignore the abort one (the one causing the notify). exceptionHandler: func(exception) begin print("Got the exception from Abort, ignoring it!"); end, // this is just the initial handshaking part to make sure that both ends are alive waitforACK: { InputForm: 'string, endCharacter: $?, // ACK? expected InputScript: func(endpoint, s) begin if (StrPos(s, "ACK?", 0)) then begin // tell status if needed endpoint:Output("ACK!", nil); // send response endpoint:FlushOutput(); endpoint:SetInputSpec(endpoint.waitForFUNCTION); // the main dispatch loop end end, discardAfter: 200, }, // This is the generic dispatcher state, send something ending with ! and // the Newton will serve. waitForFUNCTION: { InputForm: 'string, endCharacter: $!, // expects a '!' as part of the command InputScript: func(endpoint, s) begin if(StrPos(s, "CARD!", 0)) then // card function begin //print("Card Function"); print(s); // print the string itself just as an example // Call the name soup dumping function (LATER, send the ep and let the function // do the output! endpoint:Output(endpoint:DumpNameSoup(), nil); endpoint:Output(unicodeCR, nil); endpoint:Output(unicodeLF, nil); endpoint:FlushOutput(); end; if(StrPos(s, "NAME!", 0)) then // name function begin print("Name function"); // Call the Name function (just a wrapper around userConfiguration.name) endpoint:Output(endpoint:DumpName(), nil); endpoint:Output(unicodeCR, nil); endpoint:Output(unicodeLF, nil); endpoint:FlushOutput(); end; if(StrPos(s, "SIZE!", 0)) then // size function begin print("Size function"); endpoint:Output(endpoint:DumpSize(), nil); endpoint:Output(unicodeCR, nil); endpoint:Output(unicodeLF, nil); endpoint:FlushOutput(); end; if(StrPos(s, "SEND!", 0)) then //Inspector-ish function begin print("String sending function, switch to receive string state"); endpoint:Output(unicodeCR,nil); endpoint:Output(unicodeLF,nil); endpoint:SetupStringReceive(); endpoint:SetInputSpec(endpoint.waitForSTRING); end; if(StrPos(s,"PLAY!",0)) then //Let's play a beep remotely! begin PlaySound(ROM_funbeep); endpoint:Output(unicodeCR, nil); endpoint:Output(unicodeLF, nil); endpoint:FlushOutput(); end; if(StrPos(s, "BYE!", 0)) then // closes connection/kills ep begin endpoint.nextInputSpec := nil; endpoint:SetInputSpec(nil); endpoint:FlushInput (); endpoint:FlushOutput (); endpoint:Abort(); AddDelayedAction(func() begin // let the endpoint clean up from the abort before disconnecting and disposing endpoint:Disconnect(); endpoint:Dispose(); end, [], 1000); print("Bye function"); end; end, discardAfter: 200, }, // our special string handling state waitForSTRING: { InputForm: 'string, endCharacter: $>, InputScript: func(endpoint, s) begin endpoint:DoInspector(s); // try compiling string endpoint:Output("OK!", nil); // send response endpoint:Output(unicodeLF, nil); endpoint:FlushOutput(); endpoint:SetInputSpec(endpoint.waitForFUNCTION); // back to the main dispatch loop end, discardAfter: 200, } }, DumpNameSoup: func() begin DumpResult := nil; // Need to do this to keep list from getting longer and longer SetValue(result, 'text, "Sending over Card Soup Info"); // get soup local theSoup := GetStores()[0]:GetSoup("Names"); // create a cursor local myCursor := Query(theSoup, {type: 'index}); // while valid entries, dump the name information out repeat begin local val := myCursor:Entry(); if(val.name.class = 'person) then begin DumpResult := DumpResult & val.name.last & $, & val.name.first & $, & val.city & $\n & $\u000A; end; end until (myCursor:Next() = nil); // return the big string return DumpResult; end, DumpName: func() begin SetValue(result, 'text, "Sending over Name information"); return userConfiguration.name; end, DumpSize: // return size of internal storage func() begin local theStore := GetStores()[0]; local used := theStore:UsedSize(); local space := (theStore:TotalSize() - used) div 1024; local Kused := used div 1024; return "K used =" && kUsed && ", K free =" && space; end , SetupStringReceive: func() begin SetValue(result, 'text, "Ready to receive string"); end, DoInspector: func(string) begin local myString := Clone(string); // have our own ref to it (string is changing beneath!) SetValue(result, 'text, myString); // for the time being just draw it in the result view // Print("try compiling"); try self.xFunc := Compile(SubStr(string, 0, StrLen(string) - 1)); onexception |evt.ex| do //This catches compile errors begin local e := CurrentException(); :Notify(kNotifyAlert, "SendOverInfo", "Couldn't compile"); return; end; // Print("try calling"); try SetValue(result, 'text, NumberStr(Clone(self:xFunc()))); onexception |evt.ex| do //Catches calling exceptions begin local e := CurrentException(); :Notify(kNotifyAlert, "SendOverInfo", "Call exception"); return; end; end, xFunc: nil, debug: "DumpButton", _proto: @226 }; AddStepForm(baseView, DumpButton); result := {text: "Status Information", viewBounds: {left: 10, top: 146, right: 226, bottom: 186}, viewFormat: 336, debug: "result", _proto: @218 }; AddStepForm(baseView, result); StepDeclare(baseView, result, 'result); constant |layout_baseView.t| := baseView; // End of file baseView.t