2008-09-07 Miguel de Icaza <miguel@novell.com>
authorMiguel de Icaza <miguel@gnome.org>
Sun, 7 Sep 2008 22:43:15 +0000 (22:43 -0000)
committerMiguel de Icaza <miguel@gnome.org>
Sun, 7 Sep 2008 22:43:15 +0000 (22:43 -0000)
* console-io.c: Add support for tracking the window size if it
changes.

The setup is very simple: the TtySetup function will now return a
pointer to a location in memory that tracks the current console
size.  The managed code checks its current value every time its
queried against the last value set, and updates accordingly.

With this setup we can work with multiple consoles, and we do not
require to poke into managed code from a signal handler.

Additionally, the environment for COLUMNS and LINES is now handled
in unmanaged code.

(ves_icall_System_ConsoleDriver_GetTtySize): This is now gone.

svn path=/trunk/mono/; revision=112477

mono/metadata/ChangeLog
mono/metadata/console-io.c
mono/metadata/console-io.h
mono/metadata/icall-def.h

index 2aa37514383336b1805a561950747b7f30d9facf..9314a7538c421dcf5f2cb39b30c7cc123caebbfa 100644 (file)
@@ -1,3 +1,21 @@
+2008-09-07  Miguel de Icaza  <miguel@novell.com>
+
+       * console-io.c: Add support for tracking the window size if it
+       changes.
+
+       The setup is very simple: the TtySetup function will now return a
+       pointer to a location in memory that tracks the current console
+       size.  The managed code checks its current value every time its
+       queried against the last value set, and updates accordingly.
+
+       With this setup we can work with multiple consoles, and we do not
+       require to poke into managed code from a signal handler.
+
+       Additionally, the environment for COLUMNS and LINES is now handled
+       in unmanaged code.
+
+       (ves_icall_System_ConsoleDriver_GetTtySize): This is now gone.
+
 2008-09-07  Mark Probst  <mark.probst@gmail.com>
 
        * marshal.c (mono_type_native_stack_size): Treat
index a3dbf4e3519169c773301d7cf7b0abdb3422c289..2913143fe6e330e2b4b33cd45c342dfa9fa7b661 100644 (file)
@@ -97,12 +97,6 @@ ves_icall_System_ConsoleDriver_TtySetup (MonoString *keypad, MonoString *teardow
        return FALSE;
 }
 
-MonoBoolean
-ves_icall_System_ConsoleDriver_GetTtySize (HANDLE handle, gint32 *width, gint32 *height)
-{
-       return FALSE;
-}
-
 #else
 static struct termios initial_attr;
 
@@ -193,6 +187,27 @@ ves_icall_System_ConsoleDriver_InternalKeyAvailable (gint32 timeout)
        return (ret > 0) ? ret : 0;
 }
 
+static gint32 cols_and_lines;
+
+#ifdef TIOCGWINSZ
+static int
+terminal_get_dimensions (void)
+{
+       struct winsize ws;
+
+       if (ioctl (STDIN_FILENO, TIOCGWINSZ, &ws) == 0)
+               return (ws.ws_col << 16) | ws.ws_row;
+
+       return -1;
+}
+#else
+static int
+terminal_get_dimensions (void)
+{
+       return -1;
+}
+#endif
+
 static void
 tty_teardown (void)
 {
@@ -262,7 +277,7 @@ sigint_handler (int signo)
        in_sigint = FALSE;
 }
 
-static struct sigaction save_sigcont, save_sigint;
+static struct sigaction save_sigcont, save_sigint, save_sigwinch;
 
 static void
 sigcont_handler (int signo, void *the_siginfo, void *data)
@@ -273,16 +288,31 @@ sigcont_handler (int signo, void *the_siginfo, void *data)
        if (keypad_xmit_str != NULL)
                write (STDOUT_FILENO, keypad_xmit_str, strlen (keypad_xmit_str));
 
+       // Call previous handler
        if (save_sigcont.sa_sigaction != NULL &&
            save_sigcont.sa_sigaction != (void *)SIG_DFL &&
            save_sigcont.sa_sigaction != (void *)SIG_IGN)
                (*save_sigcont.sa_sigaction) (signo, the_siginfo, data);
 }
 
+static void
+sigwinch_handler (int signo, void *the_siginfo, void *data)
+{
+       int dims = terminal_get_dimensions ();
+       if (dims != -1)
+               cols_and_lines = dims;
+       
+       // Call previous handler
+       if (save_sigwinch.sa_sigaction != NULL &&
+           save_sigwinch.sa_sigaction != (void *)SIG_DFL &&
+           save_sigwinch.sa_sigaction != (void *)SIG_IGN)
+               (*save_sigwinch.sa_sigaction) (signo, the_siginfo, data);
+}
+
 void
 console_set_signal_handlers ()
 {
-       struct sigaction sigcont, sigint;
+       struct sigaction sigcont, sigint, sigwinch;
 
        memset (&sigcont, 0, sizeof (struct sigaction));
        memset (&sigint, 0, sizeof (struct sigaction));
@@ -298,6 +328,12 @@ console_set_signal_handlers ()
        sigint.sa_flags = 0;
        sigemptyset (&sigint.sa_mask);
        sigaction (SIGINT, &sigint, &save_sigint);
+
+       // Window size changed
+       sigwinch.sa_handler = (void *) sigwinch_handler;
+       sigwinch.sa_flags = 0;
+       sigemptyset (&sigwinch.sa_mask);
+       sigaction (SIGWINCH, &sigwinch, &save_sigwinch);
 }
 
 //
@@ -309,13 +345,37 @@ console_restore_signal_handlers ()
 {
        sigaction (SIGCONT, &save_sigcont, NULL);
        sigaction (SIGINT, &save_sigint, NULL);
+       sigaction (SIGWINCH, &save_sigwinch, NULL);
 }
 
 MonoBoolean
-ves_icall_System_ConsoleDriver_TtySetup (MonoString *keypad, MonoString *teardown, char *verase, char *vsusp, char*intr)
+ves_icall_System_ConsoleDriver_TtySetup (MonoString *keypad, MonoString *teardown, char *verase, char *vsusp, char*intr, int **size)
 {
+       int dims;
+
        MONO_ARCH_SAVE_REGS;
 
+       dims = terminal_get_dimensions ();
+       if (dims == -1){
+               int cols = 0, rows = 0;
+                                     
+               char *str = getenv ("COLUMNS");
+               if (str != NULL)
+                       cols = atoi (str);
+               str = getenv ("LINES");
+               if (str != NULL)
+                       rows = atoi (str);
+
+               if (cols != 0 && rows != 0)
+                       cols_and_lines = (cols << 16) | rows;
+               else
+                       cols_and_lines = -1;
+       } else {
+               cols_and_lines = dims;
+       }
+       
+       *size = &cols_and_lines;
+       
        *verase = '\0';
        *vsusp = '\0';
        *intr = '\0';
@@ -351,27 +411,4 @@ ves_icall_System_ConsoleDriver_TtySetup (MonoString *keypad, MonoString *teardow
        return TRUE;
 }
 
-MonoBoolean
-ves_icall_System_ConsoleDriver_GetTtySize (HANDLE handle, gint32 *width, gint32 *height)
-{
-#ifdef TIOCGWINSZ
-       struct winsize ws;
-       int res;
-
-       MONO_ARCH_SAVE_REGS;
-
-       res = ioctl (GPOINTER_TO_INT (handle), TIOCGWINSZ, &ws);
-
-       if (!res) {
-               *width = ws.ws_col;
-               *height = ws.ws_row;
-               return TRUE;
-       }
-       else
-               return FALSE;
-#else
-       return FALSE;
-#endif
-}
-
 #endif /* !PLATFORM_WIN32 */
index 13351579610519292e22e223f915ea0b6d14e695..6376abc71be6bd55f04d543ff0ea3d9d19785f1e 100644 (file)
@@ -22,8 +22,7 @@ MonoBoolean ves_icall_System_ConsoleDriver_Isatty (HANDLE handle) MONO_INTERNAL;
 gint32 ves_icall_System_ConsoleDriver_InternalKeyAvailable (gint32 timeout) MONO_INTERNAL;
 MonoBoolean ves_icall_System_ConsoleDriver_SetEcho (MonoBoolean echo) MONO_INTERNAL;
 MonoBoolean ves_icall_System_ConsoleDriver_SetBreak (MonoBoolean want_break) MONO_INTERNAL;
-MonoBoolean ves_icall_System_ConsoleDriver_TtySetup (MonoString *keypad, MonoString *teardown, char *verase, char *vsusp, char *intr) MONO_INTERNAL;
-MonoBoolean ves_icall_System_ConsoleDriver_GetTtySize (HANDLE handle, gint32 *width, gint32 *height) MONO_INTERNAL;
+MonoBoolean ves_icall_System_ConsoleDriver_TtySetup (MonoString *keypad, MonoString *teardown, char *verase, char *vsusp, char *intr, int **size) MONO_INTERNAL;
 void ves_icall_System_ConsoleDriver_Suspend (void) MONO_INTERNAL;
 
 void console_restore_signal_handlers (void);
index 7985d2d8d7925da4a53d8275fcfa192270bac092..55f6b1ccd4370e2904697a5570e8266a1106903e 100644 (file)
@@ -124,12 +124,11 @@ ICALL_TYPE(INTCFGHOST, "System.Configuration.InternalConfigurationHost", INTCFGH
 ICALL(INTCFGHOST_1, "get_bundled_machine_config", get_bundled_machine_config)
 
 ICALL_TYPE(CONSOLE, "System.ConsoleDriver", CONSOLE_1)
-ICALL(CONSOLE_1, "GetTtySize", ves_icall_System_ConsoleDriver_GetTtySize )
-ICALL(CONSOLE_2, "InternalKeyAvailable", ves_icall_System_ConsoleDriver_InternalKeyAvailable )
-ICALL(CONSOLE_3, "Isatty", ves_icall_System_ConsoleDriver_Isatty )
-ICALL(CONSOLE_4, "SetBreak", ves_icall_System_ConsoleDriver_SetBreak )
-ICALL(CONSOLE_5, "SetEcho", ves_icall_System_ConsoleDriver_SetEcho )
-ICALL(CONSOLE_6, "TtySetup", ves_icall_System_ConsoleDriver_TtySetup )
+ICALL(CONSOLE_1, "InternalKeyAvailable", ves_icall_System_ConsoleDriver_InternalKeyAvailable )
+ICALL(CONSOLE_2, "Isatty", ves_icall_System_ConsoleDriver_Isatty )
+ICALL(CONSOLE_3, "SetBreak", ves_icall_System_ConsoleDriver_SetBreak )
+ICALL(CONSOLE_4, "SetEcho", ves_icall_System_ConsoleDriver_SetEcho )
+ICALL(CONSOLE_5, "TtySetup", ves_icall_System_ConsoleDriver_TtySetup )
 
 ICALL_TYPE(CONVERT, "System.Convert", CONVERT_1)
 ICALL(CONVERT_1, "InternalFromBase64CharArray", InternalFromBase64CharArray )