summaryrefslogtreecommitdiff
path: root/console-client/vga.c
diff options
context:
space:
mode:
authorMarco Gerards <marco@gnu.org>2005-01-06 21:43:53 +0000
committerMarco Gerards <marco@gnu.org>2005-01-06 21:43:53 +0000
commit38fc4e4d1cef98a8b3d60b717647a9c65d91307f (patch)
tree805792e935ebbf353301070209d0af1aea1d908f /console-client/vga.c
parent4456094d61a6f5baabadc18096fc1f516921b736 (diff)
2005-01-06 Marco Gerards <metgerards@student.han.nl>
* Makefile (SRCS): Add `trans.c'. (LCLHDRS): Add `mach-inputdev.h'. (HURDLIBS): Add `netfs', `fshelp' and `iohelp'. (modules): Add `pc_mouse'. (pc_kbd.so.$(hurd-version)): Add `kdioctlServer.o' and `kbd-repeat.c'. (pc_mouse.so.$(hurd-version)): New variable. * console.c: Include <trans.h>. (DEFAULT_CONSOLE_NODE): New macro. (saved_id, saved_cons, consnode_path): New variables. (console_move_mouse): New function. (console_switch_away): New function. (console_switch_back): Likewise. (cons_vcons_set_mousecursor_pos): Likewise. (cons_vcons_set_mousecursor_status): Likewise. (options): Add the option `--console-node'. (parse_opt): Parse the options that were added to `options'. (main): Setup the console client translator node. * display.h (display_ops): New members `set_mousecursor_pos' and `set_mousecursor_status'. * driver.c (driver_start): Change the type of `i' to `unsigned int'. * driver.h (driver_ops): New members `save_status' and `restore_status'. * input.h (console_switch_away): New prototype. (console_switch_back): Likewise. (console_move_mouse): Likewise. * kbd-repeat.c: New file. * mach-inputdev.h: Likewise. * pc-mouse.c: Likewise. * trans.c: Likewise. * trans.h: Likewise. * pc-kbd.c: Include <argp.h> and "mach-inputdev.h". (DEFAULT_REPEATER_NODE): New macro. (repeater_node, cnode): New variables. (kev_type, mouse_motion, Scancode, m_deltaX, m_deltaY, MOUSE_LEFT) (MOUSE_MIDDLE, MOUSE_RIGHT, MOUSE_MOTION, KEYBD_EVENT) (IOCPARM_MASK, IOC_OUT, IOC_IN, _IOC, _IOR, _IOW, KDSKBDMODE, (KB_EVENT, KB_ASCII, KDGKBDTYPE, KB_VANILLAKB, KDSETLEDS): Removed. (gnumach_v1_input_next): Call the repeater when repeating is active. (doc, options, argp): New variables. (parse_opt): New function. (pc_kbd_init): Function rewritten. (pc_kbd_start): Initialize the repeater, when it is active. (pc_kbd_fini): Destroy the console node. * vga.c (vga_mousecursor): New struct. (vga_mousecursor_t): New type. (mousecursor): New variable. (hide_mousecursor): New function. (draw_mousecursor): Likewise. (vga_display_restore_status): Likewise. (vga_display_update): Likewise. (vga_set_mousecursor_pos): Likewise. (vga_set_mousecursor_status): Likewise. (vga_display_scroll): Update the mousecursor state. (driver_vga_ops): Add `vga_display_restore_status'. (vga_display_op): Add `vga_display_update', `vga_set_mousecursor_pos' and `vga_set_mousecursor_status'.
Diffstat (limited to 'console-client/vga.c')
-rw-r--r--console-client/vga.c124
1 files changed, 121 insertions, 3 deletions
diff --git a/console-client/vga.c b/console-client/vga.c
index c2d55f87..3cc2135a 100644
--- a/console-client/vga.c
+++ b/console-client/vga.c
@@ -1,5 +1,5 @@
/* vga.c - The VGA device display driver.
- Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
Written by Marcus Brinkmann.
This file is part of the GNU Hurd.
@@ -93,6 +93,15 @@ struct refchr
};
+typedef struct vga_mousecursor
+{
+ float posx;
+ float posy;
+ char oldcolor;
+ int visible;
+ int enabled;
+} vga_mousecursor_t;
+
struct vga_display
{
/* The VGA font for this display. */
@@ -110,6 +119,9 @@ struct vga_display
conchar_attr_t cur_conchar_attr;
char cur_attr;
+ /* The state of the mouse cursor. */
+ vga_mousecursor_t mousecursor;
+
/* Remember for each cell on the display the glyph written to it and
the colors (in the upper byte) assigned. 0 means unassigned. */
@@ -151,6 +163,37 @@ vga_display_flash (void *handle)
return 0;
}
+
+static void
+hide_mousecursor (struct vga_display *disp)
+{
+ char *oldpos = vga_videomem + 2 * ((int) disp->mousecursor.posy * disp->width
+ + (int) disp->mousecursor.posx) + 1;
+
+ if (!disp->mousecursor.visible)
+ return;
+
+ /* First remove the old cursor. */
+ *oldpos = disp->mousecursor.oldcolor;
+ disp->mousecursor.visible = 0;
+}
+
+
+static void
+draw_mousecursor (struct vga_display *disp)
+{
+ char *newpos = vga_videomem + 2 * ((int) disp->mousecursor.posy * disp->width
+ + (int) disp->mousecursor.posx) + 1;
+
+ if (disp->mousecursor.visible)
+ return;
+
+ /* Draw the new cursor. */
+ disp->mousecursor.oldcolor = *newpos;
+ *newpos = (127) ^ *newpos;
+
+ disp->mousecursor.visible = 1;
+}
static const char doc[] = "VGA Driver";
@@ -344,6 +387,16 @@ vga_display_fini (void *handle, int force)
return 0;
}
+
+static void
+vga_display_restore_status (void *handle)
+{
+ /* Read/write in interleaved mode. This is not preserved by the
+ XFree VESA driver. */
+ outb (VGA_GFX_MISC_ADDR, VGA_GFX_ADDR_REG);
+ outb (VGA_GFX_MISC_CHAINOE | VGA_GFX_MISC_A0TOAF, VGA_GFX_DATA_REG);
+}
+
/* Set the cursor's state to STATE on display HANDLE. */
static error_t
@@ -408,6 +461,8 @@ vga_display_scroll (void *handle, int delta)
int count = abs(delta) * disp->width;
int i;
struct refchr *refpos;
+
+ hide_mousecursor (disp);
/* XXX: If the virtual console is bigger than the physical console it is
impossible to scroll because the data to scroll is not in memory. */
@@ -595,6 +650,7 @@ vga_display_write (void *handle, conchar_t *str, size_t length,
struct vga_display *disp = handle;
char *pos;
struct refchr *refpos = &disp->refmatrix[row][col];
+ char *mouse_cursor_pos;
/* The starting column is outside the physical screen. */
if (disp->width < current_width && col >= disp->width)
@@ -607,6 +663,9 @@ vga_display_write (void *handle, conchar_t *str, size_t length,
}
pos = vga_videomem + 2 * (row * disp->width + col);
+ mouse_cursor_pos = (vga_videomem + 2
+ * ((int) disp->mousecursor.posy
+ * disp->width + (int) disp->mousecursor.posx) + 1);
/* Although all references to the current fgcol or bgcol could have
been released here, for example due to a scroll operation, we
@@ -662,6 +721,10 @@ vga_display_write (void *handle, conchar_t *str, size_t length,
}
*(pos++) = charval & 0xff;
+
+ if (pos == mouse_cursor_pos)
+ disp->mousecursor.visible = 0;
+
*(pos++) = disp->cur_attr
| (disp->df_size == 512 ? (charval >> 5) & 0x8 : 0);
@@ -700,12 +763,65 @@ vga_set_dimension (void *handle, unsigned int width, unsigned int height)
return 0;
}
+
+static error_t
+vga_display_update (void *handle)
+{
+ struct vga_display *disp = handle;
+
+ if (disp->mousecursor.enabled)
+ draw_mousecursor (disp);
+
+ return 0;
+}
+
+
+static error_t
+vga_set_mousecursor_pos (void *handle, float x, float y)
+{
+ struct vga_display *disp = handle;
+
+ /* If the mouse did not move from the character position, don't
+ bother about updating the cursor position. */
+ if (disp->mousecursor.visible && x == (int) disp->mousecursor.posx
+ && y == (int) disp->mousecursor.posy)
+ return 0;
+
+ hide_mousecursor (disp);
+
+ disp->mousecursor.posx = x;
+ disp->mousecursor.posy = y;
+
+ if (disp->mousecursor.enabled)
+ draw_mousecursor (disp);
+
+ return 0;
+}
+
+
+static error_t
+vga_set_mousecursor_status (void *handle, int status)
+{
+ struct vga_display *disp = handle;
+
+ disp->mousecursor.enabled = status;
+ if (!status)
+ hide_mousecursor (disp);
+ else
+ draw_mousecursor (disp);
+
+ return 0;
+}
+
+
struct driver_ops driver_vga_ops =
{
vga_display_init,
vga_display_start,
vga_display_fini,
+ NULL,
+ vga_display_restore_status
};
static struct display_ops vga_display_ops =
@@ -715,8 +831,10 @@ static struct display_ops vga_display_ops =
vga_display_scroll,
vga_display_clear,
vga_display_write,
- NULL,
+ vga_display_update,
vga_display_flash,
NULL,
- vga_set_dimension
+ vga_set_dimension,
+ vga_set_mousecursor_pos,
+ vga_set_mousecursor_status
};