OSDev.org

The Place to Start for Operating System Developers
It is currently Thu Mar 28, 2024 3:03 pm

All times are UTC - 6 hours




Post new topic Reply to topic  [ 8 posts ] 
Author Message
 Post subject: How to make a super simple GUI
PostPosted: Wed Mar 01, 2017 9:34 pm 
Offline

Joined: Fri Feb 24, 2017 6:51 pm
Posts: 10
I have setup a simple kernel and shell, but now I want to make a (super) simple GUI. I have been searching, but I have not found any examples I can build off of/test. Can someone send a simple GUI example script (in C) that maybe just draws a background and rectangle on the screen. If some code that is needed is not included in your reply let me know what I need to add.


Top
 Profile  
 
 Post subject: Re: How to make a super simple GUI
PostPosted: Thu Mar 02, 2017 1:23 am 
Offline
Member
Member
User avatar

Joined: Sun Nov 20, 2016 7:26 am
Posts: 155
Location: Somewhere
Firstly, you need to set a graphics mode indeed.

I assume you're in protected mode, so you have to program VGA controllers to set a mode, like 640x480x4.
http://wiki.osdev.org/VGA_Resources has really great examples.

If you want to have SVGA, you have two options, use VBE or write native drivers.

VBE uses BIOS interrupt 0x10 function 0x4FXX, so it only works in real mode. Instead you can use PMID from VBE3, but it isn't supported very much, as it was an optional feature to implement in graphics cards.

If you want to use BIOS interrupts you have a few options.

Drop to real mode, do the interrupt and return back to protected mode. But it is an ugly solution, also you will need reprogram PICs.

Use Virtual 8086 mode. This is a bit hard to implement, and only works in protected mode, no long mode support.
wiki.osdev.org has neat two pages for it:
http://wiki.osdev.org/Virtual_8086_Mode and http://wiki.osdev.org/Virtual_Monitor

Use an emulator like libx86emu to emulate BIOS code in protected mode, but redirect the port and memory input / outputs to real hardware, then the devices won't know the difference. This is the method I'm using, in this thread: viewtopic.php?f=1&t=31388

After setting a graphics mode, you need to plot pixels on it.

VGA modes have indexed color system, if you want to change palette you can reprogram DAC.

If you set a planar mode like 640x480x4, your buffers are four bitmaps, for each bits of index. For example if you want to plot the first pixel with palette index 2:
-> Switch to first plane, set first bit on plane to 1.
-> Switch to second plane, set first bit on plane to 1.
-> Switch to third plane, set first bit on plane to 0.
-> Switch to fourth plane, set first bit on plane to 0.

0b0011 is 2, so first pixel with be palette index 2.

If you set a linear mode like 320x200x8 then everything is much easier.
You have a linear frame buffer, if you want to plot first pixel with palette index 210, just do:

Code:
uint8_t* vgamem = (uint8_t*) 0xA0000;
vgamem[0] = 210;


If you set a VBE mode with LFB, you have to get the LFB address from mode info block, then you can plot pixels easily. And there is no indexed color mode in VBE.
If you set a mode like 800x600x24, and if you want to set first pixel with a RGB of 255,210,20:

Code:
uint8_t* lfb = (uint8_t*) mode_info->lfb_address;
lfb[0] = 20; // (Blue)
lfb[1] = 210; // (Green)
lfb[2] = 255; // (Red)


is enough.

http://wiki.osdev.org/Drawing_In_Protected_Mode has neat "example codes" for plotting pixels, drawing rectangles etc.

Cheers.

_________________
Keyboard not found!

Press F1 to run setup.
Press F2 to continue.


Top
 Profile  
 
 Post subject: Re: How to make a super simple GUI
PostPosted: Thu Mar 02, 2017 4:55 pm 
Offline

Joined: Fri Feb 24, 2017 6:51 pm
Posts: 10
Agola wrote:
~snip~

If you set a linear mode like 320x200x8 then everything is much easier.
You have a linear frame buffer, if you want to plot first pixel with palette index 210, just do:

Code:
uint8_t* vgamem = (uint8_t*) 0xA0000;
vgamem[0] = 210;


~snip~

http://wiki.osdev.org/Drawing_In_Protected_Mode has neat "example codes" for plotting pixels, drawing rectangles etc.

Cheers.

How can I set 320x200x8 mode?


Top
 Profile  
 
 Post subject: Re: How to make a super simple GUI
PostPosted: Thu Mar 02, 2017 7:57 pm 
Offline
Member
Member
User avatar

Joined: Sat Jan 15, 2005 12:00 am
Posts: 8561
Location: At his keyboard!
Hi,

HittmanA wrote:
How can I set 320x200x8 mode?


To set 320x200x8 mode you'd need to be in real mode and use the Set Video Mode BIOS function (with "AX = 0x0013" to select 320x200x8 mode).

Note that for 320x200x8 the values you write to display memory are an index into a kind of colour lookup table (e.g. the value 0x00 is whatever colour is in the lookup table for entry number zero). The default lookup table is an annoying mess where colours are split into bands (e.g. the first 16 colours is CGA compatible colours, then next 16 colours is a grey scale from black to white, etc). For this reason you will probably want to change the lookup table using this BIOS function after setting the video mode.

I normally configure it so that the lowest 2 bits of the value determines how much blue, then next 3 bits determine how much green, and the highest 3 bits determine how much red. This makes it much easier to work with for various purposes (and easier to have a generic colour format like 32-bpp that is used by all the drawing code that is converted to whatever any specific video mode wanted, so that its easier to support many different video modes later).

It is also possible to configure that lookup table dynamically to get far better graphics quality. In this case; your code would analyse a frame and determine the best possible colours/lookup table for that frame, then convert the pixel's values to suit that and configure the lookup table and blit the frame to display memory. This gives much better graphics quality because the lookup table has 32768 colours to choose from; but is complicated (it's hard to determine the best colours) and slower, and causes either a potentially unwanted (after of boot) dependency on the BIOS (e.g. excessively difficult to make the OS work for UEFI later on by just writing a different boot loader because that would break your graphics) or a potentially unwanted dependency on "100% VGA compatible video hardware with no quirks (that always end up biting you because hardware is never quite perfect)" if you attempt to do it without using the BIOS. There is also a race condition (if you don't/can't use vertical sync); because you can't change the lookup table and change the pixel values at the same time and that means there's a chance of "old pixels with new/different colours" being visible on the screen briefly. To avoid that you can can split the lookup table in half and alternate (use values 0x00 to 0x7F for one frame, then values 0x80 to 0xFF for the next frame), but that reduces you to "128 simultaneous colours (out of 32768 possible colours) per frame".

The other thing that you should probably do is check that a video card exists (and that it's at least capable of pretending it's "VGA compatible with colour monitor") by using this BIOS function. For computers that have no video card at all, at a minimum (if you have no intention of supporting this case) you should (e.g.) make the PC speaker beep to inform the user that the computer isn't supported by the OS. Of course you could also boot and provide alternatives (supporting "dumb terminal", or maybe using a networking protocol like X11, RDP, ...) or design the OS to be useful without any user interface of at all (e.g. configured by the user to work like a NAS).

Also don't forget that a GUI should depend on lower level abstractions, so that the majority of the GUI (and the apps using the GUI) don't care if the "back end" is VGA or modern video hardware or a network protocol or ... For the same reason, it shouldn't hard to support VBE (and support high resolution video modes with millions of colours, etc).


Cheers,

Brendan

_________________
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.


Top
 Profile  
 
 Post subject: Re: How to make a super simple GUI
PostPosted: Fri Mar 03, 2017 5:30 pm 
Offline
Member
Member

Joined: Thu May 19, 2011 5:13 am
Posts: 228
Agola wrote:
If you want to use BIOS interrupts you have a few options.
Drop to real mode, do the interrupt and return back to protected mode. But it is an ugly solution, ...
Ugly is in the eye of the programmer.
Agola wrote:
... also you will need reprogram PICs.
Not only do you not need to reprogram the PIC's, but you do not need to disable the A20 line, nor do you even need to back out of big real mode.
You do however require a mode transition driver to manager things properly.

_________________
Mike Gonta
look and see - many look but few see

https://mikegonta.com


Top
 Profile  
 
 Post subject: Re: How to make a super simple GUI
PostPosted: Fri Mar 03, 2017 8:58 pm 
Offline
Member
Member
User avatar

Joined: Sat Jan 15, 2005 12:00 am
Posts: 8561
Location: At his keyboard!
Hi,

mikegonta wrote:
Agola wrote:
If you want to use BIOS interrupts you have a few options.
Drop to real mode, do the interrupt and return back to protected mode. But it is an ugly solution, ...
Ugly is in the eye of the programmer.
Agola wrote:
... also you will need reprogram PICs.
Not only do you not need to reprogram the PIC's, but you do not need to disable the A20 line, nor do you even need to back out of big real mode.
You do however require a mode transition driver to manager things properly.


It also depends on "where". Within a boot loader designed for BIOS (e.g. while the BIOS is still in control of all hardware, etc) using BIOS is usually the cleanest and best way.

However; assuming its an OS from this century (which we must, given that the original poster is asking these questions now and not in 1990); for all other cases (all code that runs after boot, and code in boot loaders designed for UEFI or any other "not BIOS" environment) using BIOS for anything is "ugly in the eyes of all competent programmers".


Cheers,

Brendan

_________________
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.


Top
 Profile  
 
 Post subject: Re: How to make a super simple GUI
PostPosted: Fri Mar 03, 2017 10:12 pm 
Offline

Joined: Fri Feb 24, 2017 6:51 pm
Posts: 10
Brendan wrote:
Hi,

mikegonta wrote:
Agola wrote:
If you want to use BIOS interrupts you have a few options.
Drop to real mode, do the interrupt and return back to protected mode. But it is an ugly solution, ...
Ugly is in the eye of the programmer.
Agola wrote:
... also you will need reprogram PICs.
Not only do you not need to reprogram the PIC's, but you do not need to disable the A20 line, nor do you even need to back out of big real mode.
You do however require a mode transition driver to manager things properly.


It also depends on "where". Within a boot loader designed for BIOS (e.g. while the BIOS is still in control of all hardware, etc) using BIOS is usually the cleanest and best way.

However; assuming its an OS from this century (which we must, given that the original poster is asking these questions now and not in 1990); for all other cases (all code that runs after boot, and code in boot loaders designed for UEFI or any other "not BIOS" environment) using BIOS for anything is "ugly in the eyes of all competent programmers".


Cheers,

Brendan



Ok (I am definitely a newbie), I have been trying and can't even seem to plot a pixel. Is there some very simple code (e.g. just all the necessary barebones C and assembly code) to plot *one* simple pixel in the color red. If I can get that code I will be able to continue. Thanks in advance!


Top
 Profile  
 
 Post subject: Re: How to make a super simple GUI
PostPosted: Sat Mar 04, 2017 1:06 am 
Offline
Member
Member
User avatar

Joined: Sat Jan 15, 2005 12:00 am
Posts: 8561
Location: At his keyboard!
Hi,

HittmanA wrote:
Ok (I am definitely a newbie), I have been trying and can't even seem to plot a pixel. Is there some very simple code (e.g. just all the necessary barebones C and assembly code) to plot *one* simple pixel in the color red. If I can get that code I will be able to continue. Thanks in advance!


Simple code that works in the environment created by the barebones tutorial can't exist, because the tutorial assumes that the video mode was set to "text mode" by GRUB.

You either need to:
  • Modify it so that GRUB sets up 320x200x8 for you; recognising that GRUB may be an old version that doesn't support this at all, and won't setup that "colour lookup table" I mentioned, and may potentially choose to ignore you and give you something else instead. This is also relatively silly given that it's just as easy to ask GRUB for something like (e.g.) 1024x768x32 and get much better graphics with less hassle (no need for "index into colour lookup table" indirection).
  • Have code to switch back to real mode, setup the video mode yourself, then switch back to protected mode. This is messy/complicated (not just the mode switching, but fighting with linker, etc to ensure the "real mode code" is at an address that can work in real mode), and gets significantly worse if you try to do it after boot (rather than near the start of your kernel initialisation) and/or if you ever want to support (or learn how to support) modern computers.
  • Have "native video driver" code that either makes potentially bad assumptions (because it requires "100% VGA compatible at the hardware level") or is not generic (e.g. different code for different video cards).

Basically; depending on how you feel like switching the video mode to 320x200x8 there's a different set of complications that you need to deal with.

Once you have switched to the 320x200x8 video mode, drawing a red dot is potentially easy (e.g. just write the value that corresponds to "red" in the colour lookup table to the address "base + y*320 + x").

Note that if the only code you have is copied from the barebones tutorial; then your OS is nowhere near the stage where starting to add any kind of GUI (simple, or not) makes any sense. What you should be doing is "basic functionality that everything else depends on" (like virtual memory management, scheduling, IPC, designing device driver interfaces, file systems, etc). Without these things, it's like icing a cake that hasn't been baked yet - it's just going to be a waste of time creating a useless sticky mess (that won't even help you learn how to do it properly).


Cheers,

Brendan

_________________
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 8 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: Bing [Bot], Majestic-12 [Bot], mrjbom and 66 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group