2010-08-03 19 views
0

J'utilise ncurses pour écrire un client textuel en C. La boucle principale du programme se bloque simplement jusqu'à ce qu'une pression sur une touche soit détectée, puis la gère et continue d'attendre une autre pression sur une touche.Besoin d'aide avec le curseur et les threads ncurses

J'ai lancé un seul thread (posté ci-dessous) qui bloque (en utilisant select) en attente d'entrée du serveur et quand il le reçoit l'ajoute au tampon du journal de chat et imprime le tampon à l'écran. Cela fonctionne parfaitement. Je sais que ncurses n'est pas thread-safe mais ma compréhension des threads est que tant que je suis sûr à 100% qu'un seul thread fait des appels à ncurses à la fois, cela fonctionnera bien.

Mon problème est avec la position du curseur.

Il est modifié avec la ligne move(height+1, curx); et peu importe les valeurs que je lui passe, ncurses semble ignorer complètement l'appel et place mon curseur à une position différente. Je n'arrive pas à l'influencer. Pour expliquer davantage le problème, dans mon thread principal (la boucle keypress), j'utilise le même blocage de mutex. Lorsque le curseur est mis à jour dans ces sections de code, cela fonctionne comme prévu. Lorsqu'il est mis à jour à partir du thread de réception ci-dessous, l'appel du curseur est ignoré.

Des idées?

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); 

    } 

+0

Pourquoi utiliser un thread lorsque vous utilisez select? ne pas trop compliquer les choses! – mvds

+0

vous avez raison et tort. sélectionner des blocs qui empêcheraient l'interface utilisateur de fonctionner pendant la vérification des données. Au moins pendant mes tests. Cependant, j'étais trop compliquer les choses et a fini par réparer le problème –

Répondre

0

Peut être son trop tard pour répondre à cette question.

Vous n'avez pas spécifié sur quelle fenêtre vous voulez contrôler le curseur. Je suppose que vous vouliez le curseur à la position (height + 1, curx) de la chat_box ou de la chat_window.

On peut contrôler le curseur avec la fonction de déplacement dans la visseuse stdout qui est le terminal d'origine mais pas sur les fenêtres (chat_box et chat_window) que vous avez créées. La fonction de contrôle du curseur dans les fenêtres créées par l'utilisateur est wmove.

entier (int y, int x);

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

Espérons que cela aidera d'autres personnes confrontées à un problème similaire. Veuillez indiquer si ce n'est pas la bonne solution.