Drawing the Mouse Cursor
-
- Member
- Posts: 1146
- Joined: Sat Mar 01, 2014 2:59 pm
Drawing the Mouse Cursor
Hi!
I've been designing pretty much everything about my operating system from scratch, without reading any tutorials beyond that needed to figure out hardware I/O, but now I'm stuck with something, and I'm wondering how others do this.
Essentially my problem is to do with drawing the mouse cursor. I can draw the cursor, but when it comes to undrawing it before moving it I don't know how to determine what's underneath it. I thought of keeping a small buffer the size of the cursor containing the obscured pixels, but that was going to get difficult if the pixels under the cursor are changed. Short of keeping a separate buffer for every window (which I know can be avoided since X11 without a composting manager can do mouse cursors), I can't seem to understand how to do this.
Any ideas?
Thanks,
onlyonemac
I've been designing pretty much everything about my operating system from scratch, without reading any tutorials beyond that needed to figure out hardware I/O, but now I'm stuck with something, and I'm wondering how others do this.
Essentially my problem is to do with drawing the mouse cursor. I can draw the cursor, but when it comes to undrawing it before moving it I don't know how to determine what's underneath it. I thought of keeping a small buffer the size of the cursor containing the obscured pixels, but that was going to get difficult if the pixels under the cursor are changed. Short of keeping a separate buffer for every window (which I know can be avoided since X11 without a composting manager can do mouse cursors), I can't seem to understand how to do this.
Any ideas?
Thanks,
onlyonemac
When you start writing an OS you do the minimum possible to get the x86 processor in a usable state, then you try to get as far away from it as possible.
Syntax checkup:
Wrong: OS's, IRQ's, zero'ing
Right: OSes, IRQs, zeroing
Syntax checkup:
Wrong: OS's, IRQ's, zero'ing
Right: OSes, IRQs, zeroing
Re: Drawing the Mouse Cursor
I made my mouse pointer out of multiple windows, each of which being just one or just a few pixels large. And then I used the existing window-handling code to draw and redraw the pointer. These tiny mouse pointer windows are always on the top of all other windows and this is reflected in the data structures maintaining the z-order of all the windows.
- max
- Member
- Posts: 616
- Joined: Mon Mar 05, 2012 11:23 am
- Libera.chat IRC: maxdev
- Location: Germany
- Contact:
Re: Drawing the Mouse Cursor
Im currently writing my window manager too, so Im facing the same issues
I cant tell you if its all correct, but this is how I do it:
The desktop and all windows have their own buffer. When the screen is painted for the first time, all the window buffers are copied to the desktop buffer, which is the copied to the graphics frame buffer. When something changes somewhere, the area on the desktop or the area on the corresponding window that has changed is marked as "dirty". Then when the screen is painted again, only the dirty areas are copied to the desktop buffer again, and then the sum area of all dirty areas on the desktop buffer is copied to the graphics frame buffer. A cursor is then treated as any other window.
I cant tell you if its all correct, but this is how I do it:
The desktop and all windows have their own buffer. When the screen is painted for the first time, all the window buffers are copied to the desktop buffer, which is the copied to the graphics frame buffer. When something changes somewhere, the area on the desktop or the area on the corresponding window that has changed is marked as "dirty". Then when the screen is painted again, only the dirty areas are copied to the desktop buffer again, and then the sum area of all dirty areas on the desktop buffer is copied to the graphics frame buffer. A cursor is then treated as any other window.
Re: Drawing the Mouse Cursor
Note that if you have hardware support, some video cards allow a transparent small overlay on the framebuffer. You can put the mouse pointer here and simply move that overlay around - this will move the mouse around very cheaply without needing to redraw anything.
The modern solution is just to render the mouse like another partially transparent window, where you just redraw the damage rects when stuff moves - the window manager remembers the contents of each window so it can redraw without roundtrips. Your alternate method of remembering what you obscure can work, too - if paired with proper cache invalidation, when a window redraws while the mouse hovers above it, for instance.
The modern solution is just to render the mouse like another partially transparent window, where you just redraw the damage rects when stuff moves - the window manager remembers the contents of each window so it can redraw without roundtrips. Your alternate method of remembering what you obscure can work, too - if paired with proper cache invalidation, when a window redraws while the mouse hovers above it, for instance.
Re: Drawing the Mouse Cursor
Treating the cursor as a window (or even worse, multiple windows) sounds slow. I keep a copy of the pixels that are underneath the cursor. When a window is updated or moved and it overlaps with the cursor, the cursor is automatically hidden.
Re: Drawing the Mouse Cursor
So, you prefer to steal it from the user?Gigasoft wrote:Treating the cursor as a window (or even worse, multiple windows) sounds slow. I keep a copy of the pixels that are underneath the cursor. When a window is updated or moved and it overlaps with the cursor, the cursor is automatically hidden.
Slow or not really depends on how you implement window (re)drawing. If you redraw too much, enough to be noticeable when the mouse moves around, you have a real problem in the plain sight, because then if you drag a quarter-screen-sized window, you'll see what is really slow. If you redraw just a hundred of pixels, it's not a big deal, whether or not they represent minuscule windows or just a single small one.
- AndrewAPrice
- Member
- Posts: 2303
- Joined: Mon Jun 05, 2006 11:00 pm
- Location: USA (and Australia)
Re: Drawing the Mouse Cursor
Either double buffer or redraw the windows (the windows themselves may double buffer to avoid flickering updates). Do you double buffer your window manager when windows overlap? If so, just redraw the buffer on vsync then draw your mouse.
Alternatively, a fast single buffering approach may be to just to invert the pixels where the mouse is, and when you move your cursor remember to invert the old pixels back.
Alternatively, a fast single buffering approach may be to just to invert the pixels where the mouse is, and when you move your cursor remember to invert the old pixels back.
My OS is Perception.
Re: Drawing the Mouse Cursor
i take this approach actually.it's cool, fast and awesome!MessiahAndrw wrote: Alternatively, a fast single buffering approach may be to just to invert the pixels where the mouse is, and when you move your cursor remember to invert the old pixels back.
remember this :A xor B xor B=A xor 0=A and you will see your mouse color changing when you do a cursor moving.
Re: Drawing the Mouse Cursor
Hi,
Cheers,
Brendan
Minecraft does this when drawing cross-hairs in the middle of the screen. If you're looking at something grey, then the underlying grey gets inverted to grey and the cross-hairs are invisible (!).Shaun wrote:i take this approach actually.it's cool, fast and awesome!MessiahAndrw wrote: Alternatively, a fast single buffering approach may be to just to invert the pixels where the mouse is, and when you move your cursor remember to invert the old pixels back.
remember this :A xor B xor B=A xor 0=A and you will see your mouse color changing when you do a cursor moving.
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.
Re: Drawing the Mouse Cursor
Brendan wrote:Hi,
Minecraft does this when drawing cross-hairs in the middle of the screen. If you're looking at something grey, then the underlying grey gets inverted to grey and the cross-hairs are invisible (!).Shaun wrote:i take this approach actually.it's cool, fast and awesome!MessiahAndrw wrote: Alternatively, a fast single buffering approach may be to just to invert the pixels where the mouse is, and when you move your cursor remember to invert the old pixels back.
remember this :A xor B xor B=A xor 0=A and you will see your mouse color changing when you do a cursor moving.
Cheers,
Brendan
here is a video of my os gfx test show.
take a little bit care of the mouse color and it 's changing when you do a moving.
https://www.youtube.com/watch?v=Y95iuVXSAMk
http://v.youku.com/v_show/id_XNzE2OTA4NDg0.html
-
- Member
- Posts: 1146
- Joined: Sat Mar 01, 2014 2:59 pm
Re: Drawing the Mouse Cursor
I've got a single buffer for each window, so currently I'm just using that to redraw the exposed window areas.
As explained in the first post, that's no good if the pixels under the cursor get changed.MessiahAndrw wrote:Alternatively, a fast single buffering approach may be to just to invert the pixels where the mouse is, and when you move your cursor remember to invert the old pixels back.
When you start writing an OS you do the minimum possible to get the x86 processor in a usable state, then you try to get as far away from it as possible.
Syntax checkup:
Wrong: OS's, IRQ's, zero'ing
Right: OSes, IRQs, zeroing
Syntax checkup:
Wrong: OS's, IRQ's, zero'ing
Right: OSes, IRQs, zeroing
- Combuster
- Member
- Posts: 9301
- Joined: Wed Oct 18, 2006 3:45 am
- Libera.chat IRC: [com]buster
- Location: On the balcony, where I can actually keep 1½m distance
- Contact:
Re: Drawing the Mouse Cursor
It's good enough to "undo" the cursor if other drawing happens to intersect it, no?
- Love4Boobies
- Member
- Posts: 2111
- Joined: Fri Mar 07, 2008 5:36 pm
- Location: Bucharest, Romania
Re: Drawing the Mouse Cursor
I'm not sure what window managers should have to do with drawing the cursor. It seems to me that the best place for this functionality is the video driver. If the hardware supports accelerated cursors, good. If not, it can just provide a software implementation (using one of the techniques described in this thread, perhaps). This will result in a uniform interface and modular implementations.
"Computers in the future may weigh no more than 1.5 tons.", Popular Mechanics (1949)
[ Project UDI ]
[ Project UDI ]
Re: Drawing the Mouse Cursor
Old versions of Windows (and possibly modern versions under certain circumstances) used to do something like this:
- Before drawing the cursor, save the pixels from the cursor's bounding rectangle in an off-screen buffer.
- Draw the cursor.
- When the cursor moves, blit the saved pixels back into place and repeat the process at the new location.
- If an application draws into the space occupied by the cursor, temporarily hide the cursor (by blitting the saved pixels), do the drawing operation and then restore the cursor.
- Love4Boobies
- Member
- Posts: 2111
- Joined: Fri Mar 07, 2008 5:36 pm
- Location: Bucharest, Romania
Re: Drawing the Mouse Cursor
The only two sane options are really:
The XOR mask thing, as described above, is just a trick to overlap the front and background buffers in order to save the bit of memory required for storing the background separately, at the expense of performance and artistic options. It has nothing to do with the problem of updating the background (you still need to hide the cursor or to update the mask, which are basically the two general approaches, as discussed in this thread). However, the invisibility problem referenced by Brendan applies only if the mask has a uniform "color," which would be a problem for any cursor.
- Relying on the back buffer to keep track of the background.
- Keeping and updating a small buffer describing the background.
The XOR mask thing, as described above, is just a trick to overlap the front and background buffers in order to save the bit of memory required for storing the background separately, at the expense of performance and artistic options. It has nothing to do with the problem of updating the background (you still need to hide the cursor or to update the mask, which are basically the two general approaches, as discussed in this thread). However, the invisibility problem referenced by Brendan applies only if the mask has a uniform "color," which would be a problem for any cursor.
"Computers in the future may weigh no more than 1.5 tons.", Popular Mechanics (1949)
[ Project UDI ]
[ Project UDI ]