bug-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Patch for ncursesw (bug-fixes, other resolutions)


From: Marco Gerards
Subject: Patch for ncursesw (bug-fixes, other resolutions)
Date: 18 Jul 2003 22:16:07 +0200
User-agent: Gnus/5.09 (Gnus v5.9.0) Emacs/21.2

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  <metgerards@student.han.nl>

        * 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
   };





reply via email to

[Prev in Thread] Current Thread [Next in Thread]