hello and welcome to the 14th part of
the tutorial on writing your own
operating system yeah in the last video
we didn't finish the GUI framework so we
we didn't implement the desktop and the
window class yeah we will do this now
and yeah funny thing in the last video
at the end of the last video I compiled
the code and it compiled fine so I was
happy
and then later I realized wait a minute
why did it compile I didn't implement
the contains coordinate method for the
for the widget class so it shouldn't
have compiled and then I realized ok
here in the in the make file I didn't
put the objects for for the desktop
widget and window class they are so
that's the reason why these codes
weren't even compiled into the binary
yeah so not much to talk about
beforehand everything has been discussed
already in the last video so we can just
jump right back in ok ok so I will put
these object files also here
okay now when we come here we will get
less good X results
so here we we get errors now
specifically we didn't write the
contains coordinate method so I will do
that but the first thing the first error
it reports is this here in the common
graphics context as a is the wrong way
around
okay and now let's implement the
contains coordinate method we will do
this in a quite simpler way we'll just
check if this x and y are larger than
the x and y coordinates of of the
Whichard and smaller than the
coordinates plus width or height
respectively so okay yeah it's important
to notice I mean this X and this Y they
are relative coordinates but this still
works because down here in the composite
widget
here we we turned the the coordinates
that we get into into relative
coordinates also okay so the things that
we passed down here also relative
coordinates okay one thing I thought
about this code here is a bit ugly
because yeah we only call onmousemove
either once or twice depending but
depending on whether the the first and
the second one is the same I think more
elegant way would be to to check if they
are the same and if they are the same
you call onmousemove
and otherwise you call something like on
mouse leaf on the first Richard and on
Mouse então on the second Richard so I
mean that's common practice in GUI
frameworks but I'm gonna leave it like
this you can figure that out for
yourself if you want to okay one thing
that I have noticed is in the mouse
drive up here when when we when we sent
this one mouse move it kind of baffles
me because with the mouse cursor in the
text mode this worked but when I went
through the code beforehand I noticed
that this doesn't work strangely for the
desktops
I will just cast this to int before
passing these to the to the event
handler okay now the next thing I think
it would be a good idea if we would
derive the widget class from keyboard
event handler you know so that we don't
have to to write these on key down and
onkeyup explicitly we can just inherit
them from keyboard driver and then we
can just attach widget directly to the
keyboard okay and we will we will
actually attach the desktop directly to
the keyboard so we can just remove this
and then we have to include the head of
course okay so the keyboard event
handler on keydown and keyup just get
character so down here I mean X&Y was
nonsense anyway so
okay and I also want to derive composite
widgets from Mouse event handlers
actually no I'm not going to derive
composite widget from that I'm going to
derive the desktop from it the mouse
down here and pass up I will give them
an additional parameter they will get
also the other button that has been
pressed so
why I haven't implemented I haven't
declared the methods contains
co-ordinate
okay and we can remove these methods
because we do we inherit them from the
keyboard event handler but the one down
here yeah for the composite widget we we
overwrite them so that a composite
widget like the desktop can pass the key
strike to the focus try it okay okay and
the composite widgets also needs
something like yeah a method to add a
child because the children are private
and you shouldn't access it from outside
anyway so
makes it would instead so if we already
have as many children as we can then we
were just returned false okay so this
isn't exactly a threat safe but whatever
right now everything is synchronous
still anyways
okay now let's see if this compiles
drama secure graphics context us in the
namespace comment so that makes sense
okay the mouse down and on mouse I gave
them this additional button parameter of
course I also have to do that in the CPP
file and in the derived class
it's to Carter Bays constructor
okay now it compares again okay before I
continue I will I will add a few more
colors to the VGA driver and also this
is commands were wrong so Kara one is
zero is black
that's green father's rent and color 3f
is white
okay so now let's start writing the
desktop and window classes so the
desktop of course is a composite we do
it because it has windows on it and the
desktop will also be derived from Mouse
event handler
okay so the desktop will basically just
just work like the composite widget so
we don't actually have to do much here
but we will have to override the methods
from the mouse event handler to
translate the mouse movements because
from the mouse we only get relative
movements and so the desktop will will
turn these relative movements into
absolute positions of the mouse okay so
so the desktop will get mouse
coordinates although I have read that
it's apparently not a good idea to
hard-code
a mouse into the desktop for example
because of tablets you know the tablet
doesn't have a mouse cursor so but
anyways I will do this this way now
so for the desktop we only need the
width height actually width and height
could also be unsigned integers but
whatever and it will also get a color
so the desktop will be responsible for
drawing the mouse so we have to
overwrite the drawing of them desktop
and as I've set the events for other
mouse even event handler
okay
okay so the desktop constructor will go
to the base constructor like this so I'm
assuming here that there's only a
top-level desktop okay so the so it will
not have a parent so this is 0 it will
have x and y-coordinates 0 because it's
supposed to start in the upper left
corner I mean yeah you could do this
actually you could do it so that you can
pass other parameters here because I
think using a desktop as as a child for
maybe a window for example would be
probably a good idea if you wanted to do
something like multi document interface
the MD I form parent that you possibly
know from Windows you know where you can
have a window which has child windows in
them ok so then it would make sense to
to have a desktop which has a parent and
something else then 0 for x and y in x
but i will do it like this here
and I will initialize X with ya actually
with just the width of the screen
/ - so that it's centered okay so the
initially Mouse position was the center
of the screen
okay the onmousedown and unmask move and
unmask up are also relatively simple
some mouse down and mouse up basically
just called the event handler for the
other so i mean this is a mouse event
handler onmousedown right it just has a
button as parameters this is what the
mouse calls so if if the most does
something this is called and this
translates it to the widget form where
you get where you get the mouse position
and the button but this is really simple
we just have to pass the the current
mouse position mouse X and Mouse Y
together with a button to the other
handler so this is all we have to do for
Mouse down
then the mouse move is a bit more
complicated because we made we need to
make sure that that the mouse stays
inside inside the the screen so that's
not hard
okay and then when we call the event
handler so which would event enter and
then with two other new values back in
the coordinates
and here at the beginning I will just
divide the relative movement by four
because it's relatively fast okay
so how do we draw the desktop now well
most of what we need is already
implemented in the composite widget so
we look just called parents though and
after this is drawn so after the screen
has been drawn we put the mouse cursor
in and I will make the mouse cursor a
little white cross okay
okay but now we have a little problem
I'll just show you the problem
so now I've instantiated the desktop I
think that's kind of funny yet don't you
think it's talking about I instantiate
the desktop but okay that's what I'm
doing here so of another strange way of
saying something is if you comment this
out I think it's also hilarious to say I
have commented out the desktop something
that I've said some day and I was really
I found that quite funny okay yes I mean
that so let's see this compiles
yeah okay wait right now okay we have
the desktop now you see we have a mouse
cursor right now that it doesn't react
to the mouse because yeah we haven't
attached the desktop to the mouse yet so
I would just instantiate that desktop up
here
okay now I have attached the mouse to
the desktop and while we are edit we can
also attach the the keyboard to the
desktop okay let's see
this should compile yes okay so now the
mouse is connected to the desktop but if
I move the mouse I still doesn't move
the reason for this is we just draw the
desktop once down here and we don't
update it so I will just put this into
this loop here although I want you when
we go to the multi-threading
multitasking when we stop the
multitasking this loop will never be
executed anymore
once we start tasks so this isn't a
really good idea to put it here but for
now it will work and also we should we
should activate the interrupts really
activating the interrupts which should
really be the last thing we do and
that's also why we shouldn't do it like
this because yeah this is after we
activate it to interrupts so it's really
not a good idea to draw to redraw the
desktop inside this loop
we'll keep it like this for now okay now
you see that screen is flickering a bit
I think that's okay and now I can move
the mouse and yeah the mouse is now
really gone so it's if you look closely
I don't know if you can see it in the
video but it's flickering a problem that
we have is that we are calling the put
pixel method for the VGA and the put
pixel is really it doesn't care whether
you whether the coordinates are legal
right now and so far we have only passed
legal coordinates but when we move the
mouse we cannot be sure that the
coordinates where you move them for
example if this is the screen and you
move the mouse here to the right of the
screen then we try to draw the cross and
it's over it goes beyond the screen and
that's not really what we want because
then these pixels will just be drawn in
in the next line so we will just put
some some security here
okay these are unsigned integers so X
smaller than zero is impossible why are
they unsigned actually I mean might be a
bad idea so the scripts potentially be
cause problems when we cast unsigned -
when we say when we cast signed integers
- unsigned
okay now this make sure the coordinates
are legal
okay I still get the strange error that
I've talked about
okay so what have I done I casted this
two into 8t now so strange behavior
whatever so you see the screen is
flickering a bit but now I can move the
mouse and this is already something I
find quite cool so let's do the window
class now okay so I'm not going to do a
lot with the window I will just make it
able to be dragged around the screen
okay and I will do this in a quite
simpler way so I will just override the
unmask down and on Mouse up to set a
flag which tells us if the the window is
currently dragged and if it is set then
in the unmask move I will just change
the x and y coordinates of the window
okay so yeah initially right we need to
call the base constructor
so initially we will set this flag to
false when the mouse is released it will
also be set to false the onmousedown
will set it to true but only if we are
clicking with the left mouse button
so dragging a set to 1 and in the on
mouse move i will look if it is being
dragged then we will just change the x
and y coordinates come to think of it we
should call the base methods for this of
course because otherwise the widgets
that the windows contained would never
be notified if they are being called
okay listen X if we move it to the right
and a new coordinate - old coordinate is
positive and then we add that okay this
is all I think so let's go to the kana
now let's have a make two windows attach
them to the desktop let's say at
coordinate - 10 10 and with width and
height 20 and let's give it color red
and a second window and let's put that
right next to the other one but maybe a
little bit down so that was going to 13
14 and 15 and let's make it a bit we go
like this but this one I'll make green
okay and the desktop needs to be
notified
okay I don't know how quick you can see
this so the screen is flickering a lot
here but I'll just move the mouse over
here that's a bit unresponsive okay I
will click now and move it down here yes
you can see I can move the window now
okay okay so okay so yeah this is really
all I wanted to do for the graphics mode
I think this is quite nice now we have
we have a desktop we can have windows
and composite objects I mean I think you
can imagine now how to create further
widgets like buttons and text boxes and
radio buttons and checkboxes and all
these yeah so so I'm I don't want to go
any further into this topic but yeah I
think it really sucks that the screen
flickers so much I mean the these
drawing methods are relatively slow I
mean every pixel is set for its own I
think
graphics cards should have methods to to
tell the graphics card to draw a
rectangle on its own so then you would
just need to overwrite a rectangle with
something that calls this method
of the graphics card so then this
rendering would not be so slow anymore
but on the right side of this of this
class hierarchy here everything can stay
the same you know this is really great I
think because widgets composite Richards
desktop window they were all written in
a very in a very abstract way so yeah
you can have a better graphics card
driver if you want to and yeah so a
better graphics card driver will give
you better resolutions maybe and better
performance when you draw but but
everything here everything in the GUI
directory can stay the same so if you
want better graphics better resolutions
faster graphics you just have to change
the driver for the graphics card and but
I'm not going into that and everything
here can stay the same and that's really
nice icing so yeah what else it might be
a good idea to to have methods which
notify objects widgets when they are
focused or unfocused and yeah one one
other thing I mean this whole idea
though the way we did this is actually
quite bad I think this whole redrawing
the screen all the time it's it's really
not a good idea I think the better idea
would be to draw the screen once and
don't redraw it at all so every widget
drawers itself so it is a so it is there
for the time being but a pro a program
or any graphical object should have a
method which says invalidate this area
of the screen okay so the so here's the
screen you draw it with the windows and
you don't redraw it all the time you
just leave it like this and only when
something happens like we move a mouse
and you maybe you have moved the window
now over here so it's now should be like
this then you could just mem copy use
these pixels over here and invalidate
this these two areas of the screen and
invalidation would mean that you put
yeah rectangle objects in a list of
envelops areas and then you only redraw
these invalid areas in although the
moved window is just mem copied the
pixels are just mem copied and the area
that that we have uncovered is
invalidated and then in this loop at the
end of the kernel or later in a task in
an idle task you you would just look do
I have invalid regions if so then I say
I want to to draw this I want to redraw
this region okay and when you do it like
this it's probably also a better idea
not to draw from the back to the front
you know drawing the desktop then the
window that's they are and so on it's a
better idea to to draw from the front to
the back but that's really a lot of
geometry and rectangle intersections and
whatever so that's really a lot of math
behind that but yeah I think I mean
drawing from front to back as a lot of
math but I think if you move the another
window like this and invalidate the
screen and if you redraw the screen only
by by drawing from back to front and all
the widgets react to so the draw method
would also need a rectangle object and
the the widgets would just say okay if I
don't have any intersection with this
rectangle I just don't have to draw
anything I can return immediately and
otherwise I will draw into this
rectangle the part that belongs to me
so so then you can draw from the from
the back to the front and this should
give you a not not a great performance
but a better performance and this
flickering garbage that we have right
now but yeah so this is really all I
wanted to do for the for the graphics
mode yeah one last thing I want to
mention you probably want to be able to
draw to render text to write something
on the screen and in the last video I
showed you this this file with with the
graphics modes no it wasn't the last
video it was the video 12 in this file
and I really have to say this Chris
either big thanks to him that's that's
really a great file and it's great that
it's public domain so we are not
violating any any copyrights or anything
if we do this so
big thanks to him so down here you will
find this bitmap font 8x8 so so here you
this is an a bitmap font with with an 8
by 8 pixel characters and so when you
want to draw an a a is what is it 54 you
just go to the 54th row in there so 8
times 54 is the the bite there is the
last line of of this bitmap font so the
bite at this index in this array
yeah the the bits of this byte are just
the other pixels down here and then the
next one it's a pixels in the next line
at first I thought that this would be
the first line and then this would be
the second line and so on but then I
have when I had the characters Mirat so
yet from from bottom to top
so yeah this really should give you
everything that you need to write your
own desktop and windows and buttons and
text box and so on your text box can get
key strikes you can have the the Mouse
events and the mouse clicking and moving
and all the good stuff so so yes this is
all for the graphics mode
I hope this
so a lot as upset and even just going
into graphics mode you you just don't
find any any good tutorials on the
internet except this one that I've shown
you it's the only correct one that i
found and i remember when i when i went
to the vga programming for the first
time I was really about to quit when I
found this this one good tutorial so
yeah there you have it have fun with
this and tune in next time I think next
time will be also very awesome because
next time we will be doing multitasking
yeah next time we will look into how to
how to have multiple things run in
parallel but for the sake of that I will
basically just uncomment everything that
we did now so that the desktop and VGA
and the drawing and everything I will
put this in an area that I protect with
a with a preprocessor directive like
like this perhaps s I'm commenting out
and so on okay so so then you can just
enable the graphics mode by uncommenting
the define in the beginning and disable
X for this because the stuff that we are
doing next isn't very graphic so so
we'll be dealing with spites again and I
think that that really requires you to
to be working in text mode again so
that's why I'm doing this now
okay so see you next time don't forget
to so don't forget to subscribe so that
you don't miss the next awesome video on
multitasking hit like if you liked the
video and see you next time