LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Software
User Name
Password
Linux - Software This forum is for Software issues.
Having a problem installing a new program? Want to know which application is best for the job? Post your question in this forum.

Notices


Reply
  Search this Thread
Old 06-19-2004, 10:47 AM   #1
TTux
LQ Newbie
 
Registered: Jun 2004
Location: India, Pune
Distribution: SuSE 10.1
Posts: 8

Rep: Reputation: 0
XNextEvent() non-blocking equivalent in xlib?


Hi!

I've just started working with xlib.
Can anyone tell me if there's any nonblocking equivalent to XNextEvent() ?
XCheckWindowEvent() and others are not what i really want.
I'm writing a programme which draws to a window, after every time interval 't'. But i also want to receive user input events. If i use XNextEvent(), it blocks until there's some input, so it'll not allow me to draw to screen continously. On the other hand, if i use XCheckWindowEvent() in a loop like:

while(1)
{
if(time interval 't' has elapsed)
draw something

if(XCheckWindowEvent())
{
handle input event
}
}

this eats up cpu time like anything.

So what i really require is a function, which blocks for a period of time 't', or until an input event is received from XServer, whichever is earlier. Thus, when it doesn't need to do anything, the programme will simply block, rather than keep on looping!

I might be able to use select() system call to block for time 't', but then it'll block even if an event is received, which will make the user wait, making the programme less responsive. Not something desirable.

Is there any way out?

Please help.
Regards,
TTux
 
Old 06-24-2004, 10:38 AM   #2
TTux
LQ Newbie
 
Registered: Jun 2004
Location: India, Pune
Distribution: SuSE 10.1
Posts: 8

Original Poster
Rep: Reputation: 0
Hi!

The following code snippet is not blocking where it should! Please take a look...

struct timespec tv; //used to manage update intervals

while(1)
{
printf("\nLoop"); //this is where is actually blocks!! Strange.
//if any input event occured while the process was blocked for time

'updateInterval' microseconds, retrive & process it
if(XCheckWindowEvent(this->display, this->window, ExposureMask |

ButtonPressMask, &anEvent))
{
printf("\nGot an event");
switch(anEvent.type)
{
case Expose:
{
//code to be added later
break;
}
case ButtonPress:
{
if(anEvent.xbutton.button == Button3)
{
XCloseDisplay(this->display);
printf("\nClosed X server connection.\n\n");
this->cleanUpBodies(); //delete all bodies
return (1); //successful

completion of simulation
}
}
default: break;
}//end of event switch
}

//now draw the simulation window to depict updated state.
this->updateSimulationScreen(DRAW);
printf("\nDraw");

//wait for a time of 'updateInterval' microseconds
tv.tv_sec = 0;
tv.tv_usec = updateInterval;
select(0, NULL, NULL, NULL, &tv); //this is where it should

block
printf("\nSelect");

//erase current simulation screen
this->updateSimulationScreen(ERASE);
printf("\nErase");
//update state of all 'bodies'
this->updateState();
printf("\nUpdate State");
}

The Idea is, in the while loop, the code begins by checking is a mouse 3rd button click

event has occured or no. If yes, quit. Else, draw something to the window (

updateSimulationScreen(DRAW)), and block for 'updateInterval' microseconds. For blocking, i

have used select(). This is where the programme should block. After 'updateInterval'

microseconds, whatever was drawn to window previously should be erased (

updateSimulationScreen(ERASE)), and a call should be made updateState(). This updateState()

tells what's new to be drawn (doesn't actually draw).
Repeat loop.

The problem is that programme blocks at beginning of while loop, after executing printf("

\nLoop");
Not immediately after call to select()!!!
So there's no gap between calls to updateSimulationScreen(DRAW) and updateSimulationScreen(

ERASE), resulting in blank screen!!

Instead of select(), i tried using sleep() and nanosleep(). But the problem remains!

Please help.

Following is other relevant code:

void nature::updateSimulationScreen(enum UPDATE_MODE action)
//! Draws/erases all 'bodies' to/from the simulation

window and returns.
/*! Each 'body' is represented by a circle in the

simulation window.
* If 'action' is DRAW, all bodies contained in

'bodyList' are drawn to simulation window.
* This is done by drawing the 'bodies' using

foreground colour.
*
* If 'action' is ERASE, all bodies contained in

'bodyList' are erased from simulation window.
* This is done by drawing the 'bodies' using

background colour.
*/
{
if(action == ERASE)
{
//make background and foreground colours same
XSetForeground(this->display, this->gc, this->whitePixelID);
}

//for every 'body' in 'bodyList', compute x and y pixel coordinates, from it's x and

y distance coordinates in metres
dllNodeRef temp = this->bodyList;
body* bodyPtr;
while(temp != NULL)
{
bodyPtr = (body*)(temp->data);
double bodyX = bodyPtr->getXPosition();
double bodyY = bodyPtr->getYPosition();

//bodyX and bodyY are in metres, convert them to pixels, using conversion

scale 'yPixelScale'
//use (defaultScreenWidth / defaultScreenHeight) as aspect ratio of

simulation window
double screenX = bodyX/(this->yPixelScale * windowWidth / windowHeight);
double screenY = bodyY/this->yPixelScale;

if ( screenX < (-1*windowWidth/2 - RADIUS) || screenX > (windowWidth/2) \
|| screenY < (-1*windowHeight/2 - RADIUS) || screenY > (

windowHeight/2) )
//if the body lies outside drawable area, then no need to draw/erase it!
{
temp = temp->next;
}
else
{
this->translateCoordinates(&screenX, &screenY);
XDrawArc(this->display, this->window, this->gc, (int)screenX -

RADIUS, (int)screenY - RADIUS, RADIUS, RADIUS, 0, 360*60);
temp = temp->next;
}
}

if(action == ERASE)
{
//set foreground colour back to black
XSetForeground(this->display, this->gc, this->blackPixelID);
}
XFlush(this->display);
}

Sample output:

kapil@linux:~/Kopera/n-body-simulation> ./test

Loop <--output pauses after printing this!
Draw <--not after printing this!!
Select
Erase
Update State
Loop
Draw
Select
Erase
Update State
.
.
.
Loop
Draw
Select
Erase
Update State
Loop
Got an event
Closed X server connection.


Simulation finished alrite!kapil@linux:~/Kopera/n-body-simulation>


I also tried with checking return value of select, gives no errors. And also tried

XInternalConnectionNumbers() to get the internal file descriptor for connection with X

Server. This returns zero descriptors!! :-(

Regards,
Kapil
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Xlib: connection to ":0.0" refused by server Xlib: No protocol specified eyalkz Linux - Newbie 12 11-27-2018 01:30 PM
Xlib problems DaveyB Slackware 8 09-26-2004 06:08 AM
Xlib: connection to ":0.0" refused by server Xlib: No protocol specified eyalkz Programming 1 03-02-2004 08:22 AM
Xlib help what to do? micxz Linux - General 4 03-10-2003 01:39 PM
Xlib js72 Linux - Software 0 02-19-2003 11:09 PM

LinuxQuestions.org > Forums > Linux Forums > Linux - Software

All times are GMT -5. The time now is 05:39 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration