[ALL variants] Getting main-gcu to handle resizes.

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • CJNyfalt
    Swordsman
    • May 2007
    • 289

    [ALL variants] Getting main-gcu to handle resizes.

    I'm working on getting main-gcu.c to handle resizing of the term window. This is for S, but it should be relevant to all variants.

    I have made a fair bit of progress, but I'm having some problems.

    First, let's take a look at the NCURSES FAQ:
    This FAQ gives some background and discussion for frequently encountered problems with the ncurses library, the terminal database and applications.

    It is possible to make an application resize when running in a windowing environment (e.g., in an xterm). This is not a feature of standard SVr4 curses, though some curses implementations (e.g., HP-UX) support this.

    Within ncurses, there are two ways to accomplish this. One relies on side-effects of the library functions, and is moderately portable. The other is an extension to SVr4 curses.

    * endwin/refresh when invoked will briefly exit curses and reinitialize the display, picking up the new screen size. Ncurses will reallocate the WINDOW data (e.g., curscr, stdscr) to reflect the new limits.
    * resizeterm can be invoked directly to make ncurses resize its WINDOW data. I use it in my directory editor ded to achieve flicker-free resizing via a signal handler for SIGWINCH. (The documentation for HP-UX curses implies that they use a similar approach; I have been unable to make it work.)

    Ncurses 5.0 can be configured to establish its own SIGWINCH hander. In this configuration, the wgetch function will return a special keycode KEY_RESIZE when a resizing event is detected. The signal handler also calls resizeterm (Caveat: malloc and free are not guaranteed to be safe for use in a signal handler).
    Now the first approach seems complicated, so I want to focus on the resizeterm one. The Ncurses 5.0 KEY_RESIZE approach seems also limiting because of the strict version requirement.

    So, I should need the following:
    - A signal handler for SIGWINCH - check.
    - Check LINES & COLS for new size - check.
    - Call resizeterm to set new size - check.
    - Use wresize and Term_resize on the sub-windows - check.

    But, it doesn't work!
    I suspect that there's something work in the signal code itself, but I'm not sure.
    Code:
    /*
     * Handle signals -- term resize (SIGWINCH)  -CJN-
     */
    static void handle_signal_resize(int sig)
    {
    	/* Protect errno from library calls in signal handler */
    	int save_errno = errno;
    
    	/* Disable handler */
    	(void)(*signal_aux)(sig, SIG_IGN);
    
    	/* React to changes */
    	(void)Term_xtra(TERM_XTRA_REACT, 0);
    
    	/* Restore handler */
    	(void)(*signal_aux)(sig, handle_signal_resize);
    
    	/* Restore errno */
    	errno = save_errno;
    }
    Code:
    #ifdef SIGWINCH
    	(void)(*signal_aux)(SIGWINCH, handle_signal_resize);
    #endif
    Does anyone have had problems with the signals? Any hints at all?
  • pav
    Administrator
    • Apr 2007
    • 793

    #2
    You need to add these two lines to your signal handler:

    endwin();
    refresh();

    before you call off to Angband code. This will tell ncurses to reinit the screen and update it's idea of terminal dimensions. It got some screen flicker, but it works!
    See the elves and everything! http://angband.oook.cz

    Comment

    • Diego Gonzalez
      Adept
      • May 2007
      • 170

      #3
      I had the same problem when I was writing a Telnet client. Try with this

      Code:
      void handleSIGWINCH(int sig) 
      {
              struct winsize ws;
      
              if (ioctl(1, TIOCGWINSZ, &ws) == -1)
              {
                      perror("ioctl");
                      return;
              }
      
              resize_term(ws.ws_row, ws.ws_col);
      }

      Comment

      • pav
        Administrator
        • Apr 2007
        • 793

        #4
        Originally posted by Diego Gonzalez
        I had the same problem when I was writing a Telnet client. Try with this

        Code:
        void handleSIGWINCH(int sig) 
        {
                struct winsize ws;
        
                if (ioctl(1, TIOCGWINSZ, &ws) == -1)
                {
                        perror("ioctl");
                        return;
                }
        
                resize_term(ws.ws_row, ws.ws_col);
        }
        How portable is this ioctl interface?

        Tried it, same screen flicker as my method, so I'm not switching
        See the elves and everything! http://angband.oook.cz

        Comment

        • CJNyfalt
          Swordsman
          • May 2007
          • 289

          #5
          Thanks for the help. However that doesn't fix the problem. I suspect that there's a bug somewhere in the general signnal handling code in Sangband.
          I have had enough on working on the problem, and takes a break from it.

          Comment

          • CJNyfalt
            Swordsman
            • May 2007
            • 289

            #6
            Originally posted by CJNyfalt
            Thanks for the help. However that doesn't fix the problem. I suspect that there's a bug somewhere in the general signnal handling code in Sangband.
            I have had enough on working on the problem, and takes a break from it.
            There's a version of main-gcu with my effort on writing the resize code in the latest Sangband in the src/unix directory, if someone wants to take a look at the effort, and hopefully figure out what's went wrong.

            Comment

            Working...
            😀
            😂
            🥰
            😘
            🤢
            😎
            😞
            😡
            👍
            👎