From ccc4092e238c5e074a32e2c5794ab01934f272df Mon Sep 17 00:00:00 2001 From: Marcus Brinkmann Date: Thu, 13 Jun 2002 00:24:26 +0000 Subject: 2002-06-13 Marcus Brinkmann * 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 , not . Change all types from u_int32_t to uint32_t. * display.c: Include 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. --- console/ChangeLog | 33 ++++ console/Makefile | 5 +- console/console.c | 41 +++-- console/console.h | 26 ++-- console/display.c | 376 +++++++++++++++++++++++++++++++--------------- console/display.h | 2 + console/ourfs_notify.defs | 5 + 7 files changed, 343 insertions(+), 145 deletions(-) create mode 100644 console/ourfs_notify.defs (limited to 'console') 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 + + * 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 , not . + Change all types from u_int32_t to uint32_t. + * display.c: Include 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 * console.c: Include . 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 @@ -1165,6 +1170,24 @@ netfs_S_io_map (struct protid *cred, return errno; } + +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[] = { 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 +#include 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 #include #include #include @@ -36,6 +37,8 @@ #include #include +#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); } @@ -219,15 +231,80 @@ service_paging_requests (any_t arg) 1000 * 60 * 10, 0); } + +/* 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: . */ 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: . */ 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: . */ 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): , . */ - 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): ,
. */ - 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): , . */ - 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): , . */ - 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: , . */ - 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: , . */ - 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): . */ 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: . */ 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 -- cgit v1.2.3