Uniform and modern way for App callbacks

Discussions on more advanced topics such as monolithic vs micro-kernels, transactional memory models, and paging vs segmentation should go here. Use this forum to expand and improve the wiki!
Post Reply
User avatar
Robert
Member
Member
Posts: 25
Joined: Wed Jan 13, 2021 8:49 am

Uniform and modern way for App callbacks

Post 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
User avatar
iansjack
Member
Member
Posts: 4703
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: Uniform and modern way for App callbacks

Post by iansjack »

Can you explain what you mean by "flooding the GDT"?
User avatar
Robert
Member
Member
Posts: 25
Joined: Wed Jan 13, 2021 8:49 am

Re: Uniform and modern way for App callbacks

Post 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.
nullplan
Member
Member
Posts: 1790
Joined: Wed Aug 30, 2017 8:24 am

Re: Uniform and modern way for App callbacks

Post 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.
Carpe diem!
Gigasoft
Member
Member
Posts: 856
Joined: Sat Nov 21, 2009 5:11 pm

Re: Uniform and modern way for App callbacks

Post 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.
User avatar
bzt
Member
Member
Posts: 1584
Joined: Thu Oct 13, 2016 4:55 pm
Contact:

Re: Uniform and modern way for App callbacks

Post 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
nexos
Member
Member
Posts: 1081
Joined: Tue Feb 18, 2020 3:29 pm
Libera.chat IRC: nexos

Re: Uniform and modern way for App callbacks

Post 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).
"How did you do this?"
"It's very simple — you read the protocol and write the code." - Bill Joy
Projects: NexNix | libnex | nnpkg
User avatar
bzt
Member
Member
Posts: 1584
Joined: Thu Oct 13, 2016 4:55 pm
Contact:

Re: Uniform and modern way for App callbacks

Post 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
nexos
Member
Member
Posts: 1081
Joined: Tue Feb 18, 2020 3:29 pm
Libera.chat IRC: nexos

Re: Uniform and modern way for App callbacks

Post 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.
"How did you do this?"
"It's very simple — you read the protocol and write the code." - Bill Joy
Projects: NexNix | libnex | nnpkg
User avatar
eekee
Member
Member
Posts: 891
Joined: Mon May 22, 2017 5:56 am
Location: Kerbin
Discord: eekee
Contact:

Re: Uniform and modern way for App callbacks

Post 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.
Kaph — a modular OS intended to be easy and fun to administer and code for.
"May wisdom, fun, and the greater good shine forth in all your work." — Leo Brodie
User avatar
Robert
Member
Member
Posts: 25
Joined: Wed Jan 13, 2021 8:49 am

Re: Uniform and modern way for App callbacks

Post by Robert »

Thanks for the answers. I think I'll prefer the
application-triggered way, because it uses less cpu time.
Post Reply