1 |
/* vga.c - The VGA device display driver. |
/* vga.c - The VGA device display driver. |
2 |
Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc. |
Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc. |
3 |
Written by Marcus Brinkmann. |
Written by Marcus Brinkmann. |
4 |
|
|
5 |
This file is part of the GNU Hurd. |
This file is part of the GNU Hurd. |
93 |
}; |
}; |
94 |
|
|
95 |
|
|
96 |
|
typedef struct vga_mousecursor |
97 |
|
{ |
98 |
|
float posx; |
99 |
|
float posy; |
100 |
|
char oldcolor; |
101 |
|
int visible; |
102 |
|
int enabled; |
103 |
|
} vga_mousecursor_t; |
104 |
|
|
105 |
struct vga_display |
struct vga_display |
106 |
{ |
{ |
107 |
/* The VGA font for this display. */ |
/* The VGA font for this display. */ |
119 |
conchar_attr_t cur_conchar_attr; |
conchar_attr_t cur_conchar_attr; |
120 |
char cur_attr; |
char cur_attr; |
121 |
|
|
122 |
|
/* The state of the mouse cursor. */ |
123 |
|
vga_mousecursor_t mousecursor; |
124 |
|
|
125 |
/* Remember for each cell on the display the glyph written to it and |
/* Remember for each cell on the display the glyph written to it and |
126 |
the colors (in the upper byte) assigned. 0 means unassigned. */ |
the colors (in the upper byte) assigned. 0 means unassigned. */ |
127 |
|
|
163 |
return 0; |
return 0; |
164 |
} |
} |
165 |
|
|
166 |
|
|
167 |
|
static void |
168 |
|
hide_mousecursor (struct vga_display *disp) |
169 |
|
{ |
170 |
|
char *oldpos = vga_videomem + 2 * ((int) disp->mousecursor.posy * disp->width |
171 |
|
+ (int) disp->mousecursor.posx) + 1; |
172 |
|
|
173 |
|
if (!disp->mousecursor.visible) |
174 |
|
return; |
175 |
|
|
176 |
|
/* First remove the old cursor. */ |
177 |
|
*oldpos = disp->mousecursor.oldcolor; |
178 |
|
disp->mousecursor.visible = 0; |
179 |
|
} |
180 |
|
|
181 |
|
|
182 |
|
static void |
183 |
|
draw_mousecursor (struct vga_display *disp) |
184 |
|
{ |
185 |
|
char *newpos = vga_videomem + 2 * ((int) disp->mousecursor.posy * disp->width |
186 |
|
+ (int) disp->mousecursor.posx) + 1; |
187 |
|
|
188 |
|
if (disp->mousecursor.visible) |
189 |
|
return; |
190 |
|
|
191 |
|
/* Draw the new cursor. */ |
192 |
|
disp->mousecursor.oldcolor = *newpos; |
193 |
|
*newpos = (127) ^ *newpos; |
194 |
|
|
195 |
|
disp->mousecursor.visible = 1; |
196 |
|
} |
197 |
|
|
198 |
|
|
199 |
static const char doc[] = "VGA Driver"; |
static const char doc[] = "VGA Driver"; |
387 |
return 0; |
return 0; |
388 |
} |
} |
389 |
|
|
390 |
|
|
391 |
|
static void |
392 |
|
vga_display_restore_status (void *handle) |
393 |
|
{ |
394 |
|
/* Read/write in interleaved mode. This is not preserved by the |
395 |
|
XFree VESA driver. */ |
396 |
|
outb (VGA_GFX_MISC_ADDR, VGA_GFX_ADDR_REG); |
397 |
|
outb (VGA_GFX_MISC_CHAINOE | VGA_GFX_MISC_A0TOAF, VGA_GFX_DATA_REG); |
398 |
|
} |
399 |
|
|
400 |
|
|
401 |
/* Set the cursor's state to STATE on display HANDLE. */ |
/* Set the cursor's state to STATE on display HANDLE. */ |
402 |
static error_t |
static error_t |
461 |
int count = abs(delta) * disp->width; |
int count = abs(delta) * disp->width; |
462 |
int i; |
int i; |
463 |
struct refchr *refpos; |
struct refchr *refpos; |
464 |
|
|
465 |
|
hide_mousecursor (disp); |
466 |
|
|
467 |
/* XXX: If the virtual console is bigger than the physical console it is |
/* XXX: If the virtual console is bigger than the physical console it is |
468 |
impossible to scroll because the data to scroll is not in memory. */ |
impossible to scroll because the data to scroll is not in memory. */ |
650 |
struct vga_display *disp = handle; |
struct vga_display *disp = handle; |
651 |
char *pos; |
char *pos; |
652 |
struct refchr *refpos = &disp->refmatrix[row][col]; |
struct refchr *refpos = &disp->refmatrix[row][col]; |
653 |
|
char *mouse_cursor_pos; |
654 |
|
|
655 |
/* The starting column is outside the physical screen. */ |
/* The starting column is outside the physical screen. */ |
656 |
if (disp->width < current_width && col >= disp->width) |
if (disp->width < current_width && col >= disp->width) |
663 |
} |
} |
664 |
|
|
665 |
pos = vga_videomem + 2 * (row * disp->width + col); |
pos = vga_videomem + 2 * (row * disp->width + col); |
666 |
|
mouse_cursor_pos = (vga_videomem + 2 |
667 |
|
* ((int) disp->mousecursor.posy |
668 |
|
* disp->width + (int) disp->mousecursor.posx) + 1); |
669 |
|
|
670 |
/* Although all references to the current fgcol or bgcol could have |
/* Although all references to the current fgcol or bgcol could have |
671 |
been released here, for example due to a scroll operation, we |
been released here, for example due to a scroll operation, we |
721 |
} |
} |
722 |
|
|
723 |
*(pos++) = charval & 0xff; |
*(pos++) = charval & 0xff; |
724 |
|
|
725 |
|
if (pos == mouse_cursor_pos) |
726 |
|
disp->mousecursor.visible = 0; |
727 |
|
|
728 |
*(pos++) = disp->cur_attr |
*(pos++) = disp->cur_attr |
729 |
| (disp->df_size == 512 ? (charval >> 5) & 0x8 : 0); |
| (disp->df_size == 512 ? (charval >> 5) & 0x8 : 0); |
730 |
|
|
763 |
return 0; |
return 0; |
764 |
} |
} |
765 |
|
|
766 |
|
|
767 |
|
static error_t |
768 |
|
vga_display_update (void *handle) |
769 |
|
{ |
770 |
|
struct vga_display *disp = handle; |
771 |
|
|
772 |
|
if (disp->mousecursor.enabled) |
773 |
|
draw_mousecursor (disp); |
774 |
|
|
775 |
|
return 0; |
776 |
|
} |
777 |
|
|
778 |
|
|
779 |
|
static error_t |
780 |
|
vga_set_mousecursor_pos (void *handle, float x, float y) |
781 |
|
{ |
782 |
|
struct vga_display *disp = handle; |
783 |
|
|
784 |
|
/* If the mouse did not move from the character position, don't |
785 |
|
bother about updating the cursor position. */ |
786 |
|
if (disp->mousecursor.visible && x == (int) disp->mousecursor.posx |
787 |
|
&& y == (int) disp->mousecursor.posy) |
788 |
|
return 0; |
789 |
|
|
790 |
|
hide_mousecursor (disp); |
791 |
|
|
792 |
|
disp->mousecursor.posx = x; |
793 |
|
disp->mousecursor.posy = y; |
794 |
|
|
795 |
|
if (disp->mousecursor.enabled) |
796 |
|
draw_mousecursor (disp); |
797 |
|
|
798 |
|
return 0; |
799 |
|
} |
800 |
|
|
801 |
|
|
802 |
|
static error_t |
803 |
|
vga_set_mousecursor_status (void *handle, int status) |
804 |
|
{ |
805 |
|
struct vga_display *disp = handle; |
806 |
|
|
807 |
|
disp->mousecursor.enabled = status; |
808 |
|
if (!status) |
809 |
|
hide_mousecursor (disp); |
810 |
|
else |
811 |
|
draw_mousecursor (disp); |
812 |
|
|
813 |
|
return 0; |
814 |
|
} |
815 |
|
|
816 |
|
|
817 |
|
|
818 |
struct driver_ops driver_vga_ops = |
struct driver_ops driver_vga_ops = |
819 |
{ |
{ |
820 |
vga_display_init, |
vga_display_init, |
821 |
vga_display_start, |
vga_display_start, |
822 |
vga_display_fini, |
vga_display_fini, |
823 |
|
NULL, |
824 |
|
vga_display_restore_status |
825 |
}; |
}; |
826 |
|
|
827 |
static struct display_ops vga_display_ops = |
static struct display_ops vga_display_ops = |
831 |
vga_display_scroll, |
vga_display_scroll, |
832 |
vga_display_clear, |
vga_display_clear, |
833 |
vga_display_write, |
vga_display_write, |
834 |
NULL, |
vga_display_update, |
835 |
vga_display_flash, |
vga_display_flash, |
836 |
NULL, |
NULL, |
837 |
vga_set_dimension |
vga_set_dimension, |
838 |
|
vga_set_mousecursor_pos, |
839 |
|
vga_set_mousecursor_status |
840 |
}; |
}; |