Suspend on ^Z.
authorTimo Korvola <tkorvola@iki.fi>
Tue, 20 Feb 2018 21:33:42 +0000 (23:33 +0200)
committerTimo Korvola <tkorvola@iki.fi>
Tue, 20 Feb 2018 21:33:42 +0000 (23:33 +0200)
In raw mode ^Z is just another character.  It is easier to
handle than in cbreak because it can be done in normal execution
without having to replace the curses SIGTSTP handler.

src/curses/ux_frotz.h
src/curses/ux_input.c
src/curses/ux_screen.c

index 983492890267081a66c68d7fac92a31023fdbfde..61269813e29d26a355dbb9034bc4552321f85a3f 100644 (file)
@@ -92,6 +92,7 @@ bool unix_init_pictures(void);                /* ux_pic.c */
 // void unix_save_screen(int);         /* ux_screen.c */
 // void unix_do_scrollback(void);              /* ux_screen.c */
 void unix_resize_display(void);                /* ux_screen.c */
+void unix_suspend_program(void);        /* ux_screen.c */
 void unix_get_terminal_size(void);      /* ux_init.c */
 
 
index 9268e300e19f1e11bcc2cbf98ea188e0eeaf3f4d..db9fa9c715ea18d41fdff0b3576df0ee4f3a32d7 100644 (file)
@@ -281,6 +281,11 @@ static int unix_read_char(int extkeys)
        case MOD_CTRL ^ 'U': c = ZC_DEL_TO_BOL; break;
        case MOD_CTRL ^ 'W': c = ZC_DEL_WORD; break;
 
+       /* In raw mode we need to take care of this as well. */
+       case MOD_CTRL ^ 'Z':
+           unix_suspend_program();
+           continue;
+
        /* use ^Q to immediately exit. */
        case MOD_CTRL ^ 'Q': os_quit();
 
index 31368e446f06b04a7b5875cc7332e7ff8313b55b..fb482a017438371b6e415bb7cfd74c50b958444f 100644 (file)
@@ -25,6 +25,8 @@
 #include <stdlib.h>
 #include <string.h>
 
+#include <signal.h>
+
 #ifdef USE_NCURSES_H
 #include <ncurses.h>
 #else
@@ -136,11 +138,7 @@ void os_scroll_area (int top, int left, int bottom, int right, int units)
 }/* os_scroll_area */
 
 
-/**
- * Resize the display and redraw.  Retain the old screen starting from the
- * top left.  Call resize_screen, which may repaint more accurately.
- */
-void unix_resize_display(void)
+static void save_screen(void)
 {
     if ((saved_screen = newpad(h_screen_rows, h_screen_cols))
         && overwrite(stdscr, saved_screen) == ERR) {
@@ -152,21 +150,46 @@ void unix_resize_display(void)
         getyx(stdscr, y, x);
         wmove(saved_screen, y, x);
     }
+}
 
-    endwin();
-    refresh();
-    unix_get_terminal_size();
 
+static void resize_restore_screen(void)
+{
+    unix_get_terminal_size();
     resize_screen();
-    if (zmp != NULL) {
-       restart_header();
-    }
+    if (zmp != NULL)
+        restart_header();
     if (saved_screen) {
         delwin(saved_screen);
         saved_screen = NULL;
     }
+}
+
+
+
+/**
+ * Resize the display and redraw.  Retain the old screen starting from the
+ * top left.  Call resize_screen, which may repaint more accurately.
+ */
+void unix_resize_display(void)
+{
+    save_screen();
+    endwin();
+    refresh();
+    resize_restore_screen();
 }/* unix_redraw_display */
 
+/**
+ * Suspend ourselves.  Save the screen and raise SIGTSTP.
+ * Upon continuing restore the screen as in unix_resize_display; the terminal
+ * size may have changed while we were stopped.
+ */
+void unix_suspend_program(void)
+{
+    save_screen();
+    raise(SIGTSTP);
+    resize_restore_screen();
+}
 
 /**
  * Repaint a window.