Hi, This patch adds support for non-80x25 resolutions to the ncursesw driver. It also adds a generic interface to tell the display driver which resolution to use. If that resolution is not available it uses the next best resolution.
I made some changes to ncursesw so it uses a "pad", from the curs_pad man. file: "A pad is like a window, except that it is not restricted by the screen size, and is not necessarily associated with a particular part of the screen." So when using this it is possible to have a smaller ncursesw window than the virtual terminal. Starting the console client with the ncursesw driver in a bigger terminal wasn't possible because of a bug is ncursesw_write. It didn't wrap (and it couldn't know how to wrap). I fixed this too. Another change I made was removing the call to endwin before the input_loop was created. endwin disturbed the input loop and made it read incorrect symbols. (If the first keypress is KEY_LEFT for example it is not recognised). The last problem I encountered was with ncursesw_set_cursor_status. For some reason the cursor status couldn't be set to very visible when I used telnet. This is quite irritating in emacs because when pressing C-l the cursor is switched off and on, in my case it couldn't get switched back on. I solved this by setting the cursor to visible when it cannot be set to very visible (and it is set to very visible when setting to visible is not possible). Normally returning an error would solve this problem I think. (emacs will notice setting the cursor to very visible and set it to visible I guess). This is not posible in the Hurd console I think. The return error is ignored in the console client, because it works independantly from the console server. See the changelog entry for the exact changes (notice I made some code GCS complaint and this is not in the changelog entry). Thanks, Marco 2003-07-18 Marco Gerards <[EMAIL PROTECTED]> * console.c (cons_vcons_update): Call setres for every display driver before the driver is used. (cons_vcons_set_cursor_pos): Likewise. (cons_vcons_clear): Likewise. (cons_vcons_write): Likewise. * display.h (display_ops): New interface set_resolution. * vga.c (vga_disp_op): Set NULL for set_resolution. * ncursesw.c (ncursesw_set_resolution): New function. (ncursesw_displ): Add ncursesw_set_resolution. (ncurses_lock): Make variable static. (current_width): New variable. (current_height): Likewise. (conspad): New variable. (input_loop): Use conspad instead of (the default) stdscr. (mvwputsn): Likewise. (ncursesw_update): Likewise. (ncursesw_set_cursor_pos): Likewise. (ncursesw_scroll): Likewise. (ncursesw_write): Likewise. (ncursesw_driver_start): Likewise. Initialize conspad. (ncursesw_driver_start): Remove endwin call at the end of the function. (ncursesw_set_cursor_status): If the status can not be set, try another status that can sanely be used instead of the unavailable status. (ncursesw_write): Make it wrap around the edge. diff -bup /home/marco/src/hurdcvs/hurd/console-client/console.c console-client/console.c --- /home/marco/src/hurdcvs/hurd/console-client/console.c 2002-11-18 08:35:47.000000000 +0100 +++ console-client/console.c 2003-07-18 22:55:26.000000000 +0200 @@ -225,8 +225,14 @@ cons_vcons_update (vcons_t vcons) mutex_lock (&global_lock); if (vcons == active_vcons) display_iterate + { + if (display->ops->set_resolution) + display->ops->set_resolution (display->handle, + vcons->state.screen.width, + vcons->state.screen.height); if (display->ops->update) display->ops->update (display->handle); + } mutex_unlock (&global_lock); } @@ -239,8 +245,14 @@ cons_vcons_set_cursor_pos (vcons_t vcons mutex_lock (&global_lock); if (vcons == active_vcons) display_iterate + { + if (display->ops->set_resolution) + display->ops->set_resolution (display->handle, + vcons->state.screen.width, + vcons->state.screen.height); if (display->ops->set_cursor_pos) display->ops->set_cursor_pos (display->handle, col, row); + } mutex_unlock (&global_lock); } @@ -291,8 +303,14 @@ void cons_vcons_clear (vcons_t vcons, si mutex_lock (&global_lock); if (vcons == active_vcons) display_iterate + { + if (display->ops->set_resolution) + display->ops->set_resolution (display->handle, + vcons->state.screen.width, + vcons->state.screen.height); if (display->ops->clear) display->ops->clear (display->handle, length, col, row); + } mutex_unlock (&global_lock); } @@ -307,8 +325,14 @@ cons_vcons_write (vcons_t vcons, conchar mutex_lock (&global_lock); if (vcons == active_vcons) display_iterate + { + if (display->ops->set_resolution) + display->ops->set_resolution (display->handle, + vcons->state.screen.width, + vcons->state.screen.height); if (display->ops->write) display->ops->write (display->handle, str, length, col, row); + } mutex_unlock (&global_lock); } Common subdirectories: /home/marco/src/hurdcvs/hurd/console-client/CVS and console-client/CVS diff -bup /home/marco/src/hurdcvs/hurd/console-client/display.h console-client/display.h --- /home/marco/src/hurdcvs/hurd/console-client/display.h 2002-09-17 14:26:10.000000000 +0200 +++ console-client/display.h 2003-07-18 22:28:56.000000000 +0200 @@ -133,6 +133,11 @@ struct display_ops /* Do not use, do not remove. */ void (*deprecated) (void *handle, int key); + + /* Change the resolution of the physical screen to or one that can + display the vcons with the size of WIDTH * HEIGHT. If the + physical screen already has the right resolution do nothing. */ + error_t (*set_resolution) (void *handle, int width, int height); }; #endif /* _DISPLAY_H_ */ Only in console-client: ncursesw_bugfixes.diff diff -bup /home/marco/src/hurdcvs/hurd/console-client/ncursesw.c console-client/ncursesw.c --- /home/marco/src/hurdcvs/hurd/console-client/ncursesw.c 2002-09-18 04:47:01.000000000 +0200 +++ console-client/ncursesw.c 2003-07-18 22:58:10.000000000 +0200 @@ -34,7 +34,14 @@ /* ncurses is not thread-safe. This lock protects all calls into the ncurses library. */ -struct mutex ncurses_lock; +static struct mutex ncurses_lock; + +/* The current width and height the ncursesw driver is using. */ +static int current_width = 80; +static int current_height = 25; + +/* The window on which the console is shown. */ +static WINDOW *conspad; /* Forward declaration. */ static struct display_ops ncursesw_display_ops; @@ -282,7 +289,7 @@ input_loop (any_t unused) size_t size = 0; mutex_lock (&ncurses_lock); - while ((ret = getch ()) != ERR) + while ((ret = wgetch (conspad)) != ERR) { int i; int found; @@ -326,13 +333,15 @@ input_loop (any_t unused) break; default: found = 0; - for (i =0; i < sizeof(keycodes) / sizeof(keycodes[0]); i++) + for (i = 0; i < sizeof (keycodes) / sizeof (keycodes[0]); + i++) { if (keycodes[i].curses == ret) { if (keycodes[i].cons) { - assert (size < 101 - strlen(keycodes[i].cons)); + assert (size < 101 + - strlen (keycodes[i].cons)); strcpy (&buf[size], keycodes[i].cons); size += strlen (keycodes[i].cons); } @@ -382,7 +391,7 @@ mvwputsn (conchar_t *str, size_t len, of attr_t attr = conchar_attr_to_attr (str->attr); short color_pair = conchar_attr_to_color_pair (str->attr); - move (y, x); + wmove (conspad, y, x); while (len) { int ret; @@ -396,7 +405,7 @@ mvwputsn (conchar_t *str, size_t len, of } if (ucs4_to_altchar (str->chr, &ac)) - addch (ac | attr | color_pair); + waddch (conspad, ac | attr | color_pair); else { wch[0] = str->chr; @@ -409,7 +418,7 @@ mvwputsn (conchar_t *str, size_t len, of assert (!"Do something if setcchar fails."); } #endif - ret = add_wch (&chr); + ret = wadd_wch (conspad, &chr); #if 0 if (ret == ERR) { @@ -429,7 +438,11 @@ static error_t ncursesw_update (void *handle) { mutex_lock (&ncurses_lock); - refresh (); + + prefresh (conspad, 0, 0, 0, 0, + (current_height <= LINES ? current_height : LINES) - 1, + (current_width <= COLS ? current_width : COLS) - 1); + mutex_unlock (&ncurses_lock); return 0; } @@ -439,7 +452,7 @@ static error_t ncursesw_set_cursor_pos (void *handle, uint32_t col, uint32_t row) { mutex_lock (&ncurses_lock); - move (row, col); + wmove (conspad, row, col); mutex_unlock (&ncurses_lock); return 0; } @@ -449,7 +462,13 @@ static error_t ncursesw_set_cursor_status (void *handle, uint32_t status) { mutex_lock (&ncurses_lock); - curs_set (status ? (status == 1 ? 1 : 2) : 0); + + /* If the cursor is invisible and switching to one visible state + is impossible, switch to the other visible state or else the + cursor will not be shown at all. */ + if (curs_set (status) == -1 && status) + curs_set (status == 1 ? 2 : 1); + mutex_unlock (&ncurses_lock); return 0; } @@ -462,11 +481,11 @@ ncursesw_scroll (void *handle, int delta assert (delta >= 0); mutex_lock (&ncurses_lock); - idlok (stdscr, TRUE); - scrollok (stdscr, TRUE); - scrl (delta); - idlok (stdscr, FALSE); - scrollok (stdscr, FALSE); + idlok (conspad, TRUE); + scrollok (conspad, TRUE); + wscrl (conspad, delta); + idlok (conspad, FALSE); + scrollok (conspad, FALSE); mutex_unlock (&ncurses_lock); return 0; } @@ -478,11 +497,30 @@ ncursesw_write (void *handle, conchar_t { int x; int y; + int line; + int first_line; mutex_lock (&ncurses_lock); - getyx (stdscr, y, x); - mvwputsn (str, length, col, row); - wmove (stdscr, y, x); + first_line = current_width - col; + if (first_line > length) + first_line = length; + + getyx (conspad, y, x); + + /* Write the first line seperately because it can start on another + column than 0. */ + mvwputsn (str, first_line, col, row); + length = length - first_line; + str += first_line; + for (line = 0; line <= length / current_width; line++) + { + size_t size = (line == length / current_width) + ? length % current_width : current_width; + mvwputsn (str, size, 0, row + line + 1); + str += size; + } + + wmove (conspad, y, x); mutex_unlock (&ncurses_lock); return 0; } @@ -531,10 +569,13 @@ ncursesw_driver_start (void *handle) raw (); noecho (); nonl (); - intrflush (stdscr, FALSE); - nodelay (stdscr, TRUE); - timeout (1); - keypad (stdscr, TRUE); + + conspad = newpad (current_height, current_width); + + intrflush (conspad, FALSE); + nodelay (conspad, TRUE); + wtimeout (conspad, 1); + keypad (conspad, TRUE); err = driver_add_display (&ncursesw_display_ops, NULL); if (err) @@ -559,7 +600,6 @@ ncursesw_driver_start (void *handle) } cthread_detach (cthread_fork (input_loop, NULL)); - endwin (); return err; } @@ -579,6 +619,18 @@ ncursesw_driver_fini (void *handle, int return 0; } +static error_t +ncursesw_set_resolution (void *handle, int width, int height) +{ + mutex_lock (&ncurses_lock); + if (width != current_width || height != current_height) + wresize (conspad, height, width); + current_width = width; + current_height = height; + mutex_unlock(&ncurses_lock); + return 0; +} + struct driver_ops driver_ncursesw_ops = { @@ -596,7 +648,8 @@ static struct display_ops ncursesw_displ ncursesw_write, ncursesw_update, ncursesw_flash, - NULL + NULL, + ncursesw_set_resolution }; static struct input_ops ncursesw_input_ops = diff -bup /home/marco/src/hurdcvs/hurd/console-client/vga.c console-client/vga.c --- /home/marco/src/hurdcvs/hurd/console-client/vga.c 2002-09-17 14:26:10.000000000 +0200 +++ console-client/vga.c 2003-07-18 19:05:13.000000000 +0200 @@ -569,5 +569,6 @@ static struct display_ops vga_display_op vga_display_write, NULL, vga_display_flash, + NULL, NULL }; _______________________________________________ Bug-hurd mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/bug-hurd