summaryrefslogtreecommitdiff
path: root/console
diff options
context:
space:
mode:
authorMarcus Brinkmann <marcus@gnu.org>2002-06-13 00:24:26 +0000
committerMarcus Brinkmann <marcus@gnu.org>2002-06-13 00:24:26 +0000
commitccc4092e238c5e074a32e2c5794ab01934f272df (patch)
treed1cbbed8182717c1bc1eba4c288b400b4ed36324 /console
parent693eb63d90f9036680e538bc84275a32f707f926 (diff)
2002-06-13 Marcus Brinkmann <marcus@gnu.org>
* Makefile (DIST_FILES): New target. (MIGSTUBS): Likewise. (OBJS): Add $(MIGSTUBS). * ourfs_notify.defs: New file. * console.c: Diddle order of typedefs. (netfs_attempt_read): Clip AMT to bytes left to read before calling display_read. (netfs_S_file_notice_changes): New function. * console.h: Include <stdint.h>, not <sys/types.h>. Change all types from u_int32_t to uint32_t. * display.c: Include <stddef.h> and "outfs_notify_U.h". Change all u_int_32 types to uint32_t. (struct modreq): New structure. (struct display): New member filemod_reqs. (free_modreqs): New function. (display_notice_changes): Likewise. (display_notice_filechange): Likewise. (display_destroy): Free filemod_reqs member of DISPLAY. (MATRIX_POS): Macro removed. (screen_fill): Rewritten. (screen_shift_left): New function. (screen_shift_right): Likewise. (screen_scroll_up): Function removed. (screen_scroll_down): Likewise. (screen_scroll_left): Likewise. (screen_scroll_right): Likewise. (handle_esc_bracket): Use new screen_* functions. (display_output_one): Store old cursor and screen attributes, and if they have been changed, send file change notifications. * display.h: New prototype for display_notice_changes.
Diffstat (limited to 'console')
-rw-r--r--console/ChangeLog33
-rw-r--r--console/Makefile5
-rw-r--r--console/console.c41
-rw-r--r--console/console.h26
-rw-r--r--console/display.c376
-rw-r--r--console/display.h2
-rw-r--r--console/ourfs_notify.defs5
7 files changed, 343 insertions, 145 deletions
diff --git a/console/ChangeLog b/console/ChangeLog
index 53fa34a8..54fa609c 100644
--- a/console/ChangeLog
+++ b/console/ChangeLog
@@ -1,3 +1,36 @@
+2002-06-13 Marcus Brinkmann <marcus@gnu.org>
+
+ * Makefile (DIST_FILES): New target.
+ (MIGSTUBS): Likewise.
+ (OBJS): Add $(MIGSTUBS).
+ * ourfs_notify.defs: New file.
+ * console.c: Diddle order of typedefs.
+ (netfs_attempt_read): Clip AMT to bytes left to read before
+ calling display_read.
+ (netfs_S_file_notice_changes): New function.
+ * console.h: Include <stdint.h>, not <sys/types.h>.
+ Change all types from u_int32_t to uint32_t.
+ * display.c: Include <stddef.h> and "outfs_notify_U.h". Change
+ all u_int_32 types to uint32_t.
+ (struct modreq): New structure.
+ (struct display): New member filemod_reqs.
+ (free_modreqs): New function.
+ (display_notice_changes): Likewise.
+ (display_notice_filechange): Likewise.
+ (display_destroy): Free filemod_reqs member of DISPLAY.
+ (MATRIX_POS): Macro removed.
+ (screen_fill): Rewritten.
+ (screen_shift_left): New function.
+ (screen_shift_right): Likewise.
+ (screen_scroll_up): Function removed.
+ (screen_scroll_down): Likewise.
+ (screen_scroll_left): Likewise.
+ (screen_scroll_right): Likewise.
+ (handle_esc_bracket): Use new screen_* functions.
+ (display_output_one): Store old cursor and screen attributes, and
+ if they have been changed, send file change notifications.
+ * display.h: New prototype for display_notice_changes.
+
2002-06-12 Marcus Brinkmann <marcus@gnu.org>
* console.c: Include <argz.h>. Do not include "console.h", but
diff --git a/console/Makefile b/console/Makefile
index 2e227269..2f15f1a1 100644
--- a/console/Makefile
+++ b/console/Makefile
@@ -25,9 +25,12 @@ target = console
SRCS = console.c display.c input.c
LCLHDRS = console.h display.h input.h
+DIST_FILES = ourfs_notify.defs
+
+MIGSTUBS = ourfs_notifyUser.o
HURDLIBS = netfs fshelp iohelp threads ports ihash shouldbeinlibc
-OBJS = $(subst .c,.o,$(SRCS))
+OBJS = $(sort $(SRCS:.c=.o) $(MIGSTUBS))
# This is the old monolithic version of the console server.
#SRCS = main.c vcons.c focus.c vga-display.c vga.c dynafont.c bdf.c
diff --git a/console/console.c b/console/console.c
index 3c1c5ce2..7d12db9f 100644
--- a/console/console.c
+++ b/console/console.c
@@ -52,6 +52,12 @@ volatile struct mapped_time_value *console_maptime;
#define DEFAULT_ENCODING "ISO-8859-1"
+/* A handle for a console device. */
+typedef struct cons *cons_t;
+
+/* A handle for a virtual console device. */
+typedef struct vcons *vcons_t;
+
struct vcons
{
/* Protected by cons->lock. */
@@ -75,8 +81,6 @@ struct vcons
struct node *disp_node;
struct node *inpt_node;
};
-/* A handle for a virtual console device. */
-typedef struct vcons *vcons_t;
struct cons
{
@@ -93,8 +97,6 @@ struct cons
/* A template for the stat information of all nodes. */
struct stat stat_template;
};
-/* A handle for a console device. */
-typedef struct cons *cons_t;
/* Lookup the virtual console with number ID in the console CONS,
@@ -1051,11 +1053,14 @@ netfs_attempt_read (struct iouser *cred, struct node *np,
ssize_t amt = *len;
assert (np == vcons->disp_node);
- if (amt > np->nn_stat.st_size)
- amt = np->nn_stat.st_size;
- amt = display_read (vcons->display,
- /* cred->po->openstat & O_NONBLOCK */ 0,
- offset, data, amt);
+ if (offset + amt > np->nn_stat.st_size)
+ amt = np->nn_stat.st_size - offset;
+ if (amt < 0)
+ amt = 0;
+ else
+ amt = display_read (vcons->display,
+ /* cred->po->openstat & O_NONBLOCK */ 0,
+ offset, data, amt);
if (amt == -1)
err = errno;
else
@@ -1166,6 +1171,24 @@ netfs_S_io_map (struct protid *cred,
}
+kern_return_t
+netfs_S_file_notice_changes (struct protid *cred, mach_port_t notify)
+{
+ struct node *np;
+ vcons_t vcons;
+
+ if (!cred)
+ return EOPNOTSUPP;
+
+ np = cred->po->np;
+ vcons = np->nn->vcons;
+ if (!vcons || np != vcons->disp_node)
+ return EOPNOTSUPP;
+
+ return display_notice_changes (vcons->display, notify);
+}
+
+
static const struct argp_option options[] =
{
{"encoding", 'e', "NAME", 0, "Set encoding of virtual consoles to"
diff --git a/console/console.h b/console/console.h
index 27996955..08f35955 100644
--- a/console/console.h
+++ b/console/console.h
@@ -19,41 +19,43 @@
#ifndef _HURD_CONSOLE_H
#define _HURD_CONSOLE_H
-#include <sys/types.h>
+#include <stdint.h>
struct cons_display
{
#define CONS_MAGIC 0x48555244 /* Hex for "HURD". */
- u_int32_t magic; /* CONS_MAGIC, use to detect
+ uint32_t magic; /* CONS_MAGIC, use to detect
endianess. */
#define CONS_VERSION_MAJ 0x0
#define CONS_VERSION_MAJ_SHIFT 16
#define CONS_VERSION_AGE 0x0
- u_int32_t version; /* Version of interface. Lower 16
+ uint32_t version; /* Version of interface. Lower 16
bits define the age, upper 16 bits
the major version. */
struct
{
- u_int32_t width; /* Width of screen matrix. */
- u_int32_t lines; /* Length of whole matrix. */
- u_int32_t cur_line; /* Beginning of visible area. */
- u_int32_t scr_lines;/* Number of lines in scrollback buffer
+ uint32_t width; /* Width of screen matrix. */
+ uint32_t lines; /* Length of whole matrix. */
+ uint32_t cur_line; /* Beginning of visible area. This is only
+ ever increased by the server, so clients
+ can optimize scrolling. */
+ uint32_t scr_lines;/* Number of lines in scrollback buffer
preceeding CUR_LINE. */
- u_int32_t height; /* Number of lines in visible area following
+ uint32_t height; /* Number of lines in visible area following
(and including) CUR_LINE. */
- u_int32_t matrix; /* Index (in wchar_t) of the beginning of
+ uint32_t matrix; /* Index (in wchar_t) of the beginning of
screen matrix in this structure. */
} screen;
struct
{
- u_int32_t col; /* Current column (x-position) of cursor. */
- u_int32_t row; /* Current row (y-position) of cursor. */
+ uint32_t col; /* Current column (x-position) of cursor. */
+ uint32_t row; /* Current row (y-position) of cursor. */
#define CONS_CURSOR_INVISIBLE 0
#define CONS_CURSOR_NORMAL 1
#define CONS_CURSOR_VERY_VISIBLE 2
- u_int32_t status; /* Visibility status of cursor. */
+ uint32_t status; /* Visibility status of cursor. */
} cursor;
/* Don't use this, use ((wchar_t *) cons_display +
diff --git a/console/display.c b/console/display.c
index 9c33b933..fe2dc4f0 100644
--- a/console/display.c
+++ b/console/display.c
@@ -18,6 +18,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
+#include <stddef.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
@@ -36,6 +37,8 @@
#include <hurd.h>
#include <hurd/pager.h>
+#include "ourfs_notify_U.h"
+
#ifndef __STDC_ISO_10646__
#error It is required that wchar_t is UCS-4.
#endif
@@ -46,8 +49,8 @@
struct cursor
{
- u_int32_t saved_x;
- u_int32_t saved_y;
+ uint32_t saved_x;
+ uint32_t saved_y;
};
typedef struct cursor *cursor_t;
@@ -114,6 +117,13 @@ struct user_pager_info
struct pager *p;
};
+/* Pending directory and file modification requests. */
+struct modreq
+{
+ mach_port_t port;
+ struct modreq *next;
+};
+
struct display
{
/* The lock for the virtual console display structure. */
@@ -133,6 +143,9 @@ struct display
struct user_pager_info *upi;
memory_object_t memobj;
size_t memobj_size;
+
+ /* A list of ports to send file change notifications to. */
+ struct modreq *filemod_reqs;
};
@@ -159,8 +172,6 @@ pager_clear_user_data (struct user_pager_info *upi)
free (upi);
}
-/* XXX This is not good enough. We actually need to provide a backing
- store. */
error_t
pager_read_page (struct user_pager_info *pager, vm_offset_t page,
vm_address_t *buf, int *writelock)
@@ -178,7 +189,8 @@ pager_write_page (struct user_pager_info *pager,
vm_offset_t page,
vm_address_t buf)
{
- /* XXX Implement me. */
+ /* XXX Implement me. Just store away the page, and release it when
+ releasing the pager. */
assert (0);
}
@@ -220,14 +232,79 @@ service_paging_requests (any_t arg)
}
+/* Free the list of modification requests MR */
+static void
+free_modreqs (struct modreq *mr)
+{
+ struct modreq *tmp;
+ for (; mr; mr = tmp)
+ {
+ mach_port_deallocate (mach_task_self (), mr->port);
+ tmp = mr->next;
+ free (mr);
+ }
+}
+
+error_t
+display_notice_changes (display_t display, mach_port_t notify)
+{
+ error_t err;
+ struct modreq *req;
+
+ mutex_lock (&display->lock);
+ err = nowait_file_changed (notify, FILE_CHANGED_NULL, 0, 0);
+ if (err)
+ {
+ mutex_unlock (&display->lock);
+ return err;
+ }
+ req = malloc (sizeof (struct modreq));
+ if (!req)
+ {
+ mutex_unlock (&display->lock);
+ return errno;
+ }
+ req->port = notify;
+ req->next = display->filemod_reqs;
+ display->filemod_reqs = req;
+ mutex_unlock (&display->lock);
+ return 0;
+}
+
+/* Requires DISPLAY to be locked. */
+void
+display_notice_filechange (display_t display, enum file_changed_type type,
+ off_t start, off_t end)
+{
+ error_t err;
+ struct modreq **preq;
+
+ preq = &display->filemod_reqs;
+ while (*preq)
+ {
+ struct modreq *req = *preq;
+ err = nowait_file_changed (req->port, type, start, end);
+ if (err)
+ {
+ /* Remove notify port. */
+ *preq = req->next;
+ mach_port_deallocate (mach_task_self (), req->port);
+ free (req);
+ }
+ else
+ preq = &req->next;
+ }
+}
+
+
static error_t
-user_create (display_t display, u_int32_t width, u_int32_t height,
- u_int32_t lines)
+user_create (display_t display, uint32_t width, uint32_t height,
+ uint32_t lines)
{
error_t err;
struct cons_display *user;
display->memobj_size = round_page (sizeof (struct cons_display) +
- sizeof (u_int32_t) * width * lines);
+ sizeof (uint32_t) * width * lines);
display->upi = malloc (sizeof (struct user_pager_info));
if (!display->upi)
@@ -270,7 +347,7 @@ user_create (display_t display, u_int32_t width, u_int32_t height,
user->screen.lines = lines;
user->screen.cur_line = 0;
user->screen.scr_lines = 0;
- user->screen.matrix = sizeof (struct cons_display) / sizeof (u_int32_t);
+ user->screen.matrix = sizeof (struct cons_display) / sizeof (uint32_t);
user->cursor.col = 0;
user->cursor.row = 0;
user->cursor.status = CONS_CURSOR_NORMAL;
@@ -289,103 +366,124 @@ user_destroy (display_t display)
}
-#define MATRIX_POS(user,x,y) ((user)->_matrix \
- + (((user)->screen.cur_line + (y)) % (user)->screen.height) \
- * (user)->screen.width + (x))
-
static void
-screen_fill (display_t display, size_t x, size_t y, size_t w, size_t h,
- wchar_t chr, char attr)
+screen_fill (display_t display, size_t col1, size_t row1, size_t col2,
+ size_t row2, wchar_t chr, char attr)
{
struct cons_display *user = display->user;
- wchar_t *matrixp = MATRIX_POS (user, x, y);
+ off_t start = (user->screen.cur_line + row1) * user->screen.width + col1;
+ off_t end = (user->screen.cur_line + row2) * user->screen.width + col2;
+ off_t size = user->screen.width * user->screen.lines;
- while (h--)
+ if (start >= size && end >= size)
{
- /* XXX Set attribute flags. */
- wmemset (matrixp, L' ', w);
- matrixp += user->screen.width;
+ start -= size;
+ end -= size;
}
- /* XXX Flag screen change, but here or where else? */
-}
-
-static void
-screen_scroll_up (display_t display, size_t x, size_t y, size_t w, size_t h,
- int amt, wchar_t chr, char attr)
-{
- struct cons_display *user = display->user;
- wchar_t *matrixp = MATRIX_POS (user, x, y);
-
- if (amt < 0)
- return;
-
- while (h-- > amt)
+ if (end < size)
{
- wmemcpy (matrixp, matrixp + amt * user->screen.width, w);
- matrixp += user->screen.width;
+ wmemset (user->_matrix + start, chr, end - start + 1);
+ display_notice_filechange (display, FILE_CHANGED_WRITE,
+ sizeof (struct cons_display)
+ + start * sizeof (wchar_t),
+ sizeof (struct cons_display)
+ + (end + 1) * sizeof (wchar_t) - 1);
}
- screen_fill (display, x, y, w, h, chr, attr);
-}
-
-static void
-screen_scroll_down (display_t display, size_t x, size_t y, size_t w, size_t h,
- int amt, wchar_t chr, char attr)
-{
- struct cons_display *user = display->user;
- wchar_t *matrixp = MATRIX_POS (user, x, y + h - 1);
-
- if (amt < 0)
- return;
-
- while (h-- > amt)
+ else
{
- wmemcpy (matrixp, matrixp - amt * user->screen.width, w);
- matrixp -= user->screen.width;
+ wmemset (user->_matrix + start, chr, size - start);
+ wmemset (user->_matrix, chr, end - size + 1);
+ display_notice_filechange (display, FILE_CHANGED_WRITE,
+ sizeof (struct cons_display)
+ + start * sizeof (wchar_t),
+ sizeof (struct cons_display)
+ + (end - size + 1) * sizeof (wchar_t) - 1);
}
- screen_fill (display, x, y, w, h, chr, attr);
}
static void
-screen_scroll_left (display_t display, size_t x, size_t y, size_t w, size_t h,
- int amt, wchar_t chr, char attr)
+screen_shift_left (display_t display, size_t row1, size_t col1, size_t row2,
+ size_t col2, size_t shift, wchar_t chr, char attr)
{
struct cons_display *user = display->user;
- wchar_t *matrixp = MATRIX_POS (user, x, y);
- int i;
+ off_t start = (user->screen.cur_line + row1) * user->screen.width + col1;
+ off_t end = (user->screen.cur_line + row2) * user->screen.width + col2;
+ off_t size = user->screen.width * user->screen.lines;
- if (amt < 0)
- return;
- if (amt > w)
- amt = w;
+ if (start >= size && end >= size)
+ {
+ start -= size;
+ end -= size;
+ }
- for (i = 0; i < y + h; i++)
+ if (start + shift <= end)
{
- wmemmove (matrixp, matrixp + amt, w - amt);
- matrixp += user->screen.width;
+ /* Use a loop to copy the data. Using wmemmove and wmemset on
+ the chunks is tiresome, as there are many cases. */
+ off_t src = start + shift;
+ off_t dst = start;
+
+ while (src <= end)
+ user->_matrix[dst++ % size] = user->_matrix[src++ % size];
+ while (dst <= end)
+ user->_matrix[dst++ % size] = chr;
+
+ display_notice_filechange (display, FILE_CHANGED_TRUNCATE,
+ sizeof (struct cons_display)
+ + start * sizeof (wchar_t),
+ sizeof (struct cons_display)
+ + (start + shift) * sizeof (wchar_t) - 1);
+ display_notice_filechange (display, FILE_CHANGED_EXTEND,
+ sizeof (struct cons_display)
+ + (end - shift + 1) * sizeof (wchar_t),
+ sizeof (struct cons_display)
+ + (end + 1) * sizeof (wchar_t) - 1);
}
- screen_fill (display, x + w - amt, y, amt, h, chr, attr);
+ else
+ screen_fill (display, col1, row1, col2, row2, chr, attr);
}
static void
-screen_scroll_right (display_t display, size_t x, size_t y, size_t w, size_t h,
- int amt, wchar_t chr, char attr)
+screen_shift_right (display_t display, size_t row1, size_t col1, size_t row2,
+ size_t col2, size_t shift, wchar_t chr, char attr)
{
struct cons_display *user = display->user;
- wchar_t *matrixp = MATRIX_POS (user, x, y);
- int i;
+ off_t start = (user->screen.cur_line + row1) * user->screen.width + col1;
+ off_t end = (user->screen.cur_line + row2) * user->screen.width + col2;
+ off_t size = user->screen.width * user->screen.lines;
- if (amt < 0)
- return;
- if (amt > w)
- amt = w;
+ if (start >= size && end >= size)
+ {
+ start -= size;
+ end -= size;
+ }
- for (i = 0; i < y + h; i++)
+ if (start + shift <= end)
{
- wmemmove (matrixp + amt, matrixp, w - amt);
- matrixp += user->screen.width;
+ /* Use a loop to copy the data. Using wmemmove and wmemset on
+ the chunks is tiresome, as there are many cases. */
+ off_t src = end - shift;
+ off_t dst = end;
+
+ while (src >= start)
+ user->_matrix[dst-- % size] = user->_matrix[src-- % size];
+ while (dst >= start)
+ user->_matrix[dst-- % size] = chr;
+
+ display_notice_filechange (display, FILE_CHANGED_EXTEND,
+ sizeof (struct cons_display)
+ + start * sizeof (wchar_t),
+ sizeof (struct cons_display)
+ + (start + shift) * sizeof (wchar_t) - 1);
+ display_notice_filechange (display, FILE_CHANGED_TRUNCATE,
+ sizeof (struct cons_display)
+ + (end - shift + 1) * sizeof (wchar_t),
+ sizeof (struct cons_display)
+ + (end + 1) * sizeof (wchar_t) - 1);
}
- screen_fill (display, x, y, amt, h, chr, attr);
+ else
+ screen_fill (display, col1, row1, col2, row2, chr, attr);
}
@@ -607,26 +705,19 @@ handle_esc_bracket (display_t display, char op)
case 0:
/* Clear to end of screen: <ed>. */
screen_fill (display, user->cursor.col, user->cursor.row,
- user->screen.width - user->cursor.col, 1, L' ',
- display->attr.current);
- screen_fill (display, 0, user->cursor.row + 1,
- user->screen.width,
- user->screen.height - user->cursor.row,
- L' ', display->attr.current);
+ user->screen.width - 1, user->screen.height - 1,
+ L' ', display->attr.current);
break;
case 1:
/* Clear to beginning of screen. */
screen_fill (display, 0, 0,
- user->screen.width, user->cursor.row,
- L' ', display->attr.current);
- screen_fill (display, 0, user->cursor.row,
- user->cursor.col + 1, 1,
+ user->cursor.col, user->cursor.row,
L' ', display->attr.current);
break;
case 2:
/* Clear entire screen. */
screen_fill (display, 0, 0,
- user->screen.width, user->screen.height,
+ user->screen.width - 1, user->screen.height - 1,
L' ', display->attr.current);
break;
}
@@ -637,73 +728,70 @@ handle_esc_bracket (display_t display, char op)
case 0:
/* Clear to end of line: <el>. */
screen_fill (display, user->cursor.col, user->cursor.row,
- user->screen.width - user->cursor.col, 1,
+ user->screen.width - 1, user->cursor.row,
L' ', display->attr.current);
break;
case 1:
/* Clear to beginning of line: <el1>. */
screen_fill (display, 0, user->cursor.row,
- user->cursor.col + 1, 1,
+ user->cursor.col, user->cursor.row,
L' ', display->attr.current);
break;
case 2:
/* Clear entire line. */
screen_fill (display, 0, user->cursor.row,
- user->screen.width, 1,
+ user->screen.width - 1, user->cursor.row,
L' ', display->attr.current);
break;
}
break;
case 'L':
/* Insert line(s): <il1>, <il>. */
- screen_scroll_down (display, 0, user->cursor.row,
- user->screen.width,
- user->screen.height - user->cursor.row,
- parse->params[0] ?: 1,
+ screen_shift_right (display, 0, user->cursor.row,
+ user->screen.width - 1, user->screen.height - 1,
+ (parse->params[0] ?: 1) * user->screen.width,
L' ', display->attr.current);
break;
case 'M':
/* Delete line(s): <dl1>, <dl>. */
- screen_scroll_up (display, 0, user->cursor.row,
- user->screen.width,
- user->screen.height - user->cursor.row,
- parse->params[0] ?: 1,
- L' ', display->attr.current);
+ screen_shift_left (display, 0, user->cursor.row,
+ user->screen.width - 1, user->screen.height - 1,
+ (parse->params[0] ?: 1) * user->screen.width,
+ L' ', display->attr.current);
break;
case '@':
/* Insert character(s): <ich1>, <ich>. */
- screen_scroll_right (display, user->cursor.col,
- user->cursor.row,
- user->screen.width - user->cursor.col, 1,
- parse->params[0] ?: 1,
- L' ', display->attr.current);
+ screen_shift_right (display, user->cursor.col, user->cursor.row,
+ user->screen.width - 1, user->cursor.row,
+ parse->params[0] ?: 1,
+ L' ', display->attr.current);
break;
case 'P':
/* Delete character(s): <dch1>, <dch>. */
- screen_scroll_left (display, user->cursor.col,
- user->cursor.row,
- user->screen.width - user->cursor.col, 1,
- parse->params[0] ?: 1,
- L' ', display->attr.current);
+ screen_shift_left (display, user->cursor.col, user->cursor.row,
+ user->screen.width - 1, user->cursor.row,
+ parse->params[0] ?: 1,
+ L' ', display->attr.current);
break;
case 'S':
/* Scroll up: <ind>, <indn>. */
- screen_scroll_up (display, 0, 0,
- user->screen.width, user->screen.height,
- parse->params[0] ?: 1,
- L' ', display->attr.current);
+ screen_shift_left (display, 0, 0,
+ user->screen.width - 1, user->screen.height - 1,
+ (parse->params[0] ?: 1) * user->screen.width,
+ L' ', display->attr.current);
break;
case 'T':
/* Scroll down: <ri>, <rin>. */
- screen_scroll_down (display, 0, 0,
+ screen_shift_right (display, 0, 0,
user->screen.width, user->screen.height,
- parse->params[0] ?: 1,
+ (parse->params[0] ?: 1) * user->screen.width,
L' ', display->attr.current);
break;
case 'X':
/* Erase character(s): <ech>. */
screen_fill (display, user->cursor.col, user->cursor.row,
- parse->params[0] ?: 1, 1,
+ /* XXX limit ? */user->cursor.col + parse->params[0] ?: 1,
+ user->cursor.row,
L' ', display->attr.current);
break;
}
@@ -754,6 +842,12 @@ display_output_one (display_t display, wchar_t chr)
struct cons_display *user = display->user;
parse_t parse = &display->output.parse;
+ uint32_t old_cursor_col = user->cursor.col;
+ uint32_t old_cursor_row = user->cursor.row;
+ uint32_t old_cursor_status = user->cursor.status;
+ uint32_t old_cur_line = user->screen.cur_line;
+ uint32_t old_scr_lines = user->screen.scr_lines;
+
void newline (void)
{
if (user->cursor.row < user->screen.height - 1)
@@ -768,12 +862,12 @@ display_output_one (display_t display, wchar_t chr)
/* XXX Set attribute flags. */
screen_fill (display, 0, user->screen.height - 1,
- user->screen.width, 1, L' ', user->screen.width);
+ user->screen.width - 1, user->screen.height - 1,
+ L' ', user->screen.width);
if (user->screen.scr_lines <
user->screen.lines - user->screen.height)
user->screen.scr_lines++;
/* XXX Flag current line change. */
- /* XXX Flag change of last line. */
/* XXX Possibly flag change of length of scroll back buffer. */
}
}
@@ -831,10 +925,15 @@ display_output_one (display_t display, wchar_t chr)
{
int line = (user->screen.cur_line + user->cursor.row)
% user->screen.lines;
-
+ int idx = line * user->screen.width + user->cursor.col;
/* XXX Set attribute flags. */
- user->_matrix[line * user->screen.width
- + user->cursor.col] = chr;
+ user->_matrix[idx] = chr;
+
+ display_notice_filechange (display, FILE_CHANGED_WRITE,
+ sizeof (struct cons_display)
+ + idx * sizeof (wchar_t),
+ sizeof (struct cons_display)
+ + (idx + 1) * sizeof (wchar_t) - 1);
user->cursor.col++;
if (user->cursor.col == user->screen.width)
@@ -856,7 +955,7 @@ display_output_one (display_t display, wchar_t chr)
case L'c':
/* Clear screen and home cursor: <clear>. */
screen_fill (display, 0, 0,
- user->screen.width, user->screen.height,
+ user->screen.width - 1, user->screen.height - 1,
L' ', display->attr.current);
user->cursor.col = user->cursor.row = 0;
/* XXX Flag cursor change. */
@@ -903,6 +1002,35 @@ display_output_one (display_t display, wchar_t chr)
default:
abort ();
}
+
+ if (old_cursor_col != user->cursor.col || old_cursor_row != user->cursor.row)
+ display_notice_filechange (display, FILE_CHANGED_WRITE,
+ offsetof (struct cons_display, cursor.col),
+ (old_cursor_status == user->cursor.status
+ ? offsetof (struct cons_display, cursor.row)
+ : offsetof (struct cons_display, cursor.row))
+ + sizeof (wchar_t) - 1);
+ else if (old_cursor_status != user->cursor.status)
+ display_notice_filechange (display, FILE_CHANGED_WRITE,
+ offsetof (struct cons_display, cursor.status),
+ offsetof (struct cons_display, cursor.status)
+ + sizeof (wchar_t) - 1);
+ if (old_cur_line != user->screen.cur_line)
+ display_notice_filechange (display, FILE_CHANGED_WRITE,
+ offsetof (struct cons_display, screen.cur_line),
+ (old_scr_lines == user->screen.scr_lines
+ ? offsetof (struct cons_display,
+ screen.cur_line)
+ : offsetof (struct cons_display,
+ screen.scr_lines))
+ + sizeof (wchar_t) - 1);
+ else if (old_scr_lines != user->screen.scr_lines)
+ display_notice_filechange (display, FILE_CHANGED_WRITE,
+ offsetof (struct cons_display,
+ screen.scr_lines),
+ offsetof (struct cons_display,
+ screen.scr_lines)
+ + sizeof (wchar_t) - 1);
}
/* Output LENGTH bytes starting from BUFFER in the system encoding.
@@ -996,6 +1124,8 @@ display_create (display_t *r_display, const char *encoding)
void
display_destroy (display_t display)
{
+ if (display->filemod_reqs)
+ free_modreqs (display->filemod_reqs);
output_deinit (&display->output);
user_destroy (display);
free (display);
diff --git a/console/display.h b/console/display.h
index c48aec99..303c42e2 100644
--- a/console/display.h
+++ b/console/display.h
@@ -60,6 +60,8 @@ mach_port_t display_get_filemap (display_t display, vm_prot_t prot);
ssize_t display_read (display_t display, int nonblock, off_t off,
char *data, size_t len);
+error_t display_notice_changes (display_t display, mach_port_t notify);
+
/* Resume the output on the display DISPLAY. */
void display_start_output (display_t display);
diff --git a/console/ourfs_notify.defs b/console/ourfs_notify.defs
new file mode 100644
index 00000000..64127fe6
--- /dev/null
+++ b/console/ourfs_notify.defs
@@ -0,0 +1,5 @@
+/* Private specialized presentation of fs_notify.defs for diskfs library. */
+
+#define routine simpleroutine
+#define USERPREFIX nowait_
+#include <hurd/fs_notify.defs>