Wimp_CommandWindow issues
Jon Abbott (1421) 2651 posts |
Tested with R0=-1 and R0=0 under the 26th Feb 2019 build on a Pi3. The issue has been around a while as it occurs all the way back to RISC OS 2. There are a number of issues with Wimp_CommandWindow:
Repro
I’ve also seen it return an error off the bottom of the screen, but I’ve yet to find a reliable Repro for that, or find out what the error is. |
Steve Pampling (1551) 8172 posts |
Surely failing with a (more) meaningful error message is correct. I rather prefer systems to present meaningful feedback of my mistakes than what would in a human be labelled “dumb insolence” |
Jon Abbott (1421) 2651 posts |
This SWI should never error for R0=0 or -1. |
Jon Abbott (1421) 2651 posts |
I believe Line 5601 should clear V before exit, so it doesn’t trigger an error outside of the Wimp. There’s a precedent for this further down, as it clears V on line 5707. The issue is being caused by the SWI XOS_WriteI+5 on line 5734. Remove that and the SWI works as expected. That OS_WriteI+5 (Write text at graphics cursor) might also explain the off screen error I’ve seen. If it wants to remove the cursor, should it not use VDU 23,1,0,0,0,0,0,0,0,0? Incidentally, why is there no SWI and *command equivalent for VDU 23,1,0,0,0,0,0,0,0,0? I’ve lost count of the amount of times I’ve used that VDU sequence! Another observation I’d make is the use of VDU in Wimp_CommandWindow could have odd effects if it was called from an Error handler and VDU was in an unknown state. That’s possibly why I’ve seen text messages appear offscreen. |
André Timmermans (100) 655 posts |
OS_RemoveCursors Also I agree OS_WriteI+5 will link text and graphics, not remove the cursor as the comment implies, unless maybe it is a side effect. |
Jon Abbott (1421) 2651 posts |
The problem with that particular SWI is it needs to be balanced with OS_RestoreCursors, so isn’t something you’d want to use when you just want to turn the cursor off. |
Jeffrey Lee (213) 6048 posts |
OS_WriteI+5 is correct, when you consider that the default state for the text cursor in the Wimp is that it’s joined with the graphics cursor (the Wimp goes into VDU 5 mode at the start of each redraw operation, and at various other times, because in the olden days the default desktop font was the system font, plotted in VDU 5 mode by the kernel) VDU 5 also has the side effect of hiding the cursor, since the kernel doesn’t bother to plot it when in that mode (IIRC) So I suspect the real problem is that for the “alt-break required” case, it’s actually returned to BASIC, but you can’t see anything you’re typing because the system has been left in VDU 5 mode with the cursor off-screen. Does typing “VDU 4” fix it? |
Jon Abbott (1421) 2651 posts |
I’d suggest a correction to line 5734, so it takes account of the desktop state:
Yes, but we had to look at the source code to figure that out! |
Rick Murray (539) 13850 posts |
I wrote a simple text editor (REdit) just for the sake of it, and there are a number of comments in the code talking about the ass-backwards API that was born on the Beeb, and seemingly never changed since then. Dealing with the keyboard is a load of frankly obscure OS_Byte calls, and doing stuff with the text cursor (actually, quite a lot of things) mean tossing special magic values to the VDU driver… |
Jon Abbott (1421) 2651 posts |
I don’t have a problem with OS_Byte / OS_Word, they pretty much cover most IO functions, creating specific SWI for each would just be pointless as they work perfectly well. I do however raise my eyebrows when I see the OS using VDU calls. It’s far too easy to get VDU in a messed state, which then causes all sorts of random things to happen. I suppose you can probably get it into a known state by sending a series of zeroes to it, but it would be simpler to provide a direct interface to things like cursor state. As a workaround to the issue in the OP, I’ve modified my code to issue VDU 4 directly after calling Wimp_CommandWindow. Provided no further text is output, there’s no difference when exiting back to the Wimp and if an error subsequently occurs, I can now at least see it. Turns out WimpSysInfo_DesktopState isn’t quite what it implies. If the Wimp task has closed down and for example, the !Run Obey file is closing down, it returns 0 not 1, so it’s not actually “Desktop State”, a more reliable term would be “Within a Wimp task”. On the wiki it’s “Wimp States” which adds further ambiguity. As far as I can see, there’s no definitive way to determine if you’re in the Wimp or at a CLI. About the best workaround for this I can come up with is to see if the CAO is the Debugger or Supervisor. BASIC is an issue however as you need to know if it’s at the command line. The ideal “fix” would be for all CLI’s to issue VDU 4 before displaying their CLI prompt, but then there’s probably always an edge case where you might want VDU 5 at a CLI where VDU 21/6 don’t cover it. |
nemo (145) 2554 posts |
Jon said
“Expected” Jeffrey said
This is the wrong thing it is doing, not an explanation of how it isn’t wrong. It is wrong (but it’s too late now), as I’ll explain. Jon suggested
The Wimp does not need to be issuing Wimp SWIs in order to read the Wimp’s state.
This leads back to your “expected” – RO documentation is never particularly thorough. Look at the lengths I had to go to in order to document OS_ReadLine completely, for example. “Expectation” is the problem here – the call does not do what one would like, it does its own thing which is only partially useful.
And it’s sort of worse than that. The Wimp’s internal Command Window State (I’ve always called it DesktopState, I don’t know what it is in the original sources) is misleading, and THAT is what is causing the “unexpected” behaviour: The real problem is that after pressing F12 the DesktopState is set to 2 – “Open”. This is a lie, the Command Window is not open. Definitely not. After calling The cause is the incorrect (or insufficient) state. BUT, it’s too late now for this API. I have a module called TWState that provides a code variables called So the following Obey file: Set Before <TaskWindow$State> Echo Hello World Set After <TaskWindow$State> will result in
Having just tested TWState with the following: ... Set Before <TaskWindow$State> Run <Obey$Dir>.!RunImage Set During <TaskWindow$State> Echo Oh, I've quit! Set After <TaskWindow$State> The results are: Which is more useful, isn’t it? BTW. My version of the Wimp ignores VDU7 during a pending Command Window, because it shouldn’t pop up and demand “Press RETURN” just because something beeped. |
Jon Abbott (1421) 2651 posts |
I refer the honourable gentleman to Wimp01 where I copied the code from.
That the results one would reasonably expect from WimpSysInfo_DesktopState.
I’ve not looked at the source, but I’m guessing the Wimp is possibly hooking in WrchV and creates a command window if there’s any VDU traffic. I believe it creates a command window for most if not all VDU control codes. VDU 21 causes some interesting issues, as the Wimp doesn’t reset the VDU state when the task closes down. |
nemo (145) 2554 posts |
And it allows the Wimp’s SWI intercept hook to be triggered, which is something.
A philosophical point, well made. But it’s not done that in the past so shouldn’t change now (unless switched by API version in Wimp_Initialise… but that wouldn’t be useful in this case). Actually, do you mean reason 3 or some new reason – the latter would be fine and dandy for bleeding-edge RO5 users, but no use for authors targeting any old version of the OS. Note that TWState combines the Wimp’s DesktopState with TaskWindow’s TaskInfo state, neither of which is sufficient in isolation to understand what state the screen output is in. Although I could add a SWI to allow code to read that tristate, it’s probably more sensible to just properly document how to use those calls to derive the state. So here’s the logic: • If
Quite right. And hence it really ought to be cleverer about what does and does not constitute ‘output’. PS. Closing a Command Window doesn’t just do VDU5 – it will also reset the cursor and function keys, and close the Exec file, amongst other things. |
Rick Murray (539) 13850 posts |
Tell me about it. My OLED module creates a fake wimp task (and then destroys it) simply to prevent the entire desktop redrawing when the module is loaded because it issues VDU calls to a redirected sprite and the Wimp sees this as “something output”. Grrrrrrrrrr…… |
nemo (145) 2554 posts |
Uggh. Nope, sprite redirection definitely doesn’t exist. Heretic. |
Stuart Swales (1481) 351 posts |
Neil on sprite redirection: “It’ll only take an afternoon”… |
Jon Abbott (1421) 2651 posts |
That’s not strictly true as any WrchV calls will cause it return 0. For example, the following Obey file would return 0 even though it’s output no text:
Rick’s example of sprite redirection would also return 0. |
nemo (145) 2554 posts |
I’m not sure what you’re saying here. It is true that using Wimp_ReadSysInfo,3 from inside a WrchV claimant can return 0 during some Wimp-generated VDU actions, such as changing mode, even though one is still inside the desktop, but you wouldn’t otherwise be calling CommandWindow from inside a WrchV claimant either (apart from anything else, in the absence of VectorExtend how could you know you were being called before or after the Wimp’s WrchV handler?).
So what? I didn’t say anything about “outputting text”, I was talking about whether the Wimp believes something has taken control of the screen from it. Issuing VDUs like that indicates that something has. Hence my point about ignoring VDU7, because beeping is (uniquely) not a visual action. I did suggest that the Wimp could be more sophisticated about what it sees as stealing the screen, and VDU21…6 is such an example. But changing WrchDest would have the same effect and NOT trigger the Wimp’s hair-trigger.
Which is another limitation of the Wimp’s WrchV detector… and doubly so because the Wimp does know that output has been switched to a sprite, it just forgot to check. D’oh! So to clarify your “not strictly true”, can you see a way in which a non-Wimp program could get 0 from Wimp_ReadSysInfo,3 whilst still being in the desktop? (I’m not including VDU code here, that doesn’t count as a program). |
nemo (145) 2554 posts |
The Wimp’s pending-CommandWindow WrchV claimant could and arguably should be checking the following things before deciding to trigger the CommandWindow: • VDU7 can be ignored, it’s a sound One might argue, pedantically, that VDU23,27,1… could also be ignored, but frankly my dear… After all, you can OS_SpriteOp, Font_Paint and Draw_Fill all over the screen and the Wimp won’t notice. |