2010-05-22 4 views
2

J'ai essayé d'animer dans un programme C en utilisant Xlib et je veux faire quelque chose quand un événement se produit, sinon je veux continuer à animer. Voici un exemple extrait de code de ce que je fais actuellement:Dans Xlib, Comment puis-je animer jusqu'à ce qu'un événement se produise?

while(1) 
{ 
// If an event occurs, stop and do whatever is needed. 
// If no event occurs, skip this if statement. 
    if (XEventsQueued(display, QueuedAlready) > 0) 
{ 
     XNextEvent(display, &event) 
     switch (event.type) 
    { 
    // Don't do anything 
    case Expose: 
    while (event.xexpose.count != 0) 
    break; 

    // Do something, when a button is pressed 
    case ButtonPress: 
    ... 
    break; 

    // Do something, when a key is pressed 
    case KeyPress: 
    ... 
    break; 
     } 
} 
    animate(); // Do animation step i.e. change any drawings... 
    repaint(); // Paint again with the new changes from animation... 
} 

Donc, fondamentalement, je veux garder en boucle si l'utilisateur n'a pas cliqué sur la souris ou appuyé sur une touche du clavier encore. Lorsque l'utilisateur appuie sur une touche OU clique sur la souris, je veux arrêter et faire une action spécifique. Le problème dans mon code ci-dessus est que, il ne s'arrête pas chaque fois que je fais une action. Si je supprime l'instruction if, l'animation se bloque jusqu'à ce qu'un événement se produise, mais je ne le veux pas. C'est un problème simple, mais je suis un peu nouveau pour Xlib/animations donc toute aide serait très appréciée. Merci.

Répondre

2

Utilisez le descripteur de fichier renvoyé par ConnectionNumber(display) avec select() et utilisez l'argument timeout. Si select() renvoie 0, alors dessinez un peu plus de cadres. N'oubliez pas d'appeler le XSync() avant le select() pour que le serveur X reçoive votre mise à jour.

int fd,r; 
struct timeval tv; 
FD_SET rfds; 

fd=ConnectionNumber(display); 
FD_ZERO(&rfds); 
FD_SET(fd,&rfds); 
memset(&tv,0,sizeof(tv)); 
tv.tv_usec = 100000; /* delay in microseconds */ 
r=select(fd+1,&rfds,0,0,&tv); 
if(r == 0) { /* draw frame */ } 
else if (r < 0) { /* error; try again if errno=EINTR */ } 
else { /* pull events out */ } 
Questions connexes