В Xlib, как я могу анимировать, пока не произойдет событие? - PullRequest
2 голосов
/ 22 мая 2010

Я пытался анимировать в программе на C, используя Xlib, и я хочу что-то делать, когда происходит событие, иначе я хочу продолжать анимацию. Вот пример кода того, что я сейчас делаю:

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...
}

В общем, я хочу продолжать цикл, если пользователь еще не щелкнул мышью ИЛИ не нажал клавишу на клавиатуре. Когда пользователь нажимает клавишу ИЛИ щелкает мышью, я хочу остановиться и выполнить определенное действие. Проблема в моем коде выше заключается в том, что он не останавливается всякий раз, когда я выполняю действие. Если я удаляю оператор if, анимация блокируется, пока не происходит событие, однако я не хочу этого. Это простая проблема, но я немного новичок в Xlib / анимации, поэтому любая помощь будет высоко оценена. Спасибо.

1 Ответ

2 голосов
/ 22 мая 2010

Используйте дескриптор файла, возвращаемый ConnectionNumber(display) с select() и используйте аргумент времени ожидания.Если select() возвращает 0, тогда нарисуйте еще несколько кадров.Не забудьте позвонить XSync() перед вами select(), чтобы X-сервер получил ваше обновление.

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 */ }
...