James T. Klik
Look through the window ... See that background with alpha-blending and my anti-aliased fonts? See the corner of the screen? That's Klik's Start Menu! Hmm, no. I have no 'programs' folder, as I can't load 'programs' for now, but here's a 16-items list of test cases for my WidgetToolKit. Or maybe you prefer a different style.
Reaching Klik's level
Step 1: Documenting on video
- Read about VGA Resources and GRUB. You have the opportunity to let the bootloader switch to graphical mode for you before your kernel is started. A color depth of 32 will avoid you further headaches. Documents about Accelerated Graphic Cards are gifts from the gods for Klik, but they're rare.
- Develop (or reuse) a small library to draw lines, fill areas, copy bitmaps and draw text out of your kernel, debug it, then integrate it in your OS.
- Find a friend to make a neat logo, ask GRUB to load it as if it was a module, memcpy it to screen and voilà. You can release 0.1
Note that you'll need inline assembly functions like everybody else, and that you'll probably prefer to have a "sprintf" than a "printf" function.
Step 2: Getting input
- Document about mouse control. Try to imagine a clean way of getting mouse clicks, position, events like drags, drops, slides, etc. A common engineering technique for this is the time-travelling-camera: move yourself in the future and imagine the user, then come back and draw on paper what you've seen.
- Grab a game developing tutorial about sprites, and see how you can have a moving object like a cursor. The trick is that you have to keep a small snapshot of what was under the cursor so that you can erase the cursor when it moves.
- Connect your cursor to your mouse and voilà. See it moving. By the same time, develop a small control widget that will report coordinates and events names (MouseDown, MouseOver, etc).
Step 3: Populating your screen
It is time to draw small windows on screen. We had many discussion in the forum about how they can be moved efficiently and so on. Note that you'll really start to need a way of allocating and freeing memory at this point, as you do not want to assume that there's a maximum of N buttons in the system ...
- Collect tutorials about GUI programming, including GUI Programming at BonaFide.
- Create a class that will be responsible for receiving event from the system, including the "repaint" event.
- If you want 'windows', let there be a window manager that send them 'repaint' events when needed, handle window displacement and is in charge of "what's behind the window".
- make sure you can add content to your window, and that you don't need to write a specific "repaint" function for each new content. Most WMs allow a window to be a container of widgets.
Outrunning James T. Klik
Have programs loaded in memory
And provide a filesystem-approach to access them. It can be very easy if you use GRUB modules to map programs in memory: you just need to create a virtual directory service that will remember at which physical memory address the image of FILE.COM is located and return that address when we do open("file.com").
Have user-level programs executed when requested
The easiest approach is to create a segment for the user's code and one for its data. Then return to the program. You can even not worry about multitasking and decide every kernel operation will occur when an interrupt arise (that's how DOS works), but you will at least have 1a. implement interrupts support and 1b. implement basic segmentation support. If you're fine with asm, load asm programs as a first step.
Have the kernel access hardware
It should at least be able to receive the keyboard data (and translate them), setup video display and read mouse events. The most simple GUI at kernel level would be get_video_segment(), set_mouse_buffer(), set_keyb_buffer(). The kernel should know then where it should put data. You can even protect your "start menu" from the user application by excluding the last lines of the display from the "video segment" you return to the application.
Required steps are 2a. video driver (get a frame buffer), 2b. mouse driver (have a cursor moving on screen) and 2c. keyboard reader (have keystrokes translated and written to some memory area).
Read available programs from the virtual file system and build up the list of "start menu" with it. Ideally, this should be done by some programs external to the kernel, but let's say you do it in the kernel (at initialization) for now.
When the start menu is clicked, popup the list. When an item is selected, start the application and freeze the currently running one. When the task bar is clicked, unfreeze the selected application. When the "user area" is clicked, defer the click to the application (send it an event).
This requires 3a. Process control: select which program is currently running and 3b. Process sleep & wakeup: let the application decide that it have nothing to do but waiting something to happen and let the kernel return to the application only when something occurred.
Note that this will only offer you something like Mac OS 1.0 and that you'll certainly find yourself in troubles as soon as you'll try to add something like modular design, networking or multitasking...
Jumping right into graphics is frowned upon by many authors, and consequently he owns very few books on the subject. However, he does find some books like "Operating Systems Design and Implementation" by Andy Tanenbaum interesting for some of the "prerequisites" of GUIs, like multitasking. Yet he did find some good documentation on the graphics systems, such as "Fundamentals of Interactive Computer Graphics" by James Foley useful. And he has printed copies of all of VESA's VBE standards.
James T. Klik opponents' position
If you're wondering how you'll implement the 'start button' and its menu right from the start, you're probably getting things by the wrong end... When you want to make a word processing program, you don't ask yourself how you will have icons for "save", "print", etc. in a bar that you can move across your window. You first ask yourself how you will represent text, how you will implement basic operations like extracting text from one paragraph and put text into another one, how you will deal with embedded objects like pictures, etc. or how you will store your text efficiently on a file. Basically, you'll work yourself like that slow horse in the pack if you don't have a good kernel with a different approach up first.
Also, many proponents of protected mode find VESA unattractive, since you need some sort of hook into the BIOS.