aboutsummaryrefslogtreecommitdiff
path: root/libcons
diff options
context:
space:
mode:
Diffstat (limited to 'libcons')
-rw-r--r--libcons/Makefile38
-rw-r--r--libcons/cons-lookup.c107
-rw-r--r--libcons/cons-switch.c88
-rw-r--r--libcons/cons.h331
-rw-r--r--libcons/demuxer.c30
-rw-r--r--libcons/dir-changed.c129
-rw-r--r--libcons/extra-version.c24
-rw-r--r--libcons/file-changed.c366
-rw-r--r--libcons/init-init.c97
-rw-r--r--libcons/init-loop.c32
-rw-r--r--libcons/mutations.h27
-rw-r--r--libcons/opts-std-startup.c229
-rw-r--r--libcons/opts-version.c44
-rw-r--r--libcons/priv.h93
-rw-r--r--libcons/vcons-add.c30
-rw-r--r--libcons/vcons-close.c45
-rw-r--r--libcons/vcons-destroy.c52
-rw-r--r--libcons/vcons-event.c31
-rw-r--r--libcons/vcons-input.c64
-rw-r--r--libcons/vcons-move-mouse.c103
-rw-r--r--libcons/vcons-open.c175
-rw-r--r--libcons/vcons-refresh.c76
-rw-r--r--libcons/vcons-remove.c31
-rw-r--r--libcons/vcons-scrollback.c164
24 files changed, 2406 insertions, 0 deletions
diff --git a/libcons/Makefile b/libcons/Makefile
new file mode 100644
index 00000000..38ca74a7
--- /dev/null
+++ b/libcons/Makefile
@@ -0,0 +1,38 @@
+#
+# Copyright (C) 1994,95,96,97,98,99,2000,01,02,2005,2010 Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2, or (at
+# your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+dir := libcons
+makemode := library
+
+libname = libcons
+SRCS= demuxer.c init-init.c init-loop.c opts-version.c extra-version.c \
+ dir-changed.c file-changed.c opts-std-startup.c cons-lookup.c \
+ cons-switch.c vcons-remove.c vcons-add.c vcons-open.c \
+ vcons-close.c vcons-destroy.c vcons-refresh.c vcons-scrollback.c \
+ vcons-input.c vcons-move-mouse.c vcons-event.c
+LCLHDRS = priv.h mutations.h $(installhdrs)
+installhdrs = cons.h
+
+fs_notify-MIGSFLAGS = -imacros $(srcdir)/mutations.h
+MIGSTUBS = fs_notifyServer.o
+OBJS = $(sort $(SRCS:.c=.o) $(MIGSTUBS))
+
+HURDLIBS = threads ports
+
+MIGCOMSFLAGS = -prefix cons_
+
+include ../Makeconf
diff --git a/libcons/cons-lookup.c b/libcons/cons-lookup.c
new file mode 100644
index 00000000..d91cc3ce
--- /dev/null
+++ b/libcons/cons-lookup.c
@@ -0,0 +1,107 @@
+/* cons-lookup.c - Looking up virtual consoles.
+ Copyright (C) 2002 Free Software Foundation, Inc.
+ Written by Marcus Brinkmann.
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ The GNU Hurd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
+
+#include <errno.h>
+#include <malloc.h>
+#include <sys/mman.h>
+
+#include "cons.h"
+
+/* Lookup the virtual console entry with number ID in the console
+ CONS, and return it in R_VCONS_ENTRY. If CREATE is true, the
+ virtual console entry will be created if it doesn't exist yet. If
+ CREATE is true, and ID 0, the first free virtual console id is
+ used. CONS must be locked. */
+error_t
+cons_lookup (cons_t cons, int id, int create, vcons_list_t *r_vcons_entry)
+{
+ vcons_list_t previous_vcons_entry = 0;
+ vcons_list_t vcons_entry;
+
+ if (!id && !create)
+ return EINVAL;
+
+ if (id)
+ {
+ if (cons->vcons_list && cons->vcons_list->id <= id)
+ {
+ previous_vcons_entry = cons->vcons_list;
+ while (previous_vcons_entry->next
+ && previous_vcons_entry->next->id <= id)
+ previous_vcons_entry = previous_vcons_entry->next;
+ if (previous_vcons_entry->id == id)
+ {
+ *r_vcons_entry = previous_vcons_entry;
+ return 0;
+ }
+ }
+ else if (!create)
+ return ESRCH;
+ }
+ else
+ {
+ id = 1;
+ if (cons->vcons_list && cons->vcons_list->id == 1)
+ {
+ previous_vcons_entry = cons->vcons_list;
+ while (previous_vcons_entry && previous_vcons_entry->id == id)
+ {
+ id++;
+ previous_vcons_entry = previous_vcons_entry->next;
+ }
+ }
+ }
+
+ vcons_entry = calloc (1, sizeof (struct vcons_list));
+ if (!vcons_entry)
+ return ENOMEM;
+
+ vcons_entry->id = id;
+ vcons_entry->vcons = NULL;
+
+ /* Insert the virtual console into the doubly linked list. */
+ if (previous_vcons_entry)
+ {
+ vcons_entry->prev = previous_vcons_entry;
+ if (previous_vcons_entry->next)
+ {
+ previous_vcons_entry->next->prev = vcons_entry;
+ vcons_entry->next = previous_vcons_entry->next;
+ }
+ else
+ cons->vcons_last = vcons_entry;
+ previous_vcons_entry->next = vcons_entry;
+ }
+ else
+ {
+ if (cons->vcons_list)
+ {
+ cons->vcons_list->prev = vcons_entry;
+ vcons_entry->next = cons->vcons_list;
+ }
+ else
+ cons->vcons_last = vcons_entry;
+ cons->vcons_list = vcons_entry;
+ }
+
+ cons_vcons_add (cons, vcons_entry);
+ *r_vcons_entry = vcons_entry;
+ return 0;
+}
diff --git a/libcons/cons-switch.c b/libcons/cons-switch.c
new file mode 100644
index 00000000..752af97e
--- /dev/null
+++ b/libcons/cons-switch.c
@@ -0,0 +1,88 @@
+/* cons-switch.c - Switch to another virtual console.
+ Copyright (C) 2002 Free Software Foundation, Inc.
+ Written by Marcus Brinkmann.
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ The GNU Hurd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
+
+#include <errno.h>
+#include <assert.h>
+
+#include "cons.h"
+
+/* Open the virtual console ID or the virtual console DELTA steps away
+ from VCONS in the linked list and return it in R_VCONS, which will
+ be locked. */
+error_t
+cons_switch (vcons_t vcons, int id, int delta, vcons_t *r_vcons)
+{
+ error_t err = 0;
+ cons_t cons = vcons->cons;
+ vcons_list_t vcons_entry = NULL;
+
+ if (!id && !delta)
+ return 0;
+
+ mutex_lock (&cons->lock);
+ if (id)
+ {
+ vcons_entry = cons->vcons_list;
+ while (vcons_entry && vcons_entry->id != id)
+ vcons_entry = vcons_entry->next;
+ }
+ else if (delta > 0)
+ {
+ vcons_entry = vcons->vcons_entry;
+ while (delta-- > 0)
+ {
+ vcons_entry = vcons_entry->next;
+ if (!vcons_entry)
+ vcons_entry = cons->vcons_list;
+ }
+ }
+ else
+ {
+ assert (delta < 0);
+ vcons_entry = vcons->vcons_entry;
+ while (delta++ < 0)
+ {
+ vcons_entry = vcons_entry->prev;
+ if (!vcons_entry)
+ vcons_entry = cons->vcons_last;
+ }
+ }
+
+ if (!vcons_entry)
+ {
+ mutex_unlock (&cons->lock);
+ return ESRCH;
+ }
+
+ if (vcons_entry->vcons)
+ {
+ *r_vcons = vcons_entry->vcons;
+ mutex_lock (&vcons_entry->vcons->lock);
+ }
+ else
+ {
+ err = cons_vcons_open (cons, vcons_entry, r_vcons);
+ if (!err)
+ vcons_entry->vcons = *r_vcons;
+ }
+
+ mutex_unlock (&cons->lock);
+ return err;
+}
diff --git a/libcons/cons.h b/libcons/cons.h
new file mode 100644
index 00000000..e9d01a8c
--- /dev/null
+++ b/libcons/cons.h
@@ -0,0 +1,331 @@
+/* cons.h - Definitions for cons helper and callback functions.
+ Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
+ Written by Marcus Brinkmann.
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ The GNU Hurd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
+
+#ifndef _HURD_CONS_H
+#define _HURD_CONS_H
+
+#include <dirent.h>
+
+#include <hurd/ports.h>
+#include <mach.h>
+
+#include <hurd/console.h>
+
+typedef struct cons *cons_t;
+typedef struct vcons_list *vcons_list_t;
+typedef struct vcons *vcons_t;
+typedef struct cons_notify *cons_notify_t;
+
+struct vcons_list
+{
+ cons_t cons;
+ vcons_list_t next;
+ vcons_list_t prev;
+
+ /* The ID of the virtual console entry in the list. */
+ int id;
+
+ /* The opened vcons port on which we receive notifications. */
+ vcons_t vcons;
+};
+
+struct cons_notify
+{
+ struct port_info pi;
+
+ /* This is set for the dir notification port. */
+ cons_t cons;
+};
+
+struct vcons
+{
+ /* This must come first for the port info structure. */
+ struct cons_notify notify;
+
+ /* These elements are static from creation time. */
+ cons_t cons;
+ vcons_list_t vcons_entry;
+ int id;
+
+ /* The lock that protects all other members. */
+ struct mutex lock;
+
+ /* The FD of the input node. */
+ int input;
+
+ /* The shared memory of the display. */
+ struct cons_display *display;
+ size_t display_size;
+
+ struct
+ {
+ uint32_t flags;
+ struct
+ {
+ uint32_t col;
+ uint32_t row;
+ uint32_t status;
+ } cursor;
+ struct
+ {
+ uint32_t width;
+ uint32_t height;
+ uint32_t lines;
+ uint32_t cur_line;
+ uint32_t scr_lines;
+ conchar_t *matrix;
+ } screen;
+ struct
+ {
+ uint32_t audible;
+ uint32_t visible;
+ } bell;
+ struct
+ {
+ uint32_t written;
+ uint32_t length;
+ cons_change_t *buffer;
+ } changes;
+ } state;
+
+ uint32_t scrolling;
+};
+
+struct cons
+{
+ /* Protects the cons structure and the linked list in
+ VCONS_LIST. */
+ struct mutex lock;
+ vcons_list_t vcons_list;
+ vcons_list_t vcons_last;
+
+ struct port_class *port_class;
+ struct port_bucket *port_bucket;
+ DIR *dir;
+ io_t dirport;
+ int slack;
+};
+
+/* Determines if the mouse moves relatively, to an absolute location
+ or to an absolute location expressed by a percentage. */
+enum mouse_movement
+ {
+ CONS_VCONS_MOUSE_MOVE_REL,
+ CONS_VCONS_MOUSE_MOVE_ABS,
+ CONS_VCONS_MOUSE_MOVE_ABS_PERCENT
+ };
+
+/* The status of a mouse button. */
+enum mouse_button
+ {
+ CONS_VCONS_MOUSE_BUTTON_NO_OP,
+ CONS_VCONS_MOUSE_BUTTON_PRESSED,
+ CONS_VCONS_MOUSE_BUTTON_RELEASED
+ };
+
+/* An event produced by mouse movement an button presses. */
+typedef struct mouse_event
+{
+ enum mouse_movement mouse_movement;
+ float x;
+ float y;
+
+ enum mouse_button mouse_button;
+ int button;
+} *mouse_event_t;
+
+
+/* The user must define this variable. Set this to the name of the
+ console client. */
+extern const char *cons_client_name;
+
+/* The user must define this variable. Set this to be the client
+ version number. */
+extern const char *cons_client_version;
+
+/* The user may define this variable. Set this to be any additional
+ version specification that should be printed for --version. */
+extern char *cons_extra_version;
+
+/* The user must define this function. Deallocate the scarce
+ resources (like font glyph slots, colors etc) in the LENGTH entries
+ of the screen matrix starting from position COL and ROW. This call
+ is immediately followed by calls to cons_vcons_write that cover the
+ same area. If there are no scarce resources, the caller might do
+ nothing. */
+void cons_vcons_clear (vcons_t vcons, size_t length,
+ uint32_t col, uint32_t row);
+
+/* The user must define this function. Write LENGTH characters
+ starting from STR on the virtual console VCONS, which is locked,
+ starting from position COL and ROW. */
+void cons_vcons_write (vcons_t vcons, conchar_t *str, size_t length,
+ uint32_t col, uint32_t row);
+
+/* The user must define this function. Set the cursor on virtual
+ console VCONS, which is locked, to position COL and ROW. */
+void cons_vcons_set_cursor_pos (vcons_t vcons, uint32_t col, uint32_t row);
+
+/* The user must define this function. Set the cursor status of
+ virtual console VCONS, which is locked, to STATUS. */
+void cons_vcons_set_cursor_status (vcons_t vcons, uint32_t status);
+
+/* The user must define this function. Scroll the content of virtual
+ console VCONS, which is locked, up by DELTA if DELTA is positive or
+ down by -DELTA if DELTA is negative. DELTA will never be zero, and
+ the absolute value if DELTA will be smaller than or equal to the
+ height of the screen matrix.
+
+ This call will be immediately followed by corresponding
+ cons_vcons_write calls to fill the resulting gap on the screen, and
+ VCONS will be looked throughout the whole time. The purpose of the
+ function is two-fold: It is called with an absolute value of DELTA
+ smaller than the screen height to perform scrolling. It is called
+ with an absolute value of DELTA equal to the screen height to
+ prepare a full refresh of the screen. In the latter case the user
+ should not really perform any scrolling. Instead it might
+ deallocate limited resources (like display glyph slots and palette
+ colors) if that helps to perform the subsequent write, just like
+ cons_vcons_clear. It goes without saying that the same
+ deallocation, if any, should be performed on the area that will be
+ filled with the scrolled in content.
+
+ XXX Possibly need a function to invalidate scrollback buffer, or in
+ general to signal a switch of the console so state can be reset.
+ Only do this if we make guarantees about validity of scrollback
+ buffer, of course.
+
+ The driver is allowed to delay the effect of this operation until
+ the UPDATE function is called. */
+void cons_vcons_scroll (vcons_t vcons, int delta);
+
+/* The user may define this function. Make the changes from
+ cons_vcons_write, cons_vcons_set_cursor_pos,
+ cons_vcons_set_cursor_status and cons_vcons_scroll active. VCONS
+ is locked and will have been continuously locked from the first
+ change since the last update on. This is the latest possible point
+ the user must make the changes visible from. The user can always
+ make the changes visible at a more convenient, earlier time. */
+void cons_vcons_update (vcons_t vcons);
+
+/* The user must define this function. Make the virtual console
+ VCONS, which is locked, beep audibly. */
+void cons_vcons_beep (vcons_t vcons);
+
+/* The user must define this function. Make the virtual console
+ VCONS, which is locked, flash visibly. */
+void cons_vcons_flash (vcons_t vcons);
+
+/* The user must define this function. Notice the current status of
+ the scroll lock flag. */
+void cons_vcons_set_scroll_lock (vcons_t vcons, int onoff);
+
+/* The user must define this function. It is called whenever a
+ virtual console is selected to be the active one. It is the user's
+ responsibility to close the console at some later time. */
+error_t cons_vcons_activate (vcons_t vcons);
+
+/* The user may define this function. It is called after a
+ virtual console entry was added. CONS is locked. */
+void cons_vcons_add (cons_t cons, vcons_list_t vcons_entry);
+
+/* The user may define this function. It is called just before a
+ virtual console entry is removed. CONS is locked. */
+void cons_vcons_remove (cons_t cons, vcons_list_t vcons_entry);
+
+/* Open the virtual console ID or the virtual console DELTA steps away
+ from VCONS in the linked list and return it in R_VCONS, which will
+ be locked. */
+error_t cons_switch (vcons_t vcons, int id, int delta, vcons_t *r_vcons);
+
+/* Enter SIZE bytes from the buffer BUF into the virtual console
+ VCONS. */
+error_t cons_vcons_input (vcons_t vcons, char *buf, size_t size);
+
+/* The user must define this function. Clear the existing screen
+ matrix and set the size of the screen matrix to the dimension COL x
+ ROW. This call will be immediately followed by a call to
+ cons_vcons_write that covers the whole new screen matrix. */
+error_t cons_vcons_set_dimension (vcons_t vcons,
+ uint32_t col, uint32_t row);
+
+typedef enum
+ {
+ CONS_SCROLL_DELTA_LINES, CONS_SCROLL_DELTA_SCREENS,
+ CONS_SCROLL_ABSOLUTE_LINE, CONS_SCROLL_ABSOLUTE_PERCENTAGE
+ } cons_scroll_t;
+
+/* Scroll back into the history of VCONS. If TYPE is
+ CONS_SCROLL_DELTA_LINES, scroll up or down by VALUE lines. If TYPE
+ is CONS_SCROLL_DELTA_SCREENS, scroll up or down by VALUE multiples
+ of a screen height. If TYPE is CONS_SCROLL_ABSOLUTE_LINE, scroll to
+ line VALUE (where 0 is the lowest line). If TYPE is
+ CONS_SCROLL_ABSOLUTE_PERCENTAGE, scroll to the position determined
+ by VALUE, where 0 is the bottom and 1 is the top.
+
+ The function returns the number of lines actually scrolled up or
+ down. */
+int cons_vcons_scrollback (vcons_t vcons, cons_scroll_t type, float value);
+
+/* Set the mouse cursor position to X, Y. VCONS is locked. */
+error_t cons_vcons_set_mousecursor_pos (vcons_t vcons, float x, float y);
+
+/* If STATUS is set to 0, hide the mouse cursor, otherwise show
+ it. VCONS is locked. */
+error_t cons_vcons_set_mousecursor_status (vcons_t vcons, int status);
+
+
+
+extern const struct argp cons_startup_argp;
+
+extern struct port_bucket *cons_port_bucket;
+extern struct port_class *cons_port_class;
+
+/* The filename of the console server. */
+extern char *cons_file;
+
+error_t cons_init (void);
+void cons_server_loop (void);
+int cons_demuxer (mach_msg_header_t *inp, mach_msg_header_t *outp);
+
+/* Lookup the virtual console with number ID in the console CONS,
+ acquire a reference for it, and return its list entry in R_VCONS.
+ If CREATE is true, the virtual console will be created if it
+ doesn't exist yet. If CREATE is true, and ID 0, the first free
+ virtual console id is used. CONS must be locked. */
+error_t cons_lookup (cons_t cons, int id, int create, vcons_list_t *r_vcons);
+
+/* Open the virtual console for VCONS_ENTRY. CONS is locked. */
+error_t cons_vcons_open (cons_t cons, vcons_list_t vcons_entry,
+ vcons_t *r_vcons);
+
+/* Close the virtual console VCONS. VCONS->cons is locked. */
+void cons_vcons_close (vcons_t vcons);
+
+/* Destroy the virtual console VCONS. */
+void cons_vcons_destroy (void *port);
+
+/* Redraw the virtual console VCONS, which is locked. */
+void cons_vcons_refresh (vcons_t vcons);
+
+/* Handle the event EV on the virtual console VCONS. */
+error_t cons_vcons_move_mouse (vcons_t vcons, mouse_event_t ev);
+
+#endif /* hurd/cons.h */
diff --git a/libcons/demuxer.c b/libcons/demuxer.c
new file mode 100644
index 00000000..8982bfa9
--- /dev/null
+++ b/libcons/demuxer.c
@@ -0,0 +1,30 @@
+/* demuxer.c - Message demuxer for console client library.
+ Copyright (C) 2002 Free Software Foundation, Inc.
+ Written by Marcus Brinkmann.
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ The GNU Hurd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
+
+#include "cons.h"
+
+int
+cons_demuxer (mach_msg_header_t *inp, mach_msg_header_t *outp)
+{
+ int cons_fs_notify_server (mach_msg_header_t *inp, mach_msg_header_t *outp);
+
+ return (cons_fs_notify_server (inp, outp));
+}
+
diff --git a/libcons/dir-changed.c b/libcons/dir-changed.c
new file mode 100644
index 00000000..e1997d0f
--- /dev/null
+++ b/libcons/dir-changed.c
@@ -0,0 +1,129 @@
+/* dir-changed.c - Handling dir changed notifications.
+ Copyright (C) 2002 Free Software Foundation, Inc.
+ Written by Marcus Brinkmann.
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ The GNU Hurd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
+
+#include <errno.h>
+#include <dirent.h>
+#include <assert.h>
+#include <mach.h>
+#include <cthreads.h>
+
+#include "cons.h"
+#include "fs_notify_S.h"
+
+
+static error_t
+add_one (cons_t cons, char *name)
+{
+ unsigned long int nr;
+ char *tail;
+
+ errno = 0;
+ nr = strtoul (name, &tail, 10);
+ if (!errno && *tail == '\0' && nr > 0)
+ {
+ vcons_list_t vcons_entry;
+ return cons_lookup (cons, nr, 1, &vcons_entry);
+ }
+ return 0;
+}
+
+static error_t
+lookup_one (cons_t cons, char *name, vcons_list_t *vcons_entry)
+{
+ unsigned long int nr;
+ char *tail;
+
+ errno = 0;
+ nr = strtoul (name, &tail, 10);
+ if (!errno && *tail == '\0' && nr > 0)
+ return cons_lookup (cons, nr, 0, vcons_entry);
+ return 0;
+}
+
+
+kern_return_t
+cons_S_dir_changed (cons_notify_t notify, natural_t tickno,
+ dir_changed_type_t change, string_t name)
+{
+ error_t err;
+ cons_t cons;
+
+ if (!notify || !notify->cons)
+ return EOPNOTSUPP;
+ cons = notify->cons;
+
+ mutex_lock (&cons->lock);
+
+ switch (change)
+ {
+ case DIR_CHANGED_NULL:
+ {
+ DIR *dir = cons->dir;
+ struct dirent *dent;
+ do
+ {
+ errno = 0;
+ dent = readdir (dir);
+ if (!dent && errno)
+ err = errno;
+ else if (dent)
+ err = add_one (cons, dent->d_name);
+ }
+ while (dent && !err);
+ if (err)
+ assert ("Unexpected error"); /* XXX */
+ }
+ break;
+ case DIR_CHANGED_NEW:
+ {
+ err = add_one (cons, name);
+ if (err)
+ assert ("Unexpected error"); /* XXX */
+ }
+ break;
+ case DIR_CHANGED_UNLINK:
+ {
+ vcons_list_t vcons_entry;
+ err = lookup_one (cons, name, &vcons_entry);
+ if (!err)
+ {
+ cons_vcons_remove (cons, vcons_entry);
+ if (vcons_entry->prev)
+ vcons_entry->prev->next = vcons_entry->next;
+ else
+ cons->vcons_list = vcons_entry->next;
+ if (vcons_entry->next)
+ vcons_entry->next->prev = vcons_entry->prev;
+ else
+ cons->vcons_last = vcons_entry->prev;
+
+ free (vcons_entry);
+ }
+ }
+ break;
+ case DIR_CHANGED_RENUMBER:
+ default:
+ assert ("Unexpected dir-changed type.");
+ mutex_unlock (&cons->lock);
+ return EINVAL;
+ }
+ mutex_unlock (&cons->lock);
+ return 0;
+}
diff --git a/libcons/extra-version.c b/libcons/extra-version.c
new file mode 100644
index 00000000..4ff54d85
--- /dev/null
+++ b/libcons/extra-version.c
@@ -0,0 +1,24 @@
+/* Default value for cons_extra_version
+ Copyright (C) 2002 Free Software Foundation, Inc.
+ Written by Marcus Brinkmann.
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ The GNU Hurd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
+
+
+#include "priv.h"
+
+char *cons_extra_version = "";
diff --git a/libcons/file-changed.c b/libcons/file-changed.c
new file mode 100644
index 00000000..b12a6f10
--- /dev/null
+++ b/libcons/file-changed.c
@@ -0,0 +1,366 @@
+/* file-changed.c - Handling file changed notifications.
+ Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+ Written by Marcus Brinkmann.
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ The GNU Hurd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
+
+#include <errno.h>
+#include <assert.h>
+
+#include <mach.h>
+
+#include "cons.h"
+#include "fs_notify_S.h"
+
+kern_return_t
+cons_S_file_changed (cons_notify_t notify, natural_t tickno,
+ file_changed_type_t change,
+ off_t start, off_t end)
+{
+ error_t err = 0;
+ vcons_t vcons = (vcons_t) notify;
+
+ if (!notify || notify->cons)
+ return EOPNOTSUPP;
+
+ mutex_lock (&vcons->lock);
+ switch (change)
+ {
+ case FILE_CHANGED_NULL:
+ /* Always sent first for sync. */
+ cons_vcons_refresh (vcons);
+ break;
+ case FILE_CHANGED_WRITE:
+ /* File data has been written. */
+ while (vcons->state.changes.written < vcons->display->changes.written)
+ {
+ cons_change_t change;
+
+ if (vcons->display->changes.written - vcons->state.changes.written
+ > vcons->cons->slack)
+ {
+ cons_vcons_refresh (vcons);
+ continue;
+ }
+ change = vcons->state.changes.buffer[vcons->state.changes.written
+ % vcons->state.changes.length];
+ if (vcons->display->changes.written - vcons->state.changes.written
+ > vcons->state.changes.length - 1)
+ {
+ /* While we were reading the entry, the server might
+ have overwritten it. */
+ cons_vcons_refresh (vcons);
+ continue;
+ }
+ vcons->state.changes.written++;
+
+ if (change.what.not_matrix)
+ {
+ if (change.what.cursor_pos)
+ {
+ uint32_t old_row = vcons->state.cursor.row;
+ uint32_t height = vcons->state.screen.height;
+ uint32_t row;
+
+ vcons->state.cursor.col = vcons->display->cursor.col;
+ row = vcons->state.cursor.row = vcons->display->cursor.row;
+
+ if (row + vcons->scrolling < height)
+ {
+ cons_vcons_set_cursor_pos (vcons,
+ vcons->state.cursor.col,
+ row + vcons->scrolling);
+ if (old_row + vcons->scrolling >= height)
+ /* The cursor was invisible before. */
+ cons_vcons_set_cursor_status (vcons,
+ vcons->state.cursor.status);
+ }
+ else if (old_row + vcons->scrolling < height)
+ /* The cursor was visible before. */
+ cons_vcons_set_cursor_status (vcons, CONS_CURSOR_INVISIBLE);
+
+ _cons_vcons_console_event (vcons, CONS_EVT_OUTPUT);
+ cons_vcons_update (vcons);
+ }
+ if (change.what.cursor_status)
+ {
+ vcons->state.cursor.status = vcons->display->cursor.status;
+ cons_vcons_set_cursor_status (vcons,
+ vcons->state.cursor.status);
+ cons_vcons_update (vcons);
+ }
+ if (change.what.screen_cur_line)
+ {
+ uint32_t new_cur_line;
+
+ new_cur_line = vcons->display->screen.cur_line;
+
+ if (new_cur_line != vcons->state.screen.cur_line)
+ {
+ off_t size = vcons->state.screen.width
+ * vcons->state.screen.lines;
+ off_t vis_start;
+ uint32_t scrolling;
+ off_t start;
+ off_t end;
+
+ if (new_cur_line > vcons->state.screen.cur_line)
+ scrolling = new_cur_line
+ - vcons->state.screen.cur_line;
+ else
+ scrolling = UINT32_MAX - vcons->state.screen.cur_line
+ + 1 + new_cur_line;
+
+ /* If we are scrolling back, defer scrolling
+ until absolutely necessary. */
+ if (vcons->scrolling)
+ {
+ if (_cons_jump_down_on_output)
+ _cons_vcons_scrollback
+ (vcons, CONS_SCROLL_ABSOLUTE_LINE, 0);
+ else
+ {
+ if (vcons->scrolling + scrolling
+ <= vcons->state.screen.scr_lines)
+ {
+ vcons->scrolling += scrolling;
+ scrolling = 0;
+ }
+ else
+ {
+ scrolling -= vcons->state.screen.scr_lines
+ - vcons->scrolling;
+ vcons->scrolling
+ = vcons->state.screen.scr_lines;
+ }
+ }
+ }
+
+ if (scrolling)
+ {
+ uint32_t cur_disp_line;
+
+ if (new_cur_line >= vcons->scrolling)
+ cur_disp_line = new_cur_line - vcons->scrolling;
+ else
+ cur_disp_line = (UINT32_MAX - (vcons->scrolling - new_cur_line)) + 1;
+
+ if (scrolling > vcons->state.screen.height)
+ scrolling = vcons->state.screen.height;
+ if (scrolling < vcons->state.screen.height)
+ cons_vcons_scroll (vcons, scrolling);
+ else
+ cons_vcons_clear (vcons, vcons->state.screen.width
+ * vcons->state.screen.height,
+ 0, 0);
+ vis_start = vcons->state.screen.width
+ * (cur_disp_line % vcons->state.screen.lines);
+ start = (((cur_disp_line % vcons->state.screen.lines)
+ + vcons->state.screen.height - scrolling)
+ * vcons->state.screen.width) % size;
+ end = start + scrolling * vcons->state.screen.width - 1;
+ cons_vcons_write (vcons,
+ vcons->state.screen.matrix + start,
+ end < size
+ ? end - start + 1
+ : size - start,
+ 0, vcons->state.screen.height
+ - scrolling);
+ if (end >= size)
+ cons_vcons_write (vcons,
+ vcons->state.screen.matrix,
+ end - size + 1,
+ 0, (size - vis_start)
+ / vcons->state.screen.width);
+ _cons_vcons_console_event (vcons, CONS_EVT_OUTPUT);
+ cons_vcons_update (vcons);
+ }
+ vcons->state.screen.cur_line = new_cur_line;
+ }
+ }
+ if (change.what.screen_scr_lines)
+ {
+ vcons->state.screen.scr_lines
+ = vcons->display->screen.scr_lines;
+ if (vcons->state.screen.scr_lines < vcons->scrolling)
+ assert (!"Implement shrinking scrollback buffer! XXX");
+ }
+ if (change.what.bell_audible)
+ {
+ while (vcons->state.bell.audible
+ < vcons->display->bell.audible)
+ {
+ if (_cons_audible_bell == BELL_AUDIBLE)
+ cons_vcons_beep (vcons);
+ else if (_cons_audible_bell == BELL_VISUAL)
+ cons_vcons_flash (vcons);
+ vcons->state.bell.audible++;
+ }
+ }
+ if (change.what.bell_visible)
+ {
+ while (vcons->state.bell.visible
+ < vcons->display->bell.visible)
+ {
+ if (_cons_visual_bell == BELL_VISUAL)
+ cons_vcons_flash (vcons);
+ else if (_cons_visual_bell == BELL_AUDIBLE)
+ cons_vcons_beep (vcons);
+ vcons->state.bell.visible++;
+ }
+ }
+ if (change.what.flags)
+ {
+ uint32_t flags = vcons->display->flags;
+
+ if ((flags & CONS_FLAGS_SCROLL_LOCK)
+ != (vcons->state.flags & CONS_FLAGS_SCROLL_LOCK))
+ cons_vcons_set_scroll_lock (vcons, flags
+ & CONS_FLAGS_SCROLL_LOCK);
+ vcons->state.flags = flags;
+ }
+ }
+ else
+ {
+ /* For clipping. */
+ off_t size = vcons->state.screen.width*vcons->state.screen.lines;
+ off_t rotate;
+ off_t vis_end = vcons->state.screen.height
+ * vcons->state.screen.width - 1;
+ off_t end2 = -1;
+ off_t start_rel = 0; /* start relative to visible start. */
+ off_t start = change.matrix.start;
+ off_t end = change.matrix.end;
+
+ if (vcons->scrolling && _cons_jump_down_on_output)
+ _cons_vcons_scrollback (vcons, CONS_SCROLL_ABSOLUTE_LINE, 0);
+
+ if (vcons->state.screen.cur_line >= vcons->scrolling)
+ rotate = vcons->state.screen.cur_line - vcons->scrolling;
+ else
+ rotate = (UINT32_MAX - (vcons->scrolling - vcons->state.screen.cur_line)) + 1;
+ rotate = vcons->state.screen.width * (rotate % vcons->state.screen.lines);
+
+ /* Rotate the buffer. */
+ start -= rotate;
+ if (start < 0)
+ start += size;
+ end -= rotate;
+ if (end < 0)
+ end += size;
+
+ /* Find the intersection. */
+ if (start > vis_end)
+ {
+ if (end < start)
+ {
+ start = 0;
+ if (vis_end < end)
+ end = vis_end;
+ }
+ else
+ start = -1;
+ }
+ else
+ {
+ if (end >= start)
+ {
+ if (end > vis_end)
+ end = vis_end;
+ }
+ else
+ {
+ end2 = end;
+ end = vis_end;
+ }
+ }
+ /* We now have three cases: No intersection if start ==
+ -1, one intersection [start;end] if end2 == -1, and
+ two intersections [start;end] and [0;end2] if end2 !=
+ -1. However, we still have to undo the buffer
+ rotation. */
+ if (start != -1)
+ {
+ start_rel = start;
+ start += rotate;
+ if (start >= size)
+ start -= size;
+ end += rotate;
+ if (end >= size)
+ end -= size;
+ if (start > end)
+ end += size;
+ }
+ if (end2 != -1)
+ /* The interval should be [vis_start:end2]. */
+ end2 += rotate;
+
+ if (start != -1)
+ {
+ cons_vcons_clear (vcons, end - start + 1,
+ start_rel % vcons->state.screen.width,
+ start_rel / vcons->state.screen.width);
+ cons_vcons_write (vcons, vcons->state.screen.matrix + start,
+ end < size
+ ? end - start + 1
+ : size - start,
+ start_rel % vcons->state.screen.width,
+ start_rel / vcons->state.screen.width);
+ if (end >= size)
+ cons_vcons_write (vcons, vcons->state.screen.matrix,
+ end - size + 1,
+ (size - rotate)
+ % vcons->state.screen.width,
+ (size - rotate)
+ / vcons->state.screen.width);
+ if (end2 != -1)
+ {
+ cons_vcons_clear (vcons, end2 - rotate + 1, 0, 0);
+ cons_vcons_write (vcons,
+ vcons->state.screen.matrix + rotate,
+ end2 < size
+ ? end2 - rotate + 1
+ : size - rotate,
+ 0, 0);
+ if (end2 >= size)
+ cons_vcons_write (vcons, vcons->state.screen.matrix,
+ end2 - size + 1,
+ (size - rotate)
+ % vcons->state.screen.width,
+ (size - rotate)
+ / vcons->state.screen.width);
+ }
+ _cons_vcons_console_event (vcons, CONS_EVT_OUTPUT);
+ cons_vcons_update (vcons);
+ }
+ }
+ }
+ break;
+ case FILE_CHANGED_EXTEND:
+ /* File has grown. */
+ case FILE_CHANGED_TRUNCATE:
+ /* File has been truncated. */
+ case FILE_CHANGED_META:
+ /* Stat information has changed, and none of the previous three
+ apply. Not sent for changes in node times. */
+ default:
+ err = EINVAL;
+ };
+
+ mutex_unlock (&vcons->lock);
+ return err;
+}
diff --git a/libcons/init-init.c b/libcons/init-init.c
new file mode 100644
index 00000000..eda292f5
--- /dev/null
+++ b/libcons/init-init.c
@@ -0,0 +1,97 @@
+/* init-init.c - Initialize the console library.
+ Copyright (C) 1995, 1996, 2002 Free Software Foundation, Inc.
+ Written by Michael I. Bushnell, p/BSG and Marcus Brinkmann.
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ The GNU Hurd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
+
+#include <errno.h>
+#include <malloc.h>
+
+#include <hurd.h>
+#include <hurd/ports.h>
+
+#include <mach.h>
+
+#include "cons.h"
+#include "priv.h"
+
+struct port_bucket *cons_port_bucket;
+struct port_class *cons_port_class;
+
+
+error_t
+cons_init (void)
+{
+ error_t err;
+ cons_t cons;
+ cons_notify_t dir_notify_port;
+ mach_port_t dir_notify;
+
+ cons_port_bucket = ports_create_bucket ();
+ if (!cons_port_bucket)
+ return errno;
+
+ cons_port_class = ports_create_class (cons_vcons_destroy, NULL);
+ if (!cons_port_class)
+ return errno;
+
+ /* Create the console structure. */
+ cons = malloc (sizeof (*cons));
+ if (!cons)
+ return errno;
+ mutex_init (&cons->lock);
+ cons->vcons_list = NULL;
+ cons->vcons_last = NULL;
+ cons->dir = opendir (cons_file);
+ cons->slack = _cons_slack;
+ if (!cons->dir)
+ {
+ free (cons);
+ return errno;
+ }
+ cons->dirport = getdport (dirfd (cons->dir));
+ if (cons->dirport == MACH_PORT_NULL)
+ {
+ closedir (cons->dir);
+ free (cons);
+ return errno;
+ }
+
+ /* Request directory notifications. */
+ err = ports_create_port (cons_port_class, cons_port_bucket,
+ sizeof (*dir_notify_port), &dir_notify_port);
+ if (err)
+ {
+ mach_port_deallocate (mach_task_self (), cons->dirport);
+ closedir (cons->dir);
+ free (cons);
+ return err;
+ }
+ dir_notify_port->cons = cons;
+
+ dir_notify = ports_get_right (dir_notify_port);
+ err = dir_notice_changes (cons->dirport, dir_notify,
+ MACH_MSG_TYPE_MAKE_SEND);
+ if (err)
+ {
+ mach_port_deallocate (mach_task_self (), cons->dirport);
+ closedir (cons->dir);
+ free (cons);
+ return err;
+ }
+ return 0;
+}
diff --git a/libcons/init-loop.c b/libcons/init-loop.c
new file mode 100644
index 00000000..18576cb0
--- /dev/null
+++ b/libcons/init-loop.c
@@ -0,0 +1,32 @@
+/* init-loop.c - Server loop for console client library.
+ Copyright (C) 2002 Free Software Foundation, Inc.
+ Written by Marcus Brinkmann.
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ The GNU Hurd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
+
+#include <hurd/ports.h>
+
+#include "cons.h"
+
+void
+cons_server_loop (void)
+{
+ ports_manage_port_operations_one_thread (cons_port_bucket,
+ cons_demuxer, 0);
+ /* Not reached. */
+}
+
diff --git a/libcons/mutations.h b/libcons/mutations.h
new file mode 100644
index 00000000..af5ab2d0
--- /dev/null
+++ b/libcons/mutations.h
@@ -0,0 +1,27 @@
+/* mutations.h - MIG mutations for the console client library.
+ Copyright (C) 2002 Free Software Foundation, Inc.
+ Written by Marcus Brinkmann.
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ The GNU Hurd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
+
+/* Only CPP macro definitions should go in this file. */
+
+#define FS_NOTIFY_INTRAN cons_notify_t begin_using_notify_port (fs_notify_t)
+#define FS_NOTIFY_DESTRUCTOR end_using_notify_port (cons_notify_t)
+
+#define FS_NOTIFY_IMPORTS import "priv.h";
+
diff --git a/libcons/opts-std-startup.c b/libcons/opts-std-startup.c
new file mode 100644
index 00000000..23bd9971
--- /dev/null
+++ b/libcons/opts-std-startup.c
@@ -0,0 +1,229 @@
+/* opts-std-startup.c - Standard startup-time command line parser.
+ Copyright (C) 1995,96,97,98,99,2001,02,2003,2004,2005 Free Software Foundation, Inc.
+ Written by Miles Bader <miles@gnu.org> and Marcus Brinkmann.
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ The GNU Hurd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include <stdio.h>
+#include <argp.h>
+#include <string.h>
+
+#include "priv.h"
+
+
+/* Option keys for long-only options in argp_option. */
+#define OPT_SLACK 600 /* --slack */
+#define OPT_JUMP_DOWN_ON_INPUT 601 /* --jump-down-on-input */
+#define OPT_NO_JUMP_DOWN_ON_INPUT 602 /* --no-jump-down-on-input */
+#define OPT_JUMP_DOWN_ON_OUTPUT 603 /* --jump-down-on-output */
+#define OPT_NO_JUMP_DOWN_ON_OUTPUT 604 /* --no-jump-down-on-output */
+#define OPT_VISUAL_BELL 605 /* --visual-bell */
+#define OPT_AUDIBLE_BELL 606 /* --audible-bell */
+#define OPT_MOUSE_SHOW 607 /* --mouse-show-on */
+#define OPT_MOUSE_HIDE 608 /* --mouse-hide-on */
+#define OPT_MOUSE_SENS 609 /* --mouse-sensitivity */
+
+/* The number of records the client is allowed to lag behind the server. */
+#define DEFAULT_SLACK 100
+#define DEFAULT_SLACK_STRING STRINGIFY(DEFAULT_SLACK)
+#define STRINGIFY(x) STRINGIFY_1(x)
+#define STRINGIFY_1(x) #x
+
+/* The mouse sensitivity. */
+#define DEFAULT_MOUSE_SENS 3.0
+#define DEFAULT_MOUSE_SENS_STRING STRINGIFY(DEFAULT_MOUSE_SENS)
+
+/* Number of records the client is allowed to lag behind the
+ server. */
+int _cons_slack = DEFAULT_SLACK;
+
+/* If we jump down on input. */
+int _cons_jump_down_on_input = 1;
+
+/* If we jump down on output. */
+int _cons_jump_down_on_output;
+
+/* The filename of the console server. */
+char *cons_file;
+
+/* The type of bell used for the visual bell. */
+bell_type_t _cons_visual_bell = BELL_VISUAL;
+
+/* The type of bell used for the audible bell. */
+bell_type_t _cons_audible_bell = BELL_AUDIBLE;
+
+/* The type of events that will make the mouse cursor visible. */
+int _cons_show_mouse = CONS_EVT_MOUSE_MOVE;
+
+/* The type of events that will hide the mouse cursor. */
+int _cons_hide_mouse = CONS_EVT_KEYPRESS;
+
+/* The mouse sensitivity. */
+float _cons_mouse_sens = DEFAULT_MOUSE_SENS;
+
+static const struct argp_option
+startup_options[] =
+{
+ { "slack", OPT_SLACK, "RECORDS", 0, "Max number of records the client is"
+ " allowed to lag behind the server (default " DEFAULT_SLACK_STRING ")" },
+ { "jump-down-on-input", OPT_JUMP_DOWN_ON_INPUT, NULL, 0,
+ "End scrollback when something is entered (default)" },
+ { "no-jump-down-on-input", OPT_NO_JUMP_DOWN_ON_INPUT, NULL, 0,
+ "End scrollback when something is entered" },
+ { "jump-down-on-output", OPT_JUMP_DOWN_ON_OUTPUT, NULL, 0,
+ "End scrollback when something is printed" },
+ { "no-jump-down-on-output", OPT_NO_JUMP_DOWN_ON_OUTPUT, NULL, 0,
+ "End scrollback when something is printed (default)" },
+ { "visual-bell", OPT_VISUAL_BELL, "BELL", 0, "Visual bell: on (default), "
+ "off, visual, audible" },
+ { "audible-bell", OPT_AUDIBLE_BELL, "BELL", 0, "Audible bell: on (default), "
+ "off, visual, audible" },
+ { "mouse-show-on", OPT_MOUSE_SHOW, "EVENTS", 0, "One or more of the events"
+ " mousemove, mousebutton, keypress, output (default is mousemove), if one"
+ " of these events occur the mouse cursor will be made visible" },
+ { "mouse-hide-on", OPT_MOUSE_HIDE, "EVENTS", 0, "One or more of the events"
+ " mousemove, mousebutton, keypress, output (default is keypress), if one"
+ " of these events occur the mouse cursor will be hidden " },
+ { "mouse-sensitivity", OPT_MOUSE_SENS, "SENSITIVITY", 0, "The mouse"
+ " sensitivity (default " DEFAULT_MOUSE_SENS_STRING "). A lower value"
+ " means more sensitive" },
+ { 0, 0 }
+};
+
+static const char args_doc[] = "CONSOLE";
+static const char doc[] = "A console client.";
+
+
+static error_t
+parse_startup_opt (int opt, char *arg, struct argp_state *state)
+{
+ int parse_events (char *events)
+ {
+ char *evtstr = strdupa (events);
+ char *tok = strtok (evtstr, ",");
+ int evmask = 0;
+
+ while (tok)
+ {
+ if (!strcasecmp ("mousemove", tok))
+ evmask |= CONS_EVT_MOUSE_MOVE;
+ else if (!strcasecmp ("mousebutton", tok))
+ evmask |= CONS_EVT_MOUSE_BUTTON;
+ else if (!strcasecmp ("keypress", tok))
+ evmask |= CONS_EVT_KEYPRESS;
+ else if (!strcasecmp ("output", tok))
+ evmask |= CONS_EVT_OUTPUT;
+ else
+ argp_error (state, "The event can be one of: MOUSEMOVE,"
+ " MOUSEBUTTON, KEYPRESS or OUTPUT");
+ tok = strtok (NULL, ",");
+ }
+ return evmask;
+ }
+
+ switch (opt)
+ {
+ case OPT_SLACK:
+ _cons_slack = atoi (arg);
+ break;
+
+ case OPT_JUMP_DOWN_ON_INPUT:
+ _cons_jump_down_on_input = 1;
+ break;
+
+ case OPT_NO_JUMP_DOWN_ON_INPUT:
+ _cons_jump_down_on_input = 0;
+ break;
+
+ case OPT_JUMP_DOWN_ON_OUTPUT:
+ _cons_jump_down_on_output = 1;
+ break;
+
+ case OPT_NO_JUMP_DOWN_ON_OUTPUT:
+ _cons_jump_down_on_output = 0;
+ break;
+
+ case OPT_AUDIBLE_BELL:
+ if (!strcasecmp ("on", arg) || !strcasecmp ("audible", arg))
+ _cons_audible_bell = BELL_AUDIBLE;
+ else if (!strcasecmp ("off", arg))
+ _cons_audible_bell = BELL_OFF;
+ else if (!strcasecmp ("visual", arg))
+ _cons_audible_bell = BELL_VISUAL;
+ else
+ argp_error (state, "The audible bell can be one of: on, off, visual, "
+ "audible");
+ break;
+
+ case OPT_VISUAL_BELL:
+ if (!strcasecmp ("on", arg) || !strcasecmp ("visual", arg))
+ _cons_visual_bell = BELL_VISUAL;
+ else if (!strcasecmp ("off", arg))
+ _cons_visual_bell = BELL_OFF;
+ else if (!strcasecmp ("audible", arg))
+ _cons_visual_bell = BELL_AUDIBLE;
+ else
+ argp_error (state, "The visual bell can be one of: on, off, visual, "
+ "audible");
+ break;
+
+ case OPT_MOUSE_SHOW:
+ _cons_show_mouse = parse_events (arg);
+ break;
+
+ case OPT_MOUSE_HIDE:
+ _cons_hide_mouse = parse_events (arg);
+ break;
+
+ case OPT_MOUSE_SENS:
+ {
+ char *tail;
+
+ errno = 0;
+ _cons_mouse_sens = strtod (arg, &tail);
+ if (tail == NULL || tail == arg || *tail != '\0')
+ argp_error (state, "SENSITIVITY is not a number: %s", arg);
+ if (errno)
+ argp_error (state, "Overflow in argument SENSITIVITY %s", arg);
+ break;
+ }
+
+ case ARGP_KEY_ARG:
+ if (state->arg_num > 0)
+ /* Too many arguments. */
+ argp_error (state, "Too many non option arguments");
+ cons_file = arg;
+ break;
+
+ case ARGP_KEY_NO_ARGS:
+ argp_error (state, "Filename of console server missing");
+ break;
+
+ default:
+ return ARGP_ERR_UNKNOWN;
+ }
+
+ return 0;
+}
+
+/* An argp structure for the standard console client command line
+ arguments. */
+const struct argp
+cons_startup_argp =
+{
+ startup_options, parse_startup_opt, args_doc, doc
+};
diff --git a/libcons/opts-version.c b/libcons/opts-version.c
new file mode 100644
index 00000000..f8751490
--- /dev/null
+++ b/libcons/opts-version.c
@@ -0,0 +1,44 @@
+/* opts-version.c - Default hook for argp --version handling
+ Copyright (C) 1996, 2002 Free Software Foundation, Inc.
+ Written by Miles Bader <miles@gnu.ai.mit.edu> and Marcus Brinkmann.
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ The GNU Hurd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include <stdio.h>
+#include <argp.h>
+#include <version.h>
+
+#include "priv.h"
+
+static void
+_print_version (FILE *stream, struct argp_state *state)
+{
+ if (argp_program_version)
+ /* If this is non-zero, then the program's probably defined it, so let
+ that take precedence over the default. */
+ fputs (argp_program_version, stream);
+ else if (cons_extra_version && *cons_extra_version)
+ fprintf (stream, "%s (%s) %s\n",
+ cons_client_name, cons_extra_version, cons_client_version);
+ else
+ fprintf (stream, "%s %s\n", cons_client_name, cons_client_version);
+
+ fputs (STANDARD_HURD_VERSION (libcons) "\n", stream);
+}
+
+void (*argp_program_version_hook) (FILE *stream, struct argp_state *state)
+ = _print_version;
diff --git a/libcons/priv.h b/libcons/priv.h
new file mode 100644
index 00000000..38971ff8
--- /dev/null
+++ b/libcons/priv.h
@@ -0,0 +1,93 @@
+/* Private declarations for cons library
+ Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#ifndef _CONS_PRIV_H
+#define _CONS_PRIV_H
+
+#include "cons.h"
+
+
+/* The kind of bells available. */
+typedef enum
+ {
+ BELL_OFF,
+ BELL_VISUAL,
+ BELL_AUDIBLE
+ } bell_type_t;
+
+#define CONS_EVT_MOUSE_MOVE (1 << 1)
+#define CONS_EVT_MOUSE_BUTTON (1 << 2)
+#define CONS_EVT_KEYPRESS (1 << 4)
+#define CONS_EVT_OUTPUT (1 << 8)
+
+
+/* Number of records the client is allowed to lag behind the
+ server. */
+extern int _cons_slack;
+
+/* If we jump down at input. */
+extern int _cons_jump_down_on_input;
+
+/* If we jump down at output. */
+extern int _cons_jump_down_on_output;
+
+/* The type of bell used for the visual bell. */
+extern bell_type_t _cons_visual_bell;
+
+/* The type of bell used for the audible bell. */
+extern bell_type_t _cons_audible_bell;
+
+/* The type of events that will make the mouse cursor visible. */
+extern int _cons_show_mouse;
+
+/* The type of events that will hide the mouse cursor. */
+extern int _cons_hide_mouse;
+
+/* The mouse sensitivity. */
+extern float _cons_mouse_sens;
+
+
+/* Non-locking version of cons_vcons_scrollback. Does also not update
+ the display. */
+int _cons_vcons_scrollback (vcons_t vcons, cons_scroll_t type, float value);
+
+/* Non-locking version of cons_vcons_input. */
+error_t _cons_vcons_input (vcons_t vcons, char *buf, size_t size);
+
+/* Generate the console event EVENT for console VCONS. */
+void _cons_vcons_console_event (vcons_t vcons, int event);
+
+
+/* Called by MiG to translate ports into cons_notify_t. mutations.h
+ arranges for this to happen for the fs_notify interfaces. */
+static inline cons_notify_t
+begin_using_notify_port (fs_notify_t port)
+{
+ return ports_lookup_port (cons_port_bucket, port, cons_port_class);
+}
+
+/* Called by MiG after server routines have been run; this balances
+ begin_using_notify_port, and is arranged for the fs_notify
+ interfaces by mutations.h. */
+static inline void
+end_using_notify_port (cons_notify_t cred)
+{
+ if (cred)
+ ports_port_deref (cred);
+}
+
+#endif /* _CONS_PRIV_H */
diff --git a/libcons/vcons-add.c b/libcons/vcons-add.c
new file mode 100644
index 00000000..1a6eb204
--- /dev/null
+++ b/libcons/vcons-add.c
@@ -0,0 +1,30 @@
+/* vcons-add.c - Add a virtual console.
+ Copyright (C) 2002 Free Software Foundation, Inc.
+ Written by Marcus Brinkmann.
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ The GNU Hurd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
+
+#include <errno.h>
+
+#include "cons.h"
+
+/* The virtual console entry VCONS_ENTRY was just added. CONS is
+ locked. */
+void
+cons_vcons_add (cons_t cons, vcons_list_t vcons_entry)
+{
+}
diff --git a/libcons/vcons-close.c b/libcons/vcons-close.c
new file mode 100644
index 00000000..33a38982
--- /dev/null
+++ b/libcons/vcons-close.c
@@ -0,0 +1,45 @@
+/* vcons-close.c - Close a virtual console.
+ Copyright (C) 2002 Free Software Foundation, Inc.
+ Written by Marcus Brinkmann.
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ The GNU Hurd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
+
+#include <assert.h>
+
+#include <hurd.h>
+#include <hurd/ports.h>
+#include <cthreads.h>
+
+#include "cons.h"
+
+/* Close the virtual console VCONS. */
+void
+cons_vcons_close (vcons_t vcons)
+{
+ cons_t cons = vcons->cons;
+ vcons_list_t vcons_entry = vcons->vcons_entry;
+
+ mutex_lock (&cons->lock);
+ /* The same virtual console should never be opened twice. */
+ assert (vcons_entry->vcons == vcons);
+ vcons_entry->vcons = NULL;
+ mutex_unlock (&cons->lock);
+
+ /* Destroy the port. */
+ ports_port_deref (vcons);
+ ports_destroy_right (vcons);
+}
diff --git a/libcons/vcons-destroy.c b/libcons/vcons-destroy.c
new file mode 100644
index 00000000..ca1c5c37
--- /dev/null
+++ b/libcons/vcons-destroy.c
@@ -0,0 +1,52 @@
+/* vcons-destroy.c - Clean up the resources for a virtual console.
+ Copyright (C) 2002 Free Software Foundation, Inc.
+ Written by Marcus Brinkmann.
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ The GNU Hurd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <sys/mman.h>
+#include <sys/fcntl.h>
+
+#include <hurd.h>
+#include <mach.h>
+
+#include "cons.h"
+
+/* Destroy the virtual console VCONS. */
+void
+cons_vcons_destroy (void *port)
+{
+ cons_notify_t notify = (cons_notify_t) port;
+ vcons_t vcons = (vcons_t) port;
+
+ if (notify->cons)
+ return;
+
+ if (vcons->input >= 0)
+ {
+ close (vcons->input);
+ vcons->input = -1;
+ }
+ if (vcons->display != MAP_FAILED)
+ {
+ munmap (vcons->display, vcons->display_size);
+ vcons->display = MAP_FAILED;
+ }
+}
diff --git a/libcons/vcons-event.c b/libcons/vcons-event.c
new file mode 100644
index 00000000..d8c31dc0
--- /dev/null
+++ b/libcons/vcons-event.c
@@ -0,0 +1,31 @@
+/* vcons-event.c - Handle console events.
+ Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+ Written by Marco Gerards.
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ The GNU Hurd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
+
+#include "cons.h"
+#include "priv.h"
+
+void
+_cons_vcons_console_event (vcons_t vcons, int event)
+{
+ if (_cons_show_mouse & event)
+ cons_vcons_set_mousecursor_status (vcons, 1);
+ else if (_cons_hide_mouse & event)
+ cons_vcons_set_mousecursor_status (vcons, 0);
+}
diff --git a/libcons/vcons-input.c b/libcons/vcons-input.c
new file mode 100644
index 00000000..e008b9c9
--- /dev/null
+++ b/libcons/vcons-input.c
@@ -0,0 +1,64 @@
+/* vcons-input.c - Add input to a virtual console.
+ Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
+ Written by Marcus Brinkmann.
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ The GNU Hurd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
+
+#include <errno.h>
+#include <unistd.h>
+
+#include "cons.h"
+#include "priv.h"
+
+/* Non-locking version of cons_vcons_input. */
+error_t
+_cons_vcons_input (vcons_t vcons, char *buf, size_t size)
+{
+ int ret;
+
+ do
+ {
+ ret = write (vcons->input, buf, size);
+ if (ret > 0)
+ {
+ size -= ret;
+ buf += ret;
+ }
+ }
+ while (size && (ret != -1 || errno == EINTR));
+
+ return 0;
+}
+
+
+/* Enter SIZE bytes from the buffer BUF into the virtual console
+ VCONS. */
+error_t
+cons_vcons_input (vcons_t vcons, char *buf, size_t size)
+{
+ mutex_lock (&vcons->lock);
+
+ _cons_vcons_console_event (vcons, CONS_EVT_KEYPRESS);
+
+ if (vcons->scrolling && _cons_jump_down_on_input)
+ _cons_vcons_scrollback (vcons, CONS_SCROLL_ABSOLUTE_LINE, 0);
+
+ _cons_vcons_input (vcons, buf, size);
+
+ mutex_unlock (&vcons->lock);
+ return 0;
+}
diff --git a/libcons/vcons-move-mouse.c b/libcons/vcons-move-mouse.c
new file mode 100644
index 00000000..1e5f7b9f
--- /dev/null
+++ b/libcons/vcons-move-mouse.c
@@ -0,0 +1,103 @@
+/* vcons-move-mouse.c - Catch mouse events.
+ Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+ Written by Marco Gerards.
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ The GNU Hurd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
+
+#include <errno.h>
+#include <unistd.h>
+
+#include "cons.h"
+#include "priv.h"
+
+static float mousepos_x;
+static float mousepos_y;
+
+error_t
+cons_vcons_move_mouse (vcons_t vcons, mouse_event_t ev)
+{
+ char event[CONS_MOUSE_EVENT_LENGTH];
+ uint32_t report_events;
+
+ mutex_lock (&vcons->lock);
+ report_events = vcons->display->flags & CONS_FLAGS_TRACK_MOUSE;
+
+ switch (ev->mouse_movement)
+ {
+ case CONS_VCONS_MOUSE_MOVE_REL:
+ mousepos_x += ((float) ev->x / _cons_mouse_sens);
+ mousepos_y += ((float) ev->y / _cons_mouse_sens);
+ break;
+
+ case CONS_VCONS_MOUSE_MOVE_ABS_PERCENT:
+ mousepos_x = vcons->state.screen.width * ev->x / 100;
+ mousepos_y = vcons->state.screen.height * ev->y / 100;
+
+ case CONS_VCONS_MOUSE_MOVE_ABS:
+ mousepos_x = ev->x;
+ mousepos_y = ev->y;
+ break;
+ }
+
+ /* Keep the mouse cursor in range of the VC. */
+ if (mousepos_x < 0)
+ mousepos_x = 0;
+ if (mousepos_y < 0)
+ mousepos_y = 0;
+ if (mousepos_x >= (float) vcons->state.screen.width)
+ mousepos_x = vcons->state.screen.width - 1;
+ if (mousepos_y >= (float) vcons->state.screen.height)
+ mousepos_y = vcons->state.screen.height - 1;
+
+ cons_vcons_set_mousecursor_pos (vcons, (float) mousepos_x, (float) mousepos_y);
+
+ /* Report a mouse movement event. */
+ if (ev->x || ev->y)
+ _cons_vcons_console_event (vcons, CONS_EVT_MOUSE_MOVE);
+
+ /* Report a mouse button event. */
+ if (ev->mouse_button != CONS_VCONS_MOUSE_BUTTON_NO_OP)
+ _cons_vcons_console_event (vcons, CONS_EVT_MOUSE_BUTTON);
+
+ if (report_events)
+ {
+ switch (ev->mouse_button)
+ {
+ case CONS_VCONS_MOUSE_BUTTON_NO_OP:
+ break;
+
+ case CONS_VCONS_MOUSE_BUTTON_PRESSED:
+ /* Make an xterm like event string. */
+ CONS_MOUSE_EVENT (event, ev->button, (int) mousepos_x + 1, (int) mousepos_y + 1);
+
+ _cons_vcons_input (vcons, event, CONS_MOUSE_EVENT_LENGTH);
+ /* And send it to the server. */
+ break;
+
+ case CONS_VCONS_MOUSE_BUTTON_RELEASED:
+ /* Make an xterm like event string. */
+ CONS_MOUSE_EVENT (event, CONS_MOUSE_RELEASE, (int) mousepos_x + 1, (int) mousepos_y + 1);
+
+ /* And send it to the server. */
+ _cons_vcons_input (vcons, event, CONS_MOUSE_EVENT_LENGTH);
+ break;
+ }
+ }
+
+ mutex_unlock (&vcons->lock);
+ return 0;
+}
diff --git a/libcons/vcons-open.c b/libcons/vcons-open.c
new file mode 100644
index 00000000..8c34fc5e
--- /dev/null
+++ b/libcons/vcons-open.c
@@ -0,0 +1,175 @@
+/* vcons-open.c - Open a virtual console.
+ Copyright (C) 2002 Free Software Foundation, Inc.
+ Written by Marcus Brinkmann.
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ The GNU Hurd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <sys/mman.h>
+#include <sys/fcntl.h>
+
+#include <hurd.h>
+#include <mach.h>
+
+#include "cons.h"
+
+/* Open the virtual console for VCONS_ENTRY. CONS is locked.
+ Afterwards, R_VCONS will be locked. */
+error_t
+cons_vcons_open (cons_t cons, vcons_list_t vcons_entry, vcons_t *r_vcons)
+{
+ error_t err = 0;
+ char *name;
+ file_t vconsp = MACH_PORT_NULL;
+ file_t file = MACH_PORT_NULL;
+ int fd = -1;
+ struct stat statbuf;
+ mach_port_t notify = MACH_PORT_NULL;
+ vcons_t vcons;
+
+ if (asprintf (&name, "%u", vcons_entry->id) < 0)
+ return err;
+
+ /* Set up the port we receive notification messages on. */
+ err = ports_create_port (cons_port_class, cons_port_bucket,
+ sizeof (*vcons), &vcons);
+ if (err)
+ goto err;
+ vcons->notify.cons = NULL;
+ vcons->cons = cons;
+ vcons->vcons_entry = vcons_entry;
+ vcons->id = vcons_entry->id;
+ mutex_init (&vcons->lock);
+ vcons->input = -1;
+ vcons->display = MAP_FAILED;
+ vcons->scrolling = 0;
+
+ /* Open the directory port of the virtual console. */
+ vconsp = file_name_lookup_under (cons->dirport, name,
+ O_DIRECTORY | O_RDONLY, 0);
+ if (vconsp == MACH_PORT_NULL)
+ {
+ err = errno;
+ goto err;
+ }
+
+ /* Within that directory, open the input node. */
+ file = file_name_lookup_under (vconsp, "input", O_WRONLY /* | O_NONBLOCK */, 0);
+ if (file == MACH_PORT_NULL)
+ err = errno;
+ else
+ {
+ vcons->input = openport (file, O_WRONLY /* | O_NONBLOCK */);
+ if (vcons->input < 0)
+ err = errno;
+ else
+ /* openport() consumed the reference. */
+ file = MACH_PORT_NULL;
+ }
+ if (err)
+ goto err;
+
+ /* Within that directory, also open the display node. */
+ file = file_name_lookup_under (vconsp, "display", O_RDONLY, 0);
+ if (file == MACH_PORT_NULL)
+ err = errno;
+ else
+ {
+ /* Acquire an additional reference for openport(). */
+ err = mach_port_mod_refs (mach_task_self (), file,
+ MACH_PORT_RIGHT_SEND, +1);
+ if (err)
+ goto err;
+ fd = openport (file, O_RDONLY);
+ if (fd < 0)
+ err = errno;
+ }
+ if (err)
+ goto err;
+
+ /* Map the whole file. */
+ if (fstat (fd, &statbuf) < 0)
+ {
+ err = errno;
+ goto err;
+ }
+ vcons->display_size = statbuf.st_size;
+ vcons->display = mmap (0, vcons->display_size, PROT_READ, MAP_SHARED, fd, 0);
+ if (vcons->display == MAP_FAILED)
+ {
+ err = errno;
+ goto err;
+ }
+
+ if (vcons->display->magic != CONS_MAGIC
+ || vcons->display->version >> CONS_VERSION_MAJ_SHIFT != 0)
+ {
+ err = EINVAL;
+ goto err;
+ }
+ vcons->state.screen.width = vcons->display->screen.width;
+ vcons->state.screen.height = vcons->display->screen.height;
+ vcons->state.screen.lines = vcons->display->screen.lines;
+ vcons->state.screen.matrix = (conchar_t *)
+ (((uint32_t *) vcons->display) + vcons->display->screen.matrix);
+ vcons->state.changes.length = vcons->display->changes.length;
+ vcons->state.changes.buffer = (cons_change_t *)
+ (((uint32_t *) vcons->display) + vcons->display->changes.buffer);
+
+ /* Request notification messages. */
+ notify = ports_get_right (vcons);
+ mach_port_set_qlimit (mach_task_self (), notify, 1);
+
+ /* When this succeeds, we will immediately receive notification
+ messages for this virtual console. */
+ mutex_lock (&vcons->lock);
+ err = file_notice_changes (file, notify, MACH_MSG_TYPE_MAKE_SEND);
+ if (!err)
+ {
+ *r_vcons = vcons;
+ goto out;
+ }
+
+ err:
+ if (vcons->input >= 0)
+ {
+ close (vcons->input);
+ vcons->input = -1;
+ }
+ if (vcons->display != MAP_FAILED)
+ {
+ munmap (vcons->display, vcons->display_size);
+ vcons->display = MAP_FAILED;
+ }
+ if (notify)
+ {
+ mach_port_deallocate (mach_task_self (), notify);
+ ports_port_deref (vcons);
+ }
+ ports_destroy_right (vcons);
+ out:
+ if (fd > 0)
+ close (fd);
+ if (file != MACH_PORT_NULL)
+ mach_port_deallocate (mach_task_self (), file);
+ if (vconsp != MACH_PORT_NULL)
+ mach_port_deallocate (mach_task_self (), vconsp);
+ free (name);
+ return err;
+}
diff --git a/libcons/vcons-refresh.c b/libcons/vcons-refresh.c
new file mode 100644
index 00000000..ce6807fe
--- /dev/null
+++ b/libcons/vcons-refresh.c
@@ -0,0 +1,76 @@
+/* vcons-refresh.c - Redraw a virtual console.
+ Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+ Written by Marcus Brinkmann.
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ The GNU Hurd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
+
+#include <errno.h>
+#include <assert.h>
+
+#include "cons.h"
+#include "priv.h"
+
+/* Redraw the virtual console VCONS, which is locked. */
+void
+cons_vcons_refresh (vcons_t vcons)
+{
+ uint32_t start;
+ vcons->state.screen.cur_line = vcons->display->screen.cur_line;
+ vcons->state.screen.scr_lines = vcons->display->screen.scr_lines;
+ vcons->state.cursor.col = vcons->display->cursor.col;
+ vcons->state.cursor.row = vcons->display->cursor.row;
+ vcons->state.cursor.status = vcons->display->cursor.status;
+ vcons->state.bell.audible = vcons->display->bell.audible;
+ vcons->state.bell.visible = vcons->display->bell.visible;
+ vcons->state.flags = vcons->display->flags;
+ vcons->state.changes.written = vcons->display->changes.written;
+
+ if (vcons->state.screen.scr_lines < vcons->scrolling)
+ vcons->scrolling = vcons->scrolling;
+
+ cons_vcons_set_dimension (vcons, vcons->state.screen.width,
+ vcons->state.screen.height);
+
+ if (vcons->state.screen.cur_line >= vcons->scrolling)
+ start = vcons->state.screen.cur_line - vcons->scrolling;
+ else
+ start = (UINT32_MAX
+ - (vcons->scrolling - vcons->state.screen.cur_line)) + 1;
+ start %= vcons->state.screen.lines;
+
+ cons_vcons_write (vcons, vcons->state.screen.matrix
+ + start * vcons->state.screen.width,
+ ((vcons->state.screen.lines - start
+ < vcons->state.screen.height)
+ ? vcons->state.screen.lines - start
+ : vcons->state.screen.height)
+ * vcons->state.screen.width, 0, 0);
+ if (vcons->state.screen.lines - start < vcons->state.screen.height)
+ cons_vcons_write (vcons, vcons->state.screen.matrix,
+ vcons->state.screen.height * vcons->state.screen.width
+ - (vcons->state.screen.lines - start)
+ * vcons->state.screen.width, 0,
+ vcons->state.screen.lines - start);
+
+ cons_vcons_set_cursor_pos (vcons, vcons->state.cursor.col,
+ vcons->state.cursor.row);
+ cons_vcons_set_cursor_status (vcons, vcons->state.cursor.status);
+ cons_vcons_set_scroll_lock (vcons, vcons->state.flags
+ & CONS_FLAGS_SCROLL_LOCK);
+ _cons_vcons_console_event (vcons, CONS_EVT_OUTPUT);
+ cons_vcons_update (vcons);
+}
diff --git a/libcons/vcons-remove.c b/libcons/vcons-remove.c
new file mode 100644
index 00000000..34b31d6f
--- /dev/null
+++ b/libcons/vcons-remove.c
@@ -0,0 +1,31 @@
+/* vcons-remove.c - Remove a virtual console.
+ Copyright (C) 2002 Free Software Foundation, Inc.
+ Written by Marcus Brinkmann.
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ The GNU Hurd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
+
+#include <assert.h>
+
+#include "cons.h"
+
+/* The virtual console VCONS_ENTRY is going to be removed.
+ VCONS_ENTRY->cons is locked. */
+void
+cons_vcons_remove (cons_t cons, vcons_list_t vcons_entry)
+{
+ assert (!vcons_entry->vcons);
+}
diff --git a/libcons/vcons-scrollback.c b/libcons/vcons-scrollback.c
new file mode 100644
index 00000000..77c8c211
--- /dev/null
+++ b/libcons/vcons-scrollback.c
@@ -0,0 +1,164 @@
+/* vcons-scrollback.c - Move forward and backward in the scrollback buffer.
+ Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
+ Written by Marcus Brinkmann.
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ The GNU Hurd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
+
+#include <stdint.h>
+
+#include <cthreads.h>
+
+#include "cons.h"
+#include "priv.h"
+
+/* Non-locking version of cons_vcons_scrollback. Does also not update
+ the display. */
+int
+_cons_vcons_scrollback (vcons_t vcons, cons_scroll_t type, float value)
+{
+ int scrolling;
+ uint32_t new_scr;
+
+ switch (type)
+ {
+ case CONS_SCROLL_DELTA_LINES:
+ scrolling = vcons->scrolling + ((uint32_t) value);
+ break;
+ case CONS_SCROLL_DELTA_SCREENS:
+ scrolling = vcons->scrolling
+ + ((uint32_t) (value * vcons->state.screen.height));
+ break;
+ case CONS_SCROLL_ABSOLUTE_LINE:
+ scrolling = (uint32_t) value;
+ break;
+ case CONS_SCROLL_ABSOLUTE_PERCENTAGE:
+ scrolling = (uint32_t) (value * vcons->state.screen.scr_lines);
+ break;
+ default:
+ return 0;
+ }
+
+ if (scrolling < 0)
+ new_scr = 0;
+ else if (scrolling > vcons->state.screen.scr_lines)
+ new_scr = vcons->state.screen.scr_lines;
+ else
+ new_scr = scrolling;
+
+ if (new_scr == vcons->scrolling)
+ return 0;
+
+ scrolling = vcons->scrolling - new_scr;
+ {
+ uint32_t new_cur_line;
+ off_t size = vcons->state.screen.width
+ * vcons->state.screen.lines;
+ off_t vis_start;
+ off_t start;
+ off_t end;
+
+ if (vcons->state.screen.cur_line >= new_scr)
+ new_cur_line = vcons->state.screen.cur_line - new_scr;
+ else
+ new_cur_line = (UINT32_MAX - (new_scr - vcons->state.screen.cur_line)) + 1;
+
+ if (scrolling > 0 && (uint32_t) scrolling > vcons->state.screen.height)
+ scrolling = vcons->state.screen.height;
+ else if (scrolling < 0
+ && (uint32_t) (-scrolling) > vcons->state.screen.height)
+ scrolling = -vcons->state.screen.height;
+ if ((scrolling > 0 && scrolling < vcons->state.screen.height)
+ || (scrolling < 0
+ && (uint32_t) (-scrolling) < vcons->state.screen.height))
+ cons_vcons_scroll (vcons, scrolling);
+ else if ((scrolling > 0 && scrolling == vcons->state.screen.height)
+ || (scrolling < 0
+ && (uint32_t) (-scrolling) == vcons->state.screen.height))
+ cons_vcons_clear (vcons, vcons->state.screen.width
+ * vcons->state.screen.height, 0, 0);
+
+ vis_start = vcons->state.screen.width
+ * (new_cur_line % vcons->state.screen.lines);
+ if (scrolling > 0)
+ start = (((new_cur_line % vcons->state.screen.lines)
+ + vcons->state.screen.height - scrolling)
+ * vcons->state.screen.width) % size;
+ else
+ start = vis_start;
+ end = start + abs (scrolling) * vcons->state.screen.width - 1;
+
+ cons_vcons_write (vcons,
+ vcons->state.screen.matrix + start,
+ end < size
+ ? end - start + 1
+ : size - start,
+ 0, (scrolling > 0)
+ ? vcons->state.screen.height - scrolling : 0);
+ if (end >= size)
+ cons_vcons_write (vcons,
+ vcons->state.screen.matrix,
+ end - size + 1,
+ 0, (size - vis_start)
+ / vcons->state.screen.width);
+ }
+
+ /* Set the new cursor position. */
+ {
+ uint32_t row = vcons->state.cursor.row;
+ uint32_t height = vcons->state.screen.height;
+
+ if (row + new_scr < height)
+ {
+ cons_vcons_set_cursor_pos (vcons, vcons->state.cursor.col,
+ row + new_scr);
+ if (row + vcons->scrolling >= height)
+ /* The cursor was invisible before. */
+ cons_vcons_set_cursor_status (vcons, vcons->state.cursor.status);
+ }
+ else if (row + vcons->scrolling < height)
+ /* The cursor was visible before. */
+ cons_vcons_set_cursor_status (vcons, CONS_CURSOR_INVISIBLE);
+ }
+
+ vcons->scrolling -= scrolling;
+
+ return -scrolling;
+}
+
+/* Scroll back into the history of VCONS. If TYPE is
+ CONS_SCROLL_DELTA_LINES, scroll up or down by VALUE lines. If TYPE
+ is CONS_SCROLL_DELTA_SCREENS, scroll up or down by VALUE multiples
+ of a screen height. If TYPE is CONS_SCROLL_ABSOLUTE_LINE, scroll to
+ line VALUE (where 0 is the lowest line). If TYPE is
+ CONS_SCROLL_ABSOLUTE_PERCENTAGE, scroll to the position determined
+ by VALUE, where 0 is the bottom and 1 is the top.
+
+ The function returns the number of lines actually scrolled up or
+ down. */
+int
+cons_vcons_scrollback (vcons_t vcons, cons_scroll_t type, float value)
+{
+ int ret;
+
+ mutex_lock (&vcons->lock);
+ ret = _cons_vcons_scrollback (vcons, type, value);
+ _cons_vcons_console_event (vcons, CONS_EVT_OUTPUT);
+ cons_vcons_update (vcons);
+ mutex_unlock (&vcons->lock);
+ return ret;
+}
+