web-dev-qa-db-ja.com

--enable-sigwinchを使用せずに、端末のサイズ変更ncursesを検出します

アーチ上--enable-sigwinchはncursesにコンパイルされません。 このフォーラムの投稿 によると、端末のサイズ変更を検出するために使用できます。そのオプションをオンにすることは、ある程度の抵抗なしには利用できないようです。Cの端末サイズ変更を検出する別の手段はありますか?

3
ZeroPhase

INSTALL からの引用:

    --enable-sigwinch
        Compile support for ncurses' SIGWINCH handler.  If your application has
        its own SIGWINCH handler, ncurses will not use its own.  The ncurses
        handler causes wgetch() to return KEY_RESIZE when the screen-size
        changes.  This option is the default, unless you have disabled the
        extended functions.

そこにない場合は、無効になっています。原則として、 test/view.c ファイルの最近削除された(長い間廃止された)CAN_RESIZEセクションに示されているように行うことができます。 ncursesライブラリはそれよりも優れた仕事をします。この例は1995年7月に追加されました。 コメント はSunOS4を参照しています。

/*
 * This uses functions that are "unsafe", but it seems to work on SunOS. 
 * Usually: the "unsafe" refers to the functions that POSIX lists which may be
 * called from a signal handler.  Those do not include buffered I/O, which is
 * used for instance in wrefresh().  To be really portable, you should use the
 * KEY_RESIZE return (which relies on ncurses' sigwinch handler).
 *
 * The 'wrefresh(curscr)' is needed to force the refresh to start from the top
 * of the screen -- some xterms mangle the bitmap while resizing.
 */

現代の同等物は、 library で行われるように、シグナルハンドラーにフラグを設定するだけです。

#if USE_SIGWINCH
static void
handle_SIGWINCH(int sig GCC_UNUSED)
{
    _nc_globals.have_sigwinch = 1;
# if USE_PTHREADS_EINTR
    if (_nc_globals.read_thread) {
    if (!pthread_equal(pthread_self(), _nc_globals.read_thread))
        pthread_kill(_nc_globals.read_thread, SIGWINCH);
    _nc_globals.read_thread = 0;
    }
# endif
}
#endif /* USE_SIGWINCH */

ちなみに、 パッケージスクリプト は、機能が無効になっていることを示していません。

  ./configure --prefix=/usr --mandir=/usr/share/man \
    --with-pkg-config-libdir=/usr/lib/pkgconfig \
    --with-static --with-normal --without-debug --without-ada \
    --enable-widec --enable-pc-files --with-cxx-binding --with-cxx-static \
    --with-shared --with-cxx-shared

library を参照すると、シグナルがデフォルト(未設定)の値である場合、SIGWINCHハンドラーが初期化されます。

#if USE_SIGWINCH
        CatchIfDefault(SIGWINCH, handle_SIGWINCH);
#endif

すでにSIGWINCHハンドラーが存在する場合、ncursesは何もしません。

3
Thomas Dickey