0

ncursesを使用して、Cでテキストベースのクライアントを記述しています。プログラムのメインループは、キーが押されたことが検出されるまでブロックし、それを処理して、別のキーが押されるのを待ち続けます。

サーバーからの入力を(selectを使用して)ブロックする単一のスレッドを起動し(以下に投稿)、サーバーからの入力を受信すると、それをチャットログバッファーに追加し、バッファーを画面に出力します。それは完璧に動作します。

ncursesはスレッドセーフではないことは知っていますが、スレッドについての私の理解は、一度に1つのスレッドだけがncursesを呼び出していることを100%確認している限り、正常に機能するということです。

私の問題はカーソル位置にあります。

この行で変更され、move(height+1, curx); どの値を渡しても、ncursesは呼び出しを完全に無視し、カーソルを別の位置に置きます。私はそれに影響を与えることができないようです。

問題をさらに説明するために、私のメインスレッド(キープレスループ)では、同じミューテックスブロッキングを使用しています。コードのこれらのセクションでカーソルが更新されると、計画どおりに機能します。以下の受信スレッドから更新される場合、カーソル呼び出しは無視されます。

何か案は?

receive thread

   char buf[512];

    fd_set read_fds;
    FD_ZERO(&read_fds);

    int nbytes;

    for (;;) {

            read_fds = master;
            select(sockfd+1, &read_fds, NULL, NULL, NULL);

            pthread_mutex_lock(&mutexdisplay);

            memset(&buf, 0, sizeof buf);
            nbytes = recv(sockfd, buf, 512, 0);
            buf[nbytes] = 0;

            add_chatmsg(chatlog, &numchatlog, buf);

            // erase window
            werase(chat_window);

            // redraw border
            wborder(chat_window, '|', '|', '-', '-', '+', '+', '+', '+');

            // scroll completely into the future
            chatlogstart = numchatlog-1;

            // print the chat log
            print_chatlog(chatlog, &numchatlog, &chatlogstart, &height);

            move(height+1, curx);

            // refresh window
            wrefresh(chat_box);
            wrefresh(chat_window);

            pthread_mutex_unlock(&mutexdisplay);

    }

4

1 に答える 1

0

この質問への回答には遅すぎるかもしれません。

カーソルを制御するウィンドウを指定しませんでした。chat_box または chat_window の (height+1, curx) 位置にカーソルが必要であると想定しています。

元の端末である stdout ウィンドウで move 関数を使用してカーソルを制御できますが、作成したウィンドウ (chat_box および chat_window) では制御できません。ユーザーが作成したウィンドウでカーソルを制御するための関数は、wmove です。

int move(int y, int x);

int wmove(WINDOW *win, int y, int x);

これが、同様の問題に直面している他の人に役立つことを願っています。これが正しい解決策でない場合は、指摘してください。

于 2015-10-20T14:57:17.417 に答える