7542 - baremetal: support cursor on a grapheme
So far we've drawn a space implicitly at the cursor. Now I allow drawing an arbitrary grapheme when drawing the cursor. But the caller has to specify what to draw. (The alternative would be for layer 103 to track every single grapheme on screen along with its color and any other future attributes, just to be able to paint and unpaint the background for a single character.) I've modified existing helpers for drawing multiple graphemes to always clear the final cursor position after they finish drawing. That seems reasonable for terminal-like applications. Applications that need to control the screen in a more random-access manner will need to track the grapheme at the cursor for themselves.
This commit is contained in:
parent
a51bc7a1e0
commit
1b09418c60
|
@ -104,14 +104,16 @@ $cursor-position-on-real-screen:end:
|
|||
5d/pop-to-ebp
|
||||
c3/return
|
||||
|
||||
set-cursor-position-on-real-screen: # x: int, y: int
|
||||
# Caller is responsible for tracking what was on the screen at this position
|
||||
# before, and making sure the cursor continues to show the same grapheme.
|
||||
set-cursor-position-on-real-screen: # x: int, y: int, g: grapheme
|
||||
# . prologue
|
||||
55/push-ebp
|
||||
89/<- %ebp 4/r32/esp
|
||||
# . save registers
|
||||
50/push-eax
|
||||
#
|
||||
(draw-grapheme-on-real-screen 0x20 *(ebp+8) *(ebp+0xc) 0 7)
|
||||
(draw-grapheme-on-real-screen *(ebp+0x10) *(ebp+8) *(ebp+0xc) 0 7)
|
||||
# TODO: support fake screen; we currently assume 'screen' is always 0 (real)
|
||||
8b/-> *(ebp+8) 0/r32/eax
|
||||
89/<- *Real-screen-cursor-x 0/r32/eax
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
sig pixel-on-real-screen x: int, y: int, color: int
|
||||
sig draw-grapheme-on-real-screen g: grapheme, x: int, y: int, color: int, background-color: int
|
||||
sig cursor-position-on-real-screen -> _/eax: int, _/ecx: int
|
||||
sig set-cursor-position-on-real-screen x: int, y: int
|
||||
sig set-cursor-position-on-real-screen x: int, y: int, g: grapheme
|
||||
|
||||
# keyboard
|
||||
sig read-key kbd: (addr keyboard) -> _/eax: byte
|
||||
|
|
|
@ -112,11 +112,11 @@ fn cursor-position screen: (addr screen) -> _/eax: int, _/ecx: int {
|
|||
return *cursor-x-addr, *cursor-y-addr
|
||||
}
|
||||
|
||||
fn set-cursor-position screen: (addr screen), x: int, y: int {
|
||||
fn set-cursor-position screen: (addr screen), x: int, y: int, g: grapheme {
|
||||
{
|
||||
compare screen, 0
|
||||
break-if-!=
|
||||
set-cursor-position-on-real-screen x, y
|
||||
set-cursor-position-on-real-screen x, y, g
|
||||
return
|
||||
}
|
||||
# fake screen
|
||||
|
@ -157,6 +157,11 @@ fn set-cursor-position screen: (addr screen), x: int, y: int {
|
|||
dest <- get screen-addr, cursor-y
|
||||
src <- copy y
|
||||
copy-to *dest, src
|
||||
#
|
||||
var cursor-x/eax: int <- copy 0
|
||||
var cursor-y/ecx: int <- copy 0
|
||||
cursor-x, cursor-y <- cursor-position screen-addr
|
||||
draw-grapheme screen-addr, g, cursor-x, cursor-y, 0 # cursor color not tracked for fake screen
|
||||
}
|
||||
|
||||
fn clear-screen screen: (addr screen) {
|
||||
|
@ -168,7 +173,7 @@ fn clear-screen screen: (addr screen) {
|
|||
}
|
||||
# fake screen
|
||||
var space/edi: grapheme <- copy 0x20
|
||||
set-cursor-position screen, 0, 0
|
||||
set-cursor-position screen, 0, 0, space
|
||||
var screen-addr/esi: (addr screen) <- copy screen
|
||||
var y/eax: int <- copy 1
|
||||
var height/ecx: (addr int) <- get screen-addr, height
|
||||
|
@ -187,7 +192,7 @@ fn clear-screen screen: (addr screen) {
|
|||
y <- increment
|
||||
loop
|
||||
}
|
||||
set-cursor-position screen, 0, 0
|
||||
set-cursor-position screen, 0, 0, space
|
||||
}
|
||||
|
||||
# there's no grapheme that guarantees to cover every pixel, so we'll bump down
|
||||
|
|
|
@ -10,7 +10,8 @@ fn cursor-left screen: (addr screen) {
|
|||
return
|
||||
}
|
||||
cursor-x <- decrement
|
||||
set-cursor-position screen, cursor-x, cursor-y
|
||||
var space/esi: grapheme <- copy 0x20
|
||||
set-cursor-position screen, cursor-x, cursor-y, space
|
||||
}
|
||||
|
||||
fn cursor-right screen: (addr screen) {
|
||||
|
@ -27,7 +28,8 @@ fn cursor-right screen: (addr screen) {
|
|||
return
|
||||
}
|
||||
cursor-x <- increment
|
||||
set-cursor-position screen, cursor-x, cursor-y
|
||||
var space/esi: grapheme <- copy 0x20
|
||||
set-cursor-position screen, cursor-x, cursor-y, space
|
||||
}
|
||||
|
||||
fn cursor-up screen: (addr screen) {
|
||||
|
@ -40,7 +42,8 @@ fn cursor-up screen: (addr screen) {
|
|||
return
|
||||
}
|
||||
cursor-y <- decrement
|
||||
set-cursor-position screen, cursor-x, cursor-y
|
||||
var space/esi: grapheme <- copy 0x20
|
||||
set-cursor-position screen, cursor-x, cursor-y, space
|
||||
}
|
||||
|
||||
fn cursor-down screen: (addr screen) {
|
||||
|
@ -57,7 +60,8 @@ fn cursor-down screen: (addr screen) {
|
|||
return
|
||||
}
|
||||
cursor-y <- increment
|
||||
set-cursor-position screen, cursor-x, cursor-y
|
||||
var space/esi: grapheme <- copy 0x20
|
||||
set-cursor-position screen, cursor-x, cursor-y, space
|
||||
}
|
||||
|
||||
fn draw-grapheme-at-cursor screen: (addr screen), g: grapheme, color: int {
|
||||
|
@ -101,7 +105,8 @@ fn draw-text-rightward screen: (addr screen), text: (addr array byte), x: int, x
|
|||
xcurr <- increment
|
||||
loop
|
||||
}
|
||||
set-cursor-position screen, xcurr, y
|
||||
var space/esi: grapheme <- copy 0x20
|
||||
set-cursor-position screen, xcurr, y, space # we'll assume it's ok to clear the next grapheme
|
||||
return xcurr
|
||||
}
|
||||
|
||||
|
@ -162,7 +167,8 @@ fn draw-text-wrapping-right-then-down screen: (addr screen), text: (addr array b
|
|||
}
|
||||
loop
|
||||
}
|
||||
set-cursor-position screen, xcurr, ycurr
|
||||
var space/esi: grapheme <- copy 0x20
|
||||
set-cursor-position screen, xcurr, ycurr, space # we'll assume it's ok to clear the next grapheme
|
||||
return xcurr, ycurr
|
||||
}
|
||||
|
||||
|
@ -177,7 +183,8 @@ fn move-cursor-rightward-and-downward screen: (addr screen), xmin: int, xmax: in
|
|||
cursor-x <- copy xmin
|
||||
cursor-y <- increment
|
||||
}
|
||||
set-cursor-position screen, cursor-x, cursor-y
|
||||
var space/esi: grapheme <- copy 0x20
|
||||
set-cursor-position screen, cursor-x, cursor-y, space # we'll assume it's ok to clear the grapheme at the cursor
|
||||
}
|
||||
|
||||
fn draw-text-wrapping-right-then-down-over-full-screen screen: (addr screen), text: (addr array byte), x: int, y: int, color: int -> _/eax: int, _/ecx: int {
|
||||
|
@ -255,7 +262,8 @@ fn draw-int32-hex-wrapping-right-then-down screen: (addr screen), n: int, xmin:
|
|||
}
|
||||
loop
|
||||
}
|
||||
set-cursor-position screen, xcurr, ycurr
|
||||
var space/esi: grapheme <- copy 0x20
|
||||
set-cursor-position screen, xcurr, ycurr, space # we'll assume it's ok to clear the next grapheme
|
||||
return xcurr, ycurr
|
||||
}
|
||||
|
||||
|
@ -334,7 +342,8 @@ fn draw-int32-decimal-wrapping-right-then-down screen: (addr screen), n: int, xm
|
|||
}
|
||||
loop
|
||||
}
|
||||
set-cursor-position screen, xcurr, ycurr
|
||||
var space/esi: grapheme <- copy 0x20
|
||||
set-cursor-position screen, xcurr, ycurr, space # we'll assume it's ok to clear the next grapheme
|
||||
return xcurr, ycurr
|
||||
}
|
||||
|
||||
|
@ -404,7 +413,8 @@ fn draw-text-downward screen: (addr screen), text: (addr array byte), x: int, y:
|
|||
ycurr <- increment
|
||||
loop
|
||||
}
|
||||
set-cursor-position screen, x, ycurr
|
||||
var space/esi: grapheme <- copy 0x20
|
||||
set-cursor-position screen, x, ycurr, space # we'll assume it's ok to clear the next grapheme
|
||||
return ycurr
|
||||
}
|
||||
|
||||
|
@ -464,7 +474,8 @@ fn draw-text-wrapping-down-then-right screen: (addr screen), text: (addr array b
|
|||
}
|
||||
loop
|
||||
}
|
||||
set-cursor-position screen, xcurr, ycurr
|
||||
var space/esi: grapheme <- copy 0x20
|
||||
set-cursor-position screen, xcurr, ycurr, space # we'll assume it's ok to clear the next grapheme
|
||||
return xcurr, ycurr
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue