How to make the GUI of my OS?

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!
mkfree
Member
Member
Posts: 55
Joined: Thu Apr 30, 2020 6:03 am
Libera.chat IRC: mkfree

How to make the GUI of my OS?

Post by mkfree »

:?: I have been looking for information but I find little on the subject, for now I find it difficult to find information
About the composer, can someone help me with this. These are some of my questions:
1- How often is the video buffer refreshed so that there is no flickering on the screen, how is the calculation done?
2- The process that runs as a composer has priority and that it loads on the CPU?
3- Is it always necessary to keep drawing the video buffer ?.
User avatar
BenLunt
Member
Member
Posts: 941
Joined: Sat Nov 22, 2014 6:33 pm
Location: USA
Contact:

Re: How to make the GUI of my OS?

Post by BenLunt »

These are good questions on a difficult subject.

I have been recently working on some of my work, which includes my book on the subject. I have also recently posted the code for this book, along with the others as well.[1]

The code is a self contained small example of a GUI, displaying a few windows, text boxes, images, etc., all allowing you to move them with the mouse, just like a typical GUI would.

Have a look at it and see what you think. If you have any more questions, be sure to post here and we will see what we can do to help.

Ben

[1] - The code is a little old and possibly outdated, but I am in the process of updating it to the new release.
mkfree
Member
Member
Posts: 55
Joined: Thu Apr 30, 2020 6:03 am
Libera.chat IRC: mkfree

Re: How to make the GUI of my OS?

Post by mkfree »

BenLunt,
Thank you very much I will review it, I really appreciate your help.
mkfree
Member
Member
Posts: 55
Joined: Thu Apr 30, 2020 6:03 am
Libera.chat IRC: mkfree

Re: How to make the GUI of my OS?

Post by mkfree »

I have the following question?:

In a widget that has a scrollbar, for example a listview paints all the
contained in the container or only the content corresponding to the
container size.
I have tried painting the content only corresponding to the container, but when
a scroll is made you have to paint everything again, however if everything is painted
it would just be running the pixels and not having to paint all the text again.

Like a textview how would you proceed?
Attachments
windows.png
User avatar
Schol-R-LEA
Member
Member
Posts: 1925
Joined: Fri Oct 27, 2006 9:42 am
Location: Athens, GA, USA

Re: How to make the GUI of my OS?

Post by Schol-R-LEA »

And because shameless self-promotion is a thing for me, I would also suggest taking a quick look at the wiki page on the idea of a Graphics stack, which gives an overview of the big-picture aspects of designing a modern graphics sub-system. Note that this approach isn't mandatory; the original Mac managed to squeeze it's GUI into a 64KiB ROM, for example, though that was a case of some truly heroic assembly coding and relied on the closed-system nature of the 128K Macintosh.

On a side note, that page still could use some wiki love, preferably by someone more experienced with this topic than I am, if any have time to devote to it.
Rev. First Speaker Schol-R-LEA;2 LCF ELF JAM POEE KoR KCO PPWMTF
Ordo OS Project
Lisp programmers tend to seem very odd to outsiders, just like anyone else who has had a religious experience they can't quite explain to others.
mkfree
Member
Member
Posts: 55
Joined: Thu Apr 30, 2020 6:03 am
Libera.chat IRC: mkfree

Re: How to make the GUI of my OS?

Post by mkfree »

Schol-R-LEA,
And because shameless self-promotion is a thing for me.
I really don't understand these words.
I have reviewed the wiki and it seems great, I have clarified some concepts that I was not clear about the subject.
Thanks in advance
User avatar
bzt
Member
Member
Posts: 1584
Joined: Thu Oct 13, 2016 4:55 pm
Contact:

Re: How to make the GUI of my OS?

Post by bzt »

mkfree wrote:Schol-R-LEA,
And because shameless self-promotion is a thing for me.
I really don't understand these words.
He was just joking, because he wrote that wiki page :-) Never mind his sense of homour, it is a very good and valuable source indeed, and that's what matters.

Cheers,
bzt
mkfree
Member
Member
Posts: 55
Joined: Thu Apr 30, 2020 6:03 am
Libera.chat IRC: mkfree

Re: How to make the GUI of my OS?

Post by mkfree »

I really couldn't find a workable solution and made the following attempts but they are
a little slow, I'm going to give an example of a text editor that inherits from a scroll widget:
In a text editor, if you move the scroll, everything is repainted again on the screen, and brings
the part that was not visible until now. But how to do it well? I have tried several ways
but they are very slow I put them for consideration:
1-I have manually run the pixels x pixels according to the size of the scroll to avoid having to
paint the already painted text, then paint the new text in the dirty position, but that
it seems to be fine clicking the up and down buttons of the scroll,
but when taking the scroll with the cursor and moving it up and down the behavior
it's not good, it's a little slow.
2-The other thing that I have not tried but it occurs to me is that each line have it in a separate bitmap
and only copy it on screen at the necessary moment, only modify the bitmap of each line
depending on the operation, that is, more text, select text, but several problems arise,
every time the text of the line is enlarged you have to change the size of the bitmap and repaint
that line (or create a new line with the increment n characters above and then copy
the previous one, and there is room for more characters), but here the memory consumption is important.
3-The other thing that occurs to me is to paint everything on canvas, but I imagine a text 1000 lines x 80
characters each size is huge.

4-Create apart from the container bitmap, 4 more bitmap, where the other areas to paint, and only update the areas that are removed by scrolling the auxiliary bitmap.

Would appreciate your help.
User avatar
Schol-R-LEA
Member
Member
Posts: 1925
Joined: Fri Oct 27, 2006 9:42 am
Location: Athens, GA, USA

Re: How to make the GUI of my OS?

Post by Schol-R-LEA »

I've looked at your code a bit, though I haven't done a deep dive yet. I am a bit puzzled as to how it all fits together, but that is just because I've only done a very cursory look so far.

You seem to have a number of different places with video code, and I am not entirely certain which you are discussing. My best guess is that you're working on the sections in GUImkfree, but elsewhere you have
I'm not saying this as a criticism, I am just pointing out that I am not sure which files you are working on at the moment and where in the code you're having trouble.

From the looks of it, the core low-level class is Cgraphics, which represents and operates on the raw VGA linear frame buffer. Cvga similarly seems to be focused on the default VGA register set, operating things such as mode setting. Cbxvga and the other *bxvga code appears to be specific for the Bochs virtual video adapter.

The place you seem to be focusing on here, though, is the GUImkfree/components/ directory, primarily the performance of Gwindows and GtextEdit. Am I correct in this supposition?

I just want to make sure we're all on the same page when talking about this. We'll probably need to refer to the lower-level code a bit, but this at least would tell us what we're discussing.

One thing I don't see is any code for double buffering, nor any for vsync timing, though I may simply have missed them so far. I'm not sure if either is relevant to the specific problem at hand, though both are pretty much necessary to provide smooth, flicker-free movement. While synchronizing on the vertical refresh isn't as crucial with a modern flat-panel (LCD or LED) monitor as it was with CRTs, it still is important for avoiding problems such as screen tearing (which is where a picture begins updating partway through a vertical draw cycle, causing the output to momentarily appear fractured).

Note also that while a purely-software rendering approach will work, it will always be slower than one using a hardware-specific driver. Unfortunately, video drivers are annoying tough to write, even with full documentation, and said docs are sometime hard to come by - NVidia, in particular, keeps the details close to the vest. Also, with Bochs in particular, it will always run slower than on live hardware, or even virtualized hardware (using e.g., QEMU, Hyper-V, or Virtualbox), since (IIUC) it is interpreting the instructions rather than virtualizing the CPU. While Bochs is fast enough for many things, it is still significantly slower than live hardware.
Rev. First Speaker Schol-R-LEA;2 LCF ELF JAM POEE KoR KCO PPWMTF
Ordo OS Project
Lisp programmers tend to seem very odd to outsiders, just like anyone else who has had a religious experience they can't quite explain to others.
mkfree
Member
Member
Posts: 55
Joined: Thu Apr 30, 2020 6:03 am
Libera.chat IRC: mkfree

Re: How to make the GUI of my OS?

Post by mkfree »

I practically wrote the topic of the GUI without having looked for a bibliography about it, I just
focus on ideas you had at the time. Now that I have clarified a few concepts, I
realize that I was really doing it wrongly, I will spend some time writing as I tried
to structure it, and thus be able to give a vision of what has been implemented so far.

As you said in the kernel, the Cgraphics class is the lowest level, it is the one that connects
user applications with the video buffer. The bxvga.cc classes (virtual video Bochs)
and vga.cc (for the VGA device) are the drivers to manage the devices. The VGA folder
it only stores utilities used in the VGA class.
The video server, in order to access the video buffer, does so through a kernel call,
with the commands cgpPaintArea (To paint a specific area) and cgpGetArea (To read an area),
not if this is the most correct thing? or it would be faster and easier sharing the video buffer
with the app.

You are correct, the GUImkfree / components directory is where the components of that
he spoke. I've changed a lot of this code, and I'm running it in a program
high level to simulate painting the components and thus save a little time.
Don't call it widgets but controls, now every GUI component inherits from Gcontrol,
Gcontrol class inherits from GgraphicsBitmap which stores component buffer as
such.
The Gcontrol class is the one that interacts directly with the window's video buffer
to paint the different components. There are two variables within Gcontrol
GcanvasPainter * canvas, is that it is called directly from the components to access the bitmap of the
control and draw on it, GcanvasPainter has compo methods drawRect, drawRectGradient, ...
The other is GcanvasPainter * containerlayout which is the one to access the window buffer.
If you look in the Gwindows class I create the buffer:
containerlayout = new GcanvasPainter (new GgraphicsBitmap (width, height));
I really have my doubts about it, it is the Window Manager who creates the shared buffer
and assign it to the window, or is it the window who creates it and sends it to the Window Manager ?.
The Gclient class is the one who really deals with making the connection to the server, and sending the
events to components.
I attach the code, this is the version I'm working on, the other one I published has many
problems. I'm stuck in the GlistBox because of the Scroll issue that I raised earlier and
I have not continued to modify the GtextEdit.
Thank you very much for your time and understanding.
I may have misconceptions regarding this implementation, so any suggestion is ok
for me.
Regards
Attachments
Gui.zip
(36.03 KiB) Downloaded 93 times
gui.png
Octocontrabass
Member
Member
Posts: 5512
Joined: Mon Mar 25, 2013 7:01 pm

Re: How to make the GUI of my OS?

Post by Octocontrabass »

mkfree wrote:The video server, in order to access the video buffer, does so through a kernel call,
with the commands cgpPaintArea (To paint a specific area) and cgpGetArea (To read an area),
How often does the video server read the frame buffer? In most cases, reading the frame buffer is extremely slow, so you should avoid doing it.
mkfree
Member
Member
Posts: 55
Joined: Thu Apr 30, 2020 6:03 am
Libera.chat IRC: mkfree

Re: How to make the GUI of my OS?

Post by mkfree »

Shared memory

I've been reviewing the shared memory implementation and still having problems:
1-The first thing I implemented was to define the address space to share memory between applications
users would be 0x80000000 - 0xA0000000 (512MB). Each application asks the kernel for the memory size to share
and the kernel creates it in its shared memory structure (process pid, key, ...), another process knowing the key can
request the kernel to use this memory, the kernel only adds to the page directory of the requesting process, the same
physical addresses of the process that shares the virtual addresses of the same.

Problems:
1- I am working with the GUI and for example if several client applications request shared memory to host the buffer
drawing for the graphical server to access, then this is not possible as they will all get the same initial addresses
From 0x80000000, when the graphical server requests the kernel to obtain this address, it is overwritten in each process.
The other thing that I thought is the graphical server who asks for the shared memory and sends this zone to the client so that the client
I linked it to the drawing buffer, but I find it somewhat problematic because if you change the size of the buffer and consequently
the size of shared memory for a specific client is necessary to restructure the shared memory of the server.

2- The other thing is to make the kernel carry a shared memory management similar to a bitmap where the memory is counted
shared, and is assigned according to the amount requested.
That is, if a process A starts requesting 2 pages, of 4K, it will be assigned from 0x80000000 - 0x80001FFF
If another Process B requests 4 pages, of 4K it will be assigned 0x80001FFF - 0x80003FFF
This solution would have to create a shared memory manager that is capable of removing spaces, look for spaces if there are
available that are less than those requested to assign it, but you have to create it at the end, and several other things that would complicate
the layout in the kernel of shared memory.

I need some suggestion or another form of implementation, because it may be doing something wrong?
User avatar
BenLunt
Member
Member
Posts: 941
Joined: Sat Nov 22, 2014 6:33 pm
Location: USA
Contact:

Re: How to make the GUI of my OS?

Post by BenLunt »

I won't comment on shared memory because I haven't done a whole lot from a user app <--> kernel aspect. However, I will comment on the GUI part.

In my opinion, the GUI, especially the drawing buffer, *should not* be shared at all. The user app should not even know about or have any idea about the memory used for the display driver.

For example, let's talk about a simple dialog window. The user app only gets to know the fact that there will be a dialog displayed, but will not have any control or idea of how, what color, what shape, or any other aspect other than there will be a window drawn with certain items within the window. Period. If the dialog contains a button, it will have the shape, color, and style the GUI interface gives it. Not the User app. The User app will only know that there is a button and will receive messages when that button is pressed and released.

The user app will have the system's GUI interface do all of the drawing, moving, sizing, shadows, buttons, minimizing, maximizing, etc. The User app doesn't handle any of that. The User app can send a message to the GUI interface to minimize, resize, change the color, etc., but the User app has no control of the memory used to display the dialog.

Therefore, all drawing is done via the system's GUI interface. To the GUI interface, the User app is simply an object. To the User App the GUI interface is simply a service it can call (send messages to) or receive messages.

The User App is a (possibly) perishable object within the GUI interface and nothing more. The GUI interface is a callable service for the User app and nothing more.

Now, if you want to get a more detailed GUI User app that does do specific things, like "Owner Draw" buttons and things of that sort, using the GUI interface, you set a flag stating that the button is owner draw. When it comes time to draw that object (a button in this case) the GUI interface will expect that you have already drawn that button to a specified buffer, the buffer having a specific style. For example, that buffer might be defined as 32-bit pixels, X pixels wide, and Y pixels tall. Then the GUI interface will transform/convert that buffer to the style of buffer it uses and push that to the display buffer. It will then use that buffer as is until you send it a message stating that you have changed the pixels and/or size of that buffer, where as it will retrieve the contents once again.

Another example would be video or at the very least, an animated icon. Your User app will mark the object as "user draw" and draw the current image to a specified buffer, then send a message to the GUI interface that it is ready for drawing to the screen. The GUI interface uses that image until it receives another message from the User app stating it has updated the buffer, where as the GUI interface will grab and use the new image until told otherwise.

The simplest apps will have nothing more than a message handler receiving messages such as button presses/releases, menu item selections, etc. These simple apps will have absolutely no clue what-so-ever of display memory, drawing memory, etc. Nothing.

More sophisticated apps will then use things like "owner draw" buttons and the like to be more involved with the display, but still will remain completely independent of the actual display.

Again, your user apps should not have any idea, clue, or whereabouts of the system's display buffer. It is for the GUI display interface only.

Hope that helps,
Ben
- http://www.fysnet.net/osdesign_book_series.htm
klange
Member
Member
Posts: 679
Joined: Wed Mar 30, 2011 12:31 am
Libera.chat IRC: klange
Discord: klange

Re: How to make the GUI of my OS?

Post by klange »

What Ben describes and has implemented in his own OS is the "old-school" approach to GUI systems. X11 originally worked this, and still supports this functionality (even with its own widget toolkit). It's great for low-memory applications.

Modern desktop operating systems, primarily spurred by the introduction of GPUs with dedicated texture memory, have largely moved to a completely different approach: User applications have their own dedicated graphics memory for windows and can arbitrarily plot pixels into them, usually with some double (or even triple) buffering at play, and then signal the windowing system to refresh them on screen. Mobile OSes have gone even further, usually providing applications with arbitrary number and arrangement of "layers" that are composited together by the windowing system using a GPU.

Unfortunately, I'm writing this reply rather late at night in my timezone, but I'd be happy to write up a detailed explanation of how my own windowing system works after some rest.
mkfree
Member
Member
Posts: 55
Joined: Thu Apr 30, 2020 6:03 am
Libera.chat IRC: mkfree

Re: How to make the GUI of my OS?

Post by mkfree »

Thank you very much BenLunt and klange
I thank you in advance for your time.
klange, I think it would be helpful if you describe your own window system, I know that many of us who consult this forum will appreciate it.
Post Reply