Not blocking until an event
Is it possible to add GrEventsPending() that returns immediately?
This way I could do:
while(GrEventsPending()) {
GrGetNextEvent(&ev);
We already have GrPeekEvent and GrPeekWaitEvent, can you try using one of those? There should be info in the documentation.
I get:
function main: error: undefined reference to 'GrPeekEvent'
collect2: error: ld returned 1 exit status
This is the problem in general.
So GrPeekEvent is not in libnano-X.a ?
So GrPeekEvent is not in libnano-X.a ?
It looks like GrPeekEvent and GrPeekWaitEvent are not by default in ELKS nano-X library. This is the result of having MW_FEATURES_TINY defined, which removes a bunch of functionality so that the client library (client.c) and server code all fit in the limited code and data available. I had to add MW_FEATURES_TINY in order to remove enough stuff that the Nano-X server would link in 64k code, and its only used for ELKS.
You can try moving the #if !MW_FEATURE_TINY line down past GrPeekEvent in client.c, but it might get complicated, as the client/server code in Nano-X is not simple. I can look at this more when I am not traveling.
In general, it is very much not recommend to write an application using GrPeekEvent unless you absolutely have to. The reason is, that application will immediately and permanently use all CPU in the fast message loop, which then causes the Nano-X server to get very slow updating the screen for not only the peeking application, but all applications.
What is the reason you need GrPeekEvent / GrPeekWaitEvent?
To improve the main loop in my application and not to block wait. On a very slow system such 8MHz you get some weird behavior where some things do not happen and then they do happen much later. What you get is inconsistent behavior. Yes, I want to try only GrPeekEvent if it improves the whole experience.
Also what is the good sleep function in ELKS? One that will give CPU to another processes instead of looping the CPU?
@toncho11, you can use GrGetNextEventTimeout which is present and working well. It is used in nxtetris and is passed a second argument which is the timeout value in msecs. It can be passed GR_TIMEOUT_POLL to poll without waiting, but I would recommend passing 10-100 which will use much less CPU time and allow other applications to run, which usually accomplishes what is wanted.
Also what is the good sleep function in ELKS? One that will give CPU to another processes instead of looping the CPU?
You can use usleep which takes a long microseconds as a parameter, but GrGetNextEventTimeout can eliminate the need for that. See demos/nanox/nxtetris.c for examples of use; previously usleep was used, but now is now longer needed with GrGetNextEventTimeout.
I am all the time fighting disappearing text on 8086 8Mhz. It changes between restarts. Sometimes is perfectly OK and the text is there, sometimes there is no text at all. And it is difficult to say what triggers this behavior. This nondeterministic behavior is driving me crazy.
It is probably not related to GrGetNextEventTimeout ... On a Pentium class system - it always works. On the slow system my program starts for 10 seconds.
Yes, it is driving my crazy. I exit with CTRL+A and I start it again - sometimes I get text, but most of the time I do not. It takes around 14 seconds for my application to start.
It seems after restart it takes like 18 seconds and this is the time when it is more likely to work. After that it stops.
I am on Minix.
Here are some possible reasons for the missing text (missing most of the time, but sometimes OK):
- The 8086 was so slow that EXPOSE events arrived late and were not processed before other drawing began.
- The 20 ms timeout fired too early, causing your code to draw before the window had ever been painted.
- The event queue overflowed or merged events, causing some EXPOSE events to be lost.
- Drawing from timeouts and EXPOSE happened in the wrong order, overwriting freshly drawn text.
- Startup took so long on the 8086 that redraw logic ran during an uninitialized window state.
But it gets rather complicated for me?
Still driving me crazy. As if the first time it starts it does something that ruins the next ones. I am using 86Box version 5 emulating Amstrad 1640.
@toncho11 Thanks for the comments. Indeed, graphics programing within a window system like X11 or Nano-X can be tricky. No question that when multiple processes are involved, one issuing draw commands, and another doing the drawing, any of the problems you described around EXPOSE processing can occur.
However, the system does keep draw requests in order from an application in order. EXPOSE events, sent the other direction, can happen in any order.
I have found that when speed issues bring up display inconstistencies, sometimes the problem is related to exactly when the background is drawn, and also whether all drawing occurs in EXPOSE events, or whether drawing occurs in the main application look AND expose events. In general, the application needs to be able to redraw all backgrounds AND text on expose events, not just the default background, which otherwise appears to blank the screen. You might check this in your own app, and then try commenting out expose event handling to see how that differs.
Another approach is to take a working application and start with that, rather than writing a main loop from scratch. I can help more after hearing what you're finding from my above descriptions.
Finally, there are potentially issues within Nano-X, even bugs, relating to potentially complex graphics drawing, especially when combining expose and main loop drawing.
But it gets rather complicated for me?
Yes, it remains complicated for me also!
Ok so Nano-X sends an EXPOSE event when:
- The window is shown for the first time
- Another window that was covering it moves
- Your window is uncovered after being partially overlapped
- The window is resized
- The window is restored after being minimized (if the WM does that)
- The screen contents are invalidated for any reason
Nano-X does not automatically remember your window’s pixels. So my application is responsible for redrawing the UI whenever needed.
It also means that redraws should happen only in EXPOSE events in order to reduce the number repaints on slow systems?
It also means that redraws should happen only in EXPOSE events in order to reduce the number repaints on slow systems?
Yes, for various reasons, I recommend only drawing during expose events, if possible. If not, then more precautions may be necessary. When only drawing on expose, the NX server completely controls when the application should draw, and issues relating to when and whether to draw the background aren't an issue, since the background will be drawn (by default) prior to the expose event being sent to the application.