aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Kiszka <jan.kiszka@siemens.com>2012-07-04 19:49:54 +0200
committerBlue Swirl <blauwirbel@gmail.com>2012-07-14 10:50:52 +0000
commit9aa0ff0bf9588f86846d1045662f5d75b91552cb (patch)
tree8362358d0138a52be8b930600a05940ac75bfc67
parentbf1bed81c9c8e0c2f3b5f16de4757ee2b5fd610a (diff)
downloadqemu-9aa0ff0bf9588f86846d1045662f5d75b91552cb.zip
qemu-9aa0ff0bf9588f86846d1045662f5d75b91552cb.tar.gz
qemu-9aa0ff0bf9588f86846d1045662f5d75b91552cb.tar.bz2
vga: Implement blinking of text cursor
Let the text cursor blink at 1.875 Hz, the original VGA cursor frequency. No timer is used, instead we rely on the fact that the display is updated periodically. Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com> Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
-rw-r--r--hw/vga.c14
-rw-r--r--hw/vga_int.h2
2 files changed, 14 insertions, 2 deletions
diff --git a/hw/vga.c b/hw/vga.c
index acb3f7d..f82ced8 100644
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -38,6 +38,9 @@
//#define DEBUG_BOCHS_VBE
+/* 16 state changes per vertical frame @60 Hz */
+#define VGA_TEXT_CURSOR_PERIOD_MS (1000 * 2 * 16 / 60)
+
/*
* Video Graphics Array (VGA)
*
@@ -1300,6 +1303,7 @@ static void vga_draw_text(VGACommonState *s, int full_update)
uint32_t *ch_attr_ptr;
vga_draw_glyph8_func *vga_draw_glyph8;
vga_draw_glyph9_func *vga_draw_glyph9;
+ int64_t now = qemu_get_clock_ms(vm_clock);
/* compute font data address (in plane 2) */
v = s->sr[VGA_SEQ_CHARACTER_MAP];
@@ -1370,6 +1374,10 @@ static void vga_draw_text(VGACommonState *s, int full_update)
s->cursor_end = s->cr[VGA_CRTC_CURSOR_END];
}
cursor_ptr = s->vram_ptr + (s->start_addr + cursor_offset) * 4;
+ if (now >= s->cursor_blink_time) {
+ s->cursor_blink_time = now + VGA_TEXT_CURSOR_PERIOD_MS / 2;
+ s->cursor_visible_phase = !s->cursor_visible_phase;
+ }
depth_index = get_depth_index(s->ds);
if (cw == 16)
@@ -1390,7 +1398,7 @@ static void vga_draw_text(VGACommonState *s, int full_update)
cx_max = -1;
for(cx = 0; cx < width; cx++) {
ch_attr = *(uint16_t *)src;
- if (full_update || ch_attr != *ch_attr_ptr) {
+ if (full_update || ch_attr != *ch_attr_ptr || src == cursor_ptr) {
if (cx < cx_min)
cx_min = cx;
if (cx > cx_max)
@@ -1420,7 +1428,8 @@ static void vga_draw_text(VGACommonState *s, int full_update)
font_ptr, cheight, fgcol, bgcol, dup9);
}
if (src == cursor_ptr &&
- !(s->cr[VGA_CRTC_CURSOR_START] & 0x20)) {
+ !(s->cr[VGA_CRTC_CURSOR_START] & 0x20) &&
+ s->cursor_visible_phase) {
int line_start, line_last, h;
/* draw the cursor */
line_start = s->cr[VGA_CRTC_CURSOR_START] & 0x1f;
@@ -1884,6 +1893,7 @@ static void vga_update_display(void *opaque)
}
if (graphic_mode != s->graphic_mode) {
s->graphic_mode = graphic_mode;
+ s->cursor_blink_time = qemu_get_clock_ms(vm_clock);
full_update = 1;
}
switch(graphic_mode) {
diff --git a/hw/vga_int.h b/hw/vga_int.h
index 3b38764..8938093 100644
--- a/hw/vga_int.h
+++ b/hw/vga_int.h
@@ -156,6 +156,8 @@ typedef struct VGACommonState {
uint32_t last_scr_width, last_scr_height; /* in pixels */
uint32_t last_depth; /* in bits */
uint8_t cursor_start, cursor_end;
+ bool cursor_visible_phase;
+ int64_t cursor_blink_time;
uint32_t cursor_offset;
unsigned int (*rgb_to_pixel)(unsigned int r,
unsigned int g, unsigned b);