Page 1 of 1
Uniform and modern way for App callbacks
Posted: Thu Jan 21, 2021 6:13 am
by Robert
Hi!
I'm designing a simple GUI and I need to decide how the windows' redrawing works.
I'm interested in:
* How the (re)drawing triggered? Is it done by the application or the OS/GUI?
* In case of OS triggeting, how does the window registered? By a syscall?
By modern OSs I mean the nowadays' commercial ones and also interested in experimental ways. So if there are any theoretical works/lectures about it, I welcome them.
Edit: also finding a uniform method for non-GUI kernel->app calls. Is it possible without flooding the GDT?
Thanks in advance,
Robert
Re: Uniform and modern way for App callbacks
Posted: Thu Jan 21, 2021 7:21 am
by iansjack
Can you explain what you mean by "flooding the GDT"?
Re: Uniform and modern way for App callbacks
Posted: Thu Jan 21, 2021 7:42 am
by Robert
iansjack wrote:Can you explain what you mean by "flooding the GDT"?
I was thinking in using call gates for these priviledge-level-lowering calls. But I just figured out it's totally pointless.
Anyway, I'm trying to implement a framework to call user-level functions from kernel level.
Re: Uniform and modern way for App callbacks
Posted: Thu Jan 21, 2021 8:56 am
by nullplan
Typical implementation is that the GUI sends events to the applications. I mean, you already need that mechanism to transport button presses, keyboard presses, mouse movement, etc. So you just define another event that means the application must draw its window again. On Windows, this is called WM_PAINT. On X11, this is an XExposeEvent or XVisibilityEvent. And the application just reads these events out of some queue and handles it by drawing the damaged areas again. This way, no call gate or anything is needed.
In POSIX operating systems, there is a way for the OS to invoke a function in the application. It is called "signal", and it is pretty complicated. And the application cannot do much in a signal handler. So I would advise against that mechanism for things that need to be fast and general-purpose.
Re: Uniform and modern way for App callbacks
Posted: Thu Jan 21, 2021 11:55 am
by Gigasoft
To perform an user mode callback, you would update ESP0 in the TSS, construct a return frame on the user mode stack, save the current ESP and return to the function you want to call using IRETD or RETF. The function should return to a location that invokes an "user mode return" system call, which restores ESP and ESP0 and returns to the original function. Be sure to implement checks to ensure that infinite recursion can not happen.
In the usual case, GUI events will not be handled in this way. Instead, the application invokes the system to retrieve a message and then processes it. The exception would be if a system call displays a modal GUI and therefore has its own event loop.
Re: Uniform and modern way for App callbacks
Posted: Thu Jan 21, 2021 4:20 pm
by bzt
Robert wrote: * How the (re)drawing triggered? Is it done by the application or the OS/GUI?
There are actually two schools:
Old-way, with low-resource requirements (easily tokenisable, so good for networking and on machines with only a few KB of RAM, like C=64):
The GUI sends Expose events to the client, then the client does the clipping and redrawing. The window is typically not stored in memory at all, couple of drawing calls are made.
Used by: anything with Xserver, old Win32 API (GDI), old MacOS9 (and before), NeXT, DesqView,
GEOS,
Contiki,
MenuetOS
Compositor way (requires lots of memory plus not easy to send through networks):
When the client finished with drawing, it notifies the GUI to update it's part of the double buffer (one buffer in the client, one in the server, swapped on update). The client is totally unaware how, when and which parts of its window is redrawn. The window is often stored in GPU memory.
Used by: xcompmgr, Compiz, X11 with some extensions, Wayland, Win Vista and above (called Aero I belive?), MacOS10 and above, etc. etc. etc.
Robert wrote:* In case of OS triggeting, how does the window registered? By a syscall?
Win32 GDI: app uses a dll interface (and what's under the hood? Who knows?), Linux X11: app uses shared library call (low-level libX11, but often high-level lib used, like GTK, Qt, etc.). So no, no direct syscall.
As for MenuetOS, there's a
syscall to define and redraw windows.
Cheers,
bzt
Re: Uniform and modern way for App callbacks
Posted: Fri Jan 22, 2021 9:54 am
by nexos
bzt wrote:Win32 GDI: app uses a dll interface
Actually, that isn't how it works. In NT 3.1, 3.5 and 3.51, gdi32.dll sent a message to the CRSS (Client Runtime Server Subsystem, the Win32 subsystem program), and CRSS handles GDI calls. For performance reasons, in NT 4, they moved the GDI to a subsystem driver in kernel mode (win32k.sys), so GDI calls end up calling a kernel routine in here.
Robert wrote:* How the (re)drawing triggered? Is it done by the application or the OS/GUI?
In Windows, apps get sent a WM_PAINT message. Messages are put in a queue when win32k.sys performs a redraw. When the system returns to user mode, the program calls GetMessage, and then DispatchMessage, which calls the Window Procedure function (called WndProc normally), and then the app uses the GDI to repaint its parts of the window. I don't have much experience in X11 or Wayland, so I can't say for them. Note that these messages aren't to be confused with IPC messages, in Windows, those are entirely separate and handled by the LPC subystem of the executive AFAIK (although in pre NT 4 Windows, CRSS was communicated to with LPC).
Re: Uniform and modern way for App callbacks
Posted: Fri Jan 22, 2021 12:07 pm
by bzt
nexos wrote:bzt wrote:Win32 GDI: app uses a dll interface
Actually, that isn't how it works. In NT 3.1, 3.5 and 3.51, gdi32.dll sent a message to the CRSS (Client Runtime Server Subsystem, the Win32 subsystem program), and CRSS handles GDI calls. For performance reasons, in NT 4, they moved the GDI to a subsystem driver in kernel mode (win32k.sys), so GDI calls end up calling a kernel routine in here.
Actually that's
exactly how it works. According to MSDN, drawing a line for example with Win32:
GDI
LineTo requires
gdi32.dll
GDI+
DrawLine requires
gdiplus.dll, just as
GDIPlusStartUp.
A user application is never "linked" with win32k.sys ever. About what happens inside the DLLs, I wrote "and what's under the hood? Who knows?" because M$ never documented it officially (only the user interface part, but not what's inside and what syscalls they might make).
nexos wrote:I don't have much experience in X11 or Wayland, so I can't say for them.
For X11, the same. When the Xserver (typically Xorg) notices that a window needs redrawing, it sends an Expose event to the client. Then the client gets that with an XNextEvent() and dispatches to the redraw function. For Wayland the client lets the compositor know that the window buffer is updated, and then weston does the redrawing (compositing the window buffers into a framebuffer, hence the name, compositor) without the client knowing.
Cheers,
bzt
Re: Uniform and modern way for App callbacks
Posted: Fri Jan 22, 2021 12:13 pm
by nexos
bzt wrote:A user application is never "linked" with win32k.sys ever. About what happens inside the DLLs, I wrote "and what's under the hood? Who knows?" because M$ never documented it officially (only the user interface part, but not what's inside and what syscalls they might make).
That's not what I meant. I meant, "calls into gdi32.dll end up calling a kernel routine in win32k.sys". And yes, Microsoft did document it. Purchase Inside Windows 2000 and see for your self. Google it. Look at ReactOS.
Re: Uniform and modern way for App callbacks
Posted: Sat Jan 23, 2021 3:02 pm
by eekee
bzt wrote:There are actually two schools:
Old-way, with low-resource requirements (easily tokenisable, so good for networking and on machines with only a few KB of RAM, like C=64):
[...]
Compositor way (requires lots of memory plus not easy to send through networks):
Plan 9 is somewhere between these two schools. It can store windows in GPU memory and redraw them without the client's knowledge, but is quite good over a network. Images are not usually composed client-side, but rather component images (such as bitmap fonts) are loaded into the server and composited into the window's image on the server. Vector graphics are also drawn by the server.
Re: Uniform and modern way for App callbacks
Posted: Sun Jan 24, 2021 4:47 am
by Robert
Thanks for the answers. I think I'll prefer the
application-triggered way, because it uses less cpu time.